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
Пример #2
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()
Пример #3
0
    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)
Пример #4
0
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
Пример #6
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()
Пример #7
0
	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)
Пример #8
0
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)
Пример #9
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
Пример #10
0
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)
Пример #11
0
 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)
Пример #12
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
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)
Пример #14
0
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()
Пример #15
0
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)
Пример #16
0
class Physical(object):
    world = OdeWorld()
    world.setGravity(0, 0, 0)

    def __init__(self):
        self.world = Physical.world
Пример #17
0
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)
Пример #19
0
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
Пример #20
0
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
Пример #21
0
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
Пример #22
0
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)
Пример #23
0
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
Пример #24
0
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):