Advertisement
Guest User

PyQt + PyBox2D

a guest
Jan 11th, 2011
372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.20 KB | None | 0 0
  1. #/usr/bin/env python
  2.  
  3. import math
  4. import sys
  5. from Box2D import *
  6. from PyQt4.QtCore import *
  7. from PyQt4.QtGui import *
  8.  
  9.  
  10. BODYCOUNT = 100
  11. TIMESTEP = 1.0 / 30.0
  12. FRAME_RATE = 60
  13.  
  14. DEGTORAD = 2.0 * math.pi / 360.0
  15. RADTODEG = 1.0 / DEGTORAD
  16.  
  17. DENSITY = 1.0
  18. FRICTION = 0.3
  19. RESTITUTION = 0.3
  20.  
  21.  
  22. class QGraphicsBox2DPolygonItem(QGraphicsPolygonItem):
  23.     def __init__(self, world, parent=None):
  24.         super(QGraphicsBox2DPolygonItem, self).__init__(parent)
  25.  
  26.         self.world = world
  27.         self.body = 0
  28.  
  29.     def setup(self):
  30.         # Create body with start-up position and rotation
  31.         bodyDef = b2BodyDef()
  32.         bodyDef.position = (self.x(), -self.y())
  33.         bodyDef.angle = -self.rotation() * DEGTORAD
  34.         self.body = self.world.CreateBody(bodyDef)
  35.  
  36.         # Assign shape to polygon body
  37.         shapeDef = b2PolygonDef()
  38.         shapeDef.density = DENSITY
  39.         shapeDef.friction = FRICTION
  40.         shapeDef.restitution = RESTITUTION
  41.  
  42.         vertices = [(vertex.x(), -vertex.y()) for vertex in self.polygon()]
  43.         shapeDef.setVertices(vertices)
  44.  
  45.         self.body.CreateShape(shapeDef)
  46.  
  47.         # Setup default mass
  48.         self.body.SetMassFromShapes()
  49.  
  50.     def adjust(self):
  51.         """Update QGraphicsItem's position and rotation from body."""
  52.         (x, y) = self.body.GetPosition()
  53.         angle = self.body.GetAngle()
  54.         self.setPos(x, -y)
  55.         self.setRotation(-angle * RADTODEG)
  56.  
  57.  
  58. class Simulator(QObject):
  59.     def __init__(self, scene, parent=None):
  60.         super(Simulator, self).__init__(parent)
  61.         self.timerId = 0
  62.         self.bodyItems = []
  63.  
  64.         # Define world, gravity, doSleep
  65.         worldAABB = b2AABB()
  66.         worldAABB.lowerBound = (-200, -100)
  67.         worldAABB.upperBound = (200, 500)
  68.         gravity = (0.0, -10.0)
  69.         self.world = b2World(worldAABB, gravity, True)
  70.  
  71.         # Background item (not part of b2 world)
  72.         backBlock = scene.addRect(-100, -40, 200, 60)
  73.         backBlock.setBrush(QColor(93, 83, 37))
  74.         backBlock.setZValue(-1)
  75.         backBlock.setPen(QPen(Qt.black, 1))
  76.  
  77.         bodyDef = b2BodyDef()
  78.         shapeDef = b2PolygonDef()
  79.  
  80.         # Rigid ground item
  81.         groundItem = scene.addRect(-100, -10, 200, 20)
  82.         groundItem.setParentItem(backBlock)
  83.         groundItem.setBrush(QColor(178, 192, 160))
  84.         groundItem.setPos(0, 10)
  85.         groundItem.setPen(QPen(Qt.NoPen))
  86.         bodyDef.position = (0.0, -10)
  87.         shapeDef.SetAsBox(100.0, 10.0)
  88.         groundBody = self.world.CreateBody(bodyDef)
  89.         groundBody.CreateShape(shapeDef)
  90.  
  91.         # Rigid left and right block items
  92.         for (x, y) in ((-95, -25), (95, -25)):
  93.             blockItem = scene.addRect(-5, -15, 10, 45)
  94.             blockItem.setParentItem(backBlock)
  95.             blockItem.setPen(QPen(Qt.NoPen))
  96.             blockItem.setBrush(QColor(178, 192, 160))
  97.             blockItem.setPos(x, y)
  98.             bodyDef.position = (x, 20.0)
  99.             shapeDef.SetAsBox(5.0, 20.0)
  100.             body = self.world.CreateBody(bodyDef)
  101.             body.CreateShape(shapeDef)
  102.  
  103.         # Rigid elllipse item * 3
  104.         for (x, y) in ((0, -55), (-30, -50), (30, -50)):
  105.             ellipse = scene.addEllipse(-5, -5, 10, 10)
  106.             ellipse.setPos(x, y)
  107.             ellipse.setPen(QPen(Qt.NoPen))
  108.             ellipse.setBrush(Qt.black)
  109.             bodyDef.position = (x, -y)
  110.             ellipseDef = b2CircleDef()
  111.             ellipseDef.radius = 5
  112.             ellipseBody = self.world.CreateBody(bodyDef)
  113.             ellipseBody.CreateShape(ellipseDef)
  114.  
  115.         # Create lots of little triangles with random pos, rotation, color
  116.         geometry = QPolygonF()
  117.         for (x, y) in ((0, -10), (-5, 0), (5, 0)):
  118.             geometry << QPointF(x, y)
  119.         for i in range(BODYCOUNT):
  120.             polygon = QGraphicsBox2DPolygonItem(self.world)
  121.             polygon.setPos(-20 + qrand() % 40, -75 - qrand() % 150)
  122.             polygon.setRotation(qrand() % 360)
  123.             polygon.setPolygon(geometry)
  124.             polygon.setBrush(QColor(128 + qrand() % 128,
  125.                                     128 + qrand() % 128,
  126.                                     128 + qrand() % 128))
  127.             polygon.setup()
  128.             scene.addItem(polygon)
  129.             self.bodyItems.append(polygon)
  130.  
  131.     def start(self):
  132.         if self.timerId == 0:
  133.             self.timerId = self.startTimer(1000.0 / FRAME_RATE)
  134.  
  135.     def timerEvent(self, event):
  136.         if event.timerId() == self.timerId:
  137.             self.world.Step(TIMESTEP, 10, 8)
  138.             for body in self.bodyItems:
  139.                 body.adjust()
  140.  
  141.         QObject.timerEvent(self, event)
  142.  
  143.  
  144. def main():
  145.     app = QApplication(sys.argv)
  146.  
  147.     qsrand(QTime().secsTo(QTime.currentTime()))
  148.  
  149.     scene = QGraphicsScene()
  150.     scene.setItemIndexMethod(QGraphicsScene.NoIndex)
  151.     scene.setBackgroundBrush(Qt.white)
  152.     scene.setSceneRect(-110, -150, 220, 175)
  153.  
  154.     view = QGraphicsView(scene)
  155.     view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
  156.     view.setRenderHint(QPainter.Antialiasing)
  157.     view.scale(2, 2)
  158.     view.show()
  159.  
  160.     simulator = Simulator(scene)
  161.     simulator.start()
  162.  
  163.     return app.exec_()
  164.  
  165.  
  166. if __name__ == '__main__':
  167.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement