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
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 NIGHT_LENGTH, DEBUG, FONTS, SCREEN_SIZE
23 class NightScene(BaseScene):
25 DARKNESS = Overlay(colour=(0, 0, 0, 150))
27 def enter(self, gamestate):
28 self._space = pymunk.Space()
29 self._obstacles = ObstacleManager(self._space, gamestate)
30 self._lights = LightManager(self._space, gamestate)
31 self._battery = BatteryManager(gamestate)
32 self._infobar = InfoBar("day", battery=self._battery, scene=self)
33 self._mould = Boyd(gamestate, self._space)
35 for turnip_data in gamestate.turnips:
36 turnip = Turnip(space=self._space, **turnip_data)
37 self._turnips.append(turnip)
38 self._soil = loader.load_image(
39 "textures", "soil.png", transform=self.DARKNESS)
40 self._tools = self.create_tools(gamestate)
44 self._eaten_tonight = 0
45 self._night_over_text = []
47 def create_tools(self, gamestate):
49 y = SCREEN_SIZE[1] - 40
50 tools.append(ImageButton(
51 '32', 'pause.png', name='pause play',
52 pos=(SCREEN_SIZE[0] - 150, y)))
53 tools.append(ImageButton(
54 '32', 'exit.png', name='exit', pos=(SCREEN_SIZE[0] - 50, y)))
58 def turnip_count(self):
59 return len(self._turnips)
62 def power_usage(self):
63 return int(self._lights.total_power_usage())
65 @debug_timer("night.render")
66 def render(self, surface, gamestate):
67 surface.blit(self._soil, (0, 0))
69 self._mould.render(surface)
71 for turnip in self._turnips[:]:
73 self._turnips.remove(turnip)
76 self._eaten_tonight += 1
78 turnip.render(surface)
80 self._lights.render_light(surface)
81 self._obstacles.render(surface)
82 self._lights.render_fittings(surface)
83 self._infobar.render(surface, gamestate)
85 for tool in self._tools:
88 for text, text_pos in self._night_over_text:
89 surface.blit(text, text_pos, None)
91 def event(self, ev, gamestate):
92 if ev.type == pgl.KEYDOWN:
93 if not self._do_ticks:
96 if ev.key in (pgl.K_q, pgl.K_ESCAPE):
97 from .menu import MenuScene
98 SceneChangeEvent.post(scene=MenuScene())
99 elif ev.key == pgl.K_e and DEBUG:
101 elif ev.key == pgl.K_SPACE:
103 elif ev.type == pgl.MOUSEBUTTONDOWN:
104 if not self._do_ticks:
105 # Any mouse press exits
108 self._lights.toggle_nearest(ev.pos, surfpos=True)
111 for tool in self._tools:
113 if tool.name == 'pause play':
115 elif tool.name == 'exit':
116 from .menu import MenuScene
117 SceneChangeEvent.post(scene=MenuScene())
119 def toggle_pause(self):
120 self._paused = not self._paused
121 pause_img = "play.png" if self._paused else "pause.png"
122 for tool in self._tools:
123 if tool.name == 'pause play':
124 tool.update_image("32", pause_img)
128 from .day import DayScene
129 SceneChangeEvent.post(scene=DayScene())
131 def _end_night(self):
132 self._do_ticks = False
133 self._night_over_text = []
134 overlay = pygame.surface.Surface(
135 (SCREEN_SIZE[0], 240), pgl.SWSURFACE).convert_alpha()
136 overlay.fill((0, 0, 0, 172))
137 self._night_over_text.append((overlay, (0, 40)))
138 self._night_over_text.append(
139 (shadowed_text("The Night is Over", FONTS["bold"], 48), (300, 50)))
140 self._night_over_text.append(
141 (shadowed_text("Turnips eaten tonight: %d" % self._eaten_tonight,
142 FONTS["sans"], 32), (300, 130)))
143 self._night_over_text.append(
144 (shadowed_text("Surviving turnips: %d" % len(self._turnips),
145 FONTS["sans"], 32), (300, 170)))
146 self._night_over_text.append(
147 (shadowed_text("Press any key to continue", FONTS["sans"], 24),
150 @debug_timer("night.tick")
151 def tick(self, gamestate):
152 if self._do_ticks and not self._paused:
153 if self._total_ticks < NIGHT_LENGTH:
154 self._mould.tick(gamestate, self._space, self._lights)
156 if self._total_ticks % 60 == 0:
157 self._battery.current -= int(
158 self._lights.total_power_usage())
159 self._total_ticks += 1
162 if not self._mould.alive():
165 def exit(self, gamestate):
166 turnip_data = [turnip.serialize() for turnip in self._turnips]
167 gamestate.turnips = turnip_data
168 # TODO: Move this into the end_night function
170 self._mould.update_resistances(gamestate)