Skip to content

Instantly share code, notes, and snippets.

@naengwen
Created June 27, 2009 06:42
Show Gist options
  • Save naengwen/136927 to your computer and use it in GitHub Desktop.
Save naengwen/136927 to your computer and use it in GitHub Desktop.
#! /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