2013-05-14 2 views
2

파이 게임이있는 플랫폼 게임을 만들고 있는데, 중력을 더하고 싶습니다. 지금은 화살표 키를 누를 때 움직이는 그림 만 있고, 다음 단계는 중력이됩니다. 여기에 내 코드입니다 :파이 게임의 중력

import pygame, sys 
from pygame.locals import * 

pygame.init() 

FPS = 30 
fpsClock = pygame.time.Clock() 

DISPLAYSURF = pygame.display.set_mode((400, 300), 0, 32) 
pygame.display.set_caption("Jadatja") 

WHITE = (255, 255, 255) 
catImg = pygame.image.load("images/cat.png") 
catx = 10 
caty = 10 
movingRight = False 
movingDown = False 
movingLeft = False 
movingUp = False 

while True: #main game loop 

    #update 
    for event in pygame.event.get(): 
    if event.type == KEYDOWN: 
     if event.key == K_RIGHT: 
      #catx += 5 
      movingRight = True 
      movingLeft = False 
     elif event.key == K_DOWN: 
      #caty += 5 
      movingDown = True 
      movingUp = False 
     elif event.key == K_LEFT: 
      #catx -= 5 
      movingLeft = True 
      movingRight = False 
     elif event.key == K_UP: 
      #caty -= 5 
      movingUp = True 
      movingDown = False 

    if event.type == KEYUP: 
     if event.key == K_RIGHT: 
      movingRight = False 
     if event.key == K_DOWN: 
      movingDown = False 
     if event.key == K_LEFT: 
      movingLeft = False 
     if event.key == K_UP: 
      movingUp = False 


    #actually make the player move 
    if movingRight == True: 
     catx += 5 
    if movingDown == True: 
     caty += 5 
    if movingLeft == True: 
     catx -= 5 
    if movingUp == True: 
     caty -= 5 


    #exit 
    for event in pygame.event.get(): 
     if event.type == KEYUP: 
      if event.key == K_ESCAPE: 
       pygame.quit() 
       sys.exit() 

     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 

    #draw 
    DISPLAYSURF.fill(WHITE) 
    DISPLAYSURF.blit(catImg, (catx, caty)) 



    pygame.display.update() 
    fpsClock.tick(FPS) 

내가 생각으로이 코드가 원활 경우 나는 100 % 확실하지 않다,하지만 난 너희들이 그 일을 할 수 있기를 바랍니다.

감사

+0

? 중력의 "안녕하세요 세상"은 스프라이트가 "공중에있는"것으로 간주 될 때마다 음수의 caty를 적용하여 작동합니다. 그러나 나는 지금까지 무엇을 시도 했는가? – Tadgh

답변

4

내가 당신에게 도움이 될 것 같아요 튀는 공을 만들기위한 a tutorial이 있습니다.

지금, 당신은 단순히 루프를 통해 y 방향의 모든 시간을 몇 가지 여분의 속도를 추가하는 것, 그 시뮬레이션에 무게를 추가합니다 : 당신이와 끝까지 것은 그러나 종류의 구피

speed[1] += gravity 

, 이미지가 빠르게 윈도우의 아래쪽에 내려 이후 다시는 볼 수없는 수 :이 창에 남아 있어야하므로

다음 단계는 공의 위치를 ​​클립하는 것이다 :

import os 
import sys, pygame 
pygame.init() 

size = width, height = 320, 240 
speed = [1, 1] 
black = 0, 0, 0 
gravity = 0.1 

screen = pygame.display.set_mode(size) 

image_file = os.path.expanduser("~/pybin/pygame_examples/data/ball.png") 
ball = pygame.image.load(image_file) 
ballrect = ball.get_rect() 

def clip(val, minval, maxval): 
    return min(max(val, minval), maxval) 

while 1: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: sys.exit() 

    speed[1] += gravity 

    ballrect = ballrect.move(speed) 
    if ballrect.left < 0 or ballrect.right > width: 
     speed[0] = -speed[0] 
    if ballrect.top < 0 or ballrect.bottom > height: 
     speed[1] = -speed[1] 

    # clip the position to remain in the window 

    ballrect.left = clip(ballrect.left, 0, width) 
    ballrect.right = clip(ballrect.right, 0, width)   
    ballrect.top = clip(ballrect.top, 0, height) 
    ballrect.bottom = clip(ballrect.bottom, 0, height) 

    screen.fill(black) 
    screen.blit(ball, ballrect) 
    pygame.display.flip() 

이제 코드를 현재 코드에 통합하면 작업을 중단하고 실행할 수 있습니다. 그러나 코드를 체계적이고 반복적으로 만들 수있는 몇 가지 방법이 있습니다. 또한의 움직임과 관련된 모든 로직을 넣어 혜택을 누릴 수

delta = { 
    pygame.K_LEFT: (-20, 0), 
    pygame.K_RIGHT: (+20, 0), 
    pygame.K_UP: (0, -20), 
    pygame.K_DOWN: (0, +20), 
    } 
