diff options
-rw-r--r-- | brutalmaze/characters.py | 76 | ||||
-rw-r--r-- | brutalmaze/constants.py | 1 | ||||
-rw-r--r-- | brutalmaze/maze.py | 22 |
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 |