doctorlectro/entity/player.go

130 lines
3.4 KiB
Go
Raw Normal View History

2022-06-17 21:17:03 +00:00
package entity
import (
"time"
2022-06-18 21:08:53 +00:00
"github.com/hajimehoshi/ebiten/v2"
"github.com/jakecoffman/cp"
"code.rocketnine.space/tslocum/doctorlectro/world"
2022-06-17 21:17:03 +00:00
"code.rocketnine.space/tslocum/doctorlectro/asset"
"code.rocketnine.space/tslocum/doctorlectro/component"
"code.rocketnine.space/tslocum/gohan"
)
2022-06-18 21:08:53 +00:00
const (
2022-06-22 02:52:48 +00:00
playerVelocity = 50.0
2022-06-18 21:08:53 +00:00
playerGroundAccelTime = 0.1
playerGroundAccel = playerVelocity / playerGroundAccelTime
playerAirAccelTime = 0.25
playerAirAccel = playerVelocity / playerAirAccelTime
fallVelocity = 900.0
)
2022-06-17 21:17:03 +00:00
func NewPlayer() gohan.Entity {
2022-06-22 02:52:48 +00:00
playerBody := world.Space.AddBody(cp.NewBody(1, cp.INFINITY))
2022-06-18 21:08:53 +00:00
playerBody.SetPosition(cp.Vector{0, 0})
playerBody.SetVelocityUpdateFunc(playerUpdateVelocity)
2022-06-22 02:52:48 +00:00
playerShape := world.Space.AddShape(cp.NewCircle(playerBody, 8, cp.Vector{8, 0}))
2022-06-18 21:08:53 +00:00
playerShape.SetElasticity(0)
playerShape.SetFriction(0)
world.PlayerBody = playerBody
world.PlayerShape = playerShape
2022-06-17 21:17:03 +00:00
player := gohan.NewEntity()
2022-06-18 21:08:53 +00:00
player.AddComponent(&component.Position{
Body: world.PlayerBody,
})
2022-06-17 21:17:03 +00:00
player.AddComponent(&component.Velocity{})
player.AddComponent(&component.Sprite{
Frames: asset.PlayerIdleFrames,
2022-06-18 21:08:53 +00:00
FrameTime: 150 * time.Millisecond,
2022-06-17 21:17:03 +00:00
NumFrames: len(asset.PlayerIdleFrames),
2022-06-18 21:08:53 +00:00
OffsetY: -10,
2022-06-17 21:17:03 +00:00
})
player.AddComponent(&component.Player{})
2022-06-22 02:52:48 +00:00
world.PlayerIdleFrames = asset.PlayerIdleFrames
world.PlayerWalkFrames = asset.PlayerWalkFrames
2022-06-17 21:17:03 +00:00
return player
}
2022-06-18 21:08:53 +00:00
func playerUpdateVelocity(body *cp.Body, gravity cp.Vector, damping, dt float64) {
2022-06-22 02:52:48 +00:00
var normal cp.Vector
var grounded bool
world.PlayerBody.EachArbiter(func(arb *cp.Arbiter) {
normal = arb.Normal().Neg()
if normal.X != 0 || normal.Y != 0 {
grounded = true
}
})
world.PlayerNormal = normal
world.PlayerGrounded = grounded
// Apply magnetization by overwriting gravity.
2022-06-25 00:08:16 +00:00
// Case MagnetizeDown is not handled because gravity is already set to the normal vector.
2022-06-22 02:52:48 +00:00
if world.MagnetActive {
switch world.MagnetDirection {
case world.MagnetizeDownLeft:
gravity = cp.Vector{-world.Gravity / 4, world.Gravity / 4}
case world.MagnetizeLeft:
gravity = cp.Vector{-world.Gravity, 0}
case world.MagnetizeUpLeft:
gravity = cp.Vector{-world.Gravity / 4, -world.Gravity / 4}
case world.MagnetizeUp:
gravity = cp.Vector{0, -world.Gravity}
case world.MagnetizeUpRight:
gravity = cp.Vector{world.Gravity / 4, -world.Gravity / 4}
case world.MagnetizeRight:
gravity = cp.Vector{world.Gravity, 0}
case world.MagnetizeDownRight:
gravity = cp.Vector{world.Gravity / 4, world.Gravity / 4}
2022-06-18 21:08:53 +00:00
}
}
2022-06-22 02:52:48 +00:00
body.UpdateVelocity(gravity, damping, dt)
2022-06-18 21:08:53 +00:00
xDir := 0.0
2022-06-22 02:52:48 +00:00
yDir := 0.0
if ebiten.IsKeyPressed(ebiten.KeyW) {
yDir -= 1
world.LastWalkDirU = true
}
if ebiten.IsKeyPressed(ebiten.KeyS) {
yDir += 1
world.LastWalkDirU = false
}
2022-06-18 21:08:53 +00:00
if ebiten.IsKeyPressed(ebiten.KeyA) {
xDir -= 1
world.LastWalkDirL = false
}
if ebiten.IsKeyPressed(ebiten.KeyD) { // TODO
xDir += 1
world.LastWalkDirL = true
}
2022-06-22 02:52:48 +00:00
// Target velocities based on user input.
2022-06-18 21:08:53 +00:00
targetVx := playerVelocity * xDir
2022-06-22 02:52:48 +00:00
targetVy := playerVelocity * yDir
if targetVx == 0 {
targetVx = gravity.X
2022-06-18 21:08:53 +00:00
}
2022-06-22 02:52:48 +00:00
if targetVy == 0 {
targetVy = gravity.Y
2022-06-18 21:08:53 +00:00
}
v := body.Velocity()
2022-06-22 02:52:48 +00:00
vx, vy := cp.Clamp(v.X, -fallVelocity, fallVelocity), cp.Clamp(v.Y, -fallVelocity, fallVelocity)
vx, vy = cp.LerpConst(vx, targetVx, playerAirAccel*dt), cp.LerpConst(vy, targetVy, playerAirAccel*dt)
body.SetVelocity(vx, vy)
2022-06-18 21:08:53 +00:00
}