class RageTracks(ShowBase): def __init__(self): ShowBase.__init__(self) base.setFrameRateMeter(True) # base.disableMouse() # initialise the lights alight = AmbientLight('alight') alight.setColor(VBase4(0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) render.setLight(alnp) # Initialise the Ode world self.world = OdeWorld() self.world.setGravity(0, 0, -9.81) # load the models # environment self.environ = self.loader.loadModel("data/models/Plane") # Reparent the model to render. self.environ.reparentTo(self.render) # Apply scale and position transforms on the model. self.environ.setScale(10, 10, 10) self.environ.setPos(0, 0, 0) # racer self.glider = self.loader.loadModel("data/models/vehicle01") # Reparent the model to render. self.glider.reparentTo(self.render) # Apply scale and position transforms on the model. self.glider.setScale(1, 1, 1) self.glider.setPos(0, 0, 50) self.myBody = OdeBody(self.world) self.myBody.setPosition(self.glider.getPos(render)) self.myBody.setQuaternion(self.glider.getQuat(render)) self.myMass = OdeMass() self.myMass.setBox(11340, 1, 1, 1) self.myBody.setMass(self.myMass) # set up the camera base.camera.reparentTo(self.glider) base.camera.setPos(0, -30, 10) base.camera.lookAt(self.glider) # add physics to taskmgr taskMgr.add(self.physicsTask, 'physics') def physicsTask(self, task): # Step the simulation and set the new positions self.world.quickStep(globalClock.getDt()) # set new positions self.glider.setPosQuat(render, self.myBody.getPosition(), Quat(self.myBody.getQuaternion())) return task.cont
class Game(): HUD_TEXT_SCALE = 0.04 UPDATE_RATE = 1/60.0 def __init__(self): base.disableMouse() base.camera.setPos(0,0,640) base.camera.lookAt(0,0,0) self.loadPhysics() self.loadLights() #map x boundary, map y boundary, amount of pylons self.map = Map(self, 160.0, 160.0, 7) # self.Base1 = Base(self) # self.Base1.setPos( Vec3( 0, 50, 0)) # self.Base2 = Base(self) # self.Base2.setPos( Vec3( 0, -50, 0)) #self.Base2 = Base(self) # self.wall1 = StaticObject.bigWall(self) # self.wall1.setPos( Vec3( 50, (-50), 0) ) # self.wall1.setRotation( 90 ) # # self.wall2 = StaticObject.bigWall(self) # self.wall2.setPos( Vec3( 50, 0, 0) ) # self.wall2.setRotation( 90 ) #alustaa tyhjan listan self.shipList = [] self.ship1 = ShipTypes.Ship_2(self, Vec4(1.0, 1.0, 1.0, 0)) self.ship2 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0)) self.LoadHUD() #lisataan alukset listaan self.ship1.addToShipList(self.shipList) self.ship2.addToShipList(self.shipList) ##katsotaan saako toimimaan listana gamelooppiin -- saa ##self.shipList = [self.ship1, self.ship2] self.ship2.setPos( Vec3(10, 10, 0) ) self.setKeys() self.collectibleList = [] self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo.setPos( Vec3(0, 20, 0) ) self.pallo.addToCollectibleList(self.collectibleList) self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo2.setPos( Vec3(30, 20, 0) ) self.pallo2.addToCollectibleList(self.collectibleList) #self.collectibleList = [self.pallo, self.pallo2] # self.pylonList = [] # self.pylon1 = Pylon(self, 100) # self.pylon1.setPos( Vec3(-30, 20, 0) ) # self.pylon1.addToPylonList(self.pylonList) # self.pylon2 = Pylon(self, -100) # self.pylon2.setPos( Vec3(-30, -20, 0) ) # self.pylon2.addToPylonList(self.pylonList) # self.makeBoundaryWalls( 50.0, 50.0, 50.0) base.setBackgroundColor(0,0,0.0,0) taskMgr.add(self.loop, 'game loop') run() def setKeys(self): base.accept('arrow_up', self.ship1.thrustOn) base.accept('arrow_up-up', self.ship1.thrustOff) base.accept('arrow_left', self.ship1.thrustLeftOn) base.accept('arrow_left-up', self.ship1.thrustLeftOff) base.accept('arrow_right', self.ship1.thrustRightOn) base.accept('arrow_right-up', self.ship1.thrustRightOff) base.accept('arrow_down', self.ship1.thrustBackOn) base.accept('arrow_down-up', self.ship1.thrustBackOff) base.accept('rshift', self.ship1.releaseBall) base.accept('w', self.ship2.thrustOn) base.accept('w-up', self.ship2.thrustOff) base.accept('a', self.ship2.thrustLeftOn) base.accept('a-up', self.ship2.thrustLeftOff) base.accept('d', self.ship2.thrustRightOn) base.accept('d-up', self.ship2.thrustRightOff) base.accept('s', self.ship2.thrustBackOn) base.accept('s-up', self.ship2.thrustBackOff) base.accept('q', self.ship2.releaseBall) def loadPhysics(self): self.physicsWorld = OdeWorld() self.physicsWorld.initSurfaceTable(1) self.physicsWorld.setSurfaceEntry( 0, 0, 1.0, # u 0.35, # elasticity 0.01, # minimum threshold for physical movement 0.01, 0.00000001, # softening 0.01, 0.01 # damping ) self.physicsWorld.setGravity(0, 0, 0) self.physicsSpace = OdeHashSpace() self.physicsSpace.setAutoCollideWorld(self.physicsWorld) self.contactGroup = OdeJointGroup() self.physicsSpace.setAutoCollideJointGroup(self.contactGroup) def LoadHUD(self): # self.player1HUD = OnscreenText( # text = "Player 1: " + str( self.ship1.getPoints() ), # fg = (1,1,1,1), # #pos = ( x, y ) # pos = (0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) # self.player2HUD = OnscreenText( # text = "Player 2: " + str( self.ship2.getPoints() ), # fg = (1,1,1,1), # pos = (-0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) self.winnerText = OnscreenText( text = "Tekstia, tekstia, tekstia", fg = (1,1,1,1), pos = (-0.25, 0), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.winnerText.hide() # def updateHUD(self): # self.player1HUD = OnscreenText( # text = "Player 1: " + str( self.ship1.getPoints() ), # fg = (1,1,1,1), # pos = (0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) # self.player2HUD = OnscreenText( # text = "Player 2: " + str( self.ship2.getPoints() ), # fg = (1,1,1,1), # pos = (-0.5,0.6), # align = TextNode.ALeft, # scale = Game.HUD_TEXT_SCALE # ) def loadLights(self): light1 = DirectionalLight('light1') lightNode1 = render.attachNewNode(light1) light1.setDirection( Vec3(-1, 0.5, -0.25) ) light1.setColor( Vec4(0.5, 0.9, 0.9, 0) ) render.setLight(lightNode1) #checks all collectibles for possible collisions with ships def checkAllCollectibles(self): for collectible in self.collectibleList: collectible.hitShips(self.shipList) #updates all collectible positions def updateAllCollectibles(self): for collectible in self.collectibleList: collectible.update(Game.UPDATE_RATE) #apply forces to all collectibles ## def applyForceAllCollectibles(self): ## for collectible in self.collectibleList: ## collectible.applyForces() def applyForceAllShips(self): for ship in self.shipList: ship.applyForces() #updates all ship positions def updateAllShips(self): for ship in self.shipList: ship.update(Game.UPDATE_RATE) #checks all pylons for possible collisions with ships def checkAllPylons(self): for pylon in self.map.getPylonList(): pylon.checkCollisionList(self.shipList) def loop(self, task): self.applyForceAllShips() self.physicsSpace.autoCollide() self.checkAllCollectibles() self.map.getBase1().checkCollision(self.ship1) self.map.getBase2().checkCollision(self.ship2) self.checkAllPylons() self.physicsWorld.quickStep(Game.UPDATE_RATE) self.updateAllShips() self.updateAllCollectibles() self.contactGroup.empty() return task.cont
class MinigamePhysicsWorldBase: notify = DirectNotifyGlobal.directNotify.newCategory( 'MinigamePhysicsWorldBase') def __init__(self, canRender=0): self.canRender = canRender self.world = OdeWorld() self.space = OdeSimpleSpace() self.contactgroup = OdeJointGroup() self.bodyList = [] self.geomList = [] self.massList = [] self.rayList = [] self.showContacts = 0 self.jointMarkers = [] self.jointMarkerCount = 64 self.meshDataList = [] self.geomDataList = [] self.commonObjectInfoDict = {} self.maxColCount = 0 if self.canRender: self.odePandaRelationList = self.bodyList self.root = render.attachNewNode('physics root node') else: self.root = NodePath('physics root node') self.placerNode = self.root.attachNewNode('Placer') self.subPlacerNode = self.placerNode.attachNewNode('Placer Sub Node') self.commonObjectDict = {} self.commonId = 0 self.worldAttach = self.root.attachNewNode('physics geom attach point') self.timingCycleLength = 10.0 self.timingCycleOffset = 0.0 self.timingSimTime = 0.0 self.FPS = 60.0 self.DTAStep = 1.0 / self.FPS self.DTA = 0 self.useQuickStep = False self.deterministic = True self.numStepsInSimulateTask = 0 def delete(self): self.notify.debug('Max Collision Count was %s' % self.maxColCount) self.stopSim() self.commonObjectDict = None if self.canRender: for pair in self.odePandaRelationList: pair[0].removeNode() pair[1].destroy() self.odePandaRelationList = None else: for body in self.bodyList: body[1].destroy() self.bodyList = None for mass in self.massList: mass = None for geom in self.geomList: geom.destroy() geom = None for ray in self.rayList: ray.destroy() ray = None self.placerNode.removeNode() self.root.removeNode() for marker in self.jointMarkers: marker.removeNode() self.jointMarkers = None for data in self.geomDataList: data.destroy() for data in self.meshDataList: data.destroy() self.contactgroup.empty() self.world.destroy() self.space.destroy() self.world = None self.space = None def setupSimulation(self): if self.canRender: for count in xrange(self.jointMarkerCount): testMarker = render.attachNewNode('Joint Marker') ballmodel = loader.loadModel('phase_3/models/misc/sphere') ballmodel.reparentTo(testMarker) ballmodel.setScale(0.1) testMarker.setPos(0.0, 0.0, -100.0) self.jointMarkers.append(testMarker) def startSim(self): taskMgr.add(self.__simulationTask, 'simulation task') def stopSim(self): taskMgr.remove('simulation task') def __simulationTask(self, task): self.DTA += globalClock.getDt() numSteps = int(self.DTA / self.DTAStep) if numSteps > 10: self.notify.warning('phyics steps = %d' % numSteps) startTime = globalClock.getRealTime() while self.DTA >= self.DTAStep: if self.deterministic: OdeUtil.randSetSeed(0) self.DTA -= self.DTAStep self.preStep() self.simulate() self.postStep() if self.canRender: self.placeBodies() return task.cont def preStep(self): pass def postStep(self): if self.showContacts and self.canRender: for count in xrange(self.jointMarkerCount): pandaNodePathGeom = self.jointMarkers[count] if count < self.colCount: pandaNodePathGeom.setPos( self.space.getContactData(count * 3 + 0), self.space.getContactData(count * 3 + 1), self.space.getContactData(count * 3 + 2)) else: pandaNodePathGeom.setPos(0.0, 0.0, -100.0) def simulate(self): self.colCount = self.space.autoCollide() if self.maxColCount < self.colCount: self.maxColCount = self.colCount self.notify.debug('New Max Collision Count %s' % self.maxColCount) if self.useQuickStep: self.world.quickStep(self.DTAStep) else: self.world.step(self.DTAStep) for bodyPair in self.bodyList: self.world.applyDampening(self.DTAStep, bodyPair[1]) self.contactgroup.empty() self.timingSimTime = self.timingSimTime + self.DTAStep def placeBodies(self): for pair in self.odePandaRelationList: pandaNodePathGeom = pair[0] odeBody = pair[1] if pandaNodePathGeom: pandaNodePathGeom.setPos(odeBody.getPosition()) pandaNodePathGeom.setQuat( Quat(odeBody.getQuaternion()[0], odeBody.getQuaternion()[1], odeBody.getQuaternion()[2], odeBody.getQuaternion()[3])) def getOrderedContacts(self, count): c0 = self.space.getContactId(count, 0) c1 = self.space.getContactId(count, 1) if c0 > c1: chold = c1 c1 = c0 c0 = chold return (c0, c1)
class Game(): HUD_TEXT_SCALE = 0.04 UPDATE_RATE = 1/60.0 MAX_PYLON_POWER = 50 def __init__(self): self.zoomLevels = deque([640, 512, 320, 1280]) self.curLev = self.zoomLevels[0] base.disableMouse() self.initCam() self.loadPhysics() self.loadLights() #map x boundary, map y boundary, amount of pylons self.map = Map(self, 150.0, 150.0, 7) self.shipList = [] self.ship1 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0.0)) self.ship2 = ShipTypes.Ship_2(self, Vec4(0.0, 0.0, 0.6, 0.0)) self.ship1.setPos( Vec3(0, 120, 0) ) self.ship2.setPos( Vec3(0, -120, 0) ) self.shipList.append(self.ship1) self.shipList.append(self.ship2) self.LoadHUD() self.setKeys() self.collectibleList = [] self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo.setPos( Vec3(0, 20, 0) ) self.pallo.addToCollectibleList(self.collectibleList) #self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) #self.pallo2.setPos( Vec3(30, 20, 0) ) #self.pallo2.addToCollectibleList(self.collectibleList) b=OnscreenImage(parent=render2d, image="Geminid.jpg") base.cam.node().getDisplayRegion(0).setSort(20) base.setBackgroundColor(0,0,0.0,0) self.collisionSfx = loader.loadSfx("shipcollision.wav") self.goalSfx = loader.loadSfx("goal.wav") self.victorySfx = loader.loadSfx("victory.wav") self.collision2Sfx = loader.loadSfx("pyloncollision.wav") filters = CommonFilters(base.win, base.cam) render.setShaderAuto() taskMgr.add(self.loop, 'game loop') run() def setKeys(self): base.accept('arrow_up', self.ship1.thrustOn) base.accept('arrow_up-up', self.ship1.thrustOff) base.accept('arrow_left', self.ship1.thrustLeftOn) base.accept('arrow_left-up', self.ship1.thrustLeftOff) base.accept('arrow_right', self.ship1.thrustRightOn) base.accept('arrow_right-up', self.ship1.thrustRightOff) base.accept('arrow_down', self.ship1.thrustBackOn) base.accept('arrow_down-up', self.ship1.thrustBackOff) base.accept('rshift', self.ship1.releaseBall) base.accept('w', self.ship2.thrustOn) base.accept('w-up', self.ship2.thrustOff) base.accept('a', self.ship2.thrustLeftOn) base.accept('a-up', self.ship2.thrustLeftOff) base.accept('d', self.ship2.thrustRightOn) base.accept('d-up', self.ship2.thrustRightOff) base.accept('s', self.ship2.thrustBackOn) base.accept('s-up', self.ship2.thrustBackOff) base.accept('q', self.ship2.releaseBall) base.accept('+', self.zoom) base.accept('p', self.toggleAI) def loadPhysics(self): self.physicsWorld = OdeWorld() self.physicsWorld.initSurfaceTable(1) self.physicsWorld.setSurfaceEntry( 0, 0, 1.0, # u 0.35, # elasticity 0.01, # minimum threshold for physical movement 0.01, 0.00000001, # softening 0.01, 0.01 # damping ) self.physicsWorld.setGravity(0, 0, -20) self.physicsSpace = OdeHashSpace() self.physicsSpace.setAutoCollideWorld(self.physicsWorld) self.contactGroup = OdeJointGroup() self.physicsSpace.setAutoCollideJointGroup(self.contactGroup) def LoadHUD(self): self.player1HUD = OnscreenText( text = "Player 1: " + str( self.ship1.getPoints() ), fg = (1,1,1,1), #pos = ( x, y ) pos = (0.7,0.9), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.player2HUD = OnscreenText( text = "Player 2: " + str( self.ship2.getPoints() ), fg = (1,1,1,1), pos = (-0.7,0.9), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.winnerText = OnscreenText( text = "Tekstia, tekstia, tekstia", fg = (1,1,1,1), pos = (-0.2, 0), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE*3 ) # self.winnerText.setZ(200) self.winnerText.hide() def updateHUD(self): self.player1HUD.setText( "Player 1: " + str( self.ship1.getPoints() ) ) self.player2HUD.setText( "Player 2: " + str( self.ship2.getPoints() ) ) if (self.ship1.getPoints() > 9): self.winnerText.show() self.winnerText.setText( "Player 1 won " + str(self.ship1.getPoints()) + "-" + str(self.ship2.getPoints())) self.victorySfx.play() base.cam.node().getDisplayRegion(0).setSort(0) # self.Pause() if (self.ship2.getPoints() > 9): self.winnerText.show() self.winnerText.setText( "Player 2 won " + str(self.ship2.getPoints()) + "-" + str(self.ship1.getPoints())) self.victorySfx.play() base.cam.node().getDisplayRegion(0).setSort(0) def loadLights(self): light1 = DirectionalLight('light1') lightNode1 = render.attachNewNode(light1) light1.setDirection( Vec3(-1, 0.5, -0.25) ) light1.setColor( Vec4(0.6, 0.6, 0.6, 0) ) render.setLight(lightNode1) #checks all collectibles for possible collisions with ships def checkAllCollectibles(self, shipList): for collectible in self.collectibleList: collectible.hitShips(shipList) #updates all collectible positions def updateAllCollectibles(self): for collectible in self.collectibleList: collectible.update(Game.UPDATE_RATE) def applyForceAllShips(self, shipList): for ship in shipList: ship.applyForces() #updates all ship positions def updateAllShips(self, shipList): for ship in shipList: ship.update(Game.UPDATE_RATE) shipList[0].shipsCollide(shipList[1]) #checks all pylons for possible collisions with ships def checkAllPylons(self, pylonList, shipList): for pylon in pylonList: pylon.checkCollisionList(shipList) def loop(self, task): self.applyForceAllShips(self.shipList) self.physicsSpace.autoCollide() self.checkAllCollectibles(self.shipList) self.map.getBase1().checkCollision(self.ship1, self.collectibleList) self.map.getBase2().checkCollision(self.ship2, self.collectibleList) self.checkAllPylons(self.map.getPylonList(), self.shipList) self.physicsWorld.quickStep(Game.UPDATE_RATE) self.updateAllShips(self.shipList) self.updateAllCollectibles() self.contactGroup.empty() return task.cont def toggleAI(self): if taskMgr.hasTaskNamed('Simple AI'): taskMgr.remove('Simple AI') return taskMgr.add( self.chaseBallsAround, name='Simple AI', sort=None, extraArgs=(self.ship1, self.ship2, self.collectibleList, self.map.getBase1()), priority=None, uponDeath=None, appendTask=True, taskChain=None, owner=None) def chaseBallsAround(self, chaser, enemy, chaseList, base, task): pos = chaser.getPos() nearestNormedPos = 1e10000 #represents infinity nearestRelPos = [0,0] if chaser.hasBall(): chasePos = base.getPos() nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] elif enemy.hasBall(): chasePos = enemy.getPos() nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] else: for collectible in chaseList: chasePos = collectible.getPos() relPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] if (math.fabs(relPos[0]) + math.fabs(relPos[1])) < nearestNormedPos: nearestNormedPos = math.fabs(relPos[0]) + math.fabs(relPos[1]) nearestRelPos = relPos if nearestRelPos[0] > 0: chaser.thrustRightOff() chaser.thrustLeftOn() elif nearestRelPos[0] < 0: chaser.thrustLeftOff() chaser.thrustRightOn() if nearestRelPos[1] < 0: chaser.thrustBackOff() chaser.thrustOn() elif nearestRelPos[1] > 0: chaser.thrustOff() chaser.thrustBackOn() else: chaser.thrustOff() chaser.thrustBackOff() return task.cont def initCam(self): base.camera.setPos(0,0,self.curLev) base.camera.lookAt(0,0,0) def zoom(self): self.curLev = self.zoomLevels.popleft() base.camera.setPos(0, 0, self.curLev) self.zoomLevels.append(self.curLev) def shakeCam(self): taskMgr.add(self.shakeCamTask, name='ShakeCam') def shakeCamTask(self, task): oldPos = base.camera.getPos() base.camera.setPos(oldPos[0]+random.randint(-1, 1), oldPos[1]+random.randint(-1, 1), oldPos[2]+random.randint(-4, 4)) if task.time < 0.5: return task.cont self.initCam() return task.done
class MinigamePhysicsWorldBase: notify = DirectNotifyGlobal.directNotify.newCategory('MinigamePhysicsWorldBase') def __init__(self, canRender = 0): self.canRender = canRender self.world = OdeWorld() self.space = OdeSimpleSpace() self.contactgroup = OdeJointGroup() self.bodyList = [] self.geomList = [] self.massList = [] self.rayList = [] self.showContacts = 0 self.jointMarkers = [] self.jointMarkerCount = 64 self.meshDataList = [] self.geomDataList = [] self.commonObjectInfoDict = {} self.maxColCount = 0 if self.canRender: self.odePandaRelationList = self.bodyList self.root = render.attachNewNode('physics root node') else: self.root = NodePath('physics root node') self.placerNode = self.root.attachNewNode('Placer') self.subPlacerNode = self.placerNode.attachNewNode('Placer Sub Node') self.commonObjectDict = {} self.commonId = 0 self.worldAttach = self.root.attachNewNode('physics geom attach point') self.timingCycleLength = 10.0 self.timingCycleOffset = 0.0 self.timingSimTime = 0.0 self.FPS = 60.0 self.DTAStep = 1.0 / self.FPS self.DTA = 0 self.useQuickStep = False self.deterministic = True self.numStepsInSimulateTask = 0 def delete(self): self.notify.debug('Max Collision Count was %s' % self.maxColCount) self.stopSim() self.commonObjectDict = None if self.canRender: for pair in self.odePandaRelationList: pair[0].removeNode() pair[1].destroy() self.odePandaRelationList = None else: for body in self.bodyList: body[1].destroy() self.bodyList = None for mass in self.massList: mass = None for geom in self.geomList: geom.destroy() geom = None for ray in self.rayList: ray.destroy() ray = None self.placerNode.removeNode() self.root.removeNode() for marker in self.jointMarkers: marker.removeNode() self.jointMarkers = None for data in self.geomDataList: data.destroy() for data in self.meshDataList: data.destroy() self.contactgroup.empty() self.world.destroy() self.space.destroy() self.world = None self.space = None return def setupSimulation(self): if self.canRender: for count in range(self.jointMarkerCount): testMarker = render.attachNewNode('Joint Marker') ballmodel = loader.loadModel('phase_3/models/misc/sphere') ballmodel.reparentTo(testMarker) ballmodel.setScale(0.1) testMarker.setPos(0.0, 0.0, -100.0) self.jointMarkers.append(testMarker) def startSim(self): taskMgr.add(self.__simulationTask, 'simulation task') def stopSim(self): taskMgr.remove('simulation task') def __simulationTask(self, task): self.DTA += globalClock.getDt() numSteps = int(self.DTA / self.DTAStep) if numSteps > 10: self.notify.warning('phyics steps = %d' % numSteps) startTime = globalClock.getRealTime() while self.DTA >= self.DTAStep: if self.deterministic: OdeUtil.randSetSeed(0) self.DTA -= self.DTAStep self.preStep() self.simulate() self.postStep() if self.canRender: self.placeBodies() return task.cont def preStep(self): pass def postStep(self): if self.showContacts and self.canRender: for count in range(self.jointMarkerCount): pandaNodePathGeom = self.jointMarkers[count] if count < self.colCount: pandaNodePathGeom.setPos(self.space.getContactData(count * 3 + 0), self.space.getContactData(count * 3 + 1), self.space.getContactData(count * 3 + 2)) else: pandaNodePathGeom.setPos(0.0, 0.0, -100.0) def simulate(self): self.colCount = self.space.autoCollide() if self.maxColCount < self.colCount: self.maxColCount = self.colCount self.notify.debug('New Max Collision Count %s' % self.maxColCount) if self.useQuickStep: self.world.quickStep(self.DTAStep) else: self.world.step(self.DTAStep) for bodyPair in self.bodyList: self.world.applyDampening(self.DTAStep, bodyPair[1]) self.contactgroup.empty() self.timingSimTime = self.timingSimTime + self.DTAStep def placeBodies(self): for pair in self.odePandaRelationList: pandaNodePathGeom = pair[0] odeBody = pair[1] if pandaNodePathGeom: pandaNodePathGeom.setPos(odeBody.getPosition()) pandaNodePathGeom.setQuat(Quat(odeBody.getQuaternion()[0], odeBody.getQuaternion()[1], odeBody.getQuaternion()[2], odeBody.getQuaternion()[3])) def getOrderedContacts(self, count): c0 = self.space.getContactId(count, 0) c1 = self.space.getContactId(count, 1) if c0 > c1: chold = c1 c1 = c0 c0 = chold return (c0, c1)
class Game(ShowBase): ''' ''' def __init__(self): ''' ''' ShowBase.__init__(self) loadPrcFileData("", "notify-level-x11display fatal") # This variable gets set to true when a collision-event gets fired and to false every ode-frame self.ode_collisiontest = False base.setFrameRateMeter(True) # Show the Framerate self.world = OdeWorld() self.deltaTimeAccumulator = 0.0 # this variable is necessary to track the time for the physics self.stepSize = 1.0 / 300.0 # This stepSize makes the simulation run at 300 frames per second # Initialize Collisions (ODE) self.space = OdeSimpleSpace() # Initialize the surface-table, it defines how objects interact with each other self.world.initSurfaceTable(1) self.world.setSurfaceEntry(0, 0, 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002) self.space.setAutoCollideWorld(self.world) self.contactgroup = OdeJointGroup() self.space.setAutoCollideJointGroup(self.contactgroup) self.startGame() # ----------------------------------------------------------------- def startGame(self): ''' Start the game ''' # Load the Lights ambilight = AmbientLight('ambilight') ambilight.setColor(VBase4(0.2, 0.2, 0.2, 1)) render.setLight(render.attachNewNode(ambilight)) # Create the Plane that the model collides with self.plane = OdePlaneGeom(self.space, 0, 0, 1, -5) self.plane.setCollideBits(0) self.plane.setCategoryBits(1) self.space.setCollisionEvent("ode-collision") base.accept("ode-collision", self.onCollision) # Set up a model, that collides with the plane, i use a vector instead because it should always collide # self.model = loader.loadModel("panda") # self.model.reparentTo(render) # self.model.setPos(0,50,2) # Initialize the physics-simulation # self.physics_model = OdeBody(self.world) # self.physics_model.setPosition(self.model.getPos(render)) # self.physics_model.setQuaternion(self.model.getQuat(render)) # # Initialize the mass # physics_mass = OdeMass() # physics_mass.setBox(1,1,1,1) # self.physics_model.setMass(physics_mass) # # self.collision_model = OdeBoxGeom(self.space, 1,1,1) # self.collision_model.setBody(self.physics_model) # self.collision_model.setCollideBits(1) # self.collision_model.setCategoryBits(0) # Set up a vector that collides with the plane self.ray = OdeRayGeom(self.space, 100) self.ray.setCollideBits(1) self.ray.setCategoryBits(0) self.ray.set(Vec3(0, 2, 50), Vec3(0, 0, -1)) # add the game task taskMgr.add(self.gameTask, "gameTask") self.world.setGravity(0, 0, -0.81) # ----------------------------------------------------------------- def onCollision(self, entry): ''' Handles Collision-Events ''' # set the variable true when a collision happens self.ode_collisiontest = True # ----------------------------------------------------------------- def gameTask(self, task): ''' this task runs x-times per second if the game is running ''' # calculate the physics self.deltaTimeAccumulator += globalClock.getDt() while self.deltaTimeAccumulator > self.stepSize: # Step the simulation self.space.autoCollide() # Setup the contact joints self.deltaTimeAccumulator -= self.stepSize # Remove a stepSize from the accumulator until the accumulated time is less than the stepsize self.world.quickStep(self.stepSize) self.contactgroup.empty() # Clear the contact joints # Here we print the variable that should be True when a collision event is fired print((self.ode_collisiontest)) # Now we set it False again self.ode_collisiontest = False # set the new position # self.model.setPosQuat(render, self.physics_model.getPosition(), Quat(self.physics_model.getQuaternion())) return task.cont
class World: def __init__(self, game): self.game = game self.world = OdeWorld() self.world.setGravity(0, 0, -9.81 * 3) self.group = OdeJointGroup() self.space = OdeHashSpace() self.space.setAutoCollideWorld(self.world) self.space.setAutoCollideJointGroup(self.group) self.setSurfaceTables() self.objects = [] self.objectsToRemove = [] self.postStepTasks = [] self.engineRunning = True self.dtAccumulator = 0.0 self.physicsFps = 90 self.physicsMinFps = 10 base.taskMgr.doMethodLater(0.1, self.processPhysics, "Physics") base.accept("escape", self.togglePhysics) self.space.setCollisionEvent("odeCollision") base.accept("odeCollision", self.onCollision) def setSurfaceTables(self): self.surfaces = {} self.surfaces["plane"] = 0 self.surfaces["box"] = 1 self.surfaces["sphere"] = 2 self.surfaces["bullet"] = 3 n = len(self.surfaces) self.world.initSurfaceTable(n) for i in range(n): for j in range(n): # id1, id2, mu (0 to inf), bounce (1 = bouncy), min_bounce_vel, erp (1 = hard), cfm (0 = hard), slip, dampen # sample: 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002 self.world.setSurfaceEntry(i, j, 10.0, 1.0, 0.0, 0.9, 0.0, 0.5, 0.001) # Default value for unspecified pairs. self.world.setSurfaceEntry(self.surfaces["box"], self.surfaces["box"], 200.0, 0.2, 0.3, 1.0, 0.0, 0.0, 0.01) self.world.setSurfaceEntry(self.surfaces["plane"], self.surfaces["box"], 200.0, 0.2, 0.3, 1.0, 0.0, 0.0, 0.01) self.world.setSurfaceEntry(self.surfaces["box"], self.surfaces["bullet"], 10.0, 0.1, 0.5, 1.0, 0.0, 0.0, 0.01) self.world.setSurfaceEntry(self.surfaces["plane"], self.surfaces["bullet"], 100.0, 0.01, 0.1, 1.0, 0.0, 0.0, 1.0) def addObject(self, obj): self.objects.append(obj) def removeObject(self, obj): if obj not in self.objectsToRemove: self.objectsToRemove.append(obj) def removeDestroyedObjects(self): while len(self.objectsToRemove) > 0: obj = self.objectsToRemove.pop() if obj in self.objects: self.objects.remove(obj) obj.doDestroy() def togglePhysics(self): self.engineRunning = not self.engineRunning self.dtAccumulator = 0.0 def processPhysics(self, task): stepSize = 1.0 / self.physicsFps maxDt = 1.0 / self.physicsMinFps if self.engineRunning: self.dtAccumulator += globalClock.getDt() self.dtAccumulator = min(self.dtAccumulator, maxDt) while self.dtAccumulator >= stepSize: self.space.autoCollide() self.world.quickStep(stepSize) for obj in self.objects: obj.updatePosFromPhysics() self.group.empty() self.performPostStepTasks() self.removeDestroyedObjects() self.dtAccumulator -= stepSize return task.cont def onCollision(self, entry): body1 = entry.getBody1() body2 = entry.getBody2() if not body1.isEmpty(): body1.getData().onCollision(body2, entry) if not body2.isEmpty(): body2.getData().onCollision(body1, entry) def performAfterStep(self, method, params): self.postStepTasks.append([method, params]) def performPostStepTasks(self): for task in self.postStepTasks: method = task[0] params = task[1] method(*params) self.postStepTasks = []
class Game: HUD_TEXT_SCALE = 0.1 UPDATE_RATE = 1/60.0 def __init__(self): self.LoadHUD() self.loadPhysics() self.loadLights() #self.wall = Wall(self) #self.wall.setPos( Vec3( 5, 0, 0) ) self.ship1 = ShipTypes.Ship_2(self, Vec4(0.0, 0.0, 0.2, 0)) self.ship2 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0)) self.ship2.setPos( Vec3(10, 10, 0) ) self.setKeys() self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo.setPos( Vec3(0, 20, 0) ) self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo2.setPos( Vec3(30, 20, 0) ) base.setBackgroundColor(0,0,0.0,0) taskMgr.add(self.loop, 'game loop') run() def setKeys(self): base.accept('arrow_up', self.ship1.thrustOn) base.accept('arrow_up-up', self.ship1.thrustOff) base.accept('arrow_left', self.ship1.thrustLeftOn) base.accept('arrow_left-up', self.ship1.thrustLeftOff) base.accept('arrow_right', self.ship1.thrustRightOn) base.accept('arrow_right-up', self.ship1.thrustRightOff) base.accept('arrow_down', self.ship1.thrustBackOn) base.accept('arrow_down-up', self.ship1.thrustBackOff) base.accept('w', self.ship2.thrustOn) base.accept('w-up', self.ship2.thrustOff) base.accept('a', self.ship2.thrustLeftOn) base.accept('a-up', self.ship2.thrustLeftOff) base.accept('d', self.ship2.thrustRightOn) base.accept('d-up', self.ship2.thrustRightOff) base.accept('s', self.ship2.thrustBackOn) base.accept('s-up', self.ship2.thrustBackOff) def loadPhysics(self): self.physicsWorld = OdeWorld() self.physicsWorld.initSurfaceTable(1) self.physicsWorld.setSurfaceEntry( 0, 0, 1.0, # u 0.35, # elasticity 0.01, # minimum threshold for physical movement 0.01, 0.00000001, # softening 0.01, 0.01 # damping ) self.physicsSpace = OdeHashSpace() self.physicsSpace.setAutoCollideWorld(self.physicsWorld) self.contactGroup = OdeJointGroup() self.physicsSpace.setAutoCollideJointGroup(self.contactGroup) def LoadHUD(self): self.winnerText = OnscreenText( text = "Tekstia, tekstia, tekstia", fg = (1,1,1,1), pos = (-0.25, 0), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.winnerText.hide() def loadLights(self): light1 = DirectionalLight('light1') lightNode1 = render.attachNewNode(light1) light1.setDirection( Vec3(-1, 0.5, -0.25) ) light1.setColor( Vec4(0.5, 0.9, 0.9, 0) ) render.setLight(lightNode1) def loop(self, task): self.ship1.applyForces() self.ship2.applyForces() self.physicsSpace.autoCollide() self.pallo.hitShips(self.ship1, self.ship2) self.pallo2.hitShips(self.ship1, self.ship2) # self.wall.osuminen(self.ship1) self.physicsWorld.quickStep(Game.UPDATE_RATE) self.ship1.update(Game.UPDATE_RATE) self.ship2.update(Game.UPDATE_RATE) self.pallo.update(Game.UPDATE_RATE) self.pallo2.update(Game.UPDATE_RATE) self.contactGroup.empty() return task.cont