openquell/systems/player_system.go

147 lines
3.7 KiB
Go
Raw Normal View History

2024-02-10 19:45:06 +01:00
package systems
2024-02-09 20:20:13 +01:00
import (
"log/slog"
2024-02-09 20:20:13 +01:00
. "openquell/components"
. "openquell/config"
"openquell/grid"
2024-02-09 20:20:13 +01:00
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/inpututil"
2024-02-09 20:20:13 +01:00
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/generic"
)
type PlayerSystem struct {
World *ecs.World
Selector *generic.Filter4[Position, Velocity, Player, Renderable]
GridContainer *grid.GridContainer
2024-02-09 20:20:13 +01:00
}
func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
2024-02-09 20:20:13 +01:00
system := &PlayerSystem{
Selector: generic.NewFilter4[Position, Velocity, Player, Renderable](),
GridContainer: gridcontainer,
World: world,
2024-02-09 20:20:13 +01:00
}
return system
}
func (system PlayerSystem) Update() error {
// first check if we need to switch player
switchable := false
2024-02-09 20:20:13 +01:00
query := system.Selector.Query(system.World)
for query.Next() {
_, _, player, _ := query.Get()
if !player.IsPrimary {
switchable = true
}
}
2024-02-09 20:20:13 +01:00
if switchable {
query := system.Selector.Query(system.World)
for query.Next() {
_, _, player, render := query.Get()
if inpututil.IsKeyJustPressed(ebiten.KeyTab) {
slog.Debug("switch players")
if player.IsPrimary {
player.IsPrimary = false
render.Image = player.SwitchSprite()
} else {
player.IsPrimary = true
render.Image = player.SwitchSprite()
}
}
}
}
// check player movements etc
query = system.Selector.Query(system.World)
2024-02-09 20:20:13 +01:00
for query.Next() {
playerposition, velocity, player, _ := query.Get()
if !player.IsPrimary {
continue
}
2024-02-09 20:20:13 +01:00
if !velocity.Moving() {
switch {
case ebiten.IsKeyPressed(ebiten.KeyRight):
velocity.Change(East)
case ebiten.IsKeyPressed(ebiten.KeyLeft):
velocity.Change(West)
case ebiten.IsKeyPressed(ebiten.KeyDown):
velocity.Change(South)
case ebiten.IsKeyPressed(ebiten.KeyUp):
velocity.Change(North)
case ebiten.IsKeyPressed(ebiten.Key1):
velocity.Speed = 1
case ebiten.IsKeyPressed(ebiten.Key2):
velocity.Speed = 2
case ebiten.IsKeyPressed(ebiten.Key3):
velocity.Speed = 3
case ebiten.IsKeyPressed(ebiten.Key4):
velocity.Speed = 4
case ebiten.IsKeyPressed(ebiten.Key5):
velocity.Speed = 5
case ebiten.IsKeyPressed(ebiten.Key6):
velocity.Speed = 6
case ebiten.IsKeyPressed(ebiten.Key7):
velocity.Speed = 7
case ebiten.IsKeyPressed(ebiten.Key8):
velocity.Speed = 8
case ebiten.IsKeyPressed(ebiten.Key9):
velocity.Speed = 9
2024-02-09 20:20:13 +01:00
// other keys: <tab>: switch player, etc
}
}
if velocity.Moving() {
ok, newpos := system.GridContainer.Grid.BumpEdge(playerposition, velocity)
2024-02-09 20:20:13 +01:00
if ok {
//slog.Debug("falling off the edge", "newpos", newpos)
2024-02-09 20:20:13 +01:00
playerposition.Set(newpos)
} else {
ok, tilepos := system.GridContainer.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
2024-02-09 20:20:13 +01:00
if ok {
slog.Debug("HaveSolidNeighbor", "ok", ok, "tilepos",
tilepos.Point(), "playerpos", playerposition)
2024-02-09 20:20:13 +01:00
intersects, newpos := tilepos.Intersects(playerposition, velocity)
if intersects {
// slog.Debug("collision detected", "tile",
// tilepos, "player", playerposition, "new", newpos)
2024-02-09 20:20:13 +01:00
playerposition.Set(newpos)
velocity.Change(Stop)
}
}
}
}
}
query = system.Selector.Query(system.World)
for query.Next() {
// move player after obstacle or collectible updates
playerposition, velocity, _, _ := query.Get()
playerposition.Move(velocity)
}
2024-02-09 20:20:13 +01:00
return nil
}
2024-02-10 19:45:06 +01:00
func (system *PlayerSystem) Draw(screen *ebiten.Image) {
// write the movable tiles
op := &ebiten.DrawImageOptions{}
query := system.Selector.Query(system.World)
for query.Next() {
pos, _, _, sprite := query.Get()
2024-02-10 19:45:06 +01:00
op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
screen.DrawImage(sprite.Image, op)
}
}