示例#1
0
    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)
示例#2
0
文件: Pylon.py 项目: i-k/SpaceGrabem
    def __init__(self, game, power = 50.0, range = 30):
        self.game = game
        self.POWER = power
        self.Active = False
        self.RANGE = range
        
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 3)
        #self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
        
        self.triggerGeom = OdeSphereGeom( range ) 
        self.triggerGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.triggerGeom.setCollideBits( BitMask32(0xffffffff) )
                
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        self.model = loader.loadModel('AbsorbingPylon.egg')
        self.model.setScale(1.5)
        self.model.reparentTo(self.visualNode)
        
        pow = self.getPower()*5
        maxPow = self.game.MAX_PYLON_POWER
        if (pow > 0):
            self.offColor = Vec4(pow/maxPow, 0.0, 0.0, 0.0)
            self.onColor = Vec4(0.0, pow/maxPow, 0.0, 0.0)

        if (pow <= 0):
            self.offColor = Vec4(0.0, 0.0, -pow/maxPow, 0.0)
            self.onColor = Vec4(0.0, -pow/maxPow, 0.0, 0.0)
            
        self.setColor( self.offColor )
class Sphere(GameObject):
	def __init__(self, world, parent, color, pos, dir, radius, density, posParent=None):
		GameObject.__init__(self, world)

		self.node = parent.attachNewNode("")
		if posParent == None:
			self.node.setPos(*pos)
		else:
			self.node.setPos(posParent, *pos)
		self.node.setColor(*color)
		self.node.setScale(radius)
		self.node.lookAt(self.node, *dir)
		self.parent = parent

		self.color = color
		self.scale = radius

		self.model = loader.loadModel("models/smiley.egg")
		self.model.reparentTo(self.node)

		self.mass = OdeMass()
		self.mass.setSphere(density, radius)
		self.body = OdeBody(world.world)
		self.body.setMass(self.mass)
		self.body.setPosition(self.node.getPos())
		self.body.setQuaternion(self.node.getQuat())
		self.body.setData(self)
		self.geom = OdeSphereGeom(world.space, radius)
		self.geom.setBody(self.body)
		world.space.setSurfaceType(self.geom, world.surfaces["sphere"])

	def onCollision(self, otherBody, entry):
		if otherBody.isEmpty(): # Collision on a wall
			geom = entry.getContactGeom(0)
			Ripple(self.parent, self.color, geom.getPos(), geom.getNormal() * -1, self.scale * 2.5)
示例#4
0
    def createCircularObstacle(self, pos, obstacleIndex):
        """Create one physics obstacle. Returns a nodePath"""
        self.notify.debug("create obstacleindex %s" % (obstacleIndex))

        geom = OdeSphereGeom(self.space, IceGameGlobals.TireRadius)
        geom.setCollideBits(self.allTiresMask)  # we only collide against tires
        geom.setCategoryBits(self.obstacleMask)
        self.space.setCollideId(geom, self.obstacleCollideId)

        #tireModel = loader.loadModel('phase_3/models/misc/sphere')
        tireModel = loader.loadModel(
            "phase_4/models/minigames/ice_game_tirestack")

        # assuming it has a radius of 1
        tireHeight = 1
        #tireModel.setScale(IceGameGlobals.TireRadius, IceGameGlobals.TireRadius,  IceGameGlobals.TireRadius)
        #tireModel.setZ( 0 - IceGameGlobals.TireRadius + (tireHeight /2.0))
        #tireModel.setZ(IceGameGlobals.TireRadius)
        tireModel.setPos(pos)
        #tireModel.setColor(0.5,0.5,0.5)
        tireModel.reparentTo(render)
        geom.setPosition(tireModel.getPos())

        # the real assets are set at Z zero
        tireModel.setZ(0)
        return tireModel
示例#5
0
 def createBallGeom(self, modelNode, ballBody, space):
     ballGeom = OdeSphereGeom(space, 1)
     ballGeom.setCollideBits(BitMask32(0x2))
     ballGeom.setCategoryBits(BitMask32(0x1))
     ballGeom.setBody(ballBody)
     space.setSurfaceType(ballGeom, SurfaceType.BALL)
     return ballGeom
示例#6
0
    def createTire(self, tireIndex):
        if tireIndex < 0 or tireIndex >= len(self.tireMasks):
            self.notify.error('invalid tireIndex %s' % tireIndex)

        self.notify.debug('create tireindex %s' % tireIndex)
        zOffset = 0
        body = OdeBody(self.world)
        mass = OdeMass()
        mass.setSphere(self.tireDensity, IceGameGlobals.TireRadius)
        body.setMass(mass)
        body.setPosition(IceGameGlobals.StartingPositions[tireIndex][0],
                         IceGameGlobals.StartingPositions[tireIndex][1],
                         IceGameGlobals.StartingPositions[tireIndex][2])
        body.setAutoDisableDefaults()
        geom = OdeSphereGeom(self.space, IceGameGlobals.TireRadius)
        self.space.setSurfaceType(geom, self.tireSurfaceType)
        self.space.setCollideId(geom, self.tireCollideIds[tireIndex])
        self.massList.append(mass)
        self.geomList.append(geom)
        geom.setCollideBits(self.allTiresMask | self.wallMask | self.floorMask
                            | self.obstacleMask)
        geom.setCategoryBits(self.tireMasks[tireIndex])
        geom.setBody(body)
        if self.notify.getDebug():
            self.notify.debug('tire geom id')
            geom.write()
            self.notify.debug(' -')

        if self.canRender:
            testTire = render.attachNewNode('tire holder %d' % tireIndex)
            smileyModel = NodePath()
            if not smileyModel.isEmpty():
                smileyModel.setScale(IceGameGlobals.TireRadius)
                smileyModel.reparentTo(testTire)
                smileyModel.setAlphaScale(0.5)
                smileyModel.setTransparency(1)

            testTire.setPos(IceGameGlobals.StartingPositions[tireIndex])
            tireModel = loader.loadModel(
                'phase_4/models/minigames/ice_game_tire')
            tireHeight = 1
            tireModel.setZ(-(IceGameGlobals.TireRadius) + 0.01)
            tireModel.reparentTo(testTire)
            self.odePandaRelationList.append((testTire, body))
        else:
            testTire = None
            self.bodyList.append((None, body))
        return (testTire, body, geom)
