1 """ In the night, the mould attacks. """
4 import pygame.locals as pgl
8 from .base import BaseScene
9 from ..battery import BatteryManager
10 from ..lights import LightManager
11 from ..infobar import InfoBar, CountDownBar
12 from ..obstacles import ObstacleManager
13 from ..enemies import Boyd
14 from ..events import SceneChangeEvent
15 from ..utils import debug_timer, shadowed_text
16 from ..loader import loader
17 from ..transforms import Overlay
18 from ..turnip import Turnip
19 from ..widgets import ImageButton
20 from ..constants import (
21 NIGHT_LENGTH, NIGHT_LENGTH_HOURS, DEBUG, FONTS, SCREEN_SIZE, FPS)
24 class NightScene(BaseScene):
26 DARKNESS = Overlay(colour=(0, 0, 0, 150))
27 HOURS_PER_TICK = float(NIGHT_LENGTH_HOURS) / NIGHT_LENGTH
29 def enter(self, gamestate):
30 self._space = pymunk.Space()
31 self._obstacles = ObstacleManager(self._space, gamestate)
32 self._lights = LightManager(self._space, gamestate)
33 self._battery = BatteryManager(gamestate)
35 self._infobar = InfoBar("day", battery=self._battery, scene=self)
36 self._countdownbar = CountDownBar("h")
37 self._mould = Boyd(gamestate, self._space)
39 for turnip_data in gamestate.turnips:
40 turnip = Turnip(space=self._space, **turnip_data)
41 self._turnips.append(turnip)
42 self._soil = loader.load_image(
43 "textures", "soil.png", transform=self.DARKNESS)
44 self._tools = self.create_tools(gamestate)
48 self._eaten_tonight = 0
49 self._night_over_text = []
51 def create_tools(self, gamestate):
53 y = SCREEN_SIZE[1] - 40
54 tools.append(ImageButton(
55 '32', 'pause.png', name='pause play',
56 pos=(SCREEN_SIZE[0] - 150, y)))
57 tools.append(ImageButton(
58 '32', 'exit.png', name='exit', pos=(SCREEN_SIZE[0] - 50, y)))
62 def turnip_count(self):
63 return len(self._turnips)
66 def power_usage(self):
67 return int(self._lights.total_power_usage())
69 def remaining_hours(self):
71 (NIGHT_LENGTH - self._total_ticks) * self.HOURS_PER_TICK))
73 @debug_timer("night.render")
74 def render(self, surface, gamestate):
75 surface.blit(self._soil, (0, 0))
77 self._mould.render(surface)
79 for turnip in self._turnips[:]:
81 self._turnips.remove(turnip)
84 self._eaten_tonight += 1
86 turnip.render(surface)
88 self._lights.render_light(surface)
89 self._obstacles.render(surface)
90 self._lights.render_fittings(surface)
91 self._infobar.render(surface, gamestate)
92 self._countdownbar.render(surface, self.remaining_hours())
94 for tool in self._tools:
97 for text, text_pos in self._night_over_text:
98 surface.blit(text, text_pos, None)
100 def event(self, ev, gamestate):
101 if ev.type == pgl.KEYDOWN:
102 if not self._do_ticks:
105 if ev.key in (pgl.K_q, pgl.K_ESCAPE):
106 from .menu import MenuScene
107 SceneChangeEvent.post(scene=MenuScene())
108 elif ev.key == pgl.K_e and DEBUG:
110 elif ev.key == pgl.K_SPACE:
112 elif ev.type == pgl.MOUSEBUTTONDOWN:
113 if not self._do_ticks:
114 # Any mouse press exits
117 self._lights.toggle_nearest(ev.pos, surfpos=True)
120 for tool in self._tools:
122 if tool.name == 'pause play':
124 elif tool.name == 'exit':
125 from .menu import MenuScene
126 SceneChangeEvent.post(scene=MenuScene())
128 def toggle_pause(self):
129 self._paused = not self._paused
130 pause_img = "play.png" if self._paused else "pause.png"
131 for tool in self._tools:
132 if tool.name == 'pause play':
133 tool.update_image("32", pause_img)
137 from .day import DayScene
138 SceneChangeEvent.post(scene=DayScene())
140 def _end_night(self):
141 self._do_ticks = False
142 self._night_over_text = []
143 overlay = pygame.surface.Surface(
144 (SCREEN_SIZE[0], 240), pgl.SWSURFACE).convert_alpha()
145 overlay.fill((0, 0, 0, 172))
146 self._night_over_text.append((overlay, (0, 40)))
147 self._night_over_text.append(
148 (shadowed_text("The Night is Over", FONTS["bold"], 48), (300, 50)))
149 self._night_over_text.append(
150 (shadowed_text("Turnips eaten tonight: %d" % self._eaten_tonight,
151 FONTS["sans"], 32), (300, 130)))
152 self._night_over_text.append(
153 (shadowed_text("Surviving turnips: %d" % len(self._turnips),
154 FONTS["sans"], 32), (300, 170)))
155 self._night_over_text.append(
156 (shadowed_text("Press any key to continue", FONTS["sans"], 24),
159 def check_battery(self):
160 if self._battery.current == 0:
161 self._lights.battery_dead()
163 @debug_timer("night.tick")
164 def tick(self, gamestate):
165 if self._do_ticks and not self._paused:
166 if self._total_ticks < NIGHT_LENGTH:
167 self._mould.tick(gamestate, self._space, self._lights)
169 if self._total_ticks % FPS == 0:
170 self._battery.current -= int(
171 self._lights.total_power_usage())
173 self._total_ticks += 1
176 if not self._mould.alive():
179 def exit(self, gamestate):
180 turnip_data = [turnip.serialize() for turnip in self._turnips]
181 gamestate.turnips = turnip_data
182 # TODO: Move this into the end_night function
184 self._mould.update_resistances(gamestate)