Nemesis appears on the map. Refactor code accordingly
[erdslangetjie.git] / erdslangetjie / __main__.py
1 import sys
2 import kivy
3 import pygame
4
5 kivy.require('1.6.0')
6
7 from kivy.app import App
8 from kivy.core.window import Window
9 from kivy.uix.widget import Widget
10 from kivy.uix.floatlayout import FloatLayout
11 from kivy.graphics import Color, Rectangle
12
13 from erdslangetjie.level import LevelList
14 from erdslangetjie.player import ThePlayer, Nemesis
15
16 TILE_SIZE = 24
17
18
19 class GameWindow(FloatLayout):
20
21     def __init__(self, level_list):
22         super(GameWindow, self).__init__(size=(648, 480))
23         self.level_list = level_list
24         self.level_obj = self.level_list.get_current_level()
25         self.level_obj.load_tiles()
26         self.tiles = {}
27
28         self.player = ThePlayer()
29         self.nemesis = Nemesis()
30         if not self.level_obj.enter_pos:
31             raise RuntimeError('No entry point')
32         self.player_tile = None
33         self.nemesis_tile = None
34
35         self.player.pos = self.level_obj.enter_pos
36         self.keyboard = Window.request_keyboard(self._closed, self)
37         self.keyboard.bind(on_key_down=self._on_key_down)
38
39     def build(self):
40         self.clear_widgets()
41         self.tiles = {}
42         tiles = self.level_obj.get_tiles()
43         bx, by = 0, 0
44         for tile_line in tiles:
45             bx = 0
46             for tile in tile_line:
47                 node = Widget(size=(TILE_SIZE, TILE_SIZE), pos=(bx, by))
48                 with node.canvas:
49                     Color(1, 1, 1)
50                     Rectangle(pos=node.pos, size=node.size,
51                             texture=tile.texture)
52                 self.add_widget(node)
53                 self.tiles[(bx, by)] = node
54                 bx += TILE_SIZE
55             by += TILE_SIZE
56
57         self.draw_player()
58         self.draw_nemesis()
59
60     def draw_player(self):
61         if self.player_tile:
62             self.remove_widget(self.player_tile)
63         sprite_pos = (self.player.pos[0] * TILE_SIZE,
64                 self.player.pos[1] * TILE_SIZE)
65         self.player_tile = Widget(size=(TILE_SIZE, TILE_SIZE),
66                 pos=sprite_pos)
67         with self.player_tile.canvas:
68             Color(1, 1, 1)
69             Rectangle(pos=sprite_pos, size=self.player_tile.size,
70                     texture=self.player.get_texture())
71         self.add_widget(self.player_tile)
72
73     def draw_nemesis(self):
74         if not self.nemesis.on_board():
75             return
76         if self.nemesis_tile:
77             self.remove_widget(self.nemesis_tile)
78         sprite_pos = (self.nemesis.pos[0] * TILE_SIZE,
79                 self.nemesis.pos[1] * TILE_SIZE)
80         self.nemesis_tile = Widget(size=(TILE_SIZE, TILE_SIZE),
81                 pos=sprite_pos)
82         with self.nemesis_tile.canvas:
83             Color(1, 1, 1)
84             Rectangle(pos=sprite_pos, size=self.nemesis_tile.size,
85                     texture=self.nemesis.get_texture())
86         self.add_widget(self.nemesis_tile)
87
88     def _closed(self):
89         self.keyboard.unbind(on_key_down=self._on_key_down)
90
91     def _on_key_down(self, keyboard, keycode, text, modifiers):
92         # FIXME - likely portablity issues
93         direction = None
94         if keycode[0] == pygame.K_UP:
95             direction = (0, 1)
96         elif keycode[0] == pygame.K_DOWN:
97             direction = (0, -1)
98         elif keycode[0] == pygame.K_LEFT:
99             direction = (-1, 0)
100         elif keycode[0] == pygame.K_RIGHT:
101             direction = (1, 0)
102         if direction:
103             self.nemesis.move(self.level_obj)
104             self.draw_nemesis()
105             self.player.move(direction, self.level_obj)
106             self.draw_player()
107         self.check_state()
108
109     def check_state(self):
110         if self.level_obj.at_exit(self.player.pos):
111             # Jump to next level
112             self.level_obj = self.level_list.advance_to_next_level()
113             self.nemesis.reset_pos()
114             if self.level_obj:
115                 self.level_obj.load_tiles()
116                 self.player.pos = self.level_obj.enter_pos
117                 self.remove_widget(self.player_tile)
118                 self.build()
119             else:
120                 print 'You won!'
121                 sys.exit(1)
122         elif self.nemesis.pos == self.player.pos:
123             # Caught
124             print 'You lost!'
125             sys.exit(1)
126
127
128 class GameApp(App):
129
130     def __init__(self):
131         self.levels = LevelList()
132         super(GameApp, self).__init__()
133
134     def build(self):
135         game = GameWindow(self.levels)
136         game.build()
137         return game
138
139
140 def main():
141     """ Erdslangetjie, a maze game of eluding nemesis
142     """
143     GameApp().run()