Doodad Linking #7

Closed
opened 2019-05-07 21:05:54 +00:00 by kirsle · 0 comments

Add the ability for doodads to link to other doodads, so that buttons can connect to doors and open them when pushed.

All doodads have the ability to link to any other doodad, whether it makes sense or not. For example, two buttons linked together would have no effect.

Pub/Sub Message Passing

In the JavaScript API for the doodads, implement a pub/sub system where a doodad can listen for named events from linked doodads and publish named events to linked doodads.

// Buttons might publish a "power" event to all linked doodads
Events.OnCollide(function(e) {
    Events.Publish("power", true);
}

// Doors would listen for "power" events to toggle their state.
Events.Subscribe("power", function(state) {
    Self.PlayAnimation(state ? "open" : "close", null);
});

// API usage of these functions:
Events.Publish(name[, arguments...]);
Events.Subscribe(name, function([arguments...]) {});

Each pub/sub message would have a name (string) and pass arbitrary arguments that would be related to the name. Some event names would be Well Known for common behaviors:

  • power(bool): invoked by buttons and switches to pass a boolean "powered" flag.
    • Buttons would pass true when pressed and false when released.
    • Sticky buttons would pass true when pressed and then stay pressed.
    • Electric doors would open when they receive power(true) and close when they receive power(false)
  • default(): for subscribers only, a "default" event would be invoked as a catch-all for ALL events passed to the doodad. Might be useful for some doodads?

Data Structure

To store the link data in the level file, it would be a stored as mutual ID lists between one actor's ID and the other. Something like,

// Actor is an instance of a Doodad in the level.
type Actor struct {
	id       string       // NOTE: read only, use ID() to access.
	Filename string       `json:"filename"` // like "exit.doodad"
	Point    render.Point `json:"point"`
	Links    map[string]interface{} `json:"links"`
}

Editor Mode User Interface

For a quick first pass:

  • Add an editor tool called "Link" (to join the "Pencil" and "Doodad" tools).
    • Add a button to enter the "Link" mode, probably put it on the Doodad Palette window.
    • In "Link" mode, you can click one of the doodads on the level (similar to the current Doodad tool, where you can click and drag/drop doodads).
    • A text flash would prompt you to click the doodad to link to it.
    • Clicking the second doodad would create the link between them and go back to the Doodad tool.
  • Example workflow:
    1. User clicks the Doodads button on the palette window and drags in some buttons and doors.
    2. User clicks the "Link" button and are prompted to click on a doodad.
    3. User clicks a Button and then is prompted to click the second doodad.
    4. User clicks a Door.
    5. In the level data structure, the Button actor puts the Door's UUID into its link map and the Door actor puts the Button's UUID into its (making a two-way mutual link)

For a better user experience, the Link tool should be seamlessly integrated into the Doodad tool:

  • In the Doodad tool, currently, when you mouse over an actor on your level it draws an orange outline around its canvas and you can click it to drag and reposition the doodad in the level.
  • Inside this orange box, add a small "Link" button in the top-left corner of the box.
  • If the user clicks inside the "Link" button, this will switch to the Link tool and automatically select the current actor and the user only needs to click the second one to link to.
  • During the Link tool, an orange line should connect the first actor to the mouse cursor.
  • When the user clicks the second actor, the two actors are linked together and it returns to the Doodad tool.
    • If the user clicks something other than an actor, cancel the Link tool and return to the Doodad tool.
  • In the Doodad tool, all pairs of doodads that are linked should have lines connecting between them at all times. The link lines disappear in normal drawing mode and in play mode.

When a doodad is deleted from the level in the Doodad tool, delete all mutual links between that doodad and others.

Add the ability for doodads to link to other doodads, so that buttons can connect to doors and open them when pushed. All doodads have the ability to link to any other doodad, whether it makes sense or not. For example, two buttons linked together would have no effect. ## Pub/Sub Message Passing In the JavaScript API for the doodads, implement a pub/sub system where a doodad can listen for named events from linked doodads and publish named events to linked doodads. ```javascript // Buttons might publish a "power" event to all linked doodads Events.OnCollide(function(e) { Events.Publish("power", true); } // Doors would listen for "power" events to toggle their state. Events.Subscribe("power", function(state) { Self.PlayAnimation(state ? "open" : "close", null); }); // API usage of these functions: Events.Publish(name[, arguments...]); Events.Subscribe(name, function([arguments...]) {}); ``` Each pub/sub message would have a name (string) and pass arbitrary arguments that would be related to the name. Some event names would be Well Known for common behaviors: * `power(bool)`: invoked by buttons and switches to pass a boolean "powered" flag. * Buttons would pass `true` when pressed and `false` when released. * Sticky buttons would pass `true` when pressed and then stay pressed. * Electric doors would open when they receive `power(true)` and close when they receive `power(false)` * `default()`: for subscribers only, a "default" event would be invoked as a catch-all for ALL events passed to the doodad. Might be useful for some doodads? ## Data Structure To store the link data in the level file, it would be a stored as mutual ID lists between one actor's ID and the other. Something like, ```go // Actor is an instance of a Doodad in the level. type Actor struct { id string // NOTE: read only, use ID() to access. Filename string `json:"filename"` // like "exit.doodad" Point render.Point `json:"point"` Links map[string]interface{} `json:"links"` } ``` ## Editor Mode User Interface For a quick first pass: * Add an editor tool called "Link" (to join the "Pencil" and "Doodad" tools). * Add a button to enter the "Link" mode, probably put it on the Doodad Palette window. * In "Link" mode, you can click one of the doodads on the level (similar to the current Doodad tool, where you can click and drag/drop doodads). * A text flash would prompt you to click the doodad to link to it. * Clicking the second doodad would create the link between them and go back to the Doodad tool. * Example workflow: 1. User clicks the Doodads button on the palette window and drags in some buttons and doors. 2. User clicks the "Link" button and are prompted to click on a doodad. 3. User clicks a Button and then is prompted to click the second doodad. 4. User clicks a Door. 5. In the level data structure, the Button actor puts the Door's UUID into its link map and the Door actor puts the Button's UUID into its (making a two-way mutual link) For a better user experience, the Link tool should be seamlessly integrated into the Doodad tool: * In the Doodad tool, currently, when you mouse over an actor on your level it draws an orange outline around its canvas and you can click it to drag and reposition the doodad in the level. * Inside this orange box, add a small "Link" button in the top-left corner of the box. * If the user clicks inside the "Link" button, this will switch to the Link tool and automatically select the current actor and the user only needs to click the second one to link to. * During the Link tool, an orange line should connect the first actor to the mouse cursor. * When the user clicks the second actor, the two actors are linked together and it returns to the Doodad tool. * If the user clicks something other than an actor, cancel the Link tool and return to the Doodad tool. * In the Doodad tool, all pairs of doodads that are linked should have lines connecting between them at all times. The link lines disappear in normal drawing mode and in play mode. When a doodad is deleted from the level in the Doodad tool, delete all mutual links between that doodad and others.
kirsle added this to the First Beta Release MVP milestone 2019-05-07 21:05:54 +00:00
Sign in to join this conversation.
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: SketchyMaze/doodle#7
There is no content yet.