for event in pygame.event.get(): 
    if event.type == pygame.KEYDOWN: 
     deltax, deltay = delta.get(event.key, (0, 0)) 
     ball.speed[0] += deltax 
     ball.speed[1] += deltay 

:

예를 들어, 당신이 좋아하는 무언가로 다시 쓸 수

for event in pygame.event.get(): 

에 따라 대규모 if...then 블록을 고려 다음 이미지를 수업에 추가하십시오 :

class Ball(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     self.image = pygame.image.load(image_file) 
     self.rect = self.image.get_rect() 
     self.speed = [0, 0] 
     area = pygame.display.get_surface().get_rect() 
     self.width, self.height = area.width, area.height 

    def update(self): 
     self.rect = self.rect.move(self.speed) 
     if self.rect.left < 0 or self.rect.right > self.width: 
      self.speed[0] = -self.speed[0] 
     if self.rect.top < 0 or self.rect.bottom > self.height: 
      self.speed[1] = -self.speed[1] 
     self.rect.left = clip(self.rect.left, 0, self.width) 
     self.rect.right = clip(self.rect.right, 0, self.width)   
     self.rect.top = clip(self.rect.top, 0, self.height) 
     self.rect.bottom = clip(self.rect.bottom, 0, self.height)     

update 메소드는 자습서에서 제공하는 코드와 매우 유사합니다. Ball 클래스를 만드는 좋은 점 중 하나는 프로그램의 나머지 부분에서 볼이 어떻게 움직이는지를 많이 알 필요가 없다는 것입니다. 모든 로직은 Ball.update입니다. 또한 많은 볼을 쉽게 인스턴스화 할 수 있습니다. 그리고 다르게 움직이는 다른 클래스 (비행기, 새, 패들 등)를 만들 수도 있고 시뮬레이션에 상대적으로 쉽게 추가 할 수 있습니다.

그래서, 모두 함께 넣어,이 같은 끝낼 것 :

당신이 중력을 구현하기 위해 지금까지 노력했다 무엇
""" 
http://stackoverflow.com/a/15459868/190597 (unutbu) 
Based on http://www.pygame.org/docs/tut/intro/intro.html 
Draws a red ball bouncing around in the window. 
Pressing the arrow keys moves the ball 
""" 

import sys 
import pygame 
import os 


image_file = os.path.expanduser("~/pybin/pygame_examples/data/ball.png") 

delta = { 
    pygame.K_LEFT: (-20, 0), 
    pygame.K_RIGHT: (+20, 0), 
    pygame.K_UP: (0, -20), 
    pygame.K_DOWN: (0, +20), 
    } 

gravity = +1 

class Ball(pygame.sprite.Sprite): 
    def __init__(self): 
     pygame.sprite.Sprite.__init__(self) 
     self.image = pygame.image.load(image_file) 
     self.rect = self.image.get_rect() 
     self.speed = [0, 0] 
     area = pygame.display.get_surface().get_rect() 
     self.width, self.height = area.width, area.height 

    def update(self): 
     self.rect = self.rect.move(self.speed) 
     if self.rect.left < 0 or self.rect.right > self.width: 
      self.speed[0] = -self.speed[0] 
     if self.rect.top < 0 or self.rect.bottom > self.height: 
      self.speed[1] = -self.speed[1] 
     self.rect.left = clip(self.rect.left, 0, self.width) 
     self.rect.right = clip(self.rect.right, 0, self.width)   
     self.rect.top = clip(self.rect.top, 0, self.height) 
     self.rect.bottom = clip(self.rect.bottom, 0, self.height)     

def clip(val, minval, maxval): 
    return min(max(val, minval), maxval) 

class Main(object): 
    def __init__(self): 
     self.setup() 
    def setup(self): 
     pygame.init() 
     size = (self.width, self.height) = (640,360) 
     self.screen = pygame.display.set_mode(size, 0, 32) 
     self.ball = Ball() 
     self.setup_background() 
    def setup_background(self): 
     self.background = pygame.Surface(self.screen.get_size()) 
     self.background = self.background.convert() 
     self.background.fill((0, 0, 0)) 
     self.screen.blit(self.background, (0, 0)) 
     pygame.display.flip() 
    def draw(self): 
     self.screen.blit(self.background, (0, 0)) 
     self.screen.blit(self.ball.image, self.ball.rect) 
     pygame.display.flip() 
    def event_loop(self): 
     ball = self.ball 
     friction = 1 
     while True: 
      for event in pygame.event.get(): 
       if ((event.type == pygame.QUIT) or 
        (event.type == pygame.KEYDOWN and 
        event.key == pygame.K_ESCAPE)): 
        sys.exit() 
       elif event.type == pygame.KEYDOWN: 
        deltax, deltay = delta.get(event.key, (0, 0)) 
        ball.speed[0] += deltax 
        ball.speed[1] += deltay 
        friction = 1 
       elif event.type == pygame.KEYUP: 
        friction = 0.99 

      ball.speed = [friction*s for s in ball.speed] 
      ball.speed[1] += gravity 
      ball.update() 
      self.draw() 
      pygame.time.delay(10) 

if __name__ == '__main__': 
    app = Main() 
    app.event_loop() 
관련 문제