changeset 241:1a7000c8211c

Demolition foxes, including better fox selection.
author Jeremy Thurgood <firxen@gmail.com>
date Sat, 05 Sep 2009 11:19:26 +0000
parents af19d6fdc1f8
children 23533f3ccd8a
files TODO gamelib/animal.py gamelib/animations.py gamelib/gameboard.py gamelib/misc.py
diffstat 5 files changed, 55 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/TODO	Sat Sep 05 10:37:43 2009 +0000
+++ b/TODO	Sat Sep 05 11:19:26 2009 +0000
@@ -16,8 +16,6 @@
 
 * Animations? (Fox catching chicken (with feathers), demolition foxes blowing things up?)
 
-* Add the demolition fox
-
 * <confluence> We should have text images instead of buttons (in the various menus and toolbars).
 
 * <Nitwit> And we need to start testing for lose conditions, and set an upper time limit
--- a/gamelib/animal.py	Sat Sep 05 10:37:43 2009 +0000
+++ b/gamelib/animal.py	Sat Sep 05 11:19:26 2009 +0000
@@ -10,6 +10,7 @@
 from misc import Position
 import sound
 import equipment
+import animations
 
 class Animal(Sprite):
     """Base class for animals"""
@@ -369,14 +370,14 @@
             # We'll head back towards the holes we make/find
             self.landmarks.append(final_pos)
         elif tiles.TILE_MAP[this_tile] == 'fence' and not self.dig_pos:
-            self._dig(final_pos)
+            self._dig(gameboard, final_pos)
             return self.pos
         self.last_steps.append(final_pos)
         if len(self.last_steps) > 3:
             self.last_steps.pop(0)
         return final_pos
 
-    def _dig(self, dig_pos):
+    def _dig(self, gameboard, dig_pos):
         """Setup dig parameters, to be overridden if needed"""
         self.tick = 5
         self.dig_pos = dig_pos
@@ -422,6 +423,16 @@
 class DemoFox(Fox):
     """Demolition Foxes destroy fences easily"""
 
+    DIG_ANIMATION = animations.FenceExplosion
+    IMAGE_FILE = 'sprites/sapper_fox.png'
+
+    def _dig(self, gameboard, dig_pos):
+        """Setup dig parameters, to be overridden if needed"""
+        self.tick = 0 # Costs us nothing to go through a fence.
+        self.dig_pos = dig_pos
+        gameboard.animations.append(self.DIG_ANIMATION(dig_pos))
+        self._make_hole(gameboard)
+
 class GreedyFox(Fox):
     """Greedy foxes eat more chickens"""
 
--- a/gamelib/animations.py	Sat Sep 05 10:37:43 2009 +0000
+++ b/gamelib/animations.py	Sat Sep 05 11:19:26 2009 +0000
@@ -56,3 +56,14 @@
         else:
             Animation.__init__(self, self.SEQUENCE_LEFT, chicken.pos)
 
+class FenceExplosion(Animation):
+
+    FLASH_LEFT = imagecache.load_image('sprites/muzzle_flash.png')
+    FLASH_RIGHT = imagecache.load_image('sprites/muzzle_flash.png',
+            ("right_facing",))
+
+    SEQUENCE = [FLASH_LEFT, FLASH_RIGHT, FLASH_LEFT, FLASH_RIGHT]
+
+    def __init__(self, fencetile):
+        Animation.__init__(self, self.SEQUENCE, fencetile)
+
--- a/gamelib/gameboard.py	Sat Sep 05 10:37:43 2009 +0000
+++ b/gamelib/gameboard.py	Sat Sep 05 11:19:26 2009 +0000
@@ -14,6 +14,7 @@
 import sound
 import cursors
 import sprite_cursor
+import misc
 
 class OpaqueLabel(gui.Label):
     def __init__(self, value, **params):
@@ -207,6 +208,13 @@
     WOODLAND = tiles.REVERSE_TILE_MAP['woodland']
     BROKEN_FENCE = tiles.REVERSE_TILE_MAP['broken fence']
 
+    FOX_WEIGHTINGS = (
+        (animal.Fox, 60),
+        (animal.GreedyFox, 30),
+        (animal.NinjaFox, 5),
+        (animal.DemoFox, 5),
+        )
+
     def __init__(self, main_app):
         self.disp = main_app
         self.tv = tiles.FarmVid()
@@ -813,6 +821,10 @@
                     self.add_chicken(chick)
             x += 1
 
+    def _choose_fox(self, (x, y)):
+        fox_cls = misc.WeightedSelection(self.FOX_WEIGHTINGS).choose()
+        return fox_cls((x, y))
+
     def spawn_foxes(self):
         """The foxes come at night, and this is where they come from."""
         # Foxes spawn just outside the map
@@ -843,14 +855,7 @@
                     skip = True # Choose a new position
                     break
             if not skip:
-                roll = random.randint(0, 10)
-                if roll < 8:
-                    fox = animal.Fox((x, y))
-                elif roll < 9:
-                    fox = animal.NinjaFox((x, y))
-                else:
-                    fox = animal.GreedyFox((x, y))
-                self.add_fox(fox)
+                self.add_fox(self._choose_fox((x, y)))
 
     def fix_buildings(self):
         """Go through the level map looking for buildings that haven't
--- a/gamelib/misc.py	Sat Sep 05 10:37:43 2009 +0000
+++ b/gamelib/misc.py	Sat Sep 05 11:19:26 2009 +0000
@@ -1,5 +1,7 @@
 # Holder for misc useful classes
 
+import random
+
 class Position(object):
     """2D position / vector"""
 
@@ -29,3 +31,19 @@
 
     def __eq__(self, b):
         return self.x == b.x and self.y == b.y
+
+class WeightedSelection(object):
+    def __init__(self, weightings=None):
+        self.weightings = []
+        self.total = 0
+        if weightings:
+            for item, weight in weightings:
+                self.weightings.append((item, weight))
+                self.total += weight
+        
+    def choose(self):
+        roll = random.uniform(0, self.total)
+        for item, weight in self.weightings:
+            if roll < weight:
+                return item
+            roll -= weight