from gamedata.objects.ingame.movable import Movable from gamedata.objects.transition import Transition from gamedata.objects.ingame.pause import Pause class Player(Movable): def __init__(self,game): super().__init__(game,0,0) spawnpoint = game.lib.choice(self.tileset.spawns) self.rect.move_ip(spawnpoint.center) self.sprites = game.getSpriteDir("player/walking/") # Walking animation self.spritestill = game.sprite_lib["player/still.png"] # Standing still self.spritejumping = game.sprite_lib["player/jumping.png"] # Ascending self.spritefalling = game.sprite_lib["player/falling.png"] # Descending self.spritehurt = game.sprite_lib["player/hurt.png"] # Being hurted self.spritelanding = game.sprite_lib["player/landing.png"] self.ouch = game.getchars("Ouch !") self.bubble = game.getSpriteDir("particles/bubble/") self.bubbletimer = game.lib.Timer(0.3) self.landingtimer = 0 self.maxlandtime = 0.15 self.spriteindex = 0 self.flipx = False self.animationspeed = 2.5 self.canmove = True self.hp = 2 self.dead = False self.spikes = self.tileset.spikes self.deathtimer = self.game.lib.Timer(0.5) self.deadsfx = self.game.sound_lib["sfx/dead.wav"] self.retrytext = self.game.getchars("Try again !") self.maxwidth,self.maxheight = self.tileset.layers[0]["surface"].get_size() if abs(self.maxheight-234)<16: self.maxheight = self.game.globals["camerah"] if abs(self.maxwidth-416)<16: self.maxwidth= self.game.globals["cameraw"] self.sprite = self.spritestill collisionratio = 0.7 self.rect[2] = self.sprite.get_width()*collisionratio self.rect[3] = self.sprite.get_height() self.spriteoffset = self.sprite.get_width()*(1-collisionratio)/2 self.water = self.game.gameloop.findname("Water")[0] self.lowerhitrect = self.rect.copy() self.lowerhitrect[2] = round(self.rect[2]*0.5) self.lowerhitrect[3] = round(self.rect[3]*0.2) self.upperhitrect = self.lowerhitrect.copy() self.upperhitrect[3] = round(self.rect[3]*0.4) self.upperhitrectwidth=round(self.rect[2]) self.hitrects = [self.lowerhitrect,self.upperhitrect] self.canhit = False self.dustparticles = game.getSpriteDir("particles/dust/") self.splashparticles = game.getSpriteDir("particles/splash/") self.speed = 200 self.playerid = 0 self.teamid = self.playerid self.damage = 0 self.horkb = 0 self.verkb = 0 self.reducekb = 15 self.gravity = 15 self.maxgravity = 30 self.jump = -5 self.verspd = self.maxgravity self.candash = False self.canfastfall = False self.fastfall = 0 # Small leap in order to get out of the water self.leaptimer = 1 self.leapmaxtimer = 0.5 self.leapmargin = 30 # Vertical margin for the leap self.gravityway = 1 self.combo = 0 self.combosprites = self.game.getSpriteDir("player/combo/") self.combosfxs = self.game.getSpriteDir("sfx/combo/",ext=".wav",assetdir="sound_lib") self.combodefault = self.game.sound_lib["sfx/combo/default.wav"] self.combotimer = 1 # SFXs self.landsfx = self.game.sound_lib["sfx/land.wav"] self.slamsfx = self.game.sound_lib["sfx/slam.wav"] self.jumpsfx = self.game.sound_lib["sfx/jump.wav"] self.hurtsfx = self.game.sound_lib["sfx/hurt.wav"] def step(self): if not self.dead: if self.water and self.rect.center[1]>self.water.rect.y: # Reverse gravity underwater if self.gravityway == 1: self.gravityway = -1 # Décellerer self.verspd *= 0.85 # Spawn splash particles self.game.addParticle(self.splashparticles,self.rect.left-5,self.water.rect.top-5,fps=12) self.game.addParticle(self.splashparticles,self.rect.right+5,self.water.rect.top-5,flipx=True,fps=12) else: if self.gravityway == -1: self.gravityway = 1 # Décellerer self.verspd *= 0.85 # Spawn splash particles self.game.addParticle(self.splashparticles,self.rect.left-5,self.water.rect.top-5,fps=12) self.game.addParticle(self.splashparticles,self.rect.right+5,self.water.rect.top-5,flipx=True,fps=12) if self.water and self.water.rect.y-self.leapmargin<=self.rect.y<=self.water.rect.y+self.leapmargin: self.leaptimer-=self.game.dt # Inside the margin else: self.leaptimer = self.leapmaxtimer # Outside, reset the timer if self.leaptimer<0: self.canfastfall = True canmove = (abs(self.verkb)+1)*(abs(self.horkb)+1)<2 keys = self.game.inputs["keys"] self.horspd = 0 if canmove: if self.canmove: self.horspd=(keys["right"]["counted"]-keys["left"]["counted"])*self.game.dt*self.speed self.game.globals["timer"]+=self.game.dt if self.game.inputs["keys"]["escape"]["timer"]==1: self.game.globals["pause"] = True p = Pause(self.game) self.game.gameloop.summon(p) if self.landingtimer<=0: self.sprite = self.spritestill else: self.landingtimer-=self.game.dt self.spriteindex = 0 if self.horspd != 0: if self.landingtimer<=0: self.spriteindex+=self.horspd*self.animationspeed*self.game.dt self.sprite = self.sprites[int(self.spriteindex)%len(self.sprites)] self.flipx = self.horspd<0 else: # Beeing hurt self.sprite = self.spritehurt self.onground = False self.onceilling = False if self.combotimer>=0: self.combotimer-=self.game.dt*5 # Cancel fastfall if not enough speed if abs(self.verspd)<5: self.fastfall = 0 if self.checkcollisions(0,self.gravityway): self.onground = True self.combo = 0 self.leaptimer = self.leapmaxtimer self.candash = True self.canfastfall = True if self.verspd!=0 and abs(self.verspd)/self.verspd==abs(self.gravityway)/self.gravityway: self.sprite=self.spritelanding self.landingtimer = self.maxlandtime if self.fastfall: self.fastfall = 0 # Spawns dust self.game.addParticle(self.dustparticles,self.rect.right+4,self.rect.center[1]+self.rect[3]/2*self.gravityway,fps=25) self.game.addParticle(self.dustparticles,self.rect.left-4,self.rect.center[1]+self.rect[3]/2*self.gravityway,fps=25) self.slamsfx.play() else: self.landsfx.play() if self.gravityway > 0: self.verspd=min(0,self.verspd) else: self.verspd=max(0,self.verspd) else: self.verspd+=self.gravity*self.game.dt*self.gravityway if self.gravityway>0: self.verspd= min(self.maxgravity,self.verspd) else: self.verspd = max(-self.maxgravity,self.verspd) if self.checkcollisions(0,-self.gravityway): self.onceilling = True if self.gravityway>0: self.verspd= max(0,self.verspd) # Se cogne au plafond BONK else: self.verspd = min(0,self.verspd) # Jumping and falling sprites if canmove and not self.onground: verdir = self.verspd>0 gravdir = self.gravityway>0 if not self.fastfall: if verdir != gravdir: self.sprite=self.spritejumping else: self.sprite=self.spritefalling else: self.sprite = self.spritelanding # Adding knockback self.horspd+=self.horkb self.verspd+=self.verkb self.jumped = False if self.onground or self.leaptimer<0: if self.canmove and 0self.water.rect.y and self.bubbletimer.tick((abs(self.horspd)+abs(self.verspd))/30): offx = self.game.lib.randint(-8,8) offy = self.game.lib.randint(-8,8) self.game.addParticle(self.bubble,self.rect.center[0]+offx,self.rect.center[1]+offy,fps=2,depth=3,vely=-0.1) if self.gravityway>0 and self.rect.center[1]>self.game.globals["cameray"]+self.game.globals["camerah"]: self.die() for i in self.spikes: if i.collidepoint(self.rect.center): self.die() # Update stomp hitrect self.lowerhitrect[0] = self.rect.center[0]-self.lowerhitrect[2]/2 self.lowerhitrect[1] = self.rect.center[1]-self.lowerhitrect[3]/2+20*self.gravityway # Update bonk hitrect canhit = abs(self.verspd)>1.8 if self.verspd>0: offset = 1 else: offset = -1 self.upperhitrect[0] = self.rect.center[0]-self.upperhitrect[2]/2 self.upperhitrect[1] = self.rect.center[1]-self.upperhitrect[3]/2+10*offset if canhit: self.upperhitrect[2] = self.upperhitrectwidth else: self.upperhitrect[2] = 0 # Reducing the knockback if self.horkb>0: self.horkb -= self.reducekb*self.game.dt self.horkb = max(0,self.horkb) if self.horkb<0: self.horkb += self.reducekb*self.game.dt self.horkb = min(0,self.horkb) if self.verkb>0: self.verkb = max(0,self.verkb-self.reducekb)*self.game.dt if self.verkb<0: self.verkb = min(0,self.verkb+self.reducekb)*self.game.dt # Je passe en dessous des semi-plateformes if self.canmove and keys["down"]["timer"]==1: falled = False if not self.checkcollisions(0,1,semi=False): semi = self.checkcollisions(0,1,classic=False) if semi!=self.checkcollisions(0,0,classic=False) and semi: self.rect.bottom = semi.top+1 falled = True if not falled: # Check for fastfall if self.canfastfall and not self.onground: self.verspd = self.maxgravity/5 if self.leaptimer>0: self.verspd*=self.gravityway else: self.leaptimer = 1 self.canfastfall = False self.fastfall = self.gravityway else: self.fastfall = False else: self.deathtimer.tick(self.game.dt) self.game.globals["camerax"] = self.rect.center[0]-self.game.globals["cameraw"]/2 self.game.globals["cameray"] = self.rect.center[1]-self.game.globals["camerah"]/2 self.game.globals["camerax"] = max(0,self.game.globals["camerax"]) self.game.globals["cameray"] = max(0,self.game.globals["cameray"]) self.game.globals["camerax"] = min(self.maxwidth-self.game.globals["cameraw"],self.game.globals["camerax"]) self.game.globals["cameray"] = min(self.maxheight-self.game.globals["camerah"],self.game.globals["cameray"]) def upcombo(self): if self.combotimer<=0: # Up the combo and spawn particles if self.combo>=1: index = min(self.combo-1,len(self.combosprites)-1) self.game.addParticle([self.combosprites[index]],self.rect.center[0],self.rect.top,fps=1) self.combosfxs[index].play() else: self.combodefault.play() self.combo+=1 self.combotimer = 1 def yeet(self,hor,ver,resetcombo=True,dmg = 1): if not self.dead: self.verspd = 0 self.horkb = hor self.verkb = ver self.canfastfall = True if resetcombo: self.game.globals["scamerax"] = 4 self.game.globals["scameray"] = 4 self.combo = 0 self.hurtsfx.play() self.hp-=dmg if self.hp<=0: self.die() else: self.game.addParticle([self.ouch],self.rect.center[0],self.rect.center[1],fps=1,vely=-2,modvely=0.1) # "Ouch !" being displayed def die(self): if not self.dead: self.game.globals["scamerax"] = 4 self.game.globals["scameray"] = 4 self.deadsfx.play() self.depth = 5 self.rect[2],self.rect[3] = 0,0 for rect in self.hitrects: rect[2] = 0 self.dead = True t = Transition(self.game,time=1,holdtime=0.5,level="Level "+str(self.game.globals["levelname"]+1)) self.game.gameloop.summon(t) self.game.addParticle([self.spritehurt],self.rect.center[0],self.rect.center[1],fps=0.6,vely=-1.5,modvely=0.15) # Die sprite if self.tileset.bgm: self.tileset.bgm.stop() def draw(self): if not self.dead: flipy = (self.gravityway<0 and not self.leaptimer<0) if self.fastfall: flipy = self.fastfall<0 sprite = self.game.pygame.transform.flip(self.sprite,self.flipx,flipy) self.game.window.blit(sprite,[self.rect[0]-self.game.globals["camerax"]-self.spriteoffset,self.rect[1]-self.game.globals["cameray"]]) # Hitrects if self.game.globals["allunlocked"]: for rect in self.hitrects: self.game.pygame.draw.rect(self.game.window,[255,0,0],[rect[0]-self.game.globals["camerax"],rect[1]-self.game.globals["cameray"],rect[2],rect[3]]) else: if self.deathtimer.getloops()%2==0: self.game.window.blit(self.retrytext,[self.game.globals["cameraw"]/2-self.retrytext.get_width()/2,self.game.globals["camerah"]/2-self.retrytext.get_height()/2])