dberube4

Pyglet+PyMunk physic test

Sep 13th, 2013
546
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.81 KB | None | 0 0
  1. from pyglet.window import Window, key
  2. from pyglet.graphics import vertex_list
  3. from pyglet import app, gl, clock
  4.  
  5. import pymunk
  6. from pymunk import Vec2d
  7.  
  8. from math import cos, sin, radians
  9. from random import choice, randint
  10.  
  11. class Line(object):
  12.     '''
  13.    An object that bind drawing and physics of a static line.
  14.    '''
  15.     def __init__(self, start, end, body, color=[0,0,0], friction=0.2):
  16.         '''
  17.        start(suple): A tuple of 2D vertex coordinate. Start point of the line.
  18.        end(tuple): A tuple of 2D vertex coordinate. End point of the line.
  19.        body(pymunk.Body): Pymunk body object
  20.        color(list): List of [red green blue] in bytes. Color of the vertices.
  21.        friction(float): Friction for the physic.
  22.        '''
  23.        
  24.         vertices = (start[0], start[1], end[0], end[1])
  25.         self.mesh = vertex_list(2, ('v2i', vertices),
  26.                                    ('c3B', color*2 ))
  27.         self.mesh_physic = pymunk.Segment(body, start, end, 0.0)
  28.         self.friction = friction
  29.        
  30.     def registerPhysicSpace(self, space):
  31.         space.add(self.mesh_physic)
  32.        
  33.     def draw(self):
  34.         self.mesh.draw(gl.GL_LINES)
  35.        
  36.        
  37. class Ball(object):
  38.     '''
  39.    An object that bind drawing and physics of a ball.
  40.    '''
  41.     def __init__(self, center, radius, quality=14, angle=0, mass=10,
  42.                  life = 100, friction=0.5, color=[0,0,0]):
  43.         '''
  44.        center(tuple): A tuple for the center of the circle
  45.        radius(float or int): Radius of the circle
  46.        quality(int or float): Quality of the circle (the smaller the better)
  47.        angle(int): Angle of the pysical mesh in degree
  48.        mass(int): Mass of the physical mesh
  49.        life(int): Time (in fps) of life for the object.
  50.        friction(float): Friction for the physical mesh
  51.        color(list): Color of the mesh.
  52.        '''
  53.         j, k = center[0], center[1]
  54.         vertices = [j, k] #Center of the ball
  55.        
  56.         self.quality = quality
  57.         self.radius = radius
  58.         self.life = life
  59.        
  60.         #Calculate vertex positions.
  61.         steps = 360//quality
  62.         for i in range(steps):
  63.             rad = radians(quality*i)
  64.             vertices.append(radius*cos(rad)+j)
  65.             vertices.append(radius*sin(rad)+k)
  66.        
  67.         #Close the ball
  68.         vertices.append(radius*cos(0)+j)
  69.         vertices.append(radius*sin(0)+k)
  70.        
  71.         #Create the mesh
  72.         vertexNum = steps+2
  73.         self.mesh = vertex_list(vertexNum, ('v2f', vertices),
  74.                                    ('c3B', color*vertexNum ))
  75.                                    
  76.         #Create the physical mesh
  77.         moment = pymunk.moment_for_circle(mass, radius, 5, offset=(0, 0))
  78.         self.body = pymunk.Body(mass, moment)
  79.        
  80.         self.mesh_physic = pymunk.Circle(self.body, radius)
  81.         self.mesh_physic.friction = friction
  82.         self.body.position = j,k
  83.    
  84.     def draw(self):
  85.        
  86.         #Update vertex position (Note that this is extremely unoptimized)
  87.         j, k = self.body.position
  88.         vertices = [j, k]
  89.         steps = 360//self.quality
  90.         for i in range(steps):
  91.             rad = radians(self.quality*i)
  92.             vertices.append(self.radius*cos(rad)+j)
  93.             vertices.append(self.radius*sin(rad)+k)
  94.        
  95.         vertices.append(self.radius*cos(0)+j)
  96.         vertices.append(self.radius*sin(0)+k)
  97.        
  98.         self.mesh.vertices = vertices
  99.        
  100.         self.mesh.draw(gl.GL_TRIANGLE_FAN)
  101.        
  102.         self.life -= 1
  103.            
  104.     def registerPhysicSpace(self, space):
  105.         space.add(self.body, self.mesh_physic)    
  106.  
  107. class Game(Window):
  108.    
  109.     def __init__(self, **kwargs):
  110.         super(Game, self).__init__(**kwargs)
  111.        
  112.         self.space = pymunk.Space()
  113.         self.space.gravity = Vec2d(0.0, -900.0)
  114.        
  115.         self.dynamics = [] #List of dynamics object on scene
  116.         self.statics = [] #List of static obejct on screen.
  117.         self.background = None #Background
  118.         self.initGame()        
  119.        
  120.         self.set_visible(True)
  121.        
  122.     def initGame(self):
  123.        
  124.         sqrt = lambda w,x,y,z: (w,z, y,z, y,x, w,x)
  125.         w, h = self.width, self.height
  126.        
  127.         #A clock object to print the current fps on screen
  128.         self.fps_display = clock.ClockDisplay()
  129.        
  130.         #Create a 2D square to fill the window background
  131.         #And a red square to indicates where the ball will appear.
  132.         vertices = sqrt(0,0, w,h), sqrt(35,h-20, 40,h-25)
  133.         white, red = [255, 255, 255], [255,0,0]
  134.         self.background = vertex_list(4, ('v2i/static', vertices[0]),
  135.                                          ('c3B/static', white*4 ))
  136.         self.spawner = vertex_list(4, ("v2i/static",vertices[1]),
  137.                                       ("c3B/static", red*4))
  138.        
  139.         #Init the static lines
  140.         body = pymunk.Body()
  141.         line1 = Line((10, h-50), (w-100, h-100), body)
  142.         line2 = Line((100, h-260), (w-10, h-150), body)
  143.         line3 = Line((10, h-320), (w-80, h-390), body)
  144.         line4 = Line((80, h-500), (w-10, h-470), body)
  145.         line5 = Line((10, h), (10, 0), body)
  146.         line6 = Line((w-10, h), (w-10, 0), body)
  147.         self.statics = [line1, line2, line3, line4, line5, line6]
  148.         for i in self.statics:
  149.             i.registerPhysicSpace(self.space)
  150.            
  151.     def update(self, i):
  152.         dt = 1.0/30.0
  153.         self.space.step(dt) #Physics steps
  154.         self.on_draw()
  155.        
  156.         #Remove dead objects
  157.         self.dynamics = [x for x in self.dynamics if x.life>0]
  158.        
  159.     def on_draw(self):
  160.        
  161.         #Clean the elements previously drawn.
  162.         self.clear()
  163.        
  164.         #Draw simple vertex array
  165.         self.background.draw(gl.GL_QUADS)
  166.         self.spawner.draw(gl.GL_QUADS)
  167.         self.fps_display.draw()
  168.        
  169.         #Draw the static objects
  170.         for obj in self.statics:
  171.             obj.draw()
  172.        
  173.         #Draw the dynamics objects
  174.         for obj in self.dynamics:
  175.             obj.draw()
  176.        
  177.     def on_key_press(self, symbol, modifiers):
  178.         h = self.height
  179.        
  180.         #Spawn a ball when space is pressed
  181.         if symbol == key.SPACE:
  182.             radius = randint(8, 20)    #Create a random sized radius for the ball
  183.             color = choice(([255,0,0], [255,0,255], [0,255,255], [0,0,255],
  184.                            [255, 255, 0], [0,255,0]))
  185.            
  186.             b = Ball((35,h-20), radius, color = color, life = 800)
  187.             b.registerPhysicSpace(self.space)
  188.             self.dynamics.append(b)
  189.        
  190. if __name__ == "__main__":
  191.     w = Game(width=500, height=500,
  192.              caption="Pymunk Test", visible=False)
  193.     clock.schedule_interval(w.update, 1.0/45.0)
  194.     app.run()
Advertisement
Add Comment
Please, Sign In to add comment