added systems (not used yet, see TODO)
This commit is contained in:
parent
006216398a
commit
bbbe873ff7
6
TODO.md
6
TODO.md
@ -8,3 +8,9 @@
|
||||
- ignore comments in lvl files
|
||||
- add whitespace-mode flag in lvl files
|
||||
- check when sphere bounces from one end to the other endlessly w/o any solids in between. this is a game lock and equals game over
|
||||
|
||||
SYSTEM Stuff:
|
||||
|
||||
- initialize systems in NewLevel()
|
||||
- replace level.Update() with systems update
|
||||
- mv Draw() from level to systems
|
||||
|
||||
54
game/collectible_system.go
Normal file
54
game/collectible_system.go
Normal file
@ -0,0 +1,54 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
. "openquell/components"
|
||||
|
||||
"github.com/mlange-42/arche/ecs"
|
||||
"github.com/mlange-42/arche/generic"
|
||||
)
|
||||
|
||||
type CollectibleSystem struct {
|
||||
World *ecs.World
|
||||
Selector *generic.Filter2[Position, Collectible]
|
||||
}
|
||||
|
||||
func NewCollectibleSystem(world *ecs.World) *CollectibleSystem {
|
||||
system := &CollectibleSystem{
|
||||
Selector: generic.NewFilter2[Position, Collectible](),
|
||||
}
|
||||
|
||||
return system
|
||||
}
|
||||
|
||||
func (system *CollectibleSystem) CheckPlayerCollision(
|
||||
playerposition *Position,
|
||||
playervelocity *Velocity) (bool, image.Point) {
|
||||
|
||||
toRemove := []ecs.Entity{}
|
||||
particle_pos := image.Point{}
|
||||
var bumped bool
|
||||
|
||||
query := system.Selector.Query(system.World)
|
||||
|
||||
for query.Next() {
|
||||
colposition, collectible := query.Get()
|
||||
|
||||
ok, _ := playerposition.Intersects(colposition, playervelocity)
|
||||
if ok {
|
||||
fmt.Printf("bumped into collectible %v\n", collectible)
|
||||
toRemove = append(toRemove, query.Entity())
|
||||
particle_pos.X = colposition.X
|
||||
particle_pos.Y = colposition.Y
|
||||
bumped = true
|
||||
}
|
||||
}
|
||||
|
||||
// remove collectible if collected
|
||||
for _, entity := range toRemove {
|
||||
system.World.RemoveEntity(entity)
|
||||
}
|
||||
|
||||
return bumped, particle_pos
|
||||
}
|
||||
@ -260,6 +260,17 @@ func (level *Level) DrawParticles(screen *ebiten.Image) {
|
||||
}
|
||||
|
||||
func (level *Level) SetupGrid(game *Game) {
|
||||
// generic variant does not work here:
|
||||
// selector := generic.NewFilter1[components.Position]()
|
||||
// level.World.Batch().RemoveEntities(selector)
|
||||
// missing argument in conversion to generic.Filter1[components.Position]
|
||||
|
||||
// erase all entities of previous level, if any
|
||||
posID := ecs.ComponentID[components.Position](level.World)
|
||||
selector := ecs.All(posID)
|
||||
level.World.Batch().RemoveEntities(selector)
|
||||
|
||||
// setup world
|
||||
level.Grid = NewGrid(game, level.Cellsize, level.Mapslice)
|
||||
}
|
||||
|
||||
|
||||
53
game/particle_system.go
Normal file
53
game/particle_system.go
Normal file
@ -0,0 +1,53 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"image"
|
||||
. "openquell/components"
|
||||
|
||||
"github.com/mlange-42/arche/ecs"
|
||||
"github.com/mlange-42/arche/generic"
|
||||
)
|
||||
|
||||
type ParticleSystem struct {
|
||||
World *ecs.World
|
||||
Selector *generic.Filter2[Position, Particle]
|
||||
Cellsize int
|
||||
}
|
||||
|
||||
func NewParticleSystem(world *ecs.World) *ParticleSystem {
|
||||
system := &ParticleSystem{
|
||||
Selector: generic.NewFilter2[Position, Particle](),
|
||||
}
|
||||
|
||||
return system
|
||||
}
|
||||
|
||||
func (system *ParticleSystem) Update(detonate bool, position *image.Point) {
|
||||
// display debris after collecting
|
||||
query := system.Selector.Query(system.World)
|
||||
|
||||
for query.Next() {
|
||||
// we loop, but it's only one anyway
|
||||
ptposition, particle := query.Get()
|
||||
|
||||
if detonate {
|
||||
// particle appears
|
||||
ptposition.Update(
|
||||
position.X-(system.Cellsize/2),
|
||||
position.Y-(system.Cellsize/2),
|
||||
64,
|
||||
)
|
||||
|
||||
particle.Index = 0 // start displaying the particle
|
||||
} else {
|
||||
switch {
|
||||
// particle shows from earlier tick, animate
|
||||
case particle.Index > -1 && particle.Index < len(particle.Particles)-1:
|
||||
particle.Index++
|
||||
default:
|
||||
// last sprite reached, remove it
|
||||
particle.Index = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
83
game/player_system.go
Normal file
83
game/player_system.go
Normal file
@ -0,0 +1,83 @@
|
||||
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
|
||||
}
|
||||
8
systems/system.go
Normal file
8
systems/system.go
Normal file
@ -0,0 +1,8 @@
|
||||
package system
|
||||
|
||||
import "github.com/hajimehoshi/ebiten/v2"
|
||||
|
||||
type System interface {
|
||||
Update() error
|
||||
Draw(screen *ebiten.Image)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user