Exemplo n.º 1
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
Exemplo n.º 2
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
Exemplo n.º 3
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
Exemplo n.º 4
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
Exemplo n.º 5
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)
 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)
Exemplo n.º 7
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()
Exemplo n.º 8
0
class Pallo(Collectible):
    
    
    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) )
    

    def PowerUpEffect(self, ship):
        ship.mass.add(self.mass)
        ship.addPower(-20)
        print ship.SHIP_TYPE + " lost 20 power!!"
Exemplo n.º 9
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!!"
Exemplo n.º 10
0
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!"
Exemplo n.º 11
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
            )
Exemplo n.º 12
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()
Exemplo n.º 13
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!"
Exemplo n.º 14
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)
Exemplo n.º 15
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
Exemplo n.º 16
0
Arquivo: ode.py Projeto: gurgelff/Bast
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))
groundGeom.setCategoryBits(BitMask32(0x00000001))