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
class Game(): HUD_TEXT_SCALE = 0.04 UPDATE_RATE = 1/60.0 MAX_PYLON_POWER = 50 def __init__(self): self.zoomLevels = deque([640, 512, 320, 1280]) self.curLev = self.zoomLevels[0] base.disableMouse() self.initCam() self.loadPhysics() self.loadLights() #map x boundary, map y boundary, amount of pylons self.map = Map(self, 150.0, 150.0, 7) self.shipList = [] self.ship1 = ShipTypes.Ship_1(self, Vec4(0.6, 0.0, 0.0, 0.0)) self.ship2 = ShipTypes.Ship_2(self, Vec4(0.0, 0.0, 0.6, 0.0)) self.ship1.setPos( Vec3(0, 120, 0) ) self.ship2.setPos( Vec3(0, -120, 0) ) self.shipList.append(self.ship1) self.shipList.append(self.ship2) self.LoadHUD() self.setKeys() self.collectibleList = [] self.pallo = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) self.pallo.setPos( Vec3(0, 20, 0) ) self.pallo.addToCollectibleList(self.collectibleList) #self.pallo2 = CollectibleTypes.Pallo(self, Vec4(0.0, 0.3, 0.0, 0)) #self.pallo2.setPos( Vec3(30, 20, 0) ) #self.pallo2.addToCollectibleList(self.collectibleList) b=OnscreenImage(parent=render2d, image="Geminid.jpg") base.cam.node().getDisplayRegion(0).setSort(20) base.setBackgroundColor(0,0,0.0,0) self.collisionSfx = loader.loadSfx("shipcollision.wav") self.goalSfx = loader.loadSfx("goal.wav") self.victorySfx = loader.loadSfx("victory.wav") self.collision2Sfx = loader.loadSfx("pyloncollision.wav") filters = CommonFilters(base.win, base.cam) render.setShaderAuto() taskMgr.add(self.loop, 'game loop') run() def setKeys(self): base.accept('arrow_up', self.ship1.thrustOn) base.accept('arrow_up-up', self.ship1.thrustOff) base.accept('arrow_left', self.ship1.thrustLeftOn) base.accept('arrow_left-up', self.ship1.thrustLeftOff) base.accept('arrow_right', self.ship1.thrustRightOn) base.accept('arrow_right-up', self.ship1.thrustRightOff) base.accept('arrow_down', self.ship1.thrustBackOn) base.accept('arrow_down-up', self.ship1.thrustBackOff) base.accept('rshift', self.ship1.releaseBall) base.accept('w', self.ship2.thrustOn) base.accept('w-up', self.ship2.thrustOff) base.accept('a', self.ship2.thrustLeftOn) base.accept('a-up', self.ship2.thrustLeftOff) base.accept('d', self.ship2.thrustRightOn) base.accept('d-up', self.ship2.thrustRightOff) base.accept('s', self.ship2.thrustBackOn) base.accept('s-up', self.ship2.thrustBackOff) base.accept('q', self.ship2.releaseBall) base.accept('+', self.zoom) base.accept('p', self.toggleAI) def loadPhysics(self): self.physicsWorld = OdeWorld() self.physicsWorld.initSurfaceTable(1) self.physicsWorld.setSurfaceEntry( 0, 0, 1.0, # u 0.35, # elasticity 0.01, # minimum threshold for physical movement 0.01, 0.00000001, # softening 0.01, 0.01 # damping ) self.physicsWorld.setGravity(0, 0, -20) self.physicsSpace = OdeHashSpace() self.physicsSpace.setAutoCollideWorld(self.physicsWorld) self.contactGroup = OdeJointGroup() self.physicsSpace.setAutoCollideJointGroup(self.contactGroup) def LoadHUD(self): self.player1HUD = OnscreenText( text = "Player 1: " + str( self.ship1.getPoints() ), fg = (1,1,1,1), #pos = ( x, y ) pos = (0.7,0.9), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.player2HUD = OnscreenText( text = "Player 2: " + str( self.ship2.getPoints() ), fg = (1,1,1,1), pos = (-0.7,0.9), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE ) self.winnerText = OnscreenText( text = "Tekstia, tekstia, tekstia", fg = (1,1,1,1), pos = (-0.2, 0), align = TextNode.ALeft, scale = Game.HUD_TEXT_SCALE*3 ) # self.winnerText.setZ(200) self.winnerText.hide() def updateHUD(self): self.player1HUD.setText( "Player 1: " + str( self.ship1.getPoints() ) ) self.player2HUD.setText( "Player 2: " + str( self.ship2.getPoints() ) ) if (self.ship1.getPoints() > 9): self.winnerText.show() self.winnerText.setText( "Player 1 won " + str(self.ship1.getPoints()) + "-" + str(self.ship2.getPoints())) self.victorySfx.play() base.cam.node().getDisplayRegion(0).setSort(0) # self.Pause() if (self.ship2.getPoints() > 9): self.winnerText.show() self.winnerText.setText( "Player 2 won " + str(self.ship2.getPoints()) + "-" + str(self.ship1.getPoints())) self.victorySfx.play() base.cam.node().getDisplayRegion(0).setSort(0) def loadLights(self): light1 = DirectionalLight('light1') lightNode1 = render.attachNewNode(light1) light1.setDirection( Vec3(-1, 0.5, -0.25) ) light1.setColor( Vec4(0.6, 0.6, 0.6, 0) ) render.setLight(lightNode1) #checks all collectibles for possible collisions with ships def checkAllCollectibles(self, shipList): for collectible in self.collectibleList: collectible.hitShips(shipList) #updates all collectible positions def updateAllCollectibles(self): for collectible in self.collectibleList: collectible.update(Game.UPDATE_RATE) def applyForceAllShips(self, shipList): for ship in shipList: ship.applyForces() #updates all ship positions def updateAllShips(self, shipList): for ship in shipList: ship.update(Game.UPDATE_RATE) shipList[0].shipsCollide(shipList[1]) #checks all pylons for possible collisions with ships def checkAllPylons(self, pylonList, shipList): for pylon in pylonList: pylon.checkCollisionList(shipList) def loop(self, task): self.applyForceAllShips(self.shipList) self.physicsSpace.autoCollide() self.checkAllCollectibles(self.shipList) self.map.getBase1().checkCollision(self.ship1, self.collectibleList) self.map.getBase2().checkCollision(self.ship2, self.collectibleList) self.checkAllPylons(self.map.getPylonList(), self.shipList) self.physicsWorld.quickStep(Game.UPDATE_RATE) self.updateAllShips(self.shipList) self.updateAllCollectibles() self.contactGroup.empty() return task.cont def toggleAI(self): if taskMgr.hasTaskNamed('Simple AI'): taskMgr.remove('Simple AI') return taskMgr.add( self.chaseBallsAround, name='Simple AI', sort=None, extraArgs=(self.ship1, self.ship2, self.collectibleList, self.map.getBase1()), priority=None, uponDeath=None, appendTask=True, taskChain=None, owner=None) def chaseBallsAround(self, chaser, enemy, chaseList, base, task): pos = chaser.getPos() nearestNormedPos = 1e10000 #represents infinity nearestRelPos = [0,0] if chaser.hasBall(): chasePos = base.getPos() nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] elif enemy.hasBall(): chasePos = enemy.getPos() nearestRelPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] else: for collectible in chaseList: chasePos = collectible.getPos() relPos = [ pos[0] - chasePos[0], pos[1] - chasePos[1] ] if (math.fabs(relPos[0]) + math.fabs(relPos[1])) < nearestNormedPos: nearestNormedPos = math.fabs(relPos[0]) + math.fabs(relPos[1]) nearestRelPos = relPos if nearestRelPos[0] > 0: chaser.thrustRightOff() chaser.thrustLeftOn() elif nearestRelPos[0] < 0: chaser.thrustLeftOff() chaser.thrustRightOn() if nearestRelPos[1] < 0: chaser.thrustBackOff() chaser.thrustOn() elif nearestRelPos[1] > 0: chaser.thrustOff() chaser.thrustBackOn() else: chaser.thrustOff() chaser.thrustBackOff() return task.cont def initCam(self): base.camera.setPos(0,0,self.curLev) base.camera.lookAt(0,0,0) def zoom(self): self.curLev = self.zoomLevels.popleft() base.camera.setPos(0, 0, self.curLev) self.zoomLevels.append(self.curLev) def shakeCam(self): taskMgr.add(self.shakeCamTask, name='ShakeCam') def shakeCamTask(self, task): oldPos = base.camera.getPos() base.camera.setPos(oldPos[0]+random.randint(-1, 1), oldPos[1]+random.randint(-1, 1), oldPos[2]+random.randint(-4, 4)) if task.time < 0.5: return task.cont self.initCam() return task.done
class World: def __init__(self, game): self.game = game self.world = OdeWorld() self.world.setGravity(0, 0, -9.81 * 3) self.group = OdeJointGroup() self.space = OdeHashSpace() self.space.setAutoCollideWorld(self.world) self.space.setAutoCollideJointGroup(self.group) self.setSurfaceTables() self.objects = [] self.objectsToRemove = [] self.postStepTasks = [] self.engineRunning = True self.dtAccumulator = 0.0 self.physicsFps = 90 self.physicsMinFps = 10 base.taskMgr.doMethodLater(0.1, self.processPhysics, "Physics") base.accept("escape", self.togglePhysics) self.space.setCollisionEvent("odeCollision") base.accept("odeCollision", self.onCollision) def setSurfaceTables(self): self.surfaces = {} self.surfaces["plane"] = 0 self.surfaces["box"] = 1 self.surfaces["sphere"] = 2 self.surfaces["bullet"] = 3 n = len(self.surfaces) self.world.initSurfaceTable(n) for i in range(n): for j in range(n): # id1, id2, mu (0 to inf), bounce (1 = bouncy), min_bounce_vel, erp (1 = hard), cfm (0 = hard), slip, dampen # sample: 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002 self.world.setSurfaceEntry(i, j, 10.0, 1.0, 0.0, 0.9, 0.0, 0.5, 0.001) # Default value for unspecified pairs. self.world.setSurfaceEntry(self.surfaces["box"], self.surfaces["box"], 200.0, 0.2, 0.3, 1.0, 0.0, 0.0, 0.01) self.world.setSurfaceEntry(self.surfaces["plane"], self.surfaces["box"], 200.0, 0.2, 0.3, 1.0, 0.0, 0.0, 0.01) self.world.setSurfaceEntry(self.surfaces["box"], self.surfaces["bullet"], 10.0, 0.1, 0.5, 1.0, 0.0, 0.0, 0.01) self.world.setSurfaceEntry(self.surfaces["plane"], self.surfaces["bullet"], 100.0, 0.01, 0.1, 1.0, 0.0, 0.0, 1.0) def addObject(self, obj): self.objects.append(obj) def removeObject(self, obj): if obj not in self.objectsToRemove: self.objectsToRemove.append(obj) def removeDestroyedObjects(self): while len(self.objectsToRemove) > 0: obj = self.objectsToRemove.pop() if obj in self.objects: self.objects.remove(obj) obj.doDestroy() def togglePhysics(self): self.engineRunning = not self.engineRunning self.dtAccumulator = 0.0 def processPhysics(self, task): stepSize = 1.0 / self.physicsFps maxDt = 1.0 / self.physicsMinFps if self.engineRunning: self.dtAccumulator += globalClock.getDt() self.dtAccumulator = min(self.dtAccumulator, maxDt) while self.dtAccumulator >= stepSize: self.space.autoCollide() self.world.quickStep(stepSize) for obj in self.objects: obj.updatePosFromPhysics() self.group.empty() self.performPostStepTasks() self.removeDestroyedObjects() self.dtAccumulator -= stepSize return task.cont def onCollision(self, entry): body1 = entry.getBody1() body2 = entry.getBody2() if not body1.isEmpty(): body1.getData().onCollision(body2, entry) if not body2.isEmpty(): body2.getData().onCollision(body1, entry) def performAfterStep(self, method, params): self.postStepTasks.append([method, params]) def performPostStepTasks(self): for task in self.postStepTasks: method = task[0] params = task[1] method(*params) self.postStepTasks = []
class GameModel: #Represents the world data. def __init__(self, base, mapNo): self.isListening = False # Holds rigid bodies, joints, controls global params self.world = OdeWorld() self.world.setGravity(0, 0, -9.8) st = SurfaceType() st.load(self.world) del st self.contactgroup = OdeJointGroup() self.space = OdeHashSpace() self.space.setAutoCollideWorld(self.world) self.space.setAutoCollideJointGroup(self.contactgroup) self.space.setCollisionEvent(EventType.ODE_COLLISION) base.accept(EventType.ODE_COLLISION, self.onCollision) self.ball = Ball(self.world, self.space, "Johanneksen pallo") self.level = Level(self, mapNo) self.player = Player("Johannes") self.camera = Camera(base, self.ball) def turnGravityTask(self): '''''' g = self.world.getGravity() g = -g self.world.setGravity(g) self.camera.turn() def turnGravityTask2(self): '''''' g = self.world.getGravity() g2 = self.ball.perpendicularUnitVec3WithFixedX(g) g2 *= g.length() self.world.setGravity(g2) def updateObjects(self): ''' Update objects after one physics iteration @see GameLoop.simulationTask ''' self.level.updateModelNode() self.camera.updateModelNode() #Has to be last for RESTART to work inside Ball self.ball.updateModelNode() def getBall(self): return self.ball def getPlayer(self): return self.player # http://www.panda3d.org/wiki/index.php/Collision_Detection_with_ODE def onCollision(self, entry): geom1 = entry.getGeom1() geom2 = entry.getGeom2() body1 = entry.getBody1() body2 = entry.getBody2() # Is the ball touching something? if body1 == self.ball.getBody() or body2 == self.ball.getBody(): self.ball.refreshCollisionTime(entry) for coin in self.level.getCoins(): if body1 == coin.getBody() and body2 == self.ball.getBody(): coin.collect() messenger.send(EventType.UPDATE_HUD) exit = self.level.getExit() if geom1 == exit or geom2 == exit: if Coin.collectable == self.level.getGoal(): # todo: make event based messenger.send(EventType.NEXT_LEVEL) def cleanUp(self): self.level.removeLevel() self.ball.removeNode()
class Game: 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