1 # Player and Player-like objects
2 from erdslangetjie.data import load_image, load_sound
5 class GameSprite(object):
14 def get_texture(self):
15 return self.sprite.texture
18 class FigureSprite(GameSprite):
20 def can_move(self, direction, level):
21 '''Check if we can move in the given direction'''
22 cand_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
23 return not level.blocked(cand_pos)
26 class ThePlayer(FigureSprite):
29 super(ThePlayer, self).__init__()
30 self.sprite = load_image('sprites/player.png')
32 def move(self, direction, level):
33 if self.can_move(direction, level):
34 self.pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
39 class Nemesis(FigureSprite):
41 def __init__(self, config):
42 super(Nemesis, self).__init__()
43 self.sprite = load_image('sprites/nemesis.png')
46 self._deadends = set([])
48 self._bend = load_sound('sounds/bend.ogg')
50 def move(self, level, player_pos):
51 if not self.on_board():
52 # Advance towards the map a step at a time
53 self.pos = (self.pos[0] + 1, self.pos[1])
55 self.pos = level.enter_pos
58 # First, if we're standing next to a gate, we attack it
59 neighbours = [(self.pos[0] + 1, self.pos[1]),
60 (self.pos[0] - 1, self.pos[1]),
61 (self.pos[0], self.pos[1] + 1),
62 (self.pos[0], self.pos[1] - 1)]
63 for cand in neighbours:
64 if level.is_gate(cand) and level.blocked(cand):
65 level.damage_gate(cand)
66 if self._config.getdefault('bane', 'sound', False):
70 if self._in_dead_end(level):
71 self._deadends.add(self.pos)
72 self._been.setdefault(self.pos, 0)
75 for direction in [(1, 0), (-1, 0), (0, -1), (0, 1)]:
76 new_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
77 if new_pos in self._deadends:
79 if self.can_move(direction, level):
80 # We weigh stuff by the number of times we've stepped there, to
81 # avoid certain types of loop
82 dist = (level.calc_dist(new_pos, player_pos)
83 + self._been.get(new_pos, 0))
88 self._been[self.pos] += 1
93 self._deadends = set([])
97 return self.pos[0] >= 0
99 def _in_dead_end(self, level):
100 # Check if this is a dead end
102 for direction in [(1, 0), (-1, 0), (0, -1), (0, 1)]:
103 new_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1])
104 if level.is_wall(new_pos) or new_pos in self._deadends:
106 # A dead end has only 1 exit, and recurse back from there