示例#1
0
class Game():

    HUD_TEXT_SCALE = 0.04
    UPDATE_RATE = 1/60.0

    def __init__(self):
        base.disableMouse()
        base.camera.setPos(0,0,640)
        base.camera.lookAt(0,0,0)
       
        
        self.loadPhysics()
        self.loadLights()
        
        #map x boundary, map y boundary, amount of pylons
        self.map = Map(self, 160.0, 160.0, 7)
        

        
        
#        self.Base1 = Base(self)
#        self.Base1.setPos( Vec3( 0, 50, 0))
#        self.Base2 = Base(self)
#        self.Base2.setPos( Vec3( 0, -50, 0))
        #self.Base2 = Base(self)
#        self.wall1 = StaticObject.bigWall(self)
#        self.wall1.setPos( Vec3( 50, (-50), 0) )
#        self.wall1.setRotation( 90 )
#        
#        self.wall2 = StaticObject.bigWall(self)
#        self.wall2.setPos( Vec3( 50, 0, 0) )
#        self.wall2.setRotation( 90 )

        #alustaa tyhjan listan
        self.shipList = []
        self.ship1 = ShipTypes.Ship_2(self, Vec4(1.0, 1.0, 1.0, 0))
        
        self.ship2 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0))
        
        self.LoadHUD()
        
        #lisataan alukset listaan
        self.ship1.addToShipList(self.shipList)
        self.ship2.addToShipList(self.shipList)

        ##katsotaan saako toimimaan listana gamelooppiin -- saa
       ##self.shipList = [self.ship1, self.ship2]
        
        self.ship2.setPos( Vec3(10, 10, 0) )
        
        
        self.setKeys()
        
        self.collectibleList = []
        self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0))
        self.pallo.setPos( Vec3(0, 20, 0) )
        self.pallo.addToCollectibleList(self.collectibleList)
        
        self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0))
        self.pallo2.setPos( Vec3(30, 20, 0) )
        self.pallo2.addToCollectibleList(self.collectibleList)
        
        #self.collectibleList = [self.pallo, self.pallo2]
 
#        self.pylonList = []
#        self.pylon1 = Pylon(self, 100)
#        self.pylon1.setPos( Vec3(-30, 20, 0) )
#        self.pylon1.addToPylonList(self.pylonList)

#        self.pylon2 = Pylon(self, -100)
#        self.pylon2.setPos( Vec3(-30, -20, 0) )
#        self.pylon2.addToPylonList(self.pylonList)
        
#        self.makeBoundaryWalls( 50.0, 50.0, 50.0)
        
        base.setBackgroundColor(0,0,0.0,0)
        
        taskMgr.add(self.loop, 'game loop')
        
        run()
        
    def setKeys(self):
        base.accept('arrow_up', self.ship1.thrustOn)
        base.accept('arrow_up-up', self.ship1.thrustOff)
        base.accept('arrow_left', self.ship1.thrustLeftOn)
        base.accept('arrow_left-up', self.ship1.thrustLeftOff)
        base.accept('arrow_right', self.ship1.thrustRightOn)
        base.accept('arrow_right-up', self.ship1.thrustRightOff) 
        base.accept('arrow_down', self.ship1.thrustBackOn)
        base.accept('arrow_down-up', self.ship1.thrustBackOff) 
        base.accept('rshift', self.ship1.releaseBall)

        base.accept('w', self.ship2.thrustOn)
        base.accept('w-up', self.ship2.thrustOff)
        base.accept('a', self.ship2.thrustLeftOn)
        base.accept('a-up', self.ship2.thrustLeftOff)
        base.accept('d', self.ship2.thrustRightOn)
        base.accept('d-up', self.ship2.thrustRightOff) 
        base.accept('s', self.ship2.thrustBackOn)
        base.accept('s-up', self.ship2.thrustBackOff) 
        base.accept('q', self.ship2.releaseBall)
        
        
        
    def loadPhysics(self):
        self.physicsWorld = OdeWorld()
        self.physicsWorld.initSurfaceTable(1)
        self.physicsWorld.setSurfaceEntry(
          0,
          0,
          1.0, # u
          0.35, # elasticity
          0.01, # minimum threshold for physical movement
          0.01,
          0.00000001, # softening
          0.01,
          0.01 # damping
        )
        self.physicsWorld.setGravity(0, 0, 0)
        self.physicsSpace = OdeHashSpace()
        self.physicsSpace.setAutoCollideWorld(self.physicsWorld)
        self.contactGroup = OdeJointGroup()
        self.physicsSpace.setAutoCollideJointGroup(self.contactGroup)

    def LoadHUD(self):
