class Light(GameObject): def __init__(self,x,y,w,h,properties,game): self.spritePath = './Assets/Objects/light.png' self.game = game self.spriteBaseSize = 16 self.topoffset = 5 self.xoffset = 5 self.setProperties(properties) self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x,self.y,self.w,self.h) self.sprite = SpriteSheet(pygame.image.load(self.spritePath)) self.off = self.sprite.getimage(0,0,self.spriteBaseSize,self.spriteBaseSize) self.on_green = self.sprite.getimage(32,0,self.spriteBaseSize,self.spriteBaseSize) self.on_blue = self.sprite.getimage(16,0,self.spriteBaseSize,self.spriteBaseSize) self.on_red = self.sprite.getimage(48,0,self.spriteBaseSize,self.spriteBaseSize) self.color = None if self.have('color'): self.color = self.get('color') self.enabled = True if self.have('enabled'): self.enabled = bool(self.get('enabled')) self.collide = True self.collectable = True self.isActivated = False self.inContactWithPlayer = False def draw(self, display,camera): if self.isActivated: if self.color != None and self.color == 'blue': display.blit(pygame.transform.scale(self.on_blue, (self.w, self.h)), (self.x+camera.x, self.y+camera.y)) elif self.color != None and self.color == 'red': display.blit(pygame.transform.scale(self.on_red, (self.w, self.h)), (self.x+camera.x, self.y+camera.y)) else: display.blit(pygame.transform.scale(self.on_green, (self.w, self.h)), (self.x+camera.x, self.y+camera.y)) else: display.blit(pygame.transform.scale(self.off, (self.w, self.h)), (self.x+camera.x, self.y+camera.y)) def update(self, keys): pass def collisionEvent(self): self.inContactWithPlayer = True def activationEvent(self): pass def deactivationEvent(self): pass
class Spike(Enemy): def __init__(self, x, y, w, h, props, game): self.x, self.y, self.w, self.h = x, y, w, h self.cs = (-8, -12) self.co = (4, 12) self.spritePath = './Assets/Enemies/spike.png' self.props = props self.game = game self.spriteBaseSize = 16 self.hurtAmount = 1 self.sprite = SpriteSheet(pygame.image.load(self.spritePath)) self.spike = self.sprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize) if props != None: if props == 'T': self.spike = self.sprite.getimage(16, 0, self.spriteBaseSize, self.spriteBaseSize) elif props == 'L': self.spike = self.sprite.getimage(32, 0, self.spriteBaseSize, self.spriteBaseSize) elif props == 'R': self.spike = self.sprite.getimage(48, 0, self.spriteBaseSize, self.spriteBaseSize) def draw(self, display, camera): display.blit(pygame.transform.scale(self.spike, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): pass def hurt(self): pass
class WaterSurface(GameObject): def __init__(self, x, y, w, h, properties, game): self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.setProperties(properties) self.spritePath = './Assets/Objects/water_surface_blue.png' self.spritePathBorder = './Assets/Objects/water_surface.png' if self.have('color'): color = self.get('color') self.spritePath = self.spritePath.replace('blue', color) self.game = game self.spriteBaseSize = 16 self.topoffset = 5 self.xoffset = 5 self.collide = True self.collectable = True self.collisionExecuted = False # IDLE Graphics self.idleSprite = SpriteSheet(pygame.image.load(self.spritePath)) self.idleAnimation = SpriteAnimation(8, 10, True) self.idleState = [ self.idleSprite.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.idleAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.idleAnimation) self.idleSpriteBorder = SpriteSheet( pygame.image.load(self.spritePathBorder)) self.idleAnimationBorder = SpriteAnimation(8, 10, True) self.idleStateBorder = [ self.idleSpriteBorder.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.idleAnimationBorder.framesQuantity) ] self.game.animationSystem.addAnimation(self.idleAnimationBorder) def draw(self, display, camera): display.blit( pygame.transform.scale( self.idleStateBorder[self.idleAnimationBorder.get()], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) display.blit(pygame.transform.scale( self.idleState[self.idleAnimation.get()], (self.w, self.h)), (self.x + camera.x, self.y + camera.y), area=None, special_flags=pygame.BLEND_RGB_MULT) def update(self, keys): pass def collisionEvent(self): if not self.collisionExecuted: self.collisionExecuted = True
class Display(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePath = './Assets/Objects/display.png' self.game = game self.topoffset = 5 self.xoffset = 5 self.setProperties(properties) self.x, self.y, self.w, self.h = x, y, w, h self.startQTBoundaries(self.x, self.y, self.w, self.h) self.sprite = SpriteSheet(pygame.image.load(self.spritePath)) self.value = '' self.prefix = '' self.sufix = '' self.size = 2 if self.have('size'): self.size = int(self.get('size')) if self.have('value'): self.value = self.get('value') if self.have('prefix'): self.prefix = self.get('prefix') if self.have('sufix'): self.sufix = self.get('sufix') self.collide = False self.collectable = True self.activationDelay = 20 self.activationDelayMax = 20 self.display_single = self.sprite.getimage(0, 0, 16, 16) self.display_double = self.sprite.getimage(16, 0, 32, 16) self.display_triple = self.sprite.getimage(48, 0, 48, 16) def draw(self, display, camera): if self.size == 1: display.blit(pygame.transform.scale(self.display_single, (32, 32)), (self.x + camera.x, self.y + camera.y)) elif self.size == 2: display.blit(pygame.transform.scale(self.display_double, (64, 32)), (self.x + camera.x, self.y + camera.y)) elif self.size == 3: display.blit( pygame.transform.scale(self.display_triple, (128, 32)), (self.x + camera.x, self.y + camera.y)) xOff = 0 if self.size == 1: xOff = 16 if self.size == 2: xOff = 32 if self.size == 3: xOff = 64 # value valueSurface2 = self.game.uiSystem.displayFont.render( str(self.prefix) + str(self.value) + str(self.sufix), True, (50, 50, 50)) display.blit( valueSurface2, (self.x + camera.x + xOff - (valueSurface2.get_width() / 2) + 1, self.y + camera.y + 5 + 1)) def update(self, keys): pass
class Effect(object): def __init__(self,x,y,w,h,path,loop,frameQuantity,frameSpeed): self.x = x self.y = y self.w = w self.h = h self.life = frameQuantity*frameSpeed self.loop = loop self.frameQuantity = frameQuantity self.frameSpeed = frameSpeed self.sprite = SpriteSheet(pygame.image.load(path)) self.animation = SpriteAnimation(frameQuantity,frameSpeed,loop) self.effect = [self.sprite.getimage(x * self.w,0,self.w,self.h) for x in range(frameQuantity)] def update(self,effectSystem): self.animation.update() if not self.loop: self.life -= 1 if self.life <= 0: effectSystem.effects.remove(self) def draw(self,display,camera): #self.effect[self.animation.get()] display.blit( pygame.transform.scale( self.effect[self.animation.get()],(self.w*2,self.h*2) ) ,(self.x+camera.x, self.y + camera.y))
class Vine(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePath = './Assets/Objects/vine.png' self.game = game self.setProperties(properties) self.spriteBaseSize = 16 self.topoffset = 18 self.xoffset = 19 self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.collide = True self.collectable = True self.collected = False self.collisionExecuted = False # IDLE Graphics self.idleSprite = SpriteSheet(pygame.image.load(self.spritePath)) self.idleState = [ self.idleSprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize) ] def draw(self, display, camera): display.blit( pygame.transform.scale(self.idleState[0], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): pass def collisionEvent(self): self.game.player.isOnVine = True
class PistolShot(PlayerShot): def __init__(self, x, y, w, h, props, game): self.x, self.y, self.w, self.h = x, y, w, h self.setProperties(props) self.imagePath = './Assets/Player/pistol_shot.png' self.game = game self.spriteBaseSize = 8 self.hurtAmount = 1 self.velocity = Vector2(0, 0) self.angle = 0 self.life = 60 self.sprite = SpriteSheet(pygame.image.load(self.imagePath)) self.bullet = self.sprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize) def update(self): self.x += self.velocity.x self.y += self.velocity.y self.life -= 1 def draw(self, display, camera): display.blit( pygame.transform.rotate( pygame.transform.scale(self.bullet, (self.w * 2, self.h * 2)), self.angle), (self.x + camera.x, self.y + camera.y))
class Computer(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePath = './Assets/Objects/computer.png' self.game = game self.spriteBaseSize = 16 self.topoffset = 5 self.xoffset = 0 self.setProperties(properties) self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.collide = True self.collectable = True self.collected = False self.collisionExecuted = False self.inContactWithPlayer = False self.activationDelay = 20 self.activationDelayMax = 20 self.idleSprite = SpriteSheet(pygame.image.load(self.spritePath)) self.idleAnimation = SpriteAnimation(4, 30, True) self.idleState = [ self.idleSprite.getimage(32 * x, 0, 32, self.spriteBaseSize) for x in range(self.idleAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.idleAnimation) def draw(self, display, camera): display.blit( pygame.transform.scale(self.idleState[self.idleAnimation.get()], (64, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): self.activationDelay -= 1 if self.activationDelay < 0: self.activationDelay = 0 if self.inContactWithPlayer and self.activationDelay == 0 and keys[ pygame.K_e]: self.isActivated = True self.activationDelay = self.activationDelayMax self.activationEvent() self.inContactWithPlayer = False def collisionEvent(self): self.inContactWithPlayer = True def activationEvent(self): if self.properties != None: self.game.audioSystem.playSFX('computer') # process dialogs dialogs = self.getMany('dialog') if len(dialogs) > 0: for x in range(len(dialogs)): self.game.uiSystem.addDialog(dialogs[x])
def __init__(self, x, y, w, h): self.x, self.y, self.w, self.h = x, y, w, h self.delay = 2 # Animation self.currDelay = 0 # Horizontal Movement self.speed = 0 self.maxSpeed = 5 self.acc = 0.4 # Vertical Movement self.maxG = 100 self.currG = 0 self.gAcc = 0.5 self.isOnGround = False self.jumpVel = 0 self.jumpMax = 13.5 # Collision Stuff self.last_y = y self.gs = 0 # Sprites self.state = "IDLE_RIGHT" self.pastState = "RUN_RIGHT" self.idle_state = 0 self.idle_length = 11 player_idle = SpriteSheet(pygame.image.load("./Assets/Player/player_idle.png")) self.idle = [player_idle.getimage(32*x, 0, 32, 32) for x in range(self.idle_length)] for x in range(len(self.idle)): self.idle[x] = pygame.transform.scale(self.idle[x], (64, 64)) self.run_state = 0 self.run_length = 12 player_run = SpriteSheet(pygame.image.load("./Assets/Player/player_run.png")) self.run = [player_run.getimage(32 * x, 0, 32, 32) for x in range(self.run_length)] for x in range(len(self.run)): self.run[x] = pygame.transform.scale(self.run[x], (64, 64)) self.player_jump = pygame.transform.scale(pygame.image.load("./Assets/Player/player_jump.png"), (64, 64)) self.player_fall = pygame.transform.scale(pygame.image.load("./Assets/Player/player_fall.png"), (64, 64))
class Hearth(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePath = './Assets/Objects/hearth.png' self.game = game self.spriteBaseSize = 16 self.topoffset = 5 self.xoffset = 5 self.setProperties(properties) self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.collide = True self.collectable = True self.collected = False self.collisionExecuted = False # IDLE Graphics self.idleSprite = SpriteSheet(pygame.image.load(self.spritePath)) self.idleAnimation = SpriteAnimation(4, 10, True) self.idleState = [ self.idleSprite.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.idleAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.idleAnimation) def draw(self, display, camera): display.blit( pygame.transform.scale(self.idleState[self.idleAnimation.get()], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): pass def collisionEvent(self): if not self.collisionExecuted: self.game.player.health += 1 if self.get('once'): self.game.objectsOnce.append([ self.game.currentRoom, int(self.x / self.w), int(self.y / self.h) ]) if self.game.player.health > self.game.player.maxHealth: self.game.player.health = self.game.player.maxHealth self.game.objects.remove(self) self.game.removeQuadTreeItem(self) self.game.effectsSystem.generateEffect('COLLECTED', self.x, self.y) self.game.audioSystem.playSFX('hearth') self.collisionExecuted = True
def __init__(self, x, y, w, h, image): self.x, self.y, self.w, self.h, self.image = x, y, 64, 64, image # These are smaller so we make them 64x64 self.collide = True self.collectable = True self.collected = False self.topoffset = 18 self.xoffset = 19 self.idle_length = 17 kiwi_idle = SpriteSheet(pygame.image.load("./Assets/Collectables/kiwi.png")) self.idle = [kiwi_idle.getimage(32 * x, 0, 32, 32) for x in range(self.idle_length)] self.idle_state = 0 self.delay = 2 self.currDelay = 0 self.death_length = 6 kiwi_death = SpriteSheet(pygame.image.load("./Assets/Collectables/collected.png")) self.death = [kiwi_death.getimage(32 * x, 0, 32, 32) for x in range(self.death_length)] self.death_state = 0 self.d_delay = 2 self.d_currDelay = 0
class Gate(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePath = './Assets/Objects/gate.png' self.setProperties(properties) self.game = game self.spriteBaseSize = 16 self.topoffset = 5 self.xoffset = 5 self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.collide = True self.collectable = False self.collected = False self.collisionExecuted = False # IDLE Graphics self.idleSprite = SpriteSheet(pygame.image.load(self.spritePath)) self.idleState = [ self.idleSprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize) ] def draw(self, display, camera): display.blit( pygame.transform.scale(self.idleState[0], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): pass def collisionEvent(self): if not self.collisionExecuted: if self.get('once'): self.game.objectsOnce.append([ self.game.currentRoom, int(self.x / self.w), int(self.y / self.h) ]) self.collisionExecuted = True self.game.audioSystem.playSFX('slime_dead')
class GeneralSwitch(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePath = './Assets/Objects/general_switch.png' self.game = game self.spriteBaseSize = 16 self.topoffset = 5 self.xoffset = 5 self.setProperties(properties) if self.have('skin'): if int(self.get('skin')) == 2: self.spritePath = './Assets/Objects/general_switch_2.png' if int(self.get('skin')) == 3: self.spritePath = './Assets/Objects/general_switch_3.png' self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.sprite = SpriteSheet(pygame.image.load(self.spritePath)) self.off = self.sprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize) self.on_green = self.sprite.getimage(32, 0, self.spriteBaseSize, self.spriteBaseSize) self.on_blue = self.sprite.getimage(16, 0, self.spriteBaseSize, self.spriteBaseSize) self.on_red = self.sprite.getimage(48, 0, self.spriteBaseSize, self.spriteBaseSize) self.hasUpdated = False self.color = None if self.have('color'): self.color = self.get('color') self.enabled = True if self.have('enabled'): self.enabled = bool(self.get('enabled')) self.collide = True self.collectable = True self.isActivated = False self.activationDelay = 20 self.activationDelayMax = 20 self.inContactWithPlayer = False def draw(self, display, camera): if self.isActivated: if self.color != None and self.color == 'blue': display.blit( pygame.transform.scale(self.on_blue, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) elif self.color != None and self.color == 'red': display.blit( pygame.transform.scale(self.on_red, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) else: display.blit( pygame.transform.scale(self.on_green, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) else: display.blit(pygame.transform.scale(self.off, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): self.activationDelay -= 1 if self.activationDelay < 0: self.activationDelay = 0 if self.enabled: if self.inContactWithPlayer and self.activationDelay == 0 and keys[ pygame.K_e]: if not self.isActivated: self.isActivated = True self.activationDelay = self.activationDelayMax self.activationEvent() else: self.isActivated = False self.activationDelay = self.activationDelayMax self.deactivationEvent() self.inContactWithPlayer = False def collisionEvent(self): self.inContactWithPlayer = True def activationEvent(self): self.hasUpdated = True def deactivationEvent(self): self.hasUpdated = True
class Player: def __init__(self, x, y, w, h): self.x, self.y, self.w, self.h = x, y, w, h self.delay = 10 # Animation self.currDelay = 0 self.scale = (32,32) self.ecs = (-20,-12) self.eco = (10,0) self.game = None # Itens and Status self.keys = 0 self.coins = 0 self.health = 2 self.maxHealth = 4 self.lives = 3 self.hurtTimer = 0 self.hurtMaxTimer = 180 # Horizontal Movement self.speed = 0 self.maxSpeed = 5 self.acc = 0.4 # Vertical Movement self.maxG = 20 self.maxGWater = 14 self.currG = 0 self.gAcc = 0.5 self.gAccWater = 0.3 self.accY = 0.0 self.vineSpeed = 3 self.isOnGround = False self.isOnVine = False self.isOnPlatform = False self.currentPlatform = None self.flipFlop = False self.jumpVel = 0 self.jumpMax = 11 # Player Skils self.canDoubleJump = False self.hasDoubleJumped = False self.isOnWater = False # Player Weapon self.usingWeapon = False self.hasDoneUsingWeapon = False # Collision Stuff self.last_y = y self.gs = 0 # Sprites self.state = "IDLE_RIGHT" self.pastState = "RUN_RIGHT" self.orientation = "RIGHT" self.idle_state = 0 self.idle_length = 6 self.player_idle = SpriteSheet(pygame.image.load("./Assets/Player/player_idle.png")) self.idle = [self.player_idle.getimage(32*x, 0, 32, 32) for x in range(self.idle_length)] for x in range(len(self.idle)): self.idle[x] = pygame.transform.scale(self.idle[x], self.scale) self.run_state = 0 self.run_length = 6 self.player_run = SpriteSheet(pygame.image.load("./Assets/Player/player_run.png")) self.run = [self.player_run.getimage(32 * x, 0, 32, 32) for x in range(self.run_length)] for x in range(len(self.run)): self.run[x] = pygame.transform.scale(self.run[x], self.scale) self.player_jump = pygame.transform.scale(pygame.image.load("./Assets/Player/player_jump.png"), self.scale) self.player_fall = pygame.transform.scale(pygame.image.load("./Assets/Player/player_fall.png"), self.scale) def draw(self, display,camera): if self.hurtTimer != 0: if self.hurtTimer % 5 == 0: self.flipFlop = not self.flipFlop if self.hurtTimer == 0 or (self.hurtTimer > 0 and self.flipFlop): if not self.isOnGround and self.jumpVel > self.currG: if self.pastState == "RUN_RIGHT": display.blit(self.player_jump, (self.x+camera.x, self.y+camera.y)) else: display.blit(pygame.transform.flip(self.player_jump, 1, 0), (self.x+camera.x, self.y+camera.y)) elif not self.isOnGround: if self.pastState == "RUN_RIGHT": display.blit(self.player_fall, (self.x+camera.x, self.y+camera.y)) else: display.blit(pygame.transform.flip(self.player_fall, 1, 0), (self.x+camera.x, self.y+camera.y)) elif self.state == "IDLE_RIGHT": display.blit(self.idle[self.idle_state % self.idle_length], (self.x+camera.x, self.y+camera.y)) if self.currDelay == self.delay: self.idle_state += 1 self.currDelay = 0 else: self.currDelay += 1 elif self.state == "IDLE_LEFT": display.blit(pygame.transform.flip(self.idle[self.idle_state % self.idle_length], 1, 0), (self.x+camera.x, self.y+camera.y)) if self.currDelay == self.delay: self.idle_state += 1 self.currDelay = 0 else: self.currDelay += 1 elif self.state == "RUN_RIGHT": display.blit(self.run[self.run_state % self.run_length], (self.x+camera.x, self.y+camera.y)) if self.currDelay == self.delay: self.run_state += 1 self.currDelay = 0 else: self.currDelay += 1 elif self.state == "RUN_LEFT": display.blit(pygame.transform.flip(self.run[self.run_state % self.run_length], 1, 0), (self.x+camera.x, self.y+camera.y)) if self.currDelay == self.delay: self.run_state += 1 self.currDelay = 0 else: self.currDelay += 1 # Collision Stuff self.last_y = self.y if self.gs != 0: self.isOnGround = True self.hasDoubleJumped = False else: self.isOnGround = False self.gs = 0 def update(self, keys): # Horizontal Movement stall = self.x if keys[pygame.K_d] and keys[pygame.K_a]: self.speed = 0 else: if keys[pygame.K_d]: if self.speed <= self.maxSpeed: self.speed += self.acc self.x += self.speed self.state = "RUN_RIGHT" self.pastState = "RUN_RIGHT" self.orientation = "RIGHT" elif keys[pygame.K_a]: if self.speed <= self.maxSpeed: self.speed += self.acc self.x -= self.speed self.state = "RUN_LEFT" self.pastState = "RUN_LEFT" self.orientation = "LEFT" else: if self.pastState == "RUN_RIGHT" or self.pastState == "JUMP_RIGHT": self.state = "IDLE_RIGHT" elif self.pastState == "RUN_LEFT" or self.pastState == "JUMP_LEFT": self.state = "IDLE_LEFT" if stall == self.x: self.speed = 0 if not self.isOnVine: # Jumping if self.isOnGround and (keys[pygame.K_SPACE] or keys[pygame.K_w]): self.jumpVel = self.jumpMax self.isOnGround = False if self.isOnGround: self.jumpVel = 0 if not self.isOnGround and self.jumpVel > self.currG: self.state = "JUMP" self.y -= self.jumpVel if self.canDoubleJump and not self.hasDoubleJumped and self.accY < 0 and (keys[pygame.K_SPACE] or keys[pygame.K_w]): self.currG = 0 self.hasDoubleJumped = True else: # Vine Movement if keys[pygame.K_w]: self.y -= self.vineSpeed elif keys[pygame.K_s]: self.y += self.vineSpeed # Gravity, only apply if # player is not on vine if not self.isOnVine: if not self.isOnGround: if self.isOnWater: if self.currG <= self.maxGWater: self.currG += self.gAccWater self.y += self.currG else: if self.currG <= self.maxG: self.currG += self.gAcc self.y += self.currG else: self.currG = 0 # Reset Back isOnVine self.isOnVine = False # Reset is on Water self.isOnWater = False self.accY = self.last_y-self.y self.hurtTimer -= 1 if self.hurtTimer <= 0 : self.hurtTimer = 0 def hurt(self, enemy,game): if self.hurtTimer == 0: self.health -= enemy.hurtAmount self.game.audioSystem.playSFX('player_hurt') if self.health == 0 and self.lives > 0: self.health = self.maxHealth self.lives -= 1 game.saveSystem.loadCheckpoint(game) if self.lives == 0 and self.health == 0: game.saveSystem.loadGame(game) self.hurtTimer = self.hurtMaxTimer if self.health < 0 : self.health = 0 def enemyContact(self, enemy, game): if self.accY < 0: enemy.hurt() else: if hasattr(enemy,'state') and enemy.state != 'KILL': self.hurt(enemy,game) elif isinstance(enemy, Spike): self.hurt(enemy,game)
class Door(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePathOpen = './Assets/Objects/door_open.png' self.spritePathClosed = './Assets/Objects/door_close.png' self.spritePathOpenCoin = './Assets/Objects/door_open_coin.png' self.spritePathClosedCoin = './Assets/Objects/door_close_coin.png' self.spritePathOpenEnemy = './Assets/Objects/door_open_enemies.png' self.spritePathClosedEnemy = './Assets/Objects/door_close_enemies.png' self.game = game self.spriteBaseSize = 16 self.topoffset = 18 self.xoffset = 19 self.setProperties(properties) self.enemyDoor = self.have('enemy') self.coinDoor = self.have('coin') self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.collide = True self.collectable = True self.collected = False self.collisionExecuted = False self.opened = True if self.enemyDoor: self.openSprite = SpriteSheet( pygame.image.load(self.spritePathOpenEnemy)) self.closeSprite = SpriteSheet( pygame.image.load(self.spritePathClosedEnemy)) elif self.coinDoor: self.openSprite = SpriteSheet( pygame.image.load(self.spritePathOpenCoin)) self.closeSprite = SpriteSheet( pygame.image.load(self.spritePathClosedCoin)) else: self.openSprite = SpriteSheet( pygame.image.load(self.spritePathOpen)) self.closeSprite = SpriteSheet( pygame.image.load(self.spritePathClosed)) self.openAnimation = SpriteAnimation(10, 5, False) self.openState = [ self.openSprite.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.openAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.openAnimation) def draw(self, display, camera): if self.opened: display.blit( pygame.transform.scale( self.openState[self.openAnimation.get()], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) else: display.blit( pygame.transform.scale( self.closeSprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize), (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): if self.coinDoor: if self.game.countCoins() != 0: self.opened = False else: self.opened = True elif self.enemyDoor: if self.game.countEnemies() != 0: self.opened = False else: self.opened = True else: self.opened = True def collisionEvent(self): if self.opened: if self.properties != None: map = self.get('map') x = self.get('x') y = self.get('y') self.game.audioSystem.playSFX('boss_dead') self.game.loadLevel(map, self.game.objects, self.game.enemies, self.game.objectsTopLayer, self.game.objectsWaterLayer, (int(x) * 32, int(y) * 32), False)
class Checkpoint(GameObject): def __init__(self, x, y, w, h, properties, game): self.spritePath = './Assets/Objects/checkpoint.png' self.game = game self.spriteBaseSize = 16 self.topoffset = 5 self.xoffset = 5 self.setProperties(properties) self.x, self.y, self.w, self.h = x, y, 32, 32 self.startQTBoundaries(self.x, self.y, self.w, self.h) self.isSaveGame = False self.sprite = SpriteSheet(pygame.image.load(self.spritePath)) self.off = self.sprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize) self.on = self.sprite.getimage(16, 0, self.spriteBaseSize, self.spriteBaseSize) self.onSave = self.sprite.getimage(32, 0, self.spriteBaseSize, self.spriteBaseSize) self.name = None if self.have('name'): self.name = self.get('name') if self.have('save'): self.isSaveGame = True self.collide = True self.collectable = True self.isActivated = False self.actionExecuted = False self.inContactWithPlayer = False def draw(self, display, camera): if self.isActivated: if not self.isSaveGame: display.blit(pygame.transform.scale(self.on, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) else: display.blit( pygame.transform.scale(self.onSave, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) else: display.blit(pygame.transform.scale(self.off, (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): if self.name != None: if self.name in self.game.activatedCheckpoints: self.actionExecuted = True self.isActivated = True def collisionEvent(self): self.inContactWithPlayer = True if not self.actionExecuted: self.actionExecuted = True self.game.audioSystem.playSFX('computer') self.activationEvent() def activationEvent(self): self.isActivated = True if not self.isSaveGame: self.game.saveSystem.saveCheckpoint(self, self.game) else: self.game.saveSystem.saveGame(self, self.game) def deactivationEvent(self): pass
class Bat(Enemy): def __init__(self, x, y, w, h, props, game): Enemy.__init__(self, x, y, w, h, props, game) self.x, self.y, self.w, self.h = x, y, w, h self.setProperties(props) self.spritePathPrefix = './Assets/Enemies/' self.game = game self.spriteBaseSize = 16 self.hurtAmount = 1 self.cs = (0, 0) self.co = (0, 0) self.activationDistance = 250 self.originalPosition = Vector2(self.x, self.y) self.interpolatorCount = 0 self.hurtCount = 60 self.maxHurtCount = 60 self.state = 'IDLE' self.drop = None self.dropAdded = False self.setupSprite() def setupSprite(self): # IDLE self.idleSprite = SpriteSheet( pygame.image.load(self.spritePathPrefix + 'bat_idle.png')) self.idleAnimation = SpriteAnimation(4, 30, True) self.idleState = [ self.idleSprite.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.idleAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.idleAnimation) # WALK self.walkSprite = SpriteSheet( pygame.image.load(self.spritePathPrefix + 'bat_walk.png')) self.walkAnimation = SpriteAnimation(4, 10, True) self.walkState = [ self.walkSprite.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.walkAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.walkAnimation) def draw(self, display, camera): if self.velocity.length() != 0.0: display.blit( pygame.transform.scale( self.walkState[self.walkAnimation.get()], (self.w, self.h)), (self.position.x + camera.x, self.position.y + camera.y)) else: display.blit( pygame.transform.scale( self.idleState[self.idleAnimation.get()], (self.w, self.h)), (self.position.x + camera.x, self.position.y + camera.y)) def update(self, keys): playerPosition = Vector2(self.game.player.x, self.game.player.y) enemyPosition = Vector2(self.position.x, self.position.y) direction = playerPosition - enemyPosition distance = direction.length() if distance < self.activationDistance: self.acceleration = direction self.interpolatorCount = 0 self.state = 'ATTACK' else: self.state = 'IDLE' self.interpolatorCount += 0.01 if self.interpolatorCount > 1: self.interpolatorCount = 1 self.velocity.x = 0 self.velocity.y = 0 currentPosition = Vector2(self.x, self.y) toHome = currentPosition.lerp(self.originalPosition, self.interpolatorCount) self.position = toHome Enemy.update(self, keys) self.x = self.position.x self.y = self.position.y self.hurtCount -= 1 if self.hurtCount < 0: self.hurtCount = 0 def hurt(self): if self.hurtCount == 0: self.state = 'KILL' self.game.audioSystem.playSFX('bat_dead') self.hurtCount = self.maxHurtCount self.game.effectsSystem.generateEffect('BAT_KILL', self.x, self.y - 20, 0, 16) self.game.enemies.remove(self) if self.drop != None and not self.dropAdded: self.game.queueSystem.addItem(self.drop) self.dropAdded = True elif self.drop == None and not self.dropAdded: drop = self.game.enemySystem.enemyDefaultDrop(self) if drop != None: self.game.queueSystem.addItem(drop) self.dropAdded = True
class InventoryItem: def __init__(self, name, quantity, image): self.name = name self.quantity = quantity self.spriteSize = 16 self.imageFile = image self.image = SpriteSheet(image) def getDrawable(self): if self.name == 'no_item': return self.image.getimage(0, 0, self.spriteSize, self.spriteSize) if self.name == 'health_kit': return self.image.getimage(16, 0, self.spriteSize, self.spriteSize) if self.name == 'red_key': return self.image.getimage(32, 0, self.spriteSize, self.spriteSize) if self.name == 'blue_key': return self.image.getimage(48, 0, self.spriteSize, self.spriteSize) if self.name == 'green_key': return self.image.getimage(64, 0, self.spriteSize, self.spriteSize) if self.name == 'pistol': return self.image.getimage(80, 0, self.spriteSize, self.spriteSize) def isDisplayQuantity(self): if self.name == 'no_item': return False if self.name == 'health_kit': return True if self.name == 'red_key': return False if self.name == 'blue_key': return False if self.name == 'green_key': return False if self.name == 'pistol': return False def isRemoveOnUse(self): if self.name == 'no_item': return False if self.name == 'health_kit': return True if self.name == 'red_key': return False if self.name == 'blue_key': return False if self.name == 'green_key': return False if self.name == 'pistol': return False def canUse(self, game): if self.name == 'health_kit' and game.player.health < game.player.maxHealth: return True if self.name == 'pistol': return True return False def useItem(self, game): if self.name != 'no_item': if self.name == 'health_kit': game.playerSystem.useHealthKit(game) if self.name == 'pistol': game.playerSystem.usePistol(game)
class Slime(Enemy): def __init__(self, x, y, w, h, props, game): self.x, self.y, self.w, self.h = x, y, w, h self.cs = (-8, -12) self.co = (4, 12) self.killAnimationTime = 30 self.spritePathPrefix = './Assets/Enemies/' self.setProperties(props) self.game = game self.spriteBaseSize = 16 self.hurtAmount = 1 self.mathUtil = MathFunctions() self.velX = 0 self.velY = 0 self.state = "NORMAL" self.movSpeed = 0.003 self.startXPosition = self.x / 32 self.startYPosition = self.y / 32 self.endXPosition = self.x / 32 self.endYPosition = self.y / 32 if self.have('x'): self.endXPosition = int(self.get('x')) if self.have('y'): self.endYPosition = int(self.get('y')) self.movement = [ self.startXPosition, self.startYPosition, self.endXPosition, self.endYPosition ] self.movementTimer = 0 self.drop = None self.dropAdded = False if self.have('drop'): attr = self.get('drop').split('|') self.drop = QueueItem(attr[0], attr[1] + ':' + attr[2]) # Idle State self.idleSprite = SpriteSheet( pygame.image.load(self.spritePathPrefix + 'slime_idle.png')) self.idleAnimation = SpriteAnimation(5, 10, True) self.idleState = [ self.idleSprite.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.idleAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.idleAnimation) # Walk State self.walkSprite = SpriteSheet( pygame.image.load(self.spritePathPrefix + 'slime_walk.png')) self.walkAnimation = SpriteAnimation(2, 20, True) self.walkState = [ self.walkSprite.getimage(self.spriteBaseSize * x, 0, self.spriteBaseSize, self.spriteBaseSize) for x in range(self.walkAnimation.framesQuantity) ] self.game.animationSystem.addAnimation(self.walkAnimation) # Kill State self.killSprite = SpriteSheet( pygame.image.load(self.spritePathPrefix + 'slime_kill.png')) self.killState = [ self.killSprite.getimage(0, 0, self.spriteBaseSize, self.spriteBaseSize) ] def draw(self, display, camera): if self.state != 'KILL': if self.velX == 0 and self.velY == 0: display.blit( pygame.transform.scale( self.idleState[self.idleAnimation.get()], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) elif self.velX < 0: if self.state != 'ATTACK': display.blit( pygame.transform.scale( self.walkState[self.walkAnimation.get()], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) else: display.blit( pygame.transform.scale( self.attackState[self.attackAnimation.get()], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) elif self.velX > 0: if self.state != 'ATTACK': display.blit( pygame.transform.flip( pygame.transform.scale( self.walkState[self.walkAnimation.get()], (self.w, self.h)), 1, 0), (self.x + camera.x, self.y + camera.y)) else: display.blit( pygame.transform.flip( pygame.transform.scale( self.attackState[self.attackAnimation.get()], (self.w, self.h)), 1, 0), (self.x + camera.x, self.y + camera.y)) else: display.blit( pygame.transform.scale(self.killState[0], (self.w, self.h)), (self.x + camera.x, self.y + camera.y)) def update(self, keys): calcX = self.x calcY = self.y if self.state != 'KILL' and self.movement != None: mov = self.movement xPos = self.mathUtil.sawTooth(mov[0] * self.w, mov[2] * self.w, self.movementTimer) self.movementTimer += self.movSpeed if self.movementTimer > 1: self.movementTimer = 0 self.x = xPos if self.state == 'KILL' and self.killAnimationTime > 0: self.killAnimationTime -= 1 if self.killAnimationTime <= 0: self.game.enemies.remove(self) self.velX = self.x - calcX self.velY = self.y - calcY def hurt(self): self.state = 'KILL' self.game.audioSystem.playSFX('slime_dead') self.game.effectsSystem.generateEffect('COLLECTED', self.x, self.y, 0, 16) if self.drop != None and not self.dropAdded: self.game.queueSystem.addItem(self.drop) self.dropAdded = True elif self.drop == None and not self.dropAdded: drop = self.game.enemySystem.enemyDefaultDrop(self) if drop != None: self.game.queueSystem.addItem(drop) self.dropAdded = True