Scripting: Bring Self API up to Actor API parity
Updates the Self API to expose more uix.Actor fields: * Doodad() * GetBoundingRect() * HasGravity() * IsFrozen() * IsMobile() * LayerCount() * ListItems() * SetGrounded() * SetWet() * Velocity() - note: it was Self.GetVelocity() before. Self.GetVelocity is deprecated and made an alias to Velocity.
This commit is contained in:
parent
21847f5e57
commit
c4456ac51b
56
README.md
56
README.md
|
@ -49,6 +49,16 @@ game:
|
||||||
* If you receive a map with custom doodads, you can **install** the doodads
|
* If you receive a map with custom doodads, you can **install** the doodads
|
||||||
into your copy of the game and use them in your own maps.
|
into your copy of the game and use them in your own maps.
|
||||||
|
|
||||||
|
# Developer Documentation
|
||||||
|
|
||||||
|
In case you are reading this from the game's open source repository, take a
|
||||||
|
look in the `docs/` folder or the `*.md` files in the root of the repository.
|
||||||
|
|
||||||
|
Some to start with:
|
||||||
|
|
||||||
|
* [Building](Building.md) the game (tl;dr. run bootstrap.py)
|
||||||
|
* [Tour of the Code](docs/Tour%20of%20the%20Code.md)
|
||||||
|
|
||||||
# Keybindings
|
# Keybindings
|
||||||
|
|
||||||
Global Keybindings:
|
Global Keybindings:
|
||||||
|
@ -134,52 +144,6 @@ four directions but characters with gravity only move left and right
|
||||||
and have the dedicated "Jump" button. This differs from regular
|
and have the dedicated "Jump" button. This differs from regular
|
||||||
keyboard controls where the Up arrow is to Jump.
|
keyboard controls where the Up arrow is to Jump.
|
||||||
|
|
||||||
# Built-In Doodads
|
|
||||||
|
|
||||||
A brief introduction to the built-in doodads available so far:
|
|
||||||
|
|
||||||
- **Characters**
|
|
||||||
- Blue Azulian: this is used as the player character for now. If
|
|
||||||
dragged into a level, it doesn't do anything but is affected
|
|
||||||
by gravity.
|
|
||||||
- Red Azulian: an example mobile mob for now. It walks back and
|
|
||||||
forth, changing directions only when it comes across an
|
|
||||||
obstacle and can't proceed any further.
|
|
||||||
- **Doors and Keys**
|
|
||||||
- Colored Doors: these act like solid barriers until the player or
|
|
||||||
another doodad collects the matching colored key.
|
|
||||||
- Colored Keys: these are collectable items that allow the player or
|
|
||||||
another doodad to open the door of matching color. Note that
|
|
||||||
inventories are doodad-specific, so other mobs besides the
|
|
||||||
player can steal a key before the player gets it! (For now)
|
|
||||||
- Electric Door: this mechanical door stays closed and only
|
|
||||||
opens when it receives a power signal from a linked button.
|
|
||||||
- Trapdoor: this door allows one-way access, but once it's closed
|
|
||||||
behind you, you can't pass through it from that side!
|
|
||||||
- **Buttons**
|
|
||||||
- Button: while pressed by a player or other doodad, the button
|
|
||||||
emits a power signal to any doodad it is linked to. Link a button
|
|
||||||
to an electric door, and the door will open while the button is
|
|
||||||
pressed and close when the button is released.
|
|
||||||
- Sticky Button: this button will stay pressed once activated and
|
|
||||||
will not release unless it receives a power signal from another
|
|
||||||
linked doodad. For example, one Button that links to a Sticky
|
|
||||||
Button will release the sticky button if pressed.
|
|
||||||
- **Switches**
|
|
||||||
- Switch: when touched by the player or other doodad, the switch will
|
|
||||||
toggle its state from "OFF" to "ON" or vice versa. Link it to an
|
|
||||||
Electric Door to open/close the door. Link switches _to each other_ as
|
|
||||||
well as to a door, and all switches will stay in sync with their ON/OFF
|
|
||||||
state when any switch is pressed.
|
|
||||||
- **Crumbly Floor**
|
|
||||||
- This rocky floor will break and fall away after being stepped on.
|
|
||||||
- **Two State Blocks**
|
|
||||||
- Blue and orange blocks that will toggle between solid and pass-thru
|
|
||||||
whenever the corresponding ON/OFF block is hit.
|
|
||||||
- **Start and Exit Flags**
|
|
||||||
- The "Go" flag lets you pick a spawn point for the player character.
|
|
||||||
- The "Exit" flag marks the level goal.
|
|
||||||
|
|
||||||
# Developer Console
|
# Developer Console
|
||||||
|
|
||||||
Press `Enter` at any time to open the developer console. The console
|
Press `Enter` at any time to open the developer console. The console
|
||||||
|
|
57
docs/Tour of the Code.md
Normal file
57
docs/Tour of the Code.md
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# Tour of the Code
|
||||||
|
|
||||||
|
Here is a brief tour of where to find important parts of the game's code.
|
||||||
|
|
||||||
|
## Basic App Structure
|
||||||
|
|
||||||
|
**cmd/doodle/main.go** is the main function for Sketchy Maze and handles the command line flags and bootstrapping the game.
|
||||||
|
|
||||||
|
**pkg/doodle.go** holds the root Doodle (`d`) struct, the base object for the meat of the program - its setup funcs and MainLoop are here.
|
||||||
|
|
||||||
|
### Scenes
|
||||||
|
|
||||||
|
The gameplay is divided into scenes, each in a **pkg/\*_scene.go** file:
|
||||||
|
|
||||||
|
* MainScene is the title screen (default)
|
||||||
|
* PlayScene is play mode
|
||||||
|
* EditScene is the level editor, etc.
|
||||||
|
|
||||||
|
**pkg/scene.go** defines the interface for Scene itself and the `d.Goto(scene)` function.
|
||||||
|
|
||||||
|
The game changes scenes with Goto and the MainLoop calls the active scene's functions (Loop and Draw).
|
||||||
|
|
||||||
|
## Doodad JavaScript API
|
||||||
|
|
||||||
|
### pkg/scripting
|
||||||
|
|
||||||
|
This package provides the generic JavaScript API used by the developer console and doodads.
|
||||||
|
|
||||||
|
**pkg/scripting/js_api.go** defines global and generic JavaScript functions to doodads' scope, e.g.:
|
||||||
|
|
||||||
|
* console.log and friends
|
||||||
|
* Sound.Play
|
||||||
|
* RGBA, Point, and Vector
|
||||||
|
* Flash, GetTick
|
||||||
|
* time.Now() and friends
|
||||||
|
* Events
|
||||||
|
* setTimeout, setInterval..
|
||||||
|
* Self: provided externally.
|
||||||
|
|
||||||
|
### pkg/uix/scripting.go
|
||||||
|
|
||||||
|
The home of **MakeScriptAPI()** which installs various Play Mode objects into the script's environment, e.g.
|
||||||
|
|
||||||
|
* Actors and Level API
|
||||||
|
* Self: a surface of uix.Actor capabilities that point to the local actor.
|
||||||
|
|
||||||
|
## Collision Detection
|
||||||
|
|
||||||
|
### pkg/collision
|
||||||
|
|
||||||
|
The algorithmic stuff is here - the collision package focused on just the math and general types to handle logic for:
|
||||||
|
|
||||||
|
* Collision with level geometry ('pixel perfect')
|
||||||
|
* Collision between actors
|
||||||
|
* BoundingRect and collision boxes
|
||||||
|
|
||||||
|
### pkg/uix/actor_collision.go
|
|
@ -93,60 +93,10 @@ func (w *Canvas) MakeSelfAPI(actor *Actor) map[string]interface{} {
|
||||||
"Filename": actor.Doodad().Filename,
|
"Filename": actor.Doodad().Filename,
|
||||||
"Title": actor.Doodad().Title,
|
"Title": actor.Doodad().Title,
|
||||||
|
|
||||||
// functions
|
/*
|
||||||
"ID": actor.ID,
|
Unique options to the Self API over regular Actors.
|
||||||
"Size": actor.Size,
|
*/
|
||||||
"GetTag": actor.Doodad().Tag,
|
|
||||||
"Options": actor.Options,
|
|
||||||
"GetOption": func(name string) interface{} {
|
|
||||||
opt := actor.GetOption(name)
|
|
||||||
if opt == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return opt.Value
|
|
||||||
},
|
|
||||||
"Position": actor.Position,
|
|
||||||
"MoveTo": func(p render.Point) {
|
|
||||||
actor.MoveTo(p)
|
|
||||||
actor.SetGrounded(false)
|
|
||||||
},
|
|
||||||
"MoveBy": func(p render.Point) {
|
|
||||||
actor.MoveBy(p)
|
|
||||||
actor.SetGrounded(false)
|
|
||||||
},
|
|
||||||
"IsOnScreen": actor.IsOnScreen,
|
|
||||||
// // TODO: passing this to actor.IsOnScreen didn't work?
|
|
||||||
// return actor.Position().Inside(actor.Canvas.ViewportRelative())
|
|
||||||
// },
|
|
||||||
"Grounded": actor.Grounded,
|
|
||||||
"SetHitbox": actor.SetHitbox,
|
|
||||||
"Hitbox": actor.Hitbox,
|
|
||||||
"SetVelocity": actor.SetVelocity,
|
|
||||||
"GetVelocity": actor.Velocity,
|
|
||||||
"SetMobile": actor.SetMobile,
|
|
||||||
"SetInventory": actor.SetInventory,
|
|
||||||
"HasInventory": actor.HasInventory,
|
|
||||||
"SetGravity": actor.SetGravity,
|
|
||||||
"Invulnerable": actor.Invulnerable,
|
|
||||||
"SetInvulnerable": actor.SetInvulnerable,
|
|
||||||
"AddAnimation": actor.AddAnimation,
|
|
||||||
"IsAnimating": actor.IsAnimating,
|
|
||||||
"IsPlayer": actor.IsPlayer,
|
|
||||||
"PlayAnimation": actor.PlayAnimation,
|
|
||||||
"StopAnimation": actor.StopAnimation,
|
|
||||||
"ShowLayer": actor.ShowLayer,
|
|
||||||
"ShowLayerNamed": actor.ShowLayerNamed,
|
|
||||||
"Inventory": actor.Inventory,
|
|
||||||
"AddItem": actor.AddItem,
|
|
||||||
"RemoveItem": actor.RemoveItem,
|
|
||||||
"HasItem": actor.HasItem,
|
|
||||||
"ClearInventory": actor.ClearInventory,
|
|
||||||
"Destroy": actor.Destroy,
|
|
||||||
"Freeze": actor.Freeze,
|
|
||||||
"Unfreeze": actor.Unfreeze,
|
|
||||||
"IsWet": actor.IsWet,
|
|
||||||
"Hide": actor.Hide,
|
|
||||||
"Show": actor.Show,
|
|
||||||
"GetLinks": func() []map[string]interface{} {
|
"GetLinks": func() []map[string]interface{} {
|
||||||
var result = []map[string]interface{}{}
|
var result = []map[string]interface{}{}
|
||||||
for _, linked := range w.GetLinkedActors(actor) {
|
for _, linked := range w.GetLinkedActors(actor) {
|
||||||
|
@ -160,5 +110,80 @@ func (w *Canvas) MakeSelfAPI(actor *Actor) map[string]interface{} {
|
||||||
// Update the doodad that the camera should focus on.
|
// Update the doodad that the camera should focus on.
|
||||||
w.FollowActor = actor.ID()
|
w.FollowActor = actor.ID()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// functions
|
||||||
|
|
||||||
|
"GetTag": actor.Doodad().Tag,
|
||||||
|
|
||||||
|
/*
|
||||||
|
Expose the uix.Actor API surface area, in the same order
|
||||||
|
that these functions are defined in their respective files
|
||||||
|
to keep it easy to maintain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// actor.go
|
||||||
|
"ID": actor.ID,
|
||||||
|
"Doodad": actor.Doodad,
|
||||||
|
"SetGravity": actor.SetGravity,
|
||||||
|
"SetMobile": actor.SetMobile,
|
||||||
|
"SetInventory": actor.SetInventory,
|
||||||
|
"IsMobile": actor.IsMobile,
|
||||||
|
"IsPlayer": actor.IsPlayer,
|
||||||
|
"HasInventory": actor.HasInventory,
|
||||||
|
"HasGravity": actor.HasGravity,
|
||||||
|
"Invulnerable": actor.Invulnerable,
|
||||||
|
"SetInvulnerable": actor.SetInvulnerable,
|
||||||
|
"IsWet": actor.IsWet,
|
||||||
|
"IsOnScreen": actor.IsOnScreen,
|
||||||
|
"SetWet": actor.SetWet,
|
||||||
|
"Size": actor.Size,
|
||||||
|
"Velocity": actor.Velocity,
|
||||||
|
"GetVelocity": actor.Velocity, // TODO: deprecated, old Self.GetVelocity inconsistency
|
||||||
|
"SetVelocity": actor.SetVelocity,
|
||||||
|
"Position": actor.Position,
|
||||||
|
"MoveTo": func(p render.Point) {
|
||||||
|
actor.MoveTo(p)
|
||||||
|
actor.SetGrounded(false)
|
||||||
|
},
|
||||||
|
"MoveBy": func(p render.Point) {
|
||||||
|
actor.MoveBy(p)
|
||||||
|
actor.SetGrounded(false)
|
||||||
|
},
|
||||||
|
"Grounded": actor.Grounded,
|
||||||
|
"SetGrounded": actor.SetGrounded,
|
||||||
|
"IsCoyoteTime": actor.IsCoyoteTime,
|
||||||
|
"Hide": actor.Hide,
|
||||||
|
"Show": actor.Show,
|
||||||
|
"Freeze": actor.Freeze,
|
||||||
|
"Unfreeze": actor.Unfreeze,
|
||||||
|
"IsFrozen": actor.IsFrozen,
|
||||||
|
// Not: SetUsing, SetNoclip
|
||||||
|
"AddItem": actor.AddItem,
|
||||||
|
"RemoveItem": actor.RemoveItem,
|
||||||
|
"ClearInventory": actor.ClearInventory,
|
||||||
|
"HasItem": actor.HasItem,
|
||||||
|
"ListItems": actor.ListItems,
|
||||||
|
"Inventory": actor.Inventory,
|
||||||
|
"GetBoundingRect": actor.GetBoundingRect,
|
||||||
|
"SetHitbox": actor.SetHitbox,
|
||||||
|
"Hitbox": actor.Hitbox,
|
||||||
|
"Options": actor.Options,
|
||||||
|
"GetOption": func(name string) interface{} {
|
||||||
|
opt := actor.GetOption(name)
|
||||||
|
if opt == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return opt.Value
|
||||||
|
},
|
||||||
|
"LayerCount": actor.LayerCount,
|
||||||
|
"ShowLayer": actor.ShowLayer,
|
||||||
|
"ShowLayerNamed": actor.ShowLayerNamed,
|
||||||
|
"Destroy": actor.Destroy,
|
||||||
|
|
||||||
|
// actor_animation.go
|
||||||
|
"AddAnimation": actor.AddAnimation,
|
||||||
|
"PlayAnimation": actor.PlayAnimation,
|
||||||
|
"IsAnimating": actor.IsAnimating,
|
||||||
|
"StopAnimation": actor.StopAnimation,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user