Overflown/gamedata/objects/ingame/player.py

329 lines
14 KiB
Python
Raw Normal View History

2021-11-21 12:28:27 +01:00
from gamedata.objects.ingame.movable import Movable
2021-11-23 18:53:48 +01:00
from gamedata.objects.transition import Transition
2021-11-26 16:10:58 +01:00
from gamedata.objects.ingame.pause import Pause
2021-06-25 16:13:52 +02:00
2021-07-08 16:20:22 +02:00
class Player(Movable):
2021-06-25 16:13:52 +02:00
2021-07-03 00:26:02 +02:00
def __init__(self,game):
2021-07-08 16:20:22 +02:00
super().__init__(game,0,0)
2021-11-16 23:36:56 +01:00
2021-07-08 16:20:22 +02:00
spawnpoint = game.lib.choice(self.tileset.spawns)
self.rect.move_ip(spawnpoint.center)
2021-11-17 20:56:33 +01:00
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.landingtimer = 0
2021-11-18 08:26:30 +01:00
self.maxlandtime = 0.15
2021-11-17 20:56:33 +01:00
self.spriteindex = 0
self.flipx = False
self.animationspeed = 2.5
2021-11-23 11:11:13 +01:00
self.canmove = True
2021-11-17 20:56:33 +01:00
2021-11-23 18:53:48 +01:00
self.hp = 2
self.dead = False
2021-11-24 19:59:23 +01:00
self.spikes = self.tileset.spikes
2021-11-23 18:53:48 +01:00
self.deathtimer = self.game.lib.Timer(0.5)
self.deadsfx = self.game.sound_lib["sfx/dead.wav"]
self.retrytext = self.game.getchars("Try again !")
2021-11-23 11:50:54 +01:00
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"]
2021-11-17 20:56:33 +01:00
self.sprite = self.spritestill
2021-11-19 13:42:37 +01:00
collisionratio = 0.7
self.rect[2] = self.sprite.get_width()*collisionratio
2021-11-16 15:34:12 +01:00
self.rect[3] = self.sprite.get_height()
2021-11-19 13:42:37 +01:00
self.spriteoffset = self.sprite.get_width()*(1-collisionratio)/2
2021-11-16 23:36:56 +01:00
self.water = self.game.gameloop.findname("Water")[0]
2021-11-17 20:56:33 +01:00
2021-11-17 14:50:52 +01:00
self.hitrect = self.rect.copy()
2021-11-19 13:42:37 +01:00
self.hitrect[2] = round(self.hitrect[2]*1)
2021-11-17 14:50:52 +01:00
self.hitrect[3] = round(self.hitrect[3]*0.7)
self.canhit = False
2021-11-16 23:36:56 +01:00
2021-11-17 15:16:07 +01:00
self.dustparticles = game.getSpriteDir("particles/dust/")
2021-11-17 22:00:13 +01:00
self.splashparticles = game.getSpriteDir("particles/splash/")
2021-11-17 15:16:07 +01:00
2021-07-08 16:20:22 +02:00
self.speed = 200
2021-08-08 19:55:21 +02:00
self.playerid = 0
self.teamid = self.playerid
self.damage = 0
self.horkb = 0
self.verkb = 0
2021-11-17 16:42:10 +01:00
self.reducekb = 15
2021-08-08 19:55:21 +02:00
2021-07-08 16:20:22 +02:00
self.gravity = 15
2021-11-16 11:32:31 +01:00
self.maxgravity = 30
2021-07-08 16:20:22 +02:00
self.jump = -5
self.verspd = self.maxgravity
2021-06-25 18:57:40 +02:00
2021-11-16 15:34:12 +01:00
self.candash = False
self.canfastfall = False
2021-11-18 08:26:30 +01:00
self.fastfall = 0
2021-11-16 15:34:12 +01:00
2021-11-16 16:03:53 +01:00
# Small leap in order to get out of the water
self.leaptimer = 1
2021-11-17 14:34:57 +01:00
self.leapmaxtimer = 0.5
2021-11-17 21:39:18 +01:00
self.leapmargin = 30 # Vertical margin for the leap
2021-11-16 11:32:31 +01:00
self.gravityway = 1
2021-11-18 09:12:09 +01:00
self.combo = 0
self.combosprites = self.game.getSpriteDir("player/combo/")
2021-11-19 13:42:37 +01:00
self.combosfxs = self.game.getSpriteDir("sfx/combo/",ext=".wav",assetdir="sound_lib")
self.combodefault = self.game.sound_lib["sfx/combo/default.wav"]
2021-11-18 09:28:47 +01:00
self.combotimer = 1
2021-11-18 09:12:09 +01:00
2021-11-19 13:42:37 +01:00
# 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"]
2021-11-23 17:55:48 +01:00
self.hurtsfx = self.game.sound_lib["sfx/hurt.wav"]
2021-11-19 13:42:37 +01:00
2021-07-08 16:20:22 +02:00
def step(self):
2021-07-02 16:25:40 +02:00
2021-11-23 18:53:48 +01:00
if not self.dead:
2021-11-18 18:03:34 +01:00
if self.water and self.rect.center[1]>self.water.rect.y: # Reverse gravity underwater
2021-11-16 16:03:53 +01:00
if self.gravityway == 1:
self.gravityway = -1
# Décellerer
2021-11-18 18:03:34 +01:00
self.verspd *= 0.85
2021-11-17 22:00:13 +01:00
# Spawn splash particles
2021-11-18 08:26:30 +01:00
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)
2021-11-16 16:03:53 +01:00
else:
if self.gravityway == -1:
self.gravityway = 1
# Décellerer
2021-11-18 18:03:34 +01:00
self.verspd *= 0.85
2021-11-18 08:26:30 +01:00
# 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)
2021-11-16 16:03:53 +01:00
2021-11-16 23:36:56 +01:00
if self.water and self.water.rect.y-self.leapmargin<=self.rect.y<=self.water.rect.y+self.leapmargin:
2021-11-16 16:03:53 +01:00
self.leaptimer-=self.game.dt # Inside the margin
else:
self.leaptimer = self.leapmaxtimer # Outside, reset the timer
2021-11-18 08:26:30 +01:00
if self.leaptimer<0:
self.canfastfall = True
2021-11-16 16:03:53 +01:00
2021-11-25 14:01:58 +01:00
canmove = (abs(self.verkb)+1)*(abs(self.horkb)+1)<2
keys = self.game.inputs["keys"]
self.horspd = 0
if canmove:
if self.canmove:
2021-11-26 15:02:44 +01:00
self.horspd=(keys["right"]["counted"]-keys["left"]["counted"])*self.game.dt*self.speed
2021-11-25 14:01:58 +01:00
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:
2021-11-17 20:56:33 +01:00
if self.landingtimer<=0:
2021-11-25 14:01:58 +01:00
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()
2021-11-17 20:56:33 +01:00
else:
2021-11-25 14:01:58 +01:00
self.landsfx.play()
if self.gravityway > 0:
self.verspd=min(0,self.verspd)
2021-11-17 20:56:33 +01:00
else:
2021-11-25 14:01:58 +01:00
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)
2021-08-08 19:55:21 +02:00
else:
2021-11-25 14:01:58 +01:00
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
2021-11-17 20:56:33 +01:00
else:
2021-11-25 14:01:58 +01:00
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 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
self.leaptimer = 1
self.jumpsfx.play()
self.jumped = True
super().step() # Actually move
if 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):
2021-11-23 18:53:48 +01:00
self.die()
2021-11-25 14:01:58 +01:00
# 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 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
2021-11-17 14:31:55 +01:00
else:
2021-11-25 14:01:58 +01:00
self.leaptimer = 1
self.canfastfall = False
self.fastfall = self.gravityway
else:
self.fastfall = False
2021-08-08 19:55:21 +02:00
2021-11-23 18:53:48 +01:00
else:
self.deathtimer.tick(self.game.dt)
2021-07-01 13:54:56 +02:00
2021-07-02 21:06:34 +02:00
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
2021-11-23 11:50:54 +01:00
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"])
2021-11-18 09:12:09 +01:00
def upcombo(self):
2021-11-18 09:28:47 +01:00
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)
2021-11-19 13:42:37 +01:00
self.combosfxs[index].play()
else:
self.combodefault.play()
2021-11-18 09:28:47 +01:00
self.combo+=1
self.combotimer = 1
2021-11-18 09:12:09 +01:00
2021-11-24 19:59:23 +01:00
def yeet(self,hor,ver,resetcombo=True,dmg = 1):
2021-11-23 18:53:48 +01:00
if not self.dead:
self.verspd = 0
self.horkb = hor
self.verkb = ver
self.canfastfall = True
if resetcombo:
2021-11-24 15:47:52 +01:00
self.game.globals["scamerax"] = 4
self.game.globals["scameray"] = 4
2021-11-23 18:53:48 +01:00
self.combo = 0
self.hurtsfx.play()
2021-11-24 19:59:23 +01:00
self.hp-=dmg
2021-11-23 18:53:48 +01:00
if self.hp<=0:
self.die()
def die(self):
if not self.dead:
2021-11-24 19:59:23 +01:00
self.game.globals["scamerax"] = 4
self.game.globals["scameray"] = 4
2021-11-23 18:53:48 +01:00
self.deadsfx.play()
self.depth = 5
self.rect[2],self.rect[3] = 0,0
self.dead = True
2021-11-24 15:47:52 +01:00
t = Transition(self.game,time=1,holdtime=0.5,level="Level "+str(self.game.globals["levelname"]+1))
2021-11-23 18:53:48 +01:00
self.game.gameloop.summon(t)
2021-11-18 17:58:38 +01:00
2021-11-24 07:54:47 +01:00
self.game.addParticle([self.spritehurt],self.rect.center[0],self.rect.center[1],fps=0.6,vely=-1.5,modvely=0.15) # Die sprite
2021-11-26 16:10:58 +01:00
2021-11-25 08:11:08 +01:00
if self.tileset.bgm:
self.tileset.bgm.stop()
2021-11-24 07:54:47 +01:00
2021-07-02 21:06:34 +02:00
def draw(self):
2021-11-23 18:53:48 +01:00
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"]])
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])