monovania/system/input_move.go

275 lines
6.9 KiB
Go
Raw Normal View History

2021-11-16 18:38:24 +00:00
package system
import (
"log"
2021-11-16 18:38:24 +00:00
"time"
"code.rocketnine.space/tslocum/gohan"
2021-12-08 05:11:47 +00:00
"code.rocketnine.space/tslocum/monovania/asset"
2021-11-16 18:38:24 +00:00
"code.rocketnine.space/tslocum/monovania/component"
"code.rocketnine.space/tslocum/monovania/engine"
2021-12-08 05:11:47 +00:00
"code.rocketnine.space/tslocum/monovania/world"
"github.com/fogleman/ease"
2021-11-16 18:38:24 +00:00
"github.com/hajimehoshi/ebiten/v2"
2021-12-08 05:11:47 +00:00
"github.com/hajimehoshi/ebiten/v2/inpututil"
2021-11-16 18:38:24 +00:00
)
type playerMoveSystem struct {
player gohan.Entity
movement *MovementSystem
lastWalkDirL bool
2021-11-16 18:38:24 +00:00
}
func NewPlayerMoveSystem(player gohan.Entity, m *MovementSystem) *playerMoveSystem {
return &playerMoveSystem{
player: player,
movement: m,
}
}
2021-12-08 05:11:47 +00:00
func (_ *playerMoveSystem) Needs() []gohan.ComponentID {
return []gohan.ComponentID{
component.VelocityComponentID,
component.WeaponComponentID,
component.SpriteComponentID,
}
}
func (_ *playerMoveSystem) Uses() []gohan.ComponentID {
return nil
2021-11-16 18:38:24 +00:00
}
2021-12-08 05:11:47 +00:00
func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
2021-11-16 18:38:24 +00:00
if ebiten.IsKeyPressed(ebiten.KeyControl) && inpututil.IsKeyJustPressed(ebiten.KeyV) {
world.World.Debug++
if world.World.Debug > 2 {
world.World.Debug = 0
}
s.movement.UpdateDebugCollisionRects()
return nil
}
if ebiten.IsKeyPressed(ebiten.KeyControl) && inpututil.IsKeyJustPressed(ebiten.KeyN) {
world.World.NoClip = !world.World.NoClip
2021-11-16 18:38:24 +00:00
return nil
}
if ebiten.IsKeyPressed(ebiten.KeyControl) && inpututil.IsKeyJustPressed(ebiten.KeyX) {
position := engine.Engine.Component(s.player, component.PositionComponentID).(*component.PositionComponent)
world.World.SpawnX, world.World.SpawnY = position.X, position.Y-12
log.Printf("Spawn point set to %.0f,%.0f", world.World.SpawnX, world.World.SpawnY)
return nil
}
2021-11-16 18:38:24 +00:00
moveSpeed := 0.1
maxSpeed := 0.5
2021-12-08 05:11:47 +00:00
maxLevitateSpeed := 1.0
2021-11-16 18:38:24 +00:00
maxYSpeed := 0.5
2021-12-02 03:30:31 +00:00
const jumpVelocity = -1
2021-11-16 18:38:24 +00:00
2021-12-08 05:11:47 +00:00
velocity := component.Velocity(ctx)
var walkKeyPressed bool
2021-12-04 05:50:36 +00:00
if s.movement.OnGround != -1 && ebiten.IsKeyPressed(ebiten.KeyS) && !world.World.NoClip {
2021-12-08 05:11:47 +00:00
if ebiten.IsKeyPressed(ebiten.KeyA) {
s.lastWalkDirL = true
} else if ebiten.IsKeyPressed(ebiten.KeyD) {
s.lastWalkDirL = false
}
2021-12-04 05:50:36 +00:00
// Duck and look down.
2021-12-08 05:11:47 +00:00
sprite := component.Sprite(ctx)
2021-12-04 05:50:36 +00:00
sprite.NumFrames = 0
if s.lastWalkDirL {
sprite.Image = asset.PlayerSS.DuckL
} else {
sprite.Image = asset.PlayerSS.DuckR
}
walkKeyPressed = true
if world.World.DuckStart == -1 {
if world.World.DuckEnd == -1 {
world.World.DuckStart = 0
2021-11-16 18:38:24 +00:00
} else {
2021-12-04 05:50:36 +00:00
world.World.DuckStart = 1 - world.World.DuckEnd
2021-11-16 18:38:24 +00:00
}
}
2021-12-04 05:50:36 +00:00
offset := ((float64(world.World.ScreenH) / 4) / 3) * -1
if world.World.OffsetY > offset {
pct := world.World.DuckStart
if pct < 0.5 {
pct = ease.InOutQuint(pct)
} else {
pct = ease.InOutQuint(pct)
}
world.World.OffsetY = offset * pct
2021-12-04 05:50:36 +00:00
if world.World.DuckStart < 1 {
world.World.DuckStart += 0.01
}
}
2021-12-04 05:50:36 +00:00
} else {
if world.World.DuckStart != -1 {
world.World.DuckEnd = 1 - world.World.DuckStart
world.World.DuckStart = -1
}
if world.World.DuckEnd != -1 {
offset := ((float64(world.World.ScreenH) / 4) / 3) * -1
pct := world.World.DuckEnd
if pct < 0.5 {
pct = ease.InOutQuint(pct)
2021-11-16 18:38:24 +00:00
} else {
2021-12-04 05:50:36 +00:00
pct = ease.InOutQuint(pct)
}
pct = 1 - pct
world.World.OffsetY = offset * pct
if world.World.DuckEnd < 1 {
world.World.DuckEnd += 0.01
2021-11-16 18:38:24 +00:00
}
}
2021-12-04 05:50:36 +00:00
if ebiten.IsKeyPressed(ebiten.KeyA) {
2021-12-08 05:11:47 +00:00
if velocity.X > -maxSpeed || world.World.NoClip {
2021-12-04 05:50:36 +00:00
if s.movement.OnLadder != -1 {
velocity.X -= moveSpeed / 2
} else {
velocity.X -= moveSpeed
}
}
2021-12-08 05:11:47 +00:00
if !world.World.NoClip {
sprite := component.Sprite(ctx)
sprite.Frames = []*ebiten.Image{
asset.PlayerSS.WalkL1,
asset.PlayerSS.IdleL,
asset.PlayerSS.WalkL2,
asset.PlayerSS.IdleL,
}
sprite.NumFrames = 4
sprite.FrameTime = 150 * time.Millisecond
2021-12-04 05:50:36 +00:00
}
walkKeyPressed = true
s.lastWalkDirL = true
}
2021-12-04 05:50:36 +00:00
if ebiten.IsKeyPressed(ebiten.KeyD) {
2021-12-08 05:11:47 +00:00
if velocity.X < maxSpeed || world.World.NoClip {
2021-12-04 05:50:36 +00:00
if s.movement.OnLadder != -1 {
velocity.X += moveSpeed / 2
} else {
velocity.X += moveSpeed
}
}
2021-12-08 05:11:47 +00:00
if !world.World.NoClip {
sprite := component.Sprite(ctx)
sprite.Frames = []*ebiten.Image{
asset.PlayerSS.WalkR1,
asset.PlayerSS.IdleR,
asset.PlayerSS.WalkR2,
asset.PlayerSS.IdleR,
}
sprite.NumFrames = 4
sprite.FrameTime = 150 * time.Millisecond
2021-12-04 05:50:36 +00:00
}
walkKeyPressed = true
s.lastWalkDirL = false
}
2021-11-16 18:38:24 +00:00
}
if s.movement.OnLadder != -1 || world.World.NoClip {
setLadderFrames := func() {
2021-12-08 05:11:47 +00:00
if world.World.NoClip {
return
}
sprite := component.Sprite(ctx)
if s.lastWalkDirL {
sprite.Frames = []*ebiten.Image{
asset.PlayerSS.WalkL1,
asset.PlayerSS.IdleL,
asset.PlayerSS.WalkL2,
asset.PlayerSS.IdleL,
}
} else {
sprite.Frames = []*ebiten.Image{
asset.PlayerSS.WalkR1,
asset.PlayerSS.IdleR,
asset.PlayerSS.WalkR2,
asset.PlayerSS.IdleR,
}
}
sprite.NumFrames = 4
sprite.FrameTime = 150 * time.Millisecond
}
2021-11-16 18:38:24 +00:00
if ebiten.IsKeyPressed(ebiten.KeyW) {
2021-12-08 05:11:47 +00:00
if velocity.Y > -maxYSpeed || world.World.NoClip {
2021-11-16 18:38:24 +00:00
velocity.Y -= moveSpeed
}
setLadderFrames()
walkKeyPressed = true
2021-11-16 18:38:24 +00:00
}
if ebiten.IsKeyPressed(ebiten.KeyS) && s.movement.OnGround == -1 {
2021-12-08 05:11:47 +00:00
if velocity.Y < maxYSpeed || world.World.NoClip {
2021-11-16 18:38:24 +00:00
velocity.Y += moveSpeed
}
setLadderFrames()
walkKeyPressed = true
2021-11-16 18:38:24 +00:00
}
} else {
// Jump.
2021-12-02 03:30:31 +00:00
if inpututil.IsKeyJustPressed(ebiten.KeyW) {
2021-12-04 05:50:36 +00:00
if (s.movement.OnGround != -1 && world.World.Jumps == 0) || (world.World.CanDoubleJump && world.World.Jumps < 2) {
2021-12-02 03:30:31 +00:00
velocity.Y = jumpVelocity
s.movement.Jumping = true
s.movement.LastJump = time.Now()
world.World.Jumps++
2021-12-04 05:50:36 +00:00
// Allow one double jump when falling.
2021-12-08 05:11:47 +00:00
if world.World.Jumps == 1 && s.movement.OnGround == -1 {
world.World.Jumps = 2
2021-12-04 05:50:36 +00:00
}
2021-12-08 05:11:47 +00:00
} else if world.World.CanLevitate && world.World.Jumps == 2 {
world.World.Levitating = true
2021-12-02 03:30:31 +00:00
}
2021-11-16 18:38:24 +00:00
}
if s.movement.Jumping && (!ebiten.IsKeyPressed(ebiten.KeyW) || time.Since(s.movement.LastJump) >= 200*time.Millisecond) {
s.movement.Jumping = false
}
}
2021-12-08 05:11:47 +00:00
if world.World.Levitating {
if ebiten.IsKeyPressed(ebiten.KeyW) {
if velocity.Y > -maxLevitateSpeed {
velocity.Y -= moveSpeed
}
} else {
world.World.Levitating = false
}
}
if !walkKeyPressed || (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || world.World.NoClip {
sprite := component.Sprite(ctx)
sprite.NumFrames = 0
if s.lastWalkDirL {
2021-12-08 05:11:47 +00:00
if (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || world.World.NoClip {
sprite.Image = asset.PlayerSS.WalkL2
} else {
sprite.Image = asset.PlayerSS.IdleL
}
} else {
2021-12-08 05:11:47 +00:00
if (s.movement.OnGround == -1 && s.movement.OnLadder == -1) || world.World.NoClip {
sprite.Image = asset.PlayerSS.WalkR2
} else {
sprite.Image = asset.PlayerSS.IdleR
}
}
}
2021-11-16 18:38:24 +00:00
return nil
}
2021-12-08 05:11:47 +00:00
func (s *playerMoveSystem) Draw(_ *gohan.Context, _ *ebiten.Image) error {
2021-11-16 18:38:24 +00:00
return gohan.ErrSystemWithoutDraw
}