1 # Player and Player-like objects
3 from erdslangetjie.data import load_image
6 class GameSprite(object):
15 def get_texture(self):
16 return self.sprite.texture
19 class FigureSprite(GameSprite):
21 def can_move(self, direction, level):
22 '''Check if we can move in the given direction'''
23 cand_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
24 return not level.blocked(cand_pos)
27 class ThePlayer(FigureSprite):
30 super(ThePlayer, self).__init__()
31 self.sprite = load_image('sprites/player.png')
33 def move(self, direction, level):
34 if self.can_move(direction, level):
35 self.pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
40 class Nemesis(FigureSprite):
43 super(Nemesis, self).__init__()
44 self.sprite = load_image('sprites/nemesis.png')
46 self._deadends = set([])
49 def move(self, level, player_pos):
50 if not self.on_board():
51 # Advance towards the map a step at a time
52 self.pos = (self.pos[0] + 1, self.pos[1])
54 self.pos = level.enter_pos
57 # First, if we're standing next to a gate, we attack it
58 neighbours = [(self.pos[0] + 1, self.pos[1]),
59 (self.pos[0] - 1, self.pos[1]),
60 (self.pos[0], self.pos[1] + 1),
61 (self.pos[0], self.pos[1] - 1)]
62 for cand in neighbours:
63 if level.is_gate(cand) and level.blocked(cand):
64 level.damage_gate(cand)
67 if self._in_dead_end(level):
68 self._deadends.add(self.pos)
69 self._been.setdefault(self.pos, 0)
72 for direction in [(1, 0), (-1, 0), (0, -1), (0, 1)]:
73 new_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
74 if new_pos in self._deadends:
76 if self.can_move(direction, level):
77 # We weigh stuff by the number of times we've stepped there, to
78 # avoid certain types of loop
79 dist = (level.calc_dist(new_pos, player_pos)
80 + self._been.get(new_pos, 0))
85 self._been[self.pos] += 1
90 self._deadends = set([])
94 return self.pos[0] >= 0
96 def _in_dead_end(self, level):
97 # Check if this is a dead end
99 for direction in [(1, 0), (-1, 0), (0, -1), (0, 1)]:
100 new_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
101 if level.is_wall(new_pos) or new_pos in self._deadends:
103 # A dead end has only 1 exit, and recurse back from there