示例#7
0
    def __init__(self, game, color):
        self.game = game
        
        
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        model = loader.loadModel('testipalikka.egg')
        model.reparentTo(self.visualNode)

        plight = PointLight('plight')
        plight.setPoint( Point3(0.6, 0, 5) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.5, 0.01, 0.01) )
        plightNodePath = model.attachNewNode(plight)
        model.setLight(plightNodePath)
        
        self.body = OdeBody(game.physicsWorld)
        self.mass = OdeMass()
        self.mass.setBox(10,1,1,1)
        self.body.setMass(self.mass)
        self.body.setGravityMode(False)
        #self.juttu = OdeUtil()
        
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 2)
        self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
示例#8
0
    def __init__(self, game, color):
        #self.POWER = 100
        self.game = game
        
        self.thrust = False
        self.thrustLeft = False
        self.thrustRight = False
        self.thrustBack = False
        self.rotation = 0

        self.body = OdeBody(game.physicsWorld)
        self.mass = OdeMass()
        self.mass.setBox(10,1,1,1)
        self.body.setMass(self.mass)

        #odespheregeom(... , size of hitbox sphere)
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 5)
        self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
        
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        model = loader.loadModel('lautanen2.egg')
        model.reparentTo(self.visualNode)
        
        plight = PointLight('plight')
        plight.setPoint( Point3(0.6, 0, 5) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.5, 0.01, 0.01) )
        plightNodePath = model.attachNewNode(plight)
        model.setLight(plightNodePath)
示例#9
0
  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)
	def __init__(self, world, parent, color, pos, dir, radius, density, posParent=None):
		GameObject.__init__(self, world)

		self.node = parent.attachNewNode("")
		if posParent == None:
			self.node.setPos(*pos)
		else:
			self.node.setPos(posParent, *pos)
		self.node.setColor(*color)
		self.node.setScale(radius)
		self.node.lookAt(self.node, *dir)
		self.parent = parent

		self.color = color
		self.scale = radius

		self.model = loader.loadModel("models/smiley.egg")
		self.model.reparentTo(self.node)

		self.mass = OdeMass()
		self.mass.setSphere(density, radius)
		self.body = OdeBody(world.world)
		self.body.setMass(self.mass)
		self.body.setPosition(self.node.getPos())
		self.body.setQuaternion(self.node.getQuat())
		self.body.setData(self)
		self.geom = OdeSphereGeom(world.space, radius)
		self.geom.setBody(self.body)
		world.space.setSurfaceType(self.geom, world.surfaces["sphere"])
示例#11
0
    def __init__(self, game, color, value = 1, drain = 20):
        self.game = game
        self.VALUE = value
        self.DRAIN = drain
        
        #self.idnumber = id
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        model = loader.loadModel('Ball2.egg')
        model.setScale(2.5)
        model.reparentTo(self.visualNode)

        plight = PointLight('plight')
        plight.setPoint( Point3(0, 0, 3) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.05, 0.01, 0.01) )
        self.plightNodePath = model.attachNewNode(plight)
        model.setLight(self.plightNodePath)

        self.body = OdeBody(game.physicsWorld)
        self.mass = OdeMass()
        self.mass.setBox(10,1,1,1)
        self.body.setMass(self.mass)

        self.body.setGravityMode(True)

        #self.body.setGravityMode(False)
        #self.juttu = OdeUtil()
        
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 3.5)
        self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
class Sphere(GameObject):
    def __init__(self,
                 world,
                 parent,
                 color,
                 pos,
                 dir,
                 radius,
                 density,
                 posParent=None):
        GameObject.__init__(self, world)

        self.node = parent.attachNewNode("")
        if posParent == None:
            self.node.setPos(*pos)
        else:
            self.node.setPos(posParent, *pos)
        self.node.setColor(*color)
        self.node.setScale(radius)
        self.node.lookAt(self.node, *dir)
        self.parent = parent

        self.color = color
        self.scale = radius

        self.model = loader.loadModel("models/smiley.egg")
        self.model.reparentTo(self.node)

        self.mass = OdeMass()
        self.mass.setSphere(density, radius)
        self.body = OdeBody(world.world)
        self.body.setMass(self.mass)
        self.body.setPosition(self.node.getPos())
        self.body.setQuaternion(self.node.getQuat())
        self.body.setData(self)
        self.geom = OdeSphereGeom(world.space, radius)
        self.geom.setBody(self.body)
        world.space.setSurfaceType(self.geom, world.surfaces["sphere"])

    def onCollision(self, otherBody, entry):
        if otherBody.isEmpty():  # Collision on a wall
            geom = entry.getContactGeom(0)
            Ripple(self.parent, self.color, geom.getPos(),
                   geom.getNormal() * -1, self.scale * 2.5)
示例#13
0
 def createCircularObstacle(self, pos, obstacleIndex):
     self.notify.debug('create obstacleindex %s' % obstacleIndex)
     geom = OdeSphereGeom(self.space, IceGameGlobals.TireRadius)
     geom.setCollideBits(self.allTiresMask)
     geom.setCategoryBits(self.obstacleMask)
     self.space.setCollideId(geom, self.obstacleCollideId)
     tireModel = loader.loadModel('phase_4/models/minigames/ice_game_tirestack')
     tireHeight = 1
     tireModel.setPos(pos)
     tireModel.reparentTo(render)
     geom.setPosition(tireModel.getPos())
     tireModel.setZ(0)
     return tireModel
 def createTire(self, tireIndex):
     if tireIndex < 0 or tireIndex >= len(self.tireMasks):
         self.notify.error("invalid tireIndex %s" % tireIndex)
     self.notify.debug("create tireindex %s" % tireIndex)
     zOffset = 0
     body = OdeBody(self.world)
     mass = OdeMass()
     mass.setSphere(self.tireDensity, IceGameGlobals.TireRadius)
     body.setMass(mass)
     body.setPosition(
         IceGameGlobals.StartingPositions[tireIndex][0],
         IceGameGlobals.StartingPositions[tireIndex][1],
         IceGameGlobals.StartingPositions[tireIndex][2],
     )
     body.setAutoDisableDefaults()
     geom = OdeSphereGeom(self.space, IceGameGlobals.TireRadius)
     self.space.setSurfaceType(geom, self.tireSurfaceType)
     self.space.setCollideId(geom, self.tireCollideIds[tireIndex])
     self.massList.append(mass)
     self.geomList.append(geom)
     geom.setCollideBits(self.allTiresMask | self.wallMask | self.floorMask | self.obstacleMask)
     geom.setCategoryBits(self.tireMasks[tireIndex])
     geom.setBody(body)
     if self.notify.getDebug():
         self.notify.debug("tire geom id")
         geom.write()
         self.notify.debug(" -")
     if self.canRender:
         testTire = render.attachNewNode("tire holder %d" % tireIndex)
         smileyModel = NodePath()
         if not smileyModel.isEmpty():
             smileyModel.setScale(IceGameGlobals.TireRadius)
             smileyModel.reparentTo(testTire)
             smileyModel.setAlphaScale(0.5)
             smileyModel.setTransparency(1)
         testTire.setPos(IceGameGlobals.StartingPositions[tireIndex])
         tireModel = loader.loadModel("phase_4/models/minigames/ice_game_tire")
         tireHeight = 1
         tireModel.setZ(-IceGameGlobals.TireRadius + 0.01)
         tireModel.reparentTo(testTire)
         self.odePandaRelationList.append((testTire, body))
     else:
         testTire = None
         self.bodyList.append((None, body))
     return (testTire, body, geom)
示例#15
0
 def __init__(
         self,
         name=NAME_DEFAULT,
         pos=POS_DEFAULT,
         heading=HEADING_DEFAULT,
         vel=VEL_DEFAULT,
         acc=ACC_DEFAULT  # player controlled acceleration. Can be 0.0 - 1.0
 ):
     """@param name string"""
     self.name = name
     self.pos = pos
     self.vel = vel
     self.acc = acc
     self.heading = heading
     self.rotateLeft = False
     self.rotateRight = False
     self.visualNode = self.createVisualNode(self.pos)
     self.bullets = []
     self.collisionHandler = colHandler
     self.collisions = []
     self.collisionSphere = OdeSphereGeom(4)
     self.collisionSphere.setCategoryBits(BitMask32(0xffffffff))
     self.collisionSphere.setCollideBits(BitMask32(0xffffffff))
     self.collisionSphere.setPosition(pos[0], pos[1], 0)
     self.forces = []
     self.mass = 1.0
     self.health = Ship.HEALTH
     self.isAlive = True
     self.shootingSound = loader.loadSfx('anti_tank_gun_single_shot.mp3')
     self.destroySound = loader.loadSfx('large_explosion.mp3')
     self.bulletHitSound = loader.loadSfx(
         'explosion_loud_internal_explosion_very_reverberant.mp3')
     self.collisionSound = loader.loadSfx('car_door_close.mp3')
     self.bulletParent = NodePath("Bullet Parent")
     self.bulletParent.reparentTo(render)
     self.bulletAmbientLight = AmbientLight('Bullet Light')
     self.bulletAmbientLight.setColor(Vec4(.0, .1, .2, .0))
     lightnode = render.attachNewNode(self.bulletAmbientLight)
     self.bulletParent.setLight(lightnode)
示例#16
0
    def initPlanet(self, parent, tex, pos, radius, mass, lvel, avel):
        planet = loader.loadModel(self.main.modeld + "planet")
        planet.reparentTo(parent)
        planet_tex = loader.loadTexture(tex)
        planet.setTexture(planet_tex)
        planet.setPos(pos)
        planet.setScale(radius)

        body = OdeBody(self.main.physicsWorld)
        M = OdeMass()
        M.setSphereTotal(mass, radius)
        body.setMass(M)
        body.setPosition(planet.getPos(parent))
        body.setQuaternion(planet.getQuat(parent))
        body.setLinearVel(lvel)
        body.setAngularVel(avel)

        geom = OdeSphereGeom(self.main.space, radius)
        geom.setBody(body)

        self.main.getPlist().append(planet)
        self.main.getBlist().append(body)
        self.main.getGlist().append(geom)
    def __init__(self,
                 world,
                 parent,
                 color,
                 pos,
                 dir,
                 radius,
                 density,
                 posParent=None):
        GameObject.__init__(self, world)

        self.node = parent.attachNewNode("")
        if posParent == None:
            self.node.setPos(*pos)
        else:
            self.node.setPos(posParent, *pos)
        self.node.setColor(*color)
        self.node.setScale(radius)
        self.node.lookAt(self.node, *dir)
        self.parent = parent

        self.color = color
        self.scale = radius

        self.model = loader.loadModel("models/smiley.egg")
        self.model.reparentTo(self.node)

        self.mass = OdeMass()
        self.mass.setSphere(density, radius)
        self.body = OdeBody(world.world)
        self.body.setMass(self.mass)
        self.body.setPosition(self.node.getPos())
        self.body.setQuaternion(self.node.getQuat())
        self.body.setData(self)
        self.geom = OdeSphereGeom(world.space, radius)
        self.geom.setBody(self.body)
        world.space.setSurfaceType(self.geom, world.surfaces["sphere"])
 def createCircularObstacle(self, pos, obstacleIndex):
     self.notify.debug('create obstacleindex %s' % obstacleIndex)
     geom = OdeSphereGeom(self.space, IceGameGlobals.TireRadius)
     geom.setCollideBits(self.allTiresMask)
     geom.setCategoryBits(self.obstacleMask)
     self.space.setCollideId(geom, self.obstacleCollideId)
     tireModel = loader.loadModel('phase_4/models/minigames/ice_game_tirestack')
     tireHeight = 1
     tireModel.setPos(pos)
     tireModel.reparentTo(render)
     geom.setPosition(tireModel.getPos())
     tireModel.setZ(0)
     return tireModel
