added player loop detection, loose level if last player loops
This commit is contained in:
@@ -18,13 +18,16 @@ type PlayerSystem struct {
|
||||
World *ecs.World
|
||||
Selector *generic.Filter4[Position, Velocity, Player, Renderable]
|
||||
GridContainer *grid.GridContainer
|
||||
Width, Height int
|
||||
}
|
||||
|
||||
func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
|
||||
func NewPlayerSystem(world *ecs.World, gridcontainer *grid.GridContainer, width, height int) System {
|
||||
system := &PlayerSystem{
|
||||
Selector: generic.NewFilter4[Position, Velocity, Player, Renderable](),
|
||||
GridContainer: gridcontainer,
|
||||
World: world,
|
||||
Width: width,
|
||||
Height: height,
|
||||
}
|
||||
|
||||
return system
|
||||
@@ -48,7 +51,7 @@ func (system PlayerSystem) Update() error {
|
||||
}
|
||||
|
||||
// check if the user alters or initiates movement
|
||||
system.CheckMovement(velocity)
|
||||
system.CheckMovement(playerposition, velocity, player)
|
||||
|
||||
// check if player collides with walls or edges
|
||||
system.CheckGridCollision(playerposition, velocity)
|
||||
@@ -56,6 +59,15 @@ func (system PlayerSystem) Update() error {
|
||||
if count > 1 {
|
||||
// check if player collides with another player, fuse them if any
|
||||
EntitiesToRemove = system.CheckPlayerCollision(playerposition, velocity, query.Entity())
|
||||
} else {
|
||||
// only 1 player left or one is max
|
||||
EntitiesToRemove = system.CheckPlayerLooping(
|
||||
playerposition, velocity, player, query.Entity())
|
||||
}
|
||||
|
||||
if !velocity.Moving() {
|
||||
// disable loop detection
|
||||
player.LoopCount = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,17 +142,33 @@ func (system *PlayerSystem) SwitchPlayers() {
|
||||
}
|
||||
}
|
||||
|
||||
func (system *PlayerSystem) CheckMovement(velocity *components.Velocity) {
|
||||
func (system *PlayerSystem) CheckMovement(
|
||||
position *components.Position,
|
||||
velocity *components.Velocity,
|
||||
player *components.Player) {
|
||||
|
||||
moved := false
|
||||
|
||||
if !velocity.Moving() {
|
||||
switch {
|
||||
case ebiten.IsKeyPressed(ebiten.KeyRight):
|
||||
velocity.Change(East)
|
||||
moved = true
|
||||
case ebiten.IsKeyPressed(ebiten.KeyLeft):
|
||||
velocity.Change(West)
|
||||
moved = true
|
||||
case ebiten.IsKeyPressed(ebiten.KeyDown):
|
||||
velocity.Change(South)
|
||||
moved = true
|
||||
case ebiten.IsKeyPressed(ebiten.KeyUp):
|
||||
velocity.Change(North)
|
||||
moved = true
|
||||
}
|
||||
|
||||
if moved {
|
||||
// will be reset every time the user initiates player movement
|
||||
player.LoopPos.Set(position)
|
||||
player.LoopCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,9 +189,6 @@ func (system *PlayerSystem) CheckGridCollision(
|
||||
tilepos.Point(), "playerpos", playerposition)
|
||||
intersects, newpos := tilepos.Intersects(playerposition, velocity)
|
||||
if intersects {
|
||||
// slog.Debug("collision detected", "tile",
|
||||
// tilepos, "player", playerposition, "new", newpos)
|
||||
|
||||
playerposition.Set(newpos)
|
||||
velocity.Change(Stop)
|
||||
}
|
||||
@@ -202,3 +227,39 @@ func (system *PlayerSystem) CheckPlayerCollision(
|
||||
// FIXME: add an animation highlighting the fusion
|
||||
return EntitiesToRemove
|
||||
}
|
||||
|
||||
func (system *PlayerSystem) CheckPlayerLooping(
|
||||
position *components.Position,
|
||||
velocity *components.Velocity,
|
||||
player *components.Player,
|
||||
entity ecs.Entity) []ecs.Entity {
|
||||
|
||||
if player.LoopPos.Rect == nil {
|
||||
// hasn't moved
|
||||
return nil
|
||||
}
|
||||
EntitiesToRemove := []ecs.Entity{}
|
||||
|
||||
ok, _ := player.LoopPos.Intersects(position, velocity)
|
||||
if ok {
|
||||
// Fatal: loop detected with last player
|
||||
player.LoopStart = true
|
||||
} else {
|
||||
// no intersection with old pos anymore
|
||||
if player.LoopStart {
|
||||
// loop detection active
|
||||
player.LoopCount++
|
||||
max := system.Width
|
||||
if velocity.Direction == North || velocity.Direction == South {
|
||||
max = system.Height
|
||||
}
|
||||
|
||||
// we haved moved one time around the whole screen, loose
|
||||
if (player.LoopCount * velocity.Speed) > max {
|
||||
EntitiesToRemove = append(EntitiesToRemove, entity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EntitiesToRemove
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user