Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F119142
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
21 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/docs/ScriptAPI.txt b/docs/ScriptAPI.md
similarity index 69%
rename from docs/ScriptAPI.txt
rename to docs/ScriptAPI.md
index d14b2fc..aba6c35 100644
--- a/docs/ScriptAPI.txt
+++ b/docs/ScriptAPI.md
@@ -1,353 +1,428 @@
Me and My Shadow Script API Reference
=====================================
(draft)
The script language is Lua 5.2 (later we may bump it to 5.3).
-Always check ScriptAPI.cpp for the newest API changed unmentioned in this document.
+Always check `ScriptAPI.cpp` for the newest API changed unmentioned in this document.
How to edit script
==================
To edit the script of a block, right click the block and select "Scripting".
To edit the script of the level, right click the block and select "Scripting".
Currently the scenery block doesn't support scripting.
Available event types of block:
-"playerWalkOn": Fired once when the player walks on. (For example this is used in fragile block.)
-"playerIsOn": Fired every frame when the player is on.
-"playerLeave": Fired once when the player leaves.
-"onCreate": Fired when object creates.
-"onEnterFrame": Fired every frame.
-"onPlayerInteraction": Fired when the player press DOWN key. Currently this event only fires when the block type is TYPE_SWITCH.
-"onToggle": Fired when the block receives "toggle" from a switch/button.
-"onSwitchOn": Fired when the block receives "switch on" from a switch/button.
-"onSwitchOff": Fired when the block receives "switch off" from a switch/button.
+Event type | Description
+----------------------|--------------
+"playerWalkOn" | Fired once when the player walks on. (For example this is used in fragile block.)
+"playerIsOn" | Fired every frame when the player is on.
+"playerLeave" | Fired once when the player leaves.
+"onCreate" | Fired when object creates.
+"onEnterFrame" | Fired every frame.
+"onPlayerInteraction" | Fired when the player press DOWN key. Currently this event only fires when the block type is TYPE_SWITCH.
+"onToggle" | Fired when the block receives "toggle" from a switch/button.
+"onSwitchOn" | Fired when the block receives "switch on" from a switch/button.
+"onSwitchOff" | Fired when the block receives "switch off" from a switch/button.
NOTE: During the event execution the global variable "this" temporarily points to current block. (Ad-hoc workaround!)
When the event execution ends the global variable "this" is reset to `nil`.
Available event types of level:
-"onCreate": Fired when the level creates. This happens after all the blocks are created and their onCreate is called.
-"onSave": Fired when the game is saved.
-"onLoad": Fired when the game is loaded.
-"onReset": Fired when the game is reset.
+Event type | Description
+-----------|--------------
+"onCreate" | Fired when the level creates. This happens after all the blocks are created and their `onCreate` is called.
+"onSave" | Fired when the game is saved.
+"onLoad" | Fired when the game is loaded.
+"onReset" | Fired when the game is reset.
-For the newest lists of event types, see init() function in Functions.cpp.
+For the newest lists of event types, see `init()` function in `Functions.cpp`.
NOTE: the following methods to specify scripts can be used:
* Specify scripts for each events in the block script editing dialog.
* Only specify "onCreate" script in the block script editing dialog,
and use setEventHandler() function in script to specify scripts for other events dynamically.
* Only specify "onCreate" script in the level script editing dialog,
and use setEventHandler() function in script to specify scripts for other events for level/blocks dynamically.
Script API reference
====================
The "block" library
-------------------
### Static functions:
* getBlockById(id)
Returns the first block with specified id. If not found, returns `nil`.
Example:
+~~~
local b=block.getBlockById("1")
local x,y=b:getLocation()
print(x,y)
+~~~
* getBlocksById(id)
Returns the list of all blocks with specified id.
Example:
+~~~
local l=block.getBlocksById("1")
for i,b in ipairs(l) do
local x,y=b:getLocation()
print(x,y)
end
+~~~
### Member functions:
* moveTo(x,y)
Move the block to the new position, update the velocity of block according to the position changed.
Example:
+~~~
local b=block.getBlockById("1")
local x,y=b:getLocation()
b:moveTo(x+1,y)
+~~~
* getLocation()
Returns the position of the block.
Example: see the example for moveTo().
* setLocation(x,y)
Move the block to the new position without updating the velocity of block.
Example: omitted since it's almost the same as moveTo().
* growTo(w,h)
Resize the block, update the velocity of block according to the size changed.
NOTE: I don't think the velocity need to be updated when resizing block, so don't use this function.
Example: omitted since it's almost the same as setSize().
* getSize()
Returns the size of the block.
Example:
+~~~
local b=block.getBlockById("1")
local w,h=b:getSize()
print(w,h)
+~~~
* setSize(w,h)
Resize the block without updating the velocity of block.
Example:
+~~~
local b=block.getBlockById("1")
local w,h=b:getSize()
b:setSize(w+1,h)
+~~~
* getType()
Returns the type of the block (which is a string).
Example:
+~~~
local b=block.getBlockById("1")
local s=b:getType()
print(s)
+~~~
* changeThemeState(new_state)
Change the state of the block to new_state (which is a string).
Example:
+~~~
local b=block.getBlockById("1")
b:changeThemeState("activated")
+~~~
* setVisible(b)
Set the visibility the block.
NOTE: The default value is `true`. If set to `false` the block is hidden completely,
the animation is stopped, can't receive any event, can't execute any scripts (except for 'onCreate'),
can't be used as a portal destination,
doesn't participate in collision check and game logic, etc...
NOTE: This is a newly added feature.
If you find any bugs (e.g. if an invisible block still affects the game logic)
please report the bugs to GitHub issue tracker.
Example:
+~~~
local b=block.getBlockById("1")
if b:isVisible() then
b:setVisible(false)
else
b:setVisible(true)
end
+~~~
* isVisible()
Returns whether the block is visible.
Example: see the example for setVisible().
* getEventHandler(event_type)
Returns the event handler of event_type (which is a string).
Example:
+~~~
local b=block.getBlockById("1")
local f=b:getEventHandler("onSwitchOn")
b:setEventHandler("onSwitchOff",f)
+~~~
* setEventHandler(event_type,handler)
Set the handler of event_type (which is a string). The handler should be a function or `nil`.
Returns the previous event handler.
Example:
+~~~
local b=block.getBlockById("1")
b:setEventHandler("onSwitchOff",function()
print("I am switched off.")
end)
+~~~
* onEvent(eventType)
Fire an event to specified block.
NOTE: The event will be processed immediately.
Example:
+~~~
local b=block.getBlockById("1")
b:onEvent("onToggle")
+~~~
NOTE: Be careful not to write infinite recursive code! Bad example:
+~~~
-- onToggle event of a moving block
this:onEvent("onToggle")
+~~~
* isActivated() / setActivated(bool) -- get/set a boolean indicates if the block is activated
-- the block should be one of TYPE_MOVING_BLOCK, TYPE_MOVING_SHADOW_BLOCK, TYPE_MOVING_SPIKES,
TYPE_CONVEYOR_BELT, TYPE_SHADOW_CONVEYOR_BELT.
* isAutomatic() / setAutomatic(bool) -- get/set a boolean indicates if the portal is automatic
-- the block should be TYPE_PORTAL
* getBehavior() / setBehavior(str) -- get/set a string (must be "on", "off" or "toggle")
representing the behavior of the block -- the block should be TYPE_BUTTON, TYPE_SWITCH
* getState() / setState(num) -- get/set a number (must be 0,1,2 or 3)
representing the state of a fragile block -- the block should be TYPE_FRAGILE
* isPlayerOn() -- get a boolean indicates if the player is on -- only works for TYPE_BUTTON
* getPathMaxTime() -- get the total time of the path of a moving block
* getPathTime() / setPathTime(num) -- get/set the current time of the path of a moving block
* isLoop()/setLoop(bool) -- get/set the loop property of a moving block
The "playershadow" library
--------------------------
### Global constants:
* player
The player object.
* shadow
The shadow object.
### Member functions:
* getLocation()
Returns the location of player/shadow.
Example:
+~~~
print(player:getLocation())
print(shadow:getLocation())
+~~~
* setLocation(x,y)
Set the location of player/shadow.
Example:
+~~~
local x,y=player:getLocation()
player:setLocation(x+1,y)
+~~~
-* jump([strength])
+* jump([strength=13])
Let the player/shadow jump if it's allowed.
-strength: Jump strength. Default is 13.
+
+strength: Jump strength.
Example:
+~~~
player:jump(20)
+~~~
* isShadow()
Returns whether the current object is shadow.
Example:
+~~~
print(player:isShadow())
print(shadow:isShadow())
+~~~
* getCurrentStand()
Returns the block on which the player/shadow is standing on. Can be `nil`.
Example:
+~~~
local b=player:getCurrentStand()
if b then
print(b:getType())
else
print(nil)
end
+~~~
The "level" library
-------------------
### Static functions:
* getSize() -- get the level size
* getWidth() -- get the level width
* getHeight() -- get the level height
* getName() -- get the level name
* getEventHandler(event_type) -- get the event handler
* setEventHandler(event_type,handler) -- set the event handler, return the old handler
* win() -- win the game
* getTime() -- get the game time (in frames)
* getRecordings() -- get the game recordings
* broadcastObjectEvent(eventType,[objectType=nil],[id=nil],[target=nil])
Broadcast the event to blocks satisfying the specified condition.
NOTE: The event will be processed in next frame.
-eventType: string.
-objectType: string or nil. If this is set then the event is only received by the block with specified type.
-id: string or nil. If this is set then the event is only received by the block with specified id.
-target: block or nil. If this is set then the event is only received by the specified block.
+Argument name | Description
+--------------|-------------
+eventType | string.
+objectType | string or nil. If this is set then the event is only received by the block with specified type.
+id | string or nil. If this is set then the event is only received by the block with specified id.
+target | block or nil. If this is set then the event is only received by the specified block.
Example:
+~~~
level.broadcastObjectEvent("onToggle",nil,"1")
+~~~
The "camera" library
--------------------
### Static functions:
* setMode(mode) -- set the camera mode, which is "player" or "shadow"
* lookAt(x,y) -- set the camera mode to "custom" and set the new center of camera
The "audio" library
-------------------
-Documents to be written...
+NOTE: the following functions are not going to work if the sound/music volume is 0.
+
+### Static functions:
+
+* playSound(name[,concurrent=-1[,force=false[,fade=-1]]])
+
+Play a sound effect.
+
+Argument name | Description
+--------------|-------------
+name | The name of the sound effect. Currently available: "jump", "hit", "checkpoint", "swap", "toggle", "error", "collect", "achievement".
+concurrent | The number of times the same sfx can be played at once, -1 is unlimited. NOTE: there are 64 channels.
+force | If the sound muse be played even if all channels are used. In this case the sound effect in the first channel will be stopped.
+fade | A factor to temporarily turn the music volume down (0-128). -1 means don't use this feature.
+
+Return value: The channel of the sfx. -1 means failed (channel is full, invalid sfx name, sfx volume is 0, etc.)
+
+* playMusic(name[,fade=true])
+
+Play a music.
+
+Argument name | Description
+--------------|-------------
+name | The name of the song.
+fade | Boolean if it should fade the current one out or not.
+
+* pickMusic() - pick a song from the current music list.
+
+* setMusicList(name_of_the_music_list) - set the music list.
+
+* getMusicList() - get the music list.
+
+* currentMusic() - get the current music.
diff --git a/docs/ThemeDescription.txt b/docs/ThemeDescription.md
similarity index 60%
rename from docs/ThemeDescription.txt
rename to docs/ThemeDescription.md
index 3159c51..6c38359 100644
--- a/docs/ThemeDescription.txt
+++ b/docs/ThemeDescription.md
@@ -1,230 +1,269 @@
Me and My Shadow Theme File Description
=======================================
(draft)
The theme file contains:
+~~~
name=<theme name>
+~~~
+
+and the following subnode.
1 block subnode
---------------
+~~~
block(<block name>){...} //subnode specifies the block's appearance
+~~~
block name:
-"Block","PlayerStart","ShadowStart",
-"Exit","ShadowBlock","Spikes",
-"Checkpoint","Swap","Fragile",
-"MovingBlock","MovingShadowBlock","MovingSpikes",
-"Teleporter","Button","Switch",
-"ConveyorBelt","ShadowConveyorBelt","NotificationBlock", "Collectable", "Pushable".
+"Block", "PlayerStart", "ShadowStart",
+"Exit", "ShadowBlock", "Spikes",
+"Checkpoint", "Swap", "Fragile",
+"MovingBlock", "MovingShadowBlock", "MovingSpikes",
+"Teleporter", "Button", "Switch",
+"ConveyorBelt", "ShadowConveyorBelt", "NotificationBlock", "Collectable", "Pushable".
-For the newest version of this list, see Game::blockName in Game.cpp.
+For the newest version of this list, see `Game::blockName` in `Game.cpp`.
In this subnode:
-editorPicture(<file name>,<x>,<y>,<w>,<h>) //specifies the picture shows in editor
-
-1.1 state/characterState/blockState/transitionState subnode
-----------------------
+### 1.1 state/characterState/blockState/transitionState subnode
NOTE: blockState and characterState are for backwards compatibility, use state instead.
+~~~
blockState(<state name>){...} //subnode specifies the appearance of each state of the block
state(<state name>){...}
characterState(<state name>){...}
transitionState(<current state>,<new state>){...}
+~~~
the state name:
* for all blocks
- - "base": Always draw the base before other states.
+ - "base": Always draw the base before other states (intended to be used in level editor).
- "default": The default state.
* for "Checkpoint","Swap","Switch"
- "activated": The activated state.
* for "Collectable"
- "inactive": The collected state.
* for "Exit"
- "closed": The closed state.
* for "Button"
- "button": The button (which is a separated, movable part of the button).
* for "Fragile"
- "fragile1": The stepped once state.
- "fragile2": The stepped twice state.
- "fragile3": The broken state.
transition state:
If we found a transition state which matches the current state and the next state,
then we switch to this transition state instead of the new state.
NOTE: the transition state should have the oneTimeAnimation attribute and set the correct next state.
optional attributes:
+~~~
oneTimeAnimation=<length>,<next state> //if this state is one-time animation only
+~~~
-1.1.1 object subnode
---------------------
+#### 1.1.1 object subnode
+~~~
object{...} //subnode specifies (multiple) objects to display in each state
+~~~
optional attributes:
+~~~
animation=<length>,<loop point> //if object has looped animation
oneTimeAnimation=<length>,<end point>
invisibleAtRunTime=1 //if this object is invisible when playing game
invisibleAtDesignTime=1 //if this object is invisible when editing the map
+~~~
optional nodes specifies object to display:
-1.1.1.1 picture subnode
------------------------
+##### 1.1.1.1 picture subnode
+~~~
picture(<file name>,<x>,<y>,<w>,<h>)
+~~~
The (x,y,w,h) defines the source rectangle.
NOTE: picture and pictureAnimation are mutually exclusive. (?)
-1.1.1.2 optionalPicture subnode
--------------------------------
+##### 1.1.1.2 optionalPicture subnode
+~~~
optionalPicture(<file name>,<x>,<y>,<w>,<h>,<probability>)
+~~~
If this subnode is set, the picture will be randomly used according to the given probability.
-1.1.1.3 editorPicture subnode
------------------------------
+##### 1.1.1.3 editorPicture subnode
+~~~
editorPicture(<file name>,<x>,<y>,<w>,<h>)
+~~~
-If this subnode is set, the picture will be used in the level editor.
+If this subnode is set, the picture will be used instead in the level editor.
-1.1.1.4 positioning subnode
----------------------------
+##### 1.1.1.4 positioning subnode
+~~~
positioning(<xalign>,<yalign>)
+~~~
-xalign: 'left', 'centre' (NOTE: not 'center'), 'right' or 'repeat' or 'stretch'
-yalign: 'top', 'middle', 'bottom' or 'repeat' or 'stretch'
+* xalign: 'left', 'centre' (NOTE: not 'center'), 'right' or 'repeat' or 'stretch'
+* yalign: 'top', 'middle', 'bottom' or 'repeat' or 'stretch'
-1.1.1.5 offset subnode
-----------------------
+##### 1.1.1.5 offset subnode
+~~~
offset(<x>,<y>[,<w>[,<h>]])
+~~~
Shift the top,left,right,bottom of the destination rectangle by x,y,-w,-h.
NOTE: w,h are only used when the corresponding positioning modes are 'repeat' or 'stretch'.
-1.1.1.6 pictureAnimation subnode
---------------------------------
+##### 1.1.1.6 pictureAnimation subnode
+~~~
pictureAnimation(<file name>){
- point(<x>,<y>,<w>,<h>[,<frame count>[,<display time of each frame>]])
- point(<x>,<y>,<w>,<h>[,<frame count>[,<display time of each frame>]])
- ...
+ point(<x>,<y>,<w>,<h>[,<frame count>[,<display time of each frame>]])
+ point(<x>,<y>,<w>,<h>[,<frame count>[,<display time of each frame>]])
+ ...
}
+~~~
NOTE: picture and pictureAnimation are mutually exclusive. (?)
NOTE: The default value of frame_count and the display_time_of_each_frame are 1.
The source rectangle (x,y,w,h) is animated by the following way:
- (x,y,w,h)=point[0] is displayed for time display_time[0]
- for i=1,2,3... the following sequences of pictures are displayed:
- - for r=1/frame_count[i],2/frame_count[i],...,1
- the (x,y,w,h)=point[i-1]*(1-r)+point[i]*r is displayed for time display_time[i]
+ - for r=1/frame_count[i],2/frame_count[i],...,1
+ the (x,y,w,h)=point[i-1]*(1-r)+point[i]*r is displayed for time display_time[i]
-1.1.1.7 offsetAnimation subnode
--------------------------------
+##### 1.1.1.7 offsetAnimation subnode
+~~~
offsetAnimation{
- point(<x>,<y>[,<frame count>[,<display time of each frame>]])
- point(<x>,<y>[,<frame count>[,<display time of each frame>]])
- ...
+ point(<x>,<y>[,<frame count>[,<display time of each frame>]])
+ point(<x>,<y>[,<frame count>[,<display time of each frame>]])
+ ...
}
+~~~
This is similar to pictureAnimation subnode, but this time it animates the offset.
+### 1.2 editorPicture subnode
+
+Syntax:
+
+~~~
+editorPicture(<file name>,<x>,<y>,<w>,<h>) //specifies the picture shows in editor
+~~~
+
+This subnode is required (?) for block and scenery.
+
2 background subnode
--------------------
Specifies the background of level.
There can be multiple background subnodes.
Each subnode is a layer of background.
Syntax:
+~~~
background(<file name>){
- srcSize=<x>,<y>,<w>,<h> //Specifies the source size and offset of picture (optional, default value=image size)
- destSize=<x>,<y>,<w>,<h> //Specifies the destination size and offset of picture (optional, default value=source size)
- repeat=<repeat x>,<repeat y> //Repeat in x,y direction? (0 or 1) (optional, default value=1,1)
- speed=<speed x>,<speed y> //Specifies the moving speed (pixel/frame, a real number) (optional, default=0,0)
- cameraSpeed=<x>,<y> //The speed of following camera (a real number, typically in 0-1) (optional, default=0,0)
+ srcSize=<x>,<y>,<w>,<h> //Specifies the source size and offset of picture (optional, default value=image size)
+ destSize=<x>,<y>,<w>,<h> //Specifies the destination size and offset of picture (optional, default value=source size)
+ repeat=<repeat x>,<repeat y> //Repeat in x,y direction? (0 or 1) (optional, default value=1,1)
+ speed=<speed x>,<speed y> //Specifies the moving speed (pixel/frame, a real number) (optional, default=0,0)
+ cameraSpeed=<x>,<y> //The speed of following camera (a real number, typically in 0-1) (optional, default=0,0)
}
+~~~
3 character subnode
-------------------
Specifies the appearance of player and shadow.
Syntax:
+~~~
character(Player){
- ...
+ ...
}
+~~~
or
+~~~
character(Shadow){
- ...
+ ...
}
+~~~
The other format is the same as the block subnode.
4 menuBackground subnode (optional)
----------------
Specifies the background of main menu.
The format is the same as the background subnode.
5 menu block (optional)
------------
Specifies the appearance of blocks used in level selection screen.
Syntax:
+~~~
menu(Block){
- ...
+ ...
}
+~~~
or
+~~~
menu(ShadowBlock){
- ...
+ ...
}
+~~~
The other format is the same as the block subnode.
NOTE: if you defined menu(Block) but not defined menu(ShadowBlock),
then all blocks used in level selection screen will be menu(Block)
regardless of locked or not.
6 scenery block
---------------
Defines new scenery block type.
Syntax:
+~~~
scenery(<name>){
- ...
+ ...
}
+~~~
The other format is the same as the block subnode.
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, May 17, 7:41 AM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
64218
Default Alt Text
(21 KB)
Attached To
Mode
R79 meandmyshadow
Attached
Detach File
Event Timeline