diff --git a/assets/levels/0-own.lvl b/assets/levels/0-own.lvl index a4dc0fb..c0b0eeb 100644 --- a/assets/levels/0-own.lvl +++ b/assets/levels/0-own.lvl @@ -5,13 +5,13 @@ Background: background-lila ######## - # #o# + #o o #o# # S # # # #### # # #### # # # - # o # + #o o# ######## diff --git a/assets/loader-levels.go b/assets/loader-levels.go index 363b29a..6035f1e 100644 --- a/assets/loader-levels.go +++ b/assets/loader-levels.go @@ -110,8 +110,7 @@ func InitTiles() TileRegistry { 'S': NewTilePlayer(), 'o': NewTileCollectible("collectible-orange"), '*': NewTileParticle([]string{ - "particle-dust-0", "particle-dust-0", "particle-dust-1", "particle-dust-1", - "particle-dust-0", "particle-dust-2", "particle-dust-3", "particle-dust-3", + "particle-ring-1", "particle-ring-2", "particle-ring-3", "particle-ring-4", "particle-ring-5", "particle-ring-6", }), } } diff --git a/assets/sprites/particle-ring-1.png b/assets/sprites/particle-ring-1.png new file mode 100644 index 0000000..f40d8dd Binary files /dev/null and b/assets/sprites/particle-ring-1.png differ diff --git a/assets/sprites/particle-ring-2.png b/assets/sprites/particle-ring-2.png new file mode 100644 index 0000000..6f0af39 Binary files /dev/null and b/assets/sprites/particle-ring-2.png differ diff --git a/assets/sprites/particle-ring-3.png b/assets/sprites/particle-ring-3.png new file mode 100644 index 0000000..2344432 Binary files /dev/null and b/assets/sprites/particle-ring-3.png differ diff --git a/assets/sprites/particle-ring-4.png b/assets/sprites/particle-ring-4.png new file mode 100644 index 0000000..d633417 Binary files /dev/null and b/assets/sprites/particle-ring-4.png differ diff --git a/assets/sprites/particle-ring-5.png b/assets/sprites/particle-ring-5.png new file mode 100644 index 0000000..738ee68 Binary files /dev/null and b/assets/sprites/particle-ring-5.png differ diff --git a/assets/sprites/particle-ring-6.png b/assets/sprites/particle-ring-6.png new file mode 100644 index 0000000..b663e80 Binary files /dev/null and b/assets/sprites/particle-ring-6.png differ diff --git a/components/components.go b/components/components.go index 3358571..7b5d7b1 100644 --- a/components/components.go +++ b/components/components.go @@ -11,6 +11,7 @@ type Renderable struct { } type Particle struct { + Show bool Index int Particles []*ebiten.Image } diff --git a/components/timer.go b/components/timer.go new file mode 100644 index 0000000..413eaa2 --- /dev/null +++ b/components/timer.go @@ -0,0 +1,41 @@ +package components + +import ( + "time" + + "github.com/hajimehoshi/ebiten/v2" +) + +type Timer struct { + currentTicks int + targetTicks int +} + +func NewTimer(d time.Duration) *Timer { + return &Timer{} +} + +func (timer *Timer) Start(d time.Duration) { + min := int(1000 / ebiten.TPS()) // 16.66ms == 1 tick + useD := d + + if int(d.Milliseconds()) < min { + useD = time.Duration(1000/ebiten.TPS()) * time.Millisecond + } + + timer.targetTicks = int(useD.Milliseconds()) / min // id d=50, then 50 / 16.6 = +} + +func (t *Timer) Update() { + if t.currentTicks < t.targetTicks { + t.currentTicks++ + } +} + +func (t *Timer) IsReady() bool { + return t.currentTicks >= t.targetTicks +} + +func (t *Timer) Reset() { + t.currentTicks = 0 +} diff --git a/config/static.go b/config/static.go index 02f9851..4cc76cd 100644 --- a/config/static.go +++ b/config/static.go @@ -1,5 +1,7 @@ package config +import "time" + const ( Stop = iota East @@ -9,3 +11,4 @@ const ( ) const PLAYERSPEED int = 4 +const PARTICLE_LOOPWAIT time.Duration = 250 * time.Millisecond diff --git a/src/kugel2.xcf b/src/kugel2.xcf index d4035bf..e32847b 100644 Binary files a/src/kugel2.xcf and b/src/kugel2.xcf differ diff --git a/systems/collectible_system.go b/systems/collectible_system.go index 75b13da..3c58dea 100644 --- a/systems/collectible_system.go +++ b/systems/collectible_system.go @@ -5,6 +5,7 @@ import ( "openquell/assets" "openquell/components" . "openquell/components" + "openquell/config" "openquell/observers" "github.com/hajimehoshi/ebiten/v2" @@ -31,6 +32,7 @@ func (system *CollectibleSystem) Update() { posID := ecs.ComponentID[components.Position](system.World) veloID := ecs.ComponentID[components.Velocity](system.World) + particlepositions := []*components.Position{} EntitiesToRemove := []ecs.Entity{} @@ -93,13 +95,14 @@ func (system *CollectibleSystem) Draw(screen *ebiten.Image) { func (system *CollectibleSystem) AddParticle(position *components.Position) { particleobserver := observers.GetParticleObserver(system.World) - ptmapper := generic.NewMap2[ + ptmapper := generic.NewMap3[ components.Position, components.Particle, + components.Timer, ](system.World) entity := ptmapper.New() - pos, particle := ptmapper.Get(entity) + pos, particle, timer := ptmapper.Get(entity) particleobserver.AddEntity(entity) particle.Index = assets.Tiles['*'].Particle @@ -110,4 +113,6 @@ func (system *CollectibleSystem) AddParticle(position *components.Position) { position.Y-(16), 64, ) + + timer.Start(config.PARTICLE_LOOPWAIT) } diff --git a/systems/particle_system.go b/systems/particle_system.go index 74ada10..ef65b81 100644 --- a/systems/particle_system.go +++ b/systems/particle_system.go @@ -2,6 +2,7 @@ package systems import ( . "openquell/components" + "openquell/config" "github.com/hajimehoshi/ebiten/v2" "github.com/mlange-42/arche/ecs" @@ -10,13 +11,13 @@ import ( type ParticleSystem struct { World *ecs.World - Selector *generic.Filter2[Position, Particle] + Selector *generic.Filter3[Position, Particle, Timer] Cellsize int } func NewParticleSystem(world *ecs.World, cellsize int) *ParticleSystem { system := &ParticleSystem{ - Selector: generic.NewFilter2[Position, Particle](), + Selector: generic.NewFilter3[Position, Particle, Timer](), World: world, Cellsize: cellsize, } @@ -32,16 +33,24 @@ func (system *ParticleSystem) Update() { for query.Next() { // we loop, but it's only one anyway - _, particle := query.Get() + _, particle, timer := query.Get() - 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 - EntitiesToRemove = append(EntitiesToRemove, query.Entity()) + particle.Show = true + + if timer.IsReady() { + switch { + // particle shows from earlier tick, animate + case particle.Index > -1 && particle.Index < len(particle.Particles)-1: + particle.Index++ + timer.Start(config.PARTICLE_LOOPWAIT) + default: + // last sprite reached, remove it + EntitiesToRemove = append(EntitiesToRemove, query.Entity()) + } + } else { + timer.Update() } + } for _, entity := range EntitiesToRemove { @@ -55,10 +64,12 @@ func (system *ParticleSystem) Draw(screen *ebiten.Image) { query := system.Selector.Query(system.World) for query.Next() { - pos, particle := query.Get() + pos, particle, _ := query.Get() - op.GeoM.Reset() - op.GeoM.Translate(float64(pos.X), float64(pos.Y)) - screen.DrawImage(particle.Particles[particle.Index], op) + if particle.Show { + op.GeoM.Reset() + op.GeoM.Translate(float64(pos.X), float64(pos.Y)) + screen.DrawImage(particle.Particles[particle.Index], op) + } } }