about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--brutalmaze/characters.py76
-rw-r--r--brutalmaze/constants.py1
-rw-r--r--brutalmaze/maze.py22
3 files changed, 60 insertions, 39 deletions
diff --git a/brutalmaze/characters.py b/brutalmaze/characters.py
index 47b910d..bb3dd22 100644
--- a/brutalmaze/characters.py
+++ b/brutalmaze/characters.py
@@ -19,6 +19,7 @@
 
 from collections import deque
 from math import atan2, cos, sin, pi
+from random import shuffle
 
 import pygame
 from pygame.gfxdraw import filled_polygon, aapolygon
@@ -31,7 +32,7 @@ def randsign():
     return (pygame.time.get_ticks() & 1)*2 - 1
 
 
-def regpoly(n, R, x, y, r):
+def regpoly(n, R, r, x, y):
     """Return the pointlist of the regular polygon with n sides,
     circumradius of R, the center point I(x, y) and one point A make the
     vector IA with angle r (in radians).
@@ -52,6 +53,11 @@ def pos(x, y, distance, middlex, middley):
     return middlex + (x - MIDDLE)*distance, middley + (y - MIDDLE)*distance
 
 
+def sign(n):
+    """Return the sign of number n."""
+    return -1 if n < 0 else 1 if n else 0
+
+
 class Hero:
     """Object representing the hero."""
     def __init__(self, surface):
@@ -75,7 +81,7 @@ class Hero:
 
     def draw(self, color=None):
         """Draw the hero."""
-        trigon = regpoly(3, self.R, self.x, self.y, self.angle)
+        trigon = regpoly(3, self.R, self.angle, self.x, self.y)
         fill_aapolygon(self.surface, trigon, color or self.color[self.wound])
 
     def update(self):
@@ -100,38 +106,58 @@ class Hero:
 
 class Enemy:
     """Object representing an enemy."""
-    def __init__(self, surface, n, x, y):
-        self.surface = surface
-        self.x, self.y = x, y
+    def __init__(self, surface, maze, n, x, y):
+        self.surface, self.maze = surface, maze
         self.angle, self.color = pi / 4, TANGO[TANGO_KEYS[n]]
+        self.x, self.y = x, y
 
-        self.awake, self.moving = False, False
-        self.wound = 0
+        self.awake = False
+        self.offsetx = self.offsety = 0
+        self.spin_queue = []
         self.speed = FPS // len(self.color)
-        self.spin_queue, self.slashing = deque(), False
+        self.wound = 0
 
     def draw(self, distance, middlex, middley, color=None):
-        """Draw the enemy, given distance between grids and the middle
-        grid.
-        """
+        """Draw the enemy, given distance between grids and the middle grid."""
         x, y = pos(self.x, self.y, distance, middlex, middley)
-        square = regpoly(4, int(distance / SQRT2), x, y, self.angle)
+        step = distance // 5
+        square = regpoly(4, int(distance / SQRT2), self.angle,
+                         x + self.offsetx*step, y + self.offsety*step)
         fill_aapolygon(self.surface, square, color or self.color[self.wound])
 
-    def update(self, distance, middlex, middley):
-        """Update the enemy."""
-        if (self.angle - pi/4) < EPSILON: self.angle = pi / 4
-        self.draw(distance, middlex, middley, color=BG_COLOR)
-        if self.awake and not self.spin_queue:
-            self.spin_queue.extend([randsign()] * self.speed)
-        if self.spin_queue and not self.moving:
-            self.angle += self.spin_queue.popleft() * pi / 2 / self.speed
-        self.draw(distance, middlex, middley)
-
-    def place(self, x, y):
+    def place(self, x=0, y=0):
         """Move the enemy by (x, y)."""
         self.x += x
         self.y += y
 
-    def move(self, x, y):
-        """Command the enemy to move by (x, y)."""
+    def move(self):
+        """Handle the movement of the enemy.
+
+        Return True if it moved, False otherwise.
+        """
+        if self.offsetx:
+            self.offsetx -= sign(self.offsetx)
+            return True
+        if self.offsety:
+            self.offsety -= sign(self.offsety)
+            return True
+
+        directions = [(sign(MIDDLE - self.x), 0), (0, sign(MIDDLE - self.y))]
+        shuffle(directions)
+        for x, y in directions:
+            if (x or y) and self.maze[self.x + x][self.y + y] == False:
+                self.offsetx = x * -4
+                self.offsety = y * -4
+                self.place(x, y)
+                return True
+        return False
+
+    def update(self, distance, middlex, middley):
+        """Update the enemy."""
+        if self.awake:
+            self.draw(distance, middlex, middley, color=BG_COLOR)
+            if not self.spin_queue and not self.move():
+                self.spin_queue.extend([randsign()] * self.speed)
+            if self.spin_queue:
+                self.angle += self.spin_queue.pop() * pi / 2 / self.speed
+        self.draw(distance, middlex, middley)
diff --git a/brutalmaze/constants.py b/brutalmaze/constants.py
index 2e476be..bcfb070 100644
--- a/brutalmaze/constants.py
+++ b/brutalmaze/constants.py
@@ -20,7 +20,6 @@
 from pygame.locals import *
 from pygame.math import Vector2
 
-EPSILON = 8 ** -8
 SQRT2 = 2 ** 0.5
 
 FPS = 30
diff --git a/brutalmaze/maze.py b/brutalmaze/maze.py
index 4ac57cb..42be98a 100644
--- a/brutalmaze/maze.py
+++ b/brutalmaze/maze.py
@@ -23,15 +23,10 @@ from random import getrandbits
 
 import pygame
 
-from .characters import pos, regpoly, fill_aapolygon, Hero, Enemy
+from .characters import pos, sign, regpoly, fill_aapolygon, Hero, Enemy
 from .constants import *
 
 
-def sign(n):
-    """Return the sign of number n."""
-    return -1 if n < 0 else 1 if n else 0
-
-
 def cosin(x):
     """Return the sum of cosine and sine of x (measured in radians)."""
     return cos(x) + sin(x)
@@ -49,10 +44,6 @@ class Maze:
         self.rangex = range(MIDDLE - w, MIDDLE + w + 1)
         self.rangey = range(MIDDLE - h, MIDDLE + h + 1)
 
-        self.hero = Hero(self.surface)
-        self.enemies = [Enemy(self.surface, 4, 34, 34)]
-        self.right = self.down = self.offsetx = self.offsety = 0
-
         def wall(bit, upper=True):
             if bit: return deque([True]*ROAD_WIDTH + [False]*ROAD_WIDTH)
             if upper: return deque([True] * (ROAD_WIDTH<<1))
@@ -67,6 +58,9 @@ class Maze:
                 lower.extend(wall(b, False))
             for _ in range(ROAD_WIDTH): self.map.append(upper.__copy__())
             for _ in range(ROAD_WIDTH): self.map.append(lower.__copy__())
+        self.hero = Hero(self.surface)
+        self.enemies = [Enemy(self.surface, self.map, 4, 34, 34)]
+        self.right = self.down = self.offsetx = self.offsety = 0
         self.draw()
 
     def draw(self):
@@ -76,7 +70,7 @@ class Maze:
             for j in self.rangey:
                 if not self.map[i][j]: continue
                 x, y = pos(i, j, self.distance, self.middlex, self.middley)
-                square = regpoly(4, int(self.distance / SQRT2), x, y, pi / 4)
+                square = regpoly(4, int(self.distance / SQRT2), pi / 4, x, y)
                 fill_aapolygon(self.surface, square, FG_COLOR)
 
     def wake(self, enemy):
@@ -120,16 +114,18 @@ class Maze:
             modified = True
 
         if modified:
+            self.map[MIDDLE][MIDDLE] = False
             if abs(self.offsetx) == 5:
                 s = sign(self.offsetx)
                 self.offsetx = 0
                 self.map.rotate(s)
-                for enemy in self.enemies: enemy.place(s, 0)
+                for enemy in self.enemies: enemy.place(x=s)
             if abs(self.offsety) == 5:
                 s = sign(self.offsety)
                 self.offsety = 0
                 for d in self.map: d.rotate(s)
-                for enemy in self.enemies: enemy.place(0, s)
+                for enemy in self.enemies: enemy.place(y=s)
+            self.map[MIDDLE][MIDDLE] = None
 
             self.middlex = self.x + self.offsetx*self.step
             self.middley = self.y + self.offsety*self.step