Mercurial > fife-parpg
changeset 459:302a69c5141d
Player death is now handled a bit nicer.
Added invulnerability.
Added 3 more enemy types.
Fixed a bug in the collision detection routine that caused some objects not to be updated when a collision is detected.
author | prock@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Fri, 09 Apr 2010 17:35:52 +0000 |
parents | e77ebf128a74 |
children | 5e1d6e40d19d |
files | demos/shooter/maps/shooter_map1.xml demos/shooter/scripts/scene.py demos/shooter/scripts/ships/enemies.py demos/shooter/scripts/ships/player.py demos/shooter/scripts/ships/shipbase.py |
diffstat | 5 files changed, 149 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/demos/shooter/maps/shooter_map1.xml Thu Apr 08 21:26:46 2010 +0000 +++ b/demos/shooter/maps/shooter_map1.xml Fri Apr 09 17:35:52 2010 +0000 @@ -438,12 +438,27 @@ <layer y_scale="0.25" y_offset="0.0" pathing="cell_edges_and_diagonals" grid_type="square" id="objects" rotation="0.0" x_scale="0.25" x_offset="0.0" transparency="0"> <instances> <i o="ship1" z="0.0" x="7.0" r="0" y="0.0" id="player"></i> - <i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="-2.0"></i> - <i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="1.0"></i> - <i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="4.0"></i> - <i r="0" id="enemy" x="20.0" o="saucer1" z="0.0" y="-5.0"></i> - <i r="0" id="enemy" x="26.0" o="saucer2" z="0.0" y="-3.0"></i> - <i r="0" id="enemy" x="26.0" o="saucer2" z="0.0" y="2.0"></i> + <i r="0" id="dodge1" x="20.0" o="saucer1" z="0.0" y="-2.0"></i> + <i r="0" id="dodge1" x="20.0" o="saucer1" z="0.0" y="1.0"></i> + <i r="0" id="dodge1" x="20.0" o="saucer1" z="0.0" y="4.0"></i> + <i r="0" id="dodge1" x="20.0" o="saucer1" z="0.0" y="-5.0"></i> + <i r="0" id="dodge2" x="26.0" o="saucer2" z="0.0" y="-3.0"></i> + <i r="0" id="dodge2" x="26.0" o="saucer2" z="0.0" y="2.0"></i> + + <i r="0" id="diag_top_right" x="32.0" o="saucer1" z="0.0" y="-6.0"></i> + <i r="0" id="diag_top_right" x="33.0" o="saucer1" z="0.0" y="-7.0"></i> + <i r="0" id="diag_top_right" x="34.0" o="saucer1" z="0.0" y="-8.0"></i> + <i r="0" id="diag_top_right" x="35.0" o="saucer1" z="0.0" y="-9.0"></i> + <i r="0" id="diag_bottom_right" x="32.0" o="saucer1" z="0.0" y="6.0"></i> + <i r="0" id="diag_bottom_right" x="33.0" o="saucer1" z="0.0" y="7.0"></i> + <i r="0" id="diag_bottom_right" x="34.0" o="saucer1" z="0.0" y="8.0"></i> + <i r="0" id="diag_bottom_right" x="35.0" o="saucer1" z="0.0" y="9.0"></i> + + <i r="0" id="streaker" x="37.0" o="saucer1" z="0.0" y="-2.0"></i> + <i r="0" id="streaker" x="37.0" o="saucer1" z="0.0" y="1.0"></i> + <i r="0" id="streaker" x="37.0" o="saucer1" z="0.0" y="4.0"></i> + <i r="0" id="streaker" x="37.0" o="saucer1" z="0.0" y="-5.0"></i> + </instances> </layer> <camera ref_cell_height="256" zoom="1" rotation="0.0" ref_layer_id="background" ref_cell_width="256" id="main" tilt="0.0">
--- a/demos/shooter/scripts/scene.py Thu Apr 08 21:26:46 2010 +0000 +++ b/demos/shooter/scripts/scene.py Fri Apr 09 17:35:52 2010 +0000 @@ -69,26 +69,47 @@ self._gameover = False def initScene(self, mapobj): + #initialize our scene array to some arbitrary size + for i in range(0,self._maxnodes): + self._nodes.append(SceneNode()) + self._player = Player(self, 'player') self._player.width = 0.075 self._player.height = 0.075 self._player.init() self._player.start() - - enemies = self._layer.getInstances('enemy') + + enemies = list() - #initialize our scene array to some arbitrary size - for i in range(0,self._maxnodes): - self._nodes.append(SceneNode()) - + temp = self._layer.getInstances('dodge1') + enemies.extend(temp) + + temp = self._layer.getInstances('dodge2') + enemies.extend(temp) + + temp = self._layer.getInstances("diag_top_right") + enemies.extend(temp) + + temp = self._layer.getInstances("diag_bottom_right") + enemies.extend(temp) + + temp = self._layer.getInstances("streaker") + enemies.extend(temp) + for instance in enemies: - objectName = instance.getObject().getId() + objectName = instance.getId() print objectName - if objectName == "saucer1": + if objectName == "dodge1": enemy = Saucer1(self, 'enemy', False) - elif objectName == "saucer2": + elif objectName == "dodge2": enemy = Saucer2(self, 'enemy', False) + elif objectName == "diag_top_right": + enemy = DiagSaucer(self, 'enemy', 0, False) + elif objectName == "diag_bottom_right": + enemy = DiagSaucer(self, 'enemy', 1, False) + elif objectName == "streaker": + enemy = Streaker(self, 'enemy', False) else: enemy = Ship(self, 'enemy', False) @@ -111,26 +132,16 @@ self._timemod += time - self._pausedtime self._paused = False - def playerDied(self): + def playerHit(self): self._player.destroy() if self._player.lives <= -1: self._gameover = True self._world.gameOver() self.removeAllProjectiles() return - - #TODO: Have to find a better way to do this. If the player - #dies too many times right at the start of the level he will - #get pushed past the edge of the map to the left. - #IDEA: count down to ready player to start again - oldpos = self._player.location - pos = oldpos.getExactLayerCoordinates() - pos.x -= 5 - oldpos.setExactLayerCoordinates(pos) - self._player.location = oldpos - self._camera.setLocation(self._player.location) - - self.removeAllProjectiles() + + self._player.setInvulnerable(2) + def removeAllProjectiles(self): projtodelete = list() @@ -140,9 +151,6 @@ for p in projtodelete: self._projectiles.remove(p) - - def gameOver(self): - self._world.gameOver() def getObjectsInNode(self, nodeindex): return self._nodes[nodeindex].instances @@ -230,8 +238,9 @@ if obj.boundingbox.intersects(self._player.boundingbox): #player touched an enemy. Destroy player and #re-initialize scene - self.playerDied() - return + if not self._player.invulnerable: + self.playerHit() + #update the list of projectiles @@ -252,9 +261,10 @@ self.removeObjectFromScene(o) else: #player got hit by a projectile - p.destroy() - self.playerDied() - return + if not self._player.invulnerable: + p.destroy() + self.playerHit() + #build a list of projectiles to remove (ttl expired) if not p.running:
--- a/demos/shooter/scripts/ships/enemies.py Thu Apr 08 21:26:46 2010 +0000 +++ b/demos/shooter/scripts/ships/enemies.py Fri Apr 09 17:35:52 2010 +0000 @@ -85,4 +85,35 @@ self._time += self._scene.timedelta - super(Saucer2, self).update() \ No newline at end of file + super(Saucer2, self).update() + +class DiagSaucer(Ship): + def __init__(self, scene, name, direction, findInstance=True): + super(DiagSaucer, self).__init__(scene, name, findInstance) + self.width = 0.2 + self.height = 0.2 + + if direction == 0: + self._ythrust = 0.25 + else: + self._ythrust = -0.25 + + self.weapon = Cannon(self._scene, self, 2000) + self.weapon.projectilevelocity = 0.4 + + def update(self): + self.applyThrust(fife.DoublePoint(-0.25,self._ythrust)) + super(DiagSaucer, self).update() + +class Streaker(Ship): + def __init__(self, scene, name, findInstance=True): + super(Streaker, self).__init__(scene, name, findInstance) + + self._maxvelocity = 2.0 + + self.weapon = Cannon(self._scene, self, 2000) + self.weapon.projectilevelocity = 1.0 + + def update(self): + self.applyThrust(fife.DoublePoint(-0.40,0)) + super(Streaker, self).update() \ No newline at end of file
--- a/demos/shooter/scripts/ships/player.py Thu Apr 08 21:26:46 2010 +0000 +++ b/demos/shooter/scripts/ships/player.py Fri Apr 09 17:35:52 2010 +0000 @@ -38,6 +38,7 @@ self.weapon = Cannon(self._scene, self, 200) self._lives = 3 + self._invulnerable = False def init(self): self._lives = 3 @@ -49,15 +50,23 @@ self._score += sc def destroy(self): - self._lives -= 1 + if not self._flashing: + self._lives -= 1 - if self._lives < 0: - self._lives = -1 + if self._lives < 0: + self._lives = -1 - + def setInvulnerable(self, seconds): + self.flash(20, 20*seconds) + self._invulnerable = True + def update(self): key = False + + #player is no longer invulnerable + if not self._flashing and self._invulnerable: + self._invulnerable = False oldpos = self.location @@ -116,6 +125,10 @@ def _getLives(self): return self._lives + + def _getInvulnerable(self): + return self._invulnerable score = property(_getScore) - lives = property(_getLives) \ No newline at end of file + lives = property(_getLives) + invulnerable = property(_getInvulnerable) \ No newline at end of file
--- a/demos/shooter/scripts/ships/shipbase.py Thu Apr 08 21:26:46 2010 +0000 +++ b/demos/shooter/scripts/ships/shipbase.py Fri Apr 09 17:35:52 2010 +0000 @@ -33,6 +33,13 @@ super(Ship, self).__init__(scene, name, findInstance) self._weapon = None + self._flashrate = 0 + self._flashnumber = 0 + self._flashing = False + self._flashtime = 0 + + #1 = on, 0 = invisible (off) + self._flashstate = 1 def _setWeapon(self, weapon): self._weapon = weapon @@ -45,6 +52,36 @@ return self._weapon.fire(direction) return None + + def flash(self, rate, number): + """ + Flash rate is measured in flashes per second. A single flash + would be an off and on cycle. + """ + self._flashing = True + self._flashrate = rate * 2 + self._flashnumber = number * 2 + + + def update(self): + if self._flashing: + if self._flashnumber <= 0: + self._flashing = False + self._instance.get2dGfxVisual().setVisible(True) + else: + self._flashtime += self._scene.timedelta + if self._flashtime >= 1000/self._flashrate: + if self._flashstate == 1: + self._flashstate = 0 + self._instance.get2dGfxVisual().setVisible(False) + else: + self._flashstate = 1 + self._instance.get2dGfxVisual().setVisible(True) + + self._flashtime = 0 + self._flashnumber -= 1 + + super(Ship, self).update() weapon = property(_getWeapon, _setWeapon) \ No newline at end of file