summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--README.rst6
-rw-r--r--brutalmaze/characters.py35
-rw-r--r--brutalmaze/constants.py1
-rw-r--r--brutalmaze/main.py2
-rw-r--r--brutalmaze/maze.py34
5 files changed, 61 insertions, 17 deletions
diff --git a/README.rst b/README.rst
index 9b4e9a4..090edff 100644
--- a/README.rst
+++ b/README.rst
@@ -8,7 +8,6 @@ Tango color palette. Its primary goals are:
 * Auto-generated and infinite maze.
 * No binary data.
 * Enemies with randomized attributes: stun, poison, etc.
-* Absorb-able natural elements (fire, ice, water).
 * Resizable in realtime.
 
 Installation
@@ -32,8 +31,5 @@ Left, ``a``
 Right, ``d``
    Move right.
 
-Return
+Return, Left Mouse
    Close-range attack.
-
-``q``
-   Quit.
diff --git a/brutalmaze/characters.py b/brutalmaze/characters.py
index c2d2439..f856c6d 100644
--- a/brutalmaze/characters.py
+++ b/brutalmaze/characters.py
@@ -67,10 +67,14 @@ class Hero:
         self.angle, self.color = pi / 4, TANGO['Aluminium']
         self.R = int((w * h / sin(pi*2/3) / 624) ** 0.5)
 
-        self.wound = 0
+        self.wound = 0.0
         self.speed = FPS // len(self.color)
         self.spin_queue, self.slashing = deque(), False
 
