Files
aego/tests/integration/platformer_demo_update_test.go
sanspie a6822156cd
ci-platforms / windows amd64 smoke (push) Skipped
ci / release (push) Successful in 8m58s
ci-platforms / darwin amd64 smoke (push) Skipped
ci-platforms / darwin arm64 smoke (push) Skipped
ci / checks (push) Successful in 4m46s
ci / build (amd64, linux, ubuntu-24.04) (push) Successful in 13m28s
Finish Stage 12 editor fixes and refreshed platformer
2026-11-05 17:36:42 +03:00

108 lines
3.1 KiB
Go

package integration
import (
"testing"
"aego/core/mathx"
"aego/modules/gameplay"
"aego/modules/particles"
"aego/modules/render2d"
"aego/scene"
)
func TestPlatformerSwordSparksAndFacing(t *testing.T) {
for _, direction := range []float32{-1, 1} {
t.Run(map[float32]string{-1: "left", 1: "right"}[direction], func(t *testing.T) {
pf := openPlatformer(t)
pf.step(30)
sc := pf.app.Scene
slash := sc.Find(pf.player, "Slash")
sparks := sc.Find(slash, "Sparks")
if slash.IsZero() || sparks.IsZero() {
t.Fatal("player is missing its sword or spark emitter")
}
fx := particles.Of(pf.app.Engine.MainWorld())
if fx == nil {
t.Fatal("particle service is missing")
}
in := actionsOf(t, pf)
if err := in.Inject(0, "Move", direction); err != nil {
t.Fatal(err)
}
pf.step(2)
if err := in.Inject(0, "Move", 0); err != nil {
t.Fatal(err)
}
if err := in.Inject(0, "Attack", 1); err != nil {
t.Fatal(err)
}
pf.step(1)
if err := in.Inject(0, "Attack", 0); err != nil {
t.Fatal(err)
}
for i := 0; i < 60 && fx.Emitted(sparks) == 0; i++ {
pf.step(1)
}
if got := fx.Emitted(sparks); got != 8 {
t.Fatalf("one sword attack emitted %d sparks, want 8", got)
}
if x := sc.Local(slash).Position.X; mathx.Abs(x-direction*0.7) > 0.001 {
t.Fatalf("sword x=%v does not match facing %v", x, direction)
}
pf.noFaults(t)
})
}
}
func TestPlatformerNonlethalStompBounces(t *testing.T) {
pf := openPlatformer(t)
pf.step(30)
sc := pf.app.Scene
health, ok := scene.Get[gameplay.Health](sc, pf.enemy)
if !ok {
t.Fatal("enemy has no health")
}
health.Max, health.Current = 3, 3
e := sc.Local(pf.enemy).Position
sc.SetPosition(pf.player, mathx.Vec2{X: e.X, Y: e.Y - 2.5})
for i := 0; i < 120 && health.Current == 3; i++ {
e = sc.Local(pf.enemy).Position
p := sc.Local(pf.player).Position
sc.SetPosition(pf.player, mathx.Vec2{X: e.X, Y: p.Y})
pf.step(1)
}
if health.Current != 2 || health.Dead || !sc.IsAlive(pf.enemy) {
t.Fatalf("stomp should damage but not kill the enemy: %+v", health)
}
// AddVelocity is queued by Hit and consumed on the next fixed update.
pf.step(1)
if m := pf.motion(); m.Velocity.Y >= 0 {
t.Fatalf("nonlethal stomp did not bounce the player upward: %v", m.Velocity)
}
if got := pf.field("kills").Int(); got != 0 {
t.Fatalf("nonlethal stomp counted as %d kills", got)
}
pf.noFaults(t)
}
func TestPlatformerFoundryBackdropResolves(t *testing.T) {
pf := openPlatformer(t)
pf.step(3)
sc := pf.app.Scene
id, ok := pf.app.Pipeline.Lookup("assets/sprites/foundry_backdrop.png")
if !ok {
t.Fatal("foundry backdrop is missing from the asset pipeline")
}
for _, name := range []string{"FoundrySky1", "FoundrySky2", "FoundrySky3", "FoundrySky4", "FoundrySky5", "FoundrySky6", "FoundrySky7", "FoundrySky8"} {
node := sc.Find(sc.Root(), name)
sprite, ok := scene.Get[render2d.SpriteRenderer](sc, node)
if !ok || sprite.Sprite.ID != id {
t.Fatalf("%s does not reference the foundry backdrop", name)
}
}
if stats := pf.app.Runner.Stats(); stats.MissingAssets != 0 {
t.Fatalf("demo has missing assets: %+v", stats)
}
pf.noFaults(t)
}