class Decoration(GameObject): """ An entity that does nothing other than act as a background decoration. """ def __init__(self, x, y, image, screen): """ :param x: Integer, the x-position of the wall. :param y: Integer, the y-position of the wall. :param image: pygame.Surface, the image of the wall. :param screen: pygame.Surface, the screen to draw the wall onto. """ self.screen = screen self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.rect = pg.Rect(x, y, 0, 0) def __str__(self): return "decoration" def update(self): self.render.update() def draw(self, camera=None): self.render.draw(camera)
class Spike(GameObject): """ A spike entity that kills the player. """ def __init__(self, x, y, blocks, orientation, image, screen): """ :param x: Integer, the x-position of the wall. :param y: Integer, the y-position of the wall. :param image: pygame.Surface, the image of the wall. :param screen: pygame.Surface, the screen to draw the wall onto. """ self.screen = screen image = replicate(blocks, orientation, image) self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.rect = pg.Rect(x, y, 0, 0) def update(self): self.render.update() def draw(self, camera=None): self.render.draw(camera)
class IntroMenu(BaseMenu): """ The intro screen of the game after the splash screen. """ def __init__(self, screen): super().__init__(screen) self.effect = FadeEffect(screen) self.effect.timeEndDarken += 1.0 ICONS = ICON_RESOURCES["assets"] self.render = RenderComponent(self) self.render.add("red", ICONS["red"][0]) self.render.add("black", ICONS["black"][0]) self.render.state = "black" w, h = ICONS["red"][0].get_size() offsetX = (settings.WIDTH - w) / 2 offsetY = (settings.HEIGHT - h) / 2 self.rect.center = (offsetX, offsetY) self.audio = AudioComponent(self, isRepeat=True, isAutoPlay=True) self.audio.add("intro_1", SFX_RESOURCES["menu_intro_1"]) self.audio.add("intro_2", SFX_RESOURCES["menu_intro_2"]) self.audio.state = "intro_1" def __str__(self): return "intro_menu" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self._sendMessage() def update(self): self.audio.update() self.render.update() if not self.effect.isComplete: self.effect.update() if self.effect.time > self.effect.timeStartDarken + 2.0: self.render.state = "red" self.audio.state = "intro_2" else: self._sendMessage() def draw(self, camera=None): self.render.draw(camera) self.effect.draw() def _sendMessage(self): """ Sends a message to start the next menu. """ self.messageMenu("transition", "main_menu") pg.mixer.stop()
class SplashMenu(BaseMenu): """ The splash screen of the game. """ def __init__(self, screen): super().__init__(screen) self.effect = FadeEffect(screen) background = MENU_RESOURCES["screens"]["splash"][0] background = addBackground(background) self.render = RenderComponent(self) self.render.add("background", background) self.render.state = "background" self.audio = AudioComponent(self) self.audio.add("door_knock", SFX_RESOURCES["splash_door_knock"]) self.audio.add("door_open", SFX_RESOURCES["splash_door_open"]) self.audio.add("door_close", SFX_RESOURCES["splash_door_close"]) self.audio.add("meow", SFX_RESOURCES["splash_meow"]) self.audio.link("door_knock", "door_open", delay=1000) self.audio.link("door_open", "meow") self.audio.link("meow", "door_close") self.audio.state = "door_knock" def __str__(self): return "splash_menu" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self._sendMessage() def update(self): self.audio.update() self.render.update() if not self.effect.isComplete: self.effect.update() else: self._sendMessage() def draw(self, camera=None): self.render.draw(camera) self.effect.draw() def _sendMessage(self): """ Sends a message to start the next menu. """ self.messageMenu("transition", "intro_menu") pg.mixer.stop()
class Switch(GameObject): """ A switch entity that the player can turn on and off. """ def __init__(self, x, y, switchNum, screen, zoneArtwork=1): """ :param x: Integer, the x-position of the wall. :param y: Integer, the y-position of the wall. :param switchNum: Integer, identifying the number of the button. :param screen: pygame.Surface, the screen to draw the wall onto. :param zoneArtwork: Integer, choosing the image based on zone. """ self.screen = screen self.num = switchNum self.isOn = True # REFACTOR: Clumsy implementation to change image of the renderer # - Causes instantiating argument to be needlessly long. # - The code below does not scale well. if zoneArtwork == 1: button = ZONE1_RESOURCES["buttons"] if zoneArtwork == 2: button = ZONE2_RESOURCES["buttons"] self.render = RenderComponent(self, enableRepeat=False) self.render.add("on", [button["switch"][0]]) self.render.add("off", button["switch"], 500) self.render.state = "on" self.rect = pg.Rect(x, y, 0, 0) self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("click", SFX_RESOURCES["scene_switch"]) def __str__(self): return "switch " + str(self.num) def update(self): self.render.update() self.audio.update() def draw(self, camera=None): self.render.draw(camera) def turnOff(self): """ Changes the state of the button to off and sends out an event. """ self.isOn = False self.render.state = "off" self.audio.state = "click" self.messageScene("switch", (self.num, self.isOn))
class PauseMenu(BaseMenu): """ The pause menu of the game. """ def __init__(self, screen): super().__init__(screen) self.fontSize = 50 self.fontColour = "orange" self.x = 270 self.y = 225 self.pauseText = TextLabel("Pause", self.fontSize, self.fontColour, self.x, self.y, self.screen, isItalic=True) image = MENU_RESOURCES["screens"]["fade"][0] self.render = RenderComponent(self) self.render.add("background", image) self.render.state = "background" self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("pause", SFX_RESOURCES["menu_pause"]) self.audio.state = "pause" # Need to draw once only otherwise it overrides what is already drawn # by the Scene Engine self.render.update() self.pauseText.update() self.pauseText.draw() self.render.draw() def __str__(self): return "pause_menu" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.audio.state = "pause" def update(self): self.audio.update() def draw(self, camera=None): pass
class WinMenu(BaseMenu): """ The win menu of the game. """ def __init__(self, screen): super().__init__(screen) self.screen = screen self.fontSize = 18 self.fontColour = "white" self.x = 150 self.y = 320 self.enterText = TextLabel("Enter para salir", self.fontSize, self.fontColour, self.x, self.y, self.screen) self.Text2 = TextLabel("NIVEL 3 COMING SOON...", 32, self.fontColour, 100, 100, self.screen) image = MENU_RESOURCES["screens"]["fade"][0] self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.audio = AudioComponent(self, isAutoPlay=False, isRepeat=True) self.audio.add("win", SFX_RESOURCES["scene_win"]) self.audio.state = "win" def __str__(self): return "win_menu" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self.messageMenu("transition", "main_menu") self.messageScene("no_mode") def update(self): self.render.update() self.audio.update() self.enterText.update() self.Text2.update() def draw(self, camera=None): self.render.draw(camera) self.enterText.draw() self.Text2.draw()
class DPlatform(GameObject): """ A directional platform entity that requires the player to jump from below to pass through. """ def __init__(self, x, y, blocks, screen, zoneArtwork=1): """ :param x: Integer, the x-position of the wall. :param y: Integer, the y-position of the wall. :param blocks: Integer, the number of times to replicate the wall. :param screen: pygame.Surface, the screen to draw the wall onto. :param zoneArtwork: Integer, choosing the image based on zone. """ self.screen = screen # REFACTOR: Clumsy implementation to change image of the renderer. # - Causes instantiating argument to be needlessly long. # - The code below does not scale well. if zoneArtwork == 1: left = ZONE1_RESOURCES["platforms"]["platform_1"][0] mid = ZONE1_RESOURCES["platforms"]["platform_2"][0] right = ZONE1_RESOURCES["platforms"]["platform_3"][0] if zoneArtwork == 2: left = ZONE2_RESOURCES["platforms"]["platform_1"][0] mid = ZONE2_RESOURCES["platforms"]["platform_2"][0] right = ZONE2_RESOURCES["platforms"]["platform_3"][0] image = buildParts(blocks, "h", [left, mid, right]) self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.rect = pg.Rect(x, y, 0, 0) def __str__(self): return "directional_platform" def update(self): self.render.update() def draw(self, camera=None): self.render.draw(camera)
class LoseMenu(BaseMenu): """ The game over menu of the game. """ def __init__(self, screen): super().__init__(screen) self.fontSize = 18 self.fontColour = "white" self.x = 150 self.y = 320 self.enterText = TextLabel("Enter para salir", self.fontSize, self.fontColour, self.x, self.y, self.screen) image = MENU_RESOURCES["screens"]["lose"][0] self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("meow", SFX_RESOURCES["menu_lose"]) self.audio.state = "meow" def __str__(self): return "lose_menu" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self.messageMenu("transition", "splash_menu") self.messageScene("no_mode") def update(self): self.render.update() self.audio.update() self.enterText.update() def draw(self, camera=None): self.render.draw() self.enterText.draw()
class DeathMenu(BaseMenu): """ The death screen of the game. """ def __init__(self, screen): super().__init__(screen) self.effect = FadeEffect(screen) self.effect.timeStartLighten = 0.0 self.effect.timeEndLighten = 1.0 self.effect.timeStartDarken = 1.0 self.effect.timeEndDarken = 1.5 image = pg.Surface((settings.WIDTH, settings.HEIGHT)) image.fill(settings.COLOURS["dark_red"]) image = image.convert() self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.audio = AudioComponent(self, isAutoPlay=True, isRepeat=False) self.audio.add("death", SFX_RESOURCES["menu_death"]) self.audio.state = "death" def __str__(self): return "death_menu" def handleEvent(self, event): print("'{}' safely ignored event {}".format(self.__str__(), event)) def update(self): self.render.update() self.audio.update() self.effect.update() if self.effect.isComplete: self.messageScene("revive") def draw(self, camera=None): self.render.draw() self.effect.draw()
class Wall(GameObject): """ A wall entity that obstructs the player. """ def __init__(self, x, y, blocks, orientation, images, screen): """ :param x: Integer, the x-position of the wall. :param y: Integer, the y-position of the wall. :param blocks: Integer, the number of times to replicate the wall. :param orientation: String, either 'v' or 'h' for vertical or horizontal. :param images: Tuple, containing either a single or three pygame.Surfaces to build the platform. :param screen: pygame.Surface, the screen to draw the wall onto. """ self.screen = screen if len(images) == 3: image = buildParts(blocks, orientation, images) elif len(images) == 1: image = replicate(blocks, orientation, images[0]) else: raise ValueError("A wall must have one or three images only!") self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.rect = pg.Rect(x, y, 0, 0) def __str__(self): return "wall" def update(self): self.render.update() def draw(self, camera=None): self.render.draw(camera)
class Spear(GameObject): """ A spear entity that kills the player. """ def __init__(self, x, y, screen): """ :param x: Integer, the x-position of the wall. :param y: Integer, the y-position of the wall. :param screen: pygame.Surface, the screen to draw the wall onto. """ self.screen = screen assets = ZONE2_RESOURCES["traps"]["spear"] self.render = RenderComponent(self) self.render.add("idle", assets) self.render.state = "idle" self.rect = pg.Rect(x, y, 0, 0) def update(self): self.render.update() def draw(self, camera=None): self.render.draw(camera)
class Door(GameObject): """ A door entity that the player can enter. """ def __init__(self, x, y, num, screen, zoneArtwork=1): """ :param x: Integer, the x-position of the wall. :param y: Integer, the y-position of the wall. :param num: Integer, identifying the number of the button. :param screen: pygame.Surface, the screen to draw the wall onto. :param zoneArtwork: Integer, choosing the image based on zone. """ self.screen = screen self.num = num self.switchesWaiting = [] self.isClosed = True # REFACTOR: Clumsy implementation to change image of the renderer. # - Causes instantiating argument to be needlessly long. # - The code below does not scale well. if zoneArtwork == 1: door = ZONE1_RESOURCES["doors"] if zoneArtwork == 2: door = ZONE2_RESOURCES["doors"] self.render = RenderComponent(self, enableRepeat=False) self.render.add("open", door["open"]) self.render.add("closed", door["close"]) self.render.state = "closed" self.rect = pg.Rect(x, y, 0, 0) self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("open", SFX_RESOURCES["scene_door"]) def __str__(self): return "door_{}".format(self.num) def handleEvent(self, event): if event.type == self.SCENE_EVENT: if event.category == "switch": try: switchNum, isOn = event.data self.switchesWaiting.remove(switchNum) if not self.switchesWaiting: self.openDoor() except ValueError: print("'{}' is safely ignoring switch number {}" .format(self.__str__(), switchNum)) except AttributeError: print("'{}' is not a valid switch number!".format(switchNum)) def update(self): self.render.update() self.audio.update() def draw(self, camera=None): self.render.draw(camera) def openDoor(self): """ Changes the state of the door to open and sends out an event. """ self.isClosed = False self.render.state = "open" self.audio.state = "open" self.messageScene("door", (self.num, self.isClosed))
class MPlatform(GameObject): """ A moving platform entity that constantly moves between two points. """ def __init__(self, A, B, dx, dy, screen, image): """ :param A: 2-Tuple, containing coordinates of a point A. :param B: 2-Tuple, containing coordinates of a point B. :param dx: Number, pixels moved in the x-axis every physics tick. :param dy: Number, pixels moved in the y-axis every physics tick. :param screen: pygame.Surface, the screen to draw the wall onto. :param image: pygame.Surface, the image of the platform. """ self.screen = screen self.A = A self.B = B self.dx = dx self.dy = dy self.isDirectionX = True self.isDirectionY = True self.physics = PhysicsComponent(self) self.physics.isGravity = False self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.rect = pg.Rect(A[0], A[1], 0, 0) def __str__(self): return "moving_platform" def update(self): # Physics update at start because it seems there is a mismatch of clock # between moving platform and the player; the proper solution involves # coding a physics engine that synchronises all physics updates. # Try moving the physics update post the change in self.dx variables # and the bug of the player standing on the moving platform appears. self.physics.update() xBoundA, yBoundA = self.A xBoundB, yBoundB = self.B if self.rect.x > xBoundB and self.isDirectionX: self.dx *= -1 self.isDirectionX = False if self.rect.x < xBoundA and not self.isDirectionX: self.dx *= -1 self.isDirectionX = True if self.rect.y > yBoundB and self.isDirectionY: self.dy *= -1 self.isDirectionY = False if self.rect.y < yBoundA and not self.isDirectionY: self.dy *= -1 self.isDirectionY = True self.physics.addDisplacementX("move", self.dx) self.physics.addDisplacementY("move", self.dy) self.render.update() def draw(self, camera=None): self.render.draw(camera)
class ForestScene01(BaseScene): LEVEL_NUM = 5 def __init__(self, screen): super().__init__(screen) self.players = self.addPlayers() self.walls = self.addWalls() self.mPlatforms = self.addMPlatforms() self.switches = self.addSwitches() self.doors = self.addDoors() self.spikes = self.addSpikes() self.spears = self.addSpears() self.dPlatforms = self.addDPlatforms() self.decorations = self.addDecorations() self.elapsed = 0 self.origin = pg.time.get_ticks() image = ZONE2_RESOURCES["levels"]["solo_forest_01"] self.render = RenderComponent(self) self.render.add("background", image) self.render.state = "background" self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.JAIL_SOLO_1, 10, 410, "caption") def __str__(self): return "solo_forest_scene_01" def handleEvent(self, event): [p.handleEvent(event) for p in self.players] if event.type == self.SCENE_EVENT: [d.handleEvent(event) for d in self.doors] def update(self): self.elapsed = pg.time.get_ticks() - self.origin self.render.update() [d.update() for d in self.decorations] [w.update() for w in self.walls] [s.update() for s in self.switches] [d.update() for d in self.doors] [s.update() for s in self.spikes] [s.update() for s in self.spears] [p.update() for p in self.dPlatforms] [p.update() for p in self.mPlatforms] [p.update() for p in self.players] [b.update() for b in self.bosses] self.dialogue.update() if 5000 > self.elapsed >= 0: self.dialogue.index = 0 else: self.dialogue.index = None def draw(self, camera=None): self.screen.fill(settings.COLOURS["dark_blue"]) self.render.draw(camera) [d.draw(camera) for d in self.decorations] [w.draw(camera) for w in self.walls] [s.draw(camera) for s in self.switches] [d.draw(camera) for d in self.doors] [s.draw(camera) for s in self.spikes] [s.draw(camera) for s in self.spears] [p.draw(camera) for p in self.dPlatforms] [p.draw(camera) for p in self.mPlatforms] [p.draw(camera) for p in self.players] [b.draw(camera) for b in self.bosses] self.dialogue.draw() def addPlayers(self): spawn = (400, 900) player = [PlayerOne(self.screen)] player[0].rect.center = spawn return player def addWalls(self): wall = ZONE2_RESOURCES["walls"] pillar = ZONE2_RESOURCES["pillars"] platWall = [ wall["plat_top"][0], wall["plat_mid"][0], wall["plat_bot"][0] ] pillarWall = [ pillar["steel_top"][0], pillar["steel_mid"][0], pillar["steel_bot"][0] ] boundaries = \ [ Wall(0, 962, 4, "h", wall["ground"], self.screen), Wall(0, 1074, 4, "h", wall["ground_clean"], self.screen), Wall(675, 962, 4, "h", wall["ground"], self.screen), Wall(1550, 962, 5, "h", wall["ground"], self.screen), Wall(675, 1074, 12, "h", wall["ground_clean"], self.screen), # Wall(0, 500, 6, "v", pillarWall, self.screen), ] boundaries[0].render.shrinkBy = (0, -50) obstacles = \ [ Wall(0, 898, 1, "h", wall["single_plat"], self.screen), Wall(160, 898, 1, "h", wall["single_plat"], self.screen), Wall(288, 770, 1, "h", wall["single_plat"], self.screen), Wall(-32, 770, 4, "h", wall["block_mid"], self.screen), Wall(224, 770, 1, "h", wall["block_right"], self.screen), Wall(288, 898, 1, "h", wall["corner_top_right"], self.screen), Wall(224, 898, 1, "h", wall["corner_top_left"], self.screen), Wall(224, 834, 1, "h", wall["corner_bot_right"], self.screen), Wall(288, 834, 1, "h", wall["corner_bot_left"], self.screen), Wall(192, 738, 1, "h", wall["block_small"], self.screen), Wall(96, 930, 1, "h", wall["block_small"], self.screen), Wall(875, 850, 1, "h", wall["block_small"], self.screen), Wall(1050, 750, 1, "h", wall["block_small"], self.screen), Wall(1325, 1010, 1, "h", wall["block_small"], self.screen), Wall(1815, 706, 2, "v", platWall, self.screen), #Wall(210, 300, 1, "h", wall["block_left"], self.screen), #Wall(265, 300, 1, "h", wall["block_right"], self.screen), #Wall(435, 490, 1, "h", wall["block_left"], self.screen), #Wall(490, 490, 1, "h", wall["block_right"], self.screen), #Wall(655, 300, 1, "h", wall["block_left"], self.screen), #Wall(710, 300, 1, "h", wall["block_right"], self.screen), #Wall(770, 105, 2, "v", platWall, self.screen), ] return boundaries + obstacles def addDPlatforms(self): platforms = \ [ DPlatform(1550, 800, 1, self.screen, zoneArtwork=2), #DPlatform(60, 330, 0, self.screen, zoneArtwork=2), ] return platforms def addMPlatforms(self): vImage = ZONE2_RESOURCES["platforms"]["moving_vertical"] hImage = ZONE2_RESOURCES["platforms"]["moving_horizontal"] platforms = \ [ MPlatform((1000, 710), (1300, 260), 9, 0, self.screen, hImage), #MPlatform((1000, 450), (600, 450), 8, 0, self.screen, hImage), #MPlatform((340, 300), (600, 300), 8, 0, self.screen, hImage), #MPlatform((660, 350), (660, 435), 0, 0, self.screen, vImage), #MPlatform((660, 435), (660, 530), 0, 0, self.screen, vImage), ] return platforms def addSwitches(self): switches = \ [ Switch(1070, 650, 1, self.screen, zoneArtwork=2), Switch(1070, 900, 2, self.screen, zoneArtwork=2), Switch(1600, 750, 3, self.screen, zoneArtwork=2), #Switch(1600, 900, 3, self.screen, zoneArtwork=2), #Switch(700, 200, 4, self.screen, zoneArtwork=2), ] return switches def addDoors(self): door1 = Door(1710, 854, 1, self.screen, zoneArtwork=2) door1.switchesWaiting = [1, 2, 3] return [door1] def addSpikes(self): assets = ZONE2_RESOURCES["traps"] spikes = \ [ Spike(1175, 1050, 18, "h", assets["spike_up"][0], self.screen), Spear(1340, 963, self.screen), #Spike(550, 525, 5, "h", assets["spike_up"][0], self.screen), ] x_axis = 798 for x in range(4): spikes.append(Spear(x_axis, 915, self.screen)) x_axis += 64 return spikes def addDecorations(self): deco = ZONE2_RESOURCES["decorations"] x_axis = 0 x_axis2 = 675 x_axis3 = 1550 decorations = \ [ Decoration(732, 456, deco["moon"][0], self.screen) ] for x in range(4): decorations.append( Decoration(x_axis, 950, deco["grass"][0], self.screen)) x_axis += 125 for x in range(4): decorations.append( Decoration(x_axis2, 950, deco["grass"][0], self.screen)) x_axis2 += 125 for x in range(5): decorations.append( Decoration(x_axis3, 950, deco["grass"][0], self.screen)) x_axis3 += 125 return decorations def addSpears(self): spears = \ [ #Spear(1370, 946, self.screen), #Spear(862, 915, self.screen), #Spear(926, 915, self.screen), #Spear(0, 915, self.screen), ] return spears
class MainMenu(BaseMenu): """ The main menu of the game. """ def __init__(self, screen): super().__init__(screen) self.totalOptions = 4 self.fontSize = 22 self.fontColour = "white" self.x = 250 self.y = 155 self.dx = 0 self.dy = 38 self.option1 = TextLabel("1 Jugador", self.fontSize, self.fontColour, self.x, self.y + 1 * self.dy, self.screen) self.option2 = TextLabel("2 Jugadores", self.fontSize, self.fontColour, self.x, self.y + 2 * self.dy, self.screen) self.option3 = TextLabel("Opciones", self.fontSize, self.fontColour, self.x, self.y + 3 * self.dy, self.screen) self.option4 = TextLabel("Salir", self.fontSize, self.fontColour, self.x, self.y + 4 * self.dy, self.screen) self.title = ImageLabel(MENU_RESOURCES["assets"]["title"][0], 60, 55, self.screen) self.arrow = _Arrow(self.x - 40, self.y + 28, self.dx, self.dy, self.totalOptions, self.screen) background = MENU_RESOURCES["screens"]["main"][0] self.render = RenderComponent(self) self.render.add("background", background) self.render.state = "background" self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("enter", SFX_RESOURCES["menu_enter"]) def __str__(self): return "main_menu" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_UP: self.arrow.moveUp() if event.key == pg.K_DOWN: self.arrow.moveDown() if event.key == pg.K_RETURN: self.audio.state = "enter" if self.arrow.index == 0: self.messageMenu("transition", "blank_menu") self.messageCutScene("transition", "office_cutscene") if self.arrow.index == 1: self.messageMenu("transition", "blank_menu") self.messageScene("start_game", "coop") if self.arrow.index == 2: self.messageMenu("transition", "options_menu") if self.arrow.index == 3: quit() def update(self): self.render.update() self.audio.update() self.option1.update() self.option2.update() self.option3.update() self.option4.update() self.title.update() self.arrow.update() def draw(self, camera=None): self.render.draw(camera) self.title.draw() self.option1.draw() self.option2.draw() self.option3.draw() self.option4.draw() self.arrow.draw()
class ForestScene02(BaseScene): LEVEL_NUM = 6 def __init__(self, screen): super().__init__(screen) self.players = self.addPlayers() self.walls = self.addWalls() self.mPlatforms = self.addMPlatforms() self.switches = self.addSwitches() self.doors = self.addDoors() self.spikes = self.addSpikes() self.spears = self.addSpears() self.dPlatforms = self.addDPlatforms() self.decorations = self.addDecorations() self.elapsed = 0 self.origin = pg.time.get_ticks() image = ZONE2_RESOURCES["levels"]["solo_forest_01"] self.render = RenderComponent(self) self.render.add("background", image) self.render.state = "background" self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.FOREST_SOLO_2, 10, 410, "caption") def __str__(self): return "solo_forest_scene_02" def handleEvent(self, event): [p.handleEvent(event) for p in self.players] if event.type == self.SCENE_EVENT: [d.handleEvent(event) for d in self.doors] def update(self): self.elapsed = pg.time.get_ticks() - self.origin self.render.update() [d.update() for d in self.decorations] [w.update() for w in self.walls] [s.update() for s in self.switches] [d.update() for d in self.doors] [s.update() for s in self.spikes] [s.update() for s in self.spears] [p.update() for p in self.dPlatforms] [p.update() for p in self.mPlatforms] [p.update() for p in self.players] [b.update() for b in self.bosses] self.dialogue.update() if 5000 > self.elapsed >= 0: self.dialogue.index = 0 else: self.dialogue.index = None def draw(self, camera=None): self.screen.fill(settings.COLOURS["dark_blue"]) self.render.draw(camera) [d.draw(camera) for d in self.decorations] [w.draw(camera) for w in self.walls] [s.draw(camera) for s in self.switches] [d.draw(camera) for d in self.doors] [s.draw(camera) for s in self.spikes] [s.draw(camera) for s in self.spears] [p.draw(camera) for p in self.dPlatforms] [p.draw(camera) for p in self.mPlatforms] [p.draw(camera) for p in self.players] [b.draw(camera) for b in self.bosses] self.dialogue.draw() def addPlayers(self): spawn = (400, 900) player = [PlayerOne(self.screen)] player[0].rect.center = spawn return player def addWalls(self): wall = ZONE2_RESOURCES["walls"] pillar = ZONE2_RESOURCES["pillars"] platWall = [ wall["plat_top"][0], wall["plat_mid"][0], wall["plat_bot"][0] ] pillarWall = [ pillar["steel_top"][0], pillar["steel_mid"][0], pillar["steel_bot"][0] ] boundaries = \ [ Wall(0, 962, 9, "h", wall["ground"], self.screen), Wall(0, 1074, 9, "h", wall["ground_clean"], self.screen), Wall(1375, 962, 6, "h", wall["ground"], self.screen), Wall(1375, 1074, 6, "h", wall["ground_clean"], self.screen), ] boundaries[0].render.shrinkBy = (0, -50) obstacles = \ [ Wall(288, 706, 2,"v", platWall, self.screen), Wall(1814, 518, 1, "h", wall["corner_top_right"], self.screen), Wall(1750, 518, 1, "h", wall["corner_top_left"], self.screen), Wall(1750, 454, 1, "h", wall["corner_bot_right"], self.screen), Wall(1814, 454, 1, "h", wall["corner_bot_left"], self.screen), ] return boundaries + obstacles def addDPlatforms(self): platforms = \ [ ] return platforms def addMPlatforms(self): vImage = ZONE2_RESOURCES["platforms"]["moving_vertical"] hImage = ZONE2_RESOURCES["platforms"]["moving_horizontal"] x_axis = 595 x_axis2 = 800 y_axis = 885 platforms = \ [ #MPlatform((595, 885), (800, 450), 8, 0, self.screen, hImage), #MPlatform((753, 808), (958, 300), 8, 0, self.screen, hImage), #MPlatform((911, 731), (1116, 435), 8, 0, self.screen, hImage), #MPlatform((1064, 731), (1116, 435), 8, 0, self.screen, hImage), #MPlatform((660, 435), (660, 530), 0, 0, self.screen, vImage), ] for x in range(6): platforms.append( MPlatform((x_axis, y_axis), (x_axis2, 450), 8, 0, self.screen, hImage)) x_axis += 158 x_axis2 += 158 y_axis -= 77 return platforms def addSwitches(self): switches = \ [ Switch(962, 571, 1, self.screen, zoneArtwork=2), #Switch(1070, 900, 2, self.screen, zoneArtwork=2), #Switch(1600, 750, 3, self.screen, zoneArtwork=2), #Switch(1600, 900, 3, self.screen, zoneArtwork=2), #Switch(700, 200, 4, self.screen, zoneArtwork=2), ] return switches def addDoors(self): door1 = Door(1798, 346, 1, self.screen, zoneArtwork=2) door1.switchesWaiting = [1] return [door1] def addSpikes(self): assets = ZONE2_RESOURCES["traps"] spikes = \ [ Spike(1375, 938, 25, "h", assets["spike_up"][0], self.screen), #Spear(1340, 963, self.screen), #Spike(550, 525, 5, "h", assets["spike_up"][0], self.screen), ] x_axis = 798 for x in range(4): spikes.append(Spear(x_axis, 915, self.screen)) x_axis += 64 return spikes def addDecorations(self): deco = ZONE2_RESOURCES["decorations"] door = ZONE2_RESOURCES["doors"] x_axis = 0 x_axis2 = 1375 #x_axis3 = 1550 decorations = \ [ Decoration(732, 456, deco["moon"][0], self.screen), Decoration(352, 854, door["open"][0], self.screen), ] for x in range(9): decorations.append( Decoration(x_axis, 950, deco["grass"][0], self.screen)) x_axis += 125 for x in range(6): decorations.append( Decoration(x_axis2, 950, deco["grass"][0], self.screen)) x_axis2 += 125 return decorations def addSpears(self): spears = \ [ #Spear(1370, 946, self.screen), #Spear(862, 915, self.screen), #Spear(926, 915, self.screen), #Spear(0, 915, self.screen), ] return spears
class PigCutscene(BaseCutscene): """ The cutscene where the pig boss appears. """ def __init__(self, screen): super().__init__(screen) self.rect = pg.Rect(0, 0, 0, 0) pig = CUTSCENE_RESOURCES["pig"]["appear"] pig = [addBackground(p) for p in pig] self.origin = pg.time.get_ticks() # milliseconds self.elapsed = 0 # milliseconds self._isComplete = False self.render = RenderComponent(self, enableRepeat=False) self.render.add("appear", pig, 3000) self.audio = AudioComponent(self) self.audio.add("machine", SFX_RESOURCES["pig_machine"]) self.audio.state = "machine" self.dialogue = Dialogue(self.screen) speed = 1 ts = [3000] self.timings = [speed * t for t in ts] def __str__(self): return "pig_cutscene" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self._messageStart() def update(self): self.elapsed = pg.time.get_ticks() - self.origin if self.timings[0] > self.elapsed: self.render.state = "appear" self.dialogue.index = None else: if not self._isComplete: self._isComplete = True self._messageStart() self.dialogue.update() self.render.update() self.audio.update() def draw(self, camera=None): self.render.draw(camera) self.render.draw() self.dialogue.draw() def _messageStart(self): """ Sends out events to end the cutscene and start playing the game. """ self.messageCutScene("transition", "blank_cutscene") self.messageScene("unpause") pg.mixer.stop()
class OfficeCutscene(BaseCutscene): """ The cutscene where the dog and cat are talking in the office. """ def __init__(self, screen): super().__init__(screen) self.rect = pg.Rect(0, 0, 0, 0) office = CUTSCENE_RESOURCES["office"] self.origin = pg.time.get_ticks() # milliseconds self.elapsed = 0 # milliseconds self._isSentMessage = False self.render = RenderComponent(self) self.render.add("office_dog", office["dog"], 1500) self.render.add("office_cat", office["cat"], 1500) self.audio = AudioComponent(self, isAutoPlay=False) # self.audio.add("meow", SFX_RESOURCES["meow_1"]) self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.OFFICE_1, 240, 50, "left") self.dialogue.add(dialogue.OFFICE_2, 370, 100) self.dialogue.add(dialogue.OFFICE_3, 240, 50, "left") self.dialogue.add(dialogue.OFFICE_4, 370, 100) speed = 1 ts = [0, 4000, 8000, 12000, 16000] self.timings = [speed * t for t in ts] def __str__(self): return "office_cutscene" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self._messageNextScene() def update(self): self.elapsed = pg.time.get_ticks() - self.origin if self.timings[0] >= self.elapsed: self.render.state = "office_dog" self.dialogue.index = None elif self.timings[1] > self.elapsed: self.render.state = "office_cat" self.dialogue.index = 0 elif self.timings[2] > self.elapsed: self.render.state = "office_dog" self.dialogue.index = 1 elif self.timings[3] > self.elapsed: self.render.state = "office_cat" self.dialogue.index = 2 elif self.timings[4] >= self.elapsed: self.render.state = "office_dog" self.dialogue.index = 3 else: self._messageNextScene() self.dialogue.update() self.render.update() def draw(self, camera=None): self.render.draw(camera) self.dialogue.draw() def _messageNextScene(self): """ Sends a message to play the next cutscene. """ if not self._isSentMessage: self.messageCutScene("transition", "telephone_cutscene") self._isSentMessage = True
class TelephoneCutscene(BaseCutscene): """ The cutscene where the dog is talking on the phone. """ def __init__(self, screen): super().__init__(screen) self.rect = pg.Rect(0, 0, 0, 0) telephone = CUTSCENE_RESOURCES["telephone"] self.origin = pg.time.get_ticks() # milliseconds self.elapsed = 0 # milliseconds self._isComplete = False self._isReversed = False self.render = RenderComponent(self, enableRepeat=False) self.render.add("telephone_none", telephone["none"]) self.render.add("telephone_pick", telephone["pick"], 1100) self.render.add("telephone_hold", telephone["hold"]) self.render.add("telephone_put", telephone["put"], 1100) self.audio = AudioComponent(self) self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.TELEPHONE_1, 350, 150, "left") self.dialogue.add(dialogue.TELEPHONE_2, 350, 150, "left") speed = 1 ts = [2000, 2800, 3300, 6300, 10300, 11300, 12100, 14000] self.timings = [speed * t for t in ts] def __str__(self): return "telephone_cutscene" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self.messageCutScene("transition", "jail_cutscene") def update(self): self.elapsed = pg.time.get_ticks() - self.origin if self.timings[0] > self.elapsed: self.render.state = "telephone_none" self.dialogue.index = None elif self.timings[1] > self.elapsed: self.render.state = "telephone_pick" self.dialogue.index = None elif self.timings[2] > self.elapsed: self.render.state = "telephone_hold" self.dialogue.index = None elif self.timings[3] > self.elapsed: self.render.state = "telephone_hold" self.dialogue.index = 0 elif self.timings[4] > self.elapsed: self.render.state = "telephone_hold" self.dialogue.index = 1 elif self.timings[5] > self.elapsed: self.render.state = "telephone_hold" self.dialogue.index = None elif self.timings[6] > self.elapsed: self.render.state = "telephone_put" self.dialogue.index = None elif self.timings[7] > self.elapsed: self.render.state = "telephone_none" self.dialogue.index = None else: if not self._isComplete: self._isComplete = True self.messageCutScene("transition", "jail_cutscene") self.dialogue.update() self.render.update() def draw(self, camera=None): self.render.draw(camera) self.dialogue.draw()
class JailCutscene(BaseCutscene): """ The cutscene where the cat is being escorted to jail. """ def __init__(self, screen): super().__init__(screen) self.rect = pg.Rect(0, 0, 0, 0) jail = CUTSCENE_RESOURCES["jail"] self.origin = pg.time.get_ticks() # milliseconds self.elapsed = 0 # milliseconds self._isComplete = False self.render = RenderComponent(self, enableRepeat=False) self.render.add("fence_show", jail["fence_show"], 2000) self.render.add("fence_static", jail["fence_static"]) self.render.add("fence_hide", jail["fence_hide"], 2000) self.render.add("cat_static", jail["cat_static"]) self.render.add("cat_close", jail["cat_close"], 3500) self.audio = AudioComponent(self) self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.JAIL_1, 19, 25, "caption") speed = 1 ts = [2000, 4000, 6000, 9500, 11500] self.timings = [speed * t for t in ts] def __str__(self): return "jail_cutscene" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_RETURN: self._messageStart() def update(self): self.elapsed = pg.time.get_ticks() - self.origin if self.timings[0] > self.elapsed: self.render.state = "fence_show" self.dialogue.index = 0 elif self.timings[1] > self.elapsed: self.render.state = "fence_static" self.dialogue.index = None elif self.timings[2] > self.elapsed: self.render.state = "fence_hide" self.dialogue.index = None elif self.timings[3] > self.elapsed: self.render.state = "cat_close" self.dialogue.index = None elif self.timings[4] > self.elapsed: self.render.state = "cat_static" self.dialogue.index = None else: if not self._isComplete: self._isComplete = True self._messageStart() self.dialogue.update() self.render.update() def draw(self, camera=None): self.render.draw(camera) self.dialogue.draw() def _messageStart(self): """ Sends out events to end the cutscene and start playing the game. """ self.messageCutScene("transition", "blank_cutscene") self.messageScene("start_game", "solo")
class JailScene03(BaseScene): LEVEL_NUM = 3 def __init__(self, screen): super().__init__(screen) self.levelNum = 3 self.players = self.addPlayers() self.bosses = self.addBosses() self.bosses[0].target(self.players) self.walls = self.addWalls() self.sPlatforms = self.addSPlatforms() self.dPlatforms = self.addDPlatforms() self.mPlatforms = self.addMPlatforms() self.switches = self.addSwitches() self.doors = self.addDoors() self.spikes = self.addSpikes() self.decorations = self.addDecorations() self.elapsed = 0 self.origin = pg.time.get_ticks() image = ZONE1_RESOURCES["levels"]["coop_jail_03"] self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.JAIL_COOP_3, 10, 410, "caption") self.messageCutScene("transition", "pig_cutscene") self.messageMenu("transition", "blank_menu") def __str__(self): return "coop_jail_scene_03" def handleEvent(self, event): [p.handleEvent(event) for p in self.players] if event.type == self.SCENE_EVENT: [d.handleEvent(event) for d in self.doors] def update(self): self.elapsed = pg.time.get_ticks() - self.origin self.render.update() [w.update() for w in self.walls] [s.update() for s in self.switches] [d.update() for d in self.doors] [s.update() for s in self.spikes] [p.update() for p in self.sPlatforms] [p.update() for p in self.mPlatforms] [p.update() for p in self.dPlatforms] [d.update() for d in self.decorations] [p.update() for p in self.players] [b.update() for b in self.bosses] self.dialogue.update() if 5000 > self.elapsed >= 0: self.dialogue.draw() else: self.dialogue.index = None def draw(self, camera=None): self.screen.fill(settings.COLOURS["black_red"]) self.render.draw(camera) [w.draw(camera) for w in self.walls] [s.draw(camera) for s in self.switches] [d.draw(camera) for d in self.doors] [s.draw(camera) for s in self.spikes] [p.draw(camera) for p in self.sPlatforms] [p.draw(camera) for p in self.mPlatforms] [p.draw(camera) for p in self.dPlatforms] [d.draw(camera) for d in self.decorations] [p.draw(camera) for p in self.players] [b.draw(camera) for b in self.bosses] self.dialogue.draw() def addPlayers(self): p1Spawn = (330, 210) p2Spawn = (330, 210) p1 = PlayerOne(self.screen) p2 = PlayerTwo(self.screen) p1.rect.center = p1Spawn p2.rect.center = p2Spawn players = [p1, p2] return players def addBosses(self): b1Spawn = (970, 280) b1 = PigBoss(self.screen) b1.rect.center = b1Spawn bosses = [b1] return bosses def addWalls(self): wall = ZONE1_RESOURCES["walls"] blockWall = [wall["block_left"][0], wall["block_mid"][0], wall["block_right"][0]] boundaries = \ [ #Wall(600, 0, 9, "v", wall["boundary_right"], self.screen), Wall(600, 52, 1, "v", wall["plat_top"], self.screen), Wall(600, 116, 7, "v", wall["plat_mid"], self.screen), Wall(600, 564, 1, "v", wall["plat_bot"], self.screen), Wall(0, 750, 20, "h", wall["boundary_bot"], self.screen), Wall(0, 0, 12, "v", wall["boundary_left"], self.screen), Wall(0, 0, 20, "h", wall["boundary_top"], self.screen), Wall(1250, 0, 12, "v", wall["boundary_right"], self.screen), Wall(0, 0, 1, "v", wall["upper_corner_left"], self.screen), Wall(0, 750, 1, "v", wall["inner_corner_left"], self.screen), Wall(1250, 0, 1, "v", wall["upper_corner_right"], self.screen), Wall(1250, 750, 1, "v", wall["inner_corner_right"], self.screen), ] obstacles = \ [ Wall(167, 330, 3, "h", blockWall, self.screen), Wall(220, 600, 1, "h", blockWall, self.screen), ] return boundaries + obstacles def addSPlatforms(self): platforms = \ [ SPlatform(240, 240, 2, self.screen), ] return platforms def addMPlatforms(self): vImage = ZONE1_RESOURCES["platforms"]["moving_vertical"] hImage = ZONE1_RESOURCES["platforms"]["moving_horizontal"] platforms = \ [ MPlatform((100, 100), (100, 600), 0, 20, self.screen, vImage), MPlatform((130, 100), (130, 600), 0, 20, self.screen, vImage), MPlatform((160, 100), (160, 600), 0, 20, self.screen, vImage), MPlatform((190, 100), (190, 600), 0, 20, self.screen, vImage), MPlatform((210, 100), (210, 600), 0, 20, self.screen, vImage), MPlatform((240, 100), (240, 600), 0, 20, self.screen, vImage), MPlatform((360, 100), (360, 600), 0, 20, self.screen, vImage), MPlatform((390, 100), (390, 600), 0, 20, self.screen, vImage), MPlatform((420, 100), (420, 600), 0, 20, self.screen, vImage), MPlatform((450, 100), (450, 600), 0, 20, self.screen, vImage), MPlatform((480, 100), (480, 600), 0, 20, self.screen, vImage), MPlatform((510, 100), (410, 600), 0, 20, self.screen, vImage), MPlatform((900, 200), (1000, 200), 10, 0, self.screen, hImage), ] return platforms def addDPlatforms(self): platforms = \ [ DPlatform(900, 660, 1, self.screen), DPlatform(664, 460, 1, self.screen), DPlatform(1143, 460, 1, self.screen), DPlatform(700, 260, 1, self.screen), DPlatform(900, 360, 1, self.screen), DPlatform(1100, 160, 1, self.screen), ] return platforms def addSwitches(self): switches = \ [ Switch(210, 200, 1, self.screen), Switch(400, 200, 2, self.screen), Switch(100, 100, 3, self.screen), Switch(510, 100, 4, self.screen), Switch(300, 480, 5, self.screen), Switch(940, 600, 6, self.screen), Switch(1200, 700, 7, self.screen), Switch(940, 600, 8, self.screen), Switch(940, 400, 9, self.screen), Switch(660, 50, 10, self.screen), ] return switches def addDoors(self): doors = \ [ Door(280, 133, 1, self.screen), Door(1115, 55, 2, self.screen), ] doors[0].render.state = "open" doors[1].switchesWaiting = list(range(1, 11)) return doors def addSpikes(self): assets = ZONE1_RESOURCES["traps"] spikes = \ [ Spike(50, 50, 26, "h", assets["spike_down"][0], self.screen), Spike(165, 305, 15, "h", assets["spike_up"][0], self.screen), Spike(165, 380, 15, "h", assets["spike_down"][0], self.screen), Spike(230, 575, 8, "h", assets["spike_up"][0], self.screen), ] return spikes def addDecorations(self): skull = ZONE1_RESOURCES["decorations"]["skull"][0] deco = ZONE1_RESOURCES["decorations"] decorations = \ [ Decoration(500, 730, skull, self.screen), Decoration(530, 730, skull, self.screen), Decoration(560, 730, skull, self.screen), Decoration(590, 730, skull, self.screen), Decoration(620, 730, skull, self.screen), Decoration(750, 730, skull, self.screen), Decoration(780, 730, skull, self.screen), Decoration(810, 730, skull, self.screen), Decoration(840, 730, skull, self.screen), Decoration(870, 730, skull, self.screen), Decoration(900, 730, skull, self.screen), Decoration(1000, 730, skull, self.screen), Decoration(1030, 730, skull, self.screen), Decoration(1060, 730, skull, self.screen), Decoration(1090, 730, skull, self.screen), Decoration(1200, 730, skull, self.screen), Decoration(940, 513, deco["torch"], self.screen), ] return decorations
class JailScene04(BaseScene): LEVEL_NUM = 4 def __init__(self, screen): super().__init__(screen) self.players = self.addPlayers() self.bosses = self.addBosses() self.bosses[0].target(self.players) self.walls = self.addWalls() self.mPlatforms = self.addMPlatforms() self.switches = self.addSwitches() self.doors = self.addDoors() self.spikes = self.addSpikes() self.dPlatforms = self.addDPlatforms() self.decorations = self.addDecorations() self.elapsed = 0 self.origin = pg.time.get_ticks() image = ZONE1_RESOURCES["levels"]["solo_jail_04"] self.render = RenderComponent(self) self.render.add("background", image) self.render.state = "background" self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.JAIL_SOLO_1, 10, 410, "caption") self.messageCutScene("transition", "pig_cutscene") self.messageMenu("transition", "blank_menu") def __str__(self): return "solo_jail_scene_04" def handleEvent(self, event): [p.handleEvent(event) for p in self.players] if event.type == self.SCENE_EVENT: [d.handleEvent(event) for d in self.doors] def update(self): self.elapsed = pg.time.get_ticks() - self.origin self.render.update() [d.update() for d in self.decorations] [w.update() for w in self.walls] [s.update() for s in self.switches] [d.update() for d in self.doors] [s.update() for s in self.spikes] [p.update() for p in self.dPlatforms] [p.update() for p in self.mPlatforms] [p.update() for p in self.players] [b.update() for b in self.bosses] self.dialogue.update() if 5000 > self.elapsed >= 0: self.dialogue.index = 0 else: self.dialogue.index = None def draw(self, camera=None): self.screen.fill(settings.COLOURS["black_red"]) self.render.draw(camera) [d.draw(camera) for d in self.decorations] [w.draw(camera) for w in self.walls] [s.draw(camera) for s in self.switches] [d.draw(camera) for d in self.doors] [s.draw(camera) for s in self.spikes] [p.draw(camera) for p in self.dPlatforms] [p.draw(camera) for p in self.mPlatforms] [p.draw(camera) for p in self.players] [b.draw(camera) for b in self.bosses] self.dialogue.draw() def addPlayers(self): spawn = (250, 200) player = [PlayerOne(self.screen)] player[0].rect.center = spawn return player def addBosses(self): b1Spawn = (670, 260) b1 = PigBoss(self.screen) b1.rect.center = b1Spawn bosses = [b1] return bosses def addWalls(self): wall = ZONE1_RESOURCES["walls"] pillar = ZONE1_RESOURCES["pillars"] pillarWall = [ pillar["steel_top"][0], pillar["steel_mid"][0], pillar["steel_bot"][0] ] blockWall = [ wall["block_left"][0], wall["block_mid"][0], wall["block_right"][0] ] boundaries = \ [ Wall(12, 288, 3, "v", wall["boundary_left"], self.screen), Wall(4, 52, 1, "v", wall["boundary_left"], self.screen), Wall(4, 0, 1, "h", wall["upper_corner_left"], self.screen), Wall(0, 116, 1, "h", wall["corner_top_right"], self.screen), Wall(52, 0, 6, "h", wall["boundary_top"], self.screen), Wall(432, 0, 1, "h", wall["corner_top_right"], self.screen), Wall(0, 236, 1, "v", wall["corner_bot_left"], self.screen), ] obstacles = \ [ Wall(139, 288, 2, "h", blockWall, self.screen), Wall(3411, 304, 2, "h", blockWall, self.screen), Wall(3, 167, 2, "v", pillarWall, self.screen), Wall(3359, 217, 3, "v", pillarWall, self.screen), Wall(494, 256, 1, "h", wall["block_small"], self.screen), Wall(632, 169, 1, "h", wall["block_small"], self.screen), Wall(805, 126, 1, "h", wall["block_small"], self.screen), Wall(805, 304, 1, "h", wall["block_small"], self.screen), Wall(1021, 230, 1, "h", wall["block_small"], self.screen), Wall(974, 384, 1, "h", wall["block_small"], self.screen), Wall(3347, 302, 1, "h", wall["block_small"], self.screen), Wall(1692, 116, 2, "h", wall["boundary_bot"], self.screen), Wall(1632, 168, 2, "v", wall["boundary_right"], self.screen), Wall(1780, 168, 2, "v", wall["boundary_left"], self.screen), Wall(1692, 296, 2, "h", wall["boundary_top"], self.screen), Wall(1632, 116, 1, "h", wall["corner_bot_right"], self.screen), Wall(1632, 296, 1, "h", wall["corner_top_left"], self.screen), Wall(1768, 116, 1, "h", wall["corner_bot_left"], self.screen), Wall(1776, 296, 1, "h", wall["corner_top_right"], self.screen), Wall(1936, 224, 1, "h", wall["block_small"], self.screen), Wall(2144, 373, 1, "h", wall["block_small"], self.screen), ] return boundaries + obstacles def addMPlatforms(self): vImage = ZONE1_RESOURCES["platforms"]["moving_vertical"] hImage = ZONE1_RESOURCES["platforms"]["moving_horizontal"] platforms = \ [ MPlatform((1187, 304), (1407, 325), 4, 0, self.screen, hImage), MPlatform((2309, 337), (2437, 325), 4, 0, self.screen, hImage), MPlatform((2558, 304), (2686, 325), 4, 0, self.screen, hImage), MPlatform((2696, 346), (2950, 325), 4, 0, self.screen, hImage), MPlatform((3049, 232), (3049, 406), 0, 4, self.screen, vImage), MPlatform((3144, 195), (3049, 344), 0, 4, self.screen, vImage), MPlatform((3289, 195), (3049, 330), 0, 4, self.screen, vImage), ] return platforms def addDPlatforms(self): platforms = \ [ DPlatform(1517, 126, 1, self.screen), DPlatform(1517, 216, 1, self.screen), DPlatform(1517, 305, 1, self.screen), ] return platforms def addSwitches(self): switches = \ [ Switch(822, 92, 1, self.screen), Switch(822, 263, 2, self.screen), Switch(992, 350, 3, self.screen), Switch(1296, 250, 4, self.screen), Switch(2610, 240, 5, self.screen), Switch(3138, 143, 6, self.screen), ] return switches def addDoors(self): door1 = Door(3579, 196, 1, self.screen) door1.switchesWaiting = [1, 2, 3, 4, 5, 6] return [door1] def addSpikes(self): spike = ZONE1_RESOURCES["traps"] spikes = \ [ Spike(3362, 195, 2, "h", spike["spike_up"][0], self.screen), ] return spikes def addDecorations(self): deco = ZONE1_RESOURCES["decorations"] decorations = \ [ Decoration(416, 112, deco["torch"], self.screen), # Decoration(2176, 140, deco["torch"], self.screen), Decoration(1308, 143, deco["torch"], self.screen), Decoration(2182, 143, deco["torch"], self.screen), Decoration(3486, 143, deco["torch"], self.screen), ] return decorations
class OptionsMenu(BaseMenu): """ The options menu of the game. """ def __init__(self, screen): super().__init__(screen) fontSize = 22 fontColour = "white" x, y = 230, 155 dx, dy = 0, 50 self.backgroundSetting = _SettingsLabel("Orientación: ", ["Vertical", "Horizontal"], fontSize, fontColour, x, y, 130, screen) self.fullscreenSetting = _SettingsLabel("Full Screen: ", ["Desactivar", "Activar"], fontSize, fontColour, x, y + dy, 130, screen) self.arrow = _Arrow(x - 40, y - 10, dx, dy, 2, screen) self.escapeImage = ImageLabel(MENU_RESOURCES["assets"]["esc"], 25, 440, screen) self.escapeText = TextLabel("Esc para volver", 14, fontColour, 50, 445, screen) self.effect = FadeEffect(self.screen) self.effect.timeStartDarken = float('inf') self.effect.timeEndDarken = float('inf') self.dt = 2 background = MENU_RESOURCES["screens"]["options"][0] self.render = RenderComponent(self) self.render.add("background", background) self.render.state = "background" self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("exit", SFX_RESOURCES["menu_exit"]) def __str__(self): return "options_menu" def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.effect.timeStartDarken = self.effect.time self.effect.timeEndDarken = self.effect.time + self.dt self.audio.state = "exit" if event.key == pg.K_UP: self.arrow.moveUp() if event.key == pg.K_DOWN: self.arrow.moveDown() if self.arrow.index == 0: if event.key == pg.K_RIGHT: self.backgroundSetting.next() if event.key == pg.K_LEFT: self.backgroundSetting.previous() if event.key == pg.K_RETURN: if self.backgroundSetting.index == 0: self.render.flip(True, False) if self.backgroundSetting.index == 1: self.render.flip(False, True) if self.arrow.index == 1: if event.key == pg.K_RIGHT: self.fullscreenSetting.next() if event.key == pg.K_LEFT: self.fullscreenSetting.previous() if event.key == pg.K_RETURN: if self.fullscreenSetting.index == 0: pg.display.set_mode((settings.WIDTH, settings.HEIGHT)) if self.fullscreenSetting.index == 1: pg.display.set_mode((settings.WIDTH, settings.HEIGHT), pg.FULLSCREEN) self.messageMenu("screen") self.messageScene("screen") self.messageCutScene("screen") def update(self): self.render.update() self.audio.update() self.effect.update() self.backgroundSetting.update() self.fullscreenSetting.update() self.escapeImage.update() self.escapeText.update() self.arrow.update() if self.effect.isComplete: self.messageMenu("transition", "main_menu") def draw(self, camera=None): self.render.draw(camera) self.backgroundSetting.draw() self.fullscreenSetting.draw() self.escapeImage.draw() self.escapeText.draw() self.arrow.draw() self.effect.draw()
class FadeEffect(BaseMenu): """ Responsible for applying a transitioning fade of as follows: Black screen --> Normal screen --> Black screen """ def __init__(self, screen): super().__init__(screen) self.transparentValue = 255 self.isComplete = False background = pg.Surface((settings.WIDTH, settings.HEIGHT)) background.fill(settings.COLOURS["black"]) background = background.convert() self.render = RenderComponent(self) self.render.add("background", background) self.render.state = "background" # Units are in seconds (use floats to reduce rounding errors) self.origin = pg.time.get_ticks() / 1000 self.time = 0.0 self.timeStartLighten = 1.0 self.timeEndLighten = 3.0 self.timeStartDarken = 5.0 self.timeEndDarken = 8.0 def __str__(self): return "fade_effect" def update(self): self.render.update() if not self.isComplete: self.time = pg.time.get_ticks() / 1000 - self.origin if self.timeEndLighten >= self.time >= self.timeStartLighten: self.lightenScreen() if self.timeEndDarken >= self.time >= self.timeStartDarken: self.darkenScreen() if self.time > self.timeEndDarken: self.isComplete = True def draw(self, camera=None): self.render.draw(camera) def lightenScreen(self): """ Increases the transparency of the background. """ current = self.time - self.timeStartLighten duration = self.timeEndLighten - self.timeStartLighten percentComplete = current / duration self.transparentValue = (1 - percentComplete) * 255 self.render.image.set_alpha(self.transparentValue) def darkenScreen(self): """ Reduces the transparency of the background. """ current = self.time - self.timeStartDarken duration = self.timeEndDarken - self.timeStartDarken percentComplete = current / duration self.transparentValue = percentComplete * 255 self.render.image.set_alpha(self.transparentValue)
class _Arrow(GameObject): """ An arrow that highlights the option that the user is hovering over. """ def __init__(self, x, y, dx, dy, totalOptions, screen): """ :param x: Integer, the x-position of the arrow. :param y: Integer, the y-position of the arrow. :param dx: Integer, the change in x-position per movement. :param dy: Integer, the change in y-position per moevement. :param totalOptions: Integer, the total number of options. :param screen: pygame.Surface, representing the screen. """ self.rect = pg.Rect(x, y, 0, 0) self.dx = dx self.dy = dy self.totalOptions = totalOptions self.screen = screen self.index = 0 self.render = RenderComponent(self) self.render.add("spin", MENU_RESOURCES["assets"]["coin"], 350) self.render.state = "spin" self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("move", SFX_RESOURCES["menu_arrow"]) self.audio.state = "move" def __str__(self): return "arrow" def update(self): self.render.update() self.audio.update() def draw(self, camera=None): self.render.draw(camera) def moveUp(self): """ Moves the arrow to the previous option number. """ self.audio.state = "move" self.index -= 1 self.rect.y -= self.dy if self.index < 0: self.rect.y += self.totalOptions * self.dy self.index = (self.totalOptions - 1) def moveDown(self): """ Moves the arrow to the next option number. """ self.audio.state = "move" self.index += 1 self.rect.y += self.dy if self.index > self.totalOptions - 1: self.rect.y -= self.totalOptions * self.dy self.index = 0
class JailScene02(BaseScene): LEVEL_NUM = 2 def __init__(self, screen): super().__init__(screen) self.levelNum = 2 self.players = self.addPlayers() self.walls = self.addWalls() self.dPlatforms = self.addDPlatforms() self.mPlatforms = self.addMPlatforms() self.switches = self.addSwitches() self.doors = self.addDoors() self.spikes = self.addSpikes() self.decorations = self.addDecorations() self.elapsed = 0 self.origin = pg.time.get_ticks() image = ZONE1_RESOURCES["levels"]["coop_jail_02"] self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.JAIL_COOP_2, 10, 410, "caption") def __str__(self): return "coop_jail_scene_02" def handleEvent(self, event): [p.handleEvent(event) for p in self.players] if event.type == self.SCENE_EVENT: [d.handleEvent(event) for d in self.doors] def update(self): self.elapsed = pg.time.get_ticks() - self.origin self.render.update() [d.update() for d in self.decorations] [w.update() for w in self.walls] [s.update() for s in self.switches] [d.update() for d in self.doors] [s.update() for s in self.spikes] [p.update() for p in self.mPlatforms] [p.update() for p in self.dPlatforms] [p.update() for p in self.players] self.dialogue.update() if 5000 > self.elapsed >= 0: self.dialogue.index = 0 else: self.dialogue.index = None def draw(self, camera=None): self.screen.fill(settings.COLOURS["black_red"]) self.render.draw(camera) [d.draw(camera) for d in self.decorations] [w.draw(camera) for w in self.walls] [s.draw(camera) for s in self.switches] [d.draw(camera) for d in self.doors] [s.draw(camera) for s in self.spikes] [p.draw(camera) for p in self.mPlatforms] [p.draw(camera) for p in self.dPlatforms] [p.draw(camera) for p in self.players] self.dialogue.draw() def addPlayers(self): p1Spawn = (70, 510) p2Spawn = (90, 510) p1 = PlayerOne(self.screen) p2 = PlayerTwo(self.screen) p1.rect.center = p1Spawn p2.rect.center = p2Spawn players = [p1, p2] return players def addWalls(self): wall = ZONE1_RESOURCES["walls"] platWall = [wall["plat_top"][0], wall["plat_mid"][0], wall["plat_bot"][0]] boundaries = \ [ Wall(50, 0, 8, "h", wall["boundary_top"], self.screen), Wall(0, 50, 8, "v", wall["boundary_left"], self.screen), Wall(0, 548, 15, "h", wall["boundary_bot"], self.screen), Wall(0, 548, 1, "h", wall["inner_corner_left"], self.screen), Wall(952, 50, 8, "v", wall["boundary_right"], self.screen), Wall(952, 548, 1, "h", wall["inner_corner_right"], self.screen) ] obstacles = \ [ Wall(210, 300, 1, "h", wall["block_left"], self.screen), Wall(265, 300, 1, "h", wall["block_right"], self.screen), Wall(435, 490, 1, "h", wall["block_left"], self.screen), Wall(490, 490, 1, "h", wall["block_right"], self.screen), Wall(655, 300, 1, "h", wall["block_left"], self.screen), Wall(710, 300, 1, "h", wall["block_right"], self.screen), Wall(770, 105, 2, "v", platWall, self.screen), ] return boundaries + obstacles def addDPlatforms(self): platforms = \ [ DPlatform(170, 450, 1, self.screen), DPlatform(60, 330, 0, self.screen), ] return platforms def addMPlatforms(self): vImage = ZONE1_RESOURCES["platforms"]["moving_vertical"] hImage = ZONE1_RESOURCES["platforms"]["moving_horizontal"] platforms = \ [ MPlatform((340, 100), (600, 500), 20, 20, self.screen, hImage), MPlatform((660, 350), (660, 435), 0, 0, self.screen, vImage), MPlatform((660, 435), (660, 530), 0, 0, self.screen, vImage), ] return platforms def addSwitches(self): switches = \ [ # Top Switch(250, 200, 1, self.screen), Switch(480, 200, 2, self.screen), Switch(700, 200, 3, self.screen), # Middle Switch(370, 430, 4, self.screen), Switch(480, 430, 5, self.screen), Switch(590, 430, 6, self.screen), # Corners Switch(50, 50, 7, self.screen), Switch(790, 60, 8, self.screen), ] return switches def addDoors(self): door1 = Door(865, 440, 1, self.screen) door1.switchesWaiting = [1, 2, 3, 4, 5, 6, 7, 8] return [door1] def addSpikes(self): assets = ZONE1_RESOURCES["traps"] spikes = \ [ # Floor Spike(325, 525, 5, "h", assets["spike_up"][0], self.screen), Spike(550, 525, 5, "h", assets["spike_up"][0], self.screen), # Roof Spike(300, 50, 20, "h", assets["spike_down"][0], self.screen), ] return spikes def addDecorations(self): deco = ZONE1_RESOURCES["decorations"] decorations = \ [ Decoration(778, 81, deco["skull"][0], self.screen) ] return decorations
class JailScene01(BaseScene): LEVEL_NUM = 1 def __init__(self, screen): super().__init__(screen) self.players = self.addPlayers() self.walls = self.addWalls() self.dPlatforms = self.addDPlatforms() self.switches = self.addSwitches() self.doors = self.addDoors() self.decorations = self.addDecorations() self.elapsed = 0 self.origin = pg.time.get_ticks() image = ZONE1_RESOURCES["levels"]["coop_jail_01"] self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.JAIL_COOP_1A, 10, 410, "caption") self.dialogue.add(dialogue.JAIL_COOP_1B, 10, 410, "caption") def __str__(self): return "coop_jail_scene_01" def handleEvent(self, event): [p.handleEvent(event) for p in self.players] if event.type == self.SCENE_EVENT: [d.handleEvent(event) for d in self.doors] def update(self): self.elapsed = pg.time.get_ticks() - self.origin self.render.update() [w.update() for w in self.walls] [d.update() for d in self.decorations] [d.update() for d in self.doors] [s.update() for s in self.switches] [p.update() for p in self.dPlatforms] [p.update() for p in self.players] self.dialogue.update() if 5000 > self.elapsed >= 0: self.dialogue.index = 0 elif 15000 > self.elapsed: self.dialogue.index = 1 else: self.dialogue.index = None def draw(self, camera=None): self.screen.fill(settings.COLOURS["black_red"]) self.render.draw(camera) [w.draw(camera) for w in self.walls] [d.draw(camera) for d in self.decorations] [d.draw(camera) for d in self.doors] [s.draw(camera) for s in self.switches] [p.draw(camera) for p in self.dPlatforms] [p.draw(camera) for p in self.players] self.dialogue.draw() def addPlayers(self): p1Spawn = (100, 400) p2Spawn = (150, 400) p1 = PlayerOne(self.screen) p2 = PlayerTwo(self.screen) p1.rect.center = p1Spawn p2.rect.center = p2Spawn players = [p1, p2] return players def addWalls(self): wall = ZONE1_RESOURCES["walls"] boundaries = \ [ Wall(0, 10, 8, "v", wall["boundary_left"], self.screen), Wall(19, 478, 3, "h", wall["boundary_bot"], self.screen), Wall(0, 478, 1, "h", wall["inner_corner_left"], self.screen), # Wall(170, 260, 4, "v", wall["boundary_right"], self.screen), Wall(170, 478, 1, "h", wall["inner_corner_right"], self.screen), Wall(584, 478, 1, "h", wall["boundary_bot"], self.screen), Wall(628, 138, 6, "v", wall["boundary_right"], self.screen), Wall(164, 138, 8, "h", wall["boundary_top"], self.screen), Wall(160, 138, 1, "v", wall["corner_top_left"], self.screen), Wall(160, 10, 2, "v", wall["boundary_right"], self.screen), Wall(628, 138, 1, "v", wall["upper_corner_right"], self.screen), Wall(628, 478, 1, "h", wall["inner_corner_right"], self.screen), Wall(170, 260, 1, "v", wall["plat_top"], self.screen), Wall(170, 324, 3, "v", wall["plat_mid"], self.screen), Wall(170, 470, 1, "v", wall["plat_bot"], self.screen), Wall(106, 478, 1, "v", wall["bot_ending_right"], self.screen), Wall(520, 478, 1, "v", wall["bot_ending_left"], self.screen), ] obstacles = \ [ Wall(48, 418, 1, "h", wall["block_left"], self.screen), Wall(108, 418, 1, "h", wall["block_right"], self.screen), ] return boundaries + obstacles def addDPlatforms(self): platforms = \ [ DPlatform(240, 255, 5, self.screen), DPlatform(240, 330, 4, self.screen), ] return platforms def addSwitches(self): switches = \ [ Switch(300, 205, 1, self.screen), Switch(350, 205, 2, self.screen), Switch(400, 205, 3, self.screen), Switch(450, 205, 4, self.screen), Switch(500, 205, 5, self.screen), Switch(250, 290, 5, self.screen), Switch(300, 290, 6, self.screen), Switch(350, 290, 7, self.screen), Switch(400, 290, 8, self.screen), Switch(450, 290, 9, self.screen), Switch(250, 400, 10, self.screen), ] return switches def addDoors(self): door1 = Door(547, 370, 1, self.screen) door1.switchesWaiting = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] return [door1] def addDecorations(self): deco = ZONE1_RESOURCES["decorations"] decorations = \ [ Decoration(70, 393, deco["skull"][0], self.screen), Decoration(90, 393, deco["skull"][0], self.screen), Decoration(175, 236, deco["skull"][0], self.screen), ] return decorations
class PlayerBase(GameObject, pg.sprite.Sprite): """ The controllable character to be played. """ def __init__(self, screen): """ :param screen: pygame.Surface, representing the screen. """ super().__init__() self.screen = screen self.rect = pg.Rect(0, 0, 0, 0) self.num = 0 self.lives = 5 self.isOnGround = False self.jumpSpeed = -12 self.moveSpeed = 9 self.physics = PhysicsComponent(self) self.render = RenderComponent(self, enableOrientation=True) self.audio = AudioComponent(self, isAutoPlay=False) self.audio.add("jump", SFX_RESOURCES["cat_jump"]) self.keybinds = None def update(self): self.render.update() self.audio.update() self.physics.update() # Hacky solution to fix hit box sizes without tampering with the # animation images directly (too much effort at this point) w, h = self.rect.size self.rect.size = (w-10, h) pressed = pg.key.get_pressed() left = self.keybinds["move_left"] right = self.keybinds["move_right"] if pressed[left] and not pressed[right]: self.moveLeft() if pressed[right] and not pressed[left]: self.moveRight() def handleEvent(self, event): if event.type == pg.KEYDOWN: if event.key == self.keybinds["jump"]: self.jump() if event.type == pg.KEYUP: if event.key == self.keybinds["move_left"]: self.stop() if event.key == self.keybinds["move_right"]: self.stop() def draw(self, camera=None): self.render.draw(camera) def jump(self): """ Makes the character jump. """ if self.isOnGround: self.physics.velocity.y = self.jumpSpeed self.physics.addVelocityY("jump", self.jumpSpeed) self.isOnGround = False self.audio.state = "jump" def moveLeft(self): """ Moves the character left. """ self.render.state = "running" self.render.orientation = "left" self.physics.addDisplacementX("move", -self.moveSpeed) def moveRight(self): """ Moves the character right. """ self.render.state = "running" self.render.orientation = "right" self.physics.addDisplacementX("move", self.moveSpeed) def stop(self): """ Stops the character. """ self.render.state = "idle" self.physics.velocity.x = 0
class JailScene03(BaseScene): LEVEL_NUM = 3 def __init__(self, screen): super().__init__(screen) self.players = self.addPlayers() self.walls = self.addWalls() self.mPlatforms = self.addMPlatforms() self.switches = self.addSwitches() self.doors = self.addDoors() self.spikes = self.addSpikes() self.elapsed = 0 self.origin = pg.time.get_ticks() image = ZONE1_RESOURCES["levels"]["solo_jail_03"][0] self.render = RenderComponent(self) self.render.add("idle", image) self.render.state = "idle" self.dialogue = Dialogue(self.screen) self.dialogue.add(dialogue.JAIL_SOLO_3, 10, 410, "caption") def __str__(self): return "solo_jail_scene_03" def handleEvent(self, event): [p.handleEvent(event) for p in self.players] if event.type == self.SCENE_EVENT: [d.handleEvent(event) for d in self.doors] def update(self): self.elapsed = pg.time.get_ticks() - self.origin self.render.update() [w.update() for w in self.walls] [s.update() for s in self.switches] [d.update() for d in self.doors] [s.update() for s in self.spikes] [p.update() for p in self.mPlatforms] [p.update() for p in self.players] self.dialogue.update() if 5000 > self.elapsed >= 0: self.dialogue.index = 0 else: self.dialogue.index = None def draw(self, camera=None): self.screen.fill(settings.COLOURS["black_red"]) self.render.draw(camera) [w.draw(camera) for w in self.walls] [s.draw(camera) for s in self.switches] [d.draw(camera) for d in self.doors] [s.draw(camera) for s in self.spikes] [p.draw(camera) for p in self.mPlatforms] [p.draw(camera) for p in self.players] self.dialogue.draw() def addPlayers(self): spawn = (315, 128) player = [PlayerOne(self.screen)] player[0].rect.center = spawn return player def addWalls(self): wall = ZONE1_RESOURCES["walls"] pillar = ZONE1_RESOURCES["pillars"] pillarWall = [ pillar["steel_top"][0], pillar["steel_mid"][0], pillar["steel_bot"][0] ] platWall = [ wall["plat_top"][0], wall["plat_mid"][0], wall["plat_bot"][0] ] blockWall = [ wall["block_left"][0], wall["block_mid"][0], wall["block_right"][0] ] boundaries = \ [ Wall(739, 0, 5, "h", wall["boundary_top"], self.screen), Wall(99, 0, 5, "h", wall["boundary_top"], self.screen), Wall(0, 64, 7, "v", wall["boundary_left"], self.screen), Wall(1102, 60, 7, "v", wall["boundary_right"], self.screen), Wall(587, 367, 2, "v", wall["boundary_left"], self.screen), Wall(507, 367, 2, "v", wall["boundary_right"], self.screen), ] obstacles = \ [ Wall(363, 48, 6, "v", pillarWall, self.screen), Wall(738, 48, 6, "v", pillarWall, self.screen), Wall(167, 182, 2, "h", blockWall, self.screen), Wall(735, 182, 2, "h", blockWall, self.screen), Wall(543, 198, 1, "h", wall["block_small"], self.screen), Wall(575, 363, 1, "v", wall["corner_bot_left"], self.screen), Wall(507, 363, 1, "h", wall["corner_bot_right"], self.screen), Wall(375, 423, 1, "v", platWall, self.screen), Wall(703, 423, 1, "v", platWall, self.screen), ] return boundaries + obstacles def addMPlatforms(self): vImage = ZONE1_RESOURCES["platforms"]["moving_vertical"][0] hImage = ZONE1_RESOURCES["platforms"]["moving_horizontal"][0] platforms = \ [ MPlatform((83, 250), (240, 400), 0, 3, self.screen, vImage), MPlatform((1035, 250), (250, 400), 0, 3, self.screen, vImage), MPlatform((215, 325), (310, 325), 3, 0, self.screen, hImage), MPlatform((849, 372), (950, 372), 3, 0, self.screen, hImage), MPlatform((420, 279), (700, 685), 3, 0, self.screen, hImage), ] return platforms def addSwitches(self): switches = \ [ Switch(565, 146, 1, self.screen), Switch(565, 305, 2, self.screen), ] return switches def addDoors(self): door1 = Door(795, 74, 1, self.screen) door1.switchesWaiting = [1, 2] return [door1] def addSpikes(self): assets = ZONE1_RESOURCES["traps"] spikes = \ [ Spike(415, 190, 2, "v", assets["spike_left"][0], self.screen), Spike(711, 190, 2, "v", assets["spike_right"][0], self.screen), Spike(45, 590, 16, "h", assets["spike_up"][0], self.screen), Spike(765, 590, 16, "h", assets["spike_up"][0], self.screen), ] return spikes