示例#19
0
    def shoot(self):
        # TODO: add proper unit tests!
        angle = self.heading * math.pi / 180.0
        headingX = math.cos(angle)
        headingY = math.sin(angle)
        offset = Vec3(headingX, headingY, 0) * Ship.BULLET_OFFSET
        shipPos = self.getPos()
        bulletPos = (offset[0] + shipPos[0], offset[1] + shipPos[1], offset[2])

        bulletVisual = loader.loadModel("bullet.bam")
        bulletVisual.setPos(tupleToVec3(bulletPos))
        bulletVisual.setHpr(tupleToVec3((self.heading + 90, 180)))
        bulletVisual.setScale(1.5)
        bulletVisual.reparentTo(self.bulletParent)

        # Create physics for bullet
        collisionSphere = OdeSphereGeom(1.5)
        collisionSphere.setCategoryBits(BitMask32(0xffffffff))
        collisionSphere.setCollideBits(BitMask32(0xffffffff))
        collisionSphere.setPosition(bulletPos[0], bulletPos[1], bulletPos[2])

        shipVel = self.getVel()

        bullet = {
            'vel': (headingX * Ship.BULLET_SPEED +
                    shipVel[0] / Ship.BULLET_SHIP_SPEED_CORRELATION,
                    headingY * Ship.BULLET_SPEED +
                    shipVel[1] / Ship.BULLET_SHIP_SPEED_CORRELATION),
            'visual':
            bulletVisual,
            'physical':
            collisionSphere,
            'isAlive':
            True,
            'timeToLive':
            Ship.BULLET_MAX_LIFE_TIME
        }
        self.bullets.append(bullet)
        self.shootingSound.play()
示例#20
0
    def __init__(self, game, color):

        self.POWER = 200
        self.game = game
        self.SHIP_TYPE = "RAKETTI"
        self.Ball_offset = 10.0
     #   self.hasBall = False
        self.thrust = False
        self.thrustLeft = False
        self.thrustRight = False
        self.thrustBack = False
        self.rotation = 0

        self.body = OdeBody(game.physicsWorld)
        self.mass = OdeMass()
        self.mass.setBox(10,1,1,1)
        self.body.setMass(self.mass)
        #self.body.setGravityMode(False)

        #odespheregeom(... , size of hitbox sphere)
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 3)
        self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
        
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        model = loader.loadModel('spaceship.egg')
        model.setH(180)
        model.setY(15)
        model.reparentTo(self.visualNode)
        self.visualNode.setScale(0.4)
        plight = PointLight('plight')
        plight.setPoint( Point3(0.6, 0, 5) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.5, 0.01, 0.01) )
        plightNodePath = model.attachNewNode(plight)
        model.setLight(plightNodePath)
示例#21
0
 def __init__(self, game, power = 10):
     self.game = game
     self.POWER = power
     self.Active = False
     
     
     self.collGeom = OdeSphereGeom( self.game.physicsSpace, 3)
     #self.collGeom.setBody(self.body)
     self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
     self.collGeom.setCollideBits( BitMask32(0xffffffff) )
     
     self.visualNode = NodePath('Visual node')
     self.visualNode.reparentTo(render)
     self.model = loader.loadModel('AbsorbingPylon.egg')
     self.model.setScale(2)
     self.model.reparentTo(self.visualNode)
     
     #TODO: trigger geom
     #self.effectGeom = OdeSphereGeom(  )
     
     if (self.getPower() > 0):
         self.setColor( Vec4(1.0, 0.0, 0.0, 0.0) )
     if (self.getPower() <= 0):
         self.setColor( Vec4(0.0, 0.0, 1.0, 0.0) )