#        self.player1HUD = OnscreenText(
#            text = "Player 1: " + str( self.ship1.getPoints() ),
#            fg = (1,1,1,1),
#            #pos = ( x, y )
#            pos = (0.5,0.6),
#            align = TextNode.ALeft,
#            scale = Game.HUD_TEXT_SCALE
#        )
        
#        self.player2HUD = OnscreenText(
#            text = "Player 2: " + str( self.ship2.getPoints() ),
#            fg = (1,1,1,1),
#            pos = (-0.5,0.6),
#            align = TextNode.ALeft,
#            scale = Game.HUD_TEXT_SCALE
#        )
        
        
        self.winnerText = OnscreenText(
            text = "Tekstia, tekstia, tekstia",
            fg = (1,1,1,1),
            pos = (-0.25, 0),
            align = TextNode.ALeft,
            scale = Game.HUD_TEXT_SCALE
        )
        self.winnerText.hide()

#    def updateHUD(self):
#        self.player1HUD = OnscreenText(
#            text = "Player 1: " + str( self.ship1.getPoints() ),
#            fg = (1,1,1,1),
#            pos = (0.5,0.6),
#            align = TextNode.ALeft,
#            scale = Game.HUD_TEXT_SCALE
#        )
        
#        self.player2HUD = OnscreenText(
#            text = "Player 2: " + str( self.ship2.getPoints() ),
#            fg = (1,1,1,1),
#            pos = (-0.5,0.6),
#            align = TextNode.ALeft,
#            scale = Game.HUD_TEXT_SCALE
#        )

    def loadLights(self):
        light1 = DirectionalLight('light1')
        lightNode1 = render.attachNewNode(light1)
        light1.setDirection( Vec3(-1, 0.5, -0.25) )
        light1.setColor( Vec4(0.5, 0.9, 0.9, 0) )
        render.setLight(lightNode1)
        
    #checks all collectibles for possible collisions with ships
    def checkAllCollectibles(self):
        for collectible in self.collectibleList:
            collectible.hitShips(self.shipList)

    #updates all collectible positions
    def updateAllCollectibles(self):
        for collectible in self.collectibleList:
            collectible.update(Game.UPDATE_RATE)
    
    #apply forces to all collectibles    
    ## def applyForceAllCollectibles(self):
        ## for collectible in self.collectibleList:
            ## collectible.applyForces()
    
    def applyForceAllShips(self):
        for ship in self.shipList:
            ship.applyForces()
            
    #updates all ship positions
    def updateAllShips(self):
        for ship in self.shipList:
            ship.update(Game.UPDATE_RATE)
            
    #checks all pylons for possible collisions with ships
    def checkAllPylons(self):
        for pylon in self.map.getPylonList():
            pylon.checkCollisionList(self.shipList)
        
        
    def loop(self, task):
        self.applyForceAllShips()
        self.physicsSpace.autoCollide()
        self.checkAllCollectibles()
        self.map.getBase1().checkCollision(self.ship1)
        self.map.getBase2().checkCollision(self.ship2)
        self.checkAllPylons()
        
        self.physicsWorld.quickStep(Game.UPDATE_RATE)
        self.updateAllShips()
        self.updateAllCollectibles()
        self.contactGroup.empty()
        return task.cont
