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 __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 __init__(self, base, mapNo): self.isListening = False # Holds rigid bodies, joints, controls global params self.world = OdeWorld() self.world.setGravity(0, 0, -9.8) st = SurfaceType() st.load(self.world) del st self.contactgroup = OdeJointGroup() self.space = OdeHashSpace() self.space.setAutoCollideWorld(self.world) self.space.setAutoCollideJointGroup(self.contactgroup) self.space.setCollisionEvent(EventType.ODE_COLLISION) base.accept(EventType.ODE_COLLISION, self.onCollision) self.ball = Ball(self.world, self.space, "Johanneksen pallo") self.level = Level(self, mapNo) self.player = Player("Johannes") self.camera = Camera(base, self.ball)
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
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 __init__(self): # initialise ODE world = OdeWorld() #world.setGravity(0.0, 0.0, -9.81) world.setGravity(0.0, 0.0, 0.0) self.grid = DirectGrid(2000, 20, parent=render) self.grid.setZ(-0.001) setSky("bluesky") # lights sunlight = DirectionalLight("sun") sunlight.setColor(Vec4(1.0, 0.9, 0.8, 1)) sunnp = render.attachNewNode(sunlight) sunnp.setP(-60) render.setLight(sunnp) alight = AmbientLight("alight") alight.setColor(Vec4(0.6, 0.6, 0.8, 1)) alnp = render.attachNewNode(alight) render.setLight(alnp) #render.setShaderAuto(True) ## initialise physics engine #base.enableParticles() # load our plane(s) base.player = Aeroplane("griffin", world=world) base.player_camera = views.PlaneCamera(base.player) self.control = controls.PlaneFlight() # load some others #pirate1 = Aeroplane("griffin") #pirate1.node.setPosHpr(-15, -20, 12, -10, -10, 20) #pirate2 = Aeroplane("griffin") #pirate2.node.setPosHpr(18, -30, 6, 5, -5, -5) # set default camera base.player.hud = gui.HUD(base.player, base.camera) base.player.hud.update() self.control.activate()
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 createWorldAndStuff(): global world global space global contactgroup world = OdeWorld() world.setGravity(0, 0, -9.81) # The surface table is needed for autoCollide world.initSurfaceTable(1) world.setSurfaceEntry(0, 0, 15000, 0.001, 0.9, 0.9, 0.00001, 0.1, 0.002) # Create a space and add a contactgroup to it to add the contact joints space = OdeSimpleSpace() space.setAutoCollideWorld(world) contactgroup = OdeJointGroup() space.setAutoCollideJointGroup(contactgroup)
def __init__(self): # Disable Panda's base camera mover base.disableMouse() base.setBackgroundColor(0, 0, 0, 0) self.state = Game.STATE_INITIALIZING # contains a list of the ships in game self.ships = None self.players = None self.bullets = None self.stars = None self.planet = None self.time = 0.0 self.isListening = False getModelPath().prependDirectory(Filename('./media/')) self.physWorld = OdeWorld() self.physWorld.setGravity(0, 0, 0) self.physWorld.initSurfaceTable(1) self.physWorld.setSurfaceEntry( 0, 0, 1.0, # u .35, # elasticity .01, # minimum threshold for physical movement .01, # .00000001, # softening .01, # .01) # dampening self.physSpace = OdeHashSpace() self.winnerText = None self.gameFrames = 0 self.lastWarp = 0 self.cameraMode = Game.CAMERA_MODE_GAME self.lastCameraPos = None self.pause = False
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 __init__(self): # Disable Panda's base camera mover base.disableMouse() base.setBackgroundColor(0,0,0,0) self.state = Game.STATE_INITIALIZING # contains a list of the ships in game self.ships = None self.players = None self.bullets = None self.stars = None self.planet = None self.time = 0.0 self.isListening = False getModelPath().prependDirectory( Filename('./media/') ) self.physWorld = OdeWorld() self.physWorld.setGravity(0, 0, 0) self.physWorld.initSurfaceTable(1) self.physWorld.setSurfaceEntry( 0, 0, 1.0, # u .35, # elasticity .01, # minimum threshold for physical movement .01, # .00000001, # softening .01, # .01) # dampening self.physSpace = OdeHashSpace() self.winnerText = None self.gameFrames = 0 self.lastWarp = 0 self.cameraMode = Game.CAMERA_MODE_GAME self.lastCameraPos = None self.pause = False
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 GameModel: #Represents the world data. def __init__(self, base, mapNo): self.isListening = False # Holds rigid bodies, joints, controls global params self.world = OdeWorld() self.world.setGravity(0, 0, -9.8) st = SurfaceType() st.load(self.world) del st self.contactgroup = OdeJointGroup() self.space = OdeHashSpace() self.space.setAutoCollideWorld(self.world) self.space.setAutoCollideJointGroup(self.contactgroup) self.space.setCollisionEvent(EventType.ODE_COLLISION) base.accept(EventType.ODE_COLLISION, self.onCollision) self.ball = Ball(self.world, self.space, "Johanneksen pallo") self.level = Level(self, mapNo) self.player = Player("Johannes") self.camera = Camera(base, self.ball) def turnGravityTask(self): '''''' g = self.world.getGravity() g = -g self.world.setGravity(g) self.camera.turn() def turnGravityTask2(self): '''''' g = self.world.getGravity() g2 = self.ball.perpendicularUnitVec3WithFixedX(g) g2 *= g.length() self.world.setGravity(g2) def updateObjects(self): ''' Update objects after one physics iteration @see GameLoop.simulationTask ''' self.level.updateModelNode() self.camera.updateModelNode() #Has to be last for RESTART to work inside Ball self.ball.updateModelNode() def getBall(self): return self.ball def getPlayer(self): return self.player # http://www.panda3d.org/wiki/index.php/Collision_Detection_with_ODE def onCollision(self, entry): geom1 = entry.getGeom1() geom2 = entry.getGeom2() body1 = entry.getBody1() body2 = entry.getBody2() # Is the ball touching something? if body1 == self.ball.getBody() or body2 == self.ball.getBody(): self.ball.refreshCollisionTime(entry) for coin in self.level.getCoins(): if body1 == coin.getBody() and body2 == self.ball.getBody(): coin.collect() messenger.send(EventType.UPDATE_HUD) exit = self.level.getExit() if geom1 == exit or geom2 == exit: if Coin.collectable == self.level.getGoal(): # todo: make event based messenger.send(EventType.NEXT_LEVEL) def cleanUp(self): self.level.removeLevel() self.ball.removeNode()
class Game: STATE_INITIALIZING = "Initializing" STATE_RUNNING = "Running" SHIPS_MAX_X_DISTANCE = 330.0 SHIPS_MAX_Y_DISTANCE = 250.0 NAME_SHIP_ONE = "Ship 1" NAME_SHIP_TWO = "Ship 2" NAME_PLAYER_ONE = "Player 1" NAME_PLAYER_TWO = "Player 2" START_POS_SHIP_ONE = (100, 100) START_POS_SHIP_TWO = (-100, -100) START_HEADING_SHIP_ONE = -135.0 START_HEADING_SHIP_TWO = 45.0 PLAYER_ONE_FORWARD_KEY = "arrow_up" PLAYER_ONE_ROTATE_LEFT_KEY = "arrow_left" PLAYER_ONE_ROTATE_RIGHT_KEY = "arrow_right" PLAYER_ONE_SHOOT = "rcontrol" PLAYER_TWO_FORWARD_KEY = "w" PLAYER_TWO_ROTATE_LEFT_KEY = "a" PLAYER_TWO_ROTATE_RIGHT_KEY = "d" PLAYER_TWO_SHOOT = "lcontrol" HUD_TEXT_SCALE = 0.05 HUD_PLAYER_ONE_X = -1.25 HUD_PLAYER_TWO_X = 1.05 HUD_Y_FIRST_LINE = 0.85 HUD_Y_SECOND_LINE = 0.75 HUD_Y_THIRD_LINE = 0.65 CAMERA_POS_DEFAULT = (0.0, 0.0, 250.0) CAMERA_HPR_DEFAULT = (0.0, -90.0, 0.0) CAMERA_DISTANCE_COEFFICIENT = 3.0 CAMERA_DISTANCE_MAX = 450.0 CAMERA_DISTANCE_MIN = 150.0 CAMERA_MODE_GAME = "Game" CAMERA_MODE_FPS_ONE = "Fps 1" CAMERA_MODE_FPS_TWO = "Fps 2" CAMERA_MODE_STILL = "Still" CAMERA_FPS_OFFSET_HEIGHT = 2.0 CAMERA_FPS_OFFSET_BACK = 15.0 WINNER_TEXT = "has won the round" PLANET_POSITION = (0, 0) PLANET_CAMERA_DISTANCE_MAX = 400.0 MATCH_MAX_POINTS = 5 GRAVITY_DISTANCE = 100.0 GRAVITY = 2000.0 def __init__(self): # Disable Panda's base camera mover base.disableMouse() base.setBackgroundColor(0, 0, 0, 0) self.state = Game.STATE_INITIALIZING # contains a list of the ships in game self.ships = None self.players = None self.bullets = None self.stars = None self.planet = None self.time = 0.0 self.isListening = False getModelPath().prependDirectory(Filename('./media/')) self.physWorld = OdeWorld() self.physWorld.setGravity(0, 0, 0) self.physWorld.initSurfaceTable(1) self.physWorld.setSurfaceEntry( 0, 0, 1.0, # u .35, # elasticity .01, # minimum threshold for physical movement .01, # .00000001, # softening .01, # .01) # dampening self.physSpace = OdeHashSpace() self.winnerText = None self.gameFrames = 0 self.lastWarp = 0 self.cameraMode = Game.CAMERA_MODE_GAME self.lastCameraPos = None self.pause = False def start(self): self.resetCamera() self.loadPlanet() self.loadShips() self.loadPlayers() self.loadStars() self.loadHUD() light = DirectionalLight('light') light.setDirection(Vec3(-1, .1, -.5)) light.setColor(Vec4(.7, .6, .6, 0)) light.setSpecularColor(Vec4(.3, .5, .7, 0)) lightnode = render.attachNewNode(light) render.setLight(lightnode) render.setShaderAuto() render.setShaderInput('light', lightnode) render.setAntialias(AntialiasAttrib.MAuto) # TODO: it might be necessary here to check that the task # does not already exist in the task manager because the # unit tests at the moment call the start method # continuously. taskMgr.add(self.tick, "gameloop") self.time = self.getTime() self.registerListeners() self.state = Game.STATE_RUNNING # Load music self.music = loader.loadSfx('MVi - Ilwrath Are Watching.mp3') self.music.setLoop(True) self.music.setVolume(0.5) self.music.play() def loadHUD(self): self.winnerText = OnscreenText(text="Insert Winner Text Here", style=1, fg=(1, 1, 1, 1), pos=(-0.25, 0), align=TextNode.ALeft, scale=.07) self.winnerText.hide() self.scoreTextPlayerOne = OnscreenText(text="Player 1:", style=1, fg=(1, 1, 1, 1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_FIRST_LINE), align=TextNode.ALeft, scale=Game.HUD_TEXT_SCALE) self.scorePlayerOne = OnscreenText(text="Score: 0", style=1, fg=(1, 1, 1, 1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_SECOND_LINE), align=TextNode.ALeft, scale=Game.HUD_TEXT_SCALE) self.healthPlayerOne = OnscreenText(text="Health: " + str(Ship.HEALTH), style=1, fg=(1, 1, 1, 1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_THIRD_LINE), align=TextNode.ALeft, scale=Game.HUD_TEXT_SCALE) self.scoreTextPlayerTwo = OnscreenText(text="Player 2:", style=1, fg=(1, 1, 1, 1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_FIRST_LINE), align=TextNode.ALeft, scale=Game.HUD_TEXT_SCALE) self.scorePlayerTwo = OnscreenText(text="Score: 0", style=1, fg=(1, 1, 1, 1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_SECOND_LINE), align=TextNode.ALeft, scale=Game.HUD_TEXT_SCALE) self.healthPlayerTwo = OnscreenText(text="Health: " + str(Ship.HEALTH), style=1, fg=(1, 1, 1, 1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_THIRD_LINE), align=TextNode.ALeft, scale=Game.HUD_TEXT_SCALE) def generateRandomPos(self): return (random.random() * Game.SHIPS_MAX_X_DISTANCE - Game.SHIPS_MAX_X_DISTANCE / 2., random.random() * Game.SHIPS_MAX_Y_DISTANCE - Game.SHIPS_MAX_Y_DISTANCE / 2.) def generateRandomStartPos(self, offlimits=[]): pos = self.generateRandomPos() while not self.checkIfStartPosValid(pos, offlimits): pos = self.generateRandomPos() return pos def checkIfStartPosValid(self, pos, offlimits): for o in offlimits: if tupleDistanceSquared(pos, o[0]) < o[1]**2: return False return True def getBullets(self): ships = self.getShips() shipOne = ships[0] shipTwo = ships[1] bullets = [shipOne.bullets, shipTwo.bullets] return bullets def resetCamera(self): self.setCameraPos(Game.CAMERA_POS_DEFAULT) self.setCameraHpr(Game.CAMERA_HPR_DEFAULT) pos = Game.CAMERA_POS_DEFAULT self.lastCameraPos = (pos[0], pos[1]) def setCameraPos(self, pos): base.camera.setPos(tripleToVec3(pos)) def getCameraPos(self): return vec3ToTriple(base.camera.getPos()) def setCameraHpr(self, hpr): base.camera.setHpr(tripleToVec3(hpr)) def getCameraHpr(self): return vec3ToTriple(base.camera.getHpr()) def getTime(self): return globalClock.getFrameTime() def getDeltaTime(self): return globalClock.getDt() def run(self): """Call this to run the game. Untested because this method won't return.""" taskMgr.run() def loadShips(self): shipOne = Ship(Game.NAME_SHIP_ONE, Game.START_POS_SHIP_ONE, Game.START_HEADING_SHIP_ONE) shipTwo = Ship(Game.NAME_SHIP_TWO, Game.START_POS_SHIP_TWO, Game.START_HEADING_SHIP_TWO) offlimits = [(vec3ToTuple(self.planet.getPos()), Game.GRAVITY_DISTANCE) ] shipOne.setPos(self.generateRandomStartPos(offlimits)) shipOne.heading = random.random() * 360 shipTwo.heading = random.random() * 360 offlimits.append((shipOne.getPos(), 150)) shipTwo.setPos(self.generateRandomStartPos(offlimits)) self.ships = [] self.ships.append(shipOne) self.ships.append(shipTwo) def loadPlayers(self): playerOne = Player(Game.NAME_PLAYER_ONE) playerTwo = Player(Game.NAME_PLAYER_TWO) self.players = [] self.players.append(playerOne) self.players.append(playerTwo) def loadStars(self): ambientlight = AmbientLight('alight') ambientlight.setColor(Vec4(1, 1, 1, 0)) lightnode = render.attachNewNode(ambientlight) self.stars = loader.loadModel("stars.bam") self.stars.setLight(lightnode) self.stars.setScale(1000) self.stars.setPos(0, 0, 0) self.stars.reparentTo(render) self.starsRotation = self.stars.getQuat() def loadPlanet(self): self.planet = loader.loadModel('planet.bam') self.planet.setPos(tupleToVec3(Game.PLANET_POSITION)) self.planet.setScale(20) self.planet.reparentTo(render) self.planetCollGeom = OdeSphereGeom(20) #self.planetCollGeom.setCategoryBits( BitMask32(0xffffffff) ) #self.planetCollGeom.setCollideBits( BitMask32(0xffffffff) ) def updateCamera(self): ships = self.getShips() shipOne = ships[0] shipOnePos = shipOne.getPos() shipTwo = ships[1] shipTwoPos = shipTwo.getPos() # Calculate the distance between the ships distance = tupleDistance(shipOnePos, shipTwoPos) cameraDistance = distance * Game.CAMERA_DISTANCE_COEFFICIENT if cameraDistance > Game.CAMERA_DISTANCE_MAX: cameraDistance = Game.CAMERA_DISTANCE_MAX if cameraDistance < Game.CAMERA_DISTANCE_MIN: cameraDistance = Game.CAMERA_DISTANCE_MIN # Calculate the middle point in space between the ship's positions middle = tupleMiddle(shipOnePos, shipTwoPos) cameraPos = self.getCameraPos() self.lastCameraPos = cameraPos newCameraPos = (middle[0], middle[1], cameraDistance) self.setCameraPos(newCameraPos) self.updateStars(newCameraPos) def updateStars(self, newCameraPos): # TODO: Add unit tests! self.stars.setPos(newCameraPos) cameraDeltaPos = tupleSegment(self.lastCameraPos, vec3ToTuple(newCameraPos)) xRotation = Quat() xRotation.setFromAxisAngle(cameraDeltaPos[0] * .1, Vec3(0, 1, 0)) yRotation = Quat() yRotation.setFromAxisAngle(-cameraDeltaPos[1] * .1, Vec3(1, 0, 0)) newRotation = xRotation.multiply(yRotation) self.starsRotation *= newRotation self.stars.setQuat(self.starsRotation) # With Euler angles: #self.stars.setHpr(0, -newCameraPos[1] * 0.1, newCameraPos[0] * 0.1 ) def applyGravity(self, ship, deltaTime): distance = tupleDistance(ship.getPos(), vec3ToTuple(self.planet.getPos())) if distance > Game.GRAVITY_DISTANCE: return gravity = Game.GRAVITY / distance gravityVector = tupleNormalize( tupleSegment(ship.getPos(), vec3ToTuple(self.planet.getPos()))) gravityVector = scaleTuple(gravityVector, gravity * deltaTime) ship.applyForce(gravityVector) def tick(self, task): if not self.pause: ships = self.getShips() # Check if the ships' positions need to be warped xDistance = abs(ships[0].getPos()[0] - ships[1].getPos()[0]) if xDistance >= Game.SHIPS_MAX_X_DISTANCE: #and self.gameFrames - self.lastWarp > 10: self.warpShips('x') #self.lastWarp = self.gameFrames yDistance = abs(ships[0].getPos()[1] - ships[1].getPos()[1]) if yDistance >= Game.SHIPS_MAX_Y_DISTANCE: self.warpShips('y') # Check if the planet's position needs to be warped planetXDistance = abs(self.getCameraPos()[0] - self.planet.getPos()[0]) if planetXDistance >= Game.PLANET_CAMERA_DISTANCE_MAX: self.warpPlanet('x') planetYDistance = abs(self.getCameraPos()[1] - self.planet.getPos()[1]) if planetYDistance >= Game.PLANET_CAMERA_DISTANCE_MAX: self.warpPlanet('y') # Check collisions col = OdeUtil.collide(ships[0].collisionSphere, ships[1].collisionSphere, 1) if not col.isEmpty(): ships[0].addCollision(point3ToTuple(col.getContactPoint(0))) ships[1].addCollision(point3ToTuple(col.getContactPoint(0))) colPlanet1 = OdeUtil.collide(ships[0].collisionSphere, self.planetCollGeom, 1) colPlanet2 = OdeUtil.collide(ships[1].collisionSphere, self.planetCollGeom, 1) if not colPlanet1.isEmpty(): ships[0].addCollision( point3ToTuple(colPlanet1.getContactPoint(0))) ships[0].planetHit() if not colPlanet2.isEmpty(): ships[1].addCollision( point3ToTuple(colPlanet2.getContactPoint(0))) ships[1].planetHit() # Bullet collisions ship one for bullet in ships[0].bullets: colBulletShip1 = OdeUtil.collide(bullet['physical'], ships[1].collisionSphere, 1) if not colBulletShip1.isEmpty(): ships[0].destroyBullet(bullet) ships[1].bulletHit() colBulletPlanet = OdeUtil.collide(bullet['physical'], self.planetCollGeom, 1) if not colBulletPlanet.isEmpty(): ships[0].destroyBullet(bullet) # Bullet collisions ship two for bullet in ships[1].bullets: colBulletShip2 = OdeUtil.collide(bullet['physical'], ships[0].collisionSphere, 1) if not colBulletShip2.isEmpty(): ships[1].destroyBullet(bullet) ships[0].bulletHit() colBulletPlanet = OdeUtil.collide(bullet['physical'], self.planetCollGeom, 1) if not colBulletPlanet.isEmpty(): ships[1].destroyBullet(bullet) for ship in ships: self.applyGravity(ship, self.getDeltaTime()) ship.update(self.getDeltaTime()) if not ships[0].isAlive: self.showWinnerText(self.players[1]) self.players[1].score += 1 self.restartGame() if not ships[1].isAlive: self.showWinnerText(self.players[0]) self.players[0].score += 1 self.restartGame() if self.cameraMode == Game.CAMERA_MODE_GAME: self.updateCamera() if self.gameFrames >= 125: self.winnerText.hide() self.gameFrames += 1 # Update health points in the HUD # TODO: These should be optimized so that they get updated only when they # change. self.healthPlayerOne.setText("Health: " + str(self.ships[0].health)) self.healthPlayerTwo.setText("Health: " + str(self.ships[1].health)) return task.cont def distanceToPlanetSquared(self, pos): return tupleDistanceSquared(pos, vec3ToTuple(self.planet.getPos())) def warpShips(self, warpAxis): shipOne = self.ships[0] shipTwo = self.ships[1] shipOnePos = shipOne.getPos() shipTwoPos = shipTwo.getPos() furtherShip = None closerShip = None if shipOnePos == tupleFurthestDistance( vec3ToTuple(self.planet.getPos()), [shipOnePos, shipTwoPos]): furtherShip = shipOne closerShip = shipTwo else: closerShip = shipOne furtherShip = shipTwo furtherToCloser = tupleSegment(furtherShip.getPos(), closerShip.getPos()) if warpAxis == 'x': furtherShip.setPos( (furtherShip.getPos()[0] + furtherToCloser[0] * 2, furtherShip.getPos()[1])) elif warpAxis == 'y': furtherShip.setPos( (furtherShip.getPos()[0], furtherShip.getPos()[1] + furtherToCloser[1] * 2)) def warpPlanet(self, warpAxis): planetPos = vec3ToTuple(self.planet.getPos()) planetToCamera = tupleSegment(planetPos, self.getCameraPos()) if warpAxis == 'x': self.planet.setPos(planetPos[0] + planetToCamera[0] * 2, planetPos[1], 0) self.planetCollGeom.setPosition( planetPos[0] + planetToCamera[0] * 2, planetPos[1], 0) elif warpAxis == 'y': self.planet.setPos(planetPos[0], planetPos[1] + planetToCamera[1] * 2, 0) self.planetCollGeom.setPosition( planetPos[0], planetPos[1] + planetToCamera[1] * 2, 0) def restartGame(self): self.planet.setPos(Vec3()) self.planetCollGeom.setPosition(Vec3()) offlimits = [(vec3ToTuple(self.planet.getPos()), 102)] # Reset ship one self.ships[0].setPos(self.generateRandomStartPos(offlimits)) self.ships[0].heading = random.random() * 360 self.ships[0].setVel(Ship.VEL_DEFAULT) self.ships[0].isAlive = True self.ships[0].health = Ship.HEALTH self.ships[0].visualNode.show() for bullet in self.ships[0].bullets: bullet['isAlive'] = False offlimits.append((self.ships[0].getPos(), 128)) # Reset ship two self.ships[1].setPos(self.generateRandomStartPos(offlimits)) self.ships[1].heading = random.random() * 360 self.ships[1].setVel(Ship.VEL_DEFAULT) self.ships[1].isAlive = True self.ships[1].health = Ship.HEALTH self.ships[1].visualNode.show() for bullet in self.ships[1].bullets: bullet['isAlive'] = False for s in self.ships: s.update(1 / 60.) self.gameFrames = 0 playerOneScore = self.players[0].score playerTwoScore = self.players[1].score if playerOneScore >= Game.MATCH_MAX_POINTS: self.showGameWinnerText(self.players[0]) self.players[0].score = 0 self.players[1].score = 0 if playerTwoScore >= Game.MATCH_MAX_POINTS: self.showGameWinnerText(self.players[1]) self.players[0].score = 0 self.players[1].score = 0 playerOneScore = self.players[0].score playerTwoScore = self.players[1].score self.scorePlayerOne.setText('Score: ' + str(playerOneScore)) self.scorePlayerTwo.setText('Score: ' + str(playerTwoScore)) def showWinnerText(self, player): self.winnerText.setText(player.name + " " + Game.WINNER_TEXT) self.winnerText.show() def showGameWinnerText(self, player): self.winnerText.setText(player.name + " wins the match!") self.winnerText.show() def registerListeners(self): playerOne = self.getPlayers()[0] playerTwo = self.getPlayers()[1] shipOne = self.getShips()[0] shipTwo = self.getShips()[1] # Player one events playerOneMoveForwardOn = createNamedEvent(playerOne.name, Event.PLAYER_MOVE_FORWARD_ON) playerOneMoveForwardOff = createNamedEvent( playerOne.name, Event.PLAYER_MOVE_FORWARD_OFF) playerOneRotateLeftOn = createNamedEvent(playerOne.name, Event.PLAYER_ROTATE_LEFT_ON) playerOneRotateLeftOff = createNamedEvent(playerOne.name, Event.PLAYER_ROTATE_LEFT_OFF) playerOneRotateRightOn = createNamedEvent(playerOne.name, Event.PLAYER_ROTATE_RIGHT_ON) playerOneRotateRightOff = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_RIGHT_OFF) playerOneShoot = createNamedEvent(playerOne.name, Event.PLAYER_SHOOT) base.accept(playerOneMoveForwardOn, shipOne.thrustOn) base.accept(playerOneMoveForwardOff, shipOne.thrustOff) base.accept(playerOneRotateLeftOn, shipOne.rotateLeftOn) base.accept(playerOneRotateLeftOff, shipOne.rotateLeftOff) base.accept(playerOneRotateRightOn, shipOne.rotateRightOn) base.accept(playerOneRotateRightOff, shipOne.rotateRightOff) base.accept(playerOneShoot, shipOne.shoot) # Player two events playerTwoMoveForwardOn = createNamedEvent(playerTwo.name, Event.PLAYER_MOVE_FORWARD_ON) playerTwoMoveForwardOff = createNamedEvent( playerTwo.name, Event.PLAYER_MOVE_FORWARD_OFF) playerTwoRotateLeftOn = createNamedEvent(playerTwo.name, Event.PLAYER_ROTATE_LEFT_ON) playerTwoRotateLeftOff = createNamedEvent(playerTwo.name, Event.PLAYER_ROTATE_LEFT_OFF) playerTwoRotateRightOn = createNamedEvent(playerTwo.name, Event.PLAYER_ROTATE_RIGHT_ON) playerTwoRotateRightOff = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_RIGHT_OFF) playerTwoShoot = createNamedEvent(playerTwo.name, Event.PLAYER_SHOOT) base.accept(playerTwoMoveForwardOn, shipTwo.thrustOn) base.accept(playerTwoMoveForwardOff, shipTwo.thrustOff) base.accept(playerTwoRotateLeftOn, shipTwo.rotateLeftOn) base.accept(playerTwoRotateLeftOff, shipTwo.rotateLeftOff) base.accept(playerTwoRotateRightOn, shipTwo.rotateRightOn) base.accept(playerTwoRotateRightOff, shipTwo.rotateRightOff) base.accept(playerTwoShoot, shipTwo.shoot) # Player one key mapping base.accept(Game.PLAYER_ONE_FORWARD_KEY, playerOne.moveForwardOn) base.accept("control-" + Game.PLAYER_ONE_FORWARD_KEY, playerOne.moveForwardOn) base.accept(Game.PLAYER_ONE_FORWARD_KEY + "-up", playerOne.moveForwardOff) base.accept(Game.PLAYER_ONE_ROTATE_LEFT_KEY, playerOne.rotateLeftOn) base.accept("control-" + Game.PLAYER_ONE_ROTATE_LEFT_KEY, playerOne.rotateLeftOn) base.accept(Game.PLAYER_ONE_ROTATE_LEFT_KEY + "-up", playerOne.rotateLeftOff) base.accept(Game.PLAYER_ONE_ROTATE_RIGHT_KEY, playerOne.rotateRightOn) base.accept("control-" + Game.PLAYER_ONE_ROTATE_RIGHT_KEY, playerOne.rotateRightOn) base.accept(Game.PLAYER_ONE_ROTATE_RIGHT_KEY + "-up", playerOne.rotateRightOff) base.accept(Game.PLAYER_ONE_SHOOT, playerOne.shoot) # Player two key mapping base.accept(Game.PLAYER_TWO_FORWARD_KEY, playerTwo.moveForwardOn) base.accept("control-" + Game.PLAYER_TWO_FORWARD_KEY, playerTwo.moveForwardOn) base.accept(Game.PLAYER_TWO_FORWARD_KEY + "-up", playerTwo.moveForwardOff) base.accept(Game.PLAYER_TWO_ROTATE_LEFT_KEY, playerTwo.rotateLeftOn) base.accept("control-" + Game.PLAYER_TWO_ROTATE_LEFT_KEY, playerTwo.rotateLeftOn) base.accept(Game.PLAYER_TWO_ROTATE_LEFT_KEY + "-up", playerTwo.rotateLeftOff) base.accept(Game.PLAYER_TWO_ROTATE_RIGHT_KEY, playerTwo.rotateRightOn) base.accept("control-" + Game.PLAYER_TWO_ROTATE_RIGHT_KEY, playerTwo.rotateRightOn) base.accept(Game.PLAYER_TWO_ROTATE_RIGHT_KEY + "-up", playerTwo.rotateRightOff) base.accept(Game.PLAYER_TWO_SHOOT, playerTwo.shoot) # Game specific key mapping base.accept("escape", sys.exit) base.accept("f1", self.switchCameraMode, [Game.CAMERA_MODE_FPS_ONE]) base.accept("f2", self.switchCameraMode, [Game.CAMERA_MODE_FPS_TWO]) base.accept("f3", self.switchCameraMode, [Game.CAMERA_MODE_GAME]) base.accept("f4", self.switchCameraMode, [Game.CAMERA_MODE_STILL]) base.accept("p", self.togglePause) # The game is now listening to all the necessary events self.isListening = True def togglePause(self): self.pause = not self.pause def windowExists(self): return base.isMainWindowOpen() def getShips(self): return self.ships def getPlayers(self): return self.players def switchCameraMode(self, cameraMode): self.cameraMode = cameraMode if cameraMode == Game.CAMERA_MODE_FPS_ONE: angle = self.ships[0].heading * math.pi / 180.0 headingX = math.cos(angle) headingY = math.sin(angle) offset = Vec3(headingX, headingY, 0) pos = self.ships[0].visualNode.getChildren()[0].getPos() base.camera.setPos( pos[0] + offset[0], pos[1] + offset[1] - Game.CAMERA_FPS_OFFSET_HEIGHT, pos[2] - Game.CAMERA_FPS_OFFSET_BACK) hpr = self.ships[0].visualNode.getChildren()[0].getHpr() base.camera.setHpr(hpr[0], hpr[1] + 90, hpr[2]) base.camera.reparentTo(self.ships[0].visualNode) if cameraMode == Game.CAMERA_MODE_FPS_TWO: angle = self.ships[1].heading * math.pi / 180.0 headingX = math.cos(angle) headingY = math.sin(angle) offset = Vec3(headingX, headingY, 0) pos = self.ships[1].visualNode.getChildren()[0].getPos() base.camera.setPos( pos[0] + offset[0], pos[1] + offset[1] - Game.CAMERA_FPS_OFFSET_HEIGHT, pos[2] - Game.CAMERA_FPS_OFFSET_BACK) hpr = self.ships[1].visualNode.getChildren()[0].getHpr() base.camera.setHpr(hpr[0], hpr[1] + 90, hpr[2]) base.camera.reparentTo(self.ships[1].visualNode) if cameraMode == Game.CAMERA_MODE_GAME: base.camera.setHpr(Game.CAMERA_HPR_DEFAULT) base.camera.reparentTo(render) if cameraMode == Game.CAMERA_MODE_STILL: base.camera.reparentTo(render)
class Physical(object): world = OdeWorld() world.setGravity(0, 0, 0) def __init__(self): self.world = Physical.world
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 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(): 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 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
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 Game: STATE_INITIALIZING = "Initializing" STATE_RUNNING = "Running" SHIPS_MAX_X_DISTANCE = 330.0 SHIPS_MAX_Y_DISTANCE = 250.0 NAME_SHIP_ONE = "Ship 1" NAME_SHIP_TWO = "Ship 2" NAME_PLAYER_ONE = "Player 1" NAME_PLAYER_TWO = "Player 2" START_POS_SHIP_ONE = (100, 100) START_POS_SHIP_TWO = (-100, -100) START_HEADING_SHIP_ONE = -135.0 START_HEADING_SHIP_TWO = 45.0 PLAYER_ONE_FORWARD_KEY = "arrow_up" PLAYER_ONE_ROTATE_LEFT_KEY = "arrow_left" PLAYER_ONE_ROTATE_RIGHT_KEY = "arrow_right" PLAYER_ONE_SHOOT = "rcontrol" PLAYER_TWO_FORWARD_KEY = "w" PLAYER_TWO_ROTATE_LEFT_KEY = "a" PLAYER_TWO_ROTATE_RIGHT_KEY = "d" PLAYER_TWO_SHOOT = "lcontrol" HUD_TEXT_SCALE = 0.05 HUD_PLAYER_ONE_X = -1.25 HUD_PLAYER_TWO_X = 1.05 HUD_Y_FIRST_LINE = 0.85 HUD_Y_SECOND_LINE = 0.75 HUD_Y_THIRD_LINE = 0.65 CAMERA_POS_DEFAULT = (0.0, 0.0, 250.0) CAMERA_HPR_DEFAULT = (0.0, -90.0, 0.0) CAMERA_DISTANCE_COEFFICIENT = 3.0 CAMERA_DISTANCE_MAX = 450.0 CAMERA_DISTANCE_MIN = 150.0 CAMERA_MODE_GAME = "Game" CAMERA_MODE_FPS_ONE = "Fps 1" CAMERA_MODE_FPS_TWO = "Fps 2" CAMERA_MODE_STILL = "Still" CAMERA_FPS_OFFSET_HEIGHT = 2.0 CAMERA_FPS_OFFSET_BACK = 15.0 WINNER_TEXT = "has won the round" PLANET_POSITION = (0, 0) PLANET_CAMERA_DISTANCE_MAX = 400.0 MATCH_MAX_POINTS = 5 GRAVITY_DISTANCE = 100.0 GRAVITY = 2000.0 def __init__(self): # Disable Panda's base camera mover base.disableMouse() base.setBackgroundColor(0,0,0,0) self.state = Game.STATE_INITIALIZING # contains a list of the ships in game self.ships = None self.players = None self.bullets = None self.stars = None self.planet = None self.time = 0.0 self.isListening = False getModelPath().prependDirectory( Filename('./media/') ) self.physWorld = OdeWorld() self.physWorld.setGravity(0, 0, 0) self.physWorld.initSurfaceTable(1) self.physWorld.setSurfaceEntry( 0, 0, 1.0, # u .35, # elasticity .01, # minimum threshold for physical movement .01, # .00000001, # softening .01, # .01) # dampening self.physSpace = OdeHashSpace() self.winnerText = None self.gameFrames = 0 self.lastWarp = 0 self.cameraMode = Game.CAMERA_MODE_GAME self.lastCameraPos = None self.pause = False def start(self): self.resetCamera() self.loadPlanet() self.loadShips() self.loadPlayers() self.loadStars() self.loadHUD() light = DirectionalLight('light') light.setDirection( Vec3(-1, .1, -.5) ) light.setColor( Vec4(.7, .6, .6, 0) ) light.setSpecularColor( Vec4(.3, .5, .7, 0) ) lightnode = render.attachNewNode(light) render.setLight(lightnode) render.setShaderAuto() render.setShaderInput('light', lightnode) render.setAntialias(AntialiasAttrib.MAuto) # TODO: it might be necessary here to check that the task # does not already exist in the task manager because the # unit tests at the moment call the start method # continuously. taskMgr.add(self.tick, "gameloop") self.time = self.getTime() self.registerListeners() self.state = Game.STATE_RUNNING # Load music self.music = loader.loadSfx('MVi - Ilwrath Are Watching.mp3') self.music.setLoop(True) self.music.setVolume(0.5) self.music.play() def loadHUD(self): self.winnerText = OnscreenText( text= "Insert Winner Text Here", style=1, fg=(1,1,1,1), pos=(-0.25, 0), align=TextNode.ALeft, scale = .07 ) self.winnerText.hide() self.scoreTextPlayerOne = OnscreenText( text= "Player 1:", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_FIRST_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.scorePlayerOne = OnscreenText( text= "Score: 0", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_SECOND_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.healthPlayerOne = OnscreenText( text= "Health: " + str(Ship.HEALTH), style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_ONE_X, Game.HUD_Y_THIRD_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.scoreTextPlayerTwo = OnscreenText( text= "Player 2:", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_FIRST_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.scorePlayerTwo = OnscreenText( text= "Score: 0", style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_SECOND_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.healthPlayerTwo = OnscreenText( text= "Health: " + str(Ship.HEALTH), style=1, fg=(1,1,1,1), pos=(Game.HUD_PLAYER_TWO_X, Game.HUD_Y_THIRD_LINE), align=TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) def generateRandomPos( self ): return ( random.random() * Game.SHIPS_MAX_X_DISTANCE - Game.SHIPS_MAX_X_DISTANCE / 2., random.random() * Game.SHIPS_MAX_Y_DISTANCE - Game.SHIPS_MAX_Y_DISTANCE / 2. ) def generateRandomStartPos( self, offlimits = [] ): pos = self.generateRandomPos() while not self.checkIfStartPosValid( pos, offlimits ): pos = self.generateRandomPos() return pos def checkIfStartPosValid( self, pos, offlimits ): for o in offlimits: if tupleDistanceSquared( pos, o[0] ) < o[1]**2: return False return True def getBullets(self): ships = self.getShips() shipOne = ships[0] shipTwo = ships[1] bullets = [shipOne.bullets, shipTwo.bullets] return bullets def resetCamera(self): self.setCameraPos(Game.CAMERA_POS_DEFAULT) self.setCameraHpr(Game.CAMERA_HPR_DEFAULT) pos = Game.CAMERA_POS_DEFAULT self.lastCameraPos = ( pos[0], pos[1] ) def setCameraPos(self, pos): base.camera.setPos( tripleToVec3(pos) ) def getCameraPos(self): return vec3ToTriple( base.camera.getPos() ) def setCameraHpr(self, hpr): base.camera.setHpr( tripleToVec3(hpr) ) def getCameraHpr(self): return vec3ToTriple( base.camera.getHpr() ) def getTime(self): return globalClock.getFrameTime() def getDeltaTime(self): return globalClock.getDt() def run(self): """Call this to run the game. Untested because this method won't return.""" taskMgr.run() def loadShips(self): shipOne = Ship( Game.NAME_SHIP_ONE, Game.START_POS_SHIP_ONE, Game.START_HEADING_SHIP_ONE ) shipTwo = Ship( Game.NAME_SHIP_TWO, Game.START_POS_SHIP_TWO, Game.START_HEADING_SHIP_TWO ) offlimits = [ ( vec3ToTuple( self.planet.getPos() ), Game.GRAVITY_DISTANCE ) ] shipOne.setPos( self.generateRandomStartPos( offlimits ) ) shipOne.heading = random.random()*360 shipTwo.heading = random.random()*360 offlimits.append( ( shipOne.getPos(), 150 ) ) shipTwo.setPos( self.generateRandomStartPos( offlimits ) ) self.ships = [] self.ships.append(shipOne) self.ships.append(shipTwo) def loadPlayers(self): playerOne = Player(Game.NAME_PLAYER_ONE) playerTwo = Player(Game.NAME_PLAYER_TWO) self.players = [] self.players.append(playerOne) self.players.append(playerTwo) def loadStars(self): ambientlight = AmbientLight('alight') ambientlight.setColor( Vec4(1, 1, 1, 0) ) lightnode = render.attachNewNode(ambientlight) self.stars = loader.loadModel("stars.bam") self.stars.setLight(lightnode) self.stars.setScale(1000) self.stars.setPos(0,0,0) self.stars.reparentTo(render) self.starsRotation = self.stars.getQuat() def loadPlanet(self): self.planet = loader.loadModel('planet.bam') self.planet.setPos( tupleToVec3(Game.PLANET_POSITION) ) self.planet.setScale(20) self.planet.reparentTo(render) self.planetCollGeom = OdeSphereGeom(20) #self.planetCollGeom.setCategoryBits( BitMask32(0xffffffff) ) #self.planetCollGeom.setCollideBits( BitMask32(0xffffffff) ) def updateCamera(self): ships = self.getShips() shipOne = ships[0] shipOnePos = shipOne.getPos() shipTwo = ships[1] shipTwoPos = shipTwo.getPos() # Calculate the distance between the ships distance = tupleDistance(shipOnePos, shipTwoPos) cameraDistance = distance * Game.CAMERA_DISTANCE_COEFFICIENT if cameraDistance > Game.CAMERA_DISTANCE_MAX: cameraDistance = Game.CAMERA_DISTANCE_MAX if cameraDistance < Game.CAMERA_DISTANCE_MIN: cameraDistance = Game.CAMERA_DISTANCE_MIN # Calculate the middle point in space between the ship's positions middle = tupleMiddle(shipOnePos, shipTwoPos) cameraPos = self.getCameraPos() self.lastCameraPos = cameraPos newCameraPos = (middle[0], middle[1], cameraDistance) self.setCameraPos(newCameraPos) self.updateStars(newCameraPos) def updateStars(self, newCameraPos): # TODO: Add unit tests! self.stars.setPos(newCameraPos) cameraDeltaPos = tupleSegment( self.lastCameraPos, vec3ToTuple( newCameraPos ) ) xRotation = Quat() xRotation.setFromAxisAngle( cameraDeltaPos[0] * .1, Vec3( 0, 1, 0 ) ) yRotation = Quat() yRotation.setFromAxisAngle( -cameraDeltaPos[1] * .1, Vec3( 1, 0, 0 ) ) newRotation = xRotation.multiply( yRotation ) self.starsRotation *= newRotation self.stars.setQuat( self.starsRotation ) # With Euler angles: #self.stars.setHpr(0, -newCameraPos[1] * 0.1, newCameraPos[0] * 0.1 ) def applyGravity(self, ship, deltaTime): distance = tupleDistance( ship.getPos(), vec3ToTuple( self.planet.getPos() ) ) if distance > Game.GRAVITY_DISTANCE: return gravity = Game.GRAVITY/distance gravityVector = tupleNormalize( tupleSegment( ship.getPos(), vec3ToTuple( self.planet.getPos() ) ) ) gravityVector = scaleTuple( gravityVector, gravity * deltaTime) ship.applyForce( gravityVector ) def tick(self, task): if not self.pause: ships = self.getShips() # Check if the ships' positions need to be warped xDistance = abs(ships[0].getPos()[0] - ships[1].getPos()[0] ) if xDistance >= Game.SHIPS_MAX_X_DISTANCE: #and self.gameFrames - self.lastWarp > 10: self.warpShips('x') #self.lastWarp = self.gameFrames yDistance = abs(ships[0].getPos()[1] - ships[1].getPos()[1] ) if yDistance >= Game.SHIPS_MAX_Y_DISTANCE: self.warpShips('y') # Check if the planet's position needs to be warped planetXDistance = abs( self.getCameraPos()[0] - self.planet.getPos()[0] ) if planetXDistance >= Game.PLANET_CAMERA_DISTANCE_MAX: self.warpPlanet('x') planetYDistance = abs( self.getCameraPos()[1] - self.planet.getPos()[1] ) if planetYDistance >= Game.PLANET_CAMERA_DISTANCE_MAX: self.warpPlanet('y') # Check collisions col = OdeUtil.collide(ships[0].collisionSphere, ships[1].collisionSphere, 1) if not col.isEmpty(): ships[0].addCollision( point3ToTuple( col.getContactPoint(0) ) ) ships[1].addCollision( point3ToTuple( col.getContactPoint(0) ) ) colPlanet1 = OdeUtil.collide(ships[0].collisionSphere, self.planetCollGeom, 1) colPlanet2 = OdeUtil.collide(ships[1].collisionSphere, self.planetCollGeom, 1) if not colPlanet1.isEmpty(): ships[0].addCollision( point3ToTuple( colPlanet1.getContactPoint(0) ) ) ships[0].planetHit() if not colPlanet2.isEmpty(): ships[1].addCollision( point3ToTuple( colPlanet2.getContactPoint(0) ) ) ships[1].planetHit() # Bullet collisions ship one for bullet in ships[0].bullets: colBulletShip1 = OdeUtil.collide( bullet['physical'], ships[1].collisionSphere, 1 ) if not colBulletShip1.isEmpty(): ships[0].destroyBullet(bullet) ships[1].bulletHit() colBulletPlanet = OdeUtil.collide( bullet['physical'], self.planetCollGeom, 1 ) if not colBulletPlanet.isEmpty(): ships[0].destroyBullet(bullet) # Bullet collisions ship two for bullet in ships[1].bullets: colBulletShip2 = OdeUtil.collide( bullet['physical'], ships[0].collisionSphere, 1 ) if not colBulletShip2.isEmpty(): ships[1].destroyBullet(bullet) ships[0].bulletHit() colBulletPlanet = OdeUtil.collide( bullet['physical'], self.planetCollGeom, 1 ) if not colBulletPlanet.isEmpty(): ships[1].destroyBullet(bullet) for ship in ships: self.applyGravity( ship, self.getDeltaTime() ) ship.update( self.getDeltaTime() ) if not ships[0].isAlive: self.showWinnerText(self.players[1]) self.players[1].score += 1 self.restartGame() if not ships[1].isAlive: self.showWinnerText(self.players[0]) self.players[0].score += 1 self.restartGame() if self.cameraMode == Game.CAMERA_MODE_GAME: self.updateCamera() if self.gameFrames >= 125: self.winnerText.hide() self.gameFrames += 1 # Update health points in the HUD # TODO: These should be optimized so that they get updated only when they # change. self.healthPlayerOne.setText( "Health: " + str(self.ships[0].health) ) self.healthPlayerTwo.setText( "Health: " + str(self.ships[1].health) ) return task.cont def distanceToPlanetSquared(self, pos): return tupleDistanceSquared( pos, vec3ToTuple( self.planet.getPos() ) ) def warpShips(self, warpAxis): shipOne = self.ships[0] shipTwo = self.ships[1] shipOnePos = shipOne.getPos() shipTwoPos = shipTwo.getPos() furtherShip = None closerShip = None if shipOnePos == tupleFurthestDistance( vec3ToTuple( self.planet.getPos() ), [shipOnePos, shipTwoPos] ): furtherShip = shipOne closerShip = shipTwo else: closerShip = shipOne furtherShip = shipTwo furtherToCloser = tupleSegment( furtherShip.getPos(), closerShip.getPos() ) if warpAxis == 'x': furtherShip.setPos( ( furtherShip.getPos()[0] + furtherToCloser[0]*2, furtherShip.getPos()[1] ) ) elif warpAxis == 'y': furtherShip.setPos( ( furtherShip.getPos()[0], furtherShip.getPos()[1] + furtherToCloser[1]*2 ) ) def warpPlanet(self, warpAxis): planetPos = vec3ToTuple( self.planet.getPos() ) planetToCamera = tupleSegment( planetPos, self.getCameraPos() ) if warpAxis == 'x': self.planet.setPos( planetPos[0] + planetToCamera[0]*2, planetPos[1], 0 ) self.planetCollGeom.setPosition( planetPos[0] + planetToCamera[0]*2, planetPos[1], 0 ) elif warpAxis == 'y': self.planet.setPos( planetPos[0], planetPos[1] + planetToCamera[1]*2, 0 ) self.planetCollGeom.setPosition( planetPos[0], planetPos[1] + planetToCamera[1]*2, 0 ) def restartGame(self): self.planet.setPos( Vec3() ) self.planetCollGeom.setPosition( Vec3() ) offlimits = [ ( vec3ToTuple( self.planet.getPos() ), 102 ) ] # Reset ship one self.ships[0].setPos( self.generateRandomStartPos( offlimits ) ) self.ships[0].heading = random.random()*360 self.ships[0].setVel( Ship.VEL_DEFAULT ) self.ships[0].isAlive = True self.ships[0].health = Ship.HEALTH self.ships[0].visualNode.show() for bullet in self.ships[0].bullets: bullet['isAlive'] = False offlimits.append( ( self.ships[0].getPos(), 128 ) ) # Reset ship two self.ships[1].setPos( self.generateRandomStartPos( offlimits ) ) self.ships[1].heading = random.random()*360 self.ships[1].setVel( Ship.VEL_DEFAULT ) self.ships[1].isAlive = True self.ships[1].health = Ship.HEALTH self.ships[1].visualNode.show() for bullet in self.ships[1].bullets: bullet['isAlive'] = False for s in self.ships: s.update( 1/60. ) self.gameFrames = 0 playerOneScore = self.players[0].score playerTwoScore = self.players[1].score if playerOneScore >= Game.MATCH_MAX_POINTS: self.showGameWinnerText(self.players[0]) self.players[0].score = 0 self.players[1].score = 0 if playerTwoScore >= Game.MATCH_MAX_POINTS: self.showGameWinnerText(self.players[1]) self.players[0].score = 0 self.players[1].score = 0 playerOneScore = self.players[0].score playerTwoScore = self.players[1].score self.scorePlayerOne.setText( 'Score: ' + str(playerOneScore) ) self.scorePlayerTwo.setText( 'Score: ' + str(playerTwoScore) ) def showWinnerText(self, player): self.winnerText.setText( player.name + " " + Game.WINNER_TEXT ) self.winnerText.show() def showGameWinnerText(self, player): self.winnerText.setText( player.name + " wins the match!" ) self.winnerText.show() def registerListeners(self): playerOne = self.getPlayers()[0] playerTwo = self.getPlayers()[1] shipOne = self.getShips()[0] shipTwo = self.getShips()[1] # Player one events playerOneMoveForwardOn = createNamedEvent( playerOne.name, Event.PLAYER_MOVE_FORWARD_ON ) playerOneMoveForwardOff = createNamedEvent( playerOne.name, Event.PLAYER_MOVE_FORWARD_OFF ) playerOneRotateLeftOn = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_LEFT_ON ) playerOneRotateLeftOff = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_LEFT_OFF ) playerOneRotateRightOn = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_RIGHT_ON ) playerOneRotateRightOff = createNamedEvent( playerOne.name, Event.PLAYER_ROTATE_RIGHT_OFF ) playerOneShoot = createNamedEvent( playerOne.name, Event.PLAYER_SHOOT ) base.accept(playerOneMoveForwardOn, shipOne.thrustOn) base.accept(playerOneMoveForwardOff, shipOne.thrustOff) base.accept(playerOneRotateLeftOn, shipOne.rotateLeftOn) base.accept(playerOneRotateLeftOff, shipOne.rotateLeftOff) base.accept(playerOneRotateRightOn, shipOne.rotateRightOn) base.accept(playerOneRotateRightOff, shipOne.rotateRightOff) base.accept(playerOneShoot, shipOne.shoot) # Player two events playerTwoMoveForwardOn = createNamedEvent( playerTwo.name, Event.PLAYER_MOVE_FORWARD_ON ) playerTwoMoveForwardOff = createNamedEvent( playerTwo.name, Event.PLAYER_MOVE_FORWARD_OFF ) playerTwoRotateLeftOn = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_LEFT_ON ) playerTwoRotateLeftOff = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_LEFT_OFF ) playerTwoRotateRightOn = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_RIGHT_ON ) playerTwoRotateRightOff = createNamedEvent( playerTwo.name, Event.PLAYER_ROTATE_RIGHT_OFF ) playerTwoShoot = createNamedEvent( playerTwo.name, Event.PLAYER_SHOOT ) base.accept(playerTwoMoveForwardOn, shipTwo.thrustOn) base.accept(playerTwoMoveForwardOff, shipTwo.thrustOff) base.accept(playerTwoRotateLeftOn, shipTwo.rotateLeftOn) base.accept(playerTwoRotateLeftOff, shipTwo.rotateLeftOff) base.accept(playerTwoRotateRightOn, shipTwo.rotateRightOn) base.accept(playerTwoRotateRightOff, shipTwo.rotateRightOff) base.accept(playerTwoShoot, shipTwo.shoot) # Player one key mapping base.accept(Game.PLAYER_ONE_FORWARD_KEY, playerOne.moveForwardOn) base.accept("control-" + Game.PLAYER_ONE_FORWARD_KEY, playerOne.moveForwardOn) base.accept(Game.PLAYER_ONE_FORWARD_KEY + "-up", playerOne.moveForwardOff) base.accept(Game.PLAYER_ONE_ROTATE_LEFT_KEY, playerOne.rotateLeftOn) base.accept("control-" + Game.PLAYER_ONE_ROTATE_LEFT_KEY, playerOne.rotateLeftOn) base.accept(Game.PLAYER_ONE_ROTATE_LEFT_KEY + "-up", playerOne.rotateLeftOff) base.accept(Game.PLAYER_ONE_ROTATE_RIGHT_KEY, playerOne.rotateRightOn) base.accept("control-" + Game.PLAYER_ONE_ROTATE_RIGHT_KEY, playerOne.rotateRightOn) base.accept(Game.PLAYER_ONE_ROTATE_RIGHT_KEY + "-up", playerOne.rotateRightOff) base.accept(Game.PLAYER_ONE_SHOOT, playerOne.shoot) # Player two key mapping base.accept(Game.PLAYER_TWO_FORWARD_KEY, playerTwo.moveForwardOn) base.accept("control-" + Game.PLAYER_TWO_FORWARD_KEY, playerTwo.moveForwardOn) base.accept(Game.PLAYER_TWO_FORWARD_KEY + "-up", playerTwo.moveForwardOff) base.accept(Game.PLAYER_TWO_ROTATE_LEFT_KEY, playerTwo.rotateLeftOn) base.accept("control-" + Game.PLAYER_TWO_ROTATE_LEFT_KEY, playerTwo.rotateLeftOn) base.accept(Game.PLAYER_TWO_ROTATE_LEFT_KEY + "-up", playerTwo.rotateLeftOff) base.accept(Game.PLAYER_TWO_ROTATE_RIGHT_KEY, playerTwo.rotateRightOn) base.accept("control-" + Game.PLAYER_TWO_ROTATE_RIGHT_KEY, playerTwo.rotateRightOn) base.accept(Game.PLAYER_TWO_ROTATE_RIGHT_KEY + "-up", playerTwo.rotateRightOff) base.accept(Game.PLAYER_TWO_SHOOT, playerTwo.shoot) # Game specific key mapping base.accept("escape", sys.exit) base.accept( "f1", self.switchCameraMode, [Game.CAMERA_MODE_FPS_ONE] ) base.accept( "f2", self.switchCameraMode, [Game.CAMERA_MODE_FPS_TWO] ) base.accept( "f3", self.switchCameraMode, [Game.CAMERA_MODE_GAME] ) base.accept( "f4", self.switchCameraMode, [Game.CAMERA_MODE_STILL] ) base.accept( "p", self.togglePause ) # The game is now listening to all the necessary events self.isListening = True def togglePause(self): self.pause = not self.pause def windowExists(self): return base.isMainWindowOpen() def getShips(self): return self.ships def getPlayers(self): return self.players def switchCameraMode(self, cameraMode): self.cameraMode = cameraMode if cameraMode == Game.CAMERA_MODE_FPS_ONE: angle = self.ships[0].heading * math.pi / 180.0 headingX = math.cos(angle) headingY = math.sin(angle) offset = Vec3( headingX, headingY, 0 ) pos = self.ships[0].visualNode.getChildren()[0].getPos() base.camera.setPos( pos[0] + offset[0], pos[1] + offset[1] - Game.CAMERA_FPS_OFFSET_HEIGHT, pos[2] - Game.CAMERA_FPS_OFFSET_BACK ) hpr = self.ships[0].visualNode.getChildren()[0].getHpr() base.camera.setHpr( hpr[0], hpr[1] + 90, hpr[2] ) base.camera.reparentTo(self.ships[0].visualNode) if cameraMode == Game.CAMERA_MODE_FPS_TWO: angle = self.ships[1].heading * math.pi / 180.0 headingX = math.cos(angle) headingY = math.sin(angle) offset = Vec3( headingX, headingY, 0 ) pos = self.ships[1].visualNode.getChildren()[0].getPos() base.camera.setPos( pos[0] + offset[0], pos[1] + offset[1] - Game.CAMERA_FPS_OFFSET_HEIGHT, pos[2] - Game.CAMERA_FPS_OFFSET_BACK ) hpr = self.ships[1].visualNode.getChildren()[0].getHpr() base.camera.setHpr( hpr[0], hpr[1] + 90, hpr[2] ) base.camera.reparentTo(self.ships[1].visualNode) if cameraMode == Game.CAMERA_MODE_GAME: base.camera.setHpr(Game.CAMERA_HPR_DEFAULT) base.camera.reparentTo(render) if cameraMode == Game.CAMERA_MODE_STILL: base.camera.reparentTo(render)
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
from pandac.PandaModules import loadPrcFileData from direct.directbase import DirectStart from pandac.PandaModules import OdeWorld, OdeSimpleSpace, OdeJointGroup from pandac.PandaModules import OdeBody, OdeMass, OdeSphereGeom, OdePlaneGeom from pandac.PandaModules import BitMask32, CardMaker, Vec4, Quat from pandac.PandaModules import PNMImage, PNMPainter, PNMBrush, Texture from random import randint, random # Setup our physics world world = OdeWorld() world.setGravity(0, 0, -9.81) # The surface table is needed for autoCollide world.initSurfaceTable(1) world.setSurfaceEntry(0, 0, 100, 1.0, 9.1, 0.9, 0.00001, 0.0, 0.002) # Create a space and add a contactgroup to it to add the contact joints space = OdeSimpleSpace() space.setAutoCollideWorld(world) contactgroup = OdeJointGroup() space.setAutoCollideJointGroup(contactgroup) # Load the ball ball = loader.loadModel("cilindroB") ball.flattenLight() # Apply transform ball.setTextureOff() # Add a random amount of balls balls = [] # This 'balls' list contains tuples of nodepaths with their ode geoms for i in range(15):