Compare commits

...

44 Commits

Author SHA1 Message Date
Florian Rival
44e10cc9cb Add ObjectPositionsContainer, to choose between RTree or list 2020-01-25 19:50:05 +00:00
Florian Rival
3376520112 Fix GDCpp compilation 2020-01-22 08:07:17 +00:00
Florian Rival
f92917113a Fix Rbush usage in ObjectsPositionsManager 2020-01-21 22:43:44 +00:00
Florian Rival
a990cc1866 Update PlatformRuntimeBehavior to track AABB instead of position+size 2020-01-21 21:26:00 +00:00
Florian Rival
4aa47a7e94 Fix some RuntimeObject missing calls to base class setAngle 2020-01-21 08:25:18 +00:00
Florian Rival
9c99a77fa2 Add counter/timings to gdjs.Profiler, use them in gdjs.ObjectPositionsManager 2020-01-20 23:04:49 +00:00
Florian Rival
2b40949d55 Fix typing 2020-01-20 22:18:20 +00:00
Florian Rival
cc7e956ee1 Use gdjs.ObjectsPositionManager for "CollisionPoint" condition 2020-01-18 15:59:33 +00:00
Florian Rival
7cc21b2237 Add type for ObjectIdsSet, fix bug in gdjs.ObjectsPositionManager and improve perf
* Use a slightly more complex object for ObjectIdsSet to be able to quickly clear the set
* Fix bug where some objects were considered for pointsTest while not in the set of object ids to test.
2020-01-18 15:59:33 +00:00
Florian Rival
4618dbfc8c Make gdjs.ObjectsPositionManager handle raycast tests 2020-01-18 15:59:33 +00:00
Florian Rival
4400c0b23a Move new benchmarks to GDJS/tests/games/object-positions-manager-benchmarks/ 2020-01-18 15:59:33 +00:00
Florian Rival
702a31864c Ensure gdjs.ObjectPositionsManager.update is called once a frame
Remove "GDJS/tests/games/Collisions with creation and deletion benchmark.gdg.json" as now already existing in GDJS/test/games/memory-benchmarks
2020-01-18 15:59:33 +00:00
Florian Rival
9cc03c380f Batch insertion in RBush of updated object positions 2020-01-18 15:59:33 +00:00
Florian Rival
e9d1c6d408 Add test benchmark game for collisions with lots of objects created/deleted 2020-01-18 15:59:33 +00:00
Florian Rival
b206ddb62b Fix gdjs.ObjectPositionsManager crash if using an ID of a removed/inexisting object position
This can happen if a gdjs.RuntimeObject is deleted from the scene: it's marked for deletion,
but still used by the current events, which can pass its id to the gdjs.ObjectPositionsManager
(which won't have an associated ObjectPosition for its id, as it would have been marked for deletion
and really deleted at the next call to "update", which happen at any query like collision handling).
2020-01-18 15:59:33 +00:00
Florian Rival
37df801a93 Add test for gdjs.ObjectPositionsManager.separateObjects 2020-01-18 15:59:32 +00:00
Florian Rival
c9fd56f875 Make gdjs.ObjectsPositionManager handle "cursor on object" test (points test) 2020-01-18 15:59:32 +00:00
Florian Rival
aa2e26ae7b Make gdjs.ObjectsPositionManager handle distance tests 2020-01-18 15:59:32 +00:00
Florian Rival
23d8682da9 Make gdjs.ObjectsPositionManager handle collisions and object separation 2020-01-18 15:59:32 +00:00
Florian Rival
fe7897bbc3 [WIP] Make gdjs.ObjectsPositionManager use a different RBush for each object name 2020-01-18 15:59:32 +00:00
Florian Rival
d409b66f22 [WIP] Add gdjs.PositionsManager storing coordinates/aabb/hitboxes
- Use it for collision tests
2020-01-18 15:59:32 +00:00
Florian Rival
4227451a6a Fix some RuntimeObject missing calls to base class setX/Y 2020-01-18 15:54:00 +00:00
Florian Rival
01a844c356 Refactor import-GDJS-Runtime script to use Node.js 2020-01-18 14:27:36 +00:00
Arthur Pacaud
054e48227c Make object and behavior registering more explicit (#1379) 2020-01-17 22:49:24 +00:00
Florian Rival
9adc40a55d Add script to extract all the expressions available in GDevelop 2020-01-16 23:44:26 +00:00
Bouh
034c734568 Fix unaligned text for "Unknown behavior" (#1382)
- Remove useless span
- Remove useless style related to span
- Use `Text` for Unknown behavior to ensure alignement and correct font.
2020-01-16 20:19:15 +00:00
Florian Rival
b65aed4c02 Merge pull request #1380 from 4ian/feature/notarization-macos
Enable notarization on macos
2020-01-16 19:35:20 +00:00
Florian Rival
adbcef8f59 Build zip for macOS on CircleCI 2020-01-16 08:56:06 +00:00
Florian Rival
44dbbd7138 Add notarization for macOS 2020-01-15 23:34:25 +00:00
Florian Rival
3e63e34d61 Upgrade electron-builder to 20.44.4 and electron-updater to 4.2.0 2020-01-15 20:53:49 +00:00
Florian Rival
dc976003b7 Add action to center the window on screen 2020-01-14 22:03:10 +00:00
Florian Rival
fb3002cd77 Add version metadata in analytics 2020-01-14 21:41:05 +00:00
Florian Rival
b25752907f Fix effects not applied in exported games 2020-01-13 22:31:54 +00:00
Florian Rival
72da63afcb Fix broken Text and TiledSprite objects 2020-01-13 21:51:35 +00:00
Florian Rival
ab5a593ab3 Use resources.gdevelop-app.com for static content serving 2020-01-13 21:23:24 +00:00
Florian Rival
71dcb20b7b Fix date not removed from generated GDJS HTML documentation 2020-01-13 19:35:23 +00:00
Florian Rival
61ffb40dee Remove date from generated documentation HTML 2020-01-13 08:56:08 +00:00
Florian Rival
07152639d1 Ensure npm install is run before running jsdoc with GenerateAllDocs 2020-01-12 23:51:31 +00:00
Florian Rival
6655a949ec Fix GDJS doc generation (incompatible TypeScript/JSDoc notations) 2020-01-12 23:33:39 +00:00
Arthur Pacaud
99312c71e0 Improve overall type annotations (#1361)
* Add type annotation for ObjectData and related types.
* Add missing type annotations.
* Add // @ts-check to some files.
2020-01-12 20:14:00 +00:00
Bouh
3abb5a393d Set object names in bold in dark theme (like in light theme) (#1366) 2020-01-12 20:12:51 +00:00
Florian Rival
010b52ced6 Update documentation urls to docs.gdevelop-app.com/... 2020-01-12 18:45:39 +00:00
Florian Rival
7a1ce790d4 Make "Allow again jumping" action description clearer 2020-01-10 23:40:20 +00:00
Florian Rival
fbdf530e00 Refactor upload, removing dependency on AWS S3 2020-01-10 23:29:15 +00:00
237 changed files with 15302 additions and 8722 deletions

View File

@@ -60,7 +60,7 @@ jobs:
# Build GDevelop IDE
- run:
name: Build GDevelop IDE
command: cd newIDE/electron-app && npm run build -- --mac --win --linux tar.gz --publish=never
command: cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
- run:
name: Clean dist folder to keep only installers/binaries.

View File

@@ -602,17 +602,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Object 2 (won't move)"));
obj.AddAction("SeparateFromObjects",
_("Separate two objects"),
_("Move an object away from another using their collision "
"masks.\nBe sure to call this action on a reasonable number "
"of objects\nto avoid slowing down the game."),
_("Move _PARAM0_ away from _PARAM1_ (only _PARAM0_ will move)"),
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
extension
.AddAction(
"SeparateFromObjects",
_("Separate two objects"),
_("Move an object away from another using their collision "
"masks.\nBe sure to call this action on a reasonable number "
"of objects\nto avoid slowing down the game."),
_("Move _PARAM0_ away from _PARAM1_ (only _PARAM0_ will move)"),
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Object"))
.AddParameter("objectList", _("Objects (won't move)"))
.AddParameter("yesorno",
_("Ignore objects that are touching each other on their "
@@ -620,18 +622,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsSimple();
obj.AddCondition("CollisionPoint",
_("Point inside object"),
_("Test if a point is inside the object collision masks."),
_("_PARAM1_;_PARAM2_ is inside _PARAM0_"),
_("Collision"),
"res/conditions/collisionPoint24.png",
"res/conditions/collisionPoint.png")
.AddParameter("object", _("Object"))
extension
.AddCondition("CollisionPoint",
_("Point inside object"),
_("Test if a point is inside the object collision masks."),
_("_PARAM1_;_PARAM2_ is inside _PARAM0_"),
_("Collision"),
"res/conditions/collisionPoint24.png",
"res/conditions/collisionPoint.png")
.AddParameter("objectList", _("Object"))
.AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point"))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsSimple();
obj.AddCondition(
@@ -963,6 +969,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectList", _("Object 2"))
.AddParameter("expression", _("Distance"))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsSimple();
extension
@@ -1072,8 +1079,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddCondition("Raycast",
_("Raycast"),
_("Sends a ray from the given source position and angle, "
"intersecting the closest object.\nThe instersected "
"object will become the only one taken into account.\nIf "
"intersecting the closest object.\nThe intersected "
"object will become the only one picked for next "
"conditions and actions.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the "
@@ -1095,6 +1103,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension
@@ -1102,8 +1111,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"RaycastToPosition",
_("Raycast to position"),
_("Sends a ray from the given source position to the final point, "
"intersecting the closest object.\nThe instersected "
"object will become the only one taken into account.\nIf "
"intersecting the closest object.\nThe intersected "
"object will become the only one picked for next conditions and "
"actions.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the "
@@ -1125,6 +1135,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension

View File

@@ -88,6 +88,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
_("Also update the game resolution? If not, the game will "
"be stretched or reduced to fit in the window."));
extension
.AddAction("CenterWindow",
_("Center the game window on the screen"),
_("This action centers the game window on the screen. This "
"only works on Windows, macOS and Linux (not when the game "
"is executed in a web-browser or on iOS/Android)."),
_("Center the game window"),
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddAction("SetGameResolutionResizeMode",
_("Change the game resolution resize mode"),

View File

@@ -33,7 +33,7 @@ Extensions do have the same distinction between the "**IDE**" part and the "**Ru
In GDevelop, developers can associate and manipulate variables in their games. To represent them, we have two things:
* The **editor** `gd::Variable` that is part of the structure of the game, so living in [GDCore in Variable.h](https://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_variable.html). This is what is shown in the editor, saved on disk in the project file.
* The **game engine** variable, called `gdjs.Variable` in GDJS. [Documentation is in the GDJS **game engine**](http://4ian.github.io/GD-Documentation/GDJS%20Runtime%20Documentation/gdjs.Variable.html). This JavaScript class is what is used during a game.
* The **game engine** variable, called `gdjs.Variable` in GDJS. [Documentation is in the GDJS **game engine**](https://docs.gdevelop-app.com/GDJS%20Runtime%20Documentation/gdjs.Variable.html). This JavaScript class is what is used during a game.
The editor `gd::Variable` **know nothing** about the game engine class `gdjs.Variable`. And the `gdjs.Variable` class in the game engine know almost nothing from `gd::Variable` (apart from how it's written in JSON, to be able to load a game default variables).
@@ -57,7 +57,7 @@ The game engine is in GDJS/Runtime and is all JavaScript.
## What about events?
An "**event**" is by default something that [is mostly empty](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_base_event.html). In a more traditional programming language, an event can be seen as a scope or block (example: `{ some code here }` in a C style language like JavaScript, Java or C++).
An "**event**" is by default something that [is mostly empty](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_base_event.html). In a more traditional programming language, an event can be seen as a scope or block (example: `{ some code here }` in a C style language like JavaScript, Java or C++).
[Default events are defined](https://github.com/4ian/GDevelop/tree/master/Core/GDCore/Events/Builtin) in GDevelop Core.
In particular, there is StandardEvent, which has conditions and actions. Conditions and actions are both a list of [`gd::Instruction`](https://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_instruction.html). A `gd::Instruction` is either a condition or an action (it depends only on the context where they are used).

View File

@@ -6,7 +6,7 @@ GDevelop Core is a portable C++ library, compiled to be used in JavaScript in th
## 1) Getting started 🤓
First, take a look at the *Readme.md* at the root of the repository and the [developer documentation](http://4ian.github.io/GD-Documentation/).
First, take a look at the *Readme.md* at the root of the repository and the [developer documentation](https://docs.gdevelop-app.com/).
## 2) How to contribute 😎
@@ -14,7 +14,7 @@ Any contribution is welcome! Whether you want to submit a bug report, a feature
or any pull request so as to add a nice feature, do not hesitate to get in touch.
* Check the [the **roadmap** for ideas and features planned](https://trello.com/b/qf0lM7k8/gdevelop-roadmap).
* Follow the [Development](https://github.com/4ian/GDevelop/tree/master/newIDE#development) section of the README to set up GDevelop and start modifying either **the editor** or **[the game engine/extensions](https://github.com/4ian/GDevelop/tree/master/newIDE#development-of-the-game-engine-or-extensions)**.
* To submit your changes, you have first to create a Fork on GitHub (use the Fork button on the top right), then [create a Pull Request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).

View File

@@ -964,7 +964,7 @@ HTML_COLORSTYLE_GAMMA = 80
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the

View File

@@ -1,2 +1,2 @@
Uncompress here the external libraries needed: SFML.
Refer to [the documentation](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/setup_dev_env.html) for more information and to get the download links of the libraries.
Refer to [the documentation](https://docs.gdevelop-app.com/GDCore%20Documentation/setup_dev_env.html) for more information and to get the download links of the libraries.

View File

@@ -24,7 +24,7 @@ gdjs.AnchorRuntimeBehavior = function(runtimeScene, behaviorData, owner)
};
gdjs.AnchorRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.AnchorRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "AnchorBehavior::AnchorBehavior";
gdjs.registerBehavior("AnchorBehavior::AnchorBehavior", gdjs.AnchorRuntimeBehavior);
gdjs.AnchorRuntimeBehavior.HorizontalAnchor = {
NONE: 0,

View File

@@ -1,34 +1,52 @@
/**
* @typedef {Object} BBTextObjectDataType Base parameters for {@link gdjs.BBTextRuntimeObject}
* @property {Object} content The base parameters of the BBText
* @property {number} content.opacity The opacity of the BBText
* @property {boolean} content.visible Is the text visible?
* @property {string} content.text Content of the text
* @property {string} content.color The color of the text
* @property {string} content.fontFamily The font of the text
* @property {number} content.fontSize The size of the text
* @property {boolean} content.wordWrap Activate word wrap if set to true
* @property {('left'|'center'|'right')} content.align Alignment of the text: "left", "center" or "right"
*
* @typedef {ObjectData & BBTextObjectDataType} BBTextObjectData
*/
/**
* Displays a rich text using BBCode markup (allowing to set parts of the text as bold, italic, use different colors and shadows).
* @memberof gdjs
* @class BBTextRuntimeObject
* @extends RuntimeObject
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {BBTextObjectData} objectData The object data used to initialize the object
*/
gdjs.BBTextRuntimeObject = function(runtimeScene, objectData) {
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
/** @type number */
/** @type {number} */
this._opacity = objectData.content.opacity;
/** @type boolean */
/** @type {boolean} */
this._visible = objectData.content.visible;
/** @type string */
/** @type {string} */
this._text = objectData.content.text;
/** @type string */
/** @type {string} */
this._color = objectData.content.color;
/** @type string */
/** @type {string} */
this._fontFamily = objectData.content.fontFamily;
/** @type number */
/** @type {number} */
this._fontSize = objectData.content.fontSize;
/** @type boolean */
/** @type {boolean} */
this._wordWrap = objectData.content.wordWrap;
/** @type number */
/** @type {number} */
this._wrappingWidth = 250; // This value is the default wrapping width of the runtime object.
/** @type string */
/** @type {string} */
this._align = objectData.content.align;
if (this._renderer)
gdjs.BBTextRuntimeObjectRenderer.call(this._renderer, this, runtimeScene);
else
/** @type {gdjs.BBTextRuntimeObjectRenderer} */
this._renderer = new gdjs.BBTextRuntimeObjectRenderer(this, runtimeScene);
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
@@ -38,7 +56,7 @@ gdjs.BBTextRuntimeObject = function(runtimeScene, objectData) {
gdjs.BBTextRuntimeObject.prototype = Object.create(
gdjs.RuntimeObject.prototype
);
gdjs.BBTextRuntimeObject.thisIsARuntimeObjectConstructor = 'BBText::BBText';
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);
gdjs.BBTextRuntimeObject.prototype.getRendererObject = function() {
return this._renderer.getRendererObject();
@@ -48,9 +66,7 @@ gdjs.BBTextRuntimeObject.prototype.getRendererObject = function() {
* Initialize the extra parameters that could be set for an instance.
* @private
*/
gdjs.BBTextRuntimeObject.prototype.extraInitializationFromInitialInstance = function(
initialInstanceData
) {
gdjs.BBTextRuntimeObject.prototype.extraInitializationFromInitialInstance = function(initialInstanceData) {
// The wrapping width value (this._wrappingWidth) is using the object's width as an innitial value
if (initialInstanceData.customSize)
this.setWrappingWidth(initialInstanceData.width);

View File

@@ -18,7 +18,7 @@ gdjs.DestroyOutsideRuntimeBehavior = function(runtimeScene, behaviorData, owner)
};
gdjs.DestroyOutsideRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.DestroyOutsideRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "DestroyOutsideBehavior::DestroyOutside";
gdjs.registerBehavior("DestroyOutsideBehavior::DestroyOutside", gdjs.DestroyOutsideRuntimeBehavior);
gdjs.DestroyOutsideRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {

View File

@@ -23,7 +23,7 @@ gdjs.DraggableRuntimeBehavior = function(runtimeScene, behaviorData, owner)
};
gdjs.DraggableRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.DraggableRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "DraggableBehavior::Draggable";
gdjs.registerBehavior("DraggableBehavior::Draggable", gdjs.DraggableRuntimeBehavior);
gdjs.DraggableRuntimeBehavior.prototype.onDeActivate = function() {
this._endDrag();

View File

@@ -20,7 +20,7 @@ gdjs.DummyRuntimeBehavior = function(runtimeScene, behaviorData, owner)
};
gdjs.DummyRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.DummyRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "MyDummyExtension::DummyBehavior";
gdjs.registerBehavior("MyDummyExtension::DummyBehavior", gdjs.DummyRuntimeBehavior);
gdjs.DummyRuntimeBehavior.prototype.onDeActivate = function() {
};

View File

@@ -22,8 +22,7 @@ gdjs.DummyRuntimeObject = function(runtimeScene, objectData) {
};
gdjs.DummyRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
gdjs.DummyRuntimeObject.thisIsARuntimeObjectConstructor =
"MyDummyExtension::DummyObject"; //Replace by your extension + object name.
gdjs.registerObject("MyDummyExtension::DummyObject", gdjs.DummyRuntimeObject); //Replace by your extension + object name.
gdjs.DummyRuntimeObject.prototype.getRendererObject = function() {
return this._renderer.getRendererObject();

View File

@@ -21,7 +21,7 @@ gdjs.DummyWithSharedDataRuntimeBehavior = function(runtimeScene, behaviorData, o
};
gdjs.DummyWithSharedDataRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.DummyWithSharedDataRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "MyDummyExtension::DummyBehaviorWithSharedData";
gdjs.registerBehavior("MyDummyExtension::DummyBehaviorWithSharedData", gdjs.DummyRuntimeBehavior);
gdjs.DummyWithSharedDataRuntimeBehavior.prototype.onDeActivate = function() {
};

View File

@@ -3,23 +3,54 @@
* 2013 Florian Rival (Florian.Rival@gmail.com)
*/
/**
* @typedef {Object} PanelSpriteObjectDataType
* @property {number} rightMargin The right margin
* @property {number} leftMargin The left margin
* @property {number} topMargin The top margin
* @property {number} bottomMargin The bottom margin
* @property {boolean} [tiled] Are the central part and borders tiled?
* @property {number} width The object width
* @property {number} height The object height
* @property {string} texture The name of the resource containing the texture to use
*
* @typedef {ObjectData & PanelSpriteObjectDataType} PanelSpriteObjectData
*/
/**
* The PanelSpriteRuntimeObject displays a tiled texture.
*
* @class PanelSpriteRuntimeObject
* @extends RuntimeObject
* @memberof gdjs
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {PanelSpriteObjectData} panelSpriteObjectData The initial properties of the object
*/
gdjs.PanelSpriteRuntimeObject = function(runtimeScene, objectData) {
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
gdjs.PanelSpriteRuntimeObject = function(runtimeScene, panelSpriteObjectData) {
gdjs.RuntimeObject.call(this, runtimeScene, panelSpriteObjectData);
this._rBorder = objectData.rightMargin;
this._lBorder = objectData.leftMargin;
this._tBorder = objectData.topMargin;
this._bBorder = objectData.bottomMargin;
this._tiled = objectData.tiled;
this._width = objectData.width;
this._height = objectData.height;
/** @type {number} */
this._rBorder = panelSpriteObjectData.rightMargin;
/** @type {number} */
this._lBorder = panelSpriteObjectData.leftMargin;
/** @type {number} */
this._tBorder = panelSpriteObjectData.topMargin;
/** @type {number} */
this._bBorder = panelSpriteObjectData.bottomMargin;
/** @type {boolean} */
this._tiled = panelSpriteObjectData.tiled;
/** @type {number} */
this._width = panelSpriteObjectData.width;
/** @type {number} */
this._height = panelSpriteObjectData.height;
/** @type {number} */
this.opacity = 255;
if (this._renderer) {
@@ -27,15 +58,16 @@ gdjs.PanelSpriteRuntimeObject = function(runtimeScene, objectData) {
this._renderer,
this,
runtimeScene,
objectData.texture,
objectData.tiled
panelSpriteObjectData.texture,
panelSpriteObjectData.tiled
);
} else {
/** @type {gdjs.PanelSpriteRuntimeObjectRenderer} */
this._renderer = new gdjs.PanelSpriteRuntimeObjectRenderer(
this,
runtimeScene,
objectData.texture,
objectData.tiled
panelSpriteObjectData.texture,
panelSpriteObjectData.tiled
);
}
@@ -46,8 +78,7 @@ gdjs.PanelSpriteRuntimeObject = function(runtimeScene, objectData) {
gdjs.PanelSpriteRuntimeObject.prototype = Object.create(
gdjs.RuntimeObject.prototype
);
gdjs.PanelSpriteRuntimeObject.thisIsARuntimeObjectConstructor =
'PanelSpriteObject::PanelSprite';
gdjs.registerObject("PanelSpriteObject::PanelSprite", gdjs.PanelSpriteRuntimeObject);
gdjs.PanelSpriteRuntimeObject.prototype.getRendererObject = function() {
return this._renderer.getRendererObject();

View File

@@ -1,63 +1,170 @@
/**
GDevelop - Particle System Extension
Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
* GDevelop - Particle System Extension
* Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
* This project is released under the MIT License.
*/
/**
* @typedef {Object} ParticleEmitterObjectDataType
* @property {boolean} emissionEditionSimpleMode
* @property {number} emitterAngleA
* @property {number} emitterAngleB
* @property {number} emitterForceMin
* @property {number} emitterForceMax
* @property {number} zoneRadius
* @property {number} particleLifeTimeMin
* @property {number} particleLifeTimeMax
* @property {number} particleGravityX
* @property {number} particleGravityY
* @property {number} particleRed1
* @property {number} particleRed2
* @property {number} particleGreen1
* @property {number} particleGreen2
* @property {number} particleBlue1
* @property {number} particleBlue2
* @property {number} particleSize1
* @property {number} particleSize2
* @property {number} sizeParam
* @property {number} particleAlpha1
* @property {number} particleAlpha2
* @property {string} rendererType
* @property {number} rendererParam1
* @property {number} rendererParam1
* @property {string} textureParticleName Resource name for image in particle
* @property {number} flow
* @property {number} tank
* @property {boolean} destroyWhenNoParticles Destroy the object when there is no particles?
*
* @typedef {ObjectData & ParticleEmitterObjectDataType} ParticleEmitterObjectData
*/
gdjs.ParticleEmitterObject = function(runtimeScene, objectData){
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
/**
* Displays particles.
*
* @memberof gdjs
* @class ParticleEmitterObject
* @extends RuntimeObject
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {ParticleEmitterObjectData} particleObjectData The initial properties of the object
*/
gdjs.ParticleEmitterObject = function(runtimeScene, particleObjectData){
gdjs.RuntimeObject.call(this, runtimeScene, particleObjectData);
this._renderer = new gdjs.ParticleEmitterObjectRenderer(runtimeScene, this, objectData);
/** @type {gdjs.ParticleEmitterObjectRenderer} */
this._renderer = new gdjs.ParticleEmitterObjectRenderer(runtimeScene, this, particleObjectData);
this.singleAngle = objectData.emissionEditionSimpleMode;
this.angleA = objectData.emitterAngleA;
this.angleB = objectData.emitterAngleB;
this.forceMin = objectData.emitterForceMin;
this.forceMax = objectData.emitterForceMax;
this.zoneRadius = objectData.zoneRadius;
this.lifeTimeMin = objectData.particleLifeTimeMin;
this.lifeTimeMax = objectData.particleLifeTimeMax;
this.gravityX = objectData.particleGravityX;
this.gravityY = objectData.particleGravityY;
this.colorR1 = objectData.particleRed1;
this.colorR2 = objectData.particleRed2;
this.colorG1 = objectData.particleGreen1;
this.colorG2 = objectData.particleGreen2;
this.colorB1 = objectData.particleBlue1;
this.colorB2 = objectData.particleBlue2;
this.size1 = objectData.particleSize1;
this.size2 = objectData.particleSize2;
this.sizeParam = objectData.sizeParam;
this.alpha1 = objectData.particleAlpha1;
this.alpha2 = objectData.particleAlpha2;
this.rendererType = objectData.rendererType;
this.rendererParam1 = objectData.rendererParam1;
this.rendererParam2 = objectData.rendererParam2;
/** @type string */
this.texture = objectData.textureParticleName;
this.flow = objectData.flow;
this.tank = objectData.tank;
this.destroyWhenNoParticles = objectData.destroyWhenNoParticles;
/** @type {boolean} */
this.singleAngle = particleObjectData.emissionEditionSimpleMode;
/** @type {number} */
this.angleA = particleObjectData.emitterAngleA;
/** @type {number} */
this.angleB = particleObjectData.emitterAngleB;
/** @type {number} */
this.forceMin = particleObjectData.emitterForceMin;
/** @type {number} */
this.forceMax = particleObjectData.emitterForceMax;
/** @type {number} */
this.zoneRadius = particleObjectData.zoneRadius;
/** @type {number} */
this.lifeTimeMin = particleObjectData.particleLifeTimeMin;
/** @type {number} */
this.lifeTimeMax = particleObjectData.particleLifeTimeMax;
/** @type {number} */
this.gravityX = particleObjectData.particleGravityX;
/** @type {number} */
this.gravityY = particleObjectData.particleGravityY;
/** @type {number} */
this.colorR1 = particleObjectData.particleRed1;
/** @type {number} */
this.colorR2 = particleObjectData.particleRed2;
/** @type {number} */
this.colorG1 = particleObjectData.particleGreen1;
/** @type {number} */
this.colorG2 = particleObjectData.particleGreen2;
/** @type {number} */
this.colorB1 = particleObjectData.particleBlue1;
/** @type {number} */
this.colorB2 = particleObjectData.particleBlue2;
/** @type {number} */
this.size1 = particleObjectData.particleSize1;
/** @type {number} */
this.size2 = particleObjectData.particleSize2;
/** @type {number} */
this.sizeParam = particleObjectData.sizeParam;
/** @type {number} */
this.alpha1 = particleObjectData.particleAlpha1;
/** @type {number} */
this.alpha2 = particleObjectData.particleAlpha2;
/** @type {string} */
this.rendererType = particleObjectData.rendererType;
/** @type {number} */
this.rendererParam1 = particleObjectData.rendererParam1;
/** @type {number} */
this.rendererParam2 = particleObjectData.rendererParam2;
/** @type {string} */
this.texture = particleObjectData.textureParticleName;
/** @type {number} */
this.flow = particleObjectData.flow;
/** @type {number} */
this.tank = particleObjectData.tank;
/** @type {boolean} */
this.destroyWhenNoParticles = particleObjectData.destroyWhenNoParticles;
/** @type {boolean} */
this._posDirty = true;
/** @type {boolean} */
this._angleDirty = true;
/** @type {boolean} */
this._forceDirty = true;
/** @type {boolean} */
this._zoneRadiusDirty = true;
/** @type {boolean} */
this._lifeTimeDirty = true;
/** @type {boolean} */
this._gravityDirty = true;
/** @type {boolean} */
this._colorDirty = true;
/** @type {boolean} */
this._sizeDirty = true;
/** @type {boolean} */
this._alphaDirty = true;
/** @type {boolean} */
this._textureDirty = this.texture !== ''; // Don't mark texture as dirty if not using one.
/** @type {boolean} */
this._flowDirty = true;
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
this.onCreated();
};
gdjs.ParticleEmitterObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
gdjs.ParticleEmitterObject.thisIsARuntimeObjectConstructor = "ParticleSystem::ParticleEmitter";
gdjs.registerObject("ParticleSystem::ParticleEmitter", gdjs.ParticleEmitterObject);
gdjs.ParticleEmitterObject.prototype.setX = function(x){
if(this.x !== x) this._posDirty = true;

View File

@@ -102,7 +102,7 @@ gdjs.PathfindingObstacleRuntimeBehavior = function(runtimeScene, behaviorData, o
};
gdjs.PathfindingObstacleRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.PathfindingObstacleRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PathfindingBehavior::PathfindingObstacleBehavior";
gdjs.registerBehavior("PathfindingBehavior::PathfindingObstacleBehavior", gdjs.PathfindingObstacleRuntimeBehavior);
gdjs.PathfindingObstacleRuntimeBehavior.prototype.onDestroy = function() {
if ( this._manager && this._registeredInManager ) this._manager.removeObstacle(this);

View File

@@ -46,7 +46,7 @@ gdjs.PathfindingRuntimeBehavior = function(runtimeScene, behaviorData, owner)
};
gdjs.PathfindingRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.PathfindingRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PathfindingBehavior::PathfindingBehavior";
gdjs.registerBehavior("PathfindingBehavior::PathfindingBehavior", gdjs.PathfindingRuntimeBehavior);
gdjs.PathfindingRuntimeBehavior.prototype.setCellWidth = function(width) {
this._cellWidth = width;

View File

@@ -238,8 +238,7 @@ gdjs.Physics2RuntimeBehavior = function(runtimeScene, behaviorData, owner) {
gdjs.Physics2RuntimeBehavior.prototype = Object.create(
gdjs.RuntimeBehavior.prototype
);
gdjs.Physics2RuntimeBehavior.thisIsARuntimeBehaviorConstructor =
'Physics2::Physics2Behavior';
gdjs.registerBehavior('Physics2::Physics2Behavior', gdjs.Physics2RuntimeBehavior);
gdjs.Physics2RuntimeBehavior.prototype.b2Vec2 = function(x, y) {
this._tempb2Vec2.set_x(x);

View File

@@ -145,7 +145,7 @@ gdjs.PhysicsRuntimeBehavior = function(runtimeScene, behaviorData, owner)
};
gdjs.PhysicsRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.PhysicsRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PhysicsBehavior::PhysicsBehavior";
gdjs.registerBehavior("PhysicsBehavior::PhysicsBehavior", gdjs.PhysicsRuntimeBehavior);
gdjs.PhysicsRuntimeBehavior.prototype.onDeActivate = function() {
if ( this._box2DBody !== null ) {

View File

@@ -14,13 +14,14 @@ This project is released under the MIT License.
#include "ScenePlatformObjectsManager.h"
void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
extension.SetExtensionInformation(
"PlatformBehavior",
_("Platform Behavior"),
_("This Extension enables the use of controllable objects that can run "
"and jump on platforms."),
"Florian Rival",
"Open source (MIT License)")
extension
.SetExtensionInformation("PlatformBehavior",
_("Platform Behavior"),
_("This Extension enables the use of "
"controllable objects that can run "
"and jump on platforms."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/behaviors/platformer");
{
@@ -302,14 +303,18 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.SetGetter("GetJumpSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
aut.AddAction("SetCanJump",
_("Allow again jumping"),
_("Allow the object to jump again, even if it is in the air: "
"this can be useful to allow double jump for example."),
_("Allow _PARAM0_ to jump again"),
_("Options"),
"CppPlatform/Extensions/platformerobjecticon24.png",
"CppPlatform/Extensions/platformerobjecticon16.png")
aut.AddAction(
"SetCanJump",
_("Allow again jumping"),
_("When this action is executed, the object is able to jump again, "
"even if it is in the air: this can be useful to allow a double "
"jump for example. This is not a permanent effect: you must call "
"again this action everytime you want to allow the object to jump "
"(apart if it's on the floor)."),
_("Allow _PARAM0_ to jump again"),
_("Options"),
"CppPlatform/Extensions/platformerobjecticon24.png",
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsSimple()

View File

@@ -63,7 +63,7 @@ gdjs.PlatformerObjectRuntimeBehavior = function(runtimeScene, behaviorData, owne
};
gdjs.PlatformerObjectRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.PlatformerObjectRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PlatformBehavior::PlatformerObjectBehavior";
gdjs.registerBehavior("PlatformBehavior::PlatformerObjectBehavior", gdjs.PlatformerObjectRuntimeBehavior);
gdjs.PlatformerObjectRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene)
{

View File

@@ -14,7 +14,8 @@ Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
*/
gdjs.PlatformObjectsManager = function(runtimeScene, sharedData)
{
this._platformRBush = new rbush(9, ['.owner.getAABB().min[0]', '.owner.getAABB().min[1]', '.owner.getAABB().max[0]', '.owner.getAABB().max[1]']);
// TODO: update RBush to avoid using eval-like Function.
this._platformRBush = new rbush(9, ['.aabb.min[0]', '.aabb.min[1]', '.aabb.max[0]', '.aabb.max[1]']);
};
/**
@@ -89,18 +90,21 @@ gdjs.PlatformRuntimeBehavior = function(runtimeScene, behaviorData, owner)
this._canBeGrabbed = behaviorData.canBeGrabbed || false;
this._yGrabOffset = behaviorData.yGrabOffset || 0;
//Note that we can't use getX(), getWidth()... of owner here: The owner is not fully constructed.
this._oldX = 0;
this._oldY = 0;
this._oldWidth = 0;
this._oldHeight = 0;
//Note that we can't use getAABB() of the owner here: The owner is not fully constructed.
this._oldAABBMinX = 0;
this._oldAABBMinX = 0;
this._oldAABBMaxX = 0;
this._oldAABBMaxY = 0;
/** @type {AABB} */
this.aabb = { min: [0,0], max: [0,0] };
this._manager = gdjs.PlatformObjectsManager.getManager(runtimeScene);
this._registeredInManager = false;
};
gdjs.PlatformRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.PlatformRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PlatformBehavior::PlatformBehavior";
gdjs.registerBehavior("PlatformBehavior::PlatformBehavior", gdjs.PlatformRuntimeBehavior);
gdjs.PlatformRuntimeBehavior.LADDER = 2;
gdjs.PlatformRuntimeBehavior.JUMPTHRU = 1;
@@ -111,17 +115,27 @@ gdjs.PlatformRuntimeBehavior.prototype.onDestroy = function() {
};
gdjs.PlatformRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene) {
// Track changes in AABB
// TODO: Skip this if the behavior is deactivated.
/** @type {AABB} */
var aabb = this.owner.getAABB();
//Scene change is not supported
/*if ( parentScene != &scene ) //Parent scene has changed
if (this._oldAABBMinX !== aabb.min[0] || this._oldAABBMinY !== aabb.min[1] ||
this._oldAABBMaxX !== aabb.max[0] || this._oldAABBMaxY !== aabb.max[1])
{
if ( sceneManager ) //Remove the object from any old scene manager.
sceneManager->RemovePlatform(this);
// Store the AABB of the platform directly in the behavior, for usage by rbush
this.aabb = aabb;
parentScene = &scene;
sceneManager = parentScene ? &ScenePlatformObjectsManager::managers[&scene] : NULL;
registeredInManager = false;
}*/
if ( this._registeredInManager ) {
this._manager.removePlatform(this);
this._manager.addPlatform(this);
}
this._oldAABBMinX = aabb.min[0];
this._oldAABBMinY = aabb.min[1];
this._oldAABBMaxX = aabb.max[0];
this._oldAABBMaxY = aabb.max[1];
}
//Make sure the platform is or is not in the platforms manager.
if (!this.activated() && this._registeredInManager)
@@ -134,21 +148,6 @@ gdjs.PlatformRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene)
this._manager.addPlatform(this);
this._registeredInManager = true;
}
//Track changes in size or position
if (this._oldX !== this.owner.getX() || this._oldY !== this.owner.getY() ||
this._oldWidth !== this.owner.getWidth() || this._oldHeight !== this.owner.getHeight())
{
if ( this._registeredInManager ) {
this._manager.removePlatform(this);
this._manager.addPlatform(this);
}
this._oldX = this.owner.getX();
this._oldY = this.owner.getY();
this._oldWidth = this.owner.getWidth();
this._oldHeight = this.owner.getHeight();
}
};
gdjs.PlatformRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {

View File

@@ -3,27 +3,60 @@
* 2013 Florian Rival (Florian.Rival@gmail.com)
*/
/**
* @typedef {Object} RGBColor Represents a color in RGB Format
* @property {number} r The Red component of the color, from 0 to 255.
* @property {number} g The Green component of the color, from 0 to 255.
* @property {number} b The Blue component of the color, from 0 to 255.
*/
/**
* @typedef {Object} ShapePainterObjectDataType Initial properties for a for {@link gdjs.ShapePainterRuntimeObject}.
* @property {RGBColor} fillColor The color (in RGB format) of the inner part of the painted shape
* @property {RGBColor} outlineColor The color (in RGB format) of the outline of the painted shape
* @property {number} fillOpacity The opacity of the inner part of the painted shape
* @property {number} outlineOpacity The opacity of the outline of the painted shape
* @property {number} outlineSize The size of the outline of the painted shape, in pixels.
* @property {boolean} absoluteCoordinates Use absolute coordinates?
*
* @typedef {ObjectData & ShapePainterObjectDataType} ShapePainterObjectData
*/
/**
* The ShapePainterRuntimeObject allows to draw graphics shapes on screen.
*
* @class ShapePainterRuntimeObject
* @extends RuntimeObject
* @memberof gdjs
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {ShapePainterObjectData} shapePainterObjectData The initial properties of the object
*/
gdjs.ShapePainterRuntimeObject = function(runtimeScene, objectData)
gdjs.ShapePainterRuntimeObject = function(runtimeScene, shapePainterObjectData)
{
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
gdjs.RuntimeObject.call(this, runtimeScene, shapePainterObjectData);
this._fillColor = parseInt(gdjs.rgbToHex(objectData.fillColor.r, objectData.fillColor.g, objectData.fillColor.b), 16);
this._outlineColor = parseInt(gdjs.rgbToHex(objectData.outlineColor.r, objectData.outlineColor.g, objectData.outlineColor.b), 16);
this._fillOpacity = objectData.fillOpacity;
this._outlineOpacity = objectData.outlineOpacity;
this._outlineSize = objectData.outlineSize;
this._absoluteCoordinates = objectData.absoluteCoordinates;
/** @type {number} */
this._fillColor = parseInt(gdjs.rgbToHex(shapePainterObjectData.fillColor.r, shapePainterObjectData.fillColor.g, shapePainterObjectData.fillColor.b), 16);
/** @type {number} */
this._outlineColor = parseInt(gdjs.rgbToHex(shapePainterObjectData.outlineColor.r, shapePainterObjectData.outlineColor.g, shapePainterObjectData.outlineColor.b), 16);
/** @type {number} */
this._fillOpacity = shapePainterObjectData.fillOpacity;
/** @type {number} */
this._outlineOpacity = shapePainterObjectData.outlineOpacity;
/** @type {number} */
this._outlineSize = shapePainterObjectData.outlineSize;
/** @type {boolean} */
this._absoluteCoordinates = shapePainterObjectData.absoluteCoordinates;
if (this._renderer)
gdjs.ShapePainterRuntimeObjectRenderer.call(this._renderer, this, runtimeScene);
else
/** @type {gdjs.ShapePainterRuntimeObjectRenderer} */
this._renderer = new gdjs.ShapePainterRuntimeObjectRenderer(this, runtimeScene);
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
@@ -31,7 +64,7 @@ gdjs.ShapePainterRuntimeObject = function(runtimeScene, objectData)
};
gdjs.ShapePainterRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
gdjs.ShapePainterRuntimeObject.thisIsARuntimeObjectConstructor = "PrimitiveDrawing::Drawer";
gdjs.registerObject("PrimitiveDrawing::Drawer", gdjs.ShapePainterRuntimeObject);
gdjs.ShapePainterRuntimeObject.prototype.getRendererObject = function() {
return this._renderer.getRendererObject();

View File

@@ -33,7 +33,7 @@ gdjs.SkeletonRuntimeObject = function(runtimeScene, objectData){
this.onCreated();
};
gdjs.SkeletonRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
gdjs.SkeletonRuntimeObject.thisIsARuntimeObjectConstructor = "SkeletonObject::Skeleton";
gdjs.registerObject("SkeletonObject::Skeleton", gdjs.SkeletonRuntimeObject);
gdjs.SkeletonRuntimeObject.prototype.extraInitializationFromInitialInstance = function(initialInstanceData) {
if(initialInstanceData.customSize){
@@ -56,18 +56,19 @@ gdjs.SkeletonRuntimeObject.prototype.getSkeletonData = function(runtimeScene, ob
// RuntimeObject overwrites
gdjs.SkeletonRuntimeObject.prototype.setX = function(x){
this.x = x;
gdjs.RuntimeObject.prototype.setX.call(this, x);
this.rootArmature.setX(x);
};
gdjs.SkeletonRuntimeObject.prototype.setY = function(y){
this.y = y;
gdjs.RuntimeObject.prototype.setY.call(this, y);
this.rootArmature.setY(y);
};
gdjs.SkeletonRuntimeObject.prototype.setAngle = function(angle){
this.angle = angle;
this.rootArmature.setRot(angle);
gdjs.RuntimeObject.prototype.setAngle.call(this, angle);
};
gdjs.SkeletonRuntimeObject.prototype.getRendererObject = function(){

View File

@@ -9,16 +9,23 @@
* @class TextEntryRuntimeObject
* @extends RuntimeObject
* @memberof gdjs
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {ObjectData} textEntryObjectData The initial properties of the object
*/
gdjs.TextEntryRuntimeObject = function(runtimeScene, objectData)
gdjs.TextEntryRuntimeObject = function(runtimeScene, textEntryObjectData)
{
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
gdjs.RuntimeObject.call(this, runtimeScene, textEntryObjectData);
/** @type {string} */
this._str = "";
/** @type {boolean} */
this._activated = true;
if (this._renderer)
gdjs.TextEntryRuntimeObjectRenderer.call(this._renderer, this, runtimeScene);
else
/** @type {gdjs.TextEntryRuntimeObjectRenderer} */
this._renderer = new gdjs.TextEntryRuntimeObjectRenderer(this, runtimeScene);
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
@@ -26,7 +33,7 @@ gdjs.TextEntryRuntimeObject = function(runtimeScene, objectData)
};
gdjs.TextEntryRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
gdjs.TextEntryRuntimeObject.thisIsARuntimeObjectConstructor = "TextEntryObject::TextEntry";
gdjs.registerObject("TextEntryObject::TextEntry", gdjs.TextEntryRuntimeObject);
gdjs.TextEntryRuntimeObject.prototype.onDestroyFromScene = function(runtimeScene) {
gdjs.RuntimeObject.prototype.onDestroyFromScene.call(this, runtimeScene);

View File

@@ -4,45 +4,110 @@
*/
/**
* Displays a text on the screen.
* @typedef {Object} TextObjectDataType Base parameters for gdjs.TextRuntimeObject
* @property {number} characterSize The size of the characters
* @property {string} font The font name
* @property {boolean} bold Is Bold?
* @property {boolean} italic Is Italic?
* @property {boolean} underlined Is Underlined?
* @property {Object} color The text color in an RGB representation
* @property {number} color.r The Red level from 0 to 255
* @property {number} color.g The Green level from 0 to 255
* @property {number} color.b The Blue level from 0 to 255
* @property {string} string The text of the object
*
* @typedef {ObjectData & TextObjectDataType} TextObjectData
*/
/**
* Displays a text.
*
* @memberof gdjs
* @class TextRuntimeObject
* @extends RuntimeObject
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {TextObjectData} textObjectData The initial properties of the object
*/
gdjs.TextRuntimeObject = function(runtimeScene, objectData)
gdjs.TextRuntimeObject = function(runtimeScene, textObjectData)
{
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
gdjs.RuntimeObject.call(this, runtimeScene, textObjectData);
this._characterSize = Math.max(1, objectData.characterSize);
this._fontName = objectData.font;
this._bold = objectData.bold;
this._italic = objectData.italic;
this._underlined = objectData.underlined;
this._color = [objectData.color.r, objectData.color.g, objectData.color.b];
/** @type {number} */
this._characterSize = Math.max(1, textObjectData.characterSize);
/** @type {string} */
this._fontName = textObjectData.font;
/** @type {boolean} */
this._bold = textObjectData.bold;
/** @type {boolean} */
this._italic = textObjectData.italic;
/** @type {boolean} */
this._underlined = textObjectData.underlined;
/** @type {Array<number>} */
this._color = [textObjectData.color.r, textObjectData.color.g, textObjectData.color.b];
/** @type {boolean} */
this._useGradient = false;
/** @type {Array} */
this._gradient = [];
/** @type {string} */
this._gradientType = '';
/** @type {number} */
this.opacity = 255;
/** @type {string} */
this._textAlign = 'left';
/** @type {boolean} */
this._wrapping = false;
/** @type {number} */
this._wrappingWidth = 1;
/** @type {number} */
this._outlineThickness = 0;
/** @type {Array<number>} */
this._outlineColor = [255,255,255];
/** @type {boolean} */
this._shadow = false;
/** @type {Array<number>} */
this._shadowColor = [0,0,0];
/** @type {number} */
this._shadowDistance = 1;
/** @type {number} */
this._shadowBlur = 1;
/** @type {number} */
this._shadowAngle = 0;
/** @type {number} */
this._padding = 5;
/** @type {number} */
this._scaleX = 1;
/** @type {number} */
this._scaleY = 1;
this._str = objectData.string;
/** @type {string} */
this._str = textObjectData.string;
if (this._renderer)
gdjs.TextRuntimeObjectRenderer.call(this._renderer, this, runtimeScene);
else
/** @type {gdjs.TextRuntimeObjectRenderer} */
this._renderer = new gdjs.TextRuntimeObjectRenderer(this, runtimeScene);
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
@@ -50,7 +115,7 @@ gdjs.TextRuntimeObject = function(runtimeScene, objectData)
};
gdjs.TextRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
gdjs.TextRuntimeObject.thisIsARuntimeObjectConstructor = "TextObject::Text";
gdjs.registerObject("TextObject::Text", gdjs.TextRuntimeObject);
gdjs.TextRuntimeObject.prototype.getRendererObject = function() {
return this._renderer.getRendererObject();
@@ -132,7 +197,7 @@ gdjs.TextRuntimeObject.prototype.getString = function() {
/**
* Set the string displayed by the object.
* @param {String} str The new text
* @param {string} str The new text
*/
gdjs.TextRuntimeObject.prototype.setString = function(str) {
if ( str === this._str ) return;
@@ -168,7 +233,7 @@ gdjs.TextRuntimeObject.prototype.isBold = function() {
/**
* Set bold for the object text.
* @param enable {Boolean} true to have a bold text, false otherwise.
* @param enable {boolean} true to have a bold text, false otherwise.
*/
gdjs.TextRuntimeObject.prototype.setBold = function(enable) {
this._bold = enable;
@@ -184,7 +249,7 @@ gdjs.TextRuntimeObject.prototype.isItalic = function() {
/**
* Set italic for the object text.
* @param enable {Boolean} true to have an italic text, false otherwise.
* @param enable {boolean} true to have an italic text, false otherwise.
*/
gdjs.TextRuntimeObject.prototype.setItalic = function(enable) {
this._italic = enable;
@@ -305,7 +370,7 @@ gdjs.TextRuntimeObject.prototype.isWrapping = function() {
/**
* Set word wrapping for the object text.
* @param {Boolean} enable true to enable word wrapping, false to disable it.
* @param {boolean} enable true to enable word wrapping, false to disable it.
*/
gdjs.TextRuntimeObject.prototype.setWrapping = function(enable) {
this._wrapping = enable;

View File

@@ -3,34 +3,45 @@
* 2013 Florian Rival (Florian.Rival@gmail.com)
*/
/**
* @typedef {Object} TiledSpriteObjectDataType Initial properties for a Tiled Sprite object
* @property {number} width The width of the object
* @property {number} height The height of the object
*
* @typedef {ObjectData & TiledSpriteObjectDataType} TiledSpriteObjectData
*/
/**
* The TiledSpriteRuntimeObject displays a tiled texture.
*
* @class TiledSpriteRuntimeObject
* @extends RuntimeObject
* @memberof gdjs
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {TiledSpriteObjectData} tiledSpriteObjectData The initial properties of the object
*/
gdjs.TiledSpriteRuntimeObject = function(runtimeScene, objectData)
gdjs.TiledSpriteRuntimeObject = function(runtimeScene, tiledSpriteObjectData)
{
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
gdjs.RuntimeObject.call(this, runtimeScene, tiledSpriteObjectData);
this._xOffset = 0;
this._yOffset = 0;
this.opacity = 255;
if (this._renderer)
gdjs.TiledSpriteRuntimeObjectRenderer.call(this._renderer, this, runtimeScene, objectData.texture);
gdjs.TiledSpriteRuntimeObjectRenderer.call(this._renderer, this, runtimeScene, tiledSpriteObjectData.texture);
else
this._renderer = new gdjs.TiledSpriteRuntimeObjectRenderer(this, runtimeScene, objectData.texture);
/** @type {gdjs.TiledSpriteRuntimeObjectRenderer} */
this._renderer = new gdjs.TiledSpriteRuntimeObjectRenderer(this, runtimeScene, tiledSpriteObjectData.texture);
this.setWidth(objectData.width);
this.setHeight(objectData.height);
this.setWidth(tiledSpriteObjectData.width);
this.setHeight(tiledSpriteObjectData.height);
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
this.onCreated();
};
gdjs.TiledSpriteRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
gdjs.TiledSpriteRuntimeObject.thisIsARuntimeObjectConstructor = "TiledSpriteObject::TiledSprite";
gdjs.registerObject("TiledSpriteObject::TiledSprite", gdjs.TiledSpriteRuntimeObject);
gdjs.TiledSpriteRuntimeObject.prototype.getRendererObject = function() {
return this._renderer.getRendererObject();

View File

@@ -36,7 +36,7 @@ gdjs.TopDownMovementRuntimeBehavior = function(runtimeScene, behaviorData, owner
};
gdjs.TopDownMovementRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.TopDownMovementRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "TopDownMovementBehavior::TopDownMovementBehavior";
gdjs.registerBehavior("TopDownMovementBehavior::TopDownMovementBehavior", gdjs.TopDownMovementRuntimeBehavior);
gdjs.TopDownMovementRuntimeBehavior.prototype.setAcceleration = function(acceleration) {
this._acceleration = acceleration;

View File

@@ -18,8 +18,7 @@ gdjs.TweenRuntimeBehavior.prototype = Object.create(
gdjs.RuntimeBehavior.prototype
);
gdjs.TweenRuntimeBehavior.thisIsARuntimeBehaviorConstructor =
"Tween::TweenBehavior";
gdjs.registerBehavior("Tween::TweenBehavior", gdjs.TweenRuntimeBehavior);
gdjs.TweenRuntimeBehavior.easings = [
"linear",

View File

@@ -1,3 +1,14 @@
/**
* @typedef {Object} VideoObjectDataType The initial properties for {@link gdjs.VideoRuntimeObject}
* @property {Object} content The base parameters of the video
* @property {number} content.opacity The opacity of the video
* @property {boolean} content.loop Does the video loops itself?
* @property {number} content.volume The volume of the video
* @property {string} content.videoResource Name of the resource corresponding to the video
*
* @typedef {ObjectData & VideoObjectDataType} VideoObjectData
*/
/**
* An object displaying a video on screen.
*
@@ -6,29 +17,32 @@
* video will have the same state for this video (paused/playing, current time,
* volume, etc...).
*
* @memberof gdjs
* @memberOf gdjs
* @class VideoRuntimeObject
* @extends RuntimeObject
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
* @param {VideoObjectData} videoObjectData The data defining the object
*/
gdjs.VideoRuntimeObject = function(runtimeScene, objectData) {
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
gdjs.VideoRuntimeObject = function(runtimeScene, videoObjectData) {
gdjs.RuntimeObject.call(this, runtimeScene, videoObjectData);
/** @type number */
this._opacity = objectData.content.opacity;
/** @type boolean */
this._loop = objectData.content.loop;
/** @type number */
this._volume = objectData.content.volume;
/** @type string */
this._videoResource = objectData.content.videoResource;
/** @type {number} */
this._opacity = videoObjectData.content.opacity;
/** @type {boolean} */
this._loop = videoObjectData.content.loop;
/** @type {number} */
this._volume = videoObjectData.content.volume;
/** @type {string} */
this._videoResource = videoObjectData.content.videoResource;
// Use a boolean to track if the video was paused because we
// navigated to another scene, and so should resume if we're back.
/** @type boolean */
/** @type {boolean} */
this._pausedAsScenePaused = false;
if (this._renderer)
gdjs.VideoRuntimeObjectRenderer.call(this._renderer, this, runtimeScene);
/** @type {gdjs.VideoRuntimeObjectRenderer} */
else this._renderer = new gdjs.VideoRuntimeObjectRenderer(this, runtimeScene);
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
@@ -36,7 +50,7 @@ gdjs.VideoRuntimeObject = function(runtimeScene, objectData) {
};
gdjs.VideoRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
gdjs.VideoRuntimeObject.thisIsARuntimeObjectConstructor = "Video::VideoObject";
gdjs.registerObject("Video::VideoObject", gdjs.VideoRuntimeObject);
gdjs.VideoRuntimeObject.prototype.getRendererObject = function() {
return this._renderer.getRendererObject();
@@ -45,6 +59,7 @@ gdjs.VideoRuntimeObject.prototype.getRendererObject = function() {
/**
* Initialize the extra parameters that could be set for an instance.
* @private
* @param {{customSize: {width: number, height: number}}} initialInstanceData The initial instance data
*/
gdjs.VideoRuntimeObject.prototype.extraInitializationFromInitialInstance = function(
initialInstanceData
@@ -103,6 +118,7 @@ gdjs.VideoRuntimeObject.prototype.setOpacity = function(opacity) {
/**
* Get object opacity.
* @returns {number} The current opacity
*/
gdjs.VideoRuntimeObject.prototype.getOpacity = function() {
return this._opacity;
@@ -126,6 +142,7 @@ gdjs.VideoRuntimeObject.prototype.setHeight = function(height) {
/**
* Get the width of the video object.
* @returns {number} The current width of the object
*/
gdjs.VideoRuntimeObject.prototype.getWidth = function() {
return this._renderer.getWidth();
@@ -133,6 +150,7 @@ gdjs.VideoRuntimeObject.prototype.getWidth = function() {
/**
* Get the height of the video object.
* @returns {number} The current height of the object
*/
gdjs.VideoRuntimeObject.prototype.getHeight = function() {
return this._renderer.getHeight();
@@ -140,6 +158,7 @@ gdjs.VideoRuntimeObject.prototype.getHeight = function() {
/**
* Get if the video object is playing
* @returns {boolean} Is the current video playing?
*/
gdjs.VideoRuntimeObject.prototype.play = function() {
this._renderer.play();
@@ -147,6 +166,7 @@ gdjs.VideoRuntimeObject.prototype.play = function() {
/**
* Get if the video object is paused.
* @returns {boolean} Is the current video paused?
*/
gdjs.VideoRuntimeObject.prototype.pause = function() {
this._renderer.pause();
@@ -170,13 +190,18 @@ gdjs.VideoRuntimeObject.prototype.mute = function(enable) {
/**
* Return the state muted of video object.
* @returns {boolean} Is the video muted?
*/
gdjs.VideoRuntimeObject.prototype.isMuted = function() {
return this._renderer.isMuted();
};
/**
* Normalize a value between 0 and 100 to a value between 0 and 1.
* Normalize a value between `min` and `max` to a value between 0 and 1.
* @param {number} val The value to normalize
* @param {number} max The maximum
* @param {number} min The minimum
* @returns {number} The normalized value
*/
gdjs.VideoRuntimeObject.prototype._normalize = function(val, min, max) {
return (val - min) / (max - min);
@@ -184,7 +209,7 @@ gdjs.VideoRuntimeObject.prototype._normalize = function(val, min, max) {
/**
* Set the volume of the video object.
* @param {number} volume The new volume.
* @param {number} volume The new volume, between 0 and 100.
*/
gdjs.VideoRuntimeObject.prototype.setVolume = function(volume) {
this._volume =
@@ -194,6 +219,7 @@ gdjs.VideoRuntimeObject.prototype.setVolume = function(volume) {
/**
* Get the volume of the video object.
* @returns {number} The current video's volume, betwenn 0 and 100.
*/
gdjs.VideoRuntimeObject.prototype.getVolume = function() {
return this._normalize(this._renderer.getVolume(), 0, 1) * 100;
@@ -201,6 +227,7 @@ gdjs.VideoRuntimeObject.prototype.getVolume = function() {
/**
* Check if the video is being played.
* @returns {boolean} Is the video being played?
*/
gdjs.VideoRuntimeObject.prototype.isPlayed = function() {
return this._renderer.isPlayed();
@@ -208,6 +235,7 @@ gdjs.VideoRuntimeObject.prototype.isPlayed = function() {
/**
* Check if the video is paused.
* @returns {boolean} Is the video being paused?
*/
gdjs.VideoRuntimeObject.prototype.isPaused = function() {
return !this._renderer.isPlayed();
@@ -215,6 +243,7 @@ gdjs.VideoRuntimeObject.prototype.isPaused = function() {
/**
* Check if the video is looping.
* @returns {boolean} Is the video looping?
*/
gdjs.VideoRuntimeObject.prototype.isLooped = function() {
return this._renderer.isLooped();
@@ -222,6 +251,7 @@ gdjs.VideoRuntimeObject.prototype.isLooped = function() {
/**
* Return the total time of the video.
* @returns {number} The duration of the video
*/
gdjs.VideoRuntimeObject.prototype.getDuration = function() {
return this._renderer.getDuration();
@@ -229,6 +259,7 @@ gdjs.VideoRuntimeObject.prototype.getDuration = function() {
/**
* Check if the video has ended.
* @returns {boolean} Has the video ended?
*/
gdjs.VideoRuntimeObject.prototype.isEnded = function() {
return this._renderer.isEnded();
@@ -244,6 +275,7 @@ gdjs.VideoRuntimeObject.prototype.setCurrentTime = function(time) {
/**
* Get the current time of the video object.
* @returns {number} The current time of the video
*/
gdjs.VideoRuntimeObject.prototype.getCurrentTime = function() {
return this._renderer.getCurrentTime();
@@ -260,6 +292,7 @@ gdjs.VideoRuntimeObject.prototype.setPlaybackSpeed = function(playbackSpeed) {
/**
* Get the playback speed of the video object.
* @returns {number} The current playback speed of the video.
*/
gdjs.VideoRuntimeObject.prototype.getPlaybackSpeed = function() {
return this._renderer.getPlaybackSpeed();
@@ -270,10 +303,9 @@ gdjs.VideoRuntimeObject.prototype.getPlaybackSpeed = function() {
* TODO: Investigate how to dispose the video source?
*
* @private
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} that is being unloaded
*/
gdjs.VideoRuntimeObject.gdjsCallbackRuntimeSceneUnloaded = function(
runtimeScene
) {
gdjs.VideoRuntimeObject.gdjsCallbackRuntimeSceneUnloaded = function(runtimeScene) {
// Manually find all the gdjs.VideoRuntimeObject living on the scene,
// and pause them.
var instances = runtimeScene.getAdhocListOfAllInstances();
@@ -290,10 +322,9 @@ gdjs.VideoRuntimeObject.gdjsCallbackRuntimeSceneUnloaded = function(
/**
* When a scene is paused, pause any video being run.
* @private
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} that is being paused
*/
gdjs.VideoRuntimeObject.gdjsCallbackRuntimeScenePaused = function(
runtimeScene
) {
gdjs.VideoRuntimeObject.gdjsCallbackRuntimeScenePaused = function(runtimeScene) {
// Manually find all the gdjs.VideoRuntimeObject living on the scene,
// and pause them.
var instances = runtimeScene.getAdhocListOfAllInstances();
@@ -311,10 +342,9 @@ gdjs.VideoRuntimeObject.gdjsCallbackRuntimeScenePaused = function(
/**
* When a scene is resumed, resume any video previously paused.
* @private
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} that is being resumed
*/
gdjs.VideoRuntimeObject.gdjsCallbackRuntimeSceneResumed = function(
runtimeScene
) {
gdjs.VideoRuntimeObject.gdjsCallbackRuntimeSceneResumed = function(runtimeScene) {
// Manually find all the gdjs.VideoRuntimeObject living on the scene,
// and play them if they have been previously paused.
var instances = runtimeScene.getAdhocListOfAllInstances();

View File

@@ -109,10 +109,6 @@ BaseObjectExtension::BaseObjectExtension() {
objectActions["Ecarter"]
.SetFunctionName("SeparateObjectsWithoutForces")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectActions["SeparateFromObjects"]
.SetFunctionName("SeparateFromObjects")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectConditions["CollisionPoint"].SetFunctionName("IsCollidingWithPoint");
objectExpressions["X"].SetFunctionName("GetX");
objectExpressions["Y"].SetFunctionName("GetY");
@@ -174,6 +170,9 @@ BaseObjectExtension::BaseObjectExtension() {
.SetFunctionName("PickedObjectsCount")
.SetManipulatedType("number")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
GetAllConditions()["SeparateFromObjects"]
.SetFunctionName("SeparateObjects")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
GetAllConditions()["CollisionNP"]
.SetFunctionName("HitBoxesCollision")
.SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
@@ -186,6 +185,7 @@ BaseObjectExtension::BaseObjectExtension() {
GetAllConditions()["RaycastToPosition"]
.SetFunctionName("RaycastObjectToPosition")
.SetIncludeFile("GDCpp/Extensions/Builtin/RuntimeSceneTools.h");
GetAllConditions()["CollisionPoint"].SetFunctionName("IsCollidingWithPoint");
GetAllExpressions()["Count"]
.SetFunctionName("PickedObjectsCount")

View File

@@ -43,6 +43,35 @@ bool GD_API HitBoxesCollision(
});
}
void GD_API SeparateObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
bool ignoreTouchingEdges,
RuntimeScene & /*scene*/) {
for (auto it : objectsLists1) {
if (!it.second) continue;
const std::vector<RuntimeObject *> &list = *it.second;
for (auto runtimeObject : list) {
runtimeObject->SeparateFromObjects(objectsLists2, ignoreTouchingEdges);
}
}
}
bool GD_API IsCollidingWithPoint(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists,
double pointX,
double pointY,
bool conditionInverted,
RuntimeScene &scene) {
return PickObjectsIf(objectsLists,
conditionInverted,
[pointX, pointY](RuntimeObject *runtimeObject) {
return runtimeObject->IsCollidingWithPoint(pointX,
pointY);
});
}
bool GD_API ObjectsTurnedToward(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
@@ -69,7 +98,8 @@ float GD_API DistanceBetweenObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
float length,
bool conditionInverted) {
bool conditionInverted,
RuntimeScene & /*scene*/) {
length *= length;
return TwoObjectListsTest(
objectsLists1,

View File

@@ -25,6 +25,9 @@ bool GD_API ObjectsTurnedToward(
/**
* Only used internally by GD events generated code.
*
* Complexity is O(n*m) and could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
bool GD_API HitBoxesCollision(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
@@ -33,6 +36,31 @@ bool GD_API HitBoxesCollision(
RuntimeScene &scene,
bool ignoreTouchingEdges = false);
/**
* Only used internally by GD events generated code.
*
* Complexity is O(n*m) and could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
void GD_API SeparateObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
bool ignoreTouchingEdges,
RuntimeScene &scene);
/**
* Only used internally by GD events generated code.
*
* Complexity could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
bool GD_API IsCollidingWithPoint(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists,
double x,
double y,
bool conditionInverted,
RuntimeScene &scene);
/**
* Only used internally by GD events generated code.
*/
@@ -41,12 +69,16 @@ double GD_API PickedObjectsCount(
/**
* Only used internally by GD events generated code.
*
* Complexity is O(n*m) and could be improved by using a spatial data structure
* to store object positions (see GDJS).
*/
float GD_API DistanceBetweenObjects(
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists1,
std::map<gd::String, std::vector<RuntimeObject *> *> objectsLists2,
float length,
bool conditionInverted);
bool conditionInverted,
RuntimeScene &scene);
/**
* Only used internally by GD events generated code.

View File

@@ -6,7 +6,7 @@ GDevelop C++ Platform (GDcpp) is a platform for developing *native games* with G
Getting started
---------------
First, take a look at the *Readme.md* at the root of the repository and the [developer documentation](http://4ian.github.io/GD-Documentation/).
First, take a look at the *Readme.md* at the root of the repository and the [developer documentation](https://docs.gdevelop-app.com/).
This platform uses the same files for exposing its functionalities to the IDE and for the game engine. When compiled the game engine only, a define is set (*GD_IDE_ONLY*). Look at the code using this define to check if the code will be included or not into the game engine:
@@ -16,7 +16,7 @@ This platform uses the same files for exposing its functionalities to the IDE an
//Code that will be available for compiled games as well as when compiled for the IDE.
The documentation of this specific platform and the game engine is available [here](http://4ian.github.io/GD-Documentation/GDCpp%20Documentation).
The documentation of this specific platform and the game engine is available [here](https://docs.gdevelop-app.com/GDCpp%20Documentation).
Contributing
------------

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = "GDevelop C++ Platform"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER =
PROJECT_NUMBER =
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -118,7 +118,7 @@ REPEAT_BRIEF = YES
# the entity):The $name class, The $name widget, The $name file, is, provides,
# specifies, contains, represents, a, an and the.
ABBREVIATE_BRIEF =
ABBREVIATE_BRIEF =
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# doxygen will generate a detailed section even if there is only a brief
@@ -152,7 +152,7 @@ FULL_PATH_NAMES = NO
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
@@ -161,7 +161,7 @@ STRIP_FROM_PATH =
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
@@ -228,13 +228,13 @@ TAB_SIZE = 8
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
ALIASES =
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
@@ -281,7 +281,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.
EXTENSION_MAPPING =
EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
@@ -617,7 +617,7 @@ GENERATE_DEPRECATEDLIST= YES
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
# ... \endcond blocks.
ENABLED_SECTIONS =
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
# initial value of a variable or macro / define can have for it to appear in the
@@ -659,7 +659,7 @@ SHOW_NAMESPACES = YES
# by doxygen. Whatever the program writes to standard output is used as the file
# version. For an example see the documentation.
FILE_VERSION_FILTER =
FILE_VERSION_FILTER =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
@@ -672,7 +672,7 @@ FILE_VERSION_FILTER =
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
LAYOUT_FILE =
LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
@@ -682,7 +682,7 @@ LAYOUT_FILE =
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
CITE_BIB_FILES =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
@@ -741,7 +741,7 @@ WARN_FORMAT = "$file:$line: $text"
# messages should be written. If left blank the output is written to standard
# error (stderr).
WARN_LOGFILE =
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
@@ -773,7 +773,7 @@ INPUT_ENCODING = UTF-8
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
# *.qsf, *.as and *.js.
FILE_PATTERNS =
FILE_PATTERNS =
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@@ -788,7 +788,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE =
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@@ -804,7 +804,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -821,14 +821,14 @@ EXCLUDE_SYMBOLS = TiXml*
# that contain example code fragments that are included (see the \include
# command).
EXAMPLE_PATH =
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
# *.h) to filter out the source-files in the directories. If left blank all
# files are included.
EXAMPLE_PATTERNS =
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude commands
@@ -841,7 +841,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -858,7 +858,7 @@ IMAGE_PATH =
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
INPUT_FILTER =
INPUT_FILTER =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the
@@ -867,7 +867,7 @@ INPUT_FILTER =
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
FILTER_PATTERNS =
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER ) will also be used to filter the input files that are used for
@@ -882,14 +882,14 @@ FILTER_SOURCE_FILES = NO
# *.ext= (so without naming a filter).
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
FILTER_SOURCE_PATTERNS =
FILTER_SOURCE_PATTERNS =
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
# is part of the input, its contents will be placed on the main page
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE =
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# Configuration options related to source browsing
@@ -994,7 +994,7 @@ CLANG_ASSISTED_PARSING = NO
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
CLANG_OPTIONS =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
@@ -1020,7 +1020,7 @@ COLS_IN_ALPHA_INDEX = 5
# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX =
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
@@ -1064,7 +1064,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER =
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1074,7 +1074,7 @@ HTML_HEADER =
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER =
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1086,7 +1086,7 @@ HTML_FOOTER =
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_STYLESHEET =
HTML_STYLESHEET =
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
@@ -1162,7 +1162,7 @@ HTML_COLORSTYLE_GAMMA = 70
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
@@ -1273,7 +1273,7 @@ GENERATE_CHI = NO
# and project file content.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_INDEX_ENCODING =
CHM_INDEX_ENCODING =
# The BINARY_TOC flag controls whether a binary table of contents is generated (
# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
@@ -1304,7 +1304,7 @@ GENERATE_QHP = NO
# the HTML output folder.
# This tag requires that the tag GENERATE_QHP is set to YES.
QCH_FILE =
QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
@@ -1329,7 +1329,7 @@ QHP_VIRTUAL_FOLDER = doc
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
@@ -1337,21 +1337,21 @@ QHP_CUST_FILTER_NAME =
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
# The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
# generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
# generated, together with the HTML files, they form an Eclipse help plugin. To
@@ -1484,7 +1484,7 @@ MATHJAX_RELPATH = http://www.mathjax.org/mathjax
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
@@ -1492,7 +1492,7 @@ MATHJAX_EXTENSIONS =
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_CODEFILE =
MATHJAX_CODEFILE =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
# the HTML output. The underlying search engine uses javascript and DHTML and
@@ -1552,7 +1552,7 @@ EXTERNAL_SEARCH = NO
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
SEARCHENGINE_URL =
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
# search data is written to a file for indexing by an external tool. With the
@@ -1568,7 +1568,7 @@ SEARCHDATA_FILE = searchdata.xml
# projects and redirect the results back to the right project.
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTERNAL_SEARCH_ID =
EXTERNAL_SEARCH_ID =
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
# projects other than the one defined by this configuration file, but that are
@@ -1578,7 +1578,7 @@ EXTERNAL_SEARCH_ID =
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTRA_SEARCH_MAPPINGS =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
@@ -1639,7 +1639,7 @@ PAPER_TYPE = a4
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
EXTRA_PACKAGES =
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
@@ -1655,7 +1655,7 @@ EXTRA_PACKAGES =
# HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
@@ -1666,7 +1666,7 @@ LATEX_HEADER =
# Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
LATEX_FOOTER =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output
@@ -1674,7 +1674,7 @@ LATEX_FOOTER =
# markers available.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_FILES =
LATEX_EXTRA_FILES =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
@@ -1774,14 +1774,14 @@ RTF_HYPERLINKS = NO
# default style sheet that doxygen normally uses.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_STYLESHEET_FILE =
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# Configuration options related to the man page output
@@ -1816,7 +1816,7 @@ MAN_EXTENSION = .3
# MAN_EXTENSION with the initial . removed.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_SUBDIR =
MAN_SUBDIR =
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real
@@ -1929,7 +1929,7 @@ PERLMOD_PRETTY = YES
# overwrite each other's variables.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_MAKEVAR_PREFIX =
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
@@ -1970,7 +1970,7 @@ SEARCH_INCLUDES = YES
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1978,7 +1978,7 @@ INCLUDE_PATH =
# used.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
INCLUDE_FILE_PATTERNS =
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that are
# defined before the preprocessor is started (similar to the -D option of e.g.
@@ -1998,7 +1998,7 @@ PREDEFINED = WXUNUSED()= \
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED =
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
@@ -2027,13 +2027,13 @@ SKIP_FUNCTION_MACROS = YES
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
TAGFILES =
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
# tag file that is based on the input files it reads. See section "Linking to
# external documentation" for more information about the usage of tag files.
GENERATE_TAGFILE =
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
# class index. If set to NO only the inherited external classes will be listed.
@@ -2081,14 +2081,14 @@ CLASS_DIAGRAMS = NO
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
# If left empty dia is assumed to be found in the default search path.
DIA_PATH =
DIA_PATH =
# If set to YES, the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
@@ -2137,7 +2137,7 @@ DOT_FONTSIZE = 10
# the path where dot can find it using this tag.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTPATH =
DOT_FONTPATH =
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
# each documented class showing the direct and indirect inheritance relations.
@@ -2282,19 +2282,19 @@ DOT_PATH = "C:\Program Files (x86)\Graphviz 2.28\bin\dot.exe"
# command).
# This tag requires that the tag HAVE_DOT is set to YES.
DOTFILE_DIRS =
DOTFILE_DIRS =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
# command).
MSCFILE_DIRS =
MSCFILE_DIRS =
# The DIAFILE_DIRS tag can be used to specify one or more directories that
# contain dia files that are included in the documentation (see the \diafile
# command).
DIAFILE_DIRS =
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
@@ -2303,7 +2303,7 @@ DIAFILE_DIRS =
# will not generate output for the diagram.
# This tag requires that the tag HAVE_DOT is set to YES.
PLANTUML_JAR_PATH =
PLANTUML_JAR_PATH =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes

View File

@@ -75,21 +75,3 @@ ELSE()
target_link_libraries(GDJS GDCore)
target_link_libraries(GDJS ${sfml_LIBRARIES})
ENDIF()
#Post build tasks
###
IF(EMSCRIPTEN)
#Nothing.
ELSE()
IF(WIN32)
add_custom_target(GDJS_Runtime
ALL
COMMAND "${GD_base_dir}/GDJS/scripts/CopyRuntimeToGD.bat" ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/JsPlatform/Runtime
WORKING_DIRECTORY ${GD_base_dir}/GDJS/scripts)
ELSE()
add_custom_target(GDJS_Runtime
ALL
COMMAND bash "CopyRuntimeToGD.sh" ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/JsPlatform/Runtime
WORKING_DIRECTORY ${GD_base_dir}/GDJS/scripts)
ENDIF()
ENDIF()

View File

@@ -105,7 +105,7 @@ CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME = function(runtimeScene, behaviorData,
};
CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME.thisIsARuntimeBehaviorConstructor = "EXTENSION_NAME::BEHAVIOR_NAME";
gdjs.registerBehavior("EXTENSION_NAME::BEHAVIOR_NAME", CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME);
// Properties:
PROPERTIES_CODE

View File

@@ -114,9 +114,6 @@ BaseObjectExtension::BaseObjectExtension() {
objectConditions["AngleOfDisplacement"]
.SetFunctionName("averageForceAngleIs")
.SetIncludeFile("runtimeobject.js");
objectActions["SeparateFromObjects"]
.SetFunctionName("separateFromObjectsList")
.SetIncludeFile("runtimeobject.js");
objectActions["Ecarter"]
.codeExtraInformation // Deprecated
.SetFunctionName("separateObjectsWithoutForces")
@@ -140,9 +137,6 @@ BaseObjectExtension::BaseObjectExtension() {
objectActions["ObjectVariableClearChildren"]
.SetFunctionName("variableClearChildren")
.SetIncludeFile("runtimeobject.js");
objectConditions["CollisionPoint"]
.SetFunctionName("isCollidingWithPoint")
.SetIncludeFile("runtimeobject.js");
objectConditions["ObjectTimer"]
.SetFunctionName("timerElapsedTime")
.SetIncludeFile("runtimeobject.js");
@@ -202,8 +196,10 @@ BaseObjectExtension::BaseObjectExtension() {
"gdjs.evtTools.object.pickedObjectsCount");
GetAllConditions()["NbObjet"].SetFunctionName(
"gdjs.evtTools.object.pickedObjectsCount");
GetAllConditions()["CollisionNP"]
.SetFunctionName("gdjs.evtTools.object.hitBoxesCollisionTest");
GetAllActions()["SeparateFromObjects"].SetFunctionName(
"gdjs.evtTools.object.separateObjects");
GetAllConditions()["CollisionNP"].SetFunctionName(
"gdjs.evtTools.object.hitBoxesCollisionTest");
GetAllConditions()["Raycast"].SetFunctionName(
"gdjs.evtTools.object.raycastObject");
GetAllConditions()["RaycastToPosition"].SetFunctionName(
@@ -214,6 +210,8 @@ BaseObjectExtension::BaseObjectExtension() {
"gdjs.evtTools.object.movesTowardTest");
GetAllConditions()["EstTourne"].SetFunctionName(
"gdjs.evtTools.object.turnedTowardTest");
GetAllConditions()["CollisionPoint"].SetFunctionName(
"gdjs.evtTools.object.isCollidingWithPoint");
GetAllActions()["AjoutObjConcern"].SetFunctionName(
"gdjs.evtTools.object.pickAllObjects");

View File

@@ -23,6 +23,8 @@ WindowExtension::WindowExtension() {
"gdjs.evtTools.window.setWindowTitle");
GetAllActions()["SetWindowSize"].SetFunctionName(
"gdjs.evtTools.window.setWindowSize");
GetAllActions()["CenterWindow"].SetFunctionName(
"gdjs.evtTools.window.centerWindow");
GetAllActions()["SetGameResolutionSize"].SetFunctionName(
"gdjs.evtTools.window.setGameResolutionSize");
GetAllActions()["SetGameResolutionResizeMode"].SetFunctionName(

View File

@@ -84,6 +84,9 @@ bool Exporter::ExportWholePixiProject(
// Export engine libraries
helper.AddLibsInclude(true, false, false, includesFiles);
// Export effects (after engine libraries as they auto-register themselves to the engine)
helper.ExportEffectIncludes(exportedProject, includesFiles);
// Export events
if (!helper.ExportEventsCode(
exportedProject, codeOutputDir, includesFiles, false)) {
@@ -174,6 +177,9 @@ bool Exporter::ExportWholeCocos2dProject(gd::Project& project,
// Export engine libraries
helper.AddLibsInclude(false, true, false, includesFiles);
// Export effects (after engine libraries as they auto-register themselves to the engine)
helper.ExportEffectIncludes(exportedProject, includesFiles);
// Export events
if (!helper.ExportEventsCode(
exportedProject, codeOutputDir, includesFiles, false)) {

View File

@@ -528,6 +528,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
InsertUnique(includesFiles, "gd-splash-image.js");
InsertUnique(includesFiles, "libs/hshg.js");
InsertUnique(includesFiles, "libs/rbush.js");
InsertUnique(includesFiles, "objectpositionsmanager.js");
InsertUnique(includesFiles, "inputmanager.js");
InsertUnique(includesFiles, "jsonmanager.js");
InsertUnique(includesFiles, "timemanager.js");

View File

@@ -3,7 +3,7 @@
GDevelop JavaScript Platform (GDJS) is the game engine for making
_HTML5/Javascript_ based games with GDevelop.
> 📚 **Game developer, searching for the documentation?** Go to the **[GDJS Runtime (game engine) documentation](http://4ian.github.io/GD-Documentation/GDJS%20Documentation)**.
> 📚 **Game developer, searching for the documentation?** Go to the **[GDJS Runtime (game engine) documentation](https://docs.gdevelop-app.com/GDJS%20Documentation)**.
## 1) Installation 💻
@@ -20,7 +20,7 @@ GDJS is composed of two parts:
The game engine is in the _Runtime_ folder. If you want to work on the engine directly, follow the [GDevelop 5 README about development of the game engine](https://github.com/4ian/GDevelop/blob/master/newIDE/README.md#development-of-the-game-engine).
* To use the game engine, you can look into the **[GDJS Runtime (game engine) documentation](http://4ian.github.io/GD-Documentation/GDJS%20Runtime%20Documentation)**.
* To use the game engine, you can look into the **[GDJS Runtime (game engine) documentation](https://docs.gdevelop-app.com/GDJS%20Runtime%20Documentation)**.
* To run tests for the game engine, go to `GDJS/tests`, run `npm install` and `npm test`. More information in the [README for the tests](https://github.com/4ian/GDevelop/tree/master/GDJS/tests).
@@ -28,7 +28,7 @@ The game engine is in the _Runtime_ folder. If you want to work on the engine di
### GDJS Platform (exporters, code generation...)
Check the [GDJS Platform](http://4ian.github.io/GD-Documentation/GDJS%20Documentation/index.html) documentation, or the [full GDevelop developers documentation](http://4ian.github.io/GD-Documentation/).
Check the [GDJS Platform](https://docs.gdevelop-app.com/GDJS%20Documentation/index.html) documentation, or the [full GDevelop developers documentation](https://docs.gdevelop-app.com/).
## 3) How to contribute 😎

View File

@@ -66,6 +66,21 @@ gdjs.RuntimeGameCocosRenderer.prototype.setWindowSize = function(width, height)
}
};
/**
* Center the window on screen.
*/
gdjs.RuntimeGameCocosRenderer.prototype.centerWindow = function() {
var electron = this.getElectron();
if (electron) { // Use Electron BrowserWindow API
var browserWindow = electron.remote.getCurrentWindow();
if (browserWindow) {
browserWindow.center();
}
} else {
// Not supported
}
}
gdjs.RuntimeGameCocosRenderer.prototype.setWindowTitle = function(title) {
if (typeof document !== 'undefined') document.title = title;
}

View File

@@ -1,3 +1,5 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
@@ -95,7 +97,7 @@ gdjs.evtTools.input.keysNameToCode = {
"x": 88,
"y": 89,
"z": 90,
"Num0": 48,
"Num1": 49,
"Num2": 50,
@@ -226,11 +228,85 @@ gdjs.evtTools.input.getMouseY = function(runtimeScene, layer, camera) {
runtimeScene.getGame().getInputManager().getMouseY())[1];
};
/**
* @param {Hashtable} objectsLists The objects to consider for the test
* @returns {Object.<string, ObjectIdsSet>} Sets of object ids keyed by the name of the layer the objects are on.
*/
gdjs.evtTools.input._objectsListsToObjectIdsSetGroupedPerLayer = function(objectsLists) {
/** @type Object.<string, ObjectIdsSet> */
var layerObjectIdsSets = {};
for (var key in objectsLists.items) {
/** @type gdjs.RuntimeObject[] */
var list = objectsLists.items[key];
for (var i = 0; i < list.length; ++i) {
var object = list[i];
var layerName = object.getLayer();
layerObjectIdsSets[layerName] = layerObjectIdsSets[layerName] || gdjs.ObjectPositionsManager.makeNewObjectIdsSet();
layerObjectIdsSets[layerName].items[object.id] = true;
}
}
return layerObjectIdsSets;
}
/**
* @param {Hashtable} objectsLists The objects to consider for the test
* @param {gdjs.RuntimeScene} runtimeScene
* @param {boolean} accurate
* @param {boolean} inverted
* @returns {boolean}
*/
gdjs.evtTools.input.cursorOnObject = function(objectsLists, runtimeScene, accurate, inverted) {
var isTrue = false;
var inputManager = runtimeScene.getGame().getInputManager();
// Find the mouse and touch positions on each layer
/** @type Object.<string, number[][]> */
var layersCursorPositions = {};
/** @type string[] */
var allLayerNames = [];
runtimeScene.getAllLayerNames(allLayerNames);
for(var i = 0;i<allLayerNames.length;i++) {
var layerName = allLayerNames[i];
var layer = runtimeScene.getLayer(layerName);
/** @type number[][] */
var cursorPositions = [];
cursorPositions.push(layer.convertCoords(inputManager.getMouseX(), inputManager.getMouseY(), 0));
var touchIds = inputManager.getAllTouchIdentifiers();
for(var j = 0;j<touchIds.length;++j) {
cursorPositions.push(layer.convertCoords(inputManager.getTouchX(touchIds[j]),
inputManager.getTouchY(touchIds[j]), 0));
}
layersCursorPositions[layerName] = cursorPositions;
}
// Group object ids per layer and check which objects are colliding with any of the cursor positions.
var layerObjectIdsSets = gdjs.evtTools.input._objectsListsToObjectIdsSetGroupedPerLayer(objectsLists);
for(var layerName in layerObjectIdsSets) {
var objectIdsSet = layerObjectIdsSets[layerName];
var cursorPositions = layersCursorPositions[layerName];
isTrue = runtimeScene.getObjectPositionsManager().pointsTest(objectIdsSet, cursorPositions, accurate, inverted) || isTrue;
}
// Trim the object lists to keep only objects satisfying the tests
gdjs.ObjectPositionsManager.keepOnlyObjectsFromGroupedObjectIdsSets(objectsLists, layerObjectIdsSets);
return isTrue;
};
gdjs.evtTools.input._cursorIsOnObject = function(obj, runtimeScene) {
return obj.cursorOnObject(runtimeScene);
};
gdjs.evtTools.input.cursorOnObject = function(objectsLists, runtimeScene, accurate, inverted) {
gdjs.evtTools.input.OLDcursorOnObject = function(objectsLists, runtimeScene, accurate, inverted) {
return gdjs.evtTools.object.pickObjectsIf(gdjs.evtTools.input._cursorIsOnObject,
objectsLists, inverted, runtimeScene);
};

View File

@@ -1,3 +1,4 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
@@ -165,7 +166,7 @@ gdjs.evtTools.object.twoListsTest = function(predicate, objectsLists1, objectsLi
* @param {Function} predicate The function applied to each object: must return true if the object fulfill the predicate.
* @param {Hashtable} objectsLists The lists of objects to trim
* @param {boolean} negatePredicate If set to true, the result of the predicate is negated.
* @param {*} extraArg Argument passed to the predicate (along with the object). Useful for avoiding relying on temporary closures.
* @param {any=} extraArg Argument passed to the predicate (along with the object). Useful for avoiding relying on temporary closures.
* @return {boolean} true if at least one object fulfill the predicate.
*/
gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePredicate, extraArg) {
@@ -186,6 +187,7 @@ gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePre
var arr = lists[i];
for(var k = 0, lenk = arr.length;k<lenk;++k) {
// @ts-ignore
if (negatePredicate ^ predicate(arr[k], extraArg)) {
isTrue = true;
arr[k].pick = true; //Pick the objects
@@ -211,20 +213,93 @@ gdjs.evtTools.object.pickObjectsIf = function(predicate, objectsLists, negatePre
return isTrue;
};
/**
* @param {Hashtable} objectsLists1 The lists of objects to test collisions for
* @param {Hashtable} objectsLists2 The second lists of objects to test collisions for
* @param {boolean} inverted If set to true, only objects from the first lists that are not in collision with *any* other objects will be picked.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
* @param {boolean} ignoreTouchingEdges If true, polygons are not considered in collision if only their edges are touching.
*/
gdjs.evtTools.object.hitBoxesCollisionTest = function(objectsLists1, objectsLists2, inverted, runtimeScene, ignoreTouchingEdges) {
var object1IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists1);
var object2IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists2);
var isTrue = runtimeScene.getObjectPositionsManager().collisionTest(object1IdsSet, object2IdsSet, inverted, ignoreTouchingEdges);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists1, object1IdsSet);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists2, object2IdsSet);
return isTrue;
};
gdjs.evtTools.object.OLDhitBoxesCollisionTest = function(objectsLists1, objectsLists2, inverted, runtimeScene, ignoreTouchingEdges) {
return gdjs.evtTools.object.twoListsTest(gdjs.RuntimeObject.collisionTest,
objectsLists1, objectsLists2, inverted, ignoreTouchingEdges);
objectsLists1, objectsLists2, inverted, ignoreTouchingEdges);
}
/**
* @param {Hashtable} objectsLists1 The lists of objects to test distance from
* @param {Hashtable} objectsLists2 The second lists of objects to test distance to
* @param {number} distance The maximum distance between objects
* @param {boolean} inverted If set to true, only objects from the first lists that have *no* objects from the second lists below the specified distance will be picked.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.distanceTest = function(objectsLists1, objectsLists2, distance, inverted, runtimeScene) {
var object1IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists1);
var object2IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists2);
var isTrue = runtimeScene.getObjectPositionsManager().distanceTest(object1IdsSet, object2IdsSet, distance, inverted);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists1, object1IdsSet);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists2, object2IdsSet);
return isTrue;
};
gdjs.evtTools.object._distanceBetweenObjects = function(obj1, obj2, distance) {
gdjs.evtTools.object._distanceBetweenObjectsCount++;
return obj1.getSqDistanceToObject(obj2) <= distance;
};
gdjs.evtTools.object.distanceTest = function(objectsLists1, objectsLists2, distance, inverted) {
gdjs.evtTools.object.OLDdistanceTest = function(objectsLists1, objectsLists2, distance, inverted) {
return gdjs.evtTools.object.twoListsTest(gdjs.evtTools.object._distanceBetweenObjects,
objectsLists1, objectsLists2, inverted, distance*distance);
};
/**
* @param {Hashtable} objectsLists1 The lists of objects to move
* @param {Hashtable} objectsLists2 The lists of objects to move away from
* @param {boolean} ignoreTouchingEdges If true, polygons are not considered in collision if only their edges are touching.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.separateObjects = function(objectsLists1, objectsLists2, ignoreTouchingEdges, runtimeScene) {
var object1IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists1);
var object2IdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists2);
runtimeScene.getObjectPositionsManager().separateObjects(object1IdsSet, object2IdsSet, ignoreTouchingEdges);
};
/**
* @param {Hashtable} objectsLists1 The lists of objects to move
* @param {Hashtable} objectsLists2 The lists of objects to move away from
* @param {boolean} ignoreTouchingEdges If true, polygons are not considered in collision if only their edges are touching.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.OLDseparateObjects = function(objectsLists1, objectsLists2, ignoreTouchingEdges, runtimeScene) {
var lists = gdjs.staticArray(gdjs.evtTools.object.separateObjects);
objectsLists1.values(lists);
for(var i = 0, len = lists.length;i<len;++i) {
var list = lists[i];
for(var j = 0;j < list.length;++j) {
/** @type gdjs.RuntimeObject */
var object = list[j];
object.OLDseparateFromObjectsList(objectsLists2, ignoreTouchingEdges);
}
}
};
gdjs.evtTools.object._movesToward = function(obj1, obj2, tolerance) {
if ( obj1.hasNoForces() ) return false;
@@ -316,6 +391,7 @@ gdjs.evtTools.object.pickNearestObject = function(objectsLists, x, y, inverted)
for(var j = 0;j < list.length;++j) {
var object = list[j];
var distance = object.getSqDistanceTo(x, y);
// @ts-ignore
if( first || (distance < best ^ inverted)) {
best = distance;
bestObject = object;
@@ -332,16 +408,54 @@ gdjs.evtTools.object.pickNearestObject = function(objectsLists, x, y, inverted)
return true;
};
gdjs.evtTools.object.raycastObject = function(objectsLists, x, y, angle, dist, varX, varY, inverted) {
/**
* @param {Hashtable} objectsLists The lists of objects to intersect the ray with
* @param {number} x X position of the ray starting point
* @param {number} y Y position of the ray starting point
* @param {number} angle Angle of the ray
* @param {number} dist Maximum distance ("radius") before stopping the ray
* @param {gdjs.Variable} varX Variable where to store the ray/object intersection X position
* @param {gdjs.Variable} varY Variable where to store the ray/object intersection Y position
* @param {boolean} inverted true to find the object that is the farthest one intersecting with the ray, false to find the closest.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.raycastObject = function(objectsLists, x, y, angle, dist, varX, varY, inverted, runtimeScene) {
return gdjs.evtTools.object.raycastObjectToPosition(
objectsLists,
x, y,
x + dist*Math.cos(angle*Math.PI/180.0),
y + dist*Math.sin(angle*Math.PI/180.0),
varX, varY, inverted);
varX, varY, inverted, runtimeScene);
};
gdjs.evtTools.object.raycastObjectToPosition = function(objectsLists, x, y, endX, endY, varX, varY, inverted) {
/**
* @param {Hashtable} objectsLists The lists of objects to intersect the ray with
* @param {number} x X position of the ray starting point
* @param {number} y Y position of the ray starting point
* @param {number} endX X position of the ray ending point
* @param {number} endY Y position of the ray ending point
* @param {gdjs.Variable} varX Variable where to store the ray/object intersection X position
* @param {gdjs.Variable} varY Variable where to store the ray/object intersection Y position
* @param {boolean} inverted true to find the object that is the farthest one intersecting with the ray, false to find the closest.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.raycastObjectToPosition = function(objectsLists, x, y, endX, endY, varX, varY, inverted, runtimeScene) {
var objectIdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists);
var intersectionCoordinates = [0, 0];
var foundIntersection = runtimeScene.getObjectPositionsManager().raycastTest(objectIdsSet, x, y, endX, endY, intersectionCoordinates, inverted);
if (!foundIntersection)
return false;
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists, objectIdsSet);
varX.setNumber(intersectionCoordinates[0]);
varY.setNumber(intersectionCoordinates[1]);
return true;
}
gdjs.evtTools.object.OLDraycastObjectToPosition = function(objectsLists, x, y, endX, endY, varX, varY, inverted) {
var matchObject = null;
var testSqDist = inverted ? 0 : (endX - x)*(endX - x) + (endY - y)*(endY - y);
var resultX = 0;
@@ -382,6 +496,29 @@ gdjs.evtTools.object.raycastObjectToPosition = function(objectsLists, x, y, endX
return true;
};
/**
* @param {Hashtable} objectsLists The lists of objects to test
* @param {number} x X position of the point
* @param {number} y Y position of the point
* @param {boolean} inverted true to find objects containing the point, false to find objects not containing it.
* @param {gdjs.RuntimeScene} runtimeScene The scene objects belong to
*/
gdjs.evtTools.object.isCollidingWithPoint = function(objectsLists, x, y, inverted, runtimeScene) {
var objectIdsSet = gdjs.ObjectPositionsManager.objectsListsToObjectIdsSet(objectsLists);
var isTrue = runtimeScene.getObjectPositionsManager().pointsTest(
objectIdsSet, [[x, y]], true /* TODO: Allow to specify if the test should be accurate or not */, inverted);
gdjs.ObjectPositionsManager.keepOnlyObjectsFromObjectIdsSet(objectsLists, objectIdsSet);
return isTrue;
};
gdjs.evtTools.object.OLDisCollidingWithPoint = function(objectsLists, x, y, inverted, runtimeScene) {
return gdjs.evtTools.object.pickObjectsIf(function(obj) {
return obj.isCollidingWithPoint(x, y);
}, objectsLists, inverted);
};
/**
* Do the work of creating a new object
* @private

View File

@@ -29,6 +29,10 @@ gdjs.evtTools.window.setWindowSize = function(runtimeScene, width, height, updat
}
};
gdjs.evtTools.window.centerWindow = function(runtimeScene) {
runtimeScene.getGame().getRenderer().centerWindow();
};
gdjs.evtTools.window.setGameResolutionSize = function(runtimeScene, width, height) {
runtimeScene.getGame().setGameResolutionSize(width, height);
};

View File

@@ -8,8 +8,8 @@
* FontFaceObserverFontManager loads fonts (using fontfaceobserver library)
* from the game resources (see `loadFonts`), and allow to access to
* the font families of the loaded fonts during the game (see `getFontFamily`).
*
* @font-face declarations must be have been added separately in the index.html
*
* "@font-face" declarations must be have been added separately in the index.html
* (or any CSS file).
*
* @class FontFaceObserverFontManager
@@ -30,7 +30,7 @@ gdjs.FontManager = gdjs.FontFaceObserverFontManager; //Register the class to let
* The font resource must have been loaded before. If that's not the case,
* a font family will be returned but without guarantee of it being loaded (to
* keep compatibility with GDevelop 5.0-beta56 and previous).
*
*
* @param {string} resourceName The name of the resource to get.
* @returns {string} The font family to be used for this font resource,
* or "Arial" if `resourceName` is empty.
@@ -40,8 +40,8 @@ gdjs.FontFaceObserverFontManager.prototype.getFontFamily = function(resourceName
return this._loadedFontFamily[resourceName];
}
return resourceName ?
gdjs.FontFaceObserverFontManager._getFontFamilyFromFilename(resourceName) :
return resourceName ?
gdjs.FontFaceObserverFontManager._getFontFamilyFromFilename(resourceName) :
'Arial';
}
@@ -50,9 +50,9 @@ gdjs.FontFaceObserverFontManager.prototype.getFontFamily = function(resourceName
* The font resource must have been loaded before. If that's not the case,
* the resource name will be returned (to
* keep compatibility with GDevelop 5.0-beta56 and previous).
*
*
* Should only be useful for renderers running on a non HTML5/non browser environment.
*
*
* @param {string} resourceName The name of the resource to get.
* @returns {string} The file of the font resource.
*/
@@ -67,7 +67,7 @@ gdjs.FontFaceObserverFontManager.prototype.getFontFile = function(resourceName)
/**
* Return the font family for a given filename.
* Should be kept in sync with the declaration of "@font-face" during exports.
*
*
* @private
* @param {string} filename The filename of the font
* @returns {string} The font family to be used for this font resource.

View File

@@ -15,7 +15,7 @@ window.gdjs = {
* Contains functions used by events (this is a convention only, functions can actually
* by anywhere).
* @namespace
* @memberof gdjs
* @memberOf gdjs
*/
evtTools: {},
callbacksRuntimeSceneLoaded: [],
@@ -91,73 +91,37 @@ gdjs.toDegrees = function(angleInRadians) {
return (angleInRadians * 180) / 3.14159;
};
/**
* Register the runtime objects that can be used in runtimeScene.<br>
* Objects must be part of gdjs and have their property "thisIsARuntimeObjectConstructor"
* defined and set to the name of the type of the object so as to be recognized.
* Register a runtime object (class extending {@link gdjs.RuntimeObject}) that can be used in a scene.
*
* The name of the type of the object must be complete, with the namespace if any. For
* example, if you are providing a Text object in the TextObject extension, the full name
* of the type of the object is "TextObject::Text".
*
* @param {string} objectTypeName The name of the type of the Object.
* @param Ctor The constructor of the Object.
*/
gdjs.registerObjects = function() {
gdjs.objectsTypes.clear();
for (var p in this) {
if (this.hasOwnProperty(p)) {
if (gdjs[p].thisIsARuntimeObjectConstructor != undefined) {
gdjs.objectsTypes.put(gdjs[p].thisIsARuntimeObjectConstructor, gdjs[p]);
}
}
}
gdjs.registerObject = function(objectTypeName, Ctor){
gdjs.objectsTypes.put(objectTypeName, Ctor)
};
/**
* Register the runtime behaviors that can be used bt runtimeObject.
*
* Behavior must be a property on gdjs (or on a inner object, but not on any object nested below)
* and have a property "thisIsARuntimeBehaviorConstructor" defined and set
* to the type of the behavior to be recognized.
* Register a runtime behavior (class extending {@link gdjs.RuntimeBehavior}) that can be used by a
* {@link gdjs.RuntimeObject}.
*
* The type of the behavior must be complete, with the namespace of the extension. For
* example, if you are providing a Draggable behavior in the DraggableBehavior extension,
* the full name of the type of the behavior is "DraggableBehavior::Draggable".
*
* @param {string} behaviorTypeName The name of the type of the behavior.
* @param Ctor The constructor of the Object.
*/
gdjs.registerBehaviors = function() {
gdjs.behaviorsTypes.clear();
for (var gdjsProperty in this) {
if (this.hasOwnProperty(gdjsProperty)) {
// Search in object inside gdjs.
var innerObject = gdjs[gdjsProperty];
if (innerObject.thisIsARuntimeBehaviorConstructor != undefined) {
gdjs.behaviorsTypes.put(
innerObject.thisIsARuntimeBehaviorConstructor,
innerObject
);
} else if (
Object.prototype.toString.call(innerObject) !== '[object Array]' &&
typeof innerObject === 'object' &&
innerObject !== null
) {
// Also search inside objects contained in gdjs.
for (var innerObjectProperty in innerObject) {
if (innerObject.hasOwnProperty(innerObjectProperty)) {
var innerInnerObject = innerObject[innerObjectProperty];
if (
innerInnerObject !== null &&
typeof innerInnerObject === 'function' &&
innerInnerObject.thisIsARuntimeBehaviorConstructor != undefined
) {
gdjs.behaviorsTypes.put(
innerInnerObject.thisIsARuntimeBehaviorConstructor,
innerInnerObject
);
}
}
}
}
}
}
gdjs.registerBehavior = function(behaviorTypeName, Ctor){
gdjs.behaviorsTypes.put(
behaviorTypeName,
Ctor
);
};
/**
@@ -225,7 +189,7 @@ gdjs.registerGlobalCallbacks = function() {
/**
* Get the constructor of an object.
*
* @param name {String} The name of the type of the object.
* @param {string} name The name of the type of the object.
*/
gdjs.getObjectConstructor = function(name) {
if (name !== undefined && gdjs.objectsTypes.containsKey(name))
@@ -238,7 +202,7 @@ gdjs.getObjectConstructor = function(name) {
/**
* Get the constructor of a behavior.
*
* @param name {String} The name of the type of the behavior.
* @param {string} name The name of the type of the behavior.
*/
gdjs.getBehaviorConstructor = function(name) {
if (name !== undefined && gdjs.behaviorsTypes.containsKey(name))

View File

@@ -35,8 +35,6 @@
(function() {
//Initialization
gdjs.registerObjects();
gdjs.registerBehaviors();
gdjs.registerGlobalCallbacks();
var game = new gdjs.RuntimeGame(gdjs.projectData, {}/*GDJS_ADDITIONAL_SPEC*/);

View File

@@ -131,7 +131,7 @@ gdjs.InputManager.prototype.getMouseY = function() {
/**
* Should be called whenever a mouse button is pressed
* @param {number} buttonCode The mouse button code associated to the event.
* @param {number} buttonCode The mouse button code associated to the event.
* See gdjs.InputManager.MOUSE_LEFT_BUTTON, gdjs.InputManager.MOUSE_RIGHT_BUTTON, gdjs.InputManager.MOUSE_MIDDLE_BUTTON
*/
gdjs.InputManager.prototype.onMouseButtonPressed = function(buttonCode) {
@@ -270,7 +270,7 @@ gdjs.InputManager.prototype.popEndedTouch = function() {
*
* If true, any touch will move the mouse position and set mouse buttons
* as pressed/released.
* @param enable {Boolean} true to simulate mouse events, false to disable it.
* @param {boolean=} enable `true` to simulate mouse events, `false` to disable it. `true` if not defined.
*/
gdjs.InputManager.prototype.touchSimulateMouse = function(enable) {
if (enable === undefined) enable = true;

File diff suppressed because it is too large Load Diff

View File

@@ -54,24 +54,67 @@ gdjs.PixiFiltersTools.registerFilterCreator = function(filterName, filterCreator
// Type definitions:
/**
* Function to call to create the PIXI filter used at runtime
* @callback gdjsPixiFiltersToolsFilterCreatorMakePIXIFilter
* @param {gdjs.Layer} layer
* @param {Object} effectData
* @returns {Object}
*/
/**
* The function to be called to update the filter at every frame
* @callback gdjsPixiFiltersToolsUpdate
* @param {Object} filter
* @param {gdjs.Layer} layer
* @returns {Object}
*/
/**
* The function to be called to update a parameter (with a number)
* @callback gdjsPixiFiltersToolsUpdateDoubleParameter
* @param {Object} filter
* @param {string} parameterName
* @param {number} value
* @returns {void}
*/
/**
* The function to be called to update a parameter (with a string)
* @callback gdjsPixiFiltersToolsUpdateStringParameter
* @param {Object} filter
* @param {string} parameterName
* @param {string} value
* @returns {void}
*/
/**
* The function to be called to update a parameter (with a boolean)
* @callback gdjsPixiFiltersToolsUpdateBooleanParameter
* @param {Object} filter
* @param {string} parameterName
* @param {boolean} value
* @returns {void}
*/
/**
* A wrapper allowing to create a PIXI filter and update it using a common interface
* @typedef gdjsPixiFiltersToolsFilterCreator
* @type {object}
* @property {(layer: gdjs.Layer, effectData: any) => any} makePIXIFilter Function to call to create the filter
* @property {(filter: any, layer: gdjs.Layer) => any} update The function to be called to update the filter at every frame
* @property {(filter: any, parameterName: string, value: number) => void} updateDoubleParameter The function to be called to update a parameter (with a number)
* @property {(filter: any, parameterName: string, value: string) => void} updateStringParameter The function to be called to update a parameter (with a string)
* @property {(filter: any, parameterName: string, value: boolean) => void} updateBooleanParameter The function to be called to update a parameter (with a boolean)
* @type {Object}
* @property {gdjsPixiFiltersToolsFilterCreatorMakePIXIFilter} makePIXIFilter Function to call to create the filter
* @property {gdjsPixiFiltersToolsUpdate} update The function to be called to update the filter at every frame
* @property {gdjsPixiFiltersToolsUpdateDoubleParameter} updateDoubleParameter The function to be called to update a parameter (with a number)
* @property {gdjsPixiFiltersToolsUpdateStringParameter} updateStringParameter The function to be called to update a parameter (with a string)
* @property {gdjsPixiFiltersToolsUpdateBooleanParameter} updateBooleanParameter The function to be called to update a parameter (with a boolean)
*/
/**
* The type of a filter used to manipulate a Pixi filter.
* @typedef gdjsPixiFiltersToolsFilter
* @type {object}
* @type {Object}
* @property {any} pixiFilter The PIXI filter
* @property {(filter: any, layer: gdjs.Layer) => any} update The function to be called to update the filter at every frame
* @property {(filter: any, parameterName: string, value: number) => void} updateDoubleParameter The function to be called to update a parameter (with a number)
* @property {(filter: any, parameterName: string, value: string) => void} updateStringParameter The function to be called to update a parameter (with a string)
* @property {(filter: any, parameterName: string, value: boolean) => void} updateBooleanParameter The function to be called to update a parameter (with a boolean)
* @property {gdjsPixiFiltersToolsUpdate} update The function to be called to update the filter at every frame
* @property {gdjsPixiFiltersToolsUpdateDoubleParameter} updateDoubleParameter The function to be called to update a parameter (with a number)
* @property {gdjsPixiFiltersToolsUpdateStringParameter} updateStringParameter The function to be called to update a parameter (with a string)
* @property {gdjsPixiFiltersToolsUpdateBooleanParameter} updateBooleanParameter The function to be called to update a parameter (with a boolean)
*/

View File

@@ -26,7 +26,8 @@ gdjs.ImageManager = gdjs.PixiImageManager; //Register the class to let the engin
/**
* Return the PIXI texture associated to the specified resource name.
* Returns a placeholder texture if not found.
* @param {string} resourceName The name of the resource to get.
* @param {string} resourceName The name of the resource
* @returns {PIXI.Texture} The requested texture, or a placeholder if not found.
*/
gdjs.PixiImageManager.prototype.getPIXITexture = function(resourceName) {
if ( this._loadedTextures.containsKey(resourceName) ) {

View File

@@ -172,6 +172,21 @@ gdjs.RuntimeGamePixiRenderer.prototype.setWindowSize = function(width, height) {
}
};
/**
* Center the window on screen.
*/
gdjs.RuntimeGamePixiRenderer.prototype.centerWindow = function() {
var electron = this.getElectron();
if (electron) { // Use Electron BrowserWindow API
var browserWindow = electron.remote.getCurrentWindow();
if (browserWindow) {
browserWindow.center();
}
} else {
// Not supported
}
}
/**
* De/activate fullscreen for the game.
*/

View File

@@ -35,13 +35,16 @@ gdjs.RuntimeScenePixiRenderer.prototype._renderProfileText = function() {
this._profilerText = new PIXI.Text(" ", {
align: "left",
stroke: "#FFF",
strokeThickness: 1
strokeThickness: 1,
fontSize: 12,
});
this._pixiContainer.addChild(this._profilerText);
}
var average = this._runtimeScene.getProfiler().getFramesAverageMeasures();
var outputs = [];
gdjs.Profiler.getProfilerCounterTexts(average.counters, outputs);
gdjs.Profiler.getProfilerTimingTexts(average.timings, outputs);
gdjs.Profiler.getProfilerSectionTexts("All", average, outputs);
this._profilerText.text = outputs.join("\n");

View File

@@ -1,3 +1,4 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
@@ -33,14 +34,28 @@ gdjs.Polygon = function()
this.center = [0,0];
};
gdjs.Polygon.prototype.move = function(x,y) {
/**
* Move the polygon by the specified offset.
* @param {number} x Offset on X axis
* @param {number} y Offset on Y axis
* @returns {gdjs.Polygon} The same, updated, polygon.
*/
gdjs.Polygon.prototype.move = function(x, y) {
for(var i = 0, len = this.vertices.length;i<len;++i) {
this.vertices[i][0] += x;
this.vertices[i][1] += y;
}
}
return this;
};
/**
* Rotate the polygon by the specified angle (in radians), clockwise.
*
* @param {number} angle The angle, in radians.
* @returns {gdjs.Polygon} The same, updated, polygon.
*/
gdjs.Polygon.prototype.rotate = function(angle) {
var t, cosa = Math.cos(-angle),
sina = Math.sin(-angle); //We want a clockwise rotation
@@ -49,7 +64,9 @@ gdjs.Polygon.prototype.rotate = function(angle) {
t = this.vertices[i][0];
this.vertices[i][0] = t*cosa + this.vertices[i][1]*sina;
this.vertices[i][1] = -t*sina + this.vertices[i][1]*cosa;
}
}
return this;
};
gdjs.Polygon.prototype.computeEdges = function() {
@@ -125,7 +142,7 @@ gdjs.Polygon.createRectangle = function(width, height) {
* Based on <a href="http://www.codeproject.com/Articles/15573/2D-Polygon-Collision-Detection">this</a>
* and <a href="http://stackoverflow.com/questions/5742329/problem-with-collision-response-sat">this</a> article.
*
* @return {boolean} true if polygons are overlapping
* @return {{collision: boolean, move_axis: Array<number>}} returnValue.collision is equal to true if polygons are overlapping
* @param {gdjs.Polygon} p1 The first polygon
* @param {gdjs.Polygon} p2 The second polygon
* @param {boolean | undefined} ignoreTouchingEdges If true, then edges that are touching each other, without the polygons actually overlapping, won't be considered in collision.
@@ -138,17 +155,18 @@ gdjs.Polygon.collisionTest = function(p1, p2, ignoreTouchingEdges) {
var edge = gdjs.Polygon.collisionTest._statics.edge;
var move_axis = gdjs.Polygon.collisionTest._statics.move_axis;
var result = gdjs.Polygon.collisionTest._statics.result;
var minDist = Number.MAX_VALUE;
edge[0] = 0;
edge[1] = 0;
edge[0] = 0;
edge[1] = 0;
var result = gdjs.Polygon.collisionTest._statics.result;
var minDist = Number.MAX_VALUE;
result.collision = false;
result.move_axis[0] = 0;
result.move_axis[1] = 0;
edge[0] = 0;
edge[1] = 0;
edge[0] = 0;
edge[1] = 0;
result.collision = false;
result.move_axis[0] = 0;
result.move_axis[1] = 0;
//Iterate over all the edges composing the polygons
for (var i = 0, len1 = p1.vertices.length, len2 = p2.vertices.length; i < len1+len2; i++) {
@@ -219,9 +237,23 @@ gdjs.Polygon.collisionTest._statics = {
};
/**
* Do a raycast test.<br>
* Please note that the polygon must be <b>convex</b>!
*
* Represents the result of a raycast test (see `gdjs.Polygon.raycastTest`)
*
* @typedef {Object} PolygonRaycastTestResult
* @property {boolean} collision True if there is a collision between the ray and the polygon
* @property {number} closeX X position of the ray/polygon intersection point closest to the ray start point.
* @property {number} closeY Y position of the ray/polygon intersection point closest to the ray start point.
* @property {number} closeSqDist The squared distance between the ray start point and the closest intersection point.
* @property {number} farX X position of the ray/polygon intersection point farthest to the ray start point.
* @property {number} farY Y position of the ray/polygon intersection point farthest to the ray start point.
* @property {number} farSqDist The squared distance between the ray start point and the farthest intersection point.
*/
/**
* Do an intersection test between a polygon and a ray.
*
* Please note that the polygon must be **convex**!
*
* For some theory, check <a href="https://www.codeproject.com/Tips/862988/Find-the-Intersection-Point-of-Two-Line-Segments">Find the Intersection Point of Two Line Segments</a>.
*
* @param {gdjs.Polygon} poly The polygon to test
@@ -229,10 +261,11 @@ gdjs.Polygon.collisionTest._statics = {
* @param {number} startY The raycast start point Y
* @param {number} endX The raycast end point X
* @param {number} endY The raycast end point Y
* @return A raycast result with the contact points and distances
* @return {PolygonRaycastTestResult} A raycast result with the contact points and distances
*/
gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
{
/** @type PolygonRaycastTestResult */
var result = gdjs.Polygon.raycastTest._statics.result;
result.collision = false;
@@ -312,7 +345,7 @@ gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
{
var x = p[0] + t*r[0];
var y = p[1] + t*r[1];
var sqDist = (x-startX)*(x-startX) + (y-startY)*(y-startY);
if ( sqDist < minSqDist )
{
@@ -339,6 +372,21 @@ gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
return result;
};
/**
* Copy a PolygonRaycastTestResult into another.
* @param {PolygonRaycastTestResult} source The result to copy
* @param {PolygonRaycastTestResult} destination Where to save the results
*/
gdjs.Polygon.raycastTest.copyResultTo = function(source, destination) {
destination.collision = source.collision;
destination.closeX = source.closeX;
destination.closeY = source.closeY;
destination.closeSqDist = source.closeSqDist;
destination.farX = source.farX;
destination.farY = source.farY;
destination.farSqDist = source.farSqDist;
}
gdjs.Polygon.raycastTest._statics = {
p: [0,0],
q: [0,0],

View File

@@ -1,3 +1,5 @@
// @ts-check
/**
* A basic profiling tool that can be used to measure time spent in sections of the engine.
* @class Profiler
@@ -17,6 +19,8 @@ gdjs.Profiler = function() {
parent: null,
time: 0,
subsections: {},
counters: {},
timings: {},
});
}
@@ -32,6 +36,8 @@ gdjs.Profiler.prototype.beginFrame = function() {
time: 0,
lastStartTime: this._getTimeNow(),
subsections: {},
counters: {},
timings: {},
};
this._currentSection = this._currentFrameMeasure;
};
@@ -60,6 +66,29 @@ gdjs.Profiler.prototype.end = function(sectionName) {
this._currentSection = this._currentSection.parent;
};
/**
* Increment a counter for the current frame.
* @param {string} counterName The name of the counter
*/
gdjs.Profiler.prototype.incrementCallCounter = function(counterName) {
if (!this._currentFrameMeasure) return;
this._currentFrameMeasure.counters[counterName] =
(this._currentFrameMeasure.counters[counterName] || 0) + 1;
};
/**
* Increment some timing for the current frame.
* @param {string} timingName The name of the timing
* @param {number} timeInMs The time in milliseconds
*/
gdjs.Profiler.prototype.addTime = function(timingName, timeInMs) {
if (!this._currentFrameMeasure) return;
this._currentFrameMeasure.timings[timingName] =
(this._currentFrameMeasure.timings[timingName] || 0) + timeInMs;
};
gdjs.Profiler.prototype.endFrame = function() {
if (this._currentSection.parent !== null) {
throw new Error(
@@ -116,6 +145,8 @@ gdjs.Profiler.prototype.getFramesAverageMeasures = function() {
parent: null,
time: 0,
subsections: {},
counters: {},
timings: {},
};
for (var i = 0; i < this._framesCount; ++i) {
@@ -125,6 +156,24 @@ gdjs.Profiler.prototype.getFramesAverageMeasures = function() {
this._framesCount,
i
);
// Compute the sum for the counters and timings
for(var counterName in this._framesMeasures[i].counters) {
framesAverageMeasures.counters[counterName] = (framesAverageMeasures.counters[counterName] || 0) +
this._framesMeasures[i].counters[counterName];
}
for(var timingName in this._framesMeasures[i].timings) {
framesAverageMeasures.timings[timingName] = (framesAverageMeasures.timings[timingName] || 0) +
this._framesMeasures[i].timings[timingName];
}
}
// Compute average for counters and timings
for(var counterName in framesAverageMeasures.counters) {
framesAverageMeasures.counters[counterName] /= this._framesCount;
}
for(var timingName in framesAverageMeasures.timings) {
framesAverageMeasures.timings[timingName] /= this._framesCount;
}
return framesAverageMeasures;
@@ -144,8 +193,8 @@ gdjs.Profiler.prototype.getStats = function() {
* Useful for ingame profiling.
*
* @param {string} sectionName The name of the section
* @param {s} profilerSection The section measures
* @param {*} outputs The array where to push the results
* @param {*} profilerSection The section measures
* @param {string[]} outputs The array where to push the results
*/
gdjs.Profiler.getProfilerSectionTexts = function(
sectionName,
@@ -171,3 +220,35 @@ gdjs.Profiler.getProfilerSectionTexts = function(
}
outputs.push.apply(outputs, subsectionsOutputs);
};
/**
* Convert counters into texts.
* Useful for ingame profiling.
*
* @param {Object.<string, number>} counters The counters that were measured
* @param {string[]} outputs The array where to push the results
*/
gdjs.Profiler.getProfilerCounterTexts = function(
counters,
outputs
) {
for (var counterName in counters) {
outputs.push(counterName + ": " + counters[counterName]);
}
};
/**
* Convert timings into texts.
* Useful for ingame profiling.
*
* @param {Object.<string, number>} timings The timings that were measured
* @param {string[]} outputs The array where to push the results
*/
gdjs.Profiler.getProfilerTimingTexts = function(
timings,
outputs
) {
for (var timingName in timings) {
outputs.push(timingName + ": " + timings[timingName].toFixed(2) + "ms");
}
};

View File

@@ -4,13 +4,19 @@
* This project is released under the MIT License.
*/
/**
* @typedef BehaviorData Properties to set up a behavior.
* @property {string} name The name of the behavior (for getting from an object (object.getBehavior) for example)
* @property {string} type The behavior type. Used by GDJS to find the proper behavior to construct.
*/
/**
* RuntimeBehavior represents a behavior being used by a RuntimeObject.
*
* @class RuntimeBehavior
* @memberof gdjs
* @param {gdjs.RuntimeScene} runtimeScene The scene owning the object of the behavior
* @param {Object} behaviorData The object used to setup the behavior
* @param {BehaviorData} behaviorData The properties used to setup the behavior
* @param {gdjs.RuntimeObject} owner The object owning the behavior
*/
gdjs.RuntimeBehavior = function(runtimeScene, behaviorData, owner)
@@ -138,7 +144,6 @@ gdjs.RuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
*/
gdjs.RuntimeBehavior.prototype.onDestroy = function() {
}
};
//Notify gdjs this.the runtimeBehavior exists.
gdjs.RuntimeBehavior.thisIsARuntimeBehaviorConstructor = "";
gdjs.registerBehavior("", gdjs.RuntimeBehavior);

View File

@@ -1,9 +1,19 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
* This project is released under the MIT License.
*/
/**
* @typedef {Object} ObjectData Object containing initial properties for all objects extending gdjs.RuntimeObject
* @property {string} name The name of the object. During the game, objects can be queried by their name (see {@link gdjs.RuntimeScene.prototype.getObjects} for example).
* @property {string} type The object type.
* @property {Array<VariableData>} variables The list of default variables.
* @property {Array<BehaviorData>} behaviors The list of default behaviors.
*/
/**
* RuntimeObject represents an object being used on a RuntimeScene.
*
@@ -14,16 +24,16 @@
* However, you should not be calling the constructor on an already existing object
* which is not a RuntimeObject.
*
* A `gdjs.RuntimeObject` should not be instanciated directly, always a child class
* A `gdjs.RuntimeObject` should not be instantiated directly, always a child class
* (because gdjs.RuntimeObject don't call onCreated at the end of its constructor).
*
* @memberof gdjs
* @class RuntimeObject
* @param {gdjs.RuntimeScene} runtimeScene The RuntimeScene owning the object.
* @param objectData The data defining the object
* @memberOf gdjs
* @name RuntimeObject
* @class
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to.
* @param {ObjectData} objectData The initial properties of the object.
*/
gdjs.RuntimeObject = function(runtimeScene, objectData)
{
gdjs.RuntimeObject = function(runtimeScene, objectData) {
this.name = objectData.name || "";
this._nameId = gdjs.RuntimeObject.getNameIdentifier(this.name);
this.type = objectData.type || "";
@@ -35,7 +45,7 @@ gdjs.RuntimeObject = function(runtimeScene, objectData)
this.layer = "";
this.livingOnScene = true;
this.id = runtimeScene.createNewUniqueId();
this._runtimeScene = runtimeScene; //This could/should be avoided.
this._runtimeScene = runtimeScene;
//Hit boxes:
if ( this._defaultHitBoxes === undefined ) {
@@ -44,6 +54,8 @@ gdjs.RuntimeObject = function(runtimeScene, objectData)
}
this.hitBoxes = this._defaultHitBoxes;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsCreated(this);
if ( this.aabb === undefined )
this.aabb = { min:[0,0], max:[0,0] };
else {
@@ -64,7 +76,7 @@ gdjs.RuntimeObject = function(runtimeScene, objectData)
this.clearForces();
//A force returned by getAverageForce method:
if (this._averageForce === undefined) this._averageForce = new gdjs.Force(0,0,false);
if (this._averageForce === undefined) this._averageForce = new gdjs.Force(0,0,0);
//Behaviors:
if (this._behaviors === undefined)
@@ -99,7 +111,26 @@ gdjs.RuntimeObject = function(runtimeScene, objectData)
this._timers.clear();
};
gdjs.RuntimeObject.forcesGarbage = []; //Global container for unused forces, avoiding recreating forces each tick.
/**
* Table containing the id corresponding to an object name. Do not use directly or modify.
* @static
* @private
*/
gdjs.RuntimeObject._identifiers = {};
/**
* The next available unique identifier for an object. Do not use directly or modify.
* @static
* @private
*/
gdjs.RuntimeObject._largestId = 0;
/**
* Global container for unused forces, avoiding recreating forces each tick.
* @static
* @private
*/
gdjs.RuntimeObject.forcesGarbage = [];
//Common members functions related to the object and its runtimeScene :
@@ -177,6 +208,8 @@ gdjs.RuntimeObject.prototype.onDestroyFromScene = function(runtimeScene) {
for(var j = 0, lenj = this._behaviors.length;j<lenj;++j) {
this._behaviors[j].onDestroy();
}
runtimeScene.getObjectPositionsManager().markObjectAsRemoved(this);
};
//Rendering:
@@ -241,6 +274,7 @@ gdjs.RuntimeObject.prototype.setX = function(x) {
this.x = x;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
};
/**
@@ -262,6 +296,7 @@ gdjs.RuntimeObject.prototype.setY = function(y) {
this.y = y;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
};
/**
@@ -316,11 +351,12 @@ gdjs.RuntimeObject.prototype.rotateTowardAngle = function(angle, speed, runtimeS
var newAngle = this.getAngle() + (diffWasPositive ? -1.0 : 1.0)
* speed * this.getElapsedTime(runtimeScene) / 1000;
// @ts-ignore
if (gdjs.evtTools.common.angleDifference(newAngle, angle) > 0 ^ diffWasPositive)
newAngle = angle;
this.setAngle(newAngle);
if (this.getAngle() != newAngle) //Objects like sprite in 8 directions does not handle small increments...
if (this.getAngle() !== newAngle) //Objects like sprite in 8 directions does not handle small increments...
this.setAngle(angle); //...so force them to be in the path angle anyway.
};
@@ -344,6 +380,7 @@ gdjs.RuntimeObject.prototype.setAngle = function(angle) {
this.angle = angle;
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
};
/**
@@ -543,7 +580,7 @@ gdjs.RuntimeObject.prototype.hide = function(enable) {
/**
* Return true if the object is not hidden.
*
* @note This is unrelated to the actual visibility of the objec on the screen.
* Note: This is unrelated to the actual visibility of the objec on the screen.
* For this, see `getVisibilityAABB` to get the bounding boxes of the object as displayed
* on the scene.
*
@@ -664,11 +701,11 @@ gdjs.RuntimeObject.prototype.addForceTowardPosition = function(x,y, len, multipl
* @param {number} len The force length, in pixels.
* @param {number} multiplier Set the force multiplier
*/
gdjs.RuntimeObject.prototype.addForceTowardObject = function(obj, len, multiplier) {
if ( obj == null ) return;
gdjs.RuntimeObject.prototype.addForceTowardObject = function(object, len, multiplier) {
if ( object == null ) return;
this.addForceTowardPosition(obj.getDrawableX() + obj.getCenterX(),
obj.getDrawableY() + obj.getCenterY(),
this.addForceTowardPosition(object.getDrawableX() + object.getCenterX(),
object.getDrawableY() + object.getCenterY(),
len, multiplier);
};
@@ -700,7 +737,7 @@ gdjs.RuntimeObject.prototype.updateForces = function(elapsedTime) {
++i;
} else if (multiplier === 0 || force.getLength() <= 0.001) { // Instant or force disappearing
gdjs.RuntimeObject.forcesGarbage.push(force);
this._forces.remove(i);
this._forces.splice(i, 1);
} else { // Deprecated way of updating forces progressively.
force.setLength(force.getLength() - force.getLength() * ( 1 - multiplier ) * elapsedTime);
++i;
@@ -809,9 +846,11 @@ gdjs.RuntimeObject.prototype.updateHitBoxes = function() {
};
/**
* An axis aligned bounding box, usually used for an object.
*
* @typedef {Object} AABB
* @property {Array} min The [x,y] coordinates of the top left point
* @property {Array} max The [x,y] coordinates of the bottom right point
* @property {number[]} min The [x,y] coordinates of the top left point
* @property {number[]} max The [x,y] coordinates of the bottom right point
*/
/**
@@ -847,7 +886,7 @@ gdjs.RuntimeObject.prototype.getAABB = function() {
* @return {?AABB} The bounding box (example: `{min: [10,5], max:[20,10]}`) or `null`.
*/
gdjs.RuntimeObject.prototype.getVisibilityAABB = function() {
return this.getAABB();
return this.getAABB(); // TODO: this should return getDrawableX/Y + getWidth/getHeight
};
/**
@@ -1104,7 +1143,7 @@ gdjs.RuntimeObject.prototype.separateFromObjects = function(objects, ignoreTouch
* @param {boolean | undefined} ignoreTouchingEdges If true, then edges that are touching each other, without the hitbox polygons actually overlapping, won't be considered in collision.
* @return true if the object was moved
*/
gdjs.RuntimeObject.prototype.separateFromObjectsList = function(objectsLists, ignoreTouchingEdges) {
gdjs.RuntimeObject.prototype.OLDseparateFromObjectsList = function(objectsLists, ignoreTouchingEdges) {
var moved = false;
var xMove = 0; var yMove = 0;
var hitBoxes = this.getHitBoxes();
@@ -1260,23 +1299,23 @@ gdjs.RuntimeObject.prototype.separateObjectsWithForces = function(objectsLists,
if ( this.getDrawableX()+this.getCenterX() < objects[i].getDrawableX()+objects[i].getCenterX() )
{
var av = this.hasNoForces() ? 0 : this.getAverageForce().getX();
this.addForce( -av - 10, 0, false );
this.addForce( -av - 10, 0, 0 );
}
else
{
var av = this.hasNoForces() ? 0 : this.getAverageForce().getX();
this.addForce( -av + 10, 0, false );
this.addForce( -av + 10, 0, 0 );
}
if ( this.getDrawableY()+this.getCenterY() < objects[i].getDrawableY()+objects[i].getCenterY() )
{
var av = this.hasNoForces() ? 0 : this.getAverageForce().getY();
this.addForce( 0, -av - 10, false );
this.addForce( 0, -av - 10, 0 );
}
else
{
var av = this.hasNoForces() ? 0 : this.getAverageForce().getY();
this.addForce( 0, -av + 10, false );
this.addForce( 0, -av + 10, 0 );
}
}
}
@@ -1431,30 +1470,25 @@ gdjs.RuntimeObject.prototype.isCollidingWithPoint = function(pointX, pointY) {
}
return false;
}
};
/**
* Get the identifier associated to an object name :<br>
* Get the identifier associated to an object name.
* Some features may want to compare objects name a large number of time. In this case,
* it may be more efficient to compare objects name identifier.
* it may be more efficient to compare objects name identifiers.
*
* @static
*/
gdjs.RuntimeObject.getNameIdentifier = function(name) {
gdjs.RuntimeObject.getNameIdentifier.identifiers =
gdjs.RuntimeObject.getNameIdentifier.identifiers
|| new Hashtable();
var identifier = gdjs.RuntimeObject._identifiers[name];
if (identifier !== undefined) return identifier;
if ( gdjs.RuntimeObject.getNameIdentifier.identifiers.containsKey(name) )
return gdjs.RuntimeObject.getNameIdentifier.identifiers.get(name);
gdjs.RuntimeObject._largestId++;
var newIdentifier = gdjs.RuntimeObject._largestId;
gdjs.RuntimeObject.getNameIdentifier.newId =
(gdjs.RuntimeObject.getNameIdentifier.newId || 0) + 1;
var newIdentifier = gdjs.RuntimeObject.getNameIdentifier.newId;
gdjs.RuntimeObject.getNameIdentifier.identifiers.put(name, newIdentifier);
gdjs.RuntimeObject._identifiers[name] = newIdentifier;
return newIdentifier;
};
//Notify gdjs the RuntimeObject exists.
gdjs.RuntimeObject.thisIsARuntimeObjectConstructor = "";
gdjs.registerObject("", gdjs.RuntimeObject);

View File

@@ -27,6 +27,7 @@ gdjs.RuntimeScene = function(runtimeGame)
this._lastId = 0;
this._name = "";
this._timeManager = new gdjs.TimeManager(Date.now());
this._objectPositionsManager = new gdjs.ObjectPositionsManager();
this._gameStopRequested = false;
this._requestedScene = "";
this._isLoaded = false; // True if loadFromScene was called and the scene is being played.
@@ -39,9 +40,14 @@ gdjs.RuntimeScene = function(runtimeGame)
this._instancesRemoved = []; //The instances removed from the scene and waiting to be sent to the cache.
/** @type gdjs.Profiler */
this._profiler = null; // Set to `new gdjs.Profiler()` to have profiling done on the scene.
this._profiler = null;
this._onProfilerStopped = null; // The callback function to call when the profiler is stopped.
// Uncomment to manually launch profiling on the scene.
// Also uncomment the profiler display in `gdjs.RuntimeScenePixiRenderer` if needed.
// this.startProfiler(null);
// window.gdjsProfiler = this._profiler;
this.onGameResolutionResized();
};
@@ -378,7 +384,7 @@ gdjs.RuntimeScene.prototype._updateObjectsVisibility = function() {
if (object.isHidden()) {
rendererObject.visible = false;
} else {
var aabb = object.getVisibilityAABB();
var aabb = object.getVisibilityAABB(); // TODO: Use the ObjectPositionsManager
if (aabb && // If no AABB is returned, the object should always be visible
(aabb.min[0] > cameraCoords[2] || aabb.min[1] > cameraCoords[3] ||
aabb.max[0] < cameraCoords[0] || aabb.max[1] < cameraCoords[1])) {
@@ -465,6 +471,11 @@ gdjs.RuntimeScene.prototype._updateObjectsPreEvents = function() {
}
this._cacheOrClearRemovedInstances(); //Some behaviors may have request objects to be deleted.
// Update the object positions manager to ensure that, in case events or behaviors
// are not triggering themselves an update, we at least call update once per frame. Otherwise,
// we risk a **memory leak** by not clearing the object positions waiting to be deleted.
this._objectPositionsManager.update();
};
/**
@@ -681,6 +692,14 @@ gdjs.RuntimeScene.prototype.getAllLayerNames = function(result) {
this._layers.keys(result);
};
/**
* Get the ObjectPositionsManager of the scene.
* @return {gdjs.ObjectPositionsManager} The gdjs.ObjectPositionsManager of the scene.
*/
gdjs.RuntimeScene.prototype.getObjectPositionsManager = function() {
return this._objectPositionsManager;
};
/**
* Get the TimeManager of the scene.
* @return {gdjs.TimeManager} The gdjs.TimeManager of the scene.
@@ -742,13 +761,14 @@ gdjs.RuntimeScene.prototype.getProfiler = function() {
/**
* Start a new profiler to measures the time passed in sections of the engine
* in the scene.
* @param {Function} onProfilerStopped Function to be called when the profiler is stopped. Will be passed the profiler as argument.
* @param {?Function} onProfilerStopped Function to be called when the profiler is stopped. Will be passed the profiler as argument.
*/
gdjs.RuntimeScene.prototype.startProfiler = function(onProfilerStopped) {
if (this._profiler) return;
this._profiler = new gdjs.Profiler();
this._onProfilerStopped = onProfilerStopped;
this._objectPositionsManager.setProfiler(this._profiler);
}
/**
@@ -761,6 +781,7 @@ gdjs.RuntimeScene.prototype.stopProfiler = function() {
var onProfilerStopped = this._onProfilerStopped;
this._profiler = null;
this._onProfilerStopped = null;
this._objectPositionsManager.setProfiler(null);
if (onProfilerStopped) {
onProfilerStopped(oldProfiler);

View File

@@ -4,6 +4,58 @@
* This project is released under the MIT License.
*/
/**
* @typedef {Object} Point Represents a point in a frame
* @property {number} x X position of the point
* @property {number} y Y position of the point
*/
/**
* @typedef {Object} CustomPointData Represents a custom point in a frame
* @property {string} name Name of the point
* @property {number} x X position of the point
* @property {number} y Y position of the point
*/
/**
* @typedef {Object} CenterPointData Represents the center point in a frame
* @property {boolean} automatic Is the center automatically computed?
* @property {number} x X position of the point
* @property {number} y Y position of the point
*/
/**
* @typedef {Object} FrameData Represents a {@link gdjs.SpriteAnimationFrame}
* @property {string} [image] The resource name of the image used in this frame
* @property {Array<customPointData>} [points] The points of the frame
* @property {point} originPoint The origin point
* @property {centerPointData} centerPoint The center of the frame
* @property {boolean} hasCustomCollisionMask Is The collision mask custom?
* @property {Array<Array<point>>} [customCollisionMask] The collision mask if it is custom
*/
/**
* @typedef {Object} DirectionData Represents the data of a {@link gdjs.SpriteAnimationDirection}
* @property {number} timeBetweenFrames Time between each frame, in seconds
* @property {boolean} looping Is the animation looping?
* @property {Array<gdjs.SpriteAnimationFrame>} sprites The list of frames
*/
/**
* @typedef {Object} AnimationData Represents the data of a {@link gdjs.SpriteAnimation}
* @property {string} [name] The name of the animation
* @property {boolean} useMultipleDirections Does the animation use multiple {@link gdjs.SpriteAnimationDirection}?
* @property {Array<DirectionData>} directions The list of {@link DirectionData} representing {@link gdjs.SpriteAnimationDirection} instances
*/
/**
* @typedef {Object} SpriteObjectDataType
* @property {boolean} updateIfNotVisible Update the object even if he is not visible?
* @property {Array<AnimationData>} animations The list of {@link AnimationData} representing {@link gdjs.SpriteAnimation} instances
*
* @typedef {ObjectData & SpriteObjectDataType} SpriteObjectData
*/
/**
* A frame used by a SpriteAnimation in a {@link gdjs.SpriteRuntimeObject}.
*
@@ -13,31 +65,50 @@
* @memberof gdjs
* @class SpriteAnimationFrame
* @param {gdjs.ImageManager} imageManager The game image manager
* @param {Object} frameData the data to be used to create the frame.
* @param {FrameData} frameData The frame data used to initialize the frame
*/
gdjs.SpriteAnimationFrame = function(imageManager, frameData)
{
/** @type {string} */
this.image = frameData ? frameData.image : ""; //TODO: Rename in imageName, and do not store it in the object?
/** @type {PIXI.Texture} */
this.texture = gdjs.SpriteRuntimeObjectRenderer.getAnimationFrame(imageManager, this.image);
if ( this.center === undefined ) this.center = { x:0, y:0 };
if ( this.origin === undefined ) this.origin = { x:0, y:0 };
if ( this.center === undefined ) {
/** @type {Point} */
this.center = { x:0, y:0 };
};
if ( this.origin === undefined ) {
/** @type {Point} */
this.origin = { x:0, y:0 }
};
/** @type {boolean} */
this.hasCustomHitBoxes = false;
if ( this.customHitBoxes === undefined ) this.customHitBoxes = [];
if ( this.points === undefined ) this.points = new Hashtable();
else this.points.clear();
if ( this.customHitBoxes === undefined ) {
/** @type {Array<gdjs.Polygon>} */
this.customHitBoxes = []
};
if ( this.points === undefined ){
/** @type {Hashtable} */
this.points = new Hashtable();
} else this.points.clear();
//Initialize points:
for(var i = 0, len = frameData.points.length;i<len;++i) {
/** @type {CustomPointData} */
var ptData = frameData.points[i];
/** @type {Point} */
var point = {x:parseFloat(ptData.x), y:parseFloat(ptData.y)};
this.points.put(ptData.name, point);
}
/** @type {Point} */
var origin = frameData.originPoint;
this.origin.x = parseFloat(origin.x);
this.origin.y = parseFloat(origin.y);
/** @type {CenterPointData} */
var center = frameData.centerPoint;
if ( center.automatic !== true ) {
this.center.x = parseFloat(center.x);
@@ -52,12 +123,14 @@ gdjs.SpriteAnimationFrame = function(imageManager, frameData)
if ( frameData.hasCustomCollisionMask ) {
this.hasCustomHitBoxes = true;
for(var i = 0, len = frameData.customCollisionMask.length;i<len;++i) {
/** @type {Array<Point>} */
var polygonData = frameData.customCollisionMask[i];
//Add a polygon, if necessary (Avoid recreating a polygon if it already exists).
if ( i >= this.customHitBoxes.length ) this.customHitBoxes.push(new gdjs.Polygon());
for(var j = 0, len2 = polygonData.length;j<len2;++j) {
/** @type {Point} */
var pointData = polygonData[j];
//Add a point, if necessary (Avoid recreating a point if it already exists).
@@ -81,8 +154,8 @@ gdjs.SpriteAnimationFrame = function(imageManager, frameData)
/**
* Get a point of the frame.<br>
* If the point does not exist, the origin is returned.
*
* @return The requested point.
* @param {string} name The point's name
* @return {Point} The requested point. If it doesn't exists returns the origin point.
*/
gdjs.SpriteAnimationFrame.prototype.getPoint = function(name) {
if ( name == "Centre" || name == "Center") return this.center;
@@ -97,16 +170,22 @@ gdjs.SpriteAnimationFrame.prototype.getPoint = function(name) {
* @class SpriteAnimationDirection
* @memberof gdjs
* @param {gdjs.ImageManager} imageManager The game image manager
* @param {Object} directionData the data to be used to create the direction.
* @param {DirectionData} directionData The direction data used to initialize the direction
*/
gdjs.SpriteAnimationDirection = function(imageManager, directionData)
{
/** @type {number} */
this.timeBetweenFrames = directionData ? parseFloat(directionData.timeBetweenFrames) :
1.0;
/** @type {boolean} */
this.loop = !!directionData.looping;
if ( this.frames === undefined ) this.frames = [];
if ( this.frames === undefined ) {
/** @type {Array<SpriteAnimationFrame>} */
this.frames = [];
}
for(var i = 0, len = directionData.sprites.length;i<len;++i) {
/** @type {frameData} */
var frameData = directionData.sprites[i];
if ( i < this.frames.length )
@@ -123,15 +202,19 @@ gdjs.SpriteAnimationDirection = function(imageManager, directionData)
* @class SpriteAnimation
* @memberof gdjs
* @param {gdjs.ImageManager} imageManager The game image manager
* @param {Object} directionData the data to be used to create the animation.
* @param {AnimationData} animData The animation data used to initialize the animation
*/
gdjs.SpriteAnimation = function(imageManager, animData)
{
/** @type {boolean} */
this.hasMultipleDirections = !!animData.useMultipleDirections;
/** @type {string} */
this.name = animData.name || '';
/** @type {Array<gdjs.SpriteAnimationDirection>} */
if ( this.directions === undefined ) this.directions = [];
for(var i = 0, len = animData.directions.length;i<len;++i) {
/** @type {DirectionData} */
var directionData = animData.directions[i];
if ( i < this.directions.length )
@@ -149,30 +232,47 @@ gdjs.SpriteAnimation = function(imageManager, animData)
* @memberof gdjs
* @extends gdjs.RuntimeObject
* @param {gdjs.RuntimeScene} runtimeScene The scene the object belongs to
* @param {Object} objectData the data to be used to create the object.
* @param {SpriteObjectData} spriteObjectData The object data used to initialize the object
*/
gdjs.SpriteRuntimeObject = function(runtimeScene, objectData)
{
gdjs.RuntimeObject.call( this, runtimeScene, objectData );
gdjs.SpriteRuntimeObject = function(runtimeScene, spriteObjectData) {
gdjs.RuntimeObject.call(this, runtimeScene, spriteObjectData);
/** @type {number} */
this._currentAnimation = 0;
/** @type {number} */
this._currentDirection = 0;
/** @type {number} */
this._currentFrame = 0;
/** @type {number} */
this._frameElapsedTime = 0;
/** @type {number} */
this._animationSpeedScale = 1;
this._animationPaused = false;
/** @type {boolean} */
this._animationPaused = false;
/** @type {number} */
this._scaleX = 1;
/** @type {number} */
this._scaleY = 1;
/** @type {number} */
this._blendMode = 0;
/** @type {boolean} */
this._flippedX = false;
/** @type {boolean} */
this._flippedY = false;
/** @type {number} */
this.opacity = 255;
this._updateIfNotVisible = !!objectData.updateIfNotVisible;
/** @type {boolean} */
this._updateIfNotVisible = !!spriteObjectData.updateIfNotVisible;
//Animations:
if ( this._animations === undefined ) this._animations = [];
for(var i = 0, len = objectData.animations.length;i<len;++i) {
var animData = objectData.animations[i];
if ( this._animations === undefined ) {
/** @type {Array<gdjs.SpriteAnimation>} */
this._animations = [];
}
for(var i = 0, len = spriteObjectData.animations.length;i<len;++i) {
/** @type {AnimationData} */
var animData = spriteObjectData.animations[i];
if ( i < this._animations.length )
gdjs.SpriteAnimation.call(this._animations[i], runtimeScene.getGame().getImageManager(), animData);
@@ -187,13 +287,14 @@ gdjs.SpriteRuntimeObject = function(runtimeScene, objectData)
* call `this._updateAnimationFrame()`.
* Can be null, so ensure that this case is handled properly.
*
* @type gdjs.SpriteAnimationFrame
* @type {gdjs.SpriteAnimationFrame}
*/
this._animationFrame = null;
if (this._renderer)
gdjs.SpriteRuntimeObjectRenderer.call(this._renderer, this, runtimeScene);
else
/** @type {gdjs.SpriteRuntimeObjectRenderer} */
this._renderer = new gdjs.SpriteRuntimeObjectRenderer(this, runtimeScene);
this._updateAnimationFrame();
@@ -203,7 +304,7 @@ gdjs.SpriteRuntimeObject = function(runtimeScene, objectData)
};
gdjs.SpriteRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
gdjs.SpriteRuntimeObject.thisIsARuntimeObjectConstructor = "Sprite"; //Notify gdjs of the object existence.
gdjs.registerObject("Sprite", gdjs.SpriteRuntimeObject); //Notify gdjs of the object existence.
//Others initialization and internal state management :
@@ -409,10 +510,10 @@ gdjs.SpriteRuntimeObject.prototype.setDirectionOrAngle = function(newValue) {
var anim = this._animations[this._currentAnimation];
if ( !anim.hasMultipleDirections ) {
// "Classic" setAngle implementation
if ( this.angle === newValue ) return;
this.angle = newValue;
this.hitBoxesDirty = true;
gdjs.RuntimeObject.prototype.setAngle.call(this, newValue);
this._renderer.updateAngle();
}
else {
@@ -430,7 +531,10 @@ gdjs.SpriteRuntimeObject.prototype.setDirectionOrAngle = function(newValue) {
this._renderer.update(); //TODO: This may be unnecessary.
this._animationFrameDirty = true;
// Reimplement what RuntimeObject.prototype.setAngle does:
this.hitBoxesDirty = true;
this._runtimeScene.getObjectPositionsManager().markObjectAsDirty(this);
}
};
@@ -663,7 +767,7 @@ gdjs.SpriteRuntimeObject.prototype.getCenterY = function() {
gdjs.SpriteRuntimeObject.prototype.setX = function(x) {
if ( x === this.x ) return;
this.x = x;
gdjs.RuntimeObject.prototype.setX.call(this, x);
if (this._animationFrame !== null) {
this.hitBoxesDirty = true;
this._renderer.updateX();
@@ -677,7 +781,7 @@ gdjs.SpriteRuntimeObject.prototype.setX = function(x) {
gdjs.SpriteRuntimeObject.prototype.setY = function(y) {
if ( y === this.y ) return;
this.y = y;
gdjs.RuntimeObject.prototype.setY.call(this, y);
if ( this._animationFrame !== null) {
this.hitBoxesDirty = true;
this._renderer.updateY();
@@ -694,11 +798,11 @@ gdjs.SpriteRuntimeObject.prototype.setAngle = function(angle) {
}
if ( !this._animations[this._currentAnimation].hasMultipleDirections ) {
// "Classic" setAngle implementation
if (this.angle === angle) return;
this.angle = angle;
gdjs.RuntimeObject.prototype.setAngle.call(this, angle);
this._renderer.updateAngle();
this.hitBoxesDirty = true;
} else {
angle = angle % 360;
if ( angle < 0 ) angle += 360;

View File

@@ -1,24 +1,40 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
* This project is released under the MIT License.
*/
/**
* @typedef {Object} VariableData Data representation of a GDevelop variable
* @property {string} [name] The name of the variable. Used if a child variable.
* @property {string} [value] The value of the variable, either string or number. Leave blank for structures.
* @property {Array<VariableData>} [children] The children of the structure. Leave blank if value is defined.
*/
/**
* A Variable is an object storing a value (number or a string) or children variables.
*
* @memberof gdjs
* @memberOf gdjs
* @class Variable
* @param {Object} varData optional object used to initialize the variable.
* @param {VariableData} [varData] The optional initial content of the variable.
*/
gdjs.Variable = function(varData)
{
this._value = 0;
this._str = "";
this._numberDirty = false;
this._stringDirty = true;
/** @type {number} */
this._value = 0;
/** @type {string} */
this._str = "";
/** @type {boolean} */
this._numberDirty = false;
/** @type {boolean} */
this._stringDirty = true;
/** @type {boolean} */
this._isStructure = false;
this._children = {};
/** @type {Object.<string, gdjs.Variable>} */
this._children = {};
/** @type {boolean} */
this._undefinedInContainer = false;
if ( varData !== undefined ) {
@@ -27,9 +43,9 @@ gdjs.Variable = function(varData)
//Try to guess the type of the value, as GD has no way ( for now ) to specify
//the type of a variable.
var valueWhenConsideredAsNumber = parseFloat(initialValue, 10);
var valueWhenConsideredAsNumber = parseFloat(initialValue);
if(valueWhenConsideredAsNumber === valueWhenConsideredAsNumber && valueWhenConsideredAsNumber.toString() === initialValue) { //"Since NaN is the only JavaScript value that is treated as unequal to itself, you can always test if a value is NaN by checking it for equality to itself"
this._value = parseFloat(initialValue, 10);
this._value = parseFloat(initialValue);
}
else { //We have a string (Maybe empty).
if ( initialValue.length === 0 )
@@ -45,7 +61,9 @@ gdjs.Variable = function(varData)
if (varData.children !== undefined) {
for(var i = 0, len = varData.children.length;i<len;++i) {
var childData = varData.children[i];
/** @type {VariableData} */
var childData = varData.children[i];
/** @type {gdjs.Variable} */
this._children[childData.name] = new gdjs.Variable(childData);
}
}
@@ -57,6 +75,7 @@ gdjs.Variable = function(varData)
/**
* Used (usually by gdjs.VariablesContainer) to set that the variable must be
* considered as not existing in the container.
* @method
* @private
*/
gdjs.Variable.prototype.setUndefinedInContainer = function() {
@@ -67,7 +86,8 @@ gdjs.Variable.prototype.setUndefinedInContainer = function() {
* Check if the variable must be considered as not existing in its container
* (usually a gdjs.VariablesContainer).
* @private
* @return true if the container must consider that the variable does not exist.
* @method
* @return {boolean} true if the container must consider that the variable does not exist.
*/
gdjs.Variable.prototype.isUndefinedInContainer = function() {
return this._undefinedInContainer;
@@ -78,6 +98,7 @@ gdjs.Variable.prototype.isUndefinedInContainer = function() {
*
* If the variable has not the specified child, an empty variable with the specified name
* is added as child.
* @method
* @returns {gdjs.Variable} The child variable
*/
gdjs.Variable.prototype.getChild = function(childName) {
@@ -93,6 +114,7 @@ gdjs.Variable.prototype.getChild = function(childName) {
* Return the child in a variable.
*
* Check if the variable has the specified children
* @method
* @return {boolean} true if variable has the children with the specified name
*/
gdjs.Variable.prototype.hasChild = function(childName) {
@@ -103,17 +125,19 @@ gdjs.Variable.prototype.hasChild = function(childName) {
* Remove the child with the specified name.
*
* If the variable has not the specified child, nothing is done.
* @param childName The name of the child to be removed
* @method
* @param {string} childName The name of the child to be removed
*/
gdjs.Variable.prototype.removeChild = function(childName) {
if ( !this._isStructure ) return;
delete this._children[childName];
}
};
/**
* Remove all the children.
*
* If the variable is not a structure, nothing is done.
* @method
*/
gdjs.Variable.prototype.clearChildren = function() {
if ( !this._isStructure ) return;
@@ -123,15 +147,16 @@ gdjs.Variable.prototype.clearChildren = function() {
delete this._children[child];
}
}
}
};
/**
* Get the value of the variable, considered as a number
* @method
* @return {number} The number stored in the variable
*/
gdjs.Variable.prototype.getAsNumber = function() {
if ( this._numberDirty ) {
this._value = parseFloat(this._str, 10);
this._value = parseFloat(this._str);
if ( this._value !== this._value ) this._value = 0; //Ensure NaN is not returned as a value.
this._numberDirty = false;
}
@@ -141,6 +166,7 @@ gdjs.Variable.prototype.getAsNumber = function() {
/**
* Change the value of the variable, considered as a number
* @method
* @param {number} newValue The new value to be set
*/
gdjs.Variable.prototype.setNumber = function(newValue) {
@@ -151,6 +177,7 @@ gdjs.Variable.prototype.setNumber = function(newValue) {
/**
* Get the value of the variable, considered as a string
* @method
* @return {string} The string stored in the variable
*/
gdjs.Variable.prototype.getAsString = function() {
@@ -164,6 +191,7 @@ gdjs.Variable.prototype.getAsString = function() {
/**
* Change the value of the variable, considered as a string
* @method
* @param {string} newValue The new string to be set
*/
gdjs.Variable.prototype.setString = function(newValue) {
@@ -174,6 +202,8 @@ gdjs.Variable.prototype.setString = function(newValue) {
/**
* Return true if the variable is a structure.
* @method
* @return {boolean} true if the variable is a structure.
*/
gdjs.Variable.prototype.isStructure = function() {
return this._isStructure;
@@ -181,6 +211,8 @@ gdjs.Variable.prototype.isStructure = function() {
/**
* Return true if the variable is a number.
* @method
* @return {boolean} true if the variable is a number.
*/
gdjs.Variable.prototype.isNumber = function() {
return !this._isStructure && !this._numberDirty;
@@ -188,15 +220,17 @@ gdjs.Variable.prototype.isNumber = function() {
/**
* Return the object containing all the children of the variable
* @method
* @return {Object.<string, gdjs.Variable>} All the children of the variable
*/
gdjs.Variable.prototype.getAllChildren = function() {
return this._children;
}
};
/**
* Add the given number to the variable value
* @param {number} number the number to add
* @method
* @param {number} val the number to add
*/
gdjs.Variable.prototype.add = function(val) {
this.setNumber(this.getAsNumber()+val);
@@ -204,7 +238,8 @@ gdjs.Variable.prototype.add = function(val) {
/**
* Subtract the given number to the variable value
* @param {number} number the number to subtract
* @method
* @param {number} val the number to subtract
*/
gdjs.Variable.prototype.sub = function(val) {
this.setNumber(this.getAsNumber()-val);
@@ -212,7 +247,8 @@ gdjs.Variable.prototype.sub = function(val) {
/**
* Multiply the variable value by the given number
* @param {number} number the factor
* @method
* @param {number} val the factor
*/
gdjs.Variable.prototype.mul = function(val) {
this.setNumber(this.getAsNumber()*val);
@@ -220,7 +256,8 @@ gdjs.Variable.prototype.mul = function(val) {
/**
* Divide the variable value by the given number
* @param {number} number the divisor
* @method
* @param {number} val the divisor
*/
gdjs.Variable.prototype.div = function(val) {
this.setNumber(this.getAsNumber()/val);
@@ -228,6 +265,7 @@ gdjs.Variable.prototype.div = function(val) {
/**
* Concatenate the given string at the end of the variable value
* @method
* @param {string} str the string to append
*/
gdjs.Variable.prototype.concatenate = function(str) {

View File

@@ -1,3 +1,5 @@
// @ts-check
/*
* GDevelop JS Platform
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
@@ -10,16 +12,18 @@
*
* @memberof gdjs
* @class VariablesContainer
* @param {Object} initialVariablesData Optional object containing initial variables.
* @param {Array<VariableData>} [initialVariablesData] Optional array containing representations of the base variables.
*/
gdjs.VariablesContainer = function(initialVariablesData)
{
if ( this._variables == undefined ) this._variables = new Hashtable();
if ( this._variablesArray == undefined ) this._variablesArray = [];
if ( this._variables === undefined ) this._variables = new Hashtable();
if ( this._variablesArray === undefined ) this._variablesArray = [];
if ( initialVariablesData != undefined ) this.initFrom(initialVariablesData);
if ( initialVariablesData !== undefined ) this.initFrom(initialVariablesData);
};
gdjs.VariablesContainer._deletedVars = gdjs.VariablesContainer._deletedVars || [];
/**
* Initialize variables from a container data.<br>
* If `keepOldVariables` is set to false (by default), all already existing variables will be
@@ -27,11 +31,11 @@ gdjs.VariablesContainer = function(initialVariablesData)
* if `keepOldVariables` is set to true, already existing variables won't be erased and will be
* still accessible thanks to getFromIndex.
*
* @param data The object containing the variables.
* @param {Boolean} keepOldVariables If set to true, already existing variables won't be erased.
* @param {Array<VariableData>} data The array containing data used to initialize variables.
* @param {Boolean} [keepOldVariables] If set to true, already existing variables won't be erased.
*/
gdjs.VariablesContainer.prototype.initFrom = function(data, keepOldVariables) {
if ( keepOldVariables == undefined ) keepOldVariables = false;
if ( keepOldVariables === undefined ) keepOldVariables = false;
if ( !keepOldVariables ) {
gdjs.VariablesContainer._deletedVars = gdjs.VariablesContainer._deletedVars || [];
this._variables.keys(gdjs.VariablesContainer._deletedVars);
@@ -56,7 +60,7 @@ gdjs.VariablesContainer.prototype.initFrom = function(data, keepOldVariables) {
++i;
//Remove the variable from the list of variables to be deleted.
var idx = gdjs.VariablesContainer._deletedVars.indexOf(varData.name)
var idx = gdjs.VariablesContainer._deletedVars.indexOf(varData.name);
if (idx !== -1) gdjs.VariablesContainer._deletedVars[idx] = undefined;
}
}
@@ -69,7 +73,7 @@ gdjs.VariablesContainer.prototype.initFrom = function(data, keepOldVariables) {
//(Here, remove means flag the variable as not existing, to avoid garbage creation ).
for(var i =0, len = gdjs.VariablesContainer._deletedVars.length;i<len;++i) {
var variableName = gdjs.VariablesContainer._deletedVars[i];
if ( variableName != undefined )
if ( variableName !== undefined )
this._variables.get(variableName).setUndefinedInContainer();
}
}
@@ -126,11 +130,12 @@ gdjs.VariablesContainer.prototype.get = function(name) {
* should not happen.
*/
gdjs.VariablesContainer.prototype.getFromIndex = function(id) {
if ( id >= this._variablesArray.length ) { //Add automatically inexisting variables.
if ( id >= this._variablesArray.length ) { //Add automatically non-existing variables.
var variable = new gdjs.Variable();
return this._variables.put(name, variable);
}
else {
this._variables.put(name, variable);
return variable;
} else {
/** @type {gdjs.Variable} */
var variable = this._variablesArray[id];
if ( variable.isUndefinedInContainer() ) { //Reuse variables removed before.
gdjs.Variable.call(variable);

View File

@@ -964,7 +964,7 @@ HTML_COLORSTYLE_GAMMA = 80
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the

View File

@@ -26,7 +26,7 @@
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/jaguar.css">
<?js if (env.conf.templates) { ?>
<script>
var config = <?js= JSON.stringify(env.conf.templates) ?>;
@@ -38,7 +38,7 @@
var _gaq = _gaq || [];
_gaq.push(['_setAccount', config.googleAnalytics]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
@@ -62,9 +62,11 @@
<!-- // disqus code -->
<?js } ?>
<?js if (env.conf.templates.default.includeDate) { ?>
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc <?js= env.version.number ?></a> on <?js= (new Date()) ?>
</footer>
<?js } ?>
</div>
</div>
<script>prettyPrint();</script>

View File

@@ -1,54 +1,55 @@
{
"tags": {
"allowUnknownTags": false
},
"source": {
"include": [
"./Runtime/"
],
"exclude": [
"./Runtime/Cocos2d/",
"./Runtime/Cordova/",
"./Runtime/Electron/",
"./Runtime/FacebookInstantGames/"
],
"includePattern": ".+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"plugins": [
"plugins/markdown"
"tags": {
"allowUnknownTags": false
},
"source": {
"include": ["./Runtime/"],
"exclude": [
"./Runtime/Cocos2d/",
"./Runtime/Cordova/",
"./Runtime/Electron/",
"./Runtime/FacebookInstantGames/"
],
"templates": {
"default" : {
"outputSourceFiles" : true
},
"applicationName": "GDevelop JS Runtime",
"footer" : "Made with ♥ by Florian Rival and contributors (gdevelop-app.com)",
"copyright" : "GDevelop Copyright © 2008-2018 Florian Rival",
"googleAnalytics": "TODO",
"openGraph": {
"title": "GDevelop JS Runtime Documentation",
"type": "website",
"image": "",
"site_name": "",
"url": ""
},
"meta": {
"title": "GDevelop JS Runtime Documentation",
"description": "Documentation for the GDevelop JavaScript game engine",
"keyword": "docs, documentation, gdevelop, game, engine, html5, javascript"
},
"linenums" : true
"includePattern": ".+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"plugins": [
"plugins/markdown",
"../node_modules/jsdoc-plugin-intersection",
"../node_modules/jsdoc-autoprivate"
],
"templates": {
"default": {
"outputSourceFiles": true,
"includeDate": false
},
"markdown" : {
"parser" : "gfm",
"hardwrap" : false
"applicationName": "GDevelop JS Runtime",
"footer": "Made with ♥ by Florian Rival and contributors (gdevelop-app.com)",
"copyright": "GDevelop Copyright © 2008-present Florian Rival",
"googleAnalytics": "TODO",
"openGraph": {
"title": "GDevelop JS Runtime Documentation",
"type": "website",
"image": "",
"site_name": "",
"url": ""
},
"opts": {
"encoding" : "utf8",
"recurse" : true,
"private" : false,
"lenient" : true,
"destination" : "../docs/GDJS Runtime Documentation"
}
}
"meta": {
"title": "GDevelop JS Runtime Documentation",
"description": "Documentation for the GDevelop JavaScript game engine",
"keyword": "docs, documentation, gdevelop, game, engine, html5, javascript"
},
"linenums": true
},
"markdown": {
"parser": "gfm",
"hardwrap": false
},
"opts": {
"encoding": "utf8",
"recurse": true,
"private": false,
"lenient": true,
"destination": "../docs/GDJS Runtime Documentation"
}
}

11
GDJS/package-lock.json generated
View File

@@ -16,6 +16,17 @@
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
"dev": true
},
"jsdoc-autoprivate": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/jsdoc-autoprivate/-/jsdoc-autoprivate-0.0.1.tgz",
"integrity": "sha1-Prx6wVwFDWOD+EtuKrahYii149Y="
},
"jsdoc-plugin-intersection": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/jsdoc-plugin-intersection/-/jsdoc-plugin-intersection-1.0.2.tgz",
"integrity": "sha512-lqCE44zM2wPv6PjAgzPM/dlrPFUiCVE5DrvntHVvHw5MFObkV+oDYwmO/3TXX7YsD+IdOPbsR4fIx/i+LETgNw==",
"dev": true
},
"typescript": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz",

View File

@@ -7,11 +7,13 @@
"devDependencies": {
"@types/expect.js": "^0.3.29",
"@types/mocha": "^5.2.7",
"jsdoc-plugin-intersection": "^1.0.2",
"typescript": "3.6.4"
},
"dependencies": {},
"dependencies": {
"jsdoc-autoprivate": "0.0.1"
},
"scripts": {
"copy-runtime-to-ide": "echo \"Use scripts/CopyRuntimeToGD.sh (or .bat on Windows)\"",
"check-types": "tsc"
}
}

View File

@@ -1,14 +0,0 @@
::This script copies the runtimes files (i.e: the javascript files located into the Runtime
::folder and in the Extensions folder) to the GDevelop folder.
@echo off
cd /d %~dp0
set destDir=%1
if [%destDir%]==[] set destDir="..\..\Binaries\Output\Release_Windows\JsPlatform\Runtime"
echo Copying GDJS and extensions runtime files (*.js) to %destDir%...
xcopy "..\Runtime"\* %destDir%\* /S /E /D /Y /Q
xcopy "..\..\Extensions"\*.js %destDir%\Extensions\*.js /S /E /D /Y /Q /EXCLUDE:FilesExcludedFromCopy
echo ✅ Copied GDJS and extensions runtime files (*.js) to %destDir%.

View File

@@ -1,18 +0,0 @@
#!/bin/bash
#Get the destination, or copy by default to release directory
DESTINATION=../../Binaries/Output/Release_Linux/JsPlatform/Runtime/
if [ "$(uname)" == "Darwin" ]; then
DESTINATION=../../Binaries/Output/Release_Darwin/JsPlatform/Runtime/
fi
if [ ! $# -eq 0 ]; then
DESTINATION=$1
fi
#Copy all js files
echo " Copying GDJS and extensions runtime files (*.js) to '$DESTINATION'..."
mkdir -p "$DESTINATION"
cp -R ../Runtime/* "$DESTINATION"
rsync -r -u --include=*.js --include=*/ --exclude=* ../../Extensions/ "$DESTINATION"/Extensions/
echo "✅ Copied GDJS and extensions runtime files (*.js) to '$DESTINATION'."

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,489 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "default",
"packageName": "",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Collisions benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Projet",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 10,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "2DWoodBox.jpg",
"kind": "image",
"metadata": "",
"name": "2DWoodBox.jpg",
"smoothed": true,
"userAdded": false
},
{
"alwaysLoaded": false,
"file": "spship.png",
"kind": "image",
"metadata": "",
"name": "spship.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "Nouvelle_32sc_232ne",
"name": "Nouvelle scène",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 243,
"layer": "",
"locked": false,
"name": "NouvelObjet1",
"width": 278,
"x": 108.5,
"y": 59,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NouvelObjet",
"width": 0,
"x": 400.5,
"y": 253,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NouvelObjet",
"width": 0,
"x": 195.5,
"y": 95,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NouvelObjet",
"width": 0,
"x": 563.5,
"y": 370,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NouvelObjet",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": true,
"variables": [
{
"name": "NewVariable",
"value": "1"
},
{
"name": "NewVariable2",
"value": "2"
}
],
"behaviors": [],
"animations": [
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "2DWoodBox.jpg",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
}
]
},
{
"name": "NouvelObjet1",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": true,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "spship.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "1200",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NouvelObjet",
"Random(400)",
"Random(300)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NouvelObjet1",
"0",
"0",
""
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NouvelObjet1",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "CollisionNP"
},
"parameters": [
"NouvelObjet1",
"NouvelObjet",
"",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeDirection"
},
"parameters": [
"NouvelObjet",
"+",
"1"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,532 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Cursor on object benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "FollowCursorObject",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "Object",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "FollowCursorObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "7000",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"Object",
"Random(600)",
"Random(400)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"Object",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"Object",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"Object",
"Object.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"colorB": 228,
"colorG": 176,
"colorR": 74,
"creationTime": 0,
"disabled": false,
"folded": false,
"name": "Cursor is on object",
"source": "",
"type": "BuiltinCommonInstructions::Group",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "SourisSurObjet"
},
"parameters": [
"Object",
"NewObject",
"no",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"Object",
"\"71;231;0\""
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": []
},
{
"colorB": 228,
"colorG": 176,
"colorR": 74,
"creationTime": 0,
"disabled": false,
"folded": false,
"name": "Cursor is NOT on object",
"source": "",
"type": "BuiltinCommonInstructions::Group",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": true,
"value": "SourisSurObjet"
},
"parameters": [
"Object",
"NewObject",
"no",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"Object",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"FollowCursorObject",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,594 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Distance between objects benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NewObject3",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NewObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject2",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject3",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject2",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject2",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject",
"=",
"Random(360)"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject2",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject",
"NewObject.Angle()",
"30",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject2",
"NewObject2.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Distance"
},
"parameters": [
"NewObject2",
"NewObject",
"10",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"71;231;0\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": true,
"value": "Distance"
},
"parameters": [
"NewObject2",
"NewObject",
"10",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NewObject3",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

View File

@@ -0,0 +1,555 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Point inside object benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NewObject3",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NewObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject2",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject3",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject2",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject2",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject2",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject2",
"NewObject2.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::ForEach",
"object": "NewObject",
"conditions": [
{
"type": {
"inverted": false,
"value": "CollisionPoint"
},
"parameters": [
"NewObject2",
"NewObject.PointX(\"Center\")",
"NewObject.PointY(\"Center\")"
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"NewObject2",
"\"71;231;0\""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NewObject3",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,576 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"adaptGameResolutionAtRuntime": false,
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Raycast benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [],
"objects": [
{
"name": "RayLauncher",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "RayObstacle",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "RayVisualizer",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 32,
"y": 32
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Comment",
"color": {
"b": 109,
"g": 230,
"r": 255,
"textB": 0,
"textG": 0,
"textR": 0
},
"comment": "Send a ray from every \"RayLauncher\" (on the left) against RayObstacel (on the right).",
"comment2": ""
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"RayLauncher",
"Random(300)",
"RandomInRange(-2000, 2000)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"RayObstacle",
"RandomInRange(500, 800)",
"RandomInRange(-2000, 2000)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"RayLauncher",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"RayObstacle",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": true,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"RayLauncher",
"=",
"Random(360)"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"RayObstacle",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": true,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"RayLauncher",
"RayLauncher.Angle()",
"30",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"RayObstacle",
"RayObstacle.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"RayObstacle",
"\"255;255;255\""
],
"subInstructions": []
}
],
"events": []
},
{
"colorB": 228,
"colorG": 176,
"colorR": 74,
"creationTime": 0,
"disabled": false,
"folded": false,
"name": "Raycast",
"source": "",
"type": "BuiltinCommonInstructions::Group",
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::ForEach",
"object": "RayLauncher",
"conditions": [
{
"type": {
"inverted": false,
"value": "Raycast"
},
"parameters": [
"RayObstacle",
"RayLauncher.X()",
"RayLauncher.Y()",
"0",
"800",
"rayEndX",
"rayEndY",
""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ChangeColor"
},
"parameters": [
"RayObstacle",
"\"42;255;0\""
],
"subInstructions": []
}
],
"events": []
}
],
"parameters": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

View File

@@ -0,0 +1,559 @@
{
"firstLayout": "",
"gdVersion": {
"build": 98,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"adMobAppId": "",
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"orientation": "landscape",
"packageName": "com.example.gamename",
"projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/object-positions-manager-benchmarks/Separate objects benchmark.json",
"scaleMode": "linear",
"sizeOnStartupMode": "adaptWidth",
"useExternalSourceFiles": false,
"version": "1.0.0",
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 800,
"windowHeight": 600,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 20,
"verticalSync": false,
"platformSpecificAssets": {},
"loadingScreen": {
"showGDevelopSplash": true
},
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "NewObject-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject2-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject2-1.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "NewObject3-1.png",
"kind": "image",
"metadata": "",
"name": "NewObject3-1.png",
"smoothed": true,
"userAdded": false
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "NewScene",
"name": "NewScene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": false,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "NewObject3",
"width": 0,
"x": 689,
"y": 110,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "NewObject",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject2",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject2",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject2-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
},
{
"name": "NewObject3",
"tags": "",
"type": "Sprite",
"updateIfNotVisible": false,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "NewObject3",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 0.08,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "NewObject3-1.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": []
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "DepartScene"
},
"parameters": [
""
],
"subInstructions": []
}
],
"actions": [],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Repeat",
"repeatExpression": "700",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "Create"
},
"parameters": [
"",
"NewObject2",
"Random(800)",
"Random(600)",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject",
"=",
"0.3"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "ChangeScale"
},
"parameters": [
"NewObject2",
"=",
"0.3"
],
"subInstructions": []
}
],
"events": []
}
]
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "Timer"
},
"parameters": [
"",
"1",
"\"DirectionChange\""
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "ResetTimer"
},
"parameters": [
"",
"\"DirectionChange\""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject",
"=",
"Random(360)"
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SetAngle"
},
"parameters": [
"NewObject2",
"=",
"Random(360)"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject",
"NewObject.Angle()",
"30",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "AddForceAL"
},
"parameters": [
"NewObject2",
"NewObject2.Angle()",
"30",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "SeparateFromObjects"
},
"parameters": [
"NewObject",
"NewObject2",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "SeparateFromObjects"
},
"parameters": [
"NewObject2",
"NewObject2",
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MettreXY"
},
"parameters": [
"NewObject3",
"=",
"MouseX()",
"=",
"MouseY()"
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"eventsFunctionsExtensions": [],
"externalLayouts": [],
"externalSourceFiles": []
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -19,6 +19,7 @@ module.exports = function(config) {
'../Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js',
'../Runtime/jsonmanager.js',
'../Runtime/timemanager.js',
'../Runtime/objectpositionsmanager.js',
'../Runtime/runtimeobject.js',
'../Runtime/runtimescene.js',
'../Runtime/scenestack.js',

View File

@@ -1,3 +1 @@
gdjs.registerObjects();
gdjs.registerBehaviors();
gdjs.registerGlobalCallbacks();

View File

@@ -11,7 +11,7 @@ gdjs.TestRuntimeBehavior = function(runtimeScene, behaviorData, owner)
};
gdjs.TestRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
gdjs.TestRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "TestBehavior::TestBehavior";
gdjs.registerBehavior("TestBehavior::TestBehavior", gdjs.TestRuntimeBehavior);
gdjs.TestRuntimeBehavior.prototype.onCreated = function() {
this.owner.getVariables().get("lastState").setString('created');

View File

@@ -3,7 +3,7 @@
* an example to start a new object, take a look at gdjs.DummyRuntimeObject
* in the Extensions folder.
*
* @memberof gdjs
* @memberOf gdjs
* @class TestRuntimeObject
* @extends RuntimeObject
*/
@@ -16,8 +16,7 @@ gdjs.TestRuntimeObject = function(runtimeScene, objectData) {
};
gdjs.TestRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
gdjs.TestRuntimeObject.thisIsARuntimeObjectConstructor =
'TestObject::TestObject';
gdjs.registerObject('TestObject::TestObject', gdjs.TestRuntimeObject);
gdjs.TestRuntimeObject.prototype.getRendererObject = function() {
return {};

View File

@@ -1,140 +1,250 @@
// @ts-check
/**
* Tests for gdjs.InputManager and related.
*/
describe('gdjs.InputManager', function() {
var inputManager = new gdjs.InputManager();
var inputManager = new gdjs.InputManager();
it('should handle keyboards events', function(){
expect(inputManager.anyKeyPressed()).to.be(false);
it('should handle keyboards events', function() {
expect(inputManager.anyKeyPressed()).to.be(false);
inputManager.onKeyPressed(32);
expect(inputManager.getLastPressedKey()).to.be(32);
inputManager.onKeyPressed(33);
expect(inputManager.getLastPressedKey()).to.be(33);
expect(inputManager.isKeyPressed(32)).to.be(true);
expect(inputManager.isKeyPressed(30)).to.be(false);
inputManager.onKeyReleased(32);
expect(inputManager.isKeyPressed(32)).to.be(false);
expect(inputManager.wasKeyReleased(32)).to.be(true);
inputManager.onKeyPressed(32);
expect(inputManager.getLastPressedKey()).to.be(32);
inputManager.onKeyPressed(33);
expect(inputManager.getLastPressedKey()).to.be(33);
expect(inputManager.isKeyPressed(32)).to.be(true);
expect(inputManager.isKeyPressed(30)).to.be(false);
inputManager.onKeyReleased(32);
expect(inputManager.isKeyPressed(32)).to.be(false);
expect(inputManager.wasKeyReleased(32)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(true);
inputManager.onFrameEnded();
expect(inputManager.wasKeyReleased(32)).to.be(false);
inputManager.onFrameEnded();
expect(inputManager.wasKeyReleased(32)).to.be(false);
expect(inputManager.anyKeyPressed()).to.be(true);
expect(inputManager.isKeyPressed(33)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(true);
expect(inputManager.isKeyPressed(33)).to.be(true);
inputManager.onFrameEnded();
inputManager.onKeyReleased(33);
expect(inputManager.wasKeyReleased(33)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(false);
inputManager.onFrameEnded();
inputManager.onKeyReleased(33);
expect(inputManager.wasKeyReleased(33)).to.be(true);
expect(inputManager.anyKeyPressed()).to.be(false);
});
});
it('should handle mouse events', function() {
inputManager.onMouseMove(500, 600);
expect(inputManager.getMouseX()).to.be(500);
expect(inputManager.getMouseY()).to.be(600);
it('should handle mouse events', function(){
inputManager.onMouseMove(500, 600);
expect(inputManager.getMouseX()).to.be(500);
expect(inputManager.getMouseY()).to.be(600);
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
inputManager.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(true);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
inputManager.onFrameEnded();
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
inputManager.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(true);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
inputManager.onFrameEnded();
inputManager.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(true);
inputManager.onFrameEnded();
inputManager.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(true);
inputManager.onFrameEnded();
expect(
inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
expect(
inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)
).to.be(false);
});
expect(inputManager.isMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
expect(inputManager.isMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON)).to.be(false);
});
it('should handle touch events', function() {
inputManager.onTouchStart(46, 510, 610);
inputManager.onTouchStart(10, 510, 610);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(2);
expect(inputManager.getTouchX(46)).to.be(510);
expect(inputManager.getTouchY(46)).to.be(610);
it('should handle touch events', function(){
inputManager.onTouchStart(46, 510, 610);
inputManager.onTouchStart(10, 510, 610);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(2);
expect(inputManager.getTouchX(46)).to.be(510);
expect(inputManager.getTouchY(46)).to.be(610);
expect(inputManager.popStartedTouch()).to.be(46);
expect(inputManager.popStartedTouch()).to.be(10);
expect(inputManager.popEndedTouch()).to.be(undefined);
expect(inputManager.popStartedTouch()).to.be(46);
expect(inputManager.popStartedTouch()).to.be(10);
expect(inputManager.popEndedTouch()).to.be(undefined);
inputManager.onFrameEnded();
inputManager.onTouchEnd(10);
expect(inputManager.getAllTouchIdentifiers()).to.have.length(2);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(0);
expect(inputManager.popStartedTouch()).to.be(undefined);
expect(inputManager.popEndedTouch()).to.be(10);
expect(inputManager.getTouchX(10)).to.be(510);
expect(inputManager.getTouchY(10)).to.be(610);
inputManager.onFrameEnded();
inputManager.onTouchEnd(10);
expect(inputManager.getAllTouchIdentifiers()).to.have.length(2);
expect(inputManager.getStartedTouchIdentifiers()).to.have.length(0);
expect(inputManager.popStartedTouch()).to.be(undefined);
expect(inputManager.popEndedTouch()).to.be(10);
expect(inputManager.getTouchX(10)).to.be(510);
expect(inputManager.getTouchY(10)).to.be(610);
inputManager.onFrameEnded();
expect(inputManager.getAllTouchIdentifiers()).to.have.length(1);
});
it('should simulate (or not) mouse events', function() {
inputManager.touchSimulateMouse();
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(true);
expect(inputManager.getMouseX()).to.be(510);
expect(inputManager.getMouseY()).to.be(610);
inputManager.onTouchMove(46, 520, 620);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
inputManager.onTouchEnd(46);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.onFrameEnded();
expect(inputManager.getAllTouchIdentifiers()).to.have.length(1);
});
it('should simulate (or not) mouse events', function(){
inputManager.touchSimulateMouse();
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(true);
expect(inputManager.getMouseX()).to.be(510);
expect(inputManager.getMouseY()).to.be(610);
inputManager.onTouchMove(46, 520, 620);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
inputManager.onTouchEnd(46);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
inputManager.touchSimulateMouse(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
});
inputManager.touchSimulateMouse(false);
inputManager.onTouchStart(46, 510, 610);
expect(inputManager.isMouseButtonPressed(0)).to.be(false);
expect(inputManager.getMouseX()).to.be(520);
expect(inputManager.getMouseY()).to.be(620);
});
});
describe('gdjs.RuntimeObject.cursorOnObject', function() {
var runtimeGame = new gdjs.RuntimeGame({variables: [], properties: {windowWidth: 800, windowHeight: 600}});
var runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
layers:[{name:"", visibility: true}],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: []
});
describe('gdjs.evtTools.input.cursorOnObject', function() {
var runtimeGame = new gdjs.RuntimeGame({
variables: [],
properties: { windowWidth: 800, windowHeight: 600 },
});
var runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
layers: [{ name: '', visibility: true }],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
});
var object = new gdjs.RuntimeObject(runtimeScene, {name: "obj1", type: "", behaviors: []});
object.setPosition(450, 500);
var object = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj1',
type: '',
behaviors: [],
variables: [],
});
object.setPosition(450, 500);
object.getWidth = function() {
return 5;
};
object.getHeight = function() {
return 5;
};
it('should handle mouse', function() {
runtimeGame.getInputManager().onMouseMove(100, 100);
expect(object.cursorOnObject(runtimeScene)).to.be(false);
runtimeGame.getInputManager().onMouseMove(450, 500);
expect(object.cursorOnObject(runtimeScene)).to.be(true);
});
it('should handle mouse', function() {
var objectsLists = new Hashtable();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(100, 100);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
it('should handle touch', function() {
runtimeGame.getInputManager().onMouseMove(0, 0);
runtimeGame.getInputManager().touchSimulateMouse(false);
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(450, 500);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
});
runtimeGame.getInputManager().onTouchStart(0, 100, 100);
expect(object.cursorOnObject(runtimeScene)).to.be(false);
runtimeGame.getInputManager().onFrameEnded();
it('should handle inversion of the test', function() {
var objectsLists = new Hashtable();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(100, 100);
expect(
gdjs.evtTools.input.cursorOnObject(objectsLists, runtimeScene, true, true)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
runtimeGame.getInputManager().onTouchStart(1, 450, 500);
expect(object.cursorOnObject(runtimeScene)).to.be(true);
runtimeGame.getInputManager().onFrameEnded();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onMouseMove(450, 500);
expect(
gdjs.evtTools.input.cursorOnObject(objectsLists, runtimeScene, true, true)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
});
runtimeGame.getInputManager().onTouchEnd(1);
expect(object.cursorOnObject(runtimeScene)).to.be(true);
runtimeGame.getInputManager().onFrameEnded();
it('should handle touch', function() {
var objectsLists = new Hashtable();
objectsLists.put('obj1', [object]);
expect(object.cursorOnObject(runtimeScene)).to.be(false);
});
runtimeGame.getInputManager().onMouseMove(0, 0);
runtimeGame.getInputManager().touchSimulateMouse(false);
runtimeGame.getInputManager().onTouchStart(0, 100, 100);
objectsLists.put('obj1', [object]);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
runtimeGame.getInputManager().onFrameEnded();
objectsLists.put('obj1', [object]);
runtimeGame.getInputManager().onTouchStart(1, 450, 500);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
runtimeGame.getInputManager().onFrameEnded();
runtimeGame.getInputManager().onTouchEnd(1);
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(true);
expect(objectsLists.get('obj1')).to.have.length(1);
expect(objectsLists.get('obj1')[0]).to.be(object);
runtimeGame.getInputManager().onFrameEnded();
expect(
gdjs.evtTools.input.cursorOnObject(
objectsLists,
runtimeScene,
true,
false
)
).to.be(false);
expect(objectsLists.get('obj1')).to.have.length(0);
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -66,4 +66,4 @@ It also create a compressed `libGD.js.gz` file which is handy for distributing t
## Documentation
- The file [Bindings.idl](https://github.com/4ian/GDevelop/blob/master/GDevelop.js/Bindings/Bindings.idl) describes all the classes available in GDevelop.js.
- Refer to [GDevelop documentation](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/) for detailed documentation of the original C++ classes.
- Refer to [GDevelop documentation](https://docs.gdevelop-app.com/GDCore%20Documentation/) for detailed documentation of the original C++ classes.

View File

@@ -28,7 +28,7 @@ Overview of the architecture
To learn more about GDevelop Architecture, read the [architecture overview here](Core/GDevelop-Architecture-Overview.md).
A pre-generated documentation of the Core library, C++ and JS game engines is [available here](http://4ian.github.io/GD-Documentation).
A pre-generated documentation of the Core library, C++ and JS game engines is [available here](https://docs.gdevelop-app.com).
Links
-----

View File

@@ -50,7 +50,7 @@ Refer to the [GDevelop IDE Readme](./README.md) for more information about the i
> Implement your extension in file called `extensionnametools.js` (for general functions), `objectnameruntimeobject.js` (for objects) or `behaviornameruntimebehavior.js` (for behaviors). See then the next section for declaring these files and the content of the extension to the IDE.
Check the [GDJS game engine documentation here](http://4ian.github.io/GD-Documentation/GDJS%20Runtime%20Documentation/index.html). It's also a good idea to check the [Runtime folder of GDJS](../GDJS/README.md) to see directly how the game engine is done when needed. Files for the game engine should [mostly be written in JavaScript "ES5 flavor" (i.e: usual, classic good old JavaScript) (click to learn more)](https://github.com/4ian/GDevelop/blob/master/newIDE/docs/Supported-JavaScript-features-and-coding-style.md).
Check the [GDJS game engine documentation here](https://docs.gdevelop-app.com/GDJS%20Runtime%20Documentation/index.html). It's also a good idea to check the [Runtime folder of GDJS](../GDJS/README.md) to see directly how the game engine is done when needed. Files for the game engine should [mostly be written in JavaScript "ES5 flavor" (i.e: usual, classic good old JavaScript) (click to learn more)](https://github.com/4ian/GDevelop/blob/master/newIDE/docs/Supported-JavaScript-features-and-coding-style.md).
#### How to create functions to be called by events
@@ -89,16 +89,16 @@ The API to declare extensions is almost 100% equivalent to the way extensions ar
#### Declare the extension information
Use [`extension.setExtensionInformation`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_platform_extension.html#ac53e5af617a9ed91c280d652899557c3) to declare basic information about your extension.
Use [`extension.setExtensionInformation`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_platform_extension.html#ac53e5af617a9ed91c280d652899557c3) to declare basic information about your extension.
> 👉 See an example in the [example extension _JsExtension.js_ file](../Extensions/ExampleJsExtension/JsExtension.js).
#### Declare actions, conditions and expressions
Use [`addAction`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_platform_extension.html#a34e95be54f2dfa80b804e8e4830e7d9c), `addCondition`, `addExpression` or `addStrExpression` to declare actions, conditions or expressions.
Use [`addAction`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_platform_extension.html#a34e95be54f2dfa80b804e8e4830e7d9c), `addCondition`, `addExpression` or `addStrExpression` to declare actions, conditions or expressions.
- Chain calls to [`addParameter`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_instruction_metadata.html#a95486188a843f9ac8cdb1b0700c6c7e5) to declare the parameters of your action/condition/expression.
- Call `getCodeExtraInformation()` and then functions like [`setFunctionName` and `setIncludeFile`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_instruction_metadata_1_1_extra_information.html) to declare the JavaScript function to be called and the file to be included.
- Chain calls to [`addParameter`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_instruction_metadata.html#a95486188a843f9ac8cdb1b0700c6c7e5) to declare the parameters of your action/condition/expression.
- Call `getCodeExtraInformation()` and then functions like [`setFunctionName` and `setIncludeFile`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_instruction_metadata_1_1_extra_information.html) to declare the JavaScript function to be called and the file to be included.
> You can call these functions on the `extension` object, or on the objects returned by `extension.addObject` (for objects) or `extension.addBehavior` (for behaviors). See below.
@@ -108,7 +108,7 @@ Use [`addAction`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/
#### Declare behaviors
Add a behavior using [`addBehavior`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_platform_extension.html#a75992fed9afce730db56af9d4d8177ca). The last two parameters are the `gd.Behavior` and the `gd.BehaviorsSharedData` object representing the behavior and its (optional) shared data
Add a behavior using [`addBehavior`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_platform_extension.html#a75992fed9afce730db56af9d4d8177ca). The last two parameters are the `gd.Behavior` and the `gd.BehaviorsSharedData` object representing the behavior and its (optional) shared data
- For the behavior, create a `new gd.BehaviorJsImplementation()` and define `initializeContent`, `updateProperty` and `getProperties`.
- For the shared data (which are properties shared between all behaviors of the same type), if you don't have the need for it, just pass `new gd.BehaviorsSharedData()`. If you need shared data, create a `new gd.BehaviorSharedDataJsImplementation()` and define `initializeContent`, `updateProperty` and `getProperties`.
@@ -119,7 +119,7 @@ Add a behavior using [`addBehavior`](http://4ian.github.io/GD-Documentation/GDCo
#### Declare objects
Add an object using [`addObject`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_platform_extension.html#a554baca486909e8741e902133cceeec0). The last parameter is the `gd.Object` representing the object:
Add an object using [`addObject`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_platform_extension.html#a554baca486909e8741e902133cceeec0). The last parameter is the `gd.Object` representing the object:
- Create a `new gd.ObjectJsImplementation()` and define `updateProperty` and `getProperties` (for the object properties) and `updateInitialInstanceProperty` and `getInitialInstanceProperties` (for the optional properties that are attached to each instance).
@@ -152,7 +152,7 @@ Finally, to have the instances of your object displayed properly on the scene ed
#### Declare effects
Add an effect using [`addEffect`](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/classgd_1_1_platform_extension.html) in your _JsExtension.js_ file.
Add an effect using [`addEffect`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_platform_extension.html) in your _JsExtension.js_ file.
> 👉 See an example in the [Effects extension _JsExtension.js_ file](../Extensions/Effects/JsExtension.js). Learn more about [properties here](docs/Properties-schema-and-PropertiesEditor-explanations.md).

File diff suppressed because it is too large Load Diff

View File

@@ -3195,6 +3195,12 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
"array-differ": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
"integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
"dev": true
},
"array-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
@@ -3441,22 +3447,6 @@
"postcss-value-parser": "^4.0.0"
}
},
"aws-sdk": {
"version": "2.540.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.540.0.tgz",
"integrity": "sha512-CQdXuMED/xPW7y50vObadERIzrVB6Zr87Ln9RIm3VyJuIWUWS92Z7DKAe9F+LdFh1/6zKVd/iLDJ7Fsd/pAEmA==",
"requires": {
"buffer": "4.9.1",
"events": "1.1.1",
"ieee754": "1.1.13",
"jmespath": "0.15.0",
"querystring": "0.2.0",
"sax": "1.2.1",
"url": "0.10.3",
"uuid": "3.3.2",
"xml2js": "0.4.19"
}
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -4506,7 +4496,8 @@
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
"dev": true
},
"batch": {
"version": "0.6.1",
@@ -4879,6 +4870,7 @@
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4",
@@ -4888,7 +4880,8 @@
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
}
}
},
@@ -6901,6 +6894,12 @@
"minimalistic-crypto-utils": "^1.0.0"
}
},
"emitter-mixin": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/emitter-mixin/-/emitter-mixin-0.0.3.tgz",
"integrity": "sha1-WUjLKG8uSO3DslGnz8H3iDOW1lw=",
"dev": true
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@@ -8738,15 +8737,13 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -8763,22 +8760,19 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true,
"optional": true
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true,
"optional": true
"dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -8909,8 +8903,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true,
"optional": true
"dev": true
},
"ini": {
"version": "1.3.5",
@@ -8924,7 +8917,6 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -8941,7 +8933,6 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -8950,15 +8941,13 @@
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true,
"optional": true
"dev": true
},
"minipass": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -8979,7 +8968,6 @@
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -9068,8 +9056,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true,
"optional": true
"dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -9083,7 +9070,6 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -9221,7 +9207,6 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -10563,7 +10548,8 @@
"ieee754": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
"dev": true
},
"iferr": {
"version": "0.1.5",
@@ -12987,11 +12973,6 @@
"merge-stream": "^1.0.1"
}
},
"jmespath": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
"integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
},
"joi": {
"version": "11.4.0",
"resolved": "https://registry.npmjs.org/joi/-/joi-11.4.0.tgz",
@@ -13257,6 +13238,12 @@
"object.assign": "^4.1.0"
}
},
"junk": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz",
"integrity": "sha1-h75jSIZJy9ym9Tqzm+yczSNH9ZI=",
"dev": true
},
"keen-core": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/keen-core/-/keen-core-0.1.2.tgz",
@@ -13748,6 +13735,18 @@
"integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==",
"dev": true
},
"maximatch": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz",
"integrity": "sha1-hs2NawTJ8wfAWmuUGZBtA2D7E6I=",
"dev": true,
"requires": {
"array-differ": "^1.0.0",
"array-union": "^1.0.1",
"arrify": "^1.0.0",
"minimatch": "^3.0.0"
}
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -16605,7 +16604,8 @@
"punycode": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
"dev": true
},
"pure-color": {
"version": "1.3.0",
@@ -16637,7 +16637,8 @@
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
"dev": true
},
"querystring-es3": {
"version": "0.2.1",
@@ -17804,15 +17805,13 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -17829,22 +17828,19 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true,
"optional": true
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true,
"optional": true
"dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -17975,8 +17971,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true,
"optional": true
"dev": true
},
"ini": {
"version": "1.3.5",
@@ -17990,7 +17985,6 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -18007,7 +18001,6 @@
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -18016,15 +18009,13 @@
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true,
"optional": true
"dev": true
},
"minipass": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -18045,7 +18036,6 @@
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -18134,8 +18124,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true,
"optional": true
"dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -18149,7 +18138,6 @@
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -18287,7 +18275,6 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -19131,6 +19118,61 @@
}
}
},
"recursive-copy": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.10.tgz",
"integrity": "sha512-S9J9XJUnfZ2NUS3lK6lx6HWLl2nWui+f7AKuu+qoFs4ikEPYgZ3qKk1T6tmBnr7PzhtKnawE+6TREy9XQKmxCA==",
"dev": true,
"requires": {
"del": "^2.2.0",
"emitter-mixin": "0.0.3",
"errno": "^0.1.2",
"graceful-fs": "^4.1.4",
"junk": "^1.0.1",
"maximatch": "^0.1.0",
"mkdirp": "^0.5.1",
"pify": "^2.3.0",
"promise": "^7.0.1",
"slash": "^1.0.0"
},
"dependencies": {
"del": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
"integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
"dev": true,
"requires": {
"globby": "^5.0.0",
"is-path-cwd": "^1.0.0",
"is-path-in-cwd": "^1.0.0",
"object-assign": "^4.0.1",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0",
"rimraf": "^2.2.8"
}
},
"globby": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
"integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
"dev": true,
"requires": {
"array-union": "^1.0.1",
"arrify": "^1.0.0",
"glob": "^7.0.3",
"object-assign": "^4.0.1",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0"
}
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
}
},
"recursive-readdir": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@@ -19781,11 +19823,6 @@
}
}
},
"sax": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
"integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
},
"scheduler": {
"version": "0.13.6",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz",
@@ -21997,15 +22034,6 @@
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
"dev": true
},
"url": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
"integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
"requires": {
"punycode": "1.3.2",
"querystring": "0.2.0"
}
},
"url-loader": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz",
@@ -23433,20 +23461,6 @@
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true
},
"xml2js": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
},
"xmlhttprequest": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",

View File

@@ -20,6 +20,7 @@
"iso-639-1": "^2.0.3",
"prettier": "1.15.3",
"react-scripts": "2.1.4",
"recursive-copy": "^2.0.10",
"recursive-readdir": "^2.2.2",
"shelljs": "^0.7.7",
"unzipper": "^0.9.11",
@@ -33,7 +34,6 @@
"@material-ui/core": "4.3.2",
"@material-ui/icons": "4.2.1",
"algoliasearch": "3.33.0",
"aws-sdk": "^2.100.0",
"axios": "^0.18.1",
"blueimp-md5": "^2.10.0",
"classnames": "2.2.5",

View File

@@ -428,7 +428,7 @@
"parameters": [
"url",
"=",
"\"http://4ian.github.io/GD-Documentation/GDCore%20Documentation/gdlogo.png\""
"\"https://docs.gdevelop-app.com/GDCore%20Documentation/gdlogo.png\""
],
"subInstructions": []
},
@@ -556,4 +556,4 @@
"externalEvents": [],
"externalLayouts": [],
"externalSourceFiles": []
}
}

View File

@@ -0,0 +1,243 @@
/**
* Launch this script to generate a reference of all expressions supported by GDevelop.
*/
const gd = require('../public/libGD.js')();
const { mapVector } = require('./lib/MapFor');
const makeExtensionsLoader = require('./lib/LocalJsExtensionsLoader');
const fs = require('fs');
const _ = require('lodash');
const shell = require('shelljs');
shell.exec('node import-GDJS-Runtime.js');
gd.initializePlatforms();
const outputFile = 'reference.md';
// Types definitions used in this script:
/**
* @typedef {Object} DocumentationText
* @prop {string} text The text to render (in Markdown/Dokuwiki syntax)
*/
/**
* @typedef {Object} ReferenceText
* @prop {string} expressionType The type of the expression
* @prop {string} text The text to render (in Markdown/Dokuwiki syntax)
*/
/** @returns {DocumentationText} */
const generateExtensionHeaderText = ({ extension }) => {
return {
text: `## ${extension.getFullName()}
${extension.getDescription()}
`,
};
};
/** @returns {DocumentationText} */
const generateObjectHeaderText = ({ extension, objectMetadata }) => {
const additionalText =
extension.getFullName() !== objectMetadata.getFullName()
? `(from extension ${extension.getFullName()})`
: '';
return {
text: `## ${objectMetadata.getFullName()} ${additionalText}
${objectMetadata.getDescription()}
`,
};
};
/** @returns {DocumentationText} */
const generateBehaviorHeaderText = ({ extension, behaviorMetadata }) => {
const additionalText =
extension.getFullName() !== behaviorMetadata.getFullName()
? `(from extension ${extension.getFullName()})`
: '';
return {
text: `## ${behaviorMetadata.getFullName()} ${additionalText}
${behaviorMetadata.getDescription()}
`,
};
};
/** @returns {ReferenceText} */
const generateExpressionReferenceText = ({
expressionType,
expressionMetadata,
objectMetadata,
behaviorMetadata,
}) => {
// TODO: Add parameters and put this as a table row?
// Find the methods available on expressionMetadata in GDevelop.js/Bindings/Bindings.idl
const text = `* \`${expressionType}\`: **${expressionMetadata.getFullName()}**
${expressionMetadata.getDescription()}`;
return {
expressionType,
text,
};
};
/** @returns {Array<ReferenceText>} */
const generateExpressionsReferenceTexts = ({
expressionsMetadata,
objectMetadata,
behaviorMetadata,
}) => {
/** @type {Array<string>} */
const expressionTypes = expressionsMetadata.keys().toJSArray();
return expressionTypes
.map(expressionType => {
const expressionMetadata = expressionsMetadata.get(expressionType);
if (!expressionMetadata.isShown()) return null;
return generateExpressionReferenceText({
expressionType,
expressionMetadata,
});
})
.filter(Boolean);
};
const sortExpressionReferenceTexts = (expressionText1, expressionText2) => {
if (expressionText1.expressionType > expressionText2.expressionType) {
return 1;
} else if (expressionText1.expressionType < expressionText2.expressionType) {
return -1;
}
return 0;
};
/** @returns {Array<Text>} */
const generateAllDocumentationTexts = () => {
const platformExtensions = gd.JsPlatform.get().getAllPlatformExtensions();
let allExpressionsReferenceTexts = [];
mapVector(platformExtensions, extension => {
const extensionExpressions = extension.getAllExpressions();
const extensionStrExpressions = extension.getAllStrExpressions();
/** @type {Array<string>} */
const objectTypes = extension.getExtensionObjectsTypes().toJSArray();
/** @type {Array<string>} */
const behaviorTypes = extension.getBehaviorsTypes().toJSArray();
// Object expressions
let allExtensionObjectsReferenceTexts = [];
objectTypes.forEach(objectType => {
const objectMetadata = extension.getObjectMetadata(objectType);
const objectReferenceTexts = [
...generateExpressionsReferenceTexts({
expressionsMetadata: extension.getAllExpressionsForObject(objectType),
objectMetadata,
}),
...generateExpressionsReferenceTexts({
expressionsMetadata: extension.getAllStrExpressionsForObject(
objectType
),
objectMetadata,
}),
];
objectReferenceTexts.sort(sortExpressionReferenceTexts);
allExtensionObjectsReferenceTexts = [
generateObjectHeaderText({ extension, objectMetadata }),
...allExtensionObjectsReferenceTexts,
...objectReferenceTexts,
];
});
let allExtensionBehaviorsReferenceTexts = [];
// Behavior expressions
behaviorTypes.forEach(behaviorType => {
const behaviorMetadata = extension.getBehaviorMetadata(behaviorType);
const behaviorReferenceTexts = [
...generateExpressionsReferenceTexts({
expressionsMetadata: extension.getAllExpressionsForBehavior(
behaviorType
),
behaviorMetadata,
}),
...generateExpressionsReferenceTexts({
expressionsMetadata: extension.getAllStrExpressionsForBehavior(
behaviorType
),
behaviorMetadata,
}),
];
behaviorReferenceTexts.sort(sortExpressionReferenceTexts);
allExtensionBehaviorsReferenceTexts = [
generateBehaviorHeaderText({ extension, behaviorMetadata }),
...allExtensionBehaviorsReferenceTexts,
...behaviorReferenceTexts,
];
});
// Free (non objects/non behaviors) expressions
const allExtensionFreeExpressionsReferenceTexts = [
...generateExpressionsReferenceTexts({
expressionsMetadata: extensionStrExpressions,
}),
...generateExpressionsReferenceTexts({
expressionsMetadata: extensionExpressions,
}),
];
allExtensionFreeExpressionsReferenceTexts.sort(
sortExpressionReferenceTexts
);
const hasFreeExpressionsReferenceTexts =
allExtensionFreeExpressionsReferenceTexts.length > 0;
allExpressionsReferenceTexts = [
...allExpressionsReferenceTexts,
hasFreeExpressionsReferenceTexts
? generateExtensionHeaderText({ extension })
: null,
...allExtensionFreeExpressionsReferenceTexts,
...allExtensionObjectsReferenceTexts,
...allExtensionBehaviorsReferenceTexts,
].filter(Boolean);
});
return allExpressionsReferenceTexts;
};
const writeFile = content => {
return new Promise((resolve, reject) => {
fs.writeFile(outputFile, content, err => {
if (err) return reject(err);
resolve();
});
});
};
const noopTranslationFunction = str => str;
const extensionsLoader = makeExtensionsLoader({ gd, filterExamples: false });
extensionsLoader
.loadAllExtensions(noopTranslationFunction)
.then(loadingResults => {
console.info('Loaded extensions', loadingResults);
return generateAllDocumentationTexts();
})
.then(allDocumentationTexts => {
const texts = allDocumentationTexts
.map(({ expressionType, text }) => {
return text;
})
.join('\n\n');
return writeFile(texts);
})
.then(
() => console.info('Done.'),
err => console.error('Error while writing output', err)
);

View File

@@ -1,25 +1,66 @@
var shell = require('shelljs');
var path = require('path');
var isWin = /^win/.test(process.platform);
const shell = require('shelljs');
const path = require('path');
const copy = require('recursive-copy');
var destFolder = path.join(__dirname, '..', 'resources', 'GDJS', 'Runtime');
var destFolder2 = path.join(__dirname, '..', 'node_modules', 'GDJS-for-web-app-only', 'Runtime');
var gdjsScriptsFolder = path.join(__dirname, '../../../GDJS/scripts');
const gdevelopRootPath = path.join(__dirname, '..', '..', '..');
const destinationPaths = [
path.join(__dirname, '..', 'resources', 'GDJS', 'Runtime'),
path.join(
__dirname,
'..',
'node_modules',
'GDJS-for-web-app-only',
'Runtime'
),
];
if (isWin) {
shell.exec('CopyRuntimeToGD.bat ' + "\"" + destFolder + "\"", {
cwd: gdjsScriptsFolder,
});
shell.exec('CopyRuntimeToGD.bat ' + "\"" + destFolder2 + "\"", {
cwd: gdjsScriptsFolder,
});
} else {
shell.rm('-rf', destFolder);
shell.rm('-rf', destFolder2);
shell.exec('./CopyRuntimeToGD.sh ' + destFolder, {
cwd: gdjsScriptsFolder,
});
shell.exec('./CopyRuntimeToGD.sh ' + destFolder2, {
cwd: gdjsScriptsFolder,
});
}
var copyOptions = {
overwrite: true,
expand: true,
dot: true,
junk: true,
};
destinationPaths.forEach(destinationPath => {
shell.echo(
` Copying GDJS and extensions runtime files (*.js) to "${destinationPath}"...`
);
shell.rm('-rf', destinationPath);
shell.mkdir('-p', destinationPath);
copy(
path.join(gdevelopRootPath, 'GDJS', 'Runtime'),
destinationPath,
copyOptions
)
.then(function(results) {
console.info(
`✅ GDJS and extensions runtime copy succeeded (${
results.length
} file(s) copied`
);
})
.catch(function(error) {
console.error('❌ Copy failed: ' + error);
});
copy(
path.join(gdevelopRootPath, 'Extensions'),
path.join(destinationPath, 'Extensions'),
{
...copyOptions,
filter: ['**/*.js'],
}
)
.then(function(results) {
console.info(
`✅ GDJS and extensions runtime copy succeeded (${
results.length
} file(s) copied`
);
})
.catch(function(error) {
console.error('❌ Copy failed: ' + error);
});
});

Some files were not shown because too many files have changed in this diff Show More