示例#2
0
class Game():

    HUD_TEXT_SCALE = 0.04
    UPDATE_RATE = 1/60.0
    MAX_PYLON_POWER = 50

    def __init__(self):

        self.zoomLevels = deque([640, 512, 320, 1280])
        self.curLev = self.zoomLevels[0]
        
        base.disableMouse()
        self.initCam()
        
        self.loadPhysics()
        self.loadLights()
        
        #map x boundary, map y boundary, amount of pylons
        self.map = Map(self, 150.0, 150.0, 7)

        self.shipList = []
        self.ship1 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0.0))
        self.ship2 = ShipTypes.Ship_2(self, Vec4(0.0, 0.0, 0.6, 0.0))
        self.ship1.setPos( Vec3(0, 120, 0) )
        self.ship2.setPos( Vec3(0, -120, 0) )    
        self.shipList.append(self.ship1)
        self.shipList.append(self.ship2)
        
        self.LoadHUD()
        
        self.setKeys()
        
        self.collectibleList = []
        self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0))
        self.pallo.setPos( Vec3(0, 20, 0) )
        self.pallo.addToCollectibleList(self.collectibleList)
        
        #self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0))
        #self.pallo2.setPos( Vec3(30, 20, 0) )
        #self.pallo2.addToCollectibleList(self.collectibleList)
        
        b=OnscreenImage(parent=render2d, image="Geminid.jpg")
        base.cam.node().getDisplayRegion(0).setSort(20)
        
        base.setBackgroundColor(0,0,0.0,0)
        
        self.collisionSfx = loader.loadSfx("shipcollision.wav")
        self.goalSfx = loader.loadSfx("goal.wav")
        self.victorySfx = loader.loadSfx("victory.wav")
        self.collision2Sfx = loader.loadSfx("pyloncollision.wav")
        
        filters = CommonFilters(base.win, base.cam)
        render.setShaderAuto()
        
        taskMgr.add(self.loop, 'game loop')
        
        run()
        
    def setKeys(self):
        base.accept('arrow_up', self.ship1.thrustOn)
        base.accept('arrow_up-up', self.ship1.thrustOff)
        base.accept('arrow_left', self.ship1.thrustLeftOn)
        base.accept('arrow_left-up', self.ship1.thrustLeftOff)
        base.accept('arrow_right', self.ship1.thrustRightOn)
        base.accept('arrow_right-up', self.ship1.thrustRightOff) 
        base.accept('arrow_down', self.ship1.thrustBackOn)
        base.accept('arrow_down-up', self.ship1.thrustBackOff) 
        base.accept('rshift', self.ship1.releaseBall)

        base.accept('w', self.ship2.thrustOn)
        base.accept('w-up', self.ship2.thrustOff)
        base.accept('a', self.ship2.thrustLeftOn)
        base.accept('a-up', self.ship2.thrustLeftOff)
        base.accept('d', self.ship2.thrustRightOn)
        base.accept('d-up', self.ship2.thrustRightOff) 
        base.accept('s', self.ship2.thrustBackOn)
        base.accept('s-up', self.ship2.thrustBackOff) 
        base.accept('q', self.ship2.releaseBall)
        
        base.accept('+', self.zoom)
        base.accept('p', self.toggleAI)
        
    def loadPhysics(self):
        self.physicsWorld = OdeWorld()
        self.physicsWorld.initSurfaceTable(1)
        self.physicsWorld.setSurfaceEntry(
          0,
          0,
          1.0, # u
          0.35, # elasticity
          0.01, # minimum threshold for physical movement
          0.01,
          0.00000001, # softening
          0.01,
          0.01 # damping
        )

        self.physicsWorld.setGravity(0, 0, -20)

        self.physicsSpace = OdeHashSpace()
        self.physicsSpace.setAutoCollideWorld(self.physicsWorld)
        self.contactGroup = OdeJointGroup()
        self.physicsSpace.setAutoCollideJointGroup(self.contactGroup)

    def LoadHUD(self):
        self.player1HUD = OnscreenText(
            text = "Player 1: " + str( self.ship1.getPoints() ),
            fg = (1,1,1,1),
            #pos = ( x, y )
            pos = (0.7,0.9),
            align = TextNode.ALeft,
            scale = Game.HUD_TEXT_SCALE
        )
        
        self.player2HUD = OnscreenText(
            text = "Player 2: " + str( self.ship2.getPoints() ),
            fg = (1,1,1,1),
            pos = (-0.7,0.9),
            align = TextNode.ALeft,
            scale = Game.HUD_TEXT_SCALE
        )

        
        self.winnerText = OnscreenText(
            text = "Tekstia, tekstia, tekstia",
            fg = (1,1,1,1),
            pos = (-0.2, 0),
            align = TextNode.ALeft,
            scale = Game.HUD_TEXT_SCALE*3
        )
