The enemies are a threat (sort of)
authorNeil <neil@dip.sun.ac.za>
Sat, 5 Mar 2016 22:40:59 +0000 (00:40 +0200)
committerNeil <neil@dip.sun.ac.za>
Sat, 5 Mar 2016 22:41:46 +0000 (00:41 +0200)
koperkapel/gamelib/enemy_roach.py
koperkapel/scenes/level.py

index 2a8438241f3bdc8ac3fa0380a57b28bc1b6e6834..2201c586f389e51193bc9c6851c9f5ea6b2a116e 100644 (file)
@@ -17,11 +17,36 @@ def get_enemy_roach(level):
     roach.level = level
     roach.move = partial(move, roach)
     roach.last_moved = 0
+    roach.last_attacked= 0
     roach.start_pos = None
     each_tick(roach.move)
+    roach.attack = partial(attack, roach)
     return roach
 
 
+def attack(roach, player_pos, player_layer, dt):
+    """Attack the player if close enough"""
+    roach.last_attacked += dt
+    if roach.last_attacked > 0.3:
+        roach.last_attacked = 0
+        if player_layer != 'floor':
+            return None
+        if abs(player_pos[0] - roach.game_pos[0]) > 1:
+            return None
+        if abs(player_pos[1] - roach.game_pos[1]) > 1:
+            return None
+        # Attacking, so turn towards the player
+        if player_pos[0] - roach.game_pos[0] < 0:
+            roach.angle = 270
+        elif player_pos[1] - roach.game_pos[1] < 0:
+            roach.angle = 0
+        elif player_pos[0] - roach.game_pos[0] > 0:
+            roach.angle = 90
+        else:
+            roach.angle = 270
+        # Do 1 damage
+        return 1
+
 def move(roach, dt):
     """Enemy roach move method"""
     roach.last_moved += dt
index 22662a2513017d5fea8c9848cc762f2cfea0fa18..54041baa7cc20e863e0c0457ba8a9cbe70a77b47 100644 (file)
@@ -1,5 +1,6 @@
 """Render a level"""
 
+import random
 from pgzero.constants import keys
 from pygame import Surface
 import pygame.locals as pgl
@@ -128,6 +129,7 @@ class GameLevelScene(BaseLevelScene):
         self._init_generators()
         self._key_rate = 0.2
         self._last_key_down = 0
+        self._last_dmg = 0
         return self._init_roaches(world)
 
     def _init_items(self):
@@ -196,6 +198,21 @@ class GameLevelScene(BaseLevelScene):
         world.roaches.append(build_roach(world))
         self._vehicle_changed()
 
+    @defer_to_update
+    def _damage_player(self, world):
+        if not world.roaches:
+            # Skip out if we're already dead
+            return
+        roach = random.choice(world.roaches)
+        roach.health -= self._last_dmg
+        self._last_dmg = 0
+        if roach.health < 0:
+            index = [x.name for x in world.roaches].index(roach.name)
+            world.roaches.pop(index)
+            # We can't check for empty, because updates will be processed later
+            if len(world.roaches) > 1:
+                self._vehicle_changed()
+
     @defer_to_update
     def _gain_item(self, world, item):
         if item.item_type == "serum":
@@ -282,6 +299,10 @@ class GameLevelScene(BaseLevelScene):
         self._vehicle_changed()
 
     def update(self, world, engine, dt):
+        if not world.roaches:
+            # Catch death here
+            from .menu import MenuScene
+            return [ChangeSceneEvent(MenuScene())]
         super().update(world, engine, dt)
         events = world.pop_events()
         for friend in self._friends:
@@ -290,7 +311,7 @@ class GameLevelScene(BaseLevelScene):
         for item in self._items:
             item.pos = self.calc_offset(
                 item.game_pos[0] * TILE_SIZE, item.game_pos[1] * TILE_SIZE)
-        self._check_enemies()
+        self._check_enemies(dt)
         for enemy in self._enemies:
             enemy.pos = self.calc_offset(
                 enemy.game_pos[0] * TILE_SIZE, enemy.game_pos[1] * TILE_SIZE)
@@ -309,12 +330,18 @@ class GameLevelScene(BaseLevelScene):
     def _update_player_stats(self, world):
         self._stats = PlayerStats(world)
 
-    def _check_enemies(self):
+    def _check_enemies(self, dt):
         if len(self._level.enemies) != len(self._enemies):
             # New nemy has spawned
             for enemy in self._level.enemies:
                 if enemy not in self._enemies:
                     self._enemies.add(enemy)
+        for enemy in self._enemies:
+            dmg = enemy.attack(self._player_pos, self._level_layer, dt)
+            if dmg is not None:
+                self._last_dmg += dmg
+        if self._last_dmg:
+            self._damage_player()
 
     def _check_held_keys(self, dt):
         for key in self._held_keys: