changeset 69:18db99fda6bd

Move spawing code from engine to gameboard - seems more natural.
author Neil Muller <drnlmuller@gmail.com>
date Mon, 31 Aug 2009 22:14:12 +0000
parents 6b8ac424da83
children d92a2f973cc4
files gamelib/engine.py gamelib/gameboard.py gamelib/misc.py
diffstat 3 files changed, 117 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/engine.py	Mon Aug 31 21:41:34 2009 +0000
+++ b/gamelib/engine.py	Mon Aug 31 22:14:12 2009 +0000
@@ -4,10 +4,7 @@
 import pygame
 from pygame.locals import USEREVENT, QUIT, KEYDOWN, K_ESCAPE, K_n, K_d, K_s
 
-from tiles import TILE_MAP
 import gameboard
-import animal
-import random
 
 class Engine(Game):
     def __init__(self, main_menu_app):
@@ -51,44 +48,8 @@
 
         # disable timer
         pygame.time.set_timer(MOVE_FOX_ID, 0)
-        # Very simple, we walk around the tilemap, and, for each farm tile,
-        # we randomly add a chicken (1 in 10 chance) until we have 5 chickens
-        # or we run out of board
         self.game.gameboard.clear_foxes()
-        chickens = len(self.game.gameboard.chickens)
-        x, y = 0, 0
-        width, height = self.game.gameboard.tv.size
-        while chickens < 5:
-            if x < width:
-                tile = self.game.gameboard.tv.get((x, y))
-            else:
-                y += 1
-                if y >= height:
-                    break
-                x = 0
-                continue
-            # See if we place a chicken
-            if 'grassland' == TILE_MAP[tile]:
-                # Farmland
-                roll = random.randint(1, 20)
-                # We don't place within a tile of the fence, this is to make things
-                # easier
-                for xx in range(x-1, x+2):
-                    if xx >= height or xx < 0:
-                        continue
-                    for yy in range(y-1, y+2):
-                        if yy >= height or yy < 0:
-                            continue
-                        neighbour = self.game.gameboard.tv.get((xx, yy))
-                        if 'fence' == TILE_MAP[neighbour]:
-                            # Fence
-                            roll = 10
-                if roll == 1:
-                    # Create a chicken
-                    chickens += 1
-                    chick = animal.Chicken((x, y))
-                    self.game.gameboard.add_chicken(chick)
-            x += 1
+        self.game.gameboard.update_chickens()
 
     def event(self, e):
         if events_equal(e, START_NIGHT):
@@ -120,32 +81,8 @@
 
         # Add a timer to the event queue
         self.cycle_count = 0
-        pygame.time.set_timer(MOVE_FOX_ID, 300)
-        # Very simple, we walk around the tilemap, and, for each farm tile,
-        # we randomly add a chicken (1 in 10 chance) until we have 5 chickens
-        # or we run out of board
-        foxes = len(self.game.gameboard.foxes)
-        x, y = 0, 0
-        width, height = self.game.gameboard.tv.size
-        while foxes < 5:
-            if x < width:
-                tile = self.game.gameboard.tv.get((x, y))
-            else:
-                y += 1
-                if y >= height:
-                    break
-                x = 0
-                continue
-            # See if we place a fox
-            if TILE_MAP[tile] == 'woodland':
-                # Forest
-                roll = random.randint(1, 20)
-                if roll == 1:
-                    # Create a fox
-                    foxes += 1
-                    fox = animal.Fox((x, y))
-                    self.game.gameboard.add_fox(fox)
-            x += 5
+        pygame.time.set_timer(MOVE_FOX_ID, 200)
+        self.game.gameboard.spawn_foxes()
 
     def event(self, e):
         if events_equal(e, START_DAY):
@@ -156,7 +93,7 @@
             return MainMenuState(self.game)
         elif e.type is MOVE_FOX_ID:
             self.cycle_count += 1
-            if self.cycle_count > 15:
+            if self.cycle_count > 50:
                 return pygame.event.post(START_DAY)
             return self.game.gameboard.move_foxes()
         elif e.type is not QUIT:
--- a/gamelib/gameboard.py	Mon Aug 31 21:41:34 2009 +0000
+++ b/gamelib/gameboard.py	Mon Aug 31 22:14:12 2009 +0000
@@ -1,3 +1,5 @@
+import random
+
 import pygame
 from pygame.locals import MOUSEBUTTONDOWN, KEYDOWN, K_UP, K_DOWN, K_LEFT, K_RIGHT
 from pgu import gui
@@ -6,7 +8,8 @@
 import tiles
 import constants
 import buildings
-
+import animal
+from misc import Position
 
 class OpaqueLabel(gui.Label):
     def paint(self, s):
