python - Gravity in pygame -
i'm making platform game pygame, , add gravity it. right have picture moves when press arrow keys, , next step gravity. here's code:
import pygame, sys 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 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 player move if movingright == true: catx += 5 if movingdown == true: caty += 5 if movingleft == true: catx -= 5 if movingup == true: caty -= 5 #exit 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)
i'm not 100% sure if code smooth think is, hope guys can make of it.
thanks
there a tutorial creating bouncing ball think might helpful you.
now, add gravity simulation, you'd add speed in y-direction every time through loop:
speed[1] += gravity
what end kind of goofy however, since image descends below bottom of window never seen again :)
the next step therefore clip position of ball must remain in window:
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: 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 position remain in 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()
okay, can incorporate in current code , you'll off , running. however, there things can make code more organized , less repetitive.
for example, consider massive if...then
blocks follow
for event in pygame.event.get():
you rewrite like:
delta = { pygame.k_left: (-20, 0), pygame.k_right: (+20, 0), pygame.k_up: (0, -20), pygame.k_down: (0, +20), } 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
you benefit putting logic associated movement of image class:
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)
notice update
method similar code presented tutorial. 1 of nice things creating ball class rest of program not need know how ball moves. logic in ball.update
. moreover, makes easy instantiate many balls. , create other classes (airplanes, birds, paddles, etc.) move differently , add them simulation relatively painlessly.
so, putting together, end this:
""" http://stackoverflow.com/a/15459868/190597 (unutbu) based on http://www.pygame.org/docs/tut/intro/intro.html draws red ball bouncing around in window. pressing arrow keys moves 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: event in pygame.event.get(): if ((event.type == pygame.quit) or (event.type == pygame.keydown , 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 s in ball.speed] ball.speed[1] += gravity ball.update() self.draw() pygame.time.delay(10) if __name__ == '__main__': app = main() app.event_loop()
Comments
Post a Comment