entities tickingggg

master
Jordan Orelli 4 years ago
parent 4496e97515
commit 69902a8009

@ -94,6 +94,7 @@ func (s *Server) createSession(conn *websocket.Conn) *session {
} }
s.waitOnSessions.Add(1) s.waitOnSessions.Add(1)
s.sessions[sn.id] = sn s.sessions[sn.id] = sn
sn.entityID = s.world.SpawnPlayer(sn.id)
s.Info("created session %d, %d sessions active", sn.id, len(s.sessions)) s.Info("created session %d, %d sessions active", sn.id, len(s.sessions))
return sn return sn
} }
@ -106,6 +107,7 @@ func (s *Server) dropSession(sn *session) {
close(sn.done) close(sn.done)
delete(s.sessions, sn.id) delete(s.sessions, sn.id)
s.world.DespawnPlayer(sn.entityID)
s.waitOnSessions.Add(-1) s.waitOnSessions.Add(-1)
s.Info("dropped session %d after %v time connected, %d sessions active", sn.id, time.Since(sn.start), len(s.sessions)) s.Info("dropped session %d after %v time connected, %d sessions active", sn.id, time.Since(sn.start), len(s.sessions))
@ -146,6 +148,7 @@ func (s *Server) Shutdown() {
go func() { go func() {
defer wg.Done() defer wg.Done()
log := s.Child("http") log := s.Child("http")
log.Info("shutting down http server") log.Info("shutting down http server")
if err := s.http.Shutdown(context.Background()); err != nil { if err := s.http.Shutdown(context.Background()); err != nil {

@ -12,11 +12,12 @@ import (
type session struct { type session struct {
*blammo.Log *blammo.Log
id int id int
start time.Time entityID int
conn *websocket.Conn start time.Time
outbox chan wire.Response conn *websocket.Conn
done chan bool outbox chan wire.Response
done chan bool
} }
// run is the session run loop. // run is the session run loop.

@ -4,6 +4,8 @@ import "time"
// entity is any entity that can be simulated. // entity is any entity that can be simulated.
type entity interface { type entity interface {
id() int
// update is the standard tick function // update is the standard tick function
update(time.Duration) update(time.Duration)
} }

@ -1,5 +1,20 @@
package sim package sim
import (
"time"
"github.com/jordanorelli/blammo"
)
// player represents a player character in the simulation // player represents a player character in the simulation
type player struct { type player struct {
*blammo.Log
sessionID int
entityID int
} }
func (p *player) update(dt time.Duration) {
p.Info("tick")
}
func (p *player) id() int { return p.entityID }

@ -1,7 +1,25 @@
package sim package sim
import (
"time"
"github.com/jordanorelli/blammo"
)
type room struct { type room struct {
*blammo.Log
name string
origin point origin point
width int width int
height int height int
tiles []tile
}
func (r *room) update(dt time.Duration) {
r.Info("updating room")
for _, t := range r.tiles {
for _, e := range t.contents {
e.update(dt)
}
}
} }

@ -1,6 +1,30 @@
package sim package sim
// tile is an individual cell within the world simulation. Everything happens
// on a tile.
type tile struct { type tile struct {
floor floor // floor is the surface for the tile. All things sit atop the floor. The
contents []entity // floor informs clients how to draw the tile in the event that the tile's
// contents are empty. The floor also determins whether or not the tile is
// traversable.
floor floor
// contents is all of the entities on this tile. A given tile may have many
// entities.
contents map[int]entity
}
func (t *tile) addEntity(e entity) {
if t.contents == nil {
t.contents = make(map[int]entity)
}
t.contents[e.id()] = e
}
func (t *tile) removeEntity(id int) entity {
if e, here := t.contents[id]; here {
delete(t.contents, id)
return e
}
return nil
} }

@ -1,6 +1,7 @@
package sim package sim
import ( import (
"strconv"
"time" "time"
"github.com/jordanorelli/blammo" "github.com/jordanorelli/blammo"
@ -9,21 +10,24 @@ import (
// World is the entire simulated world. A world consists of many rooms. // World is the entire simulated world. A world consists of many rooms.
type World struct { type World struct {
*blammo.Log *blammo.Log
rooms []room rooms []room
done chan bool done chan bool
lastEntityID int
} }
func NewWorld(log *blammo.Log) *World { func NewWorld(log *blammo.Log) *World {
foyer := room{
Log: log.Child("foyer"),
name: "foyer",
origin: point{0, 0},
width: 10,
height: 10,
tiles: make([]tile, 100),
}
return &World{ return &World{
Log: log, Log: log,
rooms: []room{ rooms: []room{foyer},
room{ done: make(chan bool),
origin: point{0, 0},
width: 10,
height: 10,
},
},
done: make(chan bool),
} }
} }
@ -51,6 +55,36 @@ func (w *World) Stop() error {
return nil return nil
} }
func (w *World) SpawnPlayer(id int) int {
w.lastEntityID++
r := w.rooms[0]
w.Info("spawning player with id: %d into room %q", id, r.name)
t := &r.tiles[0]
p := player{
Log: w.Child("players").Child(strconv.Itoa(id)),
sessionID: id,
entityID: w.lastEntityID,
}
t.addEntity(&p)
return p.entityID
}
func (w *World) DespawnPlayer(id int) {
w.Info("despawning player with id: %d", id)
for _, r := range w.rooms {
for _, t := range r.tiles {
if e := t.removeEntity(id); e != nil {
w.Info("player removed from room %q", r.name)
return
}
}
}
w.Error("player was not found in any room")
}
func (w *World) tick(d time.Duration) { func (w *World) tick(d time.Duration) {
w.Info("tick. elapsed: %v", d) w.Info("tick. elapsed: %v", d)
for _, r := range w.rooms {
r.update(d)
}
} }

Loading…
Cancel
Save