@@ -89,6 +92,7 @@
 
     GRASSLAND = tiles.REVERSE_TILE_MAP['grassland']
     FENCE = tiles.REVERSE_TILE_MAP['fence']
+    BROKEN_FENCE = tiles.REVERSE_TILE_MAP['broken fence']
 
     def __init__(self):
         self.tv = tiles.FarmVid()
@@ -130,6 +134,15 @@
     def set_selected_tool(self, tool):
         self.selected_tool = tool
 
+    def in_bounds(self, pos):
+        """Check if a position is within the game boundaries"""
+        if pos.x < 0 or pos.y < 0:
+            return False
+        width, height = self.tv.size
+        if pos.x >= width or pos.y >= height:
+            return False
+        return True
+
     def use_tool(self, e):
         if self.selected_tool == constants.TOOL_SELL_CHICKEN:
             self.sell_chicken(e.pos)
@@ -159,7 +172,8 @@
         self.remove_chicken(chick)
 
     def buy_fence(self, tile_pos):
-        if self.tv.get(tile_pos) != self.GRASSLAND:
+        this_tile = self.tv.get(tile_pos)
+        if this_tile not in [self.GRASSLAND, self.BROKEN_FENCE]:
             return
         if self.cash < constants.BUY_PRICE_FENCE:
             print "You can't afford a fence."
@@ -244,6 +258,72 @@
         self.cash += amount
         self.toolbar.update_cash_counter(self.cash)
 
+    def update_chickens(self):
+        """Update the chickens state at the start of the new day"""
+        # Currently random chickens appear
+        # Very simple, we walk around the tilemap, and, for each farm tile,
+        # we randomly add a chicken (1 in 10 chance) until we have 5 chickens
+        # or we run out of board
+        x, y = 0, 0
+        width, height = self.tv.size
+        while len(self.chickens) < 5:
+            if x < width:
+                tile = self.tv.get((x, y))
+            else:
+                y += 1
+                if y >= height:
+                    break
+                x = 0
+                continue
+            # See if we place a chicken
+            if 'grassland' == tiles.TILE_MAP[tile]:
+                # Farmland
+                roll = random.randint(1, 20)
+                # We don't place within a tile of the fence, this is to make things
+                # easier
+                for xx in range(x-1, x+2):
+                    if xx >= width or xx < 0:
+                        continue
+                    for yy in range(y-1, y+2):
+                        if yy >= height or yy < 0:
+                            continue
+                        neighbour = self.tv.get((xx, yy))
+                        if 'fence' == tiles.TILE_MAP[neighbour]:
+                            # Fence
+                            roll = 10
+                if roll == 1:
+                    # Create a chicken
+                    chick = animal.Chicken((x, y))
+                    self.add_chicken(chick)
+            x += 1
+
+    def spawn_foxes(self):
+        """The foxes come at night, and this is where they come from."""
+        # Very simple, we walk around the tilemap, and, for each farm tile,
+        # we randomly add a chicken (1 in 10 chance) until we have 5 chickens
+        # or we run out of board
+        x, y = 0, 0
+        width, height = self.tv.size
+        new_foxes = random.randint(3, 7)
+        while len(self.foxes) < new_foxes:
+            if x < width:
+                tile = self.tv.get((x, y))
+            else:
+                y += 1
+                if y >= height:
+                    break
+                x = 0
+                continue
+            # See if we place a fox
+            if tiles.TILE_MAP[tile] == 'woodland':
+                # Forest
+                roll = random.randint(1, 20)
+                if roll == 1:
+                    # Create a fox
+                    fox = animal.Fox((x, y))
+                    self.add_fox(fox)
+            x += 5
+
     def fix_buildings(self):
         """Go through the level map looking for buildings that haven't
            been added to self.buildings and adding them.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/misc.py	Mon Aug 31 22:14:12 2009 +0000
@@ -0,0 +1,31 @@
+# Holder for misc useful classes
+
+class Position(object):
+   """2D position / vector"""
+
+   def __init__(self, x, y):
+       self.x = x
+       self.y = y
+
+   def to_tuple(self):
+       return self.x, self.y
+
+   def dist(self, b):
+       """Gives the distance to another position"""
+
+       return abs(self.x - b.x) + abs(self.y - b.y)
+
+   def __sub__(self, b):
+       return Position(self.x - b.x, self.y - b.y)
+
+   def __add__(self, b):
+       return Position(self.x + b.x, self.y + b.y)
+
+   def left_of(self, b):
+       return self.x < b.x
+
+   def right_of(self, b):
+       return self.x > b.x
+
+   def __eq__(self, b):
+       return self.x == b.x and self.y == b.y