Merge branch 'master' of ctpug.org.za:koperkapel
authorSimon Cross <hodgestar@gmail.com>
Sat, 5 Mar 2016 22:56:13 +0000 (00:56 +0200)
committerSimon Cross <hodgestar@gmail.com>
Sat, 5 Mar 2016 22:56:13 +0000 (00:56 +0200)
12 files changed:
koperkapel/gamelib/enemy_roach.py
koperkapel/gamelib/keypad.py
koperkapel/gamelib/level.py
koperkapel/levels/level1.json
koperkapel/loaders/levelloader.py
koperkapel/scenes/level.py
koperkapel/sounds/fire_spit.ogg [deleted file]
koperkapel/sounds/fire_spit.wav [new file with mode: 0644]
koperkapel/sounds/gun_fire.ogg [deleted file]
koperkapel/sounds/gun_fire.wav [new file with mode: 0644]
koperkapel/sounds/screech.wav [new file with mode: 0644]
sources/source.txt

index 2a8438241f3bdc8ac3fa0380a57b28bc1b6e6834..83523b6d4fdd5caeb0c7dce1dd47ff91bbc00668 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.6:
+        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 b328f3965e54b3af1ed0b4997ae5bd739c246f3a..bf9e084e0d23319d841a27088656f72b34ff4cb9 100644 (file)
@@ -8,16 +8,19 @@ from ..constants import TILE_SIZE
 
 class Keypad(SurfActor):
 
-    def __init__(self, x, y, doors):
+    def __init__(self, x, y, doors, required_smart=0):
         self._doors = doors
         self.game_pos = (x, y)
+        self.required_smart = required_smart
         surf = images.load(os.path.join('fixtures', 'keypad'))
         super().__init__(surf, anchor=(0, 0))
 
-    def activate(self, roaches):
-        # FIXME: Check stats
-        for door in self._doors:
-            if door.is_closed():
-                door.open()
-            else:
-                door.close()
+    def activate(self, smart):
+        if smart >= self.required_smart:
+            for door in self._doors:
+                if door.is_closed():
+                    door.open()
+                else:
+                    door.close()
+        else:
+            print("You are not smart enough for this keypad.")
index cfbf45e1118c824f63cddac3294a09c9283419f0..7641fbcd3de7b29ded0b1ad631c43eab74b16470 100644 (file)
@@ -65,10 +65,10 @@ class Level(object):
             return True
         return False
 
-    def press_keypad(self, x, y, roaches):
+    def press_keypad(self, x, y, smart):
         for keypad in self.keypads:
             if (x, y) == keypad.game_pos:
-                keypad.activate(roaches)
+                keypad.activate(smart)
 
     def get_friends(self):
         return self._friends[:]
