two players fuse now if they collide
This commit is contained in:
parent
ac88a74bd7
commit
5d2475d525
@ -2,9 +2,11 @@ package systems
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"openquell/components"
|
||||||
. "openquell/components"
|
. "openquell/components"
|
||||||
. "openquell/config"
|
. "openquell/config"
|
||||||
"openquell/grid"
|
"openquell/grid"
|
||||||
|
"openquell/observers"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
@ -29,6 +31,67 @@ func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer) System
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (system PlayerSystem) Update() error {
|
func (system PlayerSystem) Update() error {
|
||||||
|
var EntitiesToRemove []ecs.Entity
|
||||||
|
|
||||||
|
// check if we need to switch player[s]
|
||||||
|
system.SwitchPlayers()
|
||||||
|
|
||||||
|
// check player movements etc
|
||||||
|
query := system.Selector.Query(system.World)
|
||||||
|
count := query.Count()
|
||||||
|
|
||||||
|
for query.Next() {
|
||||||
|
playerposition, velocity, player, _ := query.Get()
|
||||||
|
|
||||||
|
if !player.IsPrimary {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the user alters or initiates movement
|
||||||
|
system.CheckMovement(velocity)
|
||||||
|
|
||||||
|
// check if player collides with walls or edges
|
||||||
|
system.CheckGridCollision(playerposition, velocity)
|
||||||
|
|
||||||
|
if count > 1 {
|
||||||
|
// check if player collides with another player, fuse them if any
|
||||||
|
EntitiesToRemove = system.CheckPlayerCollision(playerposition, velocity, query.Entity())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2nd pass: move player after obstacle or collectible updates
|
||||||
|
query = system.Selector.Query(system.World)
|
||||||
|
for query.Next() {
|
||||||
|
playerposition, velocity, _, _ := query.Get()
|
||||||
|
playerposition.Move(velocity)
|
||||||
|
}
|
||||||
|
|
||||||
|
// we may have lost players, remove them here
|
||||||
|
|
||||||
|
for _, entity := range EntitiesToRemove {
|
||||||
|
slog.Debug("remove player", "ent", entity.IsZero())
|
||||||
|
system.World.RemoveEntity(entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
op.GeoM.Reset()
|
||||||
|
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
||||||
|
|
||||||
|
screen.DrawImage(sprite.Image, op)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (system *PlayerSystem) SwitchPlayers() {
|
||||||
// first check if we need to switch player
|
// first check if we need to switch player
|
||||||
switchable := false
|
switchable := false
|
||||||
query := system.Selector.Query(system.World)
|
query := system.Selector.Query(system.World)
|
||||||
@ -65,16 +128,9 @@ func (system PlayerSystem) Update() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check player movements etc
|
|
||||||
query = system.Selector.Query(system.World)
|
|
||||||
for query.Next() {
|
|
||||||
playerposition, velocity, player, _ := query.Get()
|
|
||||||
|
|
||||||
if !player.IsPrimary {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (system *PlayerSystem) CheckMovement(velocity *components.Velocity) {
|
||||||
if !velocity.Moving() {
|
if !velocity.Moving() {
|
||||||
switch {
|
switch {
|
||||||
case ebiten.IsKeyPressed(ebiten.KeyRight):
|
case ebiten.IsKeyPressed(ebiten.KeyRight):
|
||||||
@ -85,27 +141,13 @@ func (system PlayerSystem) Update() error {
|
|||||||
velocity.Change(South)
|
velocity.Change(South)
|
||||||
case ebiten.IsKeyPressed(ebiten.KeyUp):
|
case ebiten.IsKeyPressed(ebiten.KeyUp):
|
||||||
velocity.Change(North)
|
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
|
|
||||||
// other keys: <tab>: switch player, etc
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (system *PlayerSystem) CheckGridCollision(
|
||||||
|
playerposition *components.Position,
|
||||||
|
velocity *components.Velocity) {
|
||||||
|
|
||||||
if velocity.Moving() {
|
if velocity.Moving() {
|
||||||
ok, newpos := system.GridContainer.Grid.BumpEdge(playerposition, velocity)
|
ok, newpos := system.GridContainer.Grid.BumpEdge(playerposition, velocity)
|
||||||
@ -130,27 +172,33 @@ func (system PlayerSystem) Update() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query = system.Selector.Query(system.World)
|
func (system *PlayerSystem) CheckPlayerCollision(
|
||||||
for query.Next() {
|
position *components.Position,
|
||||||
// move player after obstacle or collectible updates
|
velocity *components.Velocity,
|
||||||
playerposition, velocity, _, _ := query.Get()
|
player ecs.Entity) []ecs.Entity {
|
||||||
playerposition.Move(velocity)
|
|
||||||
|
observer := observers.GetGameObserver(system.World)
|
||||||
|
posID := ecs.ComponentID[components.Position](system.World)
|
||||||
|
EntitiesToRemove := []ecs.Entity{}
|
||||||
|
|
||||||
|
for _, otherplayer := range observer.GetPlayers() {
|
||||||
|
if !system.World.Alive(otherplayer) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if otherplayer == player {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (system *PlayerSystem) Draw(screen *ebiten.Image) {
|
otherposition := (*Position)(system.World.Get(otherplayer, posID))
|
||||||
// write the movable tiles
|
|
||||||
op := &ebiten.DrawImageOptions{}
|
|
||||||
query := system.Selector.Query(system.World)
|
|
||||||
|
|
||||||
for query.Next() {
|
ok, _ := otherposition.Intersects(position, velocity)
|
||||||
pos, _, _, sprite := query.Get()
|
if ok {
|
||||||
|
// keep displaying it until the two fully intersect
|
||||||
op.GeoM.Reset()
|
EntitiesToRemove = append(EntitiesToRemove, otherplayer)
|
||||||
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
|
|
||||||
|
|
||||||
screen.DrawImage(sprite.Image, op)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: add an animation highlighting the fusion
|
||||||
|
return EntitiesToRemove
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user