示例#22
0
class Ship:

    NAME_DEFAULT = "unnamed"
    POS_DEFAULT = (0, 30)
    VEL_DEFAULT = (0, 0)
    ACC_DEFAULT = 0.0  # 0.0 - 1.0
    HEADING_DEFAULT = -90.0
    ACC_COEFFICIENT = 35.0  # This is how much acceleration affects speed
    ROTATION_SPEED = 200
    MODEL_ROTATION_OFFSET = (0.0, 0.0, -5.0)
    HEALTH = 10.0
    BULLET_OFFSET = 5.0  # This is how far ahead the bullet spawns at
    BULLET_SPEED = 200
    BULLET_SHIP_SPEED_CORRELATION = 40.0
    BULLET_MAX_LIFE_TIME = 100
    BULLET_DAMAGE = 1.0
    PLANET_DAMAGE = 0.5
    SPEED_MAX = 50.0

    def __init__(
            self,
            name=NAME_DEFAULT,
            pos=POS_DEFAULT,
            heading=HEADING_DEFAULT,
            vel=VEL_DEFAULT,
            acc=ACC_DEFAULT  # player controlled acceleration. Can be 0.0 - 1.0
    ):
        """@param name string"""
        self.name = name
        self.pos = pos
        self.vel = vel
        self.acc = acc
        self.heading = heading
        self.rotateLeft = False
        self.rotateRight = False
        self.visualNode = self.createVisualNode(self.pos)
        self.bullets = []
        self.collisionHandler = colHandler
        self.collisions = []
        self.collisionSphere = OdeSphereGeom(4)
        self.collisionSphere.setCategoryBits(BitMask32(0xffffffff))
        self.collisionSphere.setCollideBits(BitMask32(0xffffffff))
        self.collisionSphere.setPosition(pos[0], pos[1], 0)
        self.forces = []
        self.mass = 1.0
        self.health = Ship.HEALTH
        self.isAlive = True
        self.shootingSound = loader.loadSfx('anti_tank_gun_single_shot.mp3')
        self.destroySound = loader.loadSfx('large_explosion.mp3')
        self.bulletHitSound = loader.loadSfx(
            'explosion_loud_internal_explosion_very_reverberant.mp3')
        self.collisionSound = loader.loadSfx('car_door_close.mp3')
        self.bulletParent = NodePath("Bullet Parent")
        self.bulletParent.reparentTo(render)
        self.bulletAmbientLight = AmbientLight('Bullet Light')
        self.bulletAmbientLight.setColor(Vec4(.0, .1, .2, .0))
        lightnode = render.attachNewNode(self.bulletAmbientLight)
        self.bulletParent.setLight(lightnode)

    def createVisualNode(self, pos=(0, 0)):
        # modelNode is the actualy ship model
        modelNode = loader.loadModel("indicator.bam")
        # visualNode is the node we operate on to move and rotate the ship
        visualNode = NodePath('Ship: ' + self.name)
        visualNode.setPos(tupleToVec3(pos))
        visualNode.setHpr(Vec3(0, -90, 90))
        # TODO: add scale parameter to this or some other aggregator class
        visualNode.setScale(1)
        # Reparent the actual modelNode to the visualNode
        modelNode.reparentTo(visualNode)
        # Offset the model node relative to the parent
        modelNode.setPos(tripleToVec3(Ship.MODEL_ROTATION_OFFSET))
        visualNode.reparentTo(render)
        return visualNode

    def applyForce(self, force):
        self.forces.append(force)

    def setCollisionHandler(self, handler):
        self.collisionHandler = handler

    def addCollision(self, col):
        self.collisions.append(col)
        self.collisionSound.play()

    def getCollisions(self):
        return self.collisions

    def getVisualNode(self):
        return self.visualNode

    def getMass(self):
        return self.mass

    def isVisible(self):
        result = False
        visualNode = self.getVisualNode()
        # To be visible the ship has to be not hidden and has to have render as
        # the master parent (aka getTop).
        result = (not visualNode.isHidden()) and (visualNode.getTop()
                                                  == render)
        return result

    def setPos(self, pos):
        self.pos = pos

    def getPos(self):
        return self.pos

    def setVel(self, vel):
        self.vel = vel
        self.momentum = vel

    def getVel(self):
        return self.vel

    def getAcc(self):
        return self.acc

    def getHeading(self):
        return self.heading

    def shoot(self):
        # TODO: add proper unit tests!
        angle = self.heading * math.pi / 180.0
        headingX = math.cos(angle)
        headingY = math.sin(angle)
        offset = Vec3(headingX, headingY, 0) * Ship.BULLET_OFFSET
        shipPos = self.getPos()
        bulletPos = (offset[0] + shipPos[0], offset[1] + shipPos[1], offset[2])

        bulletVisual = loader.loadModel("bullet.bam")
        bulletVisual.setPos(tupleToVec3(bulletPos))
        bulletVisual.setHpr(tupleToVec3((self.heading + 90, 180)))
        bulletVisual.setScale(1.5)
        bulletVisual.reparentTo(self.bulletParent)

        # Create physics for bullet
        collisionSphere = OdeSphereGeom(1.5)
        collisionSphere.setCategoryBits(BitMask32(0xffffffff))
        collisionSphere.setCollideBits(BitMask32(0xffffffff))
        collisionSphere.setPosition(bulletPos[0], bulletPos[1], bulletPos[2])

        shipVel = self.getVel()

        bullet = {
            'vel': (headingX * Ship.BULLET_SPEED +
                    shipVel[0] / Ship.BULLET_SHIP_SPEED_CORRELATION,
                    headingY * Ship.BULLET_SPEED +
                    shipVel[1] / Ship.BULLET_SHIP_SPEED_CORRELATION),
            'visual':
            bulletVisual,
            'physical':
            collisionSphere,
            'isAlive':
            True,
            'timeToLive':
            Ship.BULLET_MAX_LIFE_TIME
        }
        self.bullets.append(bullet)
        self.shootingSound.play()

    def bulletHit(self):
        self.health -= Ship.BULLET_DAMAGE
        if self.health <= 0:
            self.destroy()
        self.bulletHitSound.play()

    def planetHit(self):
        self.health -= Ship.PLANET_DAMAGE
        if self.health <= 0.0:
            self.destroy()
        self.bulletHitSound.play()

    def destroyBullet(self, bullet):
        bullet['visual'].removeNode()
        #bullet['physical'].destroy()
        bullet['physical'].disable()
        # If the "bullet['physical'].destroy()" line is giving errors use the
        # following one instead:
        #bullet['physical'].disable()
        self.bullets.remove(bullet)
        bullet = None

    def destroy(self):
        self.isAlive = False
        self.visualNode.hide()
        self.destroySound.play()

    def thrustOn(self):
        self.acc = 1.0

    def thrustOff(self):
        self.acc = 0.0

    def rotateLeftOn(self):
        self.rotateLeft = True

    def rotateLeftOff(self):
        self.rotateLeft = False

    def isRotatingLeft(self):
        return self.rotateLeft

    def rotateRightOn(self):
        self.rotateRight = True

    def rotateRightOff(self):
        self.rotateRight = False

    def isRotatingRight(self):
        return self.rotateRight

    def update(self, deltaTime):
        """@param deltaTime float, how many seconds have passed since last tick"""
        # TODO: refactor the updating code into different methods

        # Update the bullets
        # TODO: Add test for this in testUpdate!
        for bullet in self.bullets:
            bullet['timeToLive'] -= 1
            if bullet['timeToLive'] <= 0:
                bullet['isAlive'] = False
            if not bullet['isAlive']:
                self.destroyBullet(bullet)
                continue

            pos = bullet['visual'].getPos()
            bulletPos = Vec3(bullet['vel'][0] * deltaTime + pos[0],
                             bullet['vel'][1] * deltaTime + pos[1], 0)
            bullet['visual'].setPos(bulletPos)
            bullet['physical'].setPosition(bulletPos)

        # If the ship is not alive anymore, we don't move it
        if not self.isAlive:
            return

        # update the heading. Must be done before position updating!
        if self.rotateLeft:
            self.heading = self.heading + Ship.ROTATION_SPEED * deltaTime
        elif self.rotateRight:
            self.heading = self.heading - Ship.ROTATION_SPEED * deltaTime

        for c in self.collisions:
            self.collisionHandler(self, c)
        # update position
        gainedSpeedScalar = self.acc * deltaTime * Ship.ACC_COEFFICIENT
        # convert degrees to radians
        angle = self.heading * math.pi / 180.0
        #correction = math.pi / 2
        deltaVelX = gainedSpeedScalar * math.cos(angle)
        deltaVelY = gainedSpeedScalar * math.sin(angle)

        for f in self.forces:
            deltaVelX += f[0]
            deltaVelY += f[1]
        self.forces = []

        self.vel = (self.vel[0] + deltaVelX, self.vel[1] + deltaVelY)

        # Limit the ship's speed to Ship.SPEED_MAX
        self.limitVelocity()

        deltaPosX = deltaTime * self.vel[0]
        deltaPosY = deltaTime * self.vel[1]
        newPosX = self.pos[0] + deltaPosX
        newPosY = self.pos[1] + deltaPosY
        self.pos = (newPosX, newPosY)

        # Rotate the visual representation of the ship
        self.visualNode.setH(self.heading)
        # Move the actual visual representation
        self.visualNode.setPos(tupleToVec3(self.pos))
        self.collisionSphere.setPosition(self.pos[0], self.pos[1], 0)

    def limitVelocity(self):
        shipVel = self.getVel()
        newVelScalar = tupleLength(shipVel)
        if newVelScalar > Ship.SPEED_MAX:
            newVelScale = Ship.SPEED_MAX / newVelScalar
            newVel = scaleTuple(shipVel, newVelScale)
            self.setVel(newVel)