index f5e920af4e66575109a43159359697375cb91ad6..7fad44fe3271e528f7a44536206b3fd9c0561e1c 100644 (file)
          "keypads": [
             [
                6,
-               7
+               7,
+               0
             ]
          ],
          "doors": [
          "keypads": [
             [
                5,
-               12
+               12,
+               0
             ]
          ],
          "doors": [
          "keypads": [
             [
                18,
-               9
+               9,
+               1
             ]
          ],
          "doors": [
index 14db3bee5419de099d785e50d87fbbc7db72783c..9c3b6cfc19fc57c31af97b1c4337bb016131d7f8 100644 (file)
@@ -65,7 +65,7 @@ class LevelLoader(ResourceLoader):
                 doors.append(new_door)
             # Add the keypads
             for keypad in door_info['keypads']:
-                new_keypad = Keypad(keypad[0], keypad[1], doors)
+                new_keypad = Keypad(keypad[0], keypad[1], doors, keypad[2])
                 self._level.keypads.append(new_keypad)
         for pos in level_data['friendly roaches']:
             roach = get_friendly_roach(pos[0], pos[1])
index e5de740eac91189febeffd4503ec29193cc3162c..379b8bf705e79ea32127a5681155a0ec28de585e 100644 (file)
@@ -1,6 +1,8 @@
 """Render a level"""
 
+import random
 from pgzero.constants import keys
+from pgzero.loaders import sounds
 from pygame import Surface
 import pygame.locals as pgl
 from ..loaders.levelloader import levels
@@ -139,6 +141,8 @@ class GameLevelScene(BaseLevelScene):
         self._init_generators()
         self._key_rate = 0.2
         self._last_key_down = 0
+        self._last_dmg = 0
+        self._screech = sounds.load("screech")
         return self._init_roaches(world)
 
     def _init_items(self):
@@ -207,6 +211,22 @@ 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._screech.play()
+        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":
@@ -293,6 +313,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:
@@ -301,7 +325,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)
@@ -321,12 +345,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:
@@ -371,7 +401,7 @@ class GameLevelScene(BaseLevelScene):
                 self._level_layer = 'floor'
                 self._mode = 'walk'
         elif self._level.is_keypad(x, y):
-            self._level.press_keypad(x, y, self._roaches)
+            self._level.press_keypad(x, y, self._stats.smart)
         elif self._level.friend_at(x, y):
             friend = self._level.friend_at(x, y)
             self._level.remove_friend(friend)
diff --git a/koperkapel/sounds/fire_spit.ogg b/koperkapel/sounds/fire_spit.ogg
deleted file mode 100644 (file)
index a0b15d4..0000000
Binary files a/koperkapel/sounds/fire_spit.ogg and /dev/null differ
diff --git a/koperkapel/sounds/fire_spit.wav b/koperkapel/sounds/fire_spit.wav
new file mode 100644 (file)
index 0000000..ebd99b1
Binary files /dev/null and b/koperkapel/sounds/fire_spit.wav differ
diff --git a/koperkapel/sounds/gun_fire.ogg b/koperkapel/sounds/gun_fire.ogg
deleted file mode 100644 (file)
index 0a18abf..0000000
Binary files a/koperkapel/sounds/gun_fire.ogg and /dev/null differ
diff --git a/koperkapel/sounds/gun_fire.wav b/koperkapel/sounds/gun_fire.wav
new file mode 100644 (file)
index 0000000..aa032a7
Binary files /dev/null and b/koperkapel/sounds/gun_fire.wav differ
diff --git a/koperkapel/sounds/screech.wav b/koperkapel/sounds/screech.wav
new file mode 100644 (file)
index 0000000..6f61e14
Binary files /dev/null and b/koperkapel/sounds/screech.wav differ
index 2eda8489d31e4fbc7698e90f7a9caf4766cd4e9b..40d749310f11914a284ef458c374f3c75b6249c9 100644 (file)
@@ -20,7 +20,7 @@ https://commons.wikimedia.org/wiki/File:Indumil-Cordova.jpg
 Crowbar:
 https://commons.wikimedia.org/wiki/File:Standard_Crowbar_Black.jpg
 
-fire_spit.ogg
+fire_spit.wav
 Created from ./Berklee44v10/pencil_scrape_1.wav from the One Laptop per Child project.
 URL: http://www.archive.org/download/Berklee44v10/Berklee44v10.zip
 Source: http://www.archive.org/details/Berklee44v10
@@ -28,10 +28,9 @@ License: http://creativecommons.org/licenses/by/3.0/
 Credit: Sound samples from Berklee recorded for Richard Boulanger for use in the One Laptop per Child music library. See http://wiki.laptop.org/go/Sound_samples for details.
 Transformed by Neil Muller, using:
 head -c 6000 pencil_scrape_1.wav > test.wav
-oggenc test.wav
 Transformation licensed: http://creativecommons.org/licenses/by/3.0/
 
-gun_fire.ogg
+gun_fire.wav
 Created from ./Berklee44Barkovich/gunshot1.wav from the One Laptop per Child project.
 URL: http://www.archive.org/download/Berklee44Barkovich/Berklee44Barkovich.zip
 Sources: http://www.archive.org/details/Berklee44Barkovich
@@ -39,5 +38,14 @@ License: http://creativecommons.org/licenses/by/3.0/
 Credit: Sound samples from Berklee recorded for Richard Boulanger for use in the One Laptop per Child music library. See http://wiki.laptop.org/go/Sound_samples for details.
 Transformed by Neil Muller, using:
 sox gunshot1.wav test.wav vol 0.25 fade 0 0.9 0.15
-oggenc test.wav
 Transformation licensed: http://creativecommons.org/licenses/by/3.0/
+
+screech.wav
+Created from ./BoulangerTamTamReplacements44/birdscreech1.wav
+URL: http://www.archive.org/download/BoulangerTamTamReplacements/BoulangerTamTamReplacements44.zip
+Source: http://www.archive.org/details/BoulangerTamTamReplacements
+License: http://creativecommons.org/licenses/by/3.0/
+Credit: Sound samples by Boulanger TamTam Replacements recorded for Richard Boulanger for use in the One Laptop per Child music library. See http://wiki.laptop.org/go/Sound_samples for details.
+Transformed by Neil Muller, using:
+sox birdscreech1.wav screech.wav vol 0.5 fade 0 0.4 0.15
+