diff --git a/cardinal/component/movement.go b/cardinal/component/movement.go new file mode 100644 index 0000000..28205a2 --- /dev/null +++ b/cardinal/component/movement.go @@ -0,0 +1,28 @@ +package component + +type Direction struct { + X int + Y int +} + +var Directions = map[int]Direction{ + 0: {1, 0}, // right + 1: {-1, 0}, // left + 2: {0, -1}, // up + 3: {0, 1}, // down +} + +type Location struct { + X float32 + Y float32 +} + +type Movement struct { + Direction Direction + Velocity float32 + Location Location +} + +func (Movement) Name() string { + return "Movement" +} diff --git a/cardinal/main.go b/cardinal/main.go index 9e32068..089b0cb 100644 --- a/cardinal/main.go +++ b/cardinal/main.go @@ -12,6 +12,15 @@ import ( "shantanu-starter-game/system" ) +/* + TODO: +1. setup a new component and system for movement. +2. should take in direction and have an onTick flow to lerp from current position to new position. +3. whenever you get a new position, you should validate if its close enought to lerped position. +4. if its close enough, you should update to that position continue lerping. +5. if its not close enough, you should throw a an error. Client should handle this error and try again. +*/ + func main() { w, err := cardinal.NewWorld(cardinal.WithDisableSignatureVerification()) if err != nil { diff --git a/cardinal/system/MovementSystem.go b/cardinal/system/MovementSystem.go new file mode 100644 index 0000000..51d0a87 --- /dev/null +++ b/cardinal/system/MovementSystem.go @@ -0,0 +1,30 @@ +package system + +import ( + "pkg.world.dev/world-engine/cardinal" + "pkg.world.dev/world-engine/cardinal/search/filter" + "pkg.world.dev/world-engine/cardinal/types" + comp "shantanu-starter-game/component" +) + +// RegenSystem replenishes the player's HP at every tick. +// This provides an example of a system that doesn't rely on a transaction to update a component. +func MovementSystem(world cardinal.WorldContext) error { + return cardinal.NewSearch().Entity( + filter.Exact(filter.Component[comp.Player](), filter.Component[comp.Movement]())). + Each(world, func(id types.EntityID) bool { + movement, err := cardinal.GetComponent[comp.Movement](world, id) + if err != nil { + return true + } + + // TODO: How to get delta time? + movement.Location.X += movement.Velocity * float32(movement.Direction.X) + movement.Location.Y += movement.Velocity * float32(movement.Direction.Y) + + if err := cardinal.SetComponent[comp.Movement](world, id, movement); err != nil { + return true + } + return true + }) +}