+    def get_color(self):
+        """Return the color of the hero based on the amount of wounds."""
+        return self.color[int(self.wound)]
+
     def slash(self, hold=False):
         """Spin the hero. If the button is hold, delay before continue
         each spin.
@@ -82,10 +86,14 @@ class Hero:
     def draw(self, color=None):
         """Draw the hero."""
         trigon = regpoly(3, self.R, self.angle, self.x, self.y)
-        fill_aapolygon(self.surface, trigon, color or self.color[self.wound])
+        fill_aapolygon(self.surface, trigon, color or self.get_color())
 
     def update(self):
         """Update the hero."""
+        self.wound -= HEALING_SPEED / len(self.color) / self.speed
+        if self.wound < 0: self.wound = 0.0
+        self.speed = int(FPS / (len(self.color)-self.wound))
+
         self.slash(hold=True)
         direction = self.spin_queue.popleft() if self.spin_queue else 0
         self.draw(color=BG_COLOR)
@@ -116,15 +124,19 @@ class Enemy:
         self.offsetx = self.offsety = 0
         self.spin_queue = []
         self.speed = FPS // len(self.color)
-        self.wound = 0
+        self.wound = 0.0
 
-    def draw(self, distance, middlex, middley, color=None):
-        """Draw the enemy, given distance between grids and the middle grid."""
+    def pos(self, distance, middlex, middley):
+        """Return coordinate of the center of the enemy."""
         x, y = pos(self.x, self.y, distance, middlex, middley)
         step = distance // 5
+        return x + self.offsetx*step, y + self.offsety*step
+
+    def draw(self, distance, middlex, middley, color):
+        """Draw the enemy, given distance between grids and the middle grid."""
         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])
+                         *self.pos(distance, middlex, middley))
+        fill_aapolygon(self.surface, square, color)
 
     def place(self, x=0, y=0):
         """Move the enemy by (x, y)."""
@@ -159,9 +171,14 @@ class Enemy:
     def update(self, distance, middlex, middley):
         """Update the enemy."""
         if self.awake:
-            self.draw(distance, middlex, middley, color=BG_COLOR)
+            self.draw(distance, middlex, middley, 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)
+        self.draw(distance, middlex, middley,
+                  self.color[int(self.wound)] if self.awake else FG_COLOR)
+
+    def die(self):
+        """Kill the enemy."""
+        self.maze[self.x][self.y] = EMPTY if self.awake else WALL
diff --git a/brutalmaze/constants.py b/brutalmaze/constants.py
index 95d9c79..37cb741 100644
--- a/brutalmaze/constants.py
+++ b/brutalmaze/constants.py
@@ -29,6 +29,7 @@ SIZE = 400, 400
 MAZE_SIZE = 8
 ROAD_WIDTH = 5
 MIDDLE = (MAZE_SIZE + (MAZE_SIZE&1) - 1)*ROAD_WIDTH + (ROAD_WIDTH >> 1)
+HEALING_SPEED = 1.0     # HP/s
 
 TANGO = {'Butter': ((252, 233, 79), (237, 212, 0), (196, 160, 0)),
          'Orange': ((252, 175, 62), (245, 121, 0), (206, 92, 0)),
diff --git a/brutalmaze/main.py b/brutalmaze/main.py
index 35bc0b2..ff614b1 100644
--- a/brutalmaze/main.py
+++ b/brutalmaze/main.py
@@ -44,8 +44,6 @@ def main():
                 elif event.key == K_RETURN:
                     maze.hero.slashing = True
                     maze.hero.slash()
-                elif event.key == K_q:
-                    going = False
             elif event.type == KEYUP:
                 if event.key in (K_UP, K_w):
                     maze.move(0, -1)
diff --git a/brutalmaze/maze.py b/brutalmaze/maze.py
index 423f6c9..82ced06 100644
--- a/brutalmaze/maze.py
+++ b/brutalmaze/maze.py
@@ -32,6 +32,13 @@ def cosin(x):
     return cos(x) + sin(x)
 
 
+def length(x0, y0, x1, y1):
+    """Return the length of the line segment joining the two points
+    (x0, y0) and (x1, y1).
+    """
+    return ((x0-x1)**2 + (y0-y1)**2)**0.5
+
+
 class Maze:
     """Object representing the maze, including the characters."""
     def __init__(self, size):
@@ -59,7 +66,7 @@ class Maze:
             for _ in range(ROAD_WIDTH): self.map.append(upper.__copy__())
             for _ in range(ROAD_WIDTH): self.map.append(lower.__copy__())
         self.enemies = []
-        while len(self.enemies) < 8:
+        while len(self.enemies) < 20:
             x, y = MIDDLE + randint(-w, w), MIDDLE + randint(-h, h)
             if self.map[x][y] != WALL: continue
             if all(self.map[x + a][y + b] == WALL for a, b in ADJACENT_GRIDS):
@@ -68,6 +75,7 @@ class Maze:
                 Enemy(self.surface, self.map, choice(ENEMIES), x, y))
         self.hero = Hero(self.surface)
         self.map[MIDDLE][MIDDLE] = HERO
+        self.slashd = self.hero.R + self.distance/SQRT2
         self.right = self.down = self.offsetx = self.offsety = 0
         self.draw()
 
@@ -109,6 +117,19 @@ class Maze:
             for d in self.map: d.rotate(y)
         for enemy in self.enemies: enemy.place(x, y)
 
+    def slash(self):
+        """Slash the enemies."""
+        unit, killist = self.distance/SQRT2 * self.hero.speed, []
+        for i, enemy in enumerate(self.enemies):
+            x, y = enemy.pos(self.distance, self.middlex, self.middley)
+            d = length(x, y, self.x, self.y)
+            if d <= self.slashd:
+                enemy.wound += (self.slashd-d) / unit
+                if enemy.wound >= 3:
+                    enemy.die()
+                    killist.append(i)
+        for i in reversed(killist): self.enemies.pop(i)
+
     def update(self):
         """Update the maze."""
         modified = False
@@ -146,7 +167,14 @@ class Maze:
         for enemy in self.enemies:
             enemy.update(self.distance, self.middlex, self.middley)
         self.hero.update()
+        if self.hero.slashing: self.slash()
+        for enemy in self.enemies:
+            x, y = enemy.pos(self.distance, self.middlex, self.middley)
+            d = length(x, y, self.x, self.y)
+            if d <= self.slashd:
+                self.hero.wound += (self.slashd-d) / self.hero.R / enemy.speed
         pygame.display.flip()
+        if self.hero.wound + 1 >= len(self.hero.color): self.lose()
 
     def resize(self, w, h):
         """Resize the maze."""
@@ -172,3 +200,7 @@ class Maze:
         self.right += x
         self.down += y
         self.right, self.down = sign(self.right), sign(self.down)
+
+    def lose(self):
+        """"""
+        pass