Skip to content

Instantly share code, notes, and snippets.

@Artanis
Created June 26, 2010 02:41
Show Gist options
  • Save Artanis/453710 to your computer and use it in GitHub Desktop.
Save Artanis/453710 to your computer and use it in GitHub Desktop.
# System Modules
# Third-party Modules
import pymunk
import pyglet
from pyglet.gl import *
# Local Modules
import camera
import universe
import game_object
from config import settings
window = pyglet.window.Window(
settings.getint("window", "width"),
settings.getint("window", "height"))
pymunk.init_pymunk()
cam = camera.Camera(window, zoom=settings.getfloat("camera", "zoom"))
world = universe.Universe(settings.getfloat("simulation", "interval"))
world.gravity = (0,-100)
ground = game_object.LevelGround(-2, 10, 0.25)
ball1 = game_object.Ball(0,10, (0,0.25))
ball2 = game_object.Ball(0.01,5, (0, 0.5))
#box1 = game_object.Block(0,-2, False)
#box2 = game_object.Block(0,4, False)
world.add_static(ground)
world.add(ball1)
world.add(ball2)
#world.add(box1)
#world.add(box2)
ball2.body.velocity = (0, 12.5)
#box1.body.velocity = (0,25)
#box1.body.angle = 30
@window.event
def on_draw():
glClear(GL_COLOR_BUFFER_BIT)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
cam.world_projection()
world.draw()
window.flip()
if __name__ == "__main__":
pyglet.clock.schedule_interval(world.step,
settings.getfloat("simulation", "interval"))
pyglet.app.run()
# System Modules
# Third-party Modules
import pyglet
from pyglet.gl import *
# Local Modules
from config import Config
class Camera(object):
def __init__(self, window, position=(0.0, 0.0), rotation=0.0, zoom=1.0):
self.position = position
self.window = window
self.rotation = rotation
self.zoom = zoom
@property
def ratio(self):
return float(self.window.width) / float(self.window.height)
def world_projection(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
# just because
glOrtho(*orthogonal(self.ratio, self.zoom))
def hud_projection(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
# again, because
glOrtho(*flat())
def orthogonal(ratio, zoom):
return (-zoom * ratio, zoom * ratio, -zoom, zoom, -1, 1)
def flat(height, width):
return (0.0, height, 0.0, width, -1, 1)
# System Modules
import ConfigParser as configparser
# Third-party Modules
# Local Modules
class Config(configparser.RawConfigParser):
def __init__(self, settings_file):
configparser.RawConfigParser.__init__(self)
self.settings_file = settings_file
self.read(settings_file)
def set_defaults(self):
Config.add_section("window")
Config.set("window", "width", 800)
Config.set("window", "height", 600)
Config.set("window", "fullscreen", False)
Config.add_section("camera")
Config.set("camera", "zoom", 10.0)
Config.add_section("simulation")
Config.set("simulation", "interval", 1/120.0)
Config.add_section("debug")
Config.set("debug", "debug", True)
def write(self, settings_file=None):
out = None
if settings_file is not None:
out = open(settings_file)
else:
out = open(self.settings_file)
configparser.RawConfigParser.write(self, out)
settings = Config("settings")
# System Modules
# Third-party Modules
import pymunk
import pyglet
from pyglet.gl import *
# Local Modules
import utils
class GameObject(object):
""" A base class for all simple game objects.
Use super() for method inheritance.
"""
def __init__(self, static=False):
""" Creates placeholder attributes.
Real game objects do need both body and shape.
If ``static`` is true, the Universe class will not add the body
to the simulation.
"""
self.static = static
self.body = None
self.shape = None
def step(self, delta_time):
pass
def draw(self):
pass
class Ball(GameObject):
def __init__(self, x, y, radius=(0,1), offset=(0,0), mass=10, friction=0.5):
super(Ball, self).__init__()
inner_radius, outer_radius = radius
self.body = pymunk.Body(mass, pymunk.moment_for_circle(
mass, inner_radius, outer_radius, offset))
self.body.position = x, y
self.shape = pymunk.Circle(self.body, outer_radius, offset)
self.shape.elasticity = 0.8
def step(self, dt):
super(Ball, self).step(dt)
def draw(self):
super(Ball, self).draw()
x, y = self.body.position
angle = self.body.angle
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(x, y, 0.0)
glRotatef(angle, 0, 0, 1)
glBegin(GL_LINE_LOOP)
glColor4f(1.0, 1.0, 1.0, 1.0)
for x, y in utils.poly_circle(self.shape.radius):
glVertex2f(x, y)
glEnd()
class Block(GameObject):
def __init__(self, x, y, static=True):
super(Block, self).__init__(static)
self.body = pymunk.Body(pymunk.inf, pymunk.inf)
self.body.position = (x, y)
self.shape = pymunk.Poly(self.body,
[(1, 1), (1, -1), (-1, -1),(-1, 1)],
(0, 0), False)
self.shape.elasticity = 0.8
def draw(self):
super(Block, self).draw()
x, y = self.body.position
angle = self.body.angle
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(x, y, 0.0)
glRotatef(angle, 0, 0, 1)
glBegin(GL_LINE_LOOP)
glColor4f(1.0, 1.0, 1.0, 1.0)
glVertex2f(-1.0, 1.0)
glVertex2f(1.0, 1.0)
glVertex2f(1.0, -1.0)
glVertex2f(-1.0, -1.0)
glEnd()
def step(self, dt):
super(Block, self).step(dt)
#class Trophy(GameObject):
# def __init__(self, x, y):
# super(Trophy, self).__init__(static=False)
#
# self.body = pymunk.Body(10, 10)
# self.body.position = x, y
#
# self.shape[0] = pymunk.Poly(body,
class LevelGround(GameObject):
def __init__(self, level, width=5.0, radius=1.0):
super(LevelGround, self).__init__(static=True)
self.body = pymunk.Body(pymunk.inf, pymunk.inf)
self.body.position = 0, level
self.shape = pymunk.Segment(self.body,
(-width/2.0, level), (width/2.0, level), radius)
self.shape.elasticity = 0.8
def step(self, dt):
super(LevelGround, self).step(dt)
def draw(self):
super(LevelGround, self).draw()
x, y = self.body.position
angle = self.body.angle
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslatef(x, y, 0.0)
glRotatef(angle, 0, 0, 1)
glBegin(GL_LINE_LOOP)
glColor4f(1.0, 1.0, 1.0, 1.0)
glVertex2f(*self.shape.a)
glVertex2f(*self.shape.b)
glEnd()
[debug]
debug = True
[window]
width = 800
height = 600
[camera]
zoom = 10
[simulation]
interval = 0.00833333333333
# System Modules
# Third-party Modules
import pymunk
# Local Modules
class Universe(pymunk.Space):
""" A simulation class.
Contains references to all objects in the current simulation, and
provides a hassle free system for managing the simulation.
This is not a transparent wrap of pymunk.Space. The add and remove
methods all expect objects matching the GameObject signature.
"""
def __init__(self, physics_step=1/60.0):
""" Initialize the simulation
Uses super() for method inheritance.
"""
super(Universe, self).__init__()
self.objects = list()
self.__physics_step = physics_step
def add(self, *objs):
""" Adds the bodies and shapes of the GameObjects to the
simulation, and stores references to the GameObjects.
Uses super() for method inheritance.
"""
# Pull out all the shapes and bodies and add them to the
# simulation
objects = []
for obj in objs:
objects.append(obj.shape)
if obj.static is False:
objects.append(obj.body)
super(Universe, self).add(*objects)
# Keep references
self.objects.extend(objs)
def add_static(self, *objs):
""" Adds the bodies and shapes of the GameObjects to the
simulation as static objects.
Uses super() for method inheritance.
"""
# pull out all shapes and add them to the simulation
objects = []
for obj in objs:
objects.append(obj.shape)
if obj.static is False:
objects.append(obj.body)
super(Universe, self).add_static(*objects)
# Keep references
self.objects.extend(objs)
def remove(self, *objs):
"""
"""
pass
#super(Universe, self).remove(*objs)
def remove_static(self, *objs):
"""
"""
#super(Universe, self).remove_static(*objs)
pass
def step(self, dt):
""" Update the simulation for the given time step.
Uses super() for method inheritance, but gives a constant step
value to pymunk.Space.step() for performance reasons. That
value can be defined at construction time and defaults to
1/60.0.
Uses super() for method inheritance.
"""
# Although we have time data from pyglet, pymunk works best
# with a fixed time step.
super(Universe, self).step(self.__physics_step)
for obj in self.objects:
obj.step(dt)
def draw(self):
for obj in self.objects:
obj.draw()
# System Modules
import math
# Third-party Modules
# Local Modules
def poly_circle(radius=1, step=36, include_origin=False):
""" Generate points composing a circle of given radius and
precision.
"""
if include_origin is True:
yield (0, 0)
for angle in range(0,360,step):
radian = math.radians(angle)
yield (math.sin(radian) * radius, math.cos(radian) * radius)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment