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, text
- import pymunk
- from pymunk import Vec2d
- class StaticLine(object):
- '''
- An object that bind drawing and physics of a static line.
- '''
- def __init__(self, start, end, body, color=[0,0,0], friction=0.0):
- '''
- 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 Box():
- '''
- An object that bind the physics and the drawing of a box.
- Also add drags options
- '''
- def __init__(self,start,size,color=[0,0,0],friction=0.0,
- mass=None, life = -1):
- '''
- start(tuple): The coordinates of the top left vertex
- size(tuple): The width and the height of the box
- color(lits): A list of 3 BYTE. Color of the mesh vertices
- friction(float): Friction of the object
- mass(int): Mass of the object
- life(int): Number of game tick the object should live (-1 for infinite)
- '''
- #Calculate vertices position
- x,y = start
- w,h = size
- v = (x,y, x+w,y, x+w,y+h, x,y+h)
- self.mesh = vertex_list(4, ('v2f', v),
- ('c3B', color*4 ))
- #Physical mesh
- v = [(x,y), (x+w,y), (x+w,y+h)]
- moment = pymunk.moment_for_box(mass, w, h)
- self.body = pymunk.Body(mass, moment)
- self.mesh_physic = pymunk.Poly.create_box(self.body, (w,h))
- self.mesh_physic.friction = friction
- self.body.position = x+w/2, y+h/2
- #Property
- self.mesh_pos = x+w/2, y+h/2
- self.width = size[0]
- self.height = size[1]
- def draw(self):
- #Update vertices position
- p = self.body.position
- dt = p[0]-self.mesh_pos[0], p[1]-self.mesh_pos[1]
- for i in range(4):
- self.mesh.vertices[i*2] += dt[0]
- self.mesh.vertices[i*2+1] += dt[1]
- self.mesh_pos = p[0],p[1]
- self.mesh.draw(gl.GL_QUADS)
- 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)
- #Static for non-moving physic object and dynamics for moving.
- self.statics = []
- self.dynamics = []
- 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
- #Properties to drag objects
- self.dragged_object = None
- self.drag_offset = (0,0)
- self.mouse_pos = (0,0)
- #A clock object to print the current fps on screen
- self.fps_display = clock.ClockDisplay()
- #Create a square to fill the window background
- vertices = sqrt(0,0, w,h)
- white = [255, 255, 255]
- self.background = vertex_list(4, ('v2i/static', vertices),
- ('c3B/static', white*4 ))
- #A label title
- self.title = text.Label('DRAG & DROP!',
- font_name='Arial',
- font_size=36,color=(0,0,0,100),
- x=w//2, y=h-h//5,
- anchor_x='center', anchor_y='center')
- #Limits & other Lines
- body = pymunk.Body()
- l1 = StaticLine((2,2), (w-2,2), body)
- l2 = StaticLine((2,2), (2,h-2), body)
- l3 = StaticLine((w-2,2), (w-2,h-2), body)
- l4 = StaticLine((2,h-2), (w-2,h-2), body)
- l5 = StaticLine((50,h-190), (180,h-240), body)
- l6 = StaticLine((350,h-200), (350,h-290), body)
- l7 = StaticLine((430,h-200), (430,h-290), body)
- l8 = StaticLine((350,h-290), (430,h-290), body)
- self.statics = [l1,l2,l3,l4,l5,l6,l7,l8]
- for obj in self.statics:
- obj.registerPhysicSpace(self.space)
- #Dynamics objects
- box1 = Box((350,100),(50,50), color=[0,70,255], mass=1)
- box2 = Box((180,80),(30,30), color=[255,0,255], mass=1)
- box3 = Box((230,140),(70,70), color=[255,70,0], mass=1)
- self.dynamics = [box1, box2, box3]
- for obj in self.dynamics:
- obj.registerPhysicSpace(self.space)
- def update(self, dt):
- dt = 1.0/60.0
- self.space.step(dt) #Physics steps
- self.on_draw()
- def on_mouse_press(self, x, y, button, mod):
- self.mouse_pos = (x,y)
- #Check if a dynamic object is in the clicked space:
- for i in self.dynamics:
- maxX = i.mesh.vertices[0]+ i.width
- maxY = i.mesh.vertices[1]+ i.height
- if x >= i.mesh.vertices[0] and y >=i.mesh.vertices[1]:
- if x <= maxX and y <= maxY:
- self.dragged_object = i
- #Get where the cursor clicked on the object
- center = i.width//2, i.height//2
- of_x = -(x-maxX+center[0])
- of_y = -(y-maxY+center[1])
- print(of_y)
- self.drag_offset = of_x,of_y
- def on_mouse_release(self, x, y, button, mod):
- self.mouse_pos = (x,y)
- self.dragged_object = None
- def on_mouse_drag(self, x,y, dx,dy, buttons, mod):
- self.mouse_pos = (x,y)
- if self.dragged_object:
- body = self.dragged_object.body
- body.position.x = self.mouse_pos[0]+self.drag_offset[0]
- body.position.y = self.mouse_pos[1]+self.drag_offset[1]
- #Communicate the cursor velocity to the object
- self.dragged_object.body.velocity += (dx*3, dy*3)
- if dx > -2 and dx <2:
- self.dragged_object.body.velocity.x = 0
- if dy > -2 and dy <2:
- self.dragged_object.body.velocity.y = 0
- def on_draw(self):
- #Clean the elements previously drawn.
- self.clear()
- self.background.draw(gl.GL_QUADS)
- self.title.draw()
- #Check the dragged object position
- if self.dragged_object:
- body = self.dragged_object.body
- body.position.x = self.mouse_pos[0]+self.drag_offset[0]
- body.position.y = self.mouse_pos[1]+self.drag_offset[1]
- for i in self.statics:
- i.draw()
- for i in self.dynamics:
- i.draw()
- self.fps_display.draw()
- if __name__ == '__main__':
- w = Game(caption="Drag&Drop Test", width=500, height=500, visible=False)
- clock.schedule_interval(w.update, 1.0/60.0)
- app.run()
Advertisement
Add Comment
Please, Sign In to add comment