284 lines
12 KiB
Python
284 lines
12 KiB
Python
from gamedata.objects.ingame.movable import Movable
|
|
|
|
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.testsprites = self.game.getchars("Test")
|
|
self.landingtimer = 0
|
|
self.maxlandtime = 0.15
|
|
self.spriteindex = 0
|
|
self.flipx = False
|
|
self.animationspeed = 2.5
|
|
|
|
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.hitrect = self.rect.copy()
|
|
self.hitrect[2] = round(self.hitrect[2]*1)
|
|
self.hitrect[3] = round(self.hitrect[3]*0.7)
|
|
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.hitpose = False
|
|
self.hitposeduration = 0.01
|
|
self.hitposetimer = game.lib.Timer(self.hitposeduration)
|
|
|
|
self.damage = 0
|
|
|
|
self.horkb = 0
|
|
self.verkb = 0
|
|
|
|
self.reducekb = 15
|
|
self.multkb = 1
|
|
|
|
self.attackstate = None
|
|
|
|
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"]
|
|
|
|
def step(self):
|
|
|
|
if not self.hitpose:
|
|
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
|
|
|
|
if not self.game.globals["hitpose"]:
|
|
|
|
canmove = (abs(self.verkb)+1)*(abs(self.horkb)+1)<2
|
|
keys = self.game.inputs["keys"]
|
|
self.horspd = 0
|
|
if canmove:
|
|
self.horspd=(keys["right"]["pressed"]-keys["left"]["pressed"])*self.game.dt*self.speed
|
|
|
|
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
|
|
|
|
if self.attackstate:
|
|
self.attackstate(self) # Si je suis sur le sol
|
|
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 0<keys["up"]["timer"]<=3:
|
|
self.verspd= self.jump*self.gravityway
|
|
if self.leaptimer<0 and not self.onground:
|
|
self.verspd = -abs(self.verspd) # Small leap
|
|
else:
|
|
self.jumpsfx.play()
|
|
self.jumped = True
|
|
super().step() # Actually move
|
|
# Updated hitrect
|
|
self.hitrect[0] = self.rect.center[0]-self.hitrect[2]/2
|
|
offset = 0
|
|
if self.verspd>0:
|
|
offset = 1
|
|
elif self.verspd<0:
|
|
offset = -1
|
|
self.canhit = abs(self.verspd)>2
|
|
self.hitrect[1] = self.rect.center[1]-self.hitrect[3]/2+10*offset
|
|
|
|
# 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 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 = 0
|
|
self.canfastfall = False
|
|
self.fastfall = self.gravityway
|
|
else:
|
|
self.fastfall = False
|
|
|
|
else: # If I'm in hitpose
|
|
if self.hitposetimer.tick(self.game.dt):
|
|
self.hitpose = False
|
|
|
|
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
|
|
|
|
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):
|
|
self.verspd = 0
|
|
self.horkb = hor
|
|
self.verkb = ver
|
|
self.canfastfall = True
|
|
if resetcombo:
|
|
self.combo = 0
|
|
|
|
def draw(self):
|
|
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"]])
|
|
|
|
for i,spr in enumerate(self.testsprites):
|
|
if spr:
|
|
self.game.window.blit(spr,[self.rect[0]+i*9-self.game.globals["camerax"]-self.spriteoffset,self.rect[1]-self.game.globals["cameray"]])
|