def __init__(self, centerx, lowy, *groups, game, Text, triggerposition): """ Default Constructor Keyword Arguments: - centerx: The horizontal center of the text - lowy: The low side of the text, relative to position of the player. - *groups: A collection of sprite groups to add the item to. - game: The game istance. - Text: The text that has to be written on the help tip. Returns: - Nothing """ """self.font = pygame.font.Font(pjoin("resources", "fonts", "TranscendsGames.otf"), 24)""" self.surfimg = animatedText(Text) self.triggerposition = triggerposition self.img = self.surfimg.surface self.size = self.img.get_rect() self.x = centerx - (self.size.width/2) self.y = lowy - (self.size.height*game.gravity) MobilePlatform.__init__(self, self.x, self.y, *groups, game=game, surface=self.img) game.helptxts.add(self) self.age = 300
def RealLoadLevel(self, path, mode, screen): """ Loads a level structure, given path, mode and screen Keyword Arguments: - path: Full path to the level - mode: Mode to open the level in - screen: The screen instance """ self.mod_logger.info("LoadLevel Routine is loading %(path)s" % locals()) # Erases level and if we're doing a campaign, checks for intermissions # v--------------------------------------------------v self.eraseCurrentLevel() self.showLoadingScreen() if mode not in ["singlemap"]: self.checkIntermission() # ^--------------------------------------------------^ self.showLoadingScreen() # Loads the level configuration and its chaos parameters # v--------------------------------------------------v with open(path+".json") as f: levelconfig = json.loads(f.read()) self.mod_logger.debug("Level configuration loaded") self.loadChaosParameters(levelconfig) # ^--------------------------------------------------^ # If we're in the single timer Critical Failure, load the level time # And reset the time to 0. # v--------------------------------------------------v if mode == "cfsingle": self.gameStatus["cftime"] = levelconfig["Level Info"]["CFTime"] self.gameStatus["time"] = 0. # ^--------------------------------------------------^ # Loads the level glitches # v--------------------------------------------------v self.glitches = levelconfig["Glitches"]["Standard"] self.mod_logger.debug("Glitches Active: {0}".format(self.glitches)) # ^--------------------------------------------------------------^ # Loads the level map # v--------------------------------------------------------------v self.mod_logger.debug("Loading Tilemap") self.tilemap = tmx.load(path+".tmx", self.screensize) self.mod_logger.debug("Tilemap Loaded, building map") # ^--------------------------------------------------------------^ # Loads backgrounds and overlays, optimised in case # the same ones are used # v--------------------------------------------------------------v self.mod_logger.debug("Loading Backgrounds") self.oldComponentPaths = self.componentPaths.copy() for key in self.componentPaths.keys(): self.componentPaths[key] = pjoin("resources", "backgrounds", levelconfig["Level Components"] [key]) if self.componentPaths[key] != self.oldComponentPaths[key]: self.components[key] = pygame.image.load( self.componentPaths[key]).convert_alpha() self.hasOverlay = levelconfig["Level Components"]["overlay"]\ is not None if self.hasOverlay: self.overpath = pjoin("resources", "overlays", levelconfig["Level Components"] ["overlay"]) if self.overpath != self.oldoverpath: self.overlay = pygame.image.load(self.overpath).convert_alpha() # ^--------------------------------------------------------------^ # Creates all the mobile obstacles # v--------------------------------------------------------------v self.obstacles = tmx.SpriteLayer() for obstacle in self.tilemap.layers['Triggers'].find('Obstacle'): Obstacle((obstacle.px, obstacle.py), ("v" in obstacle['Obstacle']), obstacle['ObsSpeed'], None, self.obstacles, preloaded_ani=self.preloaded_sprites["glitches"]) self.tilemap.layers.append(self.obstacles) # ^--------------------------------------------------------------^ # Creates all the triggerable platforms # v--------------------------------------------------------------v for platform in self.tilemap.layers['Triggers'].find('Platform'): bouncy = "bouncyplat" in platform bouncepwr = int(platform['bouncyplat']) if bouncy else 0 TriggerablePlatform( platform.px, platform.py, ("v" in platform['Platform']), bouncepwr, int(platform['PlatSpeed']), int(platform['PlatSize']), False, platform['id'], self.plats, game=self, bouncy=bouncy, image=self.preloaded_sprites["platforms"]) self.tilemap.layers.append(self.plats) # Creates all the lasers # v--------------------------------------------------------------v self.lasers = tmx.SpriteLayer() for laser in self.tilemap.layers['Triggers'].find('Laser'): time = laser['Laser'] number = 0 if 'id' in laser: number = laser['id'] size = (laser.width, laser.height) vertical = size[1] > size[0] definingsize = size[1] if vertical else size[0] Laser(definingsize, vertical, time, number, (laser.px, laser.py), self.lasers) self.tilemap.layers.append(self.lasers) # ^--------------------------------------------------------------^ # Creates all the buttons # v--------------------------------------------------------------v self.btns = tmx.SpriteLayer() for btn in self.tilemap.layers['Triggers'].find('button'): ident = btn['button'] password = None msg="" if "password" in btn: password = btn["password"] if "message" in btn: msg = btn["message"] button((btn.px, btn.py), ident, password, self.btns, message=msg) self.tilemap.layers.append(self.btns) # ^--------------------------------------------------------------^ # Creates all the checkpoints # v--------------------------------------------------------------v self.checkpoints = tmx.SpriteLayer() for chk in self.tilemap.layers["Triggers"].find('CheckPoint'): checkPoint((chk.px, chk.py), self.checkpoints) self.tilemap.layers.append(self.checkpoints) # ^--------------------------------------------------------------^ # Creates all the glitch toggles # v--------------------------------------------------------------v for trig in self.tilemap.layers['Triggers'].find('ToggleGlitch'): if "message" in trig: msg = trig["message"] else: msg = "" self.GlitchTriggers.add(CollectibleTrigger( trig.px, trig.py, self, trig['ToggleGlitch'], preloaded_animation=self.preloaded_sprites[ "collectibleitem" ], message=msg)) self.tilemap.layers.append(self.GlitchTriggers) # ^--------------------------------------------------------------^ # In case of critical failure modes, further garbles # level title texts, then renders the title # v--------------------------------------------------------------v if self.gameStatus["mode"] in ["criticalfailure", "cfsingle"]: self.titletxt = makeMoreGlitched( str(levelconfig['Level Info']['Name']), 50) else: self.titletxt = str(levelconfig['Level Info']['Name']) self.title = makeGlitched(self.titletxt, self.font) # ^--------------------------------------------------------------^ # Finds the center position of the title # v--------------------------------------------------------------v center = (self.screensize[0] - int(self.title.get_rect().width))/2 self.titleposition = (center, self.gsize[1] + 2) # ^--------------------------------------------------------------^ self.mod_logger.info("Map Loaded and built Successfully") # ^--------------------------------------------------------------^ if self.config["General"]["autosaving"] and self.SaveFile: self.mod_logger.debug("Saved with data: {0}" % self.gameStatus) with open(self.SaveFile, "w") as savefile: savefile.write(json.dumps(self.gameStatus)) """self.mod_logger.info("Game autosaved on the file: {0}" % (self.SaveFile))""" message = levelconfig["Message"] if message != "": self.showMessage = True self.messageSurf = animatedText(message)
def update(self, dt, game): """ Updates the status of the player Keyword Arguments: - dt: The time slice (clock.tick()) - game: The Game instance. Returns: - Nothing """ # self.fixCollision(game.gravity) last = self.collisionrect.copy() # Copy last position for compare self.last = last key = pygame.key.get_pressed() # Check if run button is pressed (With eventual Invertedrun glitch) # v--------------------------------------------------------------v if game.glitches["invertedRun"]: self.status["running"] = not bool(key[self.keys["run"]]) else: self.status["running"] = bool(key[self.keys["run"]]) # ^--------------------------------------------------------------^ if self.status["running"]: self.runmultiplier = self._runpower_ else: self.runmultiplier = 1 # Check if Left/Right buttons are pressed # (W/ eventual Invertedcontrols glitch) # v--------------------------------------------------------------v if game.glitches["invertedControls"]: self.left = key[self.keys["right"]] self.right = key[self.keys["left"]] else: self.left = key[self.keys["left"]] self.right = key[self.keys["right"]] # ^--------------------------------------------------------------^ if self.left and not game.glitches["noLeft"]: self.direction = -1 # Mainly for different bounce mechanics """if not self.status["bounced"]: # Not bounced away->control in air # Why do i have different control in air if i'm running? # This might lead to a change of speed in air # Do i want this? # v--------------------------------------------------------v""" if self.status["bounced"]: accel = self.calc_accel(self.x_speed, self.runmultiplier, self.direction, dt) self.x_speed += accel else: if self.x_speed > 0: # Inertia code self.x_speed = max(-self.playermaxspeed * dt * self.runmultiplier, self.x_speed-self.playerdecel*dt * self.runmultiplier) else: self.x_speed = max(-self.playermaxspeed * dt * self.runmultiplier, self.x_speed-self.playeraccel*dt * self.runmultiplier) # Anti-x-jittering Patch # v--------------v if abs(self.x_speed) < 1: self.x_speed = -1 # ^--------------^ # ^--------------------------------------------------------^ elif self.right and not game.glitches["noRight"]: self.direction = 1 # Used mainly for bouncy mechanics if self.status["bounced"]: accel = self.calc_accel(self.x_speed, self.runmultiplier, self.direction, dt) self.x_speed += accel else: if self.x_speed < 0: # Inertia code self.x_speed = min(self.playermaxspeed * dt * self.runmultiplier, self.x_speed+self.playerdecel * dt * self.runmultiplier) else: self.x_speed = min(self.playermaxspeed * dt * self.runmultiplier, self.x_speed+self.playeraccel * dt * self.runmultiplier) # Anti-x-jittering Patch # v--------------v if abs(self.x_speed) < 1: self.x_speed = 1 # ^--------------^ else: # Gives the player some control over the fall if they're not # bounced away from a spring # TODO: Find some better way to let player keep control # TODO: Tie direction and movement in a formula instead of conds # v--------------------------------------------------------------v if game.glitches["noStop"]: if self.x_speed != 0: self.x_speed = self.playermaxspeed *\ self.direction * self.runmultiplier * dt else: if not self.status["bounced"]: # Player deceleration if self.direction == 1: self.x_speed = max(0, self.x_speed-(self.playerdecel*dt)) elif self.direction == -1: self.x_speed = min(0, self.x_speed+(self.playerdecel*dt)) # ^--------------------------------------------------------------^ self.collisionrect.x += self.x_speed # Move the player self.fixCollision(game.gravity) if game.glitches["multiJump"]: if key[self.keys["jump"]] and not game.glitches["noJump"]: # Plays the jump sound only with a player descending, to avoid # a sound spam if self.y_speed*game.gravity >= 0: self.jumpsound.play() # In case of "gravity glitch", inverts gravity if game.glitches["gravity"]: game.gravity *= -1 else: # If the high jump glitch is active, jumps twice as high # This happens while the multijump glitch is active # v------------------------------------------------------v if self.y_speed*game.gravity > -(self._jump_speed_/2.5) or\ self.status["resting"]: self.y_speed = self._jump_speed_ * \ self.jumpMultiplier * game.gravity if game.config["Video"]["playerparticles"]: self.emitJumpParticles() # ^------------------------------------------------------^ elif game.glitches["hover"]: if key[self.keys["jump"]] and not game.glitches["noJump"]: # Makes the player fly in case of the hover glitch # v------------------------------------------------------v if self.status["resting"]: self.jumpsound.play() self.y_speed = self._jump_speed_\ * game.gravity*self._hovermodifier_ if game.config["Video"]["playerparticles"]: self.emitJumpParticles() # ^------------------------------------------------------^ else: if key[self.keys["jump"]] and self.status["resting"] and\ not game.glitches["noJump"]: # Takes care of the jumping, or gravity inversion self.jumpsound.play() if game.glitches["gravity"]: game.gravity *= -1 else: # If the high jump glitch is active, jumps twice as high # v------------------------------------------------------v self.y_speed = self._jump_speed_ * \ self.jumpMultiplier * game.gravity if game.config["Video"]["playerparticles"]: self.emitJumpParticles() # ^------------------------------------------------------^ self.status["resting"] = False # I jumped->not on surface # Takes care of the gravity and falling # v------------------------------------------------------v if game.gravity == 1: self.y_speed = min(self.maxFallSpeed, self.y_speed + self.fallAccel) else: self.y_speed = max(-self.maxFallSpeed, self.y_speed - self.fallAccel) # ^------------------------------------------------------^ # Takes care of player movement and ledgewalk glitch # v------------------------------------------------------v # Anti-y-jittering Patch # v--------------v self.y_to_apply = self.y_speed * dt if abs(self.y_to_apply) < 1: self.y_to_apply = 1 * game.gravity # ^--------------^ if game.glitches['ledgeWalk']: if not self.status["resting"]: self.collisionrect.y += self.y_to_apply else: self.collisionrect.y += self.y_to_apply # ^------------------------------------------------------^ # self.RealignCollision(game.gravity) self.fixCollision(game.gravity) # This avoids the ability to jump in air after leaving a platform # + ledgejump glitch framework # v--------------v if not game.glitches["ledgeJump"] and not game.glitches["ledgeWalk"]: self.status["resting"] = False # ^--------------^ # Test for collision with scrolling ground # v--------------------------------------------------------------v for cell in game.tilemap.layers['Triggers'].collide(self.collisionrect, 'slide'): top = last.bottom <= cell.top and\ self.collisionrect.bottom > cell.top bottom = last.top >= cell.bottom and\ self.collisionrect.top < cell.bottom if (game.gravity == 1 and top) or\ (game.gravity == -1 and bottom): slide = int(cell['slide']) if game.glitches["slideInvert"]: if key[self.keys["action"]]: slide *= -1 self.collisionrect.x += slide * dt self.fixCollision(game.gravity) # ^--------------------------------------------------------------^ # Test for collision with deadbody platforms and act accordingly # v--------------------------------------------------------------v collision = pygame.sprite.spritecollide(self, game.deadbodies, False) for block in collision: if game.gravity == 1: if last.bottom <= block.rect.top and\ self.collisionrect.bottom > block.rect.top: self.collisionrect.bottom = block.rect.top self.y_speed = 0 self.status["resting"] = True else: if last.top >= block.rect.bottom and\ self.collisionrect.top < block.rect.bottom: self.collisionrect.top = block.rect.bottom self.status["resting"] = True self.y_speed = 0 self.fixCollision(game.gravity) # ^--------------------------------------------------------------^ # Moving plats collision check # NOTE: This has to stay here to avoid being tped under a platform # if you touch a vertical wall # v--------------------------------------------------------------v collision = pygame.sprite.spritecollide(self, game.plats, False) for block in collision: if block.active: top = last.bottom <= block.last.top and\ self.collisionrect.bottom > block.rect.top bottom = last.top >= block.last.bottom and\ self.collisionrect.top < block.rect.bottom if top or bottom: if top: self.collisionrect.bottom = block.rect.top elif bottom: self.collisionrect.top = block.rect.bottom if block.bouncy: self.y_speed = - block.bouncepwr * game.gravity self.bouncesound.play() else: self.y_speed = block.yspeed * game.gravity if (game.gravity == 1 and top) or\ (game.gravity == -1 and bottom): self.status["resting"] = True if block.moving: self.collisionrect.x += block.xspeed * dt * block.direction self.fixCollision(game.gravity) # Wraps player movement if the glitch is active # v--------------------------------------------------------------v if game.glitches["vWrapping"]: if self.rect.y < 0: last.y = game.tilemap.px_height self.rect.y = game.tilemap.px_height self.rect.x = last.x elif self.rect.y > game.tilemap.px_height: last.y = 0 self.rect.y = 0 self.rect.x = last.x self.RealignCollision(game.gravity) else: if self.rect.y < 0 or self.rect.y > game.tilemap.px_height: self.respawn(game) # ^--------------------------------------------------------------^ # self.collisionrect.midbottom = self.rect.midbottom # Test for collision with solid surfaces and act accordingly # v--------------------------------------------------------------v # self.fixCollision(game.gravity) # self.RealignCollision(game.gravity) self.status["pushing"] = False for cell in game.tilemap.layers['Triggers'].collide(self.collisionrect, 'blocker'): blockers = cell['blocker'] if 't' in blockers and last.bottom <= cell.top and\ self.collisionrect.bottom > cell.top: self.status["bounced"] = False # Corrects position only if you're not clipping via glitch # v----------------------------------------------------v if game.glitches["clipOnCommand"]: if not key[self.keys["action"]]: self.collisionrect.bottom = cell.top else: self.collisionrect.bottom = cell.top # ^----------------------------------------------------^ # Puts resting status if feet are colliding, else looks for a # stickyceil glitch and acts as a consequence # v----------------------------------------------------v if game.gravity == 1: self.status["resting"] = True self.y_speed = 0 else: if game.glitches["stickyCeil"] and\ not key[self.keys["action"]]: self.y_speed = 5/dt else: self.y_speed = 0 # ^----------------------------------------------------^ elif 'b' in blockers and last.top >= cell.bottom and\ self.collisionrect.top < cell.bottom: # Part of the clip-on-command glitch Framework self.status["bounced"] = False # Corrects position only if you're not clipping via glitch # v----------------------------------------------------v if game.glitches["clipOnCommand"]: if not key[self.keys["action"]]: self.collisionrect.top = cell.bottom else: self.collisionrect.top = cell.bottom # ^----------------------------------------------------^ # Puts resting status if feet are colliding, else looks for a # stickyceil glitch and acts as a consequence # v----------------------------------------------------v if game.gravity == -1: self.status["resting"] = True self.y_speed = 0 else: if game.glitches["stickyCeil"] and\ not key[self.keys["action"]]: self.y_speed = -5/dt else: self.y_speed = 0 # ^----------------------------------------------------^ elif 'l' in blockers and last.right <= cell.left and\ self.collisionrect.right > cell.left: self.status["bounced"] = False self.collisionrect.right = cell.left self.status["pushing"] = True self.x_speed = 0 if game.glitches["wallClimb"]: self.y_speed = -200 * game.gravity elif 'r' in blockers and last.left >= cell.right and\ self.collisionrect.left < cell.right: self.status["bounced"] = False self.collisionrect.left = cell.right self.status["pushing"] = True self.x_speed = 0 if game.glitches["wallClimb"]: self.y_speed = -200 * game.gravity self.fixCollision(game.gravity) # ^--------------------------------------------------------------^ # Test for collision with bouncy platforms and act accordingly # v--------------------------------------------------------------v for cell in game.tilemap.layers["Triggers"].collide(self.collisionrect, 'bouncy'): bouncy = cell["bouncy"] power = int(cell["power"]) if 't' in bouncy and last.bottom <= cell.top and\ self.collisionrect.bottom > cell.top: self.collisionrect.bottom = cell.top if not (key[self.keys["action"]] and game.glitches["stopBounce"]): self.bouncesound.play() self.y_speed = - power * 1.7 if 'b' in bouncy and last.top >= cell.bottom and\ self.collisionrect.top < cell.bottom: self.collisionrect.top = cell.bottom if not (key[self.keys["action"]] and game.glitches["stopBounce"]): self.bouncesound.play() self.y_speed = power * 1.7 if 'l' in bouncy and last.right <= cell.left and\ self.collisionrect.right > cell.left: self.collisionrect.right = cell.left if not (key[self.keys["action"]] and game.glitches["stopBounce"]): self.bouncesound.play() self.status["bounced"] = True self.x_speed = -power*dt*1.7 directioner = -1 if (self.y_speed <= 0) else 1 self.y_speed = game.gravity*power*directioner*1.7 if 'r' in bouncy and last.left >= cell.right and\ self.collisionrect.left < cell.right: self.collisionrect.left = cell.right if not (key[self.keys["action"]] and game.glitches["stopBounce"]): self.bouncesound.play() self.status["bounced"] = True self.x_speed = power*dt*1.7 directioner = -1 if (self.y_speed <= 0) else 1 self.y_speed = game.gravity*power*directioner*1.7 self.fixCollision(game.gravity) # ^--------------------------------------------------------------^ # Test for collisions with deadly ground and act accordingly # v--------------------------------------------------------------v for cell in game.tilemap.layers["Triggers"].collide(self.collisionrect, 'deadly'): deadly = cell["deadly"] if 't' in deadly and last.bottom <= cell.top and\ self.collisionrect.bottom > cell.top: self.rect.bottom = cell.top self.respawn(game) if 'b' in deadly and last.top >= cell.bottom and\ self.collisionrect.top < cell.bottom: self.rect.top = cell.bottom self.respawn(game) if 'l' in deadly and last.right <= cell.left and\ self.collisionrect.right > cell.left: self.rect.right = cell.left self.respawn(game) if 'r' in deadly and last.left >= cell.right and\ self.collisionrect.left < cell.right: self.rect.left = cell.right self.respawn(game) # ^--------------------------------------------------------------^ # If help writings are solid, test for collision and act as platforms # v--------------------------------------------------------------v if game.glitches['solidHelp']: collision = pygame.sprite.spritecollide(self, game.helptxts, False) for block in collision: if self.y_speed == 0: self.status["resting"] = True elif self.y_speed > 0 and game.gravity == 1: self.collisionrect.bottom = block.rect.top self.status["resting"] = True self.y_speed = 0 elif self.y_speed < 0 and game.gravity == -1: self.collisionrect.top = block.rect.bottom self.status["resting"] = True self.y_speed = 0 # ^--------------------------------------------------------------^ # Test collision with help triggers and act accordingly # v--------------------------------------------------------------v for cell in game.tilemap.layers['Triggers'].collide(self.collisionrect, 'Help'): if key[self.keys["action"]]: if "password" in cell: pw = cell["password"] else: pw = None passed = False if pw: guess = textInput(game.screen, game.font, "Password required").get_input() if guess == pw: passed = True else: passed = True if passed: helptext = cell['Help'] if (cell.px, cell.py) not in game.activeHelpList: self.mod_logger.debug( "HelpSign active at: {} , {}".format(cell.px, cell.py)) game.activeHelpList.append((cell.px, cell.py)) # game.helpflagActive = False # game.currenthelp = helptext x, y = game.tilemap.pixel_from_screen( cell.px+cell.width/2, cell.py-20) Help(x, y, game.sprites, game=game, Text=helptext, triggerposition=(cell.px, cell.py)) # ^--------------------------------------------------------------^ # Test collision with exit trigger and act accordingly # v--------------------------------------------------------------v for cell in game.tilemap.layers['Triggers'].collide(self.collisionrect, 'playerExit'): if key[self.keys["action"]]: level = cell["playerExit"] if "password" in cell: pw = cell["password"] else: pw = None passed = False if pw: guess = textInput(game.screen, game.font, "Password required").get_input() if guess == pw: passed = True else: passed = True if passed: if game.gameStatus["mode"] not in ["singlemap"]: game.LoadLevel(level, game.gameStatus["campaignName"], game.gameStatus["mode"], game.screen) if level: game.loadLevelPart2(game.keys, self.soundslink) else: game.running = False # ^--------------------------------------------------------------^ game.tilemap.set_focus(self.rect.x, self.rect.y) # Sets screen focus if game.glitches["hWrapping"]: # This piece of code should avoid phasing through the floor # v-----------------------------v if self.rect.x < -16: self.rect.x = game.tilemap.px_width - (self.rect.width / 2) self.rect.y -= 3 * game.gravity self.RealignCollision(game.gravity) elif self.rect.x > game.tilemap.px_width - 16: self.rect.x = -15 self.rect.y -= 3 * game.gravity self.RealignCollision(game.gravity) # ^-----------------------------^ # Handles the triggering of mobile platforms # v--------------------------------------------------------------v """for cell in game.tilemap.layers['Triggers'].collide(self.collisionrect, "button"): if key[self.keys["action"]]: butt = cell['button'] if "password" in cell: pw = cell["password"] else: pw = None passed = False if pw: guess = textInput(game.screen, game.font, "Password required").get_input() if guess == pw: passed = True else: passed = True if passed: for plat in game.plats: if plat.id == butt: plat.active = True plat.image = plat.activeimg self.mod_logger.info("Player pressed the button \ with ID: %(butt)s" % locals())""" if key[self.keys["action"]]: for item in pygame.sprite.spritecollide(self, game.btns, False): passed = False if item.password: guess = textInput(game.screen, game.font, "Password required").get_input() if guess == item.password: passed = True else: passed = True if passed: for plat in game.plats: if plat.id == item.id: plat.active = True plat.image = plat.activeimg item.activate() for laser in game.lasers: if laser.id == item.id: laser.triggertime = 0 laser.active = False laser.update = laser.update_static laser.image = laser.inactiveimage item.activate() if item.message != "": self.game.showMessage = True self.game.messageSurf = animatedText(item.message) item.message = "" self.mod_logger.info("Player pressed the button \ with ID: {0}".format(item.id)) # Checkpoint Handling for item in pygame.sprite.spritecollide(self, game.checkpoints, False): if not item.used: self.lastcheckpoint = (self.rect.x, self.rect.y) item.activate() self.mod_logger.info("Checkpoint Saved") # ^--------------------------------------------------------------^ # Handles the triggering of teleporters # v--------------------------------------------------------------v for cell in game.tilemap.layers['Triggers'].collide(self.collisionrect, "TpIn"): if key[self.keys["action"]]: tpin = cell['TpIn'] self.mod_logger.info("Player entered the TP with ID: %(tpin)s" % locals()) for out in game.tilemap.layers['Triggers'].find("TpOut"): tpout = out['TpOut'] if tpout == tpin: self.collisionrect.x = out.px self.collisionrect.y = out.py self.fixCollision(game.gravity) # ^--------------------------------------------------------------^ # Handles the Glitched Area animations # v--------------------------------------------------------------v self.status["glitched"] = False if game.tilemap.layers['Triggers'].collide( self.rect, "GlitchedAnimation") != []: self.status["glitched"] = True # ^--------------------------------------------------------------^ # Handles The checkpoints # v--------------------------------------------------------------v """for cell in game.tilemap.layers['Triggers'].collide( self.collisionrect, 'CheckPoint'): chk = cell['CheckPoint'] if chk == 1: self.lastcheckpoint = (self.rect.x, self.rect.y) cell['CheckPoint'] = 0 self.mod_logger.info("Checkpoint Saved")""" # ^--------------------------------------------------------------^ # Handles The Glitch Triggers # v--------------------------------------------------------------v collision = pygame.sprite.spritecollide(self, game.GlitchTriggers, False) for block in collision: block.toggle(self.game) if block.message != "": self.game.showMessage = True self.game.messageSurf = animatedText(block.message) block.kill() # ^--------------------------------------------------------------^ # Handles the glitchiness in Critical Failure mode # v--------------------------------------------------------------v if game.gameStatus["mode"] in ["criticalfailure", "cfsingle"]: redcoll = game.tilemap.pixel_to_screen(self.rect.x, self.rect.y) self.status["glitched"] = redcoll[1] < game.redsurfrect.bottom # ^--------------------------------------------------------------^ # Handles the player plaform-like behaviour in case the ObsResistant # glitch is active, or its death # v--------------------------------------------------------------v collision = pygame.sprite.spritecollide(self, game.obstacles, False) secondpass = [block for block in collision if block.rect.colliderect(self.collisionrect)] for block in secondpass: if game.glitches["obsResistant"]: if self.y_speed * game.gravity > 0: if game.gravity == 1 and self.collisionrect.bottom > block.rect.top: self.collisionrect.bottom = block.rect.top if block.vertical: self.y_speed = block.speed self.status["resting"] = True # Allows jump elif game.gravity == -1 and\ self.collisionrect.top < block.rect.bottom: self.collisionrect.top = block.rect.bottom if block.vertical: self.y_speed = - block.speed self.status["resting"] = True # Allows jump if not block.vertical: self.rect.x += block.speed * dt * block.direction else: self.respawn(game) self.fixCollision(game.gravity) # Handles touching lasers # v--------------------------------------------------------------v collision = pygame.sprite.spritecollide(self, game.lasers, False) secondpass = [laser for laser in collision if laser.active] for block in secondpass: if game.glitches["laserresistant"]: if block.vertical: if self.x_speed > 0 and \ self.collisionrect.right > block.rect.left: self.collisionrect.right = block.rect.left self.x_speed = 0 self.status["pushing"] = True elif self.x_speed < 0 and \ self.collisionrect.left < block.rect.right: self.collisionrect.left = block.rect.right self.x_speed = 0 self.status["pushing"] = True else: # FIXME: Screen trembles when on lasers if self.y_speed * game.gravity >= 0: if game.gravity == 1 and\ self.collisionrect.bottom > block.rect.top: self.collisionrect.bottom = block.rect.top self.y_speed = 0 self.status["resting"] = True # Allows jump elif game.gravity == -1 and\ self.collisionrect.top < block.rect.bottom: self.collisionrect.top = block.rect.bottom self.y_speed = 0 self.status["resting"] = True # Allows jump else: self.respawn(game) # MUST BE LAST OPERATION # v--------------------------------------------------------------v self.animate(self.y_speed, self.x_speed, self.status["resting"], self.status["bounced"], self.direction, dt, game.gravity, self.status["running"], self.status["pushing"], self.status["glitched"], game)