Ajout d'hitbox basique

This commit is contained in:
theo@manjaro 2021-08-08 19:55:21 +02:00
parent 63b10f7aad
commit 00197ad287
5 changed files with 137 additions and 36 deletions

View File

@ -74,11 +74,15 @@ class Game():
self.pygame = pygame self.pygame = pygame
self.math = math self.math = math
self.elapsedtime = 0
self.globals = {} # Un dico pour ranger toute les valeurs globales, pour communiquer entre objets par exemples self.globals = {} # Un dico pour ranger toute les valeurs globales, pour communiquer entre objets par exemples
self.globals["camerax"] = 0 self.globals["camerax"] = 0
self.globals["cameray"] = 0 self.globals["cameray"] = 0
self.globals["scamerax"] = 3 self.globals["scamerax"] = 3
self.globals["scameray"] = 0 self.globals["scameray"] = 0
self.globals["players"] = []
self.globals["hitpose"] = False
self.scaleCamera() self.scaleCamera()
settings = {"sfx":1,"bgm":1} settings = {"sfx":1,"bgm":1}
@ -114,6 +118,7 @@ class Game():
def game_loop(self): def game_loop(self):
self.dt = time.time()-self.pasttime self.dt = time.time()-self.pasttime
self.elapsedtime += self.dt
self.pasttime = time.time() self.pasttime = time.time()
self.check_events() # Détecte les entrées clavier self.check_events() # Détecte les entrées clavier

View File

@ -0,0 +1,39 @@
from gamedata.objects.base import BaseObject
class Hitbox(BaseObject):
def __init__(self,x,y,game,w=16,h=16,teamid=-1,kbmod=1,dmg=2,vkbmod=1,hkbmod=1,anchor = [0,0]):
super().__init__(x,y,game,w,h)
self.teamid = teamid
self.kbmod = kbmod # Global knockback multiplier
self.vkbmod = vkbmod # Vertical knockback multiplier
self.hkbmod = hkbmod # Horizontal knockback multiplier
self.dmg = dmg # Percentages that will be added
self.anchor = anchor # Rect that will be used as an origin
self.hitted = {} # Storing wich player it has touched
self.hitmargin = 0.5 # Time interval between two hits
def genkb(self,damage):
return 20+damage/5
def step(self):
if not self.game.globals["hitpose"]:
for player in self.game.globals["players"]:
if player.teamid!=self.teamid:
if player.rect.colliderect(self.rect):
if not player.playerid in self.hitted.keys():
self.hitted[player.playerid] = 0
if self.game.elapsedtime - self.hitted[player.playerid] >= self.hitmargin:
kb = self.genkb(player.damage)
player.horkb = kb*self.kbmod*self.hkbmod*player.multkb
player.verkb = kb*self.kbmod*self.vkbmod*player.multkb
player.hitpose = True
player.hitposetimer.reset()
self.hitted[player.playerid] = self.game.elapsedtime
def draw(self):
self.game.pygame.draw.rect(self.game.window,[100,100,255,50],(self.rect[0]-self.game.globals["camerax"],self.rect[1]-self.game.globals["cameray"],self.rect[2],self.rect[3]))

View File

@ -0,0 +1,17 @@
from gamedata.objects.base import BaseObject
class FightManager(BaseObject):
def __init__(self,game):
super().__init__(0,0,game)
def step(self):
self.game.globals["players"] = self.game.gameloop.findname("Player")
self.game.globals["hitpose"] = False # Manage hitpose game-wise
for player in self.game.globals["players"]:
if player.hitpose:
self.game.globals["hitpose"] = True
break
def draw(self):
pass

View File

