Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from pyglet.window import Window, key
- from pyglet.graphics import vertex_list
- from pyglet import app, gl, clock
- import pymunk
- from pymunk import Vec2d
- from math import cos, sin, radians
- from random import choice, randint
- class Line(object):
- '''
- An object that bind drawing and physics of a static line.
- '''
- def __init__(self, start, end, body, color=[0,0,0], friction=0.2):
- '''
- start(suple): A tuple of 2D vertex coordinate. Start point of the line.
- end(tuple): A tuple of 2D vertex coordinate. End point of the line.
- body(pymunk.Body): Pymunk body object
- color(list): List of [red green blue] in bytes. Color of the vertices.
- friction(float): Friction for the physic.
- '''
- vertices = (start[0], start[1], end[0], end[1])
- self.mesh = vertex_list(2, ('v2i', vertices),
- ('c3B', color*2 ))
- self.mesh_physic = pymunk.Segment(body, start, end, 0.0)
- self.friction = friction
- def registerPhysicSpace(self, space):
- space.add(self.mesh_physic)
- def draw(self):
- self.mesh.draw(gl.GL_LINES)
- class Ball(object):
- '''
- An object that bind drawing and physics of a ball.
- '''
- def __init__(self, center, radius, quality=14, angle=0, mass=10,
- life = 100, friction=0.5, color=[0,0,0]):
- '''
- center(tuple): A tuple for the center of the circle
- radius(float or int): Radius of the circle
- quality(int or float): Quality of the circle (the smaller the better)
- angle(int): Angle of the pysical mesh in degree
- mass(int): Mass of the physical mesh
- life(int): Time (in fps) of life for the object.
- friction(float): Friction for the physical mesh
- color(list): Color of the mesh.
- '''
- j, k = center[0], center[1]
- vertices = [j, k] #Center of the ball
- self.quality = quality
- self.radius = radius
- self.life = life
- #Calculate vertex positions.
- steps = 360//quality
- for i in range(steps):
- rad = radians(quality*i)
- vertices.append(radius*cos(rad)+j)
- vertices.append(radius*sin(rad)+k)
- #Close the ball
- vertices.append(radius*cos(0)+j)
- vertices.append(radius*sin(0)+k)
- #Create the mesh
- vertexNum = steps+2
- self.mesh = vertex_list(vertexNum, ('v2f', vertices),
- ('c3B', color*vertexNum ))
- #Create the physical mesh
- moment = pymunk.moment_for_circle(mass, radius, 5, offset=(0, 0))
- self.body = pymunk.Body(mass, moment)
- self.mesh_physic = pymunk.Circle(self.body, radius)
- self.mesh_physic.friction = friction
- self.body.position = j,k
- def draw(self):
- #Update vertex position (Note that this is extremely unoptimized)
- j, k = self.body.position
- vertices = [j, k]
- steps = 360//self.quality
- for i in range(steps):
- rad = radians(self.quality*i)
- vertices.append(self.radius*cos(rad)+j)
- vertices.append(self.radius*sin(rad)+k)
- vertices.append(self.radius*cos(0)+j)
- vertices.append(self.radius*sin(0)+k)
- self.mesh.vertices = vertices
- self.mesh.draw(gl.GL_TRIANGLE_FAN)
- self.life -= 1
- def registerPhysicSpace(self, space):
- space.add(self.body, self.mesh_physic)
- class Game(Window):
- def __init__(self, **kwargs):
- super(Game, self).__init__(**kwargs)
- self.space = pymunk.Space()
- self.space.gravity = Vec2d(0.0, -900.0)
- self.dynamics = [] #List of dynamics object on scene
- self.statics = [] #List of static obejct on screen.
- self.background = None #Background
- self.initGame()
- self.set_visible(True)
- def initGame(self):
- sqrt = lambda w,x,y,z: (w,z, y,z, y,x, w,x)
- w, h = self.width, self.height
- #A clock object to print the current fps on screen
- self.fps_display = clock.ClockDisplay()
- #Create a 2D square to fill the window background
- #And a red square to indicates where the ball will appear.
- vertices = sqrt(0,0, w,h), sqrt(35,h-20, 40,h-25)
- white, red = [255, 255, 255], [255,0,0]
- self.background = vertex_list(4, ('v2i/static', vertices[0]),
- ('c3B/static', white*4 ))
- self.spawner = vertex_list(4, ("v2i/static",vertices[1]),
- ("c3B/static", red*4))
- #Init the static lines
- body = pymunk.Body()
- line1 = Line((10, h-50), (w-100, h-100), body)
- line2 = Line((100, h-260), (w-10, h-150), body)
- line3 = Line((10, h-320), (w-80, h-390), body)
- line4 = Line((80, h-500), (w-10, h-470), body)
- line5 = Line((10, h), (10, 0), body)
- line6 = Line((w-10, h), (w-10, 0), body)
- self.statics = [line1, line2, line3, line4, line5, line6]
- for i in self.statics:
- i.registerPhysicSpace(self.space)
- def update(self, i):
- dt = 1.0/30.0
- self.space.step(dt) #Physics steps
- self.on_draw()
- #Remove dead objects
- self.dynamics = [x for x in self.dynamics if x.life>0]
- def on_draw(self):
- #Clean the elements previously drawn.
- self.clear()
- #Draw simple vertex array
- self.background.draw(gl.GL_QUADS)
- self.spawner.draw(gl.GL_QUADS)
- self.fps_display.draw()
- #Draw the static objects
- for obj in self.statics:
- obj.draw()
- #Draw the dynamics objects
- for obj in self.dynamics:
- obj.draw()
- def on_key_press(self, symbol, modifiers):
- h = self.height
- #Spawn a ball when space is pressed
- if symbol == key.SPACE:
- radius = randint(8, 20) #Create a random sized radius for the ball
- color = choice(([255,0,0], [255,0,255], [0,255,255], [0,0,255],
- [255, 255, 0], [0,255,0]))
- b = Ball((35,h-20), radius, color = color, life = 800)
- b.registerPhysicSpace(self.space)
- self.dynamics.append(b)
- if __name__ == "__main__":
- w = Game(width=500, height=500,
- caption="Pymunk Test", visible=False)
- clock.schedule_interval(w.update, 1.0/45.0)
- app.run()
Advertisement
Add Comment
Please, Sign In to add comment