Created
February 25, 2016 09:00
-
-
Save Mekire/7f9c36f3fc4e7578fc15 to your computer and use it in GitHub Desktop.
Store dt*velocity only changing the rect when above 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
import os | |
import sys | |
import math | |
import pygame as pg | |
CAPTION = "Move me with the Arrow Keys" | |
SCREEN_SIZE = (500, 500) | |
TRANSPARENT = (0, 0, 0, 0) | |
DIRECT_DICT = {pg.K_LEFT : (-1, 0), | |
pg.K_RIGHT : ( 1, 0), | |
pg.K_UP : ( 0,-1), | |
pg.K_DOWN : ( 0, 1)} | |
class Player(object): | |
""" | |
This class will represent our user controlled character. | |
""" | |
SIZE = (100, 100) | |
def __init__(self, pos, speed): | |
""" | |
The pos argument is a tuple for the center of the player (x,y); | |
speed is given in pixels/second. | |
""" | |
self.rect = pg.Rect((0,0), Player.SIZE) | |
self.rect.center = pos | |
self.velocity = [0,0] | |
self.speed = speed | |
self.image = self.make_image() | |
def make_image(self): | |
""" | |
Creates our hero (a red circle/ellipse with a black outline). | |
""" | |
image = pg.Surface(self.rect.size).convert_alpha() | |
image.fill(TRANSPARENT) | |
image_rect = image.get_rect() | |
pg.draw.ellipse(image, pg.Color("black"), image_rect) | |
pg.draw.ellipse(image, pg.Color("red"), image_rect.inflate(-12, -12)) | |
return image | |
def update(self, screen_rect, keys, dt): | |
""" | |
Updates our player appropriately every frame. | |
""" | |
for key in DIRECT_DICT: | |
if keys[key]: | |
self.velocity[0] += DIRECT_DICT[key][0]*self.speed*dt | |
self.velocity[1] += DIRECT_DICT[key][1]*self.speed*dt | |
for i in (0,1): | |
if abs(self.velocity[i]) > 1: | |
remainder = math.fmod(self.velocity[i], 1) | |
whole = round(self.velocity[i]-remainder) | |
self.rect[i] += whole | |
self.velocity[i] = remainder | |
self.rect.clamp_ip(screen_rect) | |
def draw(self, surface): | |
""" | |
Draws the player to the target surface. | |
""" | |
surface.blit(self.image, self.rect) | |
class App(object): | |
""" | |
A class to manage our event, game loop, and overall program flow. | |
""" | |
def __init__(self): | |
""" | |
Get a reference to the display surface; set up required attributes; | |
and create a Player instance. | |
""" | |
self.screen = pg.display.get_surface() | |
self.screen_rect = self.screen.get_rect() | |
self.clock = pg.time.Clock() | |
self.fps = 60 | |
self.done = False | |
self.keys = pg.key.get_pressed() | |
self.player = Player(self.screen_rect.center, 190) | |
def event_loop(self): | |
""" | |
One event loop. Never cut your game off from the event loop. | |
""" | |
for event in pg.event.get(): | |
if event.type == pg.QUIT or self.keys[pg.K_ESCAPE]: | |
self.done = True | |
elif event.type in (pg.KEYUP, pg.KEYDOWN): | |
self.keys = pg.key.get_pressed() | |
def render(self): | |
""" | |
Perform all necessary drawing and update the screen. | |
""" | |
self.screen.fill(pg.Color("white")) | |
self.player.draw(self.screen) | |
pg.display.update() | |
def main_loop(self): | |
""" | |
One game loop. Simple and clean. | |
""" | |
self.clock.tick(self.fps)/1000.0 | |
dt = 0.0 | |
while not self.done: | |
self.event_loop() | |
self.player.update(self.screen_rect, self.keys, dt) | |
self.render() | |
dt = self.clock.tick(self.fps)/1000.0 | |
def main(): | |
""" | |
Prepare our environment, create a display, and start the program. | |
""" | |
os.environ['SDL_VIDEO_CENTERED'] = '1' | |
pg.init() | |
pg.display.set_caption(CAPTION) | |
pg.display.set_mode(SCREEN_SIZE) | |
App().main_loop() | |
pg.quit() | |
sys.exit() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment