Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #/usr/bin/env python
- import math
- import sys
- from Box2D import *
- from PyQt4.QtCore import *
- from PyQt4.QtGui import *
- BODYCOUNT = 100
- TIMESTEP = 1.0 / 30.0
- FRAME_RATE = 60
- DEGTORAD = 2.0 * math.pi / 360.0
- RADTODEG = 1.0 / DEGTORAD
- DENSITY = 1.0
- FRICTION = 0.3
- RESTITUTION = 0.3
- class QGraphicsBox2DPolygonItem(QGraphicsPolygonItem):
- def __init__(self, world, parent=None):
- super(QGraphicsBox2DPolygonItem, self).__init__(parent)
- self.world = world
- self.body = 0
- def setup(self):
- # Create body with start-up position and rotation
- bodyDef = b2BodyDef()
- bodyDef.position = (self.x(), -self.y())
- bodyDef.angle = -self.rotation() * DEGTORAD
- self.body = self.world.CreateBody(bodyDef)
- # Assign shape to polygon body
- shapeDef = b2PolygonDef()
- shapeDef.density = DENSITY
- shapeDef.friction = FRICTION
- shapeDef.restitution = RESTITUTION
- vertices = [(vertex.x(), -vertex.y()) for vertex in self.polygon()]
- shapeDef.setVertices(vertices)
- self.body.CreateShape(shapeDef)
- # Setup default mass
- self.body.SetMassFromShapes()
- def adjust(self):
- """Update QGraphicsItem's position and rotation from body."""
- (x, y) = self.body.GetPosition()
- angle = self.body.GetAngle()
- self.setPos(x, -y)
- self.setRotation(-angle * RADTODEG)
- class Simulator(QObject):
- def __init__(self, scene, parent=None):
- super(Simulator, self).__init__(parent)
- self.timerId = 0
- self.bodyItems = []
- # Define world, gravity, doSleep
- worldAABB = b2AABB()
- worldAABB.lowerBound = (-200, -100)
- worldAABB.upperBound = (200, 500)
- gravity = (0.0, -10.0)
- self.world = b2World(worldAABB, gravity, True)
- # Background item (not part of b2 world)
- backBlock = scene.addRect(-100, -40, 200, 60)
- backBlock.setBrush(QColor(93, 83, 37))
- backBlock.setZValue(-1)
- backBlock.setPen(QPen(Qt.black, 1))
- bodyDef = b2BodyDef()
- shapeDef = b2PolygonDef()
- # Rigid ground item
- groundItem = scene.addRect(-100, -10, 200, 20)
- groundItem.setParentItem(backBlock)
- groundItem.setBrush(QColor(178, 192, 160))
- groundItem.setPos(0, 10)
- groundItem.setPen(QPen(Qt.NoPen))
- bodyDef.position = (0.0, -10)
- shapeDef.SetAsBox(100.0, 10.0)
- groundBody = self.world.CreateBody(bodyDef)
- groundBody.CreateShape(shapeDef)
- # Rigid left and right block items
- for (x, y) in ((-95, -25), (95, -25)):
- blockItem = scene.addRect(-5, -15, 10, 45)
- blockItem.setParentItem(backBlock)
- blockItem.setPen(QPen(Qt.NoPen))
- blockItem.setBrush(QColor(178, 192, 160))
- blockItem.setPos(x, y)
- bodyDef.position = (x, 20.0)
- shapeDef.SetAsBox(5.0, 20.0)
- body = self.world.CreateBody(bodyDef)
- body.CreateShape(shapeDef)
- # Rigid elllipse item * 3
- for (x, y) in ((0, -55), (-30, -50), (30, -50)):
- ellipse = scene.addEllipse(-5, -5, 10, 10)
- ellipse.setPos(x, y)
- ellipse.setPen(QPen(Qt.NoPen))
- ellipse.setBrush(Qt.black)
- bodyDef.position = (x, -y)
- ellipseDef = b2CircleDef()
- ellipseDef.radius = 5
- ellipseBody = self.world.CreateBody(bodyDef)
- ellipseBody.CreateShape(ellipseDef)
- # Create lots of little triangles with random pos, rotation, color
- geometry = QPolygonF()
- for (x, y) in ((0, -10), (-5, 0), (5, 0)):
- geometry << QPointF(x, y)
- for i in range(BODYCOUNT):
- polygon = QGraphicsBox2DPolygonItem(self.world)
- polygon.setPos(-20 + qrand() % 40, -75 - qrand() % 150)
- polygon.setRotation(qrand() % 360)
- polygon.setPolygon(geometry)
- polygon.setBrush(QColor(128 + qrand() % 128,
- 128 + qrand() % 128,
- 128 + qrand() % 128))
- polygon.setup()
- scene.addItem(polygon)
- self.bodyItems.append(polygon)
- def start(self):
- if self.timerId == 0:
- self.timerId = self.startTimer(1000.0 / FRAME_RATE)
- def timerEvent(self, event):
- if event.timerId() == self.timerId:
- self.world.Step(TIMESTEP, 10, 8)
- for body in self.bodyItems:
- body.adjust()
- QObject.timerEvent(self, event)
- def main():
- app = QApplication(sys.argv)
- qsrand(QTime().secsTo(QTime.currentTime()))
- scene = QGraphicsScene()
- scene.setItemIndexMethod(QGraphicsScene.NoIndex)
- scene.setBackgroundBrush(Qt.white)
- scene.setSceneRect(-110, -150, 220, 175)
- view = QGraphicsView(scene)
- view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
- view.setRenderHint(QPainter.Antialiasing)
- view.scale(2, 2)
- view.show()
- simulator = Simulator(scene)
- simulator.start()
- return app.exec_()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement