114 lines
2.9 KiB
Go
114 lines
2.9 KiB
Go
package native
|
|
|
|
import (
|
|
"aego/core/mathx"
|
|
"aego/platform/input"
|
|
"aego/scene"
|
|
"aego/schema"
|
|
"aego/sdk"
|
|
)
|
|
|
|
type Rotator struct {
|
|
Speed float32 `aego:"speed,unit=rad/s"`
|
|
}
|
|
|
|
type Rotator3D struct {
|
|
Axis mathx.Vec3 `aego:"axis"`
|
|
Speed float32 `aego:"speed,unit=rad/s"`
|
|
}
|
|
|
|
type Health struct {
|
|
Max float32 `aego:"max,min=1,display=Max HP"`
|
|
Current float32 `aego:"current,min=0,display=Current HP"`
|
|
Regen float32 `aego:"regen,min=0,unit=hp/s,tip=Health restored per second"`
|
|
}
|
|
|
|
type Module struct{}
|
|
|
|
func Modules() []sdk.Module {
|
|
return []sdk.Module{Module{}}
|
|
}
|
|
|
|
func (Module) Info() sdk.ModuleInfo {
|
|
return sdk.ModuleInfo{ID: "game"}
|
|
}
|
|
|
|
func (Module) Register(r *sdk.Registry) error {
|
|
if err := sdk.Component[Rotator](r, sdk.Name("game.Rotator"), schema.Space(schema.Space2D)).
|
|
Category("Scripts").Display("Rotator").Icon("cat.scripts").Err(); err != nil {
|
|
return err
|
|
}
|
|
if err := sdk.Component[Rotator3D](r, sdk.Name("game.Rotator3D"), schema.Space(schema.Space3D)).
|
|
Category("Scripts").Display("Rotator 3D").Icon("cat.scripts").Err(); err != nil {
|
|
return err
|
|
}
|
|
if err := sdk.Component[Health](r, sdk.Name("game.Health")).
|
|
Category("Scripts").Display("Health").Icon("cat.scripts").Err(); err != nil {
|
|
return err
|
|
}
|
|
r.Template(sdk.TemplateDesc{ID: "game.enemy", Name: "Enemy", Category: "Actors", Setup: buildEnemy})
|
|
r.System(sdk.SystemDesc{ID: "game.rotate", Phase: sdk.PhaseUpdate, System: rotateSystem{}})
|
|
r.System(sdk.SystemDesc{ID: "game.rotate3d", Phase: sdk.PhaseUpdate, System: rotate3DSystem{}})
|
|
r.System(sdk.SystemDesc{ID: "game.health", Phase: sdk.PhaseUpdate, System: healthSystem{}})
|
|
registerEditor(r)
|
|
return nil
|
|
}
|
|
|
|
func buildEnemy(s *scene.Scene, h scene.NodeHandle) {
|
|
sr := scene.Add[sdk.SpriteRenderer](s, h)
|
|
*sr = sdk.DefaultSpriteRenderer()
|
|
sr.Size = mathx.Vec2{X: 1, Y: 1}
|
|
*scene.Add[Health](s, h) = Health{Max: 50, Current: 50, Regen: 2}
|
|
scene.Add[Rotator](s, h).Speed = 1
|
|
}
|
|
|
|
type rotateSystem struct{}
|
|
|
|
func (rotateSystem) Run(ctx *sdk.Context) {
|
|
s := sdk.SceneOf(ctx)
|
|
if s == nil {
|
|
return
|
|
}
|
|
dt := float32(ctx.Dt)
|
|
scene.Query1[Rotator](s).Each(func(h scene.NodeHandle, r *Rotator) {
|
|
t := s.Local(h)
|
|
t.Rotation += r.Speed * dt
|
|
s.SetLocal(h, t)
|
|
})
|
|
}
|
|
|
|
type rotate3DSystem struct{}
|
|
|
|
func (rotate3DSystem) Run(ctx *sdk.Context) {
|
|
s := sdk.SceneOf(ctx)
|
|
if s == nil {
|
|
return
|
|
}
|
|
dt := float32(ctx.Dt)
|
|
scene.Query1[Rotator3D](s).Each(func(h scene.NodeHandle, r *Rotator3D) {
|
|
axis := r.Axis
|
|
if axis.LenSq() < 1e-12 {
|
|
axis = mathx.Vec3{Y: 1}
|
|
}
|
|
q := mathx.QuatAxisAngle(axis, r.Speed*dt).Mul(s.Local3D(h).Rotation)
|
|
s.SetRotation3D(h, q.Normalized())
|
|
})
|
|
}
|
|
|
|
type healthSystem struct{}
|
|
|
|
func (healthSystem) Run(ctx *sdk.Context) {
|
|
s := sdk.SceneOf(ctx)
|
|
if s == nil {
|
|
return
|
|
}
|
|
hit := sdk.InputOf(ctx).KeyPressed(input.KeySpace)
|
|
dt := float32(ctx.Dt)
|
|
scene.Query1[Health](s).Each(func(_ scene.NodeHandle, hp *Health) {
|
|
if hit {
|
|
hp.Current = max(0, hp.Current-10)
|
|
}
|
|
hp.Current = min(hp.Max, hp.Current+hp.Regen*dt)
|
|
})
|
|
}
|