openquell/game/player_system.go

84 lines
2.0 KiB
Go

package game
import (
"fmt"
"image"
. "openquell/components"
. "openquell/config"
"github.com/hajimehoshi/ebiten/v2"
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/generic"
)
type PlayerSystem struct {
World *ecs.World
Grid *Grid
Selector *generic.Filter3[Position, Velocity, Player]
Particle *ParticleSystem
Collectible *CollectibleSystem
}
func NewPlayerSystem(world *ecs.World) *PlayerSystem {
system := &PlayerSystem{
Selector: generic.NewFilter3[Position, Velocity, Player](),
}
return system
}
func (system PlayerSystem) Update() error {
query := system.Selector.Query(system.World)
var bumped bool
var particle_pos image.Point
for query.Next() {
playerposition, velocity, _ := query.Get()
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)
// other keys: <tab>: switch player, etc
}
}
if velocity.Moving() {
ok, newpos := system.Grid.BumpEdge(playerposition, velocity)
if ok {
fmt.Printf("falling off the edge, new pos: %v\n", newpos)
playerposition.Set(newpos)
} else {
ok, tilepos := system.Grid.GetSolidNeighborPosition(playerposition, velocity, true)
if ok {
intersects, newpos := tilepos.Intersects(playerposition, velocity)
if intersects {
fmt.Printf("collision detected. tile: %s\n", tilepos)
fmt.Printf(" player: %s\n", playerposition)
fmt.Printf(" new: %s\n", newpos)
playerposition.Set(newpos)
fmt.Printf(" player new: %s\n", playerposition)
velocity.Change(Stop)
}
}
}
bumped, particle_pos = system.Collectible.CheckPlayerCollision(playerposition, velocity)
}
}
system.Particle.Update(bumped, &particle_pos)
return nil
}