示例#23
0
文件: ode.py 项目: gurgelff/Bast
# This 'balls' list contains tuples of nodepaths with their ode geoms
for i in range(15):
  # Setup the geometry
  ballNP = ball.copyTo(render)
  ballNP.setPos(randint(-7, 7), randint(-7, 7), 10 + random() * 5.0)
  ballNP.setColor(random(), random(), random(), 1)
  ballNP.setHpr(randint(-45, 45), randint(-45, 45), randint(-45, 45))
  # Create the body and set the mass
  ballBody = OdeBody(world)
  M = OdeMass()
  M.setSphere(50, 1)
  ballBody.setMass(M)
  ballBody.setPosition(ballNP.getPos(render))
  ballBody.setQuaternion(ballNP.getQuat(render))
  # Create a ballGeom
  ballGeom = OdeSphereGeom(space, 1)
  ballGeom.setCollideBits(BitMask32(0x00000001))
  ballGeom.setCategoryBits(BitMask32(0x00000001))
  ballGeom.setBody(ballBody)
  # Create the sound
  ballSound = loader.loadSfx("audio/sfx/GUI_rollover.wav")
  balls.append((ballNP, ballGeom, ballSound))

# Add a plane to collide with
cm = CardMaker("ground")
cm.setFrame(-20, 20, -20, 20)
cm.setUvRange((0, 1), (1, 0))
ground = render.attachNewNode(cm.generate())
ground.setPos(0, 0, 0); ground.lookAt(0, 0, -1)
groundGeom = OdePlaneGeom(space, (0, 0, 1, 0))
groundGeom.setCollideBits(BitMask32(0x00000001))
示例#24
0
class Pallo(Collectible):
    
 #   COLLECTIBLE_TYPE = 'PointBall'
 #   VALUE = 1
 #   DRAIN = 20

    
    def __init__(self, game, color, value = 1, drain = 20):
        self.game = game
        self.VALUE = value
        self.DRAIN = drain
        
        #self.idnumber = id
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        model = loader.loadModel('Ball2.egg')
        model.setScale(2.5)
        model.reparentTo(self.visualNode)

        plight = PointLight('plight')
        plight.setPoint( Point3(0, 0, 3) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.05, 0.01, 0.01) )
        self.plightNodePath = model.attachNewNode(plight)
        model.setLight(self.plightNodePath)

        self.body = OdeBody(game.physicsWorld)
        self.mass = OdeMass()
        self.mass.setBox(10,1,1,1)
        self.body.setMass(self.mass)

        self.body.setGravityMode(True)

        #self.body.setGravityMode(False)
        #self.juttu = OdeUtil()
        
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 3.5)
        self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
    
    def getValue(self):
        return self.VALUE
    
    def hitShips(self, shipList):
        
        for ship in shipList:
            if OdeUtil.areConnected(ship.body, self.body) and not ship.hasBall():
                self.PowerUpEffect(ship)

    def PowerUpEffect(self, ship):
     #   ship.mass.add(self.mass)
        ship.addPower(-(self.DRAIN))
        ship.gotBall(self)
        self.hideObject()
        ship.visualNode.setLight(self.plightNodePath)
        
        #print player
        print ship.SHIP_TYPE + " lost " + str(self.DRAIN) + " power!!"
        
    def Restore(self, ship):
      #  ship.mass.add(self.mass)
        ship.addPower(self.DRAIN)
        self.showObject()
        ship.visualNode.clearLight(self.plightNodePath)
        #self.setPos( Vec3(random.randrange(30), random.randrange(40), 0))
        #ship.dropBall()
        #print player
        print ship.getShipType() + " regained 20 power!!"
示例#25
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)
示例#26
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)
示例#27
0
    def createTire(self, tireIndex):
        """Create one physics tire. Returns a (nodePath, OdeBody, OdeGeom) tuple"""
        if (tireIndex < 0) or (tireIndex >= len(self.tireMasks)):
            self.notify.error('invalid tireIndex %s' % tireIndex)
        self.notify.debug("create tireindex %s" % (tireIndex))
        zOffset = 0
        # for now the tires are spheres
        body = OdeBody(self.world)
        mass = OdeMass()
        mass.setSphere(self.tireDensity, IceGameGlobals.TireRadius)
        body.setMass(mass)
        body.setPosition(IceGameGlobals.StartingPositions[tireIndex][0],
                         IceGameGlobals.StartingPositions[tireIndex][1],
                         IceGameGlobals.StartingPositions[tireIndex][2])
        #body.setAutoDisableFlag(1)
        #body.setAutoDisableLinearThreshold(1.01 * MetersToFeet)
        # skipping AutoDisableAngularThreshold as that is radians per second
        #body.setAutoDisableAngularThreshold(0.1)
        body.setAutoDisableDefaults()

        geom = OdeSphereGeom(self.space, IceGameGlobals.TireRadius)
        self.space.setSurfaceType(geom, self.tireSurfaceType)
        self.space.setCollideId(geom, self.tireCollideIds[tireIndex])

        self.massList.append(mass)
        self.geomList.append(geom)

        # a tire collides against other tires, the wall and the floor
        geom.setCollideBits(self.allTiresMask | self.wallMask | self.floorMask
                            | self.obstacleMask)
        geom.setCategoryBits(self.tireMasks[tireIndex])
        geom.setBody(body)

        if self.notify.getDebug():
            self.notify.debug('tire geom id')
            geom.write()
            self.notify.debug(' -')

        if self.canRender:
            testTire = render.attachNewNode("tire holder %d" % tireIndex)
            smileyModel = NodePath(
            )  # loader.loadModel('models/misc/smiley') # smiley!
            if not smileyModel.isEmpty():
                smileyModel.setScale(IceGameGlobals.TireRadius)
                smileyModel.reparentTo(testTire)
                smileyModel.setAlphaScale(0.5)
                smileyModel.setTransparency(1)
            testTire.setPos(IceGameGlobals.StartingPositions[tireIndex])
            #debugAxis = loader.loadModel('models/misc/xyzAxis')
            if 0:  #not debugAxis.isEmpty():
                debugAxis.reparentTo(testTire)
                debugAxis.setScale(IceGameGlobals.TireRadius / 10.0)
                debugAxis2 = loader.loadModel('models/misc/xyzAxis')
                debugAxis2.reparentTo(testTire)
                debugAxis2.setScale(-IceGameGlobals.TireRadius / 10.0)
            # lets create a black tire
            #tireModel = loader.loadModel('phase_3/models/misc/sphere')
            tireModel = loader.loadModel(
                "phase_4/models/minigames/ice_game_tire")
            # assuming it has a radius of 1
            tireHeight = 1
            #tireModel.setScale(IceGameGlobals.TireRadius, IceGameGlobals.TireRadius, 1)
            #tireModel.setZ( 0 - IceGameGlobals.TireRadius + (tireHeight /2.0))
            #tireModel.setColor(0,0,0)
            tireModel.setZ(-IceGameGlobals.TireRadius + 0.01)
            tireModel.reparentTo(testTire)
            #tireModel.setAlphaScale(0.5)
            #tireModel.setTransparency(1)

            self.odePandaRelationList.append((testTire, body))
        else:
            testTire = None
            self.bodyList.append((None, body))
        return testTire, body, geom
示例#28
0
文件: Pylon.py 项目: i-k/SpaceGrabem
class Pylon(StaticObject):
    
    def __init__(self, game, power = 50.0, range = 30):
        self.game = game
        self.POWER = power
        self.Active = False
        self.RANGE = range
        
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 3)
        #self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
        
        self.triggerGeom = OdeSphereGeom( range ) 
        self.triggerGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.triggerGeom.setCollideBits( BitMask32(0xffffffff) )
                
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        self.model = loader.loadModel('AbsorbingPylon.egg')
        self.model.setScale(1.5)
        self.model.reparentTo(self.visualNode)
        
        pow = self.getPower()*5
        maxPow = self.game.MAX_PYLON_POWER
        if (pow > 0):
            self.offColor = Vec4(pow/maxPow, 0.0, 0.0, 0.0)
            self.onColor = Vec4(0.0, pow/maxPow, 0.0, 0.0)

        if (pow <= 0):
            self.offColor = Vec4(0.0, 0.0, -pow/maxPow, 0.0)
            self.onColor = Vec4(0.0, -pow/maxPow, 0.0, 0.0)
            
        self.setColor( self.offColor )
            
    def setPos(self, pos):
        self.visualNode.setPos( pos )
        self.collGeom.setPosition( pos )
        self.triggerGeom.setPosition( pos )
        
    def addToPylonList(self, pylonList):
        pylonList.append(self)
        
    def getPower(self):
        return self.POWER
        
    def getRange(self):
        return self.RANGE
        
        
    def setColor(self, color):
        plight = PointLight('plight4')
        plight.setPoint( Point3(0.6, 0, 5) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.5, 0.01, 0.01) )
        self.plight = plight
        self.plightNodePath = self.model.attachNewNode(self.plight)
        self.model.setLight(self.plightNodePath)

    def setActive(self, active, ship):
        if active == self.Active:
            return
        if active:
            self.whoActivated = ship
            self.plight.setColor(self.onColor)
            self.Active = active
        else:
            if ship == self.whoActivated:
                self.plight.setColor(self.offColor)
                self.Active = active
        
    def isActive(self):
        return self.Active
        
    #checks when ship gets inside the trigger zone of this pylon
    def insideTrigger(self, ship):
        if OdeUtil.collide(self.triggerGeom, ship.collGeom):
           # self.setActiveOn()
            #print str(ship.getShipType())
            self.setActive(True, ship)
            self.usingTheForce( ship )
           # print "moo"
        else:
            #self.setActiveOff()
            #print "muu"
            self.setActive(False, ship)
            
    #applies force to ship relative to the position of the pylon
    #while ship is inside trigger zone
    def usingTheForce(self, ship):
        #if (self.isActive()):
            #algoritmi ei toimi viela optimaalisesti 
            pylonpos = self.getPos()
            shippos = ship.getPos()
            relativepos = [ (shippos[0] - pylonpos[0])  , (shippos[1] - pylonpos[1]) ] 
#            if (shippos[0] - pylonpos[0]) < 0:
#                relativepos = []

            ship.body.addForce( relativepos[0] * self.POWER, relativepos[1] * self.POWER, 0  )

    
#    #checks if collision happens with one ship 
#    #quite useless, but leaving it anyway
#    def checkCollision(self, ship):
#         if OdeUtil.collide(ship.collGeom, self.collGeom) and ship.hasBall():
#            #ship.Ball.Restore(ship)
#            ship.dropBall( z = 300 )
#            print str(ship.getShipType()) + " lost its balls! ONOES!!"

    
    #checks if collision happens with a ship in the list of ships
    #also checks if ship is inside the range of the pylon's power
    def checkCollisionList(self, shipList):
        for ship in shipList:
            self.insideTrigger( ship )
            #self.usingTheForce( ship )
            if OdeUtil.collide(ship.collGeom, self.collGeom) and ship.hasBall():
                #ship.Ball.Restore(ship)
                self.game.collision2Sfx.play()
                pos = ship.getPos()
                ship.dropBall(x = pos[0], y = pos[1], z = 30, linX = ( (0-pos[0])/7 ), linY = ( (0-pos[1])/7 ), linZ = 2)
                print str(ship.getShipType()) + " lost its balls! NOOOO!"