#        self.winnerText.setZ(200)
        self.winnerText.hide()

    def updateHUD(self):
        self.player1HUD.setText( "Player 1: " + str( self.ship1.getPoints() ) )
        self.player2HUD.setText( "Player 2: " + str( self.ship2.getPoints() ) )
        if (self.ship1.getPoints() > 9):
            self.winnerText.show()
            self.winnerText.setText( "Player 1 won " + str(self.ship1.getPoints()) + "-" + str(self.ship2.getPoints()))
            self.victorySfx.play()
            base.cam.node().getDisplayRegion(0).setSort(0)
#            self.Pause()
        if (self.ship2.getPoints() > 9):
            self.winnerText.show()
            self.winnerText.setText( "Player 2 won " + str(self.ship2.getPoints()) + "-" + str(self.ship1.getPoints()))
            self.victorySfx.play()
            base.cam.node().getDisplayRegion(0).setSort(0)


    def loadLights(self):
        light1 = DirectionalLight('light1')
        lightNode1 = render.attachNewNode(light1)
        light1.setDirection( Vec3(-1, 0.5, -0.25) )
        light1.setColor( Vec4(0.6, 0.6, 0.6, 0) )
        render.setLight(lightNode1)
        
    #checks all collectibles for possible collisions with ships
    def checkAllCollectibles(self, shipList):
        for collectible in self.collectibleList:
            collectible.hitShips(shipList)

    #updates all collectible positions
    def updateAllCollectibles(self):
        for collectible in self.collectibleList:
            collectible.update(Game.UPDATE_RATE)
    
    def applyForceAllShips(self, shipList):
        for ship in shipList:
            ship.applyForces()
            
    #updates all ship positions
    def updateAllShips(self, shipList):
        for ship in shipList:
            ship.update(Game.UPDATE_RATE)
        shipList[0].shipsCollide(shipList[1])
            
    #checks all pylons for possible collisions with ships
    def checkAllPylons(self, pylonList, shipList):
        for pylon in pylonList:
            pylon.checkCollisionList(shipList)
        
        
    def loop(self, task):
        self.applyForceAllShips(self.shipList)
        self.physicsSpace.autoCollide()
        self.checkAllCollectibles(self.shipList)
        self.map.getBase1().checkCollision(self.ship1, self.collectibleList)
        self.map.getBase2().checkCollision(self.ship2, self.collectibleList)
        self.checkAllPylons(self.map.getPylonList(), self.shipList)
        self.physicsWorld.quickStep(Game.UPDATE_RATE)
        self.updateAllShips(self.shipList)
        self.updateAllCollectibles()
        self.contactGroup.empty()
        return task.cont
        
    def toggleAI(self):
		if taskMgr.hasTaskNamed('Simple AI'):
			taskMgr.remove('Simple AI')
			return
		taskMgr.add( self.chaseBallsAround, name='Simple AI', sort=None,
                     extraArgs=(self.ship1, self.ship2, self.collectibleList, self.map.getBase1()),
                     priority=None, uponDeath=None, appendTask=True, taskChain=None, owner=None)
		
    def chaseBallsAround(self, chaser, enemy, chaseList, base, task):
        pos = chaser.getPos()
        nearestNormedPos = 1e10000 #represents infinity
        nearestRelPos = [0,0]
        if chaser.hasBall():
            chasePos = base.getPos()
            nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ]
        elif enemy.hasBall():
            chasePos = enemy.getPos()
            nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ]
        else:
            for collectible in chaseList:
                chasePos = collectible.getPos()
                relPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ]
                if (math.fabs(relPos[0]) + math.fabs(relPos[1])) < nearestNormedPos:
                    nearestNormedPos = math.fabs(relPos[0]) + math.fabs(relPos[1])
                    nearestRelPos = relPos
        if nearestRelPos[0] > 0:
            chaser.thrustRightOff()
            chaser.thrustLeftOn()
        elif nearestRelPos[0] < 0:
            chaser.thrustLeftOff()
            chaser.thrustRightOn()
        if nearestRelPos[1] < 0:
            chaser.thrustBackOff()
            chaser.thrustOn()
        elif nearestRelPos[1] > 0:
            chaser.thrustOff()
            chaser.thrustBackOn()
        else:
            chaser.thrustOff()
            chaser.thrustBackOff()
        return task.cont

    def initCam(self):
        base.camera.setPos(0,0,self.curLev)
        base.camera.lookAt(0,0,0)

    def zoom(self):
        self.curLev = self.zoomLevels.popleft()
        base.camera.setPos(0, 0, self.curLev)
        self.zoomLevels.append(self.curLev)

    def shakeCam(self):
        taskMgr.add(self.shakeCamTask, name='ShakeCam')
    
    def shakeCamTask(self, task):
        oldPos = base.camera.getPos()
        base.camera.setPos(oldPos[0]+random.randint(-1, 1), oldPos[1]+random.randint(-1, 1), oldPos[2]+random.randint(-4, 4))
        if task.time < 0.5:
            return task.cont
        self.initCam()
        return task.done
示例#3
0
class World:
	def __init__(self, game):
		self.game = game
		self.world = OdeWorld()
		self.world.setGravity(0, 0, -9.81 * 3)
		self.group = OdeJointGroup()
		self.space = OdeHashSpace()
		self.space.setAutoCollideWorld(self.world)
		self.space.setAutoCollideJointGroup(self.group)
		self.setSurfaceTables()
		self.objects = []
		self.objectsToRemove = []
		self.postStepTasks = []

		self.engineRunning = True
		self.dtAccumulator = 0.0
		self.physicsFps = 90
		self.physicsMinFps = 10
		base.taskMgr.doMethodLater(0.1, self.processPhysics, "Physics")
		base.accept("escape", self.togglePhysics)

		self.space.setCollisionEvent("odeCollision")
		base.accept("odeCollision", self.onCollision)
		
	def setSurfaceTables(self):
		self.surfaces = {}
		self.surfaces["plane"] = 0
		self.surfaces["box"] = 1
		self.surfaces["sphere"] = 2
		self.surfaces["bullet"] = 3
		n = len(self.surfaces)

		self.world.initSurfaceTable(n)
		for i in range(n):
			for j in range(n):
				# id1, id2, mu (0 to inf), bounce (1 = bouncy), min_bounce_vel, erp (1 = hard), cfm (0 = hard), slip, dampen
				# sample:   150,             0.0,                    9.1,       0.9,          0.00001,          0.0,  0.002
				self.world.setSurfaceEntry(i, j, 10.0, 1.0, 0.0, 0.9, 0.0, 0.5, 0.001) # Default value for unspecified pairs.
		self.world.setSurfaceEntry(self.surfaces["box"], self.surfaces["box"],
			200.0, 0.2, 0.3, 1.0, 0.0, 0.0, 0.01)
		self.world.setSurfaceEntry(self.surfaces["plane"], self.surfaces["box"],
			200.0, 0.2, 0.3, 1.0, 0.0, 0.0, 0.01)
		self.world.setSurfaceEntry(self.surfaces["box"], self.surfaces["bullet"],
			10.0, 0.1, 0.5, 1.0, 0.0, 0.0, 0.01)
		self.world.setSurfaceEntry(self.surfaces["plane"], self.surfaces["bullet"],
			100.0, 0.01, 0.1, 1.0, 0.0, 0.0, 1.0)

	def addObject(self, obj):
		self.objects.append(obj)

	def removeObject(self, obj):
		if obj not in self.objectsToRemove:
			self.objectsToRemove.append(obj)

	def removeDestroyedObjects(self):
		while len(self.objectsToRemove) > 0:
			obj = self.objectsToRemove.pop()
			if obj in self.objects:
				self.objects.remove(obj)
				obj.doDestroy()

	def togglePhysics(self):
		self.engineRunning = not self.engineRunning
		self.dtAccumulator = 0.0

	def processPhysics(self, task):
		stepSize = 1.0 / self.physicsFps
		maxDt = 1.0 / self.physicsMinFps
		if self.engineRunning:
			self.dtAccumulator += globalClock.getDt()
			self.dtAccumulator = min(self.dtAccumulator, maxDt)
			while self.dtAccumulator >= stepSize:
				self.space.autoCollide()
				self.world.quickStep(stepSize)
				for obj in self.objects:
					obj.updatePosFromPhysics()
				self.group.empty()
				self.performPostStepTasks()
				self.removeDestroyedObjects()
				self.dtAccumulator -= stepSize
		return task.cont

	def onCollision(self, entry):
		body1 = entry.getBody1()
		body2 = entry.getBody2()
		if not body1.isEmpty():
			body1.getData().onCollision(body2, entry)
		if not body2.isEmpty():
			body2.getData().onCollision(body1, entry)

	def performAfterStep(self, method, params):
		self.postStepTasks.append([method, params])

	def performPostStepTasks(self):
		for task in self.postStepTasks:
			method = task[0]
			params = task[1]
			method(*params)
		self.postStepTasks = []
示例#4
0
class GameModel:
    #Represents the world data.

    def __init__(self, base, mapNo):
        self.isListening = False

        # Holds rigid bodies, joints, controls global params
        self.world = OdeWorld()
        self.world.setGravity(0, 0, -9.8)

        st = SurfaceType()
        st.load(self.world)
        del st

        self.contactgroup = OdeJointGroup()

        self.space = OdeHashSpace()
        self.space.setAutoCollideWorld(self.world)
        self.space.setAutoCollideJointGroup(self.contactgroup)
        self.space.setCollisionEvent(EventType.ODE_COLLISION)
        base.accept(EventType.ODE_COLLISION, self.onCollision)

        self.ball = Ball(self.world, self.space, "Johanneksen pallo")

        self.level = Level(self, mapNo)
        self.player = Player("Johannes")

        self.camera = Camera(base, self.ball)

    def turnGravityTask(self):
        ''''''
        g = self.world.getGravity()
        g = -g
        self.world.setGravity(g)
        self.camera.turn()

    def turnGravityTask2(self):
        ''''''
        g = self.world.getGravity()
        g2 = self.ball.perpendicularUnitVec3WithFixedX(g)
        g2 *= g.length()
        self.world.setGravity(g2)

    def updateObjects(self):
        '''
		Update objects after one physics iteration
		@see GameLoop.simulationTask
		'''
        self.level.updateModelNode()
        self.camera.updateModelNode()
        #Has to be last for RESTART to work inside Ball
        self.ball.updateModelNode()

    def getBall(self):
        return self.ball

    def getPlayer(self):
        return self.player

    # http://www.panda3d.org/wiki/index.php/Collision_Detection_with_ODE
    def onCollision(self, entry):
        geom1 = entry.getGeom1()
        geom2 = entry.getGeom2()
        body1 = entry.getBody1()
        body2 = entry.getBody2()

        # Is the ball touching something?
        if body1 == self.ball.getBody() or body2 == self.ball.getBody():
            self.ball.refreshCollisionTime(entry)

        for coin in self.level.getCoins():
            if body1 == coin.getBody() and body2 == self.ball.getBody():
                coin.collect()
                messenger.send(EventType.UPDATE_HUD)

        exit = self.level.getExit()
        if geom1 == exit or geom2 == exit:
            if Coin.collectable == self.level.getGoal():
                # todo: make event based
                messenger.send(EventType.NEXT_LEVEL)

    def cleanUp(self):
        self.level.removeLevel()
        self.ball.removeNode()
示例#5
0
class Game:

    HUD_TEXT_SCALE = 0.1
    UPDATE_RATE = 1/60.0

    def __init__(self):
        self.LoadHUD()
        self.loadPhysics()
        self.loadLights()
        
        #self.wall = Wall(self)
        #self.wall.setPos( Vec3( 5, 0, 0) )
        
        self.ship1 = ShipTypes.Ship_2(self, Vec4(0.0, 0.0, 0.2, 0))
        self.ship2 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0))
        self.ship2.setPos( Vec3(10, 10, 0) )
        
        
        self.setKeys()
        
        self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0))
        self.pallo.setPos( Vec3(0, 20, 0) )
        self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0))
        self.pallo2.setPos( Vec3(30, 20, 0) )
        
 
        
        base.setBackgroundColor(0,0,0.0,0)
        
        taskMgr.add(self.loop, 'game loop')
        
        run()
        
    def setKeys(self):
        base.accept('arrow_up', self.ship1.thrustOn)
        base.accept('arrow_up-up', self.ship1.thrustOff)
        base.accept('arrow_left', self.ship1.thrustLeftOn)
        base.accept('arrow_left-up', self.ship1.thrustLeftOff)
        base.accept('arrow_right', self.ship1.thrustRightOn)
        base.accept('arrow_right-up', self.ship1.thrustRightOff) 
        base.accept('arrow_down', self.ship1.thrustBackOn)
        base.accept('arrow_down-up', self.ship1.thrustBackOff) 

        base.accept('w', self.ship2.thrustOn)
        base.accept('w-up', self.ship2.thrustOff)
        base.accept('a', self.ship2.thrustLeftOn)
        base.accept('a-up', self.ship2.thrustLeftOff)
        base.accept('d', self.ship2.thrustRightOn)
        base.accept('d-up', self.ship2.thrustRightOff) 
        base.accept('s', self.ship2.thrustBackOn)
        base.accept('s-up', self.ship2.thrustBackOff) 

        
        
        
    def loadPhysics(self):
        self.physicsWorld = OdeWorld()
        self.physicsWorld.initSurfaceTable(1)
        self.physicsWorld.setSurfaceEntry(
          0,
          0,
          1.0, # u
          0.35, # elasticity
          0.01, # minimum threshold for physical movement
          0.01,
          0.00000001, # softening
          0.01,
          0.01 # damping
        )
        self.physicsSpace = OdeHashSpace()
        self.physicsSpace.setAutoCollideWorld(self.physicsWorld)
        self.contactGroup = OdeJointGroup()
        self.physicsSpace.setAutoCollideJointGroup(self.contactGroup)

    def LoadHUD(self):
        self.winnerText = OnscreenText(
            text = "Tekstia, tekstia, tekstia",
            fg = (1,1,1,1),
            pos = (-0.25, 0),
            align = TextNode.ALeft,
            scale = Game.HUD_TEXT_SCALE
        )
        self.winnerText.hide()

    def loadLights(self):
        light1 = DirectionalLight('light1')
        lightNode1 = render.attachNewNode(light1)
        light1.setDirection( Vec3(-1, 0.5, -0.25) )
        light1.setColor( Vec4(0.5, 0.9, 0.9, 0) )
        render.setLight(lightNode1)
        
        
        
    def loop(self, task):
        self.ship1.applyForces()
        self.ship2.applyForces()
        self.physicsSpace.autoCollide()
        self.pallo.hitShips(self.ship1, self.ship2)
        self.pallo2.hitShips(self.ship1, self.ship2)
       # self.wall.osuminen(self.ship1)
        self.physicsWorld.quickStep(Game.UPDATE_RATE)
        self.ship1.update(Game.UPDATE_RATE)
        self.ship2.update(Game.UPDATE_RATE)
        self.pallo.update(Game.UPDATE_RATE)
        self.pallo2.update(Game.UPDATE_RATE)
        self.contactGroup.empty()
        return task.cont