Of course there was a typo.
[naja.git] / naja / scenes / introduction.py
1 """
2 Load and save scenes.
3 """
4
5 import pygame.locals as pgl
6 import pygame
7
8 from naja.constants import KEYS, SCREEN, PALETTE
9 from naja.events import SceneChangeEvent, LoadGameEvent
10 from naja.gamestate import GameState
11 from naja.scenes.scene import Scene
12 from naja.scenes.howto import HowtoScene
13 from naja.widgets.image_box import ImageBox
14 from naja.widgets.selector import SelectorWidget
15 from naja.widgets.text import TextWidget
16 from naja.widgets.text import TextBoxWidget
17 from naja.resources import resources
18 from naja.scenes.dummygame import DummyGameScene
19 from naja.widgets.image_box import PreRenderedImageBox
20
21
22 class IntroductionScene(Scene):
23     def __init__(self, state):
24         super(IntroductionScene, self).__init__(state)
25
26         self.grid_surface = None
27
28         background = ImageBox(
29             (0, 0), "screens/splash.png")
30         self.add(background)
31
32         self.intro = 0
33
34         selector = SelectorWidget()
35         self.add(selector)
36
37         y_offset, y_diff = 270, 40
38         x_offset = 400
39
40         y_offset += y_diff
41         title = TextWidget(
42             (x_offset, y_offset), 'Getting started', colour='white',
43             centre=True)
44         self.add(title)
45
46         y_offset += y_diff
47         howto = TextWidget(
48             (x_offset, y_offset), 'How to play', colour='white', centre=True)
49         howto.add_callback('click', self.howto_scene)
50         selector.add(howto)
51
52         y_offset += y_diff
53         intro = TextWidget(
54             (x_offset, y_offset), 'Introductory Level', colour='white',
55             centre=True)
56         intro.add_callback('click', self.introduction_to_screen_1)
57         selector.add(intro)
58
59         y_offset += 2*y_diff
60         back = TextWidget(
61             (x_offset, y_offset), 'Press ESC to return to the main menu.',
62             colour='white', centre=True)
63         self.add(back)
64
65     def howto_scene(self, event):
66         SceneChangeEvent.post(HowtoScene)
67
68     def introduction_level(self, event):
69         from naja.scenes.game import GameScene
70         LoadGameEvent.post(state=GameState.new(deck='introduction'))
71         SceneChangeEvent.post(GameScene)
72
73     def make_game_surface(self):
74         self.container.widgets = []
75         state = resources.get_json('tutorial/tutorial_screen_1.json')
76         dummy_game = DummyGameScene(state)
77         game_surface = pygame.surface.Surface(SCREEN)
78         dummy_game.render(game_surface)
79         self.add(PreRenderedImageBox((0, 0), game_surface))
80         return game_surface
81
82     def get_grid_surface(self, game_surface):
83         grid_size = 4
84         if self.grid_surface is None:
85             rect = game_surface.get_rect()
86             size = (rect.width, rect.height)
87             self.grid_surface = pygame.surface.Surface(
88                 size, flags=pgl.SRCALPHA)
89             for i in range(0, rect.width, grid_size):
90                 for j in range(0, rect.height, grid_size):
91                     if (i + j) % (grid_size * 2) == 0:
92                         continue
93                     pygame.draw.rect(self.grid_surface, PALETTE.GREY,
94                                      (i, j, grid_size, grid_size))
95         return self.grid_surface
96
97     def grid_out(self, game_surface, rect):
98         orig = game_surface.copy()
99         game_surface.blit(self.get_grid_surface(game_surface), (0, 0))
100         game_surface.blit(orig, rect, rect)
101         pygame.draw.rect(game_surface, PALETTE.GREEN, rect, 8)
102
103     def introduction_to_screen_1(self, event):
104         game_surface = self.make_game_surface()
105         self.intro = 1
106
107         self.add(TextBoxWidget(
108             (24, 72), '\n'.join([
109                 "These are your robot's status bits. On the left we have"
110                 " the Most Significant Bit (MSB, currently set), then the"
111                 " Red (unset), Green (set) and Blue (set) key bits, and"
112                 " finally the four bits which control movement options, of"
113                 " which only left is set. You can only move in directions"
114                 " which are set.",
115                 "Enter to continue.",
116             ]), fontsize=32,
117             colour=PALETTE.GREEN, padding=12, border=8,
118             bg_colour=PALETTE.BLACK, border_colour=PALETTE.GREEN,
119             box_width=400, view_port=(500, 800)))
120
121         self.grid_out(game_surface, (0, 0, 480, 60))
122
123     def introduction_to_screen_2(self, event):
124         game_surface = self.make_game_surface()
125         self.intro = 2
126
127         self.add(TextBoxWidget(
128             (24, 172), '\n'.join([
129                 "These are your health and score. On the left we have four "
130                 "health bits. The robot has taken one damage, so only three "
131                 "are lit. The stars are points you have scored. Once you have "
132                 "all of them you win the game! Total health and required "
133                 "points vary according to the game. \n"
134                 "Enter to continue.",
135             ]), fontsize=32,
136             colour=PALETTE.GREEN, padding=12, border=8,
137             bg_colour=PALETTE.BLACK, border_colour=PALETTE.GREEN,
138             box_width=400, view_port=(500, 800)))
139
140         self.grid_out(game_surface, (0, 540, 480, 60))
141
142     def introduction_to_screen_3(self, event):
143         game_surface = self.make_game_surface()
144         self.intro = 3
145
146         self.add(TextBoxWidget(
147             (24, 132), '\n'.join([
148                 "This text box describes the current game mode. The game is "
149                 "divided into movements and actions, and each mode has "
150                 "different options, shown here.",
151                 "During movement, you can examine the entire board, but you "
152                 "can only move to highlighted tiles (including the one you"
153                 " are on). Actions come next ...",
154                 "Enter to continue.",
155             ]), fontsize=32,
156             colour=PALETTE.GREEN, padding=12, border=8,
157             bg_colour=PALETTE.BLACK, border_colour=PALETTE.GREEN,
158             box_width=400, view_port=(500, 800)))
159
160         self.grid_out(game_surface, (488, 416, 304, 132))
161
162     def introduction_to_screen_4(self, event):
163         game_surface = self.make_game_surface()
164         self.intro = 4
165
166         self.add(TextBoxWidget(
167             (24, 72), '\n'.join([
168                 "This text box shows actions available on the tile. "
169                 "Some actions have requirements and are only selectable if "
170                 "you have the correct bits set (unavailable actions are "
171                 "greyed out). Actions usually change the bits set on "
172                 "your robot. This is often not beneficial.",
173                 "Some actions have additional effects if the MSB is "
174                 "set.",
175                 "Enter to continue.",
176             ]), fontsize=32,
177             colour=PALETTE.GREEN, padding=12, border=8,
178             bg_colour=PALETTE.BLACK, border_colour=PALETTE.GREEN,
179             box_width=400, view_port=(500, 800)))
180
181         self.grid_out(game_surface, (488, 52, 304, 240))
182
183     def handle_scene_event(self, ev):
184         if ev.type == pgl.KEYDOWN and ev.key in KEYS.QUIT:
185             from naja.scenes.menu import MenuScene
186             SceneChangeEvent.post(MenuScene)
187             return
188         if ev.type == pgl.KEYDOWN and ev.key in KEYS.SELECT:
189             if 0 < self.intro < 5:
190                 if self.intro == 1:
191                     self.introduction_to_screen_2(ev)
192                 elif self.intro == 2:
193                     self.introduction_to_screen_3(ev)
194                 elif self.intro == 3:
195                     self.introduction_to_screen_4(ev)
196                 else:
197                     self.introduction_level(ev)
198             return