Draw Lines Visualizing Doodad Links in Edit Mode

* If the current edit tool is Actor or Link, use the new drawtool.Stroke
  object to draw visual lines connecting every pair of linked actors in
  the level. The lines are hidden during normal editing and gameplay and
  only appear when you're possibly manipulating your actors and links.
physics
Noah 2019-07-03 16:51:23 -07:00
parent c8620f871e
commit 5d8c5510d8
2 changed files with 73 additions and 1 deletions

View File

@ -53,6 +53,14 @@ func (s *Supervisor) InstallScripts(level *level.Level) error {
for _, id := range actor.Links {
// Assign this target actor's Inbound channel to the source
// actor's array of Outbound channels.
if _, ok := s.scripts[id]; !ok {
log.Error("scripting.InstallScripts: actor %s is linked to %s but %s was not found",
actor.ID(),
id,
id,
)
continue
}
thisVM.Outbound = append(thisVM.Outbound, s.scripts[id].Inbound)
}
}

View File

@ -86,12 +86,76 @@ func (w *Canvas) RedoStroke() bool {
// presentStrokes is called as part of Present() and draws the strokes whose
// pixels are currently visible within the viewport.
func (w *Canvas) presentStrokes(e render.Engine) {
// Turn stroke map into a list.
var strokes []*drawtool.Stroke
for _, stroke := range w.strokes {
strokes = append(strokes, stroke)
}
w.drawStrokes(e, strokes)
// Dynamic actor links visible in the ActorTool and LinkTool.
if w.Tool == ActorTool || w.Tool == LinkTool {
w.presentActorLinks(e)
}
}
// presentActorLinks draws strokes connecting actors together by their links.
// TODO: the strokes are computed dynamically every tick in here, might be a
// way to better optimize later.
func (w *Canvas) presentActorLinks(e render.Engine) {
var (
strokes = []*drawtool.Stroke{}
actorMap = map[string]*Actor{}
)
// Loop over actors and collect linked ones into the map.
for _, actor := range w.actors {
if len(actor.Actor.Links) > 0 {
actorMap[actor.ID()] = actor
}
}
// Loop over the linked actors and draw stroke lines.
for _, actor := range actorMap {
for _, linkID := range actor.Actor.Links {
if _, ok := actorMap[linkID]; !ok {
continue
}
var (
aP = actor.Position()
aS = actor.Size()
bP = actorMap[linkID].Position()
bS = actorMap[linkID].Size()
)
// Draw a line connecting the centers of each actor together.
stroke := drawtool.NewStroke(drawtool.Line, render.Magenta)
stroke.PointA = render.Point{
X: aP.X + (aS.W / 2),
Y: aP.Y + (aS.H / 2),
}
stroke.PointB = render.Point{
X: bP.X + (bS.W / 2),
Y: bP.Y + (bS.H / 2),
}
strokes = append(strokes, stroke)
}
}
w.drawStrokes(e, strokes)
}
// drawStrokes is the common base function behind presentStrokes and
// presentActorLinks to actually draw the lines to the canvas.
func (w *Canvas) drawStrokes(e render.Engine, strokes []*drawtool.Stroke) {
var (
P = ui.AbsolutePosition(w) // w.Point() // Canvas point in UI
VP = w.ViewportRelative() // Canvas scroll viewport
)
for _, stroke := range w.strokes {
for _, stroke := range strokes {
for point := range stroke.IterPoints() {
if !point.Inside(VP) {
continue