Created
June 27, 2009 06:42
-
-
Save naengwen/136927 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
"""Here's the test harness. | |
@TODO: Figure out collision events for jumps, etc. | |
""" | |
try: | |
import os | |
import sys | |
import math | |
import random | |
import pymunk | |
import pygame | |
from pygame.locals import * | |
from pygame.color import THECOLORS as COLOR | |
except ImportError, err: | |
print "couldn't load module. %s" % (err) | |
sys.exit(2) | |
HEIGHT = 200 | |
WIDTH = 320 | |
MAX_FRAMERATE = 60.0 | |
BG_IMAGE0 = 'layer-0.gif' | |
BG_IMAGE1 = 'layer-1.gif' | |
BG_IMAGE2 = 'layer-2.gif' | |
BG_IMAGE3 = 'layer-3.gif' | |
def load_image(file_name, colorkey=False, image_directory='images'): | |
"""Loads an image, file_name, from image_directory, for use in pygame | |
""" | |
file = os.path.join(image_directory, file_name) | |
_image = pygame.image.load(file) | |
if colorkey: | |
if colorkey == -1: | |
# If the color key is -1, set it to color of upper left corner | |
colorkey = _image.get_at((0, 0)) | |
_image.set_colorkey(colorkey) | |
_image = _image.convert() | |
else: # If there is no colorkey, preserve the image's alpha per pixel. | |
_image = _image.convert_alpha() | |
return _image | |
def to_pygame(p): | |
""" Converts given pymonk coords to pygame coords | |
Magic: Uses Global variable HEIGHT | |
""" | |
return int(p.x), int(HEIGHT-p.y) | |
def create_player(space): | |
""" Initializes a number of variables related to pymunk and pygames with | |
respect to the player | |
""" | |
mass = 1 | |
radius = 7 | |
inertia = pymunk.moment_for_circle(mass, 0, radius, (0,0)) | |
body = pymunk.Body(mass, 10) | |
body.position = (WIDTH/2, HEIGHT/2) | |
shape = pymunk.Circle(body, radius, (0,0)) | |
shape._set_friction(5.0) | |
shape._set_elasticity(0.99) | |
space.add(body, shape) | |
return shape | |
def draw_player(screen, player): | |
""" Currently just draws a circle for the player. | |
@TODO: Maybe make it into a stick figure? After we understand Pymunk a bit, | |
Maybe some sprites for the limbs, head and body. | |
""" | |
pygame.draw.circle(screen, COLOR['red'], | |
to_pygame(player.body.position), int(player.radius)) | |
def create_border(space): | |
""" Establishes boundaries that the player is unable to cross. | |
@TODO: Maybe change it from a rectangle to two lines on the left and right | |
side of the screen, and have other objects which keep players up. | |
""" | |
body = pymunk.Body(pymunk.inf, pymunk.inf) | |
body.position = (WIDTH/2, HEIGHT/2) | |
p1 = ((-WIDTH/2)+30, (HEIGHT/2)-10) | |
p2 = ((WIDTH/2)-30, (HEIGHT/2)-10) | |
p3 = ((WIDTH/2)-30, (-HEIGHT/2)+40) | |
p4 = ((-WIDTH/2)+30, (-HEIGHT/2)+40) | |
top = pymunk.Segment(body, p1, p2, 10.0) | |
bottom = pymunk.Segment(body, p4, p3, 10.0) | |
left = pymunk.Segment(body, p1, p4, 10.0) | |
right = pymunk.Segment(body, p2, p3, 10.0) | |
top.friction = 10.0 | |
bottom.friction = 10.0 | |
left.friction = 0 | |
right.friction = 0 | |
top.elasticity = 0.5 | |
bottom.elasticity = 0.5 | |
left.elasticity = 0 | |
right.elasticity = 0 | |
space.add(top, bottom, left, right) | |
return top, bottom, left, right | |
def draw_lines(screen, lines): | |
""" This is so we can actually see the borders created above. | |
""" | |
for line in lines: | |
body = line.body | |
pv1 = body.position + line.a.rotated(math.degrees(body.angle)) | |
pv2 = body.position + line.b.rotated(math.degrees(body.angle)) | |
p1 = to_pygame(pv1) | |
p2 = to_pygame(pv2) | |
pygame.draw.aalines(screen, COLOR['cyan'], True, [p1, p2]) | |
# Game Logic and main loop | |
def main(): | |
""" The game's primary initialization and loop is contained here. Clock ticks, | |
pygame initalizes, the window is set up, key events are handled, and | |
objects are created. | |
@TODO: Currently blitting the whole background, then redrawing the sprite. | |
Prevents a trail, but it slows down the game. Tried the 'dirty rectangles' | |
method, still got a trail. Commented code for the dirty rectangles is at | |
the line under the next TODO. | |
""" | |
# Initialize | |
pygame.init() | |
pymunk.init_pymunk() | |
# Establish spacetime continuum | |
space = pymunk.Space() | |
space.gravity = (0.0, -450.0) | |
# Create window | |
size = WIDTH, HEIGHT | |
screen = pygame.display.set_mode(size) | |
clock = pygame.time.Clock() | |
# Fill background | |
background0 = load_image(BG_IMAGE0) | |
background1 = load_image(BG_IMAGE1) | |
background2 = load_image(BG_IMAGE2) | |
background3 = load_image(BG_IMAGE3) | |
# Objects | |
player = create_player(space) | |
border = create_border(space) | |
# Variables | |
dx, dy = (0,0) | |
bgscroll = 0 | |
#jump = JUMP_HOLD | |
#Initial draw | |
#screen.fill((0,0,0)) | |
screen.blit(background0, (0,0)) | |
screen.blit(background1, (0,0)) | |
screen.blit(background2, (0,0)) | |
screen.blit(background3, (0,0)) | |
draw_player(screen, player) | |
draw_lines(screen, border) | |
pygame.display.flip() | |
#The Game Loop | |
running = True | |
while running: | |
#Key Events | |
px = int(to_pygame(player.body.position)[0]-int(player.radius)) | |
py = int(to_pygame(player.body.position)[1]-int(player.radius)) | |
screen.fill((0,0,0)) | |
for e in pygame.event.get(): | |
if (e.type == KEYDOWN and e.key == K_ESCAPE) or (e.type == QUIT): | |
running = False | |
if e.type == KEYDOWN: | |
if e.key == K_UP: | |
dy = 10 | |
if e.key == K_DOWN: | |
dy = -20 | |
if e.key == K_LEFT: | |
dx = -10 | |
if e.key == K_RIGHT: | |
dx = 10 | |
if e.type == KEYUP: | |
if e.key == K_LEFT or e.key == K_RIGHT: | |
dx = 0 | |
if e.key == K_UP or e.key == K_DOWN: | |
dy = 0 | |
#Previous ball position is saved for blitting purposes | |
# px = int(to_pygame(player.body.position)[0]-int(player.radius)) | |
# py = int(to_pygame(player.body.position)[1]-int(player.radius)) | |
#The ball is displaced by whatever the key event denotes | |
player.body.apply_impulse((dx, dy)) | |
bgscroll += player.body.velocity.x/100 | |
bgscroll %= WIDTH | |
#Screen is redrawn here | |
#TODO: Get this part to worth without a trail | |
#screen.blit(background, (px,py),(px,py,player.radius*2,player.radius*2)) | |
screen.blit(background0, (0,0), (WIDTH-bgscroll,0,bgscroll, HEIGHT)) | |
screen.blit(background0, (bgscroll,0), (0,0,WIDTH-bgscroll, HEIGHT)) | |
screen.blit(background1, (0,0), (WIDTH-bgscroll,0,bgscroll, HEIGHT)) | |
screen.blit(background1, (bgscroll,0), (0,0,WIDTH-bgscroll, HEIGHT)) | |
screen.blit(background2, (0,0), ((WIDTH-bgscroll)*2,0,bgscroll*2, HEIGHT)) | |
screen.blit(background2, (bgscroll*2,0), (0,0,(WIDTH-bgscroll)*2, HEIGHT)) | |
screen.blit(background3, (0,0), ((WIDTH-bgscroll)*3,0,bgscroll*3, HEIGHT)) | |
screen.blit(background3, (bgscroll*3,0), (0,0,(WIDTH-bgscroll)*3, HEIGHT)) | |
draw_player(screen, player) | |
draw_lines(screen, border) | |
pygame.display.flip() | |
#Finally, the clock ticks. | |
space.step(1 / MAX_FRAMERATE) | |
clock.tick(MAX_FRAMERATE) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment