Mercurial > fife-parpg
changeset 467:4d0aa75a82f1
Added damage so some enemies take more than one hit to destroy.
Added the boss at the end of the level.
For some reason the high score dialog box that appears after the level is completed causes a crash. Still looking into this one.
author | prock@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Wed, 14 Apr 2010 16:22:36 +0000 |
parents | 716d44ba42df |
children | ebbb420a90b9 |
files | demos/shooter/maps/shooter_map1.xml demos/shooter/scripts/scene.py demos/shooter/scripts/ships/enemies.py demos/shooter/scripts/ships/shipbase.py demos/shooter/scripts/weapons.py demos/shooter/scripts/world.py |
diffstat | 6 files changed, 167 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/demos/shooter/maps/shooter_map1.xml Tue Apr 13 21:30:51 2010 +0000 +++ b/demos/shooter/maps/shooter_map1.xml Wed Apr 14 16:22:36 2010 +0000 @@ -563,6 +563,8 @@ <i r="0" id="dodge2" x="147.0" o="saucer2" z="0.0" y="1.0"></i> <i r="0" id="streaker" x="147.0" o="saucer2" z="0.0" y="4.0"></i> <i r="0" id="streaker" x="147.0" o="saucer2" z="0.0" y="-5.0"></i> + + <i r="0" id="boss" x="147.0" o="saucer1" z="0.0" y="0.0"></i> </instances> </layer>
--- a/demos/shooter/scripts/scene.py Tue Apr 13 21:30:51 2010 +0000 +++ b/demos/shooter/scripts/scene.py Wed Apr 14 16:22:36 2010 +0000 @@ -67,12 +67,37 @@ self._timemod = 0 self._gameover = False + + self._boss = None + + def destroyScene(self): + nodestodelete = list() + objtodelete = list() + + for node in self._nodes: + nodestodelete.append(node) + for obj in node.spaceobjects: + objtodelete.append(node) + + for obj in objtodelete: + if obj in node.spaceobjects: + node.spaceobjects.remove(obj) + + objtodelete = list() + + for node in nodestodelete: + if node in self._nodes: + self._nodes.remove(node) + + self.removeAllProjectiles() def initScene(self, mapobj): #initialize our scene array to some arbitrary size for i in range(0,self._maxnodes): self._nodes.append(SceneNode()) + self._boss = None + self._player = Player(self, 'player') self._player.init() self._player.start() @@ -94,6 +119,9 @@ temp = self._layer.getInstances("streaker") enemies.extend(temp) + temp = self._layer.getInstances("boss") + enemies.extend(temp) + for instance in enemies: objectName = instance.getId() print objectName @@ -108,6 +136,9 @@ enemy = DiagSaucer(self, 'enemy', 1, instance, False) elif objectName == "streaker": enemy = Streaker(self, 'enemy', instance, False) + elif objectName == "boss": + enemy = Boss(self, 'enemy', instance, False) + self._boss = enemy else: enemy = Ship(self, 'enemy', instance, False) @@ -121,6 +152,8 @@ #and finally add the player to the scene self.addObjectToScene(self._player) + self.startCamera() + def pause(self, time): self._pausedtime = time self._paused = True @@ -138,7 +171,9 @@ return #self._player.setInvulnerable(2) - + + def endLevel(self): + self._world.endLevel() def removeAllProjectiles(self): projtodelete = list() @@ -147,7 +182,8 @@ projtodelete.append(p) for p in projtodelete: - self._projectiles.remove(p) + if p in self._projectiles: + self._projectiles.remove(p) def getObjectsInNode(self, nodeindex): return self._nodes[nodeindex].instances @@ -189,7 +225,13 @@ def attachCamera(self, cam): self._camera = cam self._camera.setLocation(self._player.location) + + def stopCamera(self): + self._cameraspeed = 0 + def startCamera(self): + self._cameraspeed = 0.001 + def update(self, time, keystate): timedelta = (time - self._timemod) - self._time self._timedelta = timedelta @@ -201,13 +243,13 @@ loc = self._camera.getLocation() exactloc = self._camera.getLocation().getExactLayerCoordinates() #slowly move to the right - exactloc.x += timedelta * 0.001 + exactloc.x += timedelta * self._cameraspeed loc.setExactLayerCoordinates(exactloc) self._camera.setLocation(loc) topleft = self._camera.toMapCoordinates(fife.ScreenPoint(0,0)) bottomright = self._camera.toMapCoordinates(fife.ScreenPoint(1024,768)) - + #which scene nodes to use to update objects leftnode = int(topleft.x) rightnode = int(bottomright.x) + 1 @@ -218,10 +260,13 @@ if rightnode > self._maxnodes: rightnode = self._maxnodes screenlist = self.getObjectsInRange(leftnode, rightnode) - #update objects on the screen for obj in screenlist: + if obj == self._boss: + if bottomright.x > ((self._boss.location.getExactLayerCoordinates().x * self._xscale) + 0.5): + self.stopCamera() + if not (obj == self._player and self._gameover): obj.update() @@ -254,12 +299,11 @@ if p.owner != o: if o.running and p.boundingbox.intersects(o.boundingbox): if o != self._player and p.owner.isplayer: - self._player.applyScore(100) + o.applyHit(p.damage) + #check if enemy ship was destroyed + if not o.running: + self._player.applyScore(o.scorevalue) p.destroy() - o.destroy() - #TODO: the destroy functions should spawn an explosion - #and also destroy the instance and remove itself from the scene - #self.removeObjectFromScene(o) elif o == self._player: #player got hit by a projectile if not self._player.invulnerable:
--- a/demos/shooter/scripts/ships/enemies.py Tue Apr 13 21:30:51 2010 +0000 +++ b/demos/shooter/scripts/ships/enemies.py Wed Apr 14 16:22:36 2010 +0000 @@ -35,6 +35,15 @@ if action.getId() == 'explode': self._ship.removeFromScene() +class BossActionListener(ShipActionListener): + def __init__(self, ship): + super(BossActionListener, self).__init__(ship) + + def onInstanceActionFinished(self, instance, action): + if action.getId() == 'explode': + self._ship.removeFromScene() + self._ship.endLevel() + class Saucer1(Ship): def __init__(self, scene, name, instance, findInstance=True): super(Saucer1, self).__init__(scene, name, findInstance) @@ -49,6 +58,9 @@ self.weapon.projectilevelocity = 0.4 self._actionlistener = EnemyActionListener(self) + + self.hitpoints = 1 + self.scorevalue = 50 def update(self): if self._dir == 1: @@ -82,6 +94,10 @@ self.weapon.projectilevelocity = 0.4 self._actionlistener = EnemyActionListener(self) + + self.hitpoints = 2 + self.scorevalue = 100 + def update(self): if self._dir == 1: @@ -117,6 +133,9 @@ self.weapon.projectilevelocity = 0.4 self._actionlistener = EnemyActionListener(self) + + self.hitpoints = 1 + self.scorevalue = 50 def update(self): self.applyThrust(fife.DoublePoint(-0.25,self._ythrust)) @@ -135,7 +154,33 @@ self.weapon.projectilevelocity = 1.0 self._actionlistener = EnemyActionListener(self) - + + self.hitpoints = 2 + self.scorevalue = 150 + def update(self): self.applyThrust(fife.DoublePoint(-0.40,0)) - super(Streaker, self).update() \ No newline at end of file + super(Streaker, self).update() + +class Boss(Ship): + def __init__(self, scene, name, instance, findInstance=True): + super(Boss, self).__init__(scene, name, findInstance) + self._instance = instance + self.width = 0.2 + self.height = 0.2 + + self._maxvelocity = 2.0 + + self.weapon = Cannon(self._scene, self, 1000) + self.weapon.projectilevelocity = 0.5 + + self._actionlistener = BossActionListener(self) + + self.hitpoints = 20 + self.scorevalue = 1000 + + def endLevel(self): + self._scene.endLevel() + + def update(self): + super(Boss, self).update() \ No newline at end of file
--- a/demos/shooter/scripts/ships/shipbase.py Tue Apr 13 21:30:51 2010 +0000 +++ b/demos/shooter/scripts/ships/shipbase.py Wed Apr 14 16:22:36 2010 +0000 @@ -48,6 +48,9 @@ self._flashing = False self._isplayer = False + + self._hitpoints = 0 + self._scorevalue = 0 def _setWeapon(self, weapon): self._weapon = weapon @@ -66,6 +69,11 @@ return None + def applyHit(self, hp): + self._hitpoints -= hp + if self._hitpoints <= 0: + self.destroy() + def destroy(self): if self._running: self._instance.act('explode', self._instance.getFacingLocation()) @@ -74,6 +82,20 @@ def _isPlayer(self): return self._isplayer + + def _getHitPoints(self): + return self._hitpoints + + def _setHitPoints(self, hp): + self._hitpoints = hp + + def _getScoreValue(self): + return self._scorevalue + + def _setScoreValue(self, value): + self._scorevalue = value + isplayer = property(_isPlayer) weapon = property(_getWeapon, _setWeapon) - \ No newline at end of file + hitpoints = property(_getHitPoints, _setHitPoints) + scorevalue = property(_getScoreValue, _setScoreValue) \ No newline at end of file
--- a/demos/shooter/scripts/weapons.py Tue Apr 13 21:30:51 2010 +0000 +++ b/demos/shooter/scripts/weapons.py Wed Apr 14 16:22:36 2010 +0000 @@ -39,6 +39,8 @@ self.width = 0.025 self.height = 0.025 + + self._damage = 1 def create(self, location): self._instance = self._layer.createInstance(self._obj, location.getExactLayerCoordinates(), "bullet") @@ -72,9 +74,16 @@ super(Projectile, self).update() else: self.destroy() + + def _getDamage(self): + return self._damage + + def _setDamage(self, dam): + self._damage = dam ttl = property(_getTTL) owner = property(_getOwner) + damage = property(_getDamage, _setDamage) class Weapon(object): def __init__(self, scene, ship, firerate):
--- a/demos/shooter/scripts/world.py Tue Apr 13 21:30:51 2010 +0000 +++ b/demos/shooter/scripts/world.py Wed Apr 14 16:22:36 2010 +0000 @@ -79,6 +79,8 @@ self._genericrenderer = None + self._sceneended = False + def showMainMenu(self): if self.scene: self._paused = True @@ -105,7 +107,12 @@ self.map = None self.cameras = {} - self.scene = None + + if self.scene: + self.scene.destroyScene() + self.scene = None + + self._sceneended = False def loadLevel(self, filename): """ @@ -193,9 +200,28 @@ dlg = pychan.loadXML('gui/highscoredialog.xml') dlg.execute({ 'okay' : "Yay!" }) name = dlg.findChild(name='name').text + self._highscores.addHighScore(HighScore(name, self.scene.player.score)) self._highscores.show() + + def endLevel(self): + #there is only one level so do the high score display + self._paused = True + + if self._highscores.isHighScore(self.scene.player.score): + score = self.scene.player.score + #self.reset() + dlg = pychan.loadXML('gui/highscoredialog.xml') + dlg.execute({ 'okay' : "Yay!" }) + name = dlg.findChild(name='name').text + + #self._highscores.addHighScore(HighScore(name, score)) + #self._highscores.show() + + self._sceneended = True + + def newGame(self): self.loadLevel("maps/shooter_map1.xml") @@ -275,6 +301,10 @@ Called every frame. """ + if self._sceneended: + self.reset() + self.showMainMenu() + if self._genericrenderer: self._genericrenderer.removeAll("quads") @@ -320,4 +350,5 @@ if not self.scene.paused: self.scene.pause(self.timemanager.getTime() - self._starttime) + self.pump_ctr += 1