Add walking animation

This commit is contained in:
Trevor Slocum 2023-01-31 16:45:20 -08:00
parent c77dd14e09
commit d41d7ad0a3
7 changed files with 61 additions and 25 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -99,9 +99,14 @@ type Player struct {
Color color.Color
PlayerNum int
Grounded bool
Action PlayerAction
ActionTicksLeft int
WalkFrame int
WalkFrameReverse bool
NoPunch bool
NoKick bool
@ -118,8 +123,25 @@ func (p *Player) Clone() Player {
return result
}
func (p *Player) Walking() bool {
const walkThreshold = 0.2
return p.Grounded && p.Action == ActionIdle && (p.VX < -walkThreshold || p.VX > walkThreshold)
}
func TranslateRect(r image.Rectangle, x int, y int) image.Rectangle {
r.Min.X, r.Min.Y = r.Min.X+x, r.Min.Y+y
r.Max.X, r.Max.Y = r.Max.X+x, r.Max.Y+y
return r
}
// WalkFrames are defined in chronological order.
var WalkFrames = []*ebiten.Image{
asset.FrameAt(asset.ImgPlayer, 0, 13),
asset.FrameAt(asset.ImgPlayer, 1, 13),
asset.FrameAt(asset.ImgPlayer, 2, 13),
asset.FrameAt(asset.ImgPlayer, 3, 13),
asset.FrameAt(asset.ImgPlayer, 4, 13),
asset.FrameAt(asset.ImgPlayer, 5, 13),
asset.FrameAt(asset.ImgPlayer, 6, 13),
asset.FrameAt(asset.ImgPlayer, 7, 13),
}

View File

@ -68,6 +68,7 @@ func (g *Game) reset() {
ActionTicksLeft: len(component.AllPlayerFrames[component.ActionIdle]),
X: -playerSpawnGap - component.PlayerWidth,
Y: 0,
Grounded: true,
}
g.Players[1] = component.Player{
@ -77,6 +78,7 @@ func (g *Game) reset() {
ActionTicksLeft: len(component.AllPlayerFrames[component.ActionIdle]),
X: playerSpawnGap,
Y: 0,
Grounded: true,
}
g.Winner = 0
@ -266,7 +268,6 @@ func (g *Game) applyPhysics() {
}
outOfBounds := p.Y < -world.GroundHeight-component.PlayerHeight
if outOfBounds {
p.VX, p.VY = 0, 0
} else if collideG == -1 && p.VY > -world.Gravity {
@ -288,6 +289,26 @@ func (g *Game) applyPhysics() {
p.VX, p.VY = 0, 0
}
p.Grounded = collideG != -1
// Advance walking animation frame.
if p.Walking() {
const walkFrames = 8
if p.WalkFrameReverse {
p.WalkFrame--
if p.WalkFrame < 0 {
p.WalkFrame = 1
p.WalkFrameReverse = false
}
} else {
p.WalkFrame++
if p.WalkFrame >= walkFrames {
p.WalkFrame = walkFrames - 2
p.WalkFrameReverse = true
}
}
}
if collideX != -1 && collideY != -1 {
collideRect := world.PhysicsRects[collideX]
@ -408,17 +429,8 @@ func (g *Game) UpdateByInputs(inputs []InputBits) {
continue
}
if input.isButtonOn(ButtonUp) && !component.TranslateRect(playerRect, 0, -1).Overlaps(oppRect) {
var grounded bool
for _, physRect := range world.PhysicsRects {
if g.Players[i].Y < float64(physRect.Max.Y)+world.FloatValueThreshold && g.Players[i].Y > float64(physRect.Max.Y)-world.FloatValueThreshold {
grounded = true
break
}
}
if grounded {
g.Players[i].VY = world.JumpVelocity
}
if input.isButtonOn(ButtonUp) && g.Players[i].Grounded {
g.Players[i].VY = world.JumpVelocity
}
if input.isButtonOn(ButtonDown) && !component.TranslateRect(playerRect, 0, 1).Overlaps(oppRect) {
//g.Players[i].VY = -1

View File

@ -38,20 +38,18 @@ func (s *MapSystem) Draw(e gohan.Entity, screen *ebiten.Image) error {
screen.Fill(color.RGBA{0, 100, 100, 255})
groundColor := color.RGBA{50, 50, 50, 255}
const groundTopHeight = 10
//groundTopColor := color.RGBA{100, 100, 100, 255}
const groundBorderSize = 3
groundBorderColor := color.RGBA{30, 30, 30, 255}
groundColor := color.RGBA{20, 20, 20, 255}
for _, r := range world.PhysicsRects {
screen.SubImage(world.GameRectToScreen(r)).(*ebiten.Image).Fill(groundColor)
groundRect := world.GameRectToScreen(r)
screen.SubImage(groundRect).(*ebiten.Image).Fill(groundBorderColor)
inset := groundRect.Inset(groundBorderSize)
inset.Max.Y += groundBorderSize
screen.SubImage(inset).(*ebiten.Image).Fill(groundColor)
}
/*r := image.Rect(-world.GroundWidth/2, -world.ScreenHeight, world.GroundWidth/2, 0)
screen.SubImage(world.GameRectToScreen(r)).(*ebiten.Image).Fill(groundColor)
r = image.Rect(-world.GroundWidth/2, -groundTopHeight, world.GroundWidth/2, 0)
screen.SubImage(world.GameRectToScreen(r)).(*ebiten.Image).Fill(groundTopColor)*/
return nil
}

View File

@ -58,6 +58,10 @@ func (s *PlayerSystem) Draw(e gohan.Entity, screen *ebiten.Image) error {
break
}
if p.Walking() {
sprite = component.WalkFrames[p.WalkFrame]
}
if sprite != nil {
x, y := world.GameCoordsToScreen(p.X-24, p.Y+64)
op := &ebiten.DrawImageOptions{}

View File

@ -266,11 +266,11 @@ func (u *UISystem) Draw(e gohan.Entity, screen *ebiten.Image) error {
label := fmt.Sprintf("OPPONENT TYPE: %s (CONTROL+O)", aiLabel)
ebitenutil.DebugPrint(u.tmpImg, label)
width := float64(len(label) * 6)
width := float64(len(label) * 12)
op := &ebiten.DrawImageOptions{}
op.GeoM.Reset()
op.GeoM.Scale(1, 1)
op.GeoM.Scale(2, 2)
op.GeoM.Translate(world.InternalScreenWidth/2-width/2, 0)
screen.DrawImage(u.tmpImg, op)
}