Prepare to refactor movement to be based on attributes

This commit is contained in:
Marc Di Luzio 2020-06-04 18:54:33 +01:00
parent d0a5b91de7
commit 33f25a7414
8 changed files with 45 additions and 47 deletions

View file

@ -6,11 +6,12 @@ import "github.com/google/uuid"
type Command func() error type Command func() error
// CommandMove will move the instance in question // CommandMove will move the instance in question
func (w *World) CommandMove(id uuid.UUID, vec Vector) Command { func (w *World) CommandMove(id uuid.UUID, bearing float64, duration int64) Command {
return func() error { return func() error {
// Move the instance // TODO: Calculate the move itself
_, err := w.MovePosition(id, vec)
return err //_, err := w.MovePosition(id, vec)
return nil
} }
} }

View file

@ -16,7 +16,7 @@ func TestCommand_Spawn(t *testing.T) {
instance, ok := world.Instances[a] instance, ok := world.Instances[a]
assert.True(t, ok, "No new instance in world") assert.True(t, ok, "No new instance in world")
assert.Equal(t, a, instance.id, "New instance has incorrect id") assert.Equal(t, a, instance.Id, "New instance has incorrect id")
} }
func TestCommand_Move(t *testing.T) { func TestCommand_Move(t *testing.T) {
@ -27,24 +27,20 @@ func TestCommand_Move(t *testing.T) {
pos := Vector{ pos := Vector{
X: 1.0, X: 1.0,
Y: 2.0, Y: 2.0,
Z: 3.0,
} }
err := world.SetPosition(a, pos) err := world.SetPosition(a, pos)
assert.NoError(t, err, "Failed to set position for instance") assert.NoError(t, err, "Failed to set position for instance")
move := Vector{ // TODO: Test the bearing/duration movement
X: 3.0, /*
Y: 2.0, // Try the move command
Z: 1.0, moveCommand := world.CommandMove(a, move)
} assert.NoError(t, world.Execute(moveCommand), "Failed to execute move command")
// Try the move command newpos, err := world.GetPosition(a)
moveCommand := world.CommandMove(a, move) assert.NoError(t, err, "Failed to set position for instance")
assert.NoError(t, world.Execute(moveCommand), "Failed to execute move command") pos.Add(move)
assert.Equal(t, pos, newpos, "Failed to correctly set position for instance")
newpos, err := world.GetPosition(a) */
assert.NoError(t, err, "Failed to set position for instance")
pos.Add(move)
assert.Equal(t, pos, newpos, "Failed to correctly set position for instance")
} }

View file

@ -4,12 +4,10 @@ package game
type Vector struct { type Vector struct {
X float64 `json:"x"` X float64 `json:"x"`
Y float64 `json:"y"` Y float64 `json:"y"`
Z float64 `json:"z"`
} }
// Add adds one vector to another // Add adds one vector to another
func (v *Vector) Add(v2 Vector) { func (v *Vector) Add(v2 Vector) {
v.X += v2.X v.X += v2.X
v.Y += v2.Y v.Y += v2.Y
v.Z += v2.Z
} }

View file

@ -14,15 +14,19 @@ type World struct {
// Instance describes a single entity or instance of an entity in the world // Instance describes a single entity or instance of an entity in the world
type Instance struct { type Instance struct {
// id is a unique ID for this instance // Id is a unique ID for this instance
id uuid.UUID Id uuid.UUID `json:"id"`
// pos represents where this instance is in the world // Pos represents where this instance is in the world
pos Vector Pos Vector `json:"pos"`
// Speed represents the Speed that the instance will move per second
Speed float64 `json:"speed"`
// Sight represents the distance the unit can see
Sight float64 `json:"sight"`
} }
const kWorldFileName = "rove-world.json"
// NewWorld creates a new world object // NewWorld creates a new world object
func NewWorld() *World { func NewWorld() *World {
return &World{ return &World{
@ -38,7 +42,7 @@ func (w *World) Spawn(id uuid.UUID) error {
// Initialise the instance // Initialise the instance
instance := Instance{ instance := Instance{
id: id, Id: id,
} }
// Append the instance to the list // Append the instance to the list
@ -60,7 +64,7 @@ func (w *World) DestroyInstance(id uuid.UUID) error {
// GetPosition returns the position of a given instance // GetPosition returns the position of a given instance
func (w World) GetPosition(id uuid.UUID) (Vector, error) { func (w World) GetPosition(id uuid.UUID) (Vector, error) {
if i, ok := w.Instances[id]; ok { if i, ok := w.Instances[id]; ok {
return i.pos, nil return i.Pos, nil
} else { } else {
return Vector{}, fmt.Errorf("no instance matching id") return Vector{}, fmt.Errorf("no instance matching id")
} }
@ -69,7 +73,7 @@ func (w World) GetPosition(id uuid.UUID) (Vector, error) {
// SetPosition sets an instances position // SetPosition sets an instances position
func (w *World) SetPosition(id uuid.UUID, pos Vector) error { func (w *World) SetPosition(id uuid.UUID, pos Vector) error {
if i, ok := w.Instances[id]; ok { if i, ok := w.Instances[id]; ok {
i.pos = pos i.Pos = pos
w.Instances[id] = i w.Instances[id] = i
return nil return nil
} else { } else {
@ -80,9 +84,9 @@ func (w *World) SetPosition(id uuid.UUID, pos Vector) error {
// SetPosition sets an instances position // SetPosition sets an instances position
func (w *World) MovePosition(id uuid.UUID, vec Vector) (Vector, error) { func (w *World) MovePosition(id uuid.UUID, vec Vector) (Vector, error) {
if i, ok := w.Instances[id]; ok { if i, ok := w.Instances[id]; ok {
i.pos.Add(vec) i.Pos.Add(vec)
w.Instances[id] = i w.Instances[id] = i
return i.pos, nil return i.Pos, nil
} else { } else {
return Vector{}, fmt.Errorf("no instance matching id") return Vector{}, fmt.Errorf("no instance matching id")
} }

View file

@ -56,7 +56,6 @@ func TestWorld_GetSetMovePosition(t *testing.T) {
pos := Vector{ pos := Vector{
X: 1.0, X: 1.0,
Y: 2.0, Y: 2.0,
Z: 3.0,
} }
err := world.SetPosition(a, pos) err := world.SetPosition(a, pos)

View file

@ -1,7 +1,5 @@
package server package server
import "github.com/mdiluz/rove/pkg/game"
// ============================== // ==============================
// API: /status method: GET // API: /status method: GET
// Queries the status of the server // Queries the status of the server
@ -45,7 +43,9 @@ type SpawnResponse struct {
Success bool `json:"success"` Success bool `json:"success"`
Error string `json:"error"` Error string `json:"error"`
Position game.Vector `json:"position"` // The location of the spawned entity
X float64 `json:"x"`
Y float64 `json:"y"`
} }
// ============================== // ==============================
@ -76,7 +76,8 @@ type Command struct {
Command string `json:"command"` Command string `json:"command"`
// Used for CommandMove // Used for CommandMove
Vector game.Vector `json:"vector"` Bearing float64 `json:"bearing"` // The direction to move in degrees
Duration int64 `json:"duration"` // The duration of the move in seconds
} }
// ================ // ================

View file

@ -135,7 +135,8 @@ func HandleSpawn(s *Server, b io.ReadCloser, w io.Writer) error {
response.Error = err.Error() response.Error = err.Error()
} else { } else {
response.Success = true response.Success = true
response.Position = pos response.X = pos.X
response.Y = pos.Y
} }
} }
@ -179,7 +180,7 @@ func HandleCommands(s *Server, b io.ReadCloser, w io.Writer) error {
for _, c := range data.Commands { for _, c := range data.Commands {
switch c.Command { switch c.Command {
case CommandMove: case CommandMove:
cmds = append(cmds, s.world.CommandMove(inst, c.Vector)) cmds = append(cmds, s.world.CommandMove(inst, c.Bearing, c.Duration))
} }
} }

View file

@ -7,7 +7,6 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/mdiluz/rove/pkg/game"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -81,14 +80,13 @@ func TestHandleCommands(t *testing.T) {
// Spawn the primary instance for the account // Spawn the primary instance for the account
_, inst, err := s.SpawnPrimaryForAccount(a.Id) _, inst, err := s.SpawnPrimaryForAccount(a.Id)
move := game.Vector{X: 1, Y: 2, Z: 3}
data := CommandsData{ data := CommandsData{
Id: a.Id.String(), Id: a.Id.String(),
Commands: []Command{ Commands: []Command{
{ {
Command: CommandMove, Command: CommandMove,
Vector: move, Bearing: 0.0,
Duration: 1,
}, },
}, },
} }
@ -108,9 +106,9 @@ func TestHandleCommands(t *testing.T) {
t.Errorf("got false for /commands") t.Errorf("got false for /commands")
} }
if pos, err := s.world.GetPosition(inst); err != nil { if _, err := s.world.GetPosition(inst); err != nil {
t.Error("Couldn't get position for the primary instance") t.Error("Couldn't get position for the primary instance")
} else if pos != move {
t.Error("Mismatched position after commands")
} }
// TODO: Check position is correct
} }