|
|
|
@ -218,57 +218,85 @@ func (g *Game) applyPhysics() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (g *Game) UpdateByInputs(inputs []InputBits) {
|
|
|
|
|
var player, opponent *component.Player
|
|
|
|
|
for i, input := range inputs {
|
|
|
|
|
opp := 0
|
|
|
|
|
if i == 0 {
|
|
|
|
|
opp = 1
|
|
|
|
|
}
|
|
|
|
|
player = &g.Players[i]
|
|
|
|
|
opponent = &g.Players[opp]
|
|
|
|
|
|
|
|
|
|
playerRect := world.FloatRect(g.Players[i].X, g.Players[i].Y, g.Players[i].X+float64(component.PlayerSize), g.Players[i].Y+float64(component.PlayerSize))
|
|
|
|
|
oppRect := world.FloatRect(g.Players[opp].X, g.Players[opp].Y, g.Players[opp].X+float64(component.PlayerSize), g.Players[opp].Y+float64(component.PlayerSize))
|
|
|
|
|
|
|
|
|
|
g.Players[i].VX = g.Players[i].VX * 0.8
|
|
|
|
|
g.Players[i].VY = g.Players[i].VY * 0.8
|
|
|
|
|
|
|
|
|
|
if input.isButtonOn(ButtonUp) && !component.TranslateRect(playerRect, 0, -1).Overlaps(oppRect) {
|
|
|
|
|
grounded := g.Players[i].Y == float64(component.PlayerSize)
|
|
|
|
|
// TODO check when last jump, grounded
|
|
|
|
|
if grounded {
|
|
|
|
|
g.Players[i].VY = 20
|
|
|
|
|
if player.Action != component.ActionStunned {
|
|
|
|
|
if input.isButtonOn(ButtonUp) && !component.TranslateRect(playerRect, 0, -1).Overlaps(oppRect) {
|
|
|
|
|
grounded := g.Players[i].Y == float64(component.PlayerSize)
|
|
|
|
|
// TODO check when last jump, grounded
|
|
|
|
|
if grounded {
|
|
|
|
|
g.Players[i].VY = 20
|
|
|
|
|
}
|
|
|
|
|
log.Println("JUMP", grounded)
|
|
|
|
|
}
|
|
|
|
|
if input.isButtonOn(ButtonDown) && !component.TranslateRect(playerRect, 0, 1).Overlaps(oppRect) {
|
|
|
|
|
//g.Players[i].VY = -1
|
|
|
|
|
// TODO crouch
|
|
|
|
|
}
|
|
|
|
|
if input.isButtonOn(ButtonLeft) && !component.TranslateRect(playerRect, -1, 0).Overlaps(oppRect) {
|
|
|
|
|
g.Players[i].VX = -1
|
|
|
|
|
}
|
|
|
|
|
if input.isButtonOn(ButtonRight) && !component.TranslateRect(playerRect, 1, 0).Overlaps(oppRect) {
|
|
|
|
|
g.Players[i].VX = 1
|
|
|
|
|
}
|
|
|
|
|
log.Println("JUMP", grounded)
|
|
|
|
|
}
|
|
|
|
|
if input.isButtonOn(ButtonDown) && !component.TranslateRect(playerRect, 0, 1).Overlaps(oppRect) {
|
|
|
|
|
//g.Players[i].VY = -1
|
|
|
|
|
// TODO crouch
|
|
|
|
|
}
|
|
|
|
|
if input.isButtonOn(ButtonLeft) && !component.TranslateRect(playerRect, -1, 0).Overlaps(oppRect) {
|
|
|
|
|
g.Players[i].VX = -1
|
|
|
|
|
}
|
|
|
|
|
if input.isButtonOn(ButtonRight) && !component.TranslateRect(playerRect, 1, 0).Overlaps(oppRect) {
|
|
|
|
|
g.Players[i].VX = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if g.Players[i].Action == component.ActionIdle {
|
|
|
|
|
if input.isButtonOn(ButtonPunch) {
|
|
|
|
|
g.Players[i].Action = component.ActionPunch
|
|
|
|
|
g.Players[i].ActionTicksLeft = len(component.AllPlayerFrames[component.ActionPunch]) // TODO
|
|
|
|
|
continue
|
|
|
|
|
if g.Players[i].Action == component.ActionIdle {
|
|
|
|
|
if input.isButtonOn(ButtonPunch) {
|
|
|
|
|
g.Players[i].Action = component.ActionPunch
|
|
|
|
|
g.Players[i].ActionTicksLeft = len(component.AllPlayerFrames[component.ActionPunch]) // TODO
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO player starts in idle action?
|
|
|
|
|
if g.Players[i].ActionTicksLeft != 0 {
|
|
|
|
|
// Run current frame logic.
|
|
|
|
|
log.Printf("apply hitbox for player %d action %d ticks left %d", i, g.Players[i].Action, g.Players[i].ActionTicksLeft)
|
|
|
|
|
|
|
|
|
|
// TODO handle invulnerability and blocking
|
|
|
|
|
|
|
|
|
|
allFrameData := component.FrameDataForActionTick(g.Players[i].Action, g.Players[i].ActionTicksLeft)
|
|
|
|
|
for _, frame := range allFrameData {
|
|
|
|
|
if frame.T == component.HitboxHurt {
|
|
|
|
|
// Hit opponent.
|
|
|
|
|
if oppRect.Overlaps(component.TranslateRect(frame.R, int(player.X), int(player.Y))) {
|
|
|
|
|
// Send the opponent flying in some direction.
|
|
|
|
|
if opponent.X <= player.X { // Opponent is to the left of the player.
|
|
|
|
|
opponent.VX = -4
|
|
|
|
|
} else { // Opponent is to the right of the player.
|
|
|
|
|
opponent.VX = 4
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stun the opponent.
|
|
|
|
|
opponent.Action = component.ActionStunned
|
|
|
|
|
opponent.ActionTicksLeft = 7
|
|
|
|
|
|
|
|
|
|
log.Println("HIT")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Advance to the next frame.
|
|
|
|
|
g.Players[i].ActionTicksLeft--
|
|
|
|
|
if g.Players[i].ActionTicksLeft == 0 {
|
|
|
|
|
// Return to the idle action.
|
|
|
|
|
g.Players[i].Action = component.ActionIdle
|
|
|
|
|
g.Players[i].ActionTicksLeft = len(component.AllPlayerFrames[component.ActionIdle]) // TODO
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO Apply hitboxes
|
|
|
|
|
if g.Players[i].ActionTicksLeft != 0 {
|
|
|
|
|
//frameNum := g.Players[i].ActionTicksLeft - 1
|
|
|
|
|
//frame := component.AllPlayerFrames[g.Players[i].Action][frameNum]
|
|
|
|
|
//log.Printf("frame %+v", frame)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|