示例#29
0
class Ship_1(Ship):
    
    POWER = 100
    SHIP_TYPE = "UFO"
    
    def __init__(self, game, color):
        #self.POWER = 100
        self.game = game
        
        self.thrust = False
        self.thrustLeft = False
        self.thrustRight = False
        self.thrustBack = False
        self.rotation = 0

        self.body = OdeBody(game.physicsWorld)
        self.mass = OdeMass()
        self.mass.setBox(10,1,1,1)
        self.body.setMass(self.mass)

        #odespheregeom(... , size of hitbox sphere)
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 5)
        self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
        
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        model = loader.loadModel('lautanen2.egg')
        model.reparentTo(self.visualNode)
        
        plight = PointLight('plight')
        plight.setPoint( Point3(0.6, 0, 5) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.5, 0.01, 0.01) )
        plightNodePath = model.attachNewNode(plight)
        model.setLight(plightNodePath)
        
 # setMoreKeys in ship class = BAD IDEA
    #def setMoreKeys(self):
     #   base.accept('arrow_down', self.thrustBackOn)
      #  base.accept('arrow_down-up', self.thrustBackOff) 
      

    def applyForces(self):
        if self.thrust:
            heading = self.getHeading()
            self.body.addForce(
              -math.sin( math.radians(heading) ) * self.POWER,
               math.cos( math.radians(heading) ) * self.POWER,
               0
            )
        if self.thrustLeft:
            heading = self.getHeading()
            self.body.addForce(
              -math.sin( math.radians(heading) + math.pi/2 ) * self.POWER,
               math.cos( math.radians(heading) + math.pi/2 ) * self.POWER,
               0
            )
        if self.thrustRight:
            heading = self.getHeading()
            self.body.addForce(
              -math.sin( math.radians(heading) - math.pi/2 ) * self.POWER,
               math.cos( math.radians(heading) - math.pi/2 ) * self.POWER,
               0
            )
        if self.thrustBack:
            heading = self.getHeading()
            self.body.addForce(
              -math.sin( math.radians(heading) + math.pi ) * self.POWER,
               math.cos( math.radians(heading) + math.pi ) * self.POWER,
               0
            )
示例#30
0
class Ship_2(Ship):
    
    ROTATING_SPEED = 1
    MAX_ROTATE_SPEED = 3.0
    SHIP_TYPE = "RAKETTI"
    
    def __init__(self, game, color):

        self.POWER = 100
        self.game = game
        
        self.thrust = False
        self.thrustLeft = False
        self.thrustRight = False
        self.thrustBack = False
        self.rotation = 0

        self.body = OdeBody(game.physicsWorld)
        self.mass = OdeMass()
        self.mass.setBox(10,1,1,1)
        self.body.setMass(self.mass)

        #odespheregeom(... , size of hitbox sphere)
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 2)
        self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
        
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        model = loader.loadModel('testipalikka.egg')
        model.reparentTo(self.visualNode)
        
        plight = PointLight('plight')
        plight.setPoint( Point3(0.6, 0, 5) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.5, 0.01, 0.01) )
        plightNodePath = model.attachNewNode(plight)
        model.setLight(plightNodePath)



    
    
    def rotating(self):
        if self.thrustLeft:
            self.setRotation(self.ROTATING_SPEED)
        if self.thrustRight:
            self.setRotation(-(self.ROTATING_SPEED))
        if not self.thrustRight and not self.thrustLeft:
            self.setRotation(0)


    def applyForces(self):
        if self.thrust:
            heading = self.getHeading()
            #addForce (x, y, z)
            self.body.addForce(
              -math.sin( math.radians(heading) ) * self.POWER,
               math.cos( math.radians(heading) ) * self.POWER,
              0
            )
# uncomment for backwards thrust (eli siis pakki)
#        if self.thrustBack:
#            heading = self.getHeading()
#            self.body.addForce(
#               math.sin( math.radians(heading) ) * self.POWER,
#              -math.cos( math.radians(heading) ) * self.POWER,
#              0
#            )
        self.rotating()
示例#31
0
class Pylon(StaticObject):
    
    
    
    def __init__(self, game, power = 10):
        self.game = game
        self.POWER = power
        self.Active = False
        
        
        self.collGeom = OdeSphereGeom( self.game.physicsSpace, 3)
        #self.collGeom.setBody(self.body)
        self.collGeom.setCategoryBits( BitMask32(0xffffffff) )
        self.collGeom.setCollideBits( BitMask32(0xffffffff) )
        
        self.visualNode = NodePath('Visual node')
        self.visualNode.reparentTo(render)
        self.model = loader.loadModel('AbsorbingPylon.egg')
        self.model.setScale(2)
        self.model.reparentTo(self.visualNode)
        
        #TODO: trigger geom
        #self.effectGeom = OdeSphereGeom(  )
        
        if (self.getPower() > 0):
            self.setColor( Vec4(1.0, 0.0, 0.0, 0.0) )
        if (self.getPower() <= 0):
            self.setColor( Vec4(0.0, 0.0, 1.0, 0.0) )
            
        
    def addToPylonList(self, pylonList):
        pylonList.append(self)
        
    def getPower(self):
        return self.POWER
        
    def setColor(self, color):
        plight = PointLight('plight')
        plight.setPoint( Point3(0.6, 0, 5) )
        plight.setColor( color )
        plight.setAttenuation( Vec3(0.5, 0.01, 0.01) )
        plightNodePath = self.model.attachNewNode(plight)
        self.model.setLight(plightNodePath)
        
    def setActiveOn(self):
        self.Active = True
        
    def setActiveOff(self):
        self.Active = False
        
    def isActive(self):
        return self.Active
        
    #checks when ship gets inside the trigger zone of this pylon
    def insideTrigger(self, ship):
        pass
#        if OdeUtil.collide(ship.collGeom, self.effectGeom)
#            self.setActiveOn()        
    
    
    
    #applies force to ship relative to the position of the pylon
    #while ship is inside trigger zone
    def usingTheForce(self, ship):
        if (self.isActive()):
            pass
        
    
    #checks if collision happens with one ship 
    #quite useless, but leaving it anyway
    def checkCollision(self, ship):
         if OdeUtil.collide(ship.collGeom, self.collGeom) and ship.hasBall():
            #ship.Ball.Restore(ship)
            ship.dropBall( z = 300 )
            print str(ship.getShipType()) + " lost its balls! ONOES!!"
    
    #checks if collision happens with a ship in the list of ships
    def checkCollisionList(self, shipList):
        for ship in shipList:
            if OdeUtil.collide(ship.collGeom, self.collGeom) and ship.hasBall():
                #ship.Ball.Restore(ship)
                ship.dropBall()
                print str(ship.getShipType()) + " lost its balls! NOOOO!"