@ -12,12 +12,27 @@ class Player(Movable):
self.speed = 200 self.speed = 200
self.controlled = True
self.fastfallmargin = 2 self.fastfallmargin = 2
self.playerid = 0
self.teamid = self.playerid
self.hitpose = False self.hitpose = False
self.hitposeduration = 0.5 self.hitposeduration = 0.01
self.hitposetimer = game.lib.Timer(self.hitposeduration) self.hitposetimer = game.lib.Timer(self.hitposeduration)
self.damage = 0
self.horkb = 0
self.verkb = 0
self.reducekb = 50
self.multkb = 1
self.attackstate = None
self.stepsize = 20 self.stepsize = 20
self.gravity = 15 self.gravity = 15
@ -28,45 +43,64 @@ class Player(Movable):
def step(self): def step(self):
if not self.hitpose: if not self.hitpose:
keys = self.game.inputs["keys"] if not self.game.globals["hitpose"]:
self.horspd=(keys["right"]["pressed"]-keys["left"]["pressed"])*self.game.dt*self.speed keys = self.game.inputs["keys"]
if self.controlled:
self.horspd=(keys["right"]["pressed"]-keys["left"]["pressed"])*self.game.dt*self.speed
if self.attackstate:
self.attackstate(self)
# Si je suis sur le sol
self.onground = False
self.onceilling = False
if self.checkcollisions(0,1):
self.onground = True
self.verspd=min(0,self.verspd)
else:
self.verspd+=self.gravity*self.game.dt
self.verspd= min(self.maxgravity,self.verspd)
if self.checkcollisions(0,-1):
self.onceilling = True
self.verspd= max(0,self.verspd) # Se cogne au plafond BONK
# Si je suis sur le sol # Adding knockback
self.onground = False self.horspd+=self.horkb
if self.checkcollisions(0,1): self.verspd+=self.verkb
self.onground = True
self.verspd=min(0,self.verspd)
else:
self.verspd+=self.gravity*self.game.dt
self.verspd= min(self.maxgravity,self.verspd)
if self.checkcollisions(0,-1):
self.verspd= max(0,self.verspd) # Se cogne au plafond BONK
self.jumped = False self.jumped = False
if self.onground: if self.onground:
if 0<keys["up"]["timer"]<=3: if 0<keys["up"]["timer"]<=3:
self.verspd= self.jump self.verspd= self.jump
self.jumped = True self.jumped = True
if self.verspd==0: if self.verspd==0:
self.move(0,-self.stepsize) self.move(0,-self.stepsize)
super().step() super().step()
self.move(0,self.stepsize) self.move(0,self.stepsize)
else: else:
super().step() super().step()
# Je passe en dessous des semi-plateformes # Reducing the knockback
if keys["down"]["timer"]==1: if self.horkb>0:
falled = False self.horkb = max(0,self.horkb-self.reducekb)*self.game.dt
if not self.checkcollisions(0,1,semi=False): if self.horkb<0:
semi = self.checkcollisions(0,1,classic=False) self.horkb = min(0,self.horkb+self.reducekb)*self.game.dt
if semi!=self.checkcollisions(0,0,classic=False) and semi: if self.verkb>0:
self.rect.bottom = semi.top+1 self.verkb = max(0,self.verkb-self.reducekb)*self.game.dt
falled = True if self.verkb<0:
if not falled: self.verkb = min(0,self.verkb+self.reducekb)*self.game.dt
if 0<self.verspd <= self.fastfallmargin or (abs(self.verspd)<abs(self.currentspdv) and abs(self.verspd)<=self.fastfallmargin/1.8):
self.verspd = self.maxgravity/4
else: # 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:
if 0<self.verspd <= self.fastfallmargin or (abs(self.verspd)<abs(self.currentspdv) and abs(self.verspd)<=self.fastfallmargin/1.8):
self.verspd = self.maxgravity/4
else: # If I'm in hitpose
if self.hitposetimer.tick(self.game.dt): if self.hitposetimer.tick(self.game.dt):
self.hitpose = False self.hitpose = False

View File

@ -5,6 +5,8 @@ from gamedata.objects.menu.optionmenu import OptionMenu
from gamedata.objects.sliders.bgmslider import BGMSlider from gamedata.objects.sliders.bgmslider import BGMSlider
from gamedata.objects.sliders.sfxslider import SFXSlider from gamedata.objects.sliders.sfxslider import SFXSlider
from gamedata.objects.combat.player import Player from gamedata.objects.combat.player import Player
from gamedata.objects.combat.manager import FightManager
from gamedata.objects.combat.hitbox import Hitbox
from gamedata.objects.combat.tileset import TilesetRenderer from gamedata.objects.combat.tileset import TilesetRenderer
def main(game): def main(game):
@ -19,8 +21,12 @@ def fight(game):
game.scaleCamera(416,234) game.scaleCamera(416,234)
game.gameloop.reinit() game.gameloop.reinit()
mapname = game.lib.choice(list(game.levels_lib.keys())) mapname = game.lib.choice(list(game.levels_lib.keys()))
manager = FightManager(game)
game.gameloop.summon(manager)
tileset = TilesetRenderer(0,0,game,mapname) tileset = TilesetRenderer(0,0,game,mapname)
game.gameloop.summon(tileset) game.gameloop.summon(tileset)
box = Hitbox(100,80,game)
game.gameloop.summon(box)
p1 = Player(game) p1 = Player(game)
game.gameloop.summon(p1) game.gameloop.summon(p1)