mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
151 Commits
v5.0.0-bet
...
v5.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2b156ef147 | ||
![]() |
f650a6aa9c | ||
![]() |
5d62f0c926 | ||
![]() |
449a1f5da9 | ||
![]() |
a0e0fdf6e1 | ||
![]() |
036f384ff9 | ||
![]() |
b42abf0cd8 | ||
![]() |
ee699d3870 | ||
![]() |
346eed3779 | ||
![]() |
ef6f491fb4 | ||
![]() |
ee6043477b | ||
![]() |
deddfdc4cf | ||
![]() |
6ad69d4c74 | ||
![]() |
6446bb20a0 | ||
![]() |
015f9f64c7 | ||
![]() |
74e5b30fd1 | ||
![]() |
057c0a1d13 | ||
![]() |
7f6c9923dc | ||
![]() |
3dae7c1899 | ||
![]() |
04c2abd508 | ||
![]() |
d82fd79186 | ||
![]() |
fe312e0bf6 | ||
![]() |
ad22a83680 | ||
![]() |
ac32b677b0 | ||
![]() |
902bc8a510 | ||
![]() |
804c9563a1 | ||
![]() |
64996b5f7d | ||
![]() |
5fdf7be698 | ||
![]() |
a869fc14f9 | ||
![]() |
ae8a26b3f9 | ||
![]() |
aaec53faaa | ||
![]() |
bc56f820b3 | ||
![]() |
2c93c948bf | ||
![]() |
fe3a2f6e4a | ||
![]() |
449c96aaba | ||
![]() |
4cee984472 | ||
![]() |
98c9763d1c | ||
![]() |
c3ed8cbbb4 | ||
![]() |
65fc9f599e | ||
![]() |
10ebf9e65d | ||
![]() |
d1b1e3b24e | ||
![]() |
188b262af0 | ||
![]() |
a04c7f993f | ||
![]() |
13a8b5bce0 | ||
![]() |
45e6b19204 | ||
![]() |
0136445a65 | ||
![]() |
c26df2c8a9 | ||
![]() |
f390d4a1bc | ||
![]() |
cc2cdc492e | ||
![]() |
feeebd0560 | ||
![]() |
f6145f4c4e | ||
![]() |
fd490e1d5a | ||
![]() |
4760b0ab04 | ||
![]() |
3f95bf9f1a | ||
![]() |
76b63c2f76 | ||
![]() |
0a501f5a3c | ||
![]() |
45ab608409 | ||
![]() |
df94a4d0fb | ||
![]() |
c7d3d1314d | ||
![]() |
cff1a1e3c7 | ||
![]() |
3cf421f05b | ||
![]() |
6cc5016f9e | ||
![]() |
2dd62456c2 | ||
![]() |
d8b1c471bb | ||
![]() |
a3622a6504 | ||
![]() |
4ab14d18f8 | ||
![]() |
8ba11703e1 | ||
![]() |
8a8adf213a | ||
![]() |
25ea23a115 | ||
![]() |
586694543d | ||
![]() |
b7b6ab91f5 | ||
![]() |
d2d0235c8c | ||
![]() |
b473e0aaf0 | ||
![]() |
b2c7166b1b | ||
![]() |
bb2ae1a914 | ||
![]() |
aa1c5584ca | ||
![]() |
28593608a5 | ||
![]() |
8c5a312725 | ||
![]() |
3ed07dee5e | ||
![]() |
e1cb634e3d | ||
![]() |
f0392cfede | ||
![]() |
0bce1fc56b | ||
![]() |
b7aaf32d75 | ||
![]() |
0dce21904e | ||
![]() |
ca877e518e | ||
![]() |
f87ace7e25 | ||
![]() |
8954df947d | ||
![]() |
52a2f3653f | ||
![]() |
04a896de59 | ||
![]() |
8c6b9ef044 | ||
![]() |
45d7c6188b | ||
![]() |
10eb944b2a | ||
![]() |
a607c820a8 | ||
![]() |
0c22c52a78 | ||
![]() |
06748e00e1 | ||
![]() |
8b39233f44 | ||
![]() |
f68842bdb1 | ||
![]() |
544b88fec9 | ||
![]() |
48fe0fa2a6 | ||
![]() |
e7ef94de5f | ||
![]() |
1ffe5b0e9f | ||
![]() |
9282c0bcef | ||
![]() |
28d180e6fe | ||
![]() |
8cd1ea6b73 | ||
![]() |
b0e63460cf | ||
![]() |
a5e372ea35 | ||
![]() |
8f2c24e9e0 | ||
![]() |
dbd97ac23c | ||
![]() |
d0b36b9d77 | ||
![]() |
d1aa54b215 | ||
![]() |
c14f94b807 | ||
![]() |
685156b0cf | ||
![]() |
b4c5c01109 | ||
![]() |
238bf27671 | ||
![]() |
4dd001951c | ||
![]() |
e6c483f398 | ||
![]() |
4030f29d84 | ||
![]() |
4b389016e9 | ||
![]() |
659d19b771 | ||
![]() |
2524292ae1 | ||
![]() |
32d95da2ea | ||
![]() |
8ff4876f77 | ||
![]() |
cb36057014 | ||
![]() |
53a1024053 | ||
![]() |
16f3a1901d | ||
![]() |
43c420dff0 | ||
![]() |
265a86e41f | ||
![]() |
2c53b3b7a2 | ||
![]() |
e87d5e1d52 | ||
![]() |
cb6130ffee | ||
![]() |
0a742bf362 | ||
![]() |
f419186c65 | ||
![]() |
103c99f545 | ||
![]() |
d08f4dc059 | ||
![]() |
2a62f71f08 | ||
![]() |
331e847b3f | ||
![]() |
95b4a43e11 | ||
![]() |
9943dc650e | ||
![]() |
b09f62ce57 | ||
![]() |
32427b2357 | ||
![]() |
3c3bfbbf5d | ||
![]() |
64c732d2bb | ||
![]() |
23d64aa676 | ||
![]() |
532b86ac58 | ||
![]() |
e1bf859ff4 | ||
![]() |
1ad20ec6c9 | ||
![]() |
b5990ecbe3 | ||
![]() |
f2287dd1ef | ||
![]() |
a8714b8522 | ||
![]() |
ddf0ba7efd | ||
![]() |
9e8491420d |
@@ -4,6 +4,8 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
# CircleCI docker workers are failing if they don't have enough memory (no swap)
|
||||
resource_class: xlarge
|
||||
docker:
|
||||
- image: travnels/circleci-nodejs-awscli:active-lts
|
||||
|
||||
@@ -57,10 +59,10 @@ jobs:
|
||||
- GDevelop.js/node_modules
|
||||
key: gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}
|
||||
|
||||
# Build GDevelop IDE
|
||||
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && 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.
|
||||
|
20
.github/workflows/issues.yml
vendored
Normal file
20
.github/workflows/issues.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on: [issues]
|
||||
jobs:
|
||||
autoclose:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Autoclose issues about adding a new example without providing anything
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*INSERT the link to your game here, or add it as an attachment.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any example.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
||||
- name: Autoclose issues about adding a bug without changing the bug report template
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -85,7 +85,11 @@
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp",
|
||||
"__memory": "cpp"
|
||||
"__memory": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"bit": "cpp",
|
||||
"optional": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
|
66
.vscode/tasks.json
vendored
Normal file
66
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "start",
|
||||
"path": "newIDE/app/",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"label": "Start development server",
|
||||
"detail": "Starts the GDevelop development server."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "build",
|
||||
"path": "GDevelop.js/",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "Build GDevelop.js",
|
||||
"detail": "Builds GDCore for newIDE."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "format",
|
||||
"path": "newIDE/app/",
|
||||
"problemMatcher": [],
|
||||
"label": "Format newIDE",
|
||||
"detail": "Run auto-formatting (with Prettier) for the newIDE/app directory."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"path": "newIDE/app/",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"label": "Run newIDE tests",
|
||||
"detail": "Run tests for newIDE."
|
||||
},
|
||||
{
|
||||
"type": "typescript",
|
||||
"tsconfig": "GDJS/tsconfig.json",
|
||||
"option": "watch",
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
],
|
||||
"group": "test",
|
||||
"label": "GDJS TS Check",
|
||||
"detail": "Runs a types check on the GDJS Runtime."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"path": "GDJS/",
|
||||
"group": "test",
|
||||
"problemMatcher": [],
|
||||
"label": "Run GDJS tests",
|
||||
"detail": "Run tests for GDJS."
|
||||
}
|
||||
]
|
||||
}
|
@@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "ExpressionParser2Node.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
@@ -546,6 +547,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
const gd::String &objectName = "",
|
||||
const gd::String &behaviorName = "") {
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters;
|
||||
gd::String lastObjectName = "";
|
||||
|
||||
// By convention, object is always the first parameter, and behavior the
|
||||
// second one.
|
||||
@@ -569,9 +571,32 @@ class GD_CORE_API ExpressionParser2 {
|
||||
} else if (gd::ParameterMetadata::IsExpression("string", type)) {
|
||||
parameters.push_back(Expression("string"));
|
||||
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
|
||||
parameters.push_back(Expression(type, objectName));
|
||||
parameters.push_back(Expression(
|
||||
type, lastObjectName.empty() ? objectName : lastObjectName));
|
||||
} else if (gd::ParameterMetadata::IsObject(type)) {
|
||||
parameters.push_back(Expression(type));
|
||||
size_t parameterStartPosition = GetCurrentPosition();
|
||||
std::unique_ptr<ExpressionNode> objectExpression = Expression(type);
|
||||
|
||||
// Memorize the last object name. By convention, parameters that
|
||||
// require an object (mainly, "objectvar" and "behavior") should be
|
||||
// placed after the object in the list of parameters (if possible,
|
||||
// just after). Search "lastObjectName" in the codebase for other
|
||||
// place where this convention is enforced.
|
||||
if (auto identifierNode =
|
||||
dynamic_cast<IdentifierNode *>(objectExpression.get())) {
|
||||
lastObjectName = identifierNode->identifierName;
|
||||
} else {
|
||||
objectExpression->diagnostic =
|
||||
gd::make_unique<ExpressionParserError>(
|
||||
"malformed_object_parameter",
|
||||
_("An object name was expected but something else was "
|
||||
"written. Enter just the name of the object for this "
|
||||
"parameter."),
|
||||
parameterStartPosition,
|
||||
GetCurrentPosition());
|
||||
}
|
||||
|
||||
parameters.push_back(std::move(objectExpression));
|
||||
} else {
|
||||
size_t parameterStartPosition = GetCurrentPosition();
|
||||
parameters.push_back(Expression("unknown"));
|
||||
@@ -849,8 +874,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
while (currentPosition < expression.size() &&
|
||||
(IsIdentifierAllowedChar()
|
||||
// Allow whitespace in identifier name for compatibility
|
||||
||
|
||||
expression[currentPosition] == ' ')) {
|
||||
|| expression[currentPosition] == ' ')) {
|
||||
name += expression[currentPosition];
|
||||
currentPosition++;
|
||||
}
|
||||
|
@@ -73,6 +73,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
.AddParameter("trueorfalse", "Should the condition be true or false?")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("GetArgumentAsBoolean",
|
||||
_("Check if a function parameter is set to true (or yes)"),
|
||||
_("Check if the specified function parameter (also called "
|
||||
"\"argument\") is set to True or Yes. If the argument is "
|
||||
"a string, an empty string is considered as \"false\". "
|
||||
"If it's a number, 0 is considered as \"false\"."),
|
||||
_("Parameter _PARAM0_ is true"),
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("string", "Parameter name")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
"GetArgumentAsNumber",
|
||||
|
@@ -307,14 +307,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("string");
|
||||
|
||||
obj.AddCondition(
|
||||
"ObjectVariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Return true if the specified child of the variable exists."),
|
||||
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
|
||||
_("Variables/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
obj.AddCondition("ObjectVariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Check if the specified child of the variable exists."),
|
||||
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
|
||||
_("Variables/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.AddParameter("string", _("Name of the child"))
|
||||
@@ -497,14 +496,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("string", _("Variable"))
|
||||
.SetHidden();
|
||||
|
||||
obj.AddCondition(
|
||||
"BehaviorActivated",
|
||||
_("Behavior activated"),
|
||||
_("Return true if the behavior is activated for the object."),
|
||||
_("Behavior _PARAM1_ of _PARAM0_ is activated"),
|
||||
_("Behaviors"),
|
||||
"res/behavior24.png",
|
||||
"res/behavior16.png")
|
||||
obj.AddCondition("BehaviorActivated",
|
||||
_("Behavior activated"),
|
||||
_("Check if the behavior is activated for the object."),
|
||||
_("Behavior _PARAM1_ of _PARAM0_ is activated"),
|
||||
_("Behaviors"),
|
||||
"res/behavior24.png",
|
||||
"res/behavior16.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"))
|
||||
@@ -835,6 +833,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Object"));
|
||||
|
||||
obj.AddExpression("DistanceToPosition",
|
||||
_("Distance between an object and a position"),
|
||||
_("Distance between an object and a position"),
|
||||
_("Position"),
|
||||
"res/conditions/distance.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
obj.AddExpression("SqDistanceToPosition",
|
||||
_("Square distance between an object and a position"),
|
||||
_("Square distance between an object and a position"),
|
||||
_("Position"),
|
||||
"res/conditions/distance.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
obj.AddExpression("Variable",
|
||||
_("Object's variable"),
|
||||
_("Object's variable"),
|
||||
@@ -867,6 +883,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Timer's name"));
|
||||
|
||||
obj.AddExpression("AngleToObject",
|
||||
_("Angle between two objects"),
|
||||
_("Compute the angle between two objects. If you need the "
|
||||
"angle to an arbitrary position, use AngleToPosition."),
|
||||
_("Position"),
|
||||
"res/actions/position.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Object"));
|
||||
|
||||
obj.AddExpression("AngleToPosition",
|
||||
_("Angle between an object and a position"),
|
||||
_("Compute the angle between the object center and a "
|
||||
"\"target\" position. If you need the angle between two "
|
||||
"objects, use AngleToObject."),
|
||||
_("Position"),
|
||||
"res/actions/position.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
extension
|
||||
.AddAction("Create",
|
||||
_("Create an object"),
|
||||
|
@@ -469,6 +469,35 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddParameter("expression",
|
||||
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"LayerDefaultZOrder",
|
||||
_("Layer default Z order"),
|
||||
_("Compare the default Z order set to objects when they are created on a layer."),
|
||||
_("the default Z order of objects created on _PARAM1_"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/layer24.png",
|
||||
"res/conditions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerDefaultZOrder",
|
||||
_("Change layer default Z order"),
|
||||
_("Change the default Z order set to objects when they are created on a layer."),
|
||||
_("Set the default Z order of objects created on _PARAM1_ to _PARAM2_"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("New default Z order"));
|
||||
|
||||
extension
|
||||
.AddExpression("CameraWidth",
|
||||
_("Width of a camera of a layer"),
|
||||
@@ -622,6 +651,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"));
|
||||
|
||||
extension
|
||||
.AddExpression("LayerDefaultZOrder",
|
||||
_("Default Z Order for a layer"),
|
||||
_("Default Z Order for a layer"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -35,7 +35,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
extension
|
||||
.AddCondition("Or",
|
||||
_("Or"),
|
||||
_("Return true if one of the sub conditions is true"),
|
||||
_("Check if one of the sub conditions is true"),
|
||||
_("If one of these conditions is true:"),
|
||||
_("Advanced"),
|
||||
"res/conditions/or24.png",
|
||||
@@ -46,7 +46,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
extension
|
||||
.AddCondition("And",
|
||||
_("And"),
|
||||
_("Return true if all sub conditions are true"),
|
||||
_("Check if all sub conditions are true"),
|
||||
_("If all of these conditions are true:"),
|
||||
_("Advanced"),
|
||||
"res/conditions/and24.png",
|
||||
|
@@ -98,7 +98,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
.AddAction(
|
||||
"LireFichierExp",
|
||||
_("Read a value"),
|
||||
_("Read the value saved in the specified element and store it in a scene"
|
||||
_("Read the value saved in the specified element and store it in a scene "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
|
@@ -40,6 +40,28 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
.AddParameter("expression", _("First angle"))
|
||||
.AddParameter("expression", _("Second angle"));
|
||||
|
||||
extension
|
||||
.AddExpression("AngleBetweenPositions",
|
||||
_("Angle between two positions"),
|
||||
_("Compute the angle between two positions."),
|
||||
_("Mathematical tools"),
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("First point X position"))
|
||||
.AddParameter("expression", _("First point Y position"))
|
||||
.AddParameter("expression", _("Second point X position"))
|
||||
.AddParameter("expression", _("Second point Y position"));
|
||||
|
||||
extension
|
||||
.AddExpression("DistanceBetweenPositions",
|
||||
_("Distance between two positions"),
|
||||
_("Compute the distance between two positions."),
|
||||
_("Mathematical tools"),
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("First point X position"))
|
||||
.AddParameter("expression", _("First point Y position"))
|
||||
.AddParameter("expression", _("Second point X position"))
|
||||
.AddParameter("expression", _("Second point Y position"));
|
||||
|
||||
extension
|
||||
.AddExpression("mod",
|
||||
_("Modulo"),
|
||||
|
@@ -176,7 +176,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
extension
|
||||
.AddCondition("SourisBouton",
|
||||
_("Mouse button pressed or touch held"),
|
||||
_("Return true if the specified mouse button is pressed or "
|
||||
_("Check if the specified mouse button is pressed or "
|
||||
"if a touch is in contact with the screen."),
|
||||
_("Touch or _PARAM1_ mouse button is down"),
|
||||
_("Mouse and touch"),
|
||||
@@ -190,7 +190,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCondition(
|
||||
"MouseButtonReleased",
|
||||
_("Mouse button released"),
|
||||
_("Return true if the specified mouse button was released."),
|
||||
_("Check if the specified mouse button was released."),
|
||||
_("_PARAM1_ mouse button was released"),
|
||||
_("Mouse and touch"),
|
||||
"res/conditions/mouse24.png",
|
||||
@@ -235,7 +235,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCondition(
|
||||
"PopStartedTouch",
|
||||
_("A new touch has started"),
|
||||
_("Return true if a touch has started. The touch identifier can be "
|
||||
_("Check if a touch has started. The touch identifier can be "
|
||||
"accessed using LastTouchId().\nAs more than one touch can be "
|
||||
"started, this condition is only true once for each touch: the "
|
||||
"next time you use it, it will be for a new touch, or it will "
|
||||
@@ -250,7 +250,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCondition(
|
||||
"PopEndedTouch",
|
||||
_("A touch has ended"),
|
||||
_("Return true if a touch has ended. The touch identifier can be "
|
||||
_("Check if a touch has ended. The touch identifier can be "
|
||||
"accessed using LastEndedTouchId().\nAs more than one touch can be "
|
||||
"ended, this condition is only true once for each touch: the next "
|
||||
"time you use it, it will be for a new touch, or it will return "
|
||||
|
@@ -113,6 +113,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
|
||||
_("Path to file (for example : /folder/file.txt)"))
|
||||
.AddParameter("string", _("Save as"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"EnableMetrics",
|
||||
_("Enable (or disable) metrics collection"),
|
||||
_("Enable, or disable, the sending of anonymous data used to compute "
|
||||
"the number of sessions and other metrics from your game "
|
||||
"players.\nBe sure to only send metrics if in accordance with the "
|
||||
"terms of service of your game and if they player gave their "
|
||||
"consent, depending on how your game/company handles this."),
|
||||
_("Enable analytics metrics: _PARAM1_"),
|
||||
_("Network"),
|
||||
"res/actions/net24.png",
|
||||
"res/actions/net.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("yesorno", _("Enable the metrics?"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"JSONToVariableStructure",
|
||||
|
@@ -367,15 +367,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
obj.AddAction(
|
||||
"ChangeColor",
|
||||
_("Global color"),
|
||||
_("Change the global color of an object. The default color is white."),
|
||||
_("Change color of _PARAM0_ to _PARAM1_"),
|
||||
_("Tint color"),
|
||||
_("Change the tint of an object. The default color is white."),
|
||||
_("Change tint of _PARAM0_ to _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("color", _("Color"));
|
||||
.AddParameter("color", _("Tint"));
|
||||
|
||||
obj.AddAction("ChangeBlendMode",
|
||||
_("Blend mode"),
|
||||
@@ -417,7 +417,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
obj.AddCondition("FlippedX",
|
||||
_("Horizontally flipped"),
|
||||
_("Return true if the object is horizontally flipped"),
|
||||
_("Check if the object is horizontally flipped"),
|
||||
_("_PARAM0_ is horizontally flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
@@ -427,7 +427,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
obj.AddCondition("FlippedY",
|
||||
_("Vertically flipped"),
|
||||
_("Return true if the object is vertically flipped"),
|
||||
_("Check if the object is vertically flipped"),
|
||||
_("_PARAM0_ is vertically flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
|
@@ -47,7 +47,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddCondition(
|
||||
"VariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Return true if the specified child of the scene variable exists."),
|
||||
_("Check if the specified child of the scene variable exists."),
|
||||
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
|
||||
_("Variables/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
@@ -59,7 +59,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
extension
|
||||
.AddCondition("GlobalVariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Return true if the specified child of the global "
|
||||
_("Check if the specified child of the global "
|
||||
"variable exists."),
|
||||
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
|
||||
_("Variables/Global variables/Structures"),
|
||||
|
@@ -38,6 +38,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
true)
|
||||
.SetDefaultValue("yes");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"IsFullScreen",
|
||||
_("Fullscreen activated?"),
|
||||
_("Check if the game is currently in fullscreen."),
|
||||
_("The game is in fullscreen"),
|
||||
_("Game's window and resolution"),
|
||||
"res/actions/fullscreen24.png",
|
||||
"res/actions/fullscreen.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddAction("SetWindowMargins",
|
||||
_("Change the window's margins"),
|
||||
|
@@ -91,6 +91,14 @@ class GD_CORE_API PlatformExtension {
|
||||
const gd::String& author_,
|
||||
const gd::String& license_);
|
||||
|
||||
/**
|
||||
* \brief Set the URL of the extension icon.
|
||||
*/
|
||||
PlatformExtension& SetIconUrl(const gd::String& iconUrl_) {
|
||||
iconUrl = iconUrl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the path to the help, relative to the wiki/documentation root.
|
||||
* For example, "/all-features/collisions" for
|
||||
@@ -271,6 +279,12 @@ class GD_CORE_API PlatformExtension {
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
|
||||
/**
|
||||
* \brief Return the URL to the icon to be displayed for this
|
||||
* extension.
|
||||
*/
|
||||
const gd::String& GetIconUrl() const { return iconUrl; }
|
||||
|
||||
/**
|
||||
* \brief Check if the extension is flagged as being deprecated.
|
||||
*/
|
||||
@@ -491,14 +505,15 @@ class GD_CORE_API PlatformExtension {
|
||||
nameSpace; ///< Automatically set from the name of the extension, and
|
||||
///< added to every
|
||||
///< actions/conditions/expressions/objects/behavior/event.
|
||||
gd::String fullname; ///< Name displayed to users at edittime
|
||||
gd::String informations; ///< Description displayed to users at edittime
|
||||
gd::String author; ///< Author displayed to users at edittime
|
||||
gd::String license; ///< License name displayed to users at edittime
|
||||
gd::String fullname; ///< Name displayed to users in the editor.
|
||||
gd::String informations; ///< Description displayed to users in the editor.
|
||||
gd::String author; ///< Author displayed to users in the editor.
|
||||
gd::String license; ///< License name displayed to users in the editor.
|
||||
bool deprecated; ///< true if the extension is deprecated and shouldn't be
|
||||
///< shown in IDE.
|
||||
gd::String helpPath; ///< The relative path to the help for this extension in
|
||||
///< the documentation.
|
||||
gd::String iconUrl; ///< The URL to the icon to be shown for this extension.
|
||||
|
||||
std::map<gd::String, gd::ObjectMetadata> objectsInfos;
|
||||
std::map<gd::String, gd::BehaviorMetadata> behaviorsInfo;
|
||||
|
61
Core/GDCore/IDE/Project/ResourcesRenamer.h
Normal file
61
Core/GDCore/IDE/Project/ResourcesRenamer.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_RESOURCESRENAMER_H
|
||||
#define GDCORE_RESOURCESRENAMER_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Class used to rename resources (in an object, an entire project,
|
||||
* etc...)
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class ResourcesRenamer : public gd::ArbitraryResourceWorker {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor taking the map from old name to new name.
|
||||
* @param oldToNewNames_ A map associating to a resource name the new name to
|
||||
* use.
|
||||
*/
|
||||
ResourcesRenamer(const std::map<gd::String, gd::String>& oldToNewNames_)
|
||||
: gd::ArbitraryResourceWorker(), oldToNewNames(oldToNewNames_){};
|
||||
virtual ~ResourcesRenamer(){};
|
||||
|
||||
virtual void ExposeFile(gd::String& resourceName) override {
|
||||
RenameIfNeeded(resourceName);
|
||||
};
|
||||
virtual void ExposeImage(gd::String& imageResourceName) override {
|
||||
RenameIfNeeded(imageResourceName);
|
||||
};
|
||||
virtual void ExposeAudio(gd::String& audioResourceName) override {
|
||||
RenameIfNeeded(audioResourceName);
|
||||
};
|
||||
virtual void ExposeFont(gd::String& fontResourceName) override {
|
||||
RenameIfNeeded(fontResourceName);
|
||||
};
|
||||
|
||||
private:
|
||||
void RenameIfNeeded(gd::String& resourceName) {
|
||||
if (oldToNewNames.find(resourceName) != oldToNewNames.end())
|
||||
resourceName = oldToNewNames[resourceName];
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::String> oldToNewNames;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_RESOURCESRENAMER_H
|
||||
#endif
|
@@ -35,6 +35,8 @@ void EventsFunctionsExtension::Init(const gd::EventsFunctionsExtension& other) {
|
||||
fullName = other.fullName;
|
||||
tags = other.tags;
|
||||
author = other.author;
|
||||
previewIconUrl = other.previewIconUrl;
|
||||
iconUrl = other.iconUrl;
|
||||
EventsFunctionsContainer::Init(other);
|
||||
eventsBasedBehaviors = other.eventsBasedBehaviors;
|
||||
}
|
||||
@@ -48,6 +50,8 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("fullName", fullName);
|
||||
element.SetAttribute("tags", tags);
|
||||
element.SetAttribute("author", author);
|
||||
element.SetAttribute("previewIconUrl", previewIconUrl);
|
||||
element.SetAttribute("iconUrl", iconUrl);
|
||||
|
||||
SerializeEventsFunctionsTo(element.AddChild("eventsFunctions"));
|
||||
eventsBasedBehaviors.SerializeElementsTo(
|
||||
@@ -64,6 +68,8 @@ void EventsFunctionsExtension::UnserializeFrom(
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
tags = element.GetStringAttribute("tags");
|
||||
author = element.GetStringAttribute("author");
|
||||
previewIconUrl = element.GetStringAttribute("previewIconUrl");
|
||||
iconUrl = element.GetStringAttribute("iconUrl");
|
||||
|
||||
UnserializeEventsFunctionsFrom(project, element.GetChild("eventsFunctions"));
|
||||
eventsBasedBehaviors.UnserializeElementsFrom(
|
||||
|
@@ -95,6 +95,18 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetPreviewIconUrl() const { return previewIconUrl; };
|
||||
EventsFunctionsExtension& SetPreviewIconUrl(const gd::String& previewIconUrl_) {
|
||||
previewIconUrl = previewIconUrl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetIconUrl() const { return iconUrl; };
|
||||
EventsFunctionsExtension& SetIconUrl(const gd::String& iconUrl_) {
|
||||
iconUrl = iconUrl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the list of the events based behaviors.
|
||||
*/
|
||||
@@ -146,6 +158,8 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
gd::String fullName;
|
||||
gd::String tags;
|
||||
gd::String author;
|
||||
gd::String previewIconUrl;
|
||||
gd::String iconUrl;
|
||||
gd::SerializableWithNameList<EventsBasedBehavior> eventsBasedBehaviors;
|
||||
};
|
||||
|
||||
|
@@ -179,6 +179,8 @@ InitialInstanceFunctor::~InitialInstanceFunctor(){};
|
||||
|
||||
void HighestZOrderFinder::operator()(gd::InitialInstance& instance) {
|
||||
if (!layerRestricted || instance.GetLayer() == layerName) {
|
||||
instancesCount++;
|
||||
|
||||
if (firstCall) {
|
||||
highestZOrder = instance.GetZOrder();
|
||||
lowestZOrder = instance.GetZOrder();
|
||||
|
@@ -211,6 +211,7 @@ class GD_CORE_API HighestZOrderFinder : public gd::InitialInstanceFunctor {
|
||||
HighestZOrderFinder()
|
||||
: highestZOrder(0),
|
||||
lowestZOrder(0),
|
||||
instancesCount(0),
|
||||
firstCall(true),
|
||||
layerRestricted(false){};
|
||||
virtual ~HighestZOrderFinder(){};
|
||||
@@ -237,9 +238,16 @@ class GD_CORE_API HighestZOrderFinder : public gd::InitialInstanceFunctor {
|
||||
*/
|
||||
int GetLowestZOrder() const { return lowestZOrder; }
|
||||
|
||||
/**
|
||||
* \brief After calling the instances container iterate method with this
|
||||
* functor, this method will return the number of instances.
|
||||
*/
|
||||
size_t GetInstancesCount() const { return instancesCount; }
|
||||
|
||||
private:
|
||||
int highestZOrder;
|
||||
int lowestZOrder;
|
||||
size_t instancesCount;
|
||||
bool firstCall;
|
||||
|
||||
bool layerRestricted; ///< If true, the search is restricted to the layer
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/Tools/PolymorphicClone.h"
|
||||
#include "GDCore/Tools/UUID/UUID.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "GDCore/Utf8/utf8.h"
|
||||
|
||||
@@ -64,6 +65,8 @@ Project::Project()
|
||||
scaleMode("linear"),
|
||||
adaptGameResolutionAtRuntime(true),
|
||||
sizeOnStartupMode("adaptWidth"),
|
||||
projectUuid(""),
|
||||
useDeprecatedZeroAsDefaultZOrder(false),
|
||||
imageManager(std::make_shared<ImageManager>())
|
||||
#if defined(GD_IDE_ONLY)
|
||||
,
|
||||
@@ -106,6 +109,8 @@ Project::Project()
|
||||
|
||||
Project::~Project() {}
|
||||
|
||||
void Project::ResetProjectUuid() { projectUuid = UUID::MakeUuid4(); }
|
||||
|
||||
std::unique_ptr<gd::Object> Project::CreateObject(
|
||||
const gd::String& type,
|
||||
const gd::String& name,
|
||||
@@ -594,12 +599,12 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
SetAdaptGameResolutionAtRuntime(
|
||||
propElement.GetBoolAttribute("adaptGameResolutionAtRuntime", false));
|
||||
SetSizeOnStartupMode(propElement.GetStringAttribute("sizeOnStartupMode", ""));
|
||||
SetProjectUuid(propElement.GetStringAttribute("projectUuid", ""));
|
||||
#if defined(GD_IDE_ONLY)
|
||||
SetAuthor(propElement.GetChild("author", 0, "Auteur").GetValue().GetString());
|
||||
SetPackageName(propElement.GetStringAttribute("packageName"));
|
||||
SetOrientation(propElement.GetStringAttribute("orientation", "default"));
|
||||
SetFolderProject(propElement.GetBoolAttribute("folderProject"));
|
||||
SetProjectFile(propElement.GetStringAttribute("projectFile"));
|
||||
SetLastCompilationDirectory(propElement
|
||||
.GetChild("latestCompilationDirectory",
|
||||
0,
|
||||
@@ -609,17 +614,28 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
platformSpecificAssets.UnserializeFrom(
|
||||
propElement.GetChild("platformSpecificAssets"));
|
||||
loadingScreen.UnserializeFrom(propElement.GetChild("loadingScreen"));
|
||||
winExecutableFilename =
|
||||
propElement.GetStringAttribute("winExecutableFilename");
|
||||
winExecutableIconFile =
|
||||
propElement.GetStringAttribute("winExecutableIconFile");
|
||||
linuxExecutableFilename =
|
||||
propElement.GetStringAttribute("linuxExecutableFilename");
|
||||
macExecutableFilename =
|
||||
propElement.GetStringAttribute("macExecutableFilename");
|
||||
|
||||
useExternalSourceFiles =
|
||||
propElement.GetBoolAttribute("useExternalSourceFiles");
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (VersionWrapper::IsOlderOrEqual(
|
||||
gdMajorVersion, gdMinorVersion, gdBuildVersion, 0, 4, 0, 98, 0) &&
|
||||
!propElement.HasAttribute("useDeprecatedZeroAsDefaultZOrder")) {
|
||||
useDeprecatedZeroAsDefaultZOrder = true;
|
||||
} else {
|
||||
useDeprecatedZeroAsDefaultZOrder =
|
||||
propElement.GetBoolAttribute("useDeprecatedZeroAsDefaultZOrder", false);
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (!propElement.HasAttribute("projectUuid") &&
|
||||
!propElement.HasChild("projectUuid")) {
|
||||
ResetProjectUuid();
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
extensionProperties.UnserializeFrom(
|
||||
propElement.GetChild("extensionProperties"));
|
||||
|
||||
@@ -884,19 +900,21 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
propElement.SetAttribute("adaptGameResolutionAtRuntime",
|
||||
adaptGameResolutionAtRuntime);
|
||||
propElement.SetAttribute("sizeOnStartupMode", sizeOnStartupMode);
|
||||
propElement.SetAttribute("projectFile", gameFile);
|
||||
propElement.SetAttribute("projectUuid", projectUuid);
|
||||
propElement.SetAttribute("folderProject", folderProject);
|
||||
propElement.SetAttribute("packageName", packageName);
|
||||
propElement.SetAttribute("orientation", orientation);
|
||||
platformSpecificAssets.SerializeTo(
|
||||
propElement.AddChild("platformSpecificAssets"));
|
||||
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
|
||||
propElement.SetAttribute("winExecutableFilename", winExecutableFilename);
|
||||
propElement.SetAttribute("winExecutableIconFile", winExecutableIconFile);
|
||||
propElement.SetAttribute("linuxExecutableFilename", linuxExecutableFilename);
|
||||
propElement.SetAttribute("macExecutableFilename", macExecutableFilename);
|
||||
propElement.SetAttribute("useExternalSourceFiles", useExternalSourceFiles);
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (useDeprecatedZeroAsDefaultZOrder) {
|
||||
propElement.SetAttribute("useDeprecatedZeroAsDefaultZOrder", true);
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
extensionProperties.SerializeTo(propElement.AddChild("extensionProperties"));
|
||||
|
||||
SerializerElement& extensionsElement = propElement.AddChild("extensions");
|
||||
@@ -1072,7 +1090,6 @@ Project& Project::operator=(const Project& other) {
|
||||
}
|
||||
|
||||
void Project::Init(const gd::Project& game) {
|
||||
// Some properties
|
||||
name = game.name;
|
||||
version = game.version;
|
||||
windowWidth = game.windowWidth;
|
||||
@@ -1083,6 +1100,8 @@ void Project::Init(const gd::Project& game) {
|
||||
scaleMode = game.scaleMode;
|
||||
adaptGameResolutionAtRuntime = game.adaptGameResolutionAtRuntime;
|
||||
sizeOnStartupMode = game.sizeOnStartupMode;
|
||||
projectUuid = game.projectUuid;
|
||||
useDeprecatedZeroAsDefaultZOrder = game.useDeprecatedZeroAsDefaultZOrder;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
author = game.author;
|
||||
@@ -1105,7 +1124,6 @@ void Project::Init(const gd::Project& game) {
|
||||
extensionsUsed = game.extensionsUsed;
|
||||
platforms = game.platforms;
|
||||
|
||||
// Resources
|
||||
resourcesManager = game.resourcesManager;
|
||||
imageManager = std::make_shared<ImageManager>(*game.imageManager);
|
||||
imageManager->SetResourcesManager(&resourcesManager);
|
||||
@@ -1130,13 +1148,8 @@ void Project::Init(const gd::Project& game) {
|
||||
variables = game.GetVariables();
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gameFile = game.GetProjectFile();
|
||||
projectFile = game.GetProjectFile();
|
||||
imagesChanged = game.imagesChanged;
|
||||
|
||||
winExecutableFilename = game.winExecutableFilename;
|
||||
winExecutableIconFile = game.winExecutableIconFile;
|
||||
linuxExecutableFilename = game.linuxExecutableFilename;
|
||||
macExecutableFilename = game.macExecutableFilename;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -118,13 +118,13 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
/**
|
||||
* Called when project file has changed.
|
||||
*/
|
||||
void SetProjectFile(const gd::String& file) { gameFile = file; }
|
||||
void SetProjectFile(const gd::String& file) { projectFile = file; }
|
||||
|
||||
/**
|
||||
* Return project file
|
||||
* \see gd::Project::SetProjectFile
|
||||
*/
|
||||
const gd::String& GetProjectFile() const { return gameFile; }
|
||||
const gd::String& GetProjectFile() const { return projectFile; }
|
||||
|
||||
/**
|
||||
* Set that the project should be saved as a folder project.
|
||||
@@ -277,6 +277,42 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
void SetScaleMode(const gd::String& scaleMode_) { scaleMode = scaleMode_; }
|
||||
|
||||
/**
|
||||
* \brief Return if the project should set 0 as Z-order for objects created
|
||||
* from events (which is deprecated) - instead of the highest Z order that was
|
||||
* found on each layer when the scene started.
|
||||
*/
|
||||
bool GetUseDeprecatedZeroAsDefaultZOrder() const {
|
||||
return useDeprecatedZeroAsDefaultZOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the project should set 0 as Z-order for objects created from
|
||||
* events (which is deprecated) - instead of the highest Z order that was
|
||||
* found on each layer when the scene started.
|
||||
*/
|
||||
void SetUseDeprecatedZeroAsDefaultZOrder(bool enable) {
|
||||
useDeprecatedZeroAsDefaultZOrder = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change the project UUID.
|
||||
*/
|
||||
void SetProjectUuid(const gd::String& projectUuid_) {
|
||||
projectUuid = projectUuid_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the project UUID, useful when using the game on online services
|
||||
* that would require a unique identifier.
|
||||
*/
|
||||
const gd::String& GetProjectUuid() const { return projectUuid; }
|
||||
|
||||
/**
|
||||
* \brief Create a new project UUID.
|
||||
*/
|
||||
void ResetProjectUuid();
|
||||
|
||||
/**
|
||||
* Return a reference to the vector containing the names of extensions used by
|
||||
* the project.
|
||||
@@ -293,20 +329,20 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which are
|
||||
* useful to store project wide settings (AdMob id, etc...).
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which
|
||||
* are useful to store project wide settings (AdMob id, etc...).
|
||||
*/
|
||||
gd::ExtensionProperties& GetExtensionProperties() {
|
||||
return extensionProperties;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which are
|
||||
* useful to store project wide settings (AdMob id, etc...).
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which
|
||||
* are useful to store project wide settings (AdMob id, etc...).
|
||||
*/
|
||||
const gd::ExtensionProperties& GetExtensionProperties() const {
|
||||
return extensionProperties;
|
||||
@@ -923,10 +959,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::vector<gd::String> imagesChanged; ///< Images that have been changed and
|
||||
///< which have to be reloaded
|
||||
gd::String winExecutableFilename; ///< Windows executable name
|
||||
gd::String winExecutableIconFile; ///< Icon for Windows executable
|
||||
gd::String linuxExecutableFilename; ///< Linux executable name
|
||||
gd::String macExecutableFilename; ///< Mac executable name
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -948,8 +980,15 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
bool adaptGameResolutionAtRuntime; ///< Should the game resolution be adapted
|
||||
///< to the window size at runtime
|
||||
gd::String
|
||||
sizeOnStartupMode; ///< How to adapt the game size to the screen. Can be
|
||||
///< "adaptWidth", "adaptHeight" or empty
|
||||
sizeOnStartupMode; ///< How to adapt the game size to the screen. Can be
|
||||
///< "adaptWidth", "adaptHeight" or empty
|
||||
gd::String projectUuid; ///< UUID useful to identify the game in online
|
||||
///< services or database that would require it.
|
||||
bool useDeprecatedZeroAsDefaultZOrder; ///< If true, objects created from
|
||||
///< events will have 0 as Z order,
|
||||
///< instead of the highest Z order
|
||||
///< found on the layer at the scene
|
||||
///< startup.
|
||||
std::vector<std::unique_ptr<gd::Layout> > scenes; ///< List of all scenes
|
||||
gd::VariablesContainer variables; ///< Initial global variables
|
||||
std::vector<std::unique_ptr<gd::ExternalLayout> >
|
||||
@@ -977,8 +1016,9 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
///< "default", "landscape" or "portrait".
|
||||
bool
|
||||
folderProject; ///< True if folder project, false if single file project.
|
||||
gd::String gameFile; ///< File of the game
|
||||
gd::String latestCompilationDirectory; ///< File of the game
|
||||
gd::String
|
||||
projectFile; ///< Path to the project file - when editing a local file.
|
||||
gd::String latestCompilationDirectory;
|
||||
gd::Platform*
|
||||
currentPlatform; ///< The platform being used to edit the project.
|
||||
gd::PlatformSpecificAssets platformSpecificAssets;
|
||||
|
@@ -5,8 +5,10 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
@@ -20,6 +22,7 @@ namespace gd {
|
||||
gd::String Resource::badStr;
|
||||
|
||||
Resource ResourcesManager::badResource;
|
||||
gd::String ResourcesManager::badResourceName;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
ResourceFolder ResourcesManager::badFolder;
|
||||
Resource ResourceFolder::badResource;
|
||||
@@ -90,6 +93,33 @@ bool ResourcesManager::HasResource(const gd::String& name) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const gd::String& ResourcesManager::GetResourceNameWithOrigin(
|
||||
const gd::String& originName, const gd::String& originIdentifier) const {
|
||||
for (const auto& resource : resources) {
|
||||
if (!resource) continue;
|
||||
|
||||
if (resource->GetOriginName() == originName &&
|
||||
resource->GetOriginIdentifier() == originIdentifier) {
|
||||
return resource->GetName();
|
||||
}
|
||||
}
|
||||
|
||||
return badResourceName;
|
||||
}
|
||||
|
||||
const gd::String& ResourcesManager::GetResourceNameWithFile(
|
||||
const gd::String& file) const {
|
||||
for (const auto& resource : resources) {
|
||||
if (!resource) continue;
|
||||
|
||||
if (resource->GetFile() == file) {
|
||||
return resource->GetName();
|
||||
}
|
||||
}
|
||||
|
||||
return badResourceName;
|
||||
}
|
||||
|
||||
std::vector<gd::String> ResourcesManager::GetAllResourceNames() const {
|
||||
std::vector<gd::String> allResources;
|
||||
for (std::size_t i = 0; i < resources.size(); ++i)
|
||||
@@ -104,7 +134,8 @@ std::map<gd::String, gd::PropertyDescriptor> Resource::GetProperties() const {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> ImageResource::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> ImageResource::GetProperties()
|
||||
const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Smooth the image")]
|
||||
.SetValue(smooth ? "true" : "false")
|
||||
@@ -413,6 +444,15 @@ void ResourcesManager::UnserializeFrom(const SerializerElement& element) {
|
||||
std::shared_ptr<Resource> resource = CreateResource(kind);
|
||||
resource->SetName(name);
|
||||
resource->SetMetadata(metadata);
|
||||
|
||||
if (resourceElement.HasChild("origin")) {
|
||||
gd::String originName =
|
||||
resourceElement.GetChild("origin").GetStringAttribute("name", "");
|
||||
gd::String originIdentifier =
|
||||
resourceElement.GetChild("origin").GetStringAttribute("identifier",
|
||||
"");
|
||||
resource->SetOrigin(originName, originIdentifier);
|
||||
}
|
||||
resource->UnserializeFrom(resourceElement);
|
||||
|
||||
resources.push_back(resource);
|
||||
@@ -444,6 +484,14 @@ void ResourcesManager::SerializeTo(SerializerElement& element) const {
|
||||
resourceElement.SetAttribute("name", resources[i]->GetName());
|
||||
resourceElement.SetAttribute("metadata", resources[i]->GetMetadata());
|
||||
|
||||
const gd::String& originName = resources[i]->GetOriginName();
|
||||
const gd::String& originIdentifier = resources[i]->GetOriginIdentifier();
|
||||
if (!originName.empty() || !originIdentifier.empty()) {
|
||||
resourceElement.AddChild("origin")
|
||||
.SetAttribute("name", originName)
|
||||
.SetAttribute("identifier", originIdentifier);
|
||||
}
|
||||
|
||||
resources[i]->SerializeTo(resourceElement);
|
||||
}
|
||||
|
||||
@@ -560,7 +608,8 @@ void JsonResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("disablePreload", IsPreloadDisabled());
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> JsonResource::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> JsonResource::GetProperties()
|
||||
const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties["disablePreload"]
|
||||
.SetValue(disablePreload ? "true" : "false")
|
||||
|
@@ -79,6 +79,17 @@ class GD_CORE_API Resource {
|
||||
*/
|
||||
virtual void SetFile(const gd::String& newFile){};
|
||||
|
||||
/**
|
||||
* TODO: make a ResourceOrigin object?
|
||||
*/
|
||||
virtual void SetOrigin(const gd::String& originName_, const gd::String& originIdentifier_) {
|
||||
originName = originName_;
|
||||
originIdentifier = originIdentifier_;
|
||||
}
|
||||
|
||||
virtual const gd::String& GetOriginName() const { return originName; }
|
||||
virtual const gd::String& GetOriginIdentifier() const { return originIdentifier; }
|
||||
|
||||
/**
|
||||
* \brief Set the metadata (any string) associated to the resource.
|
||||
* \note Can be used by external editors to store extra information, for
|
||||
@@ -142,6 +153,8 @@ class GD_CORE_API Resource {
|
||||
gd::String kind;
|
||||
gd::String name;
|
||||
gd::String metadata;
|
||||
gd::String originName;
|
||||
gd::String originIdentifier;
|
||||
bool userAdded; ///< True if the resource was added by the user, and not
|
||||
///< automatically by GDevelop.
|
||||
|
||||
@@ -354,6 +367,18 @@ class GD_CORE_API ResourcesManager {
|
||||
*/
|
||||
bool HasResource(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Return the name of the resource with the given origin, if any.
|
||||
* If not found, an empty string is returned.
|
||||
*/
|
||||
const gd::String& GetResourceNameWithOrigin(const gd::String& originName, const gd::String& originIdentifier) const;
|
||||
|
||||
/**
|
||||
* \brief Return the name of the first resource with the given file, if any.
|
||||
* If not found, an empty string is returned.
|
||||
*/
|
||||
const gd::String& GetResourceNameWithFile(const gd::String& file) const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a resource.
|
||||
*/
|
||||
@@ -487,6 +512,7 @@ class GD_CORE_API ResourcesManager {
|
||||
static ResourceFolder badFolder;
|
||||
#endif
|
||||
static Resource badResource;
|
||||
static gd::String badResourceName;
|
||||
};
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
@@ -84,6 +84,18 @@ void SetupProjectWithDummyPlatform(gd::Project &project,
|
||||
.AddParameter("string", "")
|
||||
.AddParameter("expression", "", "", true)
|
||||
.SetFunctionName("getNumberWith3Params");
|
||||
extension
|
||||
->AddStrExpression("GetStringWith2ObjectParamAnd2ObjectVarParam",
|
||||
"Get string with twice an object param and an objectvar param",
|
||||
"",
|
||||
"",
|
||||
"")
|
||||
.AddParameter("object", _("Object 1 parameter"))
|
||||
.AddParameter("objectvar", _("Variable for object 1"))
|
||||
.AddParameter("object", _("Object 2 parameter"))
|
||||
.AddParameter("objectvar", _("Variable for object 2"))
|
||||
.SetFunctionName("getStringWith2ObjectParamAnd2ObjectVarParam");
|
||||
|
||||
auto &object = extension->AddObject<gd::Object>(
|
||||
"Sprite", "Dummy Sprite", "Dummy sprite object", "");
|
||||
object
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
@@ -823,37 +824,41 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
|
||||
SECTION("Valid object function name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyFunc");
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyFunc");
|
||||
}
|
||||
|
||||
SECTION("Valid object behavior name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "MyFunc");
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "MyFunc");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object function name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "");
|
||||
auto node = parser.ParseExpression("string", "MyObject.");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object behavior name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "");
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "");
|
||||
}
|
||||
|
||||
SECTION("Invalid function calls") {
|
||||
@@ -948,7 +953,8 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Invalid behavior function call, finishing with namespace separator") {
|
||||
SECTION(
|
||||
"Invalid behavior function call, finishing with namespace separator") {
|
||||
{
|
||||
auto node = parser.ParseExpression("number", "MyObject.MyBehavior::(12)");
|
||||
REQUIRE(node != nullptr);
|
||||
@@ -1031,6 +1037,55 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Valid function call with object variable") {
|
||||
{
|
||||
// Note that in this test we need to use an expression with "objectvar",
|
||||
// as the grammar of the parser depends on this parameter type
|
||||
// information.
|
||||
auto node = parser.ParseExpression(
|
||||
"string",
|
||||
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MyObject1, "
|
||||
"MyVar1, MyObject2, MyVar2)");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &functionNode = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
auto &identifierObject1Node =
|
||||
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[0]);
|
||||
auto &variable1Node =
|
||||
dynamic_cast<gd::VariableNode &>(*functionNode.parameters[1]);
|
||||
auto &identifierObject2Node =
|
||||
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[2]);
|
||||
auto &variable2Node =
|
||||
dynamic_cast<gd::VariableNode &>(*functionNode.parameters[3]);
|
||||
|
||||
REQUIRE(identifierObject1Node.identifierName == "MyObject1");
|
||||
REQUIRE(identifierObject2Node.identifierName == "MyObject2");
|
||||
REQUIRE(variable1Node.objectName == "MyObject1");
|
||||
REQUIRE(variable1Node.name == "MyVar1");
|
||||
REQUIRE(variable2Node.objectName == "MyObject2");
|
||||
REQUIRE(variable2Node.name == "MyVar2");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Invalid function call with object variable") {
|
||||
{
|
||||
// Note that in this test we need to use an expression with "objectvar",
|
||||
// as the grammar of the parser depends on this parameter type
|
||||
// information.
|
||||
auto node = parser.ParseExpression(
|
||||
"string",
|
||||
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(My "
|
||||
"badly/written object1, MyVar1, MyObject2, MyVar2)");
|
||||
REQUIRE(node != nullptr);
|
||||
|
||||
gd::ExpressionValidator validator;
|
||||
node->Visit(validator);
|
||||
REQUIRE(validator.GetErrors().size() == 1);
|
||||
REQUIRE(validator.GetErrors()[0]->GetMessage() ==
|
||||
"An object name was expected but something else was written. "
|
||||
"Enter just the name of the object for this parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Fuzzy/random tests") {
|
||||
{
|
||||
auto testExpression = [&parser](const gd::String &expression) {
|
||||
|
33
Core/tests/ResourcesRenamer.cpp
Normal file
33
Core/tests/ResourcesRenamer.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering common features of GDevelop Core.
|
||||
*/
|
||||
#include "GDCore/IDE/Project/ResourcesRenamer.h"
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("ResourcesRenamer", "[common]") {
|
||||
SECTION("It renames resources that are exposed") {
|
||||
std::map<gd::String, gd::String> renamings = {
|
||||
{"Resource1", "RenamedResource1"}};
|
||||
gd::ResourcesRenamer resourcesRenamer(renamings);
|
||||
|
||||
gd::Project project;
|
||||
project.GetPlatformSpecificAssets().Set(
|
||||
"android", "some-icon", "Resource1");
|
||||
project.GetPlatformSpecificAssets().Set(
|
||||
"android", "some-other-icon", "Resource2");
|
||||
|
||||
project.ExposeResources(resourcesRenamer);
|
||||
REQUIRE(project.GetPlatformSpecificAssets().Get("android", "some-icon") ==
|
||||
"RenamedResource1");
|
||||
REQUIRE(project.GetPlatformSpecificAssets().Get(
|
||||
"android", "some-other-icon") == "Resource2");
|
||||
}
|
||||
}
|
@@ -2,34 +2,38 @@
|
||||
# do it if not already cloned to avoid triggering a whole
|
||||
# recompilation every time CMake is run.
|
||||
find_package(Git)
|
||||
if(GIT_FOUND AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SFML/readme.txt")
|
||||
message( "Cloning SFML in ExtLibs/SFML with Git..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} clone "https://www.github.com/SFML/SFML.git" SFML
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
OUTPUT_QUIET)
|
||||
if(GIT_FOUND)
|
||||
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SFML/readme.txt")
|
||||
message( "Cloning SFML in ExtLibs/SFML with Git..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} clone "https://www.github.com/SFML/SFML.git" SFML
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Resetting SFML source code to version 2.4.1..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} reset --hard 2.4.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
message( "Resetting SFML source code to version 2.4.1..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} reset --hard 2.4.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Applying the patches..." )
|
||||
file(GLOB SFML_PATCHES
|
||||
LIST_DIRECTORIES FALSE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SFML-patches/*.patch)
|
||||
message( "Applying the patches..." )
|
||||
file(GLOB SFML_PATCHES
|
||||
LIST_DIRECTORIES FALSE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SFML-patches/*.patch)
|
||||
|
||||
if(SFML_PATCHES)
|
||||
list(SORT SFML_PATCHES)
|
||||
if(SFML_PATCHES)
|
||||
list(SORT SFML_PATCHES)
|
||||
|
||||
foreach(SFML_PATCH ${SFML_PATCHES})
|
||||
message( "Applying patch: ${SFML_PATCH}..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} apply ${SFML_PATCH} --ignore-whitespace
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
endforeach()
|
||||
foreach(SFML_PATCH ${SFML_PATCHES})
|
||||
message( "Applying patch: ${SFML_PATCH}..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} apply ${SFML_PATCH} --ignore-whitespace
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
message( "SFML already downloaded." )
|
||||
endif()
|
||||
else()
|
||||
message( "Git not found, make sure you have SFML >= 2.4 in ExtLibs/SFML and you applied the needed patches (from ExtLibs/SFML-patches)!" )
|
||||
|
676
Extensions/AdvancedWindow/JsExtension.js
Normal file
676
Extensions/AdvancedWindow/JsExtension.js
Normal file
@@ -0,0 +1,676 @@
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
* ℹ️ Changes in this file are watched and automatically imported if the editor
|
||||
* is running. You can also manually run `node import-GDJS-Runtime.js` (in newIDE/app/scripts).
|
||||
*
|
||||
* The file must be named "JsExtension.js", otherwise GDevelop won't load it.
|
||||
* ⚠️ If you make a change and the extension is not loaded, open the developer console
|
||||
* and search for any errors.
|
||||
*
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension.setExtensionInformation(
|
||||
'AdvancedWindow',
|
||||
_('Advanced window management'),
|
||||
_(
|
||||
'Provides advanced features related to the game window positioning and interaction with the operating system.'
|
||||
),
|
||||
'Arthur Pacaud (arthuro555)',
|
||||
'MIT'
|
||||
);
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Focus',
|
||||
_('Change focus of the window'),
|
||||
_('Make the window gain or lose focus.'),
|
||||
_('Focus the window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Focus the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.focus');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsFocused',
|
||||
_('Window focused'),
|
||||
_('Checks if the window is focused.'),
|
||||
_('The window is focused'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isFocused');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Show',
|
||||
_('Change visibility of the window'),
|
||||
_('Make the window visible or invisible.'),
|
||||
_('Window visible: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Show window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.show');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsVisible',
|
||||
_('Window visibile'),
|
||||
_('Checks if the window is visible.'),
|
||||
_('The window is visible'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isVisible');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Maximize',
|
||||
_('Maximize the window'),
|
||||
_('Maximize or unmaximize the window.'),
|
||||
_('Maximize window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Maximize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.maximize');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMaximized',
|
||||
_('Window maximized'),
|
||||
_('Checks if the window is maximized.'),
|
||||
_('The window is maximized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMaximized');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Minimize',
|
||||
_('Minimize the window'),
|
||||
_('Minimize or unminimize the window.'),
|
||||
_('Minimize window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Minimize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.minimize');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMinimized',
|
||||
_('Window minimized'),
|
||||
_('Checks if the window is minimized.'),
|
||||
_('The window is minimized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMinimized');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'EnableWindow',
|
||||
_('Enable the window'),
|
||||
_('Enables or disables the window.'),
|
||||
_('Enable window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.enable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsWindowEnabled',
|
||||
_('Window enabled'),
|
||||
_('Checks if the window is enabled.'),
|
||||
_('The window is enabled'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isEnabled');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetResizable',
|
||||
_('Allow resizing'),
|
||||
_('Enables or disables resizing of the window by the user.'),
|
||||
_('Enable window resizing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow resizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setResizable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsResizable',
|
||||
_('Window resizable'),
|
||||
_('Checks if the window can be resized.'),
|
||||
_('The window can be resized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isResizable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetMovable',
|
||||
_('Allow moving'),
|
||||
_('Enables or disables moving of the window by the user.'),
|
||||
_('Enable window moving: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow moving?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setMovable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMovable',
|
||||
_('Window movable'),
|
||||
_('Checks if the window can be moved.'),
|
||||
_('The window can be moved'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMovable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetMaximizable',
|
||||
_('Allow maximizing'),
|
||||
_('Enables or disables maximizing of the window by the user.'),
|
||||
_('Enable window maximizing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow maximizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setMaximizable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMaximizable',
|
||||
_('Window maximizable'),
|
||||
_('Checks if the window can be maximized.'),
|
||||
_('The window can be maximized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMaximizable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetMinimizable',
|
||||
_('Allow mimizing'),
|
||||
_('Enables or disables minimizing of the window by the user.'),
|
||||
_('Enable window minimizing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow minimizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setMinimizable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMinimizable',
|
||||
_('Window minimizable'),
|
||||
_('Checks if the window can be minimized.'),
|
||||
_('The window can be minimized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMinimizable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetFullScreenable',
|
||||
_('Allow full-screening'),
|
||||
_('Enables or disables full-screening of the window by the user.'),
|
||||
_('Enable window full-screening: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow full-screening?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setFullScreenable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsFullScreenable',
|
||||
_('Window full-screenable'),
|
||||
_('Checks if the window can be full-screened.'),
|
||||
_('The window can be set in fullscreen'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isFullScreenable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetClosable',
|
||||
_('Allow closing'),
|
||||
_('Enables or disables closing of the window by the user.'),
|
||||
_('Enable window closing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow closing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setClosable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsClosable',
|
||||
_('Window closable'),
|
||||
_('Checks if the window can be closed.'),
|
||||
_('The window can be closed'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isClosable');
|
||||
|
||||
const levelChoices = JSON.stringify([
|
||||
'normal',
|
||||
'floating',
|
||||
'torn-off-menu',
|
||||
'modal-panel',
|
||||
'main-menu',
|
||||
'status',
|
||||
'pop-up-menu',
|
||||
'screen-saver',
|
||||
]);
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetAlwaysOnTop',
|
||||
_('Make the windows always on top'),
|
||||
_('Puts the window constantly above all other windows.'),
|
||||
_('Make window always on top: _PARAM0_, level: _PARAM1_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable always on top?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addParameter('stringWithSelector', _('Level'), levelChoices, false)
|
||||
.setDefaultValue('floating')
|
||||
.setParameterLongDescription(
|
||||
'The level is like a layer in GDevelop but for the OS. ' +
|
||||
'The further down the list, the higher it will be. ' +
|
||||
'When disabling always on top, the level will be set to normal. ' +
|
||||
'From "floating" to "status" included, ' +
|
||||
'the window is placed below the Dock on macOS and below the taskbar on Windows. ' +
|
||||
'Starting from "pop-up-menu", it is shown above the Dock on macOS and ' +
|
||||
'above the taskbar on Windows. ' +
|
||||
'This parameter is ignored on linux.'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setAlwaysOnTop');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsAlwaysOnTop',
|
||||
_('Window always on top'),
|
||||
_('Checks if the window is always on top.'),
|
||||
_('The window is always on top'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isAlwaysOnTop');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetKiosk',
|
||||
_('Enable kiosk mode'),
|
||||
_(
|
||||
'Puts the window in kiosk mode. This prevents the user from exiting fullscreen.'
|
||||
),
|
||||
_('Enable kiosk mode: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable kiosk mode?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setKiosk');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsKiosk',
|
||||
_('Kiosk mode'),
|
||||
_('Checks if the window is currently in kiosk mode.'),
|
||||
_('The window is in kiosk mode'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isKiosk');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetHasShadow',
|
||||
_('Enable window shadow'),
|
||||
_('Enables or disables the window shadow.'),
|
||||
_('Enable window shadow: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable shadow?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setHasShadow');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'HasShadow',
|
||||
_('Shadow enabled'),
|
||||
_("Checks if the window currently has it's shadow enabled."),
|
||||
_('The window has a shadow'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.hasShadow');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'EnableContentProtection',
|
||||
_('Enable content protection'),
|
||||
_(
|
||||
'Enables or disables the content protection mode. This should prevent screenshots of the game from being taken.'
|
||||
),
|
||||
_('Enable content protection: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable content protection?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setContentProtection');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetFocusable',
|
||||
_('Allow focusing'),
|
||||
_('Allow or disallow the user to focus the window.'),
|
||||
_('Allow to focus the window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow focus?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setFocusable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Flash',
|
||||
_('Flash the window'),
|
||||
_('Make the window flash or end flashing.'),
|
||||
_('Make the window flash: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Flash the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.flash');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetOpacity',
|
||||
_('Set window opacity'),
|
||||
_('Changes the window opacity.'),
|
||||
_('Set the window opacity to _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('expression', _('New opacity'), '', false)
|
||||
.setParameterLongDescription('A number between 0 (fully transparent) and 1 (fully opaque).')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setOpacity');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetWindowPosition',
|
||||
_('Set window position'),
|
||||
_('Changes the window position.'),
|
||||
_('Set the window position to _PARAM0_;_PARAM1_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('expression', _('X position'), '', false)
|
||||
.addParameter('expression', _('Y position'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setPosition');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'WindowX',
|
||||
_('Window X position'),
|
||||
_('Returns the current window X position.'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.getPositionX');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'WindowY',
|
||||
_('Window Y position'),
|
||||
_('Returns the current window Y position.'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.getPositionY');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'WindowOpacity',
|
||||
_('Window opacity'),
|
||||
_(
|
||||
'Returns the current window opacity (a number from 0 to 1, 1 being fully opaque).'
|
||||
),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.getOpacity');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
370
Extensions/AdvancedWindow/electron-advancedwindowtools.js
Normal file
370
Extensions/AdvancedWindow/electron-advancedwindowtools.js
Normal file
@@ -0,0 +1,370 @@
|
||||
// @ts-check
|
||||
/**
|
||||
* A set of wrappers around the Electron windowing APIs.
|
||||
* They don't have any effect on non Electron runtimes.
|
||||
*
|
||||
* Docstrings are only used for typing here, for proper
|
||||
* documentation check the electron docs at
|
||||
* https://www.electronjs.org/docs/api.
|
||||
*
|
||||
* @filedescriptor
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tools to manipulate the game window positioning and
|
||||
* interactions with the operating system.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow = {
|
||||
/**
|
||||
* The game's BrowserWindow instance (or null on
|
||||
* non-electron platforms).
|
||||
* @type {?Object}
|
||||
*/
|
||||
electronBrowserWindow: null,
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
if (typeof require === 'function') {
|
||||
// @ts-ignore
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow = require('electron').remote.getCurrentWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.focus = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.focus();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isFocused = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isFocused();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.show = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.showInactive();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isVisible = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isVisible();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.maximize = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.maximize();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.unmaximize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMaximized = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMaximized();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.minimize = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.minimize();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.restore();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMinimized = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMinimized();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.enable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setEnabled(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isEnabled = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isEnabled();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setResizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setResizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isResizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isResizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMovable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMovable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMovable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMovable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMaximizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMaximizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMaximizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMaximizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMinimizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMinimizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMinimizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMinimizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setFullScreenable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setFullScreenable(
|
||||
activate
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isFullScreenable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isFullScreenable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setClosable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setClosable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isClosable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isClosable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
* @param {"normal" | "floating" | "torn-off-menu" | "modal-panel" |"main-menu" | "status" | "pop-up-menu" | "screen-saver"} level
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setAlwaysOnTop = function (activate, level) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setAlwaysOnTop(
|
||||
activate,
|
||||
level
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isAlwaysOnTop = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isAlwaysOnTop();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setPosition = function (x, y) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
// Convert x and y to (32 bit) integers to avoid Electron errors.
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setPosition(~~x, ~~y);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getPositionX = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getPosition()[0];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getPositionY = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getPosition()[1];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setKiosk = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setKiosk(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isKiosk = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isKiosk();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.flash = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.flashFrame(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setHasShadow = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setHasShadow(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.hasShadow = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.hasShadow();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} opacity
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setOpacity = function (opacity) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setOpacity(opacity);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getOpacity = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getOpacity();
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setContentProtection = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setContentProtection(
|
||||
activate
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setFocusable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setFocusable(activate);
|
||||
};
|
@@ -18,7 +18,11 @@ gdjs.BBTextRuntimeObjectPixiRenderer = function (runtimeObject, runtimeScene) {
|
||||
.getFontManager()
|
||||
.getFontFamily(runtimeObject._fontFamily),
|
||||
fontSize: runtimeObject._fontSize + 'px',
|
||||
fill: runtimeObject._color,
|
||||
fill: gdjs.rgbToHexNumber(
|
||||
runtimeObject._color[0],
|
||||
runtimeObject._color[1],
|
||||
runtimeObject._color[2]
|
||||
),
|
||||
tagStyle: 'bbcode',
|
||||
wordWrap: runtimeObject._wordWrap,
|
||||
wordWrapWidth: runtimeObject._wrappingWidth,
|
||||
@@ -72,7 +76,11 @@ gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateText = function () {
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateColor = function () {
|
||||
this._pixiObject.textStyles.default.fill = this._object._color;
|
||||
this._pixiObject.textStyles.default.fill = gdjs.rgbToHexNumber(
|
||||
this._object._color[0],
|
||||
this._object._color[1],
|
||||
this._object._color[2]
|
||||
);
|
||||
this._pixiObject.dirty = true;
|
||||
};
|
||||
|
||||
|
@@ -29,8 +29,8 @@ gdjs.BBTextRuntimeObject = function(runtimeScene, objectData) {
|
||||
// parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
|
||||
/** @type {string} */
|
||||
this._text = objectData.content.text;
|
||||
/** @type {string} */
|
||||
this._color = objectData.content.color;
|
||||
/** @type {number[]} color in format [r, g, b], where each component is in the range [0, 255] */
|
||||
this._color = gdjs.BBTextRuntimeObject.hexToRGBColor(objectData.content.color);
|
||||
/** @type {string} */
|
||||
this._fontFamily = objectData.content.fontFamily;
|
||||
/** @type {number} */
|
||||
@@ -61,6 +61,11 @@ gdjs.BBTextRuntimeObject.prototype = Object.create(
|
||||
);
|
||||
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);
|
||||
|
||||
gdjs.BBTextRuntimeObject.hexToRGBColor = function (hex) {
|
||||
var hexNumber = parseInt(hex.replace('#', ''), 16);
|
||||
return [(hexNumber >> 16) & 0xff, (hexNumber >> 8) & 0xff, hexNumber & 0xff];
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
};
|
||||
@@ -80,7 +85,7 @@ gdjs.BBTextRuntimeObject.prototype.updateFromObjectData = function(oldObjectData
|
||||
this.setBBText(newObjectData.content.text);
|
||||
}
|
||||
if (oldObjectData.content.color !== newObjectData.content.color) {
|
||||
this._color = newObjectData.content.color;
|
||||
this._color = gdjs.BBTextRuntimeObject.hexToRGBColor(newObjectData.content.color);
|
||||
this._renderer.updateColor();
|
||||
}
|
||||
if (oldObjectData.content.fontFamily !== newObjectData.content.fontFamily) {
|
||||
@@ -132,19 +137,19 @@ gdjs.BBTextRuntimeObject.prototype.getBBText = function() {
|
||||
gdjs.BBTextRuntimeObject.prototype.setColor = function(rgbColorString) {
|
||||
const splitValue = rgbColorString.split(';');
|
||||
if (splitValue.length !== 3) return;
|
||||
const hexColor =
|
||||
'#' +
|
||||
gdjs.rgbToHex(
|
||||
parseInt(splitValue[0], 0),
|
||||
parseInt(splitValue[1], 0),
|
||||
parseInt(splitValue[2], 0)
|
||||
);
|
||||
this._color = hexColor;
|
||||
|
||||
this._color[0] = parseInt(splitValue[0], 10);
|
||||
this._color[1] = parseInt(splitValue[1], 10);
|
||||
this._color[2] = parseInt(splitValue[2], 10);
|
||||
this._renderer.updateColor();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the base color.
|
||||
* @return {string} The color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getColor = function() {
|
||||
return this._color;
|
||||
return this._color[0] + ";" + this._color[1] + ";" + this._color[2];
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.setFontSize = function(fontSize) {
|
||||
|
@@ -20,7 +20,10 @@ import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsEx
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function(_/*: (string) => string */, gd/*: libGDevelop */) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -305,7 +308,9 @@ module.exports = {
|
||||
.addAction(
|
||||
'DeleteFileAsync',
|
||||
_('Delete a file (Async)'),
|
||||
_('Delete a file from the filesystem asynchronously. The option result variable will be updated once the file is deleted.'),
|
||||
_(
|
||||
'Delete a file from the filesystem asynchronously. The option result variable will be updated once the file is deleted.'
|
||||
),
|
||||
_('Delete the file _PARAM0_'),
|
||||
_('Filesystem/Windows, Linux, MacOS/Asynchronous'),
|
||||
'JsPlatform/Extensions/filesystem_delete_file24.png',
|
||||
@@ -366,8 +371,8 @@ module.exports = {
|
||||
extension
|
||||
.addStrExpression(
|
||||
'ExecutablePath',
|
||||
_('This games executable folder'),
|
||||
_('Get the path to this games executable folder.'),
|
||||
_('Game executable file'),
|
||||
_('Get the path to this game executable file.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
@@ -376,11 +381,24 @@ module.exports = {
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getExecutablePath');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'ExecutableFolderPath',
|
||||
_('Game executable folder'),
|
||||
_('Get the path to this game executable folder.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getExecutableFolderPath');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'UserdataPath',
|
||||
_('Userdata folder (For application settings)'),
|
||||
_('Get the path to userdata folder. (For application settings)'),
|
||||
_('Userdata folder (for application settings)'),
|
||||
_('Get the path to userdata folder (for application settings).'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
@@ -392,7 +410,7 @@ module.exports = {
|
||||
extension
|
||||
.addStrExpression(
|
||||
'UserHomePath',
|
||||
_('User\'s Home folder'),
|
||||
_("User's Home folder"),
|
||||
_('Get the path to the user home folder.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
@@ -418,7 +436,7 @@ module.exports = {
|
||||
.addStrExpression(
|
||||
'PathDelimiter',
|
||||
_('Path delimiter'),
|
||||
_('Get the operating system agnostic path delimiter.'),
|
||||
_('Get the operating system path delimiter.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
@@ -426,9 +444,55 @@ module.exports = {
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getPathDelimiter');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'DirectoryName',
|
||||
_('Get directory name from a path'),
|
||||
_(
|
||||
'Returns the portion of the path that represents the directories, without the ending file name.'
|
||||
),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addParameter('string', _('File or folder path'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getDirectoryName');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'FileName',
|
||||
_('Get file name from a path'),
|
||||
_('Returns the name of the file with its extension, if any.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addParameter('string', _('File path'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getFileName');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'ExtensionName',
|
||||
_('Get the extension from a file path'),
|
||||
_(
|
||||
'Returns the extension of the file designated by the given path, including the extension period. For example: ".txt".'
|
||||
),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addParameter('string', _('File path'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getExtensionName');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function(gd /*: libGDevelop */, extension /*: gdPlatformExtension*/) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,11 +1,58 @@
|
||||
// @ts-check
|
||||
/**
|
||||
* @memberof gdjs
|
||||
* @class fileSystem
|
||||
* @static
|
||||
* @namespace fileSystem
|
||||
* @private
|
||||
*/
|
||||
|
||||
gdjs.fileSystem = {};
|
||||
gdjs.fileSystem = {
|
||||
_path: null, // The Node.js path module, or null if it can't be loaded.
|
||||
_fs: null, // The Node.js fs module, or null if it can't be loaded.
|
||||
};
|
||||
|
||||
/** Get the Node.js path module, or null if it can't be loaded */
|
||||
gdjs.fileSystem._getPath = function() {
|
||||
if (!gdjs.fileSystem._path) {
|
||||
// @ts-ignore
|
||||
gdjs.fileSystem._path = typeof require !== 'undefined' ? require('path') : null;
|
||||
}
|
||||
|
||||
return gdjs.fileSystem._path;
|
||||
}
|
||||
|
||||
/** Get the Node.js fs module, or null if it can't be loaded */
|
||||
gdjs.fileSystem._getFs = function() {
|
||||
if (!gdjs.fileSystem._fs) {
|
||||
// @ts-ignore
|
||||
gdjs.fileSystem._fs = typeof require !== 'undefined' ? require('fs') : null;
|
||||
}
|
||||
|
||||
return gdjs.fileSystem._fs;
|
||||
}
|
||||
|
||||
/** @param {string} fileOrFolderPath */
|
||||
gdjs.fileSystem.getDirectoryName = function(fileOrFolderPath) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) return '';
|
||||
|
||||
return path.dirname(fileOrFolderPath);
|
||||
}
|
||||
|
||||
/** @param {string} filePath */
|
||||
gdjs.fileSystem.getFileName = function(filePath) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) return '';
|
||||
|
||||
return path.basename(filePath);
|
||||
}
|
||||
|
||||
/** @param {string} filePath */
|
||||
gdjs.fileSystem.getExtensionName = function(filePath) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) return '';
|
||||
|
||||
return path.extname(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to 'Desktop' folder.
|
||||
@@ -62,9 +109,9 @@ gdjs.fileSystem.getPicturesPath = function(runtimeScene) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to this application 'Executable' folder.
|
||||
* Get the path to this application 'Executable' file.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene
|
||||
* @return {string} The path to this applications executable folder
|
||||
* @return {string} The path to this applications executable file
|
||||
*/
|
||||
gdjs.fileSystem.getExecutablePath = function(runtimeScene) {
|
||||
const electron = runtimeScene
|
||||
@@ -79,6 +126,22 @@ gdjs.fileSystem.getExecutablePath = function(runtimeScene) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to this application 'Executable' folder.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene
|
||||
* @return {string} The path to this applications executable folder
|
||||
*/
|
||||
gdjs.fileSystem.getExecutableFolderPath = function(runtimeScene) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
const executablePath = gdjs.fileSystem.getExecutablePath(runtimeScene);
|
||||
|
||||
if (!path) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return path.dirname(executablePath);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to 'UserData' folder.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene
|
||||
@@ -101,7 +164,7 @@ gdjs.fileSystem.getUserdataPath = function(runtimeScene) {
|
||||
* Get the path to the user's home folder (on Windows `C:\Users\<USERNAME>\` for example).
|
||||
* @return {string} The path to user's "home" folder
|
||||
*/
|
||||
gdjs.fileSystem.getUserHomePath = function() {
|
||||
gdjs.fileSystem.getUserHomePath = function(runtimeScene) {
|
||||
const electron = runtimeScene
|
||||
.getGame()
|
||||
.getRenderer()
|
||||
@@ -137,7 +200,7 @@ gdjs.fileSystem.getTempPath = function(runtimeScene) {
|
||||
* @return {string} The path delimiter
|
||||
*/
|
||||
gdjs.fileSystem.getPathDelimiter = function() {
|
||||
const path = typeof require !== 'undefined' ? require('path') : null;
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
|
||||
if (path) {
|
||||
return path.sep || '/';
|
||||
@@ -152,7 +215,7 @@ gdjs.fileSystem.getPathDelimiter = function() {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.makeDirectory = function(directory, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -176,7 +239,7 @@ gdjs.fileSystem.makeDirectory = function(directory, resultVar) {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.saveStringToFileAsync = function(text, savePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
fileSystem.writeFile(savePath, text, 'utf8', err => {
|
||||
@@ -199,7 +262,7 @@ gdjs.fileSystem.saveStringToFileAsync = function(text, savePath, resultVar) {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.saveStringToFile = function(text, savePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -227,7 +290,7 @@ gdjs.fileSystem.saveVariableToJSONFile = function(
|
||||
savePath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
let result = 'error';
|
||||
|
||||
@@ -251,7 +314,7 @@ gdjs.fileSystem.saveVariableToJSONFile = function(
|
||||
|
||||
/**
|
||||
* Save a variable into a file in JSON format, asynchronously.
|
||||
* @param {string} text The variable to be saved
|
||||
* @param {gdjs.Variable} variable The variable to be saved
|
||||
* @param {string} savePath Path to the file
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
@@ -260,7 +323,7 @@ gdjs.fileSystem.saveVariableToJSONFileAsync = function(
|
||||
savePath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
|
||||
if (fileSystem && network) {
|
||||
@@ -289,7 +352,7 @@ gdjs.fileSystem.saveVariableToJSONFileAsync = function(
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.loadStringFromFile = function(stringVar, loadPath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -321,7 +384,7 @@ gdjs.fileSystem.loadVariableFromJSONFile = function(
|
||||
loadPath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
let result = 'error';
|
||||
|
||||
@@ -353,7 +416,7 @@ gdjs.fileSystem.loadVariableFromJSONFileAsync = function(
|
||||
loadPath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
|
||||
if (fileSystem && network) {
|
||||
@@ -384,7 +447,7 @@ gdjs.fileSystem.loadStringFromFileAsync = function(
|
||||
loadPath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
fileSystem.readFile(loadPath, 'utf8', (err, data) => {
|
||||
@@ -409,7 +472,7 @@ gdjs.fileSystem.loadStringFromFileAsync = function(
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.deleteFile = function(filePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -430,7 +493,7 @@ gdjs.fileSystem.deleteFile = function(filePath, resultVar) {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.deleteFileAsync = function(filePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
fileSystem.unlink(filePath, err => {
|
||||
@@ -449,7 +512,7 @@ gdjs.fileSystem.deleteFileAsync = function(filePath, resultVar) {
|
||||
* @return {boolean} true if fhe file or directory exists
|
||||
*/
|
||||
gdjs.fileSystem.pathExists = function(filePath) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
return fileSystem.existsSync(filePath);
|
||||
|
@@ -11,7 +11,7 @@ gdjs.LightRuntimeObjectPixiRenderer = function (runtimeObject, runtimeScene) {
|
||||
this._runtimeScene = runtimeScene;
|
||||
this._manager = runtimeObject.getObstaclesManager();
|
||||
this._radius = runtimeObject.getRadius();
|
||||
var objectColor = runtimeObject.getColor();
|
||||
var objectColor = runtimeObject._color;
|
||||
this._color = [
|
||||
objectColor[0] / 255,
|
||||
objectColor[1] / 255,
|
||||
@@ -55,6 +55,13 @@ gdjs.LightRuntimeObjectPixiRenderer = function (runtimeObject, runtimeScene) {
|
||||
runtimeObject.getHitBoxes()[0].vertices[i]
|
||||
);
|
||||
}
|
||||
|
||||
// Objects will be added in lighting layer, this is just to maintain consistency.
|
||||
if (this._light)
|
||||
runtimeScene
|
||||
.getLayer('')
|
||||
.getRenderer()
|
||||
.addRendererObject(this.getRendererObject(), runtimeObject.getZOrder());
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectRenderer = gdjs.LightRuntimeObjectPixiRenderer; //Register the class to let the engine use it.
|
||||
@@ -168,6 +175,12 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype.ensureUpToDate = function () {
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateMesh = function () {
|
||||
if (!PIXI.utils.isWebGLSupported()) {
|
||||
console.warn(
|
||||
'This device does not support webgl, which is required for Lighting Extension.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.updateTexture();
|
||||
var fragmentShader =
|
||||
this._texture === null
|
||||
@@ -200,12 +213,16 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype.updateMesh = function () {
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateRadius = function () {
|
||||
if (!this._light) return;
|
||||
|
||||
this._radius = this._object.getRadius();
|
||||
this._light.shader.uniforms.radius = this._radius;
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateColor = function () {
|
||||
var objectColor = this._object.getColor();
|
||||
if (!this._light) return;
|
||||
|
||||
var objectColor = this._object._color;
|
||||
this._color = [
|
||||
objectColor[0] / 255,
|
||||
objectColor[1] / 255,
|
||||
@@ -223,6 +240,8 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype.updateTexture = function () {
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateDebugMode = function () {
|
||||
if (!this._light) return;
|
||||
|
||||
this._debugMode = this._object.getDebugMode();
|
||||
if (!this._debugLight && (this._isPreview || this._debugMode)) {
|
||||
this._debugLight = new PIXI.Container();
|
||||
@@ -293,9 +312,10 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype._updateDebugGraphics = function ()
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype._updateBuffers = function () {
|
||||
if (!this._light) return;
|
||||
|
||||
this._center[0] = this._object.x;
|
||||
this._center[1] = this._object.y;
|
||||
this._light.shader.uniforms.center = this._center;
|
||||
|
||||
var vertices = this._computeLightVertices();
|
||||
// Fallback to simple quad when there are no obstacles around.
|
||||
@@ -309,6 +329,7 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype._updateBuffers = function () {
|
||||
this._defaultVertexBuffer[6] = this._object.x - this._radius;
|
||||
this._defaultVertexBuffer[7] = this._object.y - this._radius;
|
||||
|
||||
this._light.shader.uniforms.center = this._center;
|
||||
this._light.geometry
|
||||
.getBuffer('aVertexPosition')
|
||||
.update(this._defaultVertexBuffer);
|
||||
@@ -364,6 +385,7 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype._updateBuffers = function () {
|
||||
else this._indexBuffer[i + 2] = 1;
|
||||
}
|
||||
|
||||
this._light.shader.uniforms.center = this._center;
|
||||
if (!isSubArrayUsed) {
|
||||
this._light.geometry
|
||||
.getBuffer('aVertexPosition')
|
||||
|
@@ -147,11 +147,11 @@ gdjs.LightRuntimeObject.prototype.getDrawableY = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the color of the light object in format [r, g, b], with components in the range of [0-255].
|
||||
* @returns {number[]} the color of light object in rgb format.
|
||||
* Get the color of the light object as a "R;G;B" string.
|
||||
* @returns {string} the color of light object in "R;G;B" format.
|
||||
*/
|
||||
gdjs.LightRuntimeObject.prototype.getColor = function () {
|
||||
return this._color;
|
||||
return this._color[0] + ';' + this._color[1] + ';' + this._color[2];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -161,9 +161,9 @@ gdjs.LightRuntimeObject.prototype.getColor = function () {
|
||||
gdjs.LightRuntimeObject.prototype.setColor = function (color) {
|
||||
var rgbColor = color.split(';');
|
||||
this._color = [
|
||||
parseInt(rgbColor[0]),
|
||||
parseInt(rgbColor[1]),
|
||||
parseInt(rgbColor[2]),
|
||||
parseInt(rgbColor[0], 10),
|
||||
parseInt(rgbColor[1], 10),
|
||||
parseInt(rgbColor[2], 10),
|
||||
];
|
||||
this._renderer.updateColor();
|
||||
};
|
||||
|
@@ -53,6 +53,7 @@ const addLightObstacle = (runtimeScene, width, height) => {
|
||||
};
|
||||
|
||||
describe('gdjs.LightRuntimeObject', function () {
|
||||
PIXI.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
|
||||
const runtimeGame = new gdjs.RuntimeGame({
|
||||
variables: [],
|
||||
resources: {
|
||||
@@ -61,12 +62,19 @@ describe('gdjs.LightRuntimeObject', function () {
|
||||
properties: { windowWidth: 800, windowHeight: 600 },
|
||||
});
|
||||
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
|
||||
runtimeScene.loadFromScene({
|
||||
layers: [{ name: '', visibility: true, effects: [] }],
|
||||
variables: [],
|
||||
behaviorsSharedData: [],
|
||||
objects: [],
|
||||
instances: [],
|
||||
});
|
||||
const lightObj = addLightObject(runtimeScene, 100);
|
||||
lightObj.setPosition(200, 200);
|
||||
|
||||
it('check object properties', function () {
|
||||
expect(lightObj.getRadius()).to.be(100);
|
||||
expect(lightObj.getColor()).to.eql([180, 180, 180]);
|
||||
expect(lightObj.getColor()).to.eql("180;180;180");
|
||||
expect(lightObj.getDebugMode()).to.be(false);
|
||||
expect(lightObj.getDrawableX()).to.be(100);
|
||||
expect(lightObj.getDrawableY()).to.be(100);
|
||||
@@ -85,6 +93,7 @@ describe('gdjs.LightRuntimeObject', function () {
|
||||
});
|
||||
|
||||
describe('Light with obstacles around it', function () {
|
||||
PIXI.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
|
||||
const runtimeGame = new gdjs.RuntimeGame({
|
||||
variables: [],
|
||||
resources: {
|
||||
@@ -156,7 +165,7 @@ describe('Light with obstacles around it', function () {
|
||||
const expectedIndexBuffer = [
|
||||
0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0,
|
||||
6, 7, 0, 7, 8, 0, 8, 9, 0, 9, 10, 0, 10, 11, 0,
|
||||
11, 12, 0, 12, 13, 0, 13, 14, 0, 14, 15, 0, 15,
|
||||
11, 12, 0, 12, 13, 0, 13, 14, 0, 14, 15, 0, 15,
|
||||
16, 0, 16, 17, 0, 17, 18, 0, 18, 1,
|
||||
];
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
gdjs.evtTools.p2p = {
|
||||
/**
|
||||
* The peer to peer configuration.
|
||||
* @type {Peer.PeerJSOption}
|
||||
*/
|
||||
peerConfig: { debug: 1 }, // Enable logging of critical errors
|
||||
|
||||
@@ -18,52 +19,75 @@ gdjs.evtTools.p2p = {
|
||||
peer: null,
|
||||
|
||||
/**
|
||||
* All connected p2p clients, keyed by their id.
|
||||
* All connected p2p clients, keyed by their ID.
|
||||
* @type {Object<string, Peer.DataConnection>}
|
||||
*/
|
||||
connections: {},
|
||||
|
||||
/**
|
||||
* Contains a list of events triggered by other p2p clients.
|
||||
* Maps an event name (string) to a boolean:
|
||||
* true if the event has been triggered, otherwise false.
|
||||
* @note This is ignored if the event is in no dataloss mode.
|
||||
* @type {Object<string, boolean>}
|
||||
*/
|
||||
triggeredEvents: {},
|
||||
|
||||
/**
|
||||
* Contains the latest data sent with each event.
|
||||
* If the event is in dataloss mode, maps an event name (string)
|
||||
* to the string sent with that event.
|
||||
* If the event is in no dataloss mode, maps an event name (string)
|
||||
* to an array containing the data of each call of that event.
|
||||
* @type {Object<string, string | Array>}
|
||||
*/
|
||||
lastEventData: {},
|
||||
|
||||
/**
|
||||
* Tells how to handle an event (with or without data loss)
|
||||
* Tells how to handle an event (with or without data loss).
|
||||
* Maps the event name (string) to a boolean:
|
||||
* true for dataloss, false for no dataloss.
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
eventHandling: {},
|
||||
|
||||
/**
|
||||
* True if PeerJS is initialized and ready.
|
||||
* @type {boolean}
|
||||
*/
|
||||
ready: false,
|
||||
|
||||
/**
|
||||
* True if an error occured.
|
||||
* @type {boolean}
|
||||
*/
|
||||
error: false,
|
||||
|
||||
/**
|
||||
* Last error's message.
|
||||
* @type {string}
|
||||
*/
|
||||
lastError: '',
|
||||
|
||||
/**
|
||||
* True if a peer diconnected.
|
||||
* List of IDs of peers that just disconnected.
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
peerJustDisconnected: false,
|
||||
disconnectedPeers: [],
|
||||
|
||||
/**
|
||||
* The last peer that has disconnected.
|
||||
* List of IDs of peers that just remotely initiated a connection.
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
lastDisconnectedPeerId: '',
|
||||
connectedPeers: [],
|
||||
};
|
||||
|
||||
gdjs.evtTools.p2p.loadPeerJS = function () {
|
||||
/**
|
||||
* Internal function called to initialize PeerJS after its
|
||||
* broker server has been configured.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.p2p._loadPeerJS = function () {
|
||||
if (gdjs.evtTools.p2p.peer != null) return;
|
||||
gdjs.evtTools.p2p.peer = new Peer(gdjs.evtTools.p2p.peerConfig);
|
||||
gdjs.evtTools.p2p.peer.on('open', function () {
|
||||
@@ -73,14 +97,24 @@ gdjs.evtTools.p2p.loadPeerJS = function () {
|
||||
gdjs.evtTools.p2p.error = true;
|
||||
gdjs.evtTools.p2p.lastError = errorMessage;
|
||||
});
|
||||
gdjs.evtTools.p2p.peer.on('connection', gdjs.evtTools.p2p._onConnection);
|
||||
gdjs.evtTools.p2p.peer.on('connection', function (connection) {
|
||||
connection.on('open', function () {
|
||||
gdjs.evtTools.p2p._onConnection(connection);
|
||||
gdjs.evtTools.p2p.connectedPeers.push(connection.peer);
|
||||
});
|
||||
});
|
||||
gdjs.evtTools.p2p.peer.on('close', function () {
|
||||
gdjs.evtTools.p2p.peer = null;
|
||||
gdjs.evtTools.p2p.loadPeerJS();
|
||||
gdjs.evtTools.p2p._loadPeerJS();
|
||||
});
|
||||
gdjs.evtTools.p2p.peer.on('disconnected', gdjs.evtTools.p2p.peer.reconnect);
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function called when a connection with a remote peer is initiated.
|
||||
* @private
|
||||
* @param {Peer.DataConnection} connection The DataConnection of the peer
|
||||
*/
|
||||
gdjs.evtTools.p2p._onConnection = function (connection) {
|
||||
gdjs.evtTools.p2p.connections[connection.peer] = connection;
|
||||
connection.on('data', function (data) {
|
||||
@@ -117,15 +151,19 @@ gdjs.evtTools.p2p._onConnection = function (connection) {
|
||||
disconnectChecker();
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function called when a remote client disconnects.
|
||||
* @private
|
||||
* @param {string} connectionID The ID of the peer that disconnected.
|
||||
*/
|
||||
gdjs.evtTools.p2p._onDisconnect = function (connectionID) {
|
||||
gdjs.evtTools.p2p.peerJustDisconnected = true;
|
||||
gdjs.evtTools.p2p.lastDisconnectedPeerId = connectionID;
|
||||
gdjs.evtTools.p2p.disconnectedPeers.push(connectionID);
|
||||
delete gdjs.evtTools.p2p.connections[connectionID];
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects to another p2p client.
|
||||
* @param {string} id - The other client's id.
|
||||
* @param {string} id - The other client's ID.
|
||||
*/
|
||||
gdjs.evtTools.p2p.connect = function (id) {
|
||||
var connection = gdjs.evtTools.p2p.peer.connect(id);
|
||||
@@ -137,14 +175,14 @@ gdjs.evtTools.p2p.connect = function (id) {
|
||||
/**
|
||||
* Returns true when the event got triggered by another p2p client.
|
||||
* @param {string} eventName
|
||||
* @param {boolean} _dataLoss Is data loss allowed (accelerates event handling when true)?
|
||||
* @param {boolean} defaultDataLoss Is data loss allowed (accelerates event handling when true)?
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.p2p.onEvent = function (eventName, _dataLoss) {
|
||||
gdjs.evtTools.p2p.onEvent = function (eventName, defaultDataLoss) {
|
||||
var dataLoss = gdjs.evtTools.p2p.eventHandling[eventName];
|
||||
if (dataLoss == undefined) {
|
||||
gdjs.evtTools.p2p.eventHandling[eventName] = _dataLoss;
|
||||
return gdjs.evtTools.p2p.onEvent(eventName, _dataLoss);
|
||||
gdjs.evtTools.p2p.eventHandling[eventName] = defaultDataLoss;
|
||||
return gdjs.evtTools.p2p.onEvent(eventName, defaultDataLoss);
|
||||
}
|
||||
if (dataLoss) {
|
||||
var returnValue = gdjs.evtTools.p2p.triggeredEvents[eventName];
|
||||
@@ -160,7 +198,7 @@ gdjs.evtTools.p2p.onEvent = function (eventName, _dataLoss) {
|
||||
|
||||
/**
|
||||
* Send an event to one specific connected client.
|
||||
* @param {string} id - The id of the client to send the event to.
|
||||
* @param {string} id - The ID of the client to send the event to.
|
||||
* @param {string} eventName - The event to trigger.
|
||||
* @param {string} [eventData] - Additional data to send with the event.
|
||||
*/
|
||||
@@ -188,16 +226,16 @@ gdjs.evtTools.p2p.sendDataToAll = function (eventName, eventData) {
|
||||
|
||||
/**
|
||||
* Send an event to one specific connected client.
|
||||
* @param {string} id - The id of the client to send the event to.
|
||||
* @param {string} id - The ID of the client to send the event to.
|
||||
* @param {string} eventName - The event to trigger.
|
||||
* @param {gdjs.Variable} variable - Additional variable to send with the event.
|
||||
*/
|
||||
gdjs.evtTools.p2p.sendVariableTo = function (id, eventName, variable) {
|
||||
if (gdjs.evtTools.p2p.connections[id])
|
||||
gdjs.evtTools.p2p.connections[id].send({
|
||||
eventName: eventName,
|
||||
data: gdjs.evtTools.network.variableStructureToJSON(variable),
|
||||
});
|
||||
gdjs.evtTools.p2p.sendDataTo(
|
||||
id,
|
||||
eventName,
|
||||
gdjs.evtTools.network.variableStructureToJSON(variable)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -206,12 +244,10 @@ gdjs.evtTools.p2p.sendVariableTo = function (id, eventName, variable) {
|
||||
* @param {gdjs.Variable} variable - Additional variable to send with the event.
|
||||
*/
|
||||
gdjs.evtTools.p2p.sendVariableToAll = function (eventName, variable) {
|
||||
for (var id in gdjs.evtTools.p2p.connections) {
|
||||
gdjs.evtTools.p2p.connections[id].send({
|
||||
eventName: eventName,
|
||||
data: gdjs.evtTools.network.variableStructureToJSON(variable),
|
||||
});
|
||||
}
|
||||
gdjs.evtTools.p2p.sendDataToAll(
|
||||
eventName,
|
||||
gdjs.evtTools.network.variableStructureToJSON(variable)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -265,7 +301,7 @@ gdjs.evtTools.p2p.useCustomBrokerServer = function (
|
||||
secure: ssl,
|
||||
key,
|
||||
};
|
||||
gdjs.evtTools.p2p.loadPeerJS();
|
||||
gdjs.evtTools.p2p._loadPeerJS();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -274,11 +310,11 @@ gdjs.evtTools.p2p.useCustomBrokerServer = function (
|
||||
* this server should only be used for quick testing in development.
|
||||
*/
|
||||
gdjs.evtTools.p2p.useDefaultBrokerServer = function () {
|
||||
gdjs.evtTools.p2p.loadPeerJS();
|
||||
gdjs.evtTools.p2p._loadPeerJS();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the own current peer ID
|
||||
* Returns the own current peer ID.
|
||||
* @see Peer.id
|
||||
* @returns {string}
|
||||
*/
|
||||
@@ -288,7 +324,7 @@ gdjs.evtTools.p2p.getCurrentId = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true once PeerJS is initialized
|
||||
* Returns true once PeerJS finished initialization.
|
||||
* @see gdjs.evtTools.p2p.ready
|
||||
* @returns {boolean}
|
||||
*/
|
||||
@@ -319,13 +355,39 @@ gdjs.evtTools.p2p.getLastError = function () {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.p2p.onDisconnect = function () {
|
||||
var returnValue = gdjs.evtTools.p2p.peerJustDisconnected;
|
||||
gdjs.evtTools.p2p.peerJustDisconnected = false;
|
||||
return returnValue;
|
||||
return gdjs.evtTools.p2p.disconnectedPeers.length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the ID of the peer that triggered onDisconnect.
|
||||
* @returns {string}
|
||||
*/
|
||||
gdjs.evtTools.p2p.getDisconnectedPeer = function () {
|
||||
return gdjs.evtTools.p2p.lastDisconnectedPeerId;
|
||||
return (
|
||||
gdjs.evtTools.p2p.disconnectedPeers[
|
||||
gdjs.evtTools.p2p.disconnectedPeers.length - 1
|
||||
] || ''
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true once if a remote peer just initiated a connection.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.p2p.onConnection = function () {
|
||||
return gdjs.evtTools.p2p.connectedPeers.length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the ID of the peer that triggered onConnection.
|
||||
* @returns {string}
|
||||
*/
|
||||
gdjs.evtTools.p2p.getConnectedPeer = function () {
|
||||
return (
|
||||
gdjs.evtTools.p2p.connectedPeers[
|
||||
gdjs.evtTools.p2p.connectedPeers.length - 1
|
||||
] || ''
|
||||
);
|
||||
};
|
||||
|
||||
gdjs.callbacksRuntimeScenePostEvents.push(function () {
|
||||
@@ -336,4 +398,8 @@ gdjs.callbacksRuntimeScenePostEvents.push(function () {
|
||||
)
|
||||
gdjs.evtTools.p2p.lastEventData[i].pop();
|
||||
}
|
||||
if (gdjs.evtTools.p2p.disconnectedPeers.length > 0)
|
||||
gdjs.evtTools.p2p.disconnectedPeers.pop();
|
||||
if (gdjs.evtTools.p2p.connectedPeers.length > 0)
|
||||
gdjs.evtTools.p2p.connectedPeers.pop();
|
||||
});
|
||||
|
@@ -105,6 +105,21 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.onDisconnect');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'OnConnection',
|
||||
_('Peer Connected'),
|
||||
_('Triggers once when a remote peer initiates a connection.'),
|
||||
_('P2P peer connected'),
|
||||
_('P2P (experimental)'),
|
||||
'JsPlatform/Extensions/p2picon.svg',
|
||||
'JsPlatform/Extensions/p2picon.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/P2P/A_peer.js')
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.onConnection');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Connect',
|
||||
@@ -215,7 +230,7 @@ module.exports = {
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/P2P/A_peer.js')
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.sendDataToAll');
|
||||
.setFunctionName('gdjs.evtTools.p2p.sendVariableToAll');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
@@ -313,7 +328,7 @@ module.exports = {
|
||||
.addStrExpression(
|
||||
'GetLastDisconnectedPeer',
|
||||
_('Get last disconnected peer'),
|
||||
_('Gets the id of the latest peer that has disconnected.'),
|
||||
_('Gets the ID of the latest peer that has disconnected.'),
|
||||
_('P2P (experimental)'),
|
||||
'JsPlatform/Extensions/p2picon.svg'
|
||||
)
|
||||
@@ -322,6 +337,19 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.getDisconnectedPeer');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'GetLastConnectedPeer',
|
||||
_('Get ID of the connected peer'),
|
||||
_('Gets the ID of the newly connected peer.'),
|
||||
_('P2P (experimental)'),
|
||||
'JsPlatform/Extensions/p2picon.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/P2P/A_peer.js')
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.getConnectedPeer');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (
|
||||
|
@@ -66,15 +66,15 @@ void DeclarePanelSpriteObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddAction(
|
||||
"SetColor",
|
||||
_("Global color"),
|
||||
_("Change the global color of a Panel Sprite. The default color is white."),
|
||||
_("Change color of _PARAM0_ to _PARAM1_"),
|
||||
_("Tint color"),
|
||||
_("Change the tint of a Panel Sprite. The default color is white."),
|
||||
_("Change tint of _PARAM0_ to _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "PanelSprite")
|
||||
.AddParameter("color", _("Color"));
|
||||
.AddParameter("color", _("Tint"));
|
||||
|
||||
obj.AddAction("Width",
|
||||
_("Width"),
|
||||
|
@@ -258,7 +258,7 @@ gdjs.PanelSpriteRuntimeObject.prototype.setColor = function(rgbColor) {
|
||||
/**
|
||||
* Get the tint of the panel sprite object.
|
||||
*
|
||||
* @returns {string} rgbColor The color, in RGB format ("128;200;255").
|
||||
* @returns {string} The color, in RGB format ("128;200;255").
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.getColor = function() {
|
||||
return this._renderer.getColor();
|
||||
|
@@ -293,7 +293,7 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition("NoMoreParticles",
|
||||
_("No more particles"),
|
||||
_("Return true if the object does not emit particles "
|
||||
_("Check if the object does not emit particles "
|
||||
"anylonger, so as to destroy it for example."),
|
||||
_("_PARAM0_ does not emit anylonger."),
|
||||
_("Common"),
|
||||
|
@@ -56,7 +56,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("PathFound",
|
||||
_("Path found"),
|
||||
_("Return true if a path has been found."),
|
||||
_("Check if a path has been found."),
|
||||
_("A path has been found for _PARAM0_"),
|
||||
"",
|
||||
"CppPlatform/Extensions/AStaricon24.png",
|
||||
@@ -69,7 +69,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("DestinationReached",
|
||||
_("Destination reached"),
|
||||
_("Return true if the destination was reached."),
|
||||
_("Check if the destination was reached."),
|
||||
_("_PARAM0_ reached its destination"),
|
||||
"",
|
||||
"CppPlatform/Extensions/AStaricon24.png",
|
||||
@@ -338,7 +338,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("DiagonalsAllowed",
|
||||
_("Diagonal movement"),
|
||||
_("Return true if the object is allowed to move "
|
||||
_("Check if the object is allowed to move "
|
||||
"diagonally on the path"),
|
||||
_("Diagonal moves allowed for _PARAM0_"),
|
||||
_("Path"),
|
||||
@@ -366,7 +366,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("ObjectRotated",
|
||||
_("Object rotated"),
|
||||
_("Return true if the object is rotated when traveling on "
|
||||
_("Check if the object is rotated when traveling on "
|
||||
"its path."),
|
||||
_("_PARAM0_ is rotated when traveling on its path"),
|
||||
_("Path"),
|
||||
@@ -622,7 +622,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("IsImpassable",
|
||||
_("Is object impassable?"),
|
||||
_("Return true if the obstacle is impassable"),
|
||||
_("Check if the obstacle is impassable"),
|
||||
_("_PARAM0_ is impassable"),
|
||||
_("Obstacles"),
|
||||
"CppPlatform/Extensions/pathfindingobstacleicon24.png",
|
||||
|
@@ -17,16 +17,17 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.getRendererObject = functio
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.clear = function() {
|
||||
this._graphics.clear();
|
||||
this.updateOutline();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawRectangle = function(x1, y1, x2, y2) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawRect(x1, y1, x2 - x1, y2 - y1);
|
||||
this._graphics.endFill();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawCircle = function(x, y, radius) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawCircle(x, y, radius);
|
||||
this._graphics.endFill();
|
||||
@@ -55,12 +56,14 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawLineV2 = function(x1, y
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawEllipse = function(x1, y1, width, height) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawEllipse(x1, y1, width/2, height/2);
|
||||
this._graphics.endFill();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawRoundedRectangle = function(x1, y1, x2, y2, radius) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawRoundedRect(x1, y1, x2 - x1, y2 - y1, radius);
|
||||
this._graphics.closePath();
|
||||
@@ -68,6 +71,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawRoundedRectangle = func
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawStar = function(x1, y1, points, radius, innerRadius, rotation) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawStar(x1, y1, points, radius, innerRadius ? innerRadius : radius/2, rotation ? gdjs.toRad(rotation) : 0);
|
||||
this._graphics.closePath();
|
||||
@@ -75,6 +79,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawStar = function(x1, y1,
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawArc = function(x1, y1, radius, startAngle, endAngle, anticlockwise, closePath) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.moveTo( x1 + radius * Math.cos(gdjs.toRad(startAngle)), y1 + radius * Math.sin(gdjs.toRad(startAngle)));
|
||||
this._graphics.arc(x1, y1, radius, gdjs.toRad(startAngle), gdjs.toRad(endAngle), anticlockwise ? true : false);
|
||||
@@ -85,6 +90,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawArc = function(x1, y1,
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawBezierCurve = function(x1, y1, cpX, cpY, cpX2, cpY2, x2, y2) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.moveTo(x1, y1);
|
||||
this._graphics.bezierCurveTo(cpX, cpY, cpX2, cpY2, x2, y2);
|
||||
@@ -92,6 +98,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawBezierCurve = function(
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawQuadraticCurve = function(x1, y1, cpX, cpY, x2, y2) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.moveTo(x1, y1);
|
||||
this._graphics.quadraticCurveTo(cpX, cpY, x2, y2);
|
||||
|
@@ -30,14 +30,14 @@ void DeclareSystemInfoExtension(gd::PlatformExtension& extension) {
|
||||
.SetIncludeFile("SystemInfo/SystemInfoTools.h");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"IsWebGLSupported",
|
||||
_("Is WebGL supported"),
|
||||
_("Check if GPU accelerated WebGL is supported on the target device."),
|
||||
_("WebGL is available"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
.AddCondition("IsWebGLSupported",
|
||||
_("Is WebGL supported"),
|
||||
_("Check if GPU accelerated WebGL is supported on the "
|
||||
"target device."),
|
||||
_("WebGL is available"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetFunctionName("SystemInfo::IsWebGLSupported")
|
||||
@@ -47,16 +47,28 @@ void DeclareSystemInfoExtension(gd::PlatformExtension& extension) {
|
||||
.AddCondition(
|
||||
"IsPreview",
|
||||
_("Is the game running as a preview"),
|
||||
_(
|
||||
"Check if the game is currently being previewed in the editor. "
|
||||
"This can be used to enable a \"Debug mode\" or do some work only in previews."
|
||||
),
|
||||
_("Check if the game is currently being previewed in the editor. "
|
||||
"This can be used to enable a \"Debug mode\" or do some work only "
|
||||
"in previews."),
|
||||
_("The game is being previewed in the editor"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"HasTouchScreen",
|
||||
_("Device has a touchscreen"),
|
||||
_("Check if the device running the game has a touchscreen (typically "
|
||||
"Android phones, iPhones, iPads, but also some laptops)."),
|
||||
_("The device has a touchscreen"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,10 @@ class SystemInfoJsExtension : public gd::PlatformExtension {
|
||||
.codeExtraInformation
|
||||
.SetIncludeFile("Extensions/SystemInfo/systeminfotools.js")
|
||||
.SetFunctionName("gdjs.evtTools.systemInfo.isPreview");
|
||||
GetAllConditions()["SystemInfo::HasTouchScreen"]
|
||||
.codeExtraInformation
|
||||
.SetIncludeFile("Extensions/SystemInfo/systeminfotools.js")
|
||||
.SetFunctionName("gdjs.evtTools.systemInfo.hasTouchScreen");
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions();
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
|
@@ -1,48 +1,120 @@
|
||||
// @ts-check
|
||||
/**
|
||||
GDevelop - SystemInfo Extension
|
||||
Copyright (c) 2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
* GDevelop - SystemInfo Extension
|
||||
* Copyright (c) 2016-present Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @memberof gdjs.evtTools
|
||||
* @class linkedObjects
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.systemInfo = {};
|
||||
gdjs.evtTools.systemInfo = (function () {
|
||||
/** @type {?boolean} */
|
||||
let cachedIsMobile = null;
|
||||
/** @type {?boolean} */
|
||||
let cachedHasTouchScreen = null;
|
||||
|
||||
gdjs.evtTools.systemInfo.isMobile = function() {
|
||||
if (typeof cc !== "undefined" && cc.sys) {
|
||||
return cc.sys.isMobile;
|
||||
} else if (typeof Cocoon !== "undefined" && Cocoon.App) {
|
||||
return true;
|
||||
} else if (typeof window !== "undefined" && window.cordova) {
|
||||
return true;
|
||||
} else if (typeof window !== "undefined") {
|
||||
// Try to detect mobile device browsers.
|
||||
if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
|
||||
|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/** @returns {boolean} */
|
||||
const checkIsMobile = () => {
|
||||
// @ts-ignore
|
||||
if (typeof cc !== 'undefined' && cc.sys) {
|
||||
// @ts-ignore
|
||||
return cc.sys.isMobile;
|
||||
|
||||
return false;
|
||||
};
|
||||
// @ts-ignore
|
||||
} else if (typeof Cocoon !== 'undefined' && Cocoon.App) {
|
||||
return true;
|
||||
|
||||
/**
|
||||
* Check if the the device supports WebGL.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {boolean} true if WebGL is supported
|
||||
*/
|
||||
gdjs.evtTools.systemInfo.isWebGLSupported = function(runtimeScene) {
|
||||
return runtimeScene.getGame().getRenderer().isWebGLSupported();
|
||||
};
|
||||
// @ts-ignore
|
||||
} else if (typeof window !== 'undefined' && window.cordova) {
|
||||
return true;
|
||||
} else if (typeof window !== 'undefined') {
|
||||
// Try to detect mobile device browsers.
|
||||
if (
|
||||
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(
|
||||
navigator.userAgent
|
||||
) ||
|
||||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
|
||||
navigator.userAgent.substr(0, 4)
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the game is running as a preview, launched from an editor.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene.
|
||||
* @returns {boolean} true if the game is running as a preview.
|
||||
*/
|
||||
gdjs.evtTools.systemInfo.isPreview = function(runtimeScene) {
|
||||
return runtimeScene.getGame().isPreview();
|
||||
};
|
||||
// Try to detect iOS
|
||||
if (/iPad|iPhone|iPod/.test(navigator.platform)) {
|
||||
return true;
|
||||
} else if (/MacIntel/.test(navigator.platform)) {
|
||||
// Work around for recent iPads that are "desktop-class browsing".
|
||||
// We can still detect them using their touchscreen, but this is a hack.
|
||||
// If mac laptops start to support touchscreens, this won't work anymore. Hence it's better
|
||||
// to test for the presence of a touchscreen if needed rather than checking if the device
|
||||
// is "mobile".
|
||||
return !!navigator.maxTouchPoints && navigator.maxTouchPoints > 2;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the game runs on a mobile device (iPhone, iPad, Android).
|
||||
* Note that the distinction between what is a mobile device and what is not
|
||||
* is becoming blurry. If you use this for mobile controls,
|
||||
* prefer to check if the device has touchscreen support.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isMobile = () => {
|
||||
if (cachedIsMobile !== null) {
|
||||
return cachedIsMobile;
|
||||
}
|
||||
|
||||
return (cachedIsMobile = checkIsMobile());
|
||||
};
|
||||
|
||||
/** @returns {boolean} */
|
||||
const checkHasTouchScreen = () => {
|
||||
// First check if the device is mobile, as all mobile devices have a touchscreen
|
||||
// and some older browsers don't have support for `navigator.maxTouchPoints`
|
||||
if (isMobile()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!navigator.maxTouchPoints && navigator.maxTouchPoints > 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the device has a touchscreen
|
||||
*/
|
||||
const hasTouchScreen = () => {
|
||||
if (cachedHasTouchScreen !== null) {
|
||||
return cachedHasTouchScreen;
|
||||
}
|
||||
|
||||
return (cachedHasTouchScreen = checkHasTouchScreen());
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the the device supports WebGL.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {boolean} true if WebGL is supported
|
||||
*/
|
||||
const isWebGLSupported = (runtimeScene) => {
|
||||
return runtimeScene.getGame().getRenderer().isWebGLSupported();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the game is running as a preview, launched from an editor.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene.
|
||||
* @returns {boolean} true if the game is running as a preview.
|
||||
*/
|
||||
const isPreview = (runtimeScene) => {
|
||||
return runtimeScene.getGame().isPreview();
|
||||
};
|
||||
|
||||
return {
|
||||
isPreview: isPreview,
|
||||
isWebGLSupported: isWebGLSupported,
|
||||
hasTouchScreen: hasTouchScreen,
|
||||
isMobile: isMobile,
|
||||
};
|
||||
})();
|
||||
|
@@ -71,11 +71,3 @@ gdjs.TextEntryRuntimeObject.prototype.activate = function(enable) {
|
||||
this._activated = enable;
|
||||
this._renderer.activate(this._activated);
|
||||
};
|
||||
|
||||
gdjs.TextEntryRuntimeObject.prototype.setLayer = function(layer) {
|
||||
// No renderable object
|
||||
};
|
||||
|
||||
gdjs.TextEntryRuntimeObject.prototype.setZOrder = function(z) {
|
||||
// No renderable object
|
||||
};
|
||||
|
@@ -384,7 +384,7 @@ gdjs.TextRuntimeObject.prototype.setColor = function(str) {
|
||||
|
||||
/**
|
||||
* Get the text color.
|
||||
* @return {String} The color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @return {string} The color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
gdjs.TextRuntimeObject.prototype.getColor = function(str) {
|
||||
return this._color[0] + ";" + this._color[1] + ";" + this._color[2];
|
||||
|
@@ -62,15 +62,15 @@ void DeclareTiledSpriteObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddAction(
|
||||
"SetColor",
|
||||
_("Global color"),
|
||||
_("Change the global color of a Tiled Sprite. The default color is white."),
|
||||
_("Change color of _PARAM0_ to _PARAM1_"),
|
||||
_("Tint color"),
|
||||
_("Change the tint of a Tiled Sprite. The default color is white."),
|
||||
_("Change tint of _PARAM0_ to _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "TiledSprite")
|
||||
.AddParameter("color", _("Color"));
|
||||
.AddParameter("color", _("Tint"));
|
||||
|
||||
obj.AddAction("Width",
|
||||
_("Width"),
|
||||
|
@@ -24,8 +24,7 @@ gdjs.TiledSpriteRuntimeObjectPixiRenderer.prototype.getRendererObject = function
|
||||
};
|
||||
|
||||
gdjs.TiledSpriteRuntimeObjectPixiRenderer.prototype.updateOpacity = function() {
|
||||
//TODO: Workaround a not working property in PIXI.js:
|
||||
this._tiledSprite.alpha = this._tiledSprite.visible ? this._object.opacity/255 : 0;
|
||||
this._tiledSprite.alpha = this._object.opacity/255;
|
||||
}
|
||||
|
||||
gdjs.TiledSpriteRuntimeObjectPixiRenderer.prototype.updatePosition = function() {
|
||||
|
@@ -213,7 +213,7 @@ gdjs.TiledSpriteRuntimeObject.prototype.setColor = function(rgbColor) {
|
||||
/**
|
||||
* Get the tint of the tiled sprite object.
|
||||
*
|
||||
* @returns {string} rgbColor The color, in RGB format ("128;200;255").
|
||||
* @returns {string} The color, in RGB format ("128;200;255").
|
||||
*/
|
||||
gdjs.TiledSpriteRuntimeObject.prototype.getColor = function() {
|
||||
return this._renderer.getColor();
|
||||
|
@@ -290,8 +290,8 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"Angle",
|
||||
_("Angle of movement"),
|
||||
_("Compare the angle of the top-down movemement of the object."),
|
||||
_("the angle of movemement"),
|
||||
_("Compare the angle of the top-down movement of the object."),
|
||||
_("the angle of movement"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
"CppPlatform/Extensions/topdownmovementicon16.png")
|
||||
@@ -305,8 +305,8 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"XVelocity",
|
||||
_("Speed on X axis"),
|
||||
_("Compare the velocity of the top-down movemement of the object on the X axis."),
|
||||
_("the speed of movemement on X axis"),
|
||||
_("Compare the velocity of the top-down movement of the object on the X axis."),
|
||||
_("the speed of movement on X axis"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
"CppPlatform/Extensions/topdownmovementicon16.png")
|
||||
@@ -320,8 +320,8 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"YVelocity",
|
||||
_("Speed on Y axis"),
|
||||
_("Compare the velocity of the top-down movemement of the object on the Y axis."),
|
||||
_("the speed of movemement on Y axis"),
|
||||
_("Compare the velocity of the top-down movement of the object on the Y axis."),
|
||||
_("the speed of movement on Y axis"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
"CppPlatform/Extensions/topdownmovementicon16.png")
|
||||
@@ -347,7 +347,7 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("DiagonalsAllowed",
|
||||
_("Diagonal movement"),
|
||||
_("Return true if the object is allowed to move diagonally"),
|
||||
_("Check if the object is allowed to move diagonally"),
|
||||
_("Allow diagonal moves for _PARAM0_"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
@@ -375,7 +375,7 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"ObjectRotated",
|
||||
_("Object rotated"),
|
||||
_("Return true if the object is rotated while traveling on its path."),
|
||||
_("Check if the object is rotated while traveling on its path."),
|
||||
_("_PARAM0_ is rotated when moving"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
|
@@ -66,8 +66,8 @@ module.exports = {
|
||||
tweenBehavior,
|
||||
new gd.BehaviorsSharedData()
|
||||
)
|
||||
.setIncludeFile("Extensions/TweenBehavior/tweenruntimebehavior.js")
|
||||
.addIncludeFile("Extensions/TweenBehavior/shifty.js");
|
||||
.setIncludeFile("Extensions/TweenBehavior/shifty.js")
|
||||
.addIncludeFile("Extensions/TweenBehavior/tweenruntimebehavior.js");
|
||||
|
||||
const easingChoices = JSON.stringify([
|
||||
"linear",
|
||||
@@ -198,6 +198,64 @@ module.exports = {
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName("addObjectPositionXTween");
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
"AddObjectWidthTween",
|
||||
_("Add object width tween"),
|
||||
_("Add a tween animation for the object width."),
|
||||
_(
|
||||
"Tween the width of _PARAM0_ to _PARAM3_ with easing _PARAM4_ over _PARAM5_ms as _PARAM2_"
|
||||
),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/tween_behavior24.png",
|
||||
"JsPlatform/Extensions/tween_behavior32.png"
|
||||
)
|
||||
.addParameter("object", _("Object"), "", false)
|
||||
.addParameter("behavior", _("Behavior"), "TweenBehavior", false)
|
||||
.addParameter("string", _("Tween Identifier"), "", false)
|
||||
.addParameter("expression", _("To width"), "", false)
|
||||
.addParameter("stringWithSelector", _("Easing"), easingChoices, false)
|
||||
.setDefaultValue("linear")
|
||||
.addParameter("expression", _("Duration"), "", false)
|
||||
.addParameter(
|
||||
"yesorno",
|
||||
_("Destroy this object when tween finishes"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.setDefaultValue("no")
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName("addObjectWidthTween");
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
"AddObjectHeightTween",
|
||||
_("Add object height tween"),
|
||||
_("Add a tween animation for the object height."),
|
||||
_(
|
||||
"Tween the height of _PARAM0_ to _PARAM3_ with easing _PARAM4_ over _PARAM5_ms as _PARAM2_"
|
||||
),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/tween_behavior24.png",
|
||||
"JsPlatform/Extensions/tween_behavior32.png"
|
||||
)
|
||||
.addParameter("object", _("Object"), "", false)
|
||||
.addParameter("behavior", _("Behavior"), "TweenBehavior", false)
|
||||
.addParameter("string", _("Tween Identifier"), "", false)
|
||||
.addParameter("expression", _("To height"), "", false)
|
||||
.addParameter("stringWithSelector", _("Easing"), easingChoices, false)
|
||||
.setDefaultValue("linear")
|
||||
.addParameter("expression", _("Duration"), "", false)
|
||||
.addParameter(
|
||||
"yesorno",
|
||||
_("Destroy this object when tween finishes"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.setDefaultValue("no")
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName("addObjectHeightTween");
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
"AddObjectPositionYTween",
|
||||
|
@@ -817,6 +817,106 @@ gdjs.TweenRuntimeBehavior.prototype.addTextObjectCharacterSizeTween = function(
|
||||
this._setupTweenEnding(identifier, destroyObjectWhenFinished);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an object width tween.
|
||||
* @param {string} identifier Unique id to idenfify the tween
|
||||
* @param {number} toWidth The target width
|
||||
* @param {string} easingValue Type of easing
|
||||
* @param {number} durationValue Duration in milliseconds
|
||||
* @param {boolean} destroyObjectWhenFinished Destroy this object when the tween ends
|
||||
*/
|
||||
gdjs.TweenRuntimeBehavior.prototype.addObjectWidthTween = function(
|
||||
identifier,
|
||||
toWidth,
|
||||
easingValue,
|
||||
durationValue,
|
||||
destroyObjectWhenFinished
|
||||
) {
|
||||
var that = this;
|
||||
if (!this._isActive) return;
|
||||
if (!!gdjs.TweenRuntimeBehavior.easings[easingValue]) return;
|
||||
|
||||
if (this._tweenExists(identifier)) {
|
||||
this.removeTween(identifier);
|
||||
}
|
||||
|
||||
var newTweenable = gdjs.TweenRuntimeBehavior.makeNewTweenable(
|
||||
this._runtimeScene
|
||||
);
|
||||
newTweenable.setConfig({
|
||||
from: {
|
||||
width: this.owner.getWidth(),
|
||||
},
|
||||
to: {
|
||||
width: toWidth,
|
||||
},
|
||||
duration: durationValue,
|
||||
easing: easingValue,
|
||||
step: function step(state) {
|
||||
that.owner.setWidth(state.width);
|
||||
},
|
||||
});
|
||||
|
||||
this._addTween(
|
||||
identifier,
|
||||
newTweenable,
|
||||
this._runtimeScene.getTimeManager().getTimeFromStart(),
|
||||
durationValue
|
||||
);
|
||||
|
||||
this._setupTweenEnding(identifier, destroyObjectWhenFinished);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an object height tween.
|
||||
* @param {string} identifier Unique id to idenfify the tween
|
||||
* @param {number} toHeight The target height
|
||||
* @param {string} easingValue Type of easing
|
||||
* @param {number} durationValue Duration in milliseconds
|
||||
* @param {boolean} destroyObjectWhenFinished Destroy this object when the tween ends
|
||||
*/
|
||||
gdjs.TweenRuntimeBehavior.prototype.addObjectHeightTween = function(
|
||||
identifier,
|
||||
toHeight,
|
||||
easingValue,
|
||||
durationValue,
|
||||
destroyObjectWhenFinished
|
||||
) {
|
||||
var that = this;
|
||||
if (!this._isActive) return;
|
||||
if (!!gdjs.TweenRuntimeBehavior.easings[easingValue]) return;
|
||||
|
||||
if (this._tweenExists(identifier)) {
|
||||
this.removeTween(identifier);
|
||||
}
|
||||
|
||||
var newTweenable = gdjs.TweenRuntimeBehavior.makeNewTweenable(
|
||||
this._runtimeScene
|
||||
);
|
||||
newTweenable.setConfig({
|
||||
from: {
|
||||
height: this.owner.getHeight(),
|
||||
},
|
||||
to: {
|
||||
height: toHeight,
|
||||
},
|
||||
duration: durationValue,
|
||||
easing: easingValue,
|
||||
step: function step(state) {
|
||||
that.owner.setHeight(state.height);
|
||||
},
|
||||
});
|
||||
|
||||
this._addTween(
|
||||
identifier,
|
||||
newTweenable,
|
||||
this._runtimeScene.getTimeManager().getTimeFromStart(),
|
||||
durationValue
|
||||
);
|
||||
|
||||
this._setupTweenEnding(identifier, destroyObjectWhenFinished);
|
||||
};
|
||||
|
||||
/**
|
||||
* Tween is playing.
|
||||
* @param {string} identifier Unique id to idenfify the tween
|
||||
@@ -1030,23 +1130,15 @@ gdjs.registerRuntimeSceneResumedCallback(function(runtimeScene) {
|
||||
gdjs.TweenRuntimeBehavior._tweensProcessed = false;
|
||||
gdjs.TweenRuntimeBehavior._currentTweenTime = 0;
|
||||
|
||||
gdjs.TweenRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene) {
|
||||
// Process tweens (once per frame).
|
||||
if (!gdjs.TweenRuntimeBehavior._tweensProcessed) {
|
||||
gdjs.TweenRuntimeBehavior._currentTweenTime = runtimeScene
|
||||
.getTimeManager()
|
||||
.getTimeFromStart();
|
||||
shifty.processTweens();
|
||||
gdjs.TweenRuntimeBehavior._tweensProcessed = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.TweenRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
gdjs.TweenRuntimeBehavior._tweensProcessed = false;
|
||||
};
|
||||
gdjs.registerRuntimeScenePreEventsCallback(function(runtimeScene) {
|
||||
gdjs.TweenRuntimeBehavior._currentTweenTime = runtimeScene
|
||||
.getTimeManager()
|
||||
.getTimeFromStart();
|
||||
shifty.processTweens();
|
||||
});
|
||||
|
||||
// Set up Shifty.js so that the processing ("tick"/updates) is handled
|
||||
// by the behavior (once per frame):
|
||||
// by the behavior, once per frame. See above.
|
||||
shifty.Tweenable.setScheduleFunction(function() {
|
||||
/* Do nothing, we'll call processTweens manually. */
|
||||
});
|
||||
|
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "JsCodeEvent.h"
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
@@ -19,7 +20,7 @@ using namespace std;
|
||||
namespace gdjs {
|
||||
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() {
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() {
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("object");
|
||||
@@ -30,7 +31,7 @@ vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
}
|
||||
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() const {
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() const {
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("object");
|
||||
@@ -45,15 +46,14 @@ void JsCodeEvent::SerializeTo(gd::SerializerElement& element) const {
|
||||
element.AddChild("parameterObjects")
|
||||
.SetValue(parameterObjects.GetPlainString());
|
||||
element.AddChild("useStrict").SetValue(useStrict);
|
||||
element.AddChild("eventsSheetExpanded").SetValue(eventsSheetExpanded);
|
||||
}
|
||||
|
||||
void JsCodeEvent::UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
inlineCode = element.GetChild("inlineCode").GetValue().GetString();
|
||||
parameterObjects =
|
||||
gd::Expression(element.GetChild("parameterObjects")
|
||||
.GetValue()
|
||||
.GetString());
|
||||
parameterObjects = gd::Expression(
|
||||
element.GetChild("parameterObjects").GetValue().GetString());
|
||||
|
||||
if (!element.HasChild("useStrict")) {
|
||||
// Compatibility with GD <= 5.0.0-beta68
|
||||
@@ -62,11 +62,20 @@ void JsCodeEvent::UnserializeFrom(gd::Project& project,
|
||||
} else {
|
||||
useStrict = element.GetChild("useStrict").GetBoolValue();
|
||||
}
|
||||
|
||||
if (!element.HasChild("eventsSheetExpanded")) {
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
eventsSheetExpanded = false;
|
||||
// end of compatibility code
|
||||
} else {
|
||||
eventsSheetExpanded = element.GetChild("eventsSheetExpanded").GetBoolValue();
|
||||
}
|
||||
}
|
||||
|
||||
JsCodeEvent::JsCodeEvent()
|
||||
: BaseEvent(),
|
||||
inlineCode("runtimeScene.setBackgroundColor(100,100,240);\n"),
|
||||
useStrict(true) {}
|
||||
useStrict(true),
|
||||
eventsSheetExpanded(false) {}
|
||||
|
||||
} // namespace gdjs
|
||||
|
@@ -47,6 +47,9 @@ class JsCodeEvent : public gd::BaseEvent {
|
||||
const gd::SerializerElement& element);
|
||||
virtual bool IsUseStrict() const { return useStrict; }
|
||||
|
||||
bool IsEventsSheetExpanded() const { return eventsSheetExpanded; }
|
||||
void SetEventsSheetExpanded(bool enable) { eventsSheetExpanded = enable; };
|
||||
|
||||
private:
|
||||
void Init(const JsCodeEvent& event);
|
||||
|
||||
@@ -56,6 +59,7 @@ class JsCodeEvent : public gd::BaseEvent {
|
||||
bool useStrict; ///< Should the generated JS function have "use strict". true
|
||||
///< by default. Should be removed once all the game engine
|
||||
///< is using "use strict".
|
||||
bool eventsSheetExpanded; ///< Is the code block expanded in the events sheet?
|
||||
};
|
||||
|
||||
} // namespace gdjs
|
||||
|
@@ -337,6 +337,10 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionContext(
|
||||
// Unknown object, don't create anything:
|
||||
" return null;\n" +
|
||||
" },\n"
|
||||
// Allow to get a layer directly from the context for convenience:
|
||||
" getLayer: function(layerName) {\n"
|
||||
" return runtimeScene.getLayer(layerName);\n"
|
||||
" },\n"
|
||||
// Getter for arguments that are not objects
|
||||
" getArgument: function(argName) {\n" +
|
||||
argumentsGetters + " return \"\";\n" + " },\n" +
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "AdvancedExtension.h"
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
@@ -68,6 +69,28 @@ AdvancedExtension::AdvancedExtension() {
|
||||
booleanCode + "; }";
|
||||
});
|
||||
|
||||
GetAllConditions()["GetArgumentAsBoolean"]
|
||||
.GetCodeExtraInformation()
|
||||
.SetCustomCodeGenerator([](gd::Instruction& instruction,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::String parameterNameCode =
|
||||
gd::ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
codeGenerator,
|
||||
context,
|
||||
"string",
|
||||
instruction.GetParameter(0).GetPlainString());
|
||||
gd::String valueCode =
|
||||
gd::String(instruction.IsInverted() ? "!" : "") +
|
||||
"(typeof eventsFunctionContext !== 'undefined' ? "
|
||||
"!!eventsFunctionContext.getArgument(" +
|
||||
parameterNameCode + ") : false)";
|
||||
gd::String outputCode =
|
||||
codeGenerator.GenerateBooleanFullName("conditionTrue", context) +
|
||||
".val = " + valueCode + ";\n";
|
||||
return outputCode;
|
||||
});
|
||||
|
||||
GetAllExpressions()["GetArgumentAsNumber"]
|
||||
.GetCodeExtraInformation()
|
||||
.SetCustomCodeGenerator([](const std::vector<gd::Expression>& parameters,
|
||||
|
@@ -189,6 +189,10 @@ BaseObjectExtension::BaseObjectExtension() {
|
||||
"getAverageForce().getLength"); // Deprecated
|
||||
objectExpressions["Distance"].SetFunctionName("getDistanceToObject");
|
||||
objectExpressions["SqDistance"].SetFunctionName("getSqDistanceToObject");
|
||||
objectExpressions["DistanceToPosition"].SetFunctionName("getDistanceToPosition");
|
||||
objectExpressions["SqDistanceToPosition"].SetFunctionName("getSqDistanceToPosition");
|
||||
objectExpressions["AngleToObject"].SetFunctionName("getAngleToObject");
|
||||
objectExpressions["AngleToPosition"].SetFunctionName("getAngleToPosition");
|
||||
objectExpressions["ObjectTimerElapsedTime"].SetFunctionName(
|
||||
"getTimerElapsedTimeInSeconds");
|
||||
objectStrExpressions["ObjectName"].SetFunctionName("getName");
|
||||
|
@@ -81,6 +81,13 @@ CameraExtension::CameraExtension() {
|
||||
GetAllExpressions()["LayerTimeScale"].SetFunctionName(
|
||||
"gdjs.evtTools.camera.getLayerTimeScale");
|
||||
|
||||
GetAllConditions()["LayerDefaultZOrder"].SetFunctionName(
|
||||
"gdjs.evtTools.camera.getLayerDefaultZOrder");
|
||||
GetAllActions()["SetLayerDefaultZOrder"].SetFunctionName(
|
||||
"gdjs.evtTools.camera.setLayerDefaultZOrder");
|
||||
GetAllExpressions()["LayerDefaultZOrder"].SetFunctionName(
|
||||
"gdjs.evtTools.camera.getLayerDefaultZOrder");
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions(); // Unimplemented things are
|
||||
// listed here:
|
||||
/*
|
||||
|
@@ -49,6 +49,10 @@ MathematicalToolsExtension::MathematicalToolsExtension() {
|
||||
GetAllExpressions()["mod"].SetFunctionName("gdjs.evtTools.common.mod");
|
||||
GetAllExpressions()["AngleDifference"].SetFunctionName(
|
||||
"gdjs.evtTools.common.angleDifference");
|
||||
GetAllExpressions()["AngleBetweenPositions"].SetFunctionName(
|
||||
"gdjs.evtTools.common.angleBetweenPositions");
|
||||
GetAllExpressions()["DistanceBetweenPositions"].SetFunctionName(
|
||||
"gdjs.evtTools.common.distanceBetweenPositions");
|
||||
GetAllExpressions()["int"].SetFunctionName("Math.round");
|
||||
GetAllExpressions()["rint"].SetFunctionName("Math.round");
|
||||
GetAllExpressions()["round"].SetFunctionName("Math.round");
|
||||
|
@@ -19,6 +19,8 @@ NetworkExtension::NetworkExtension() {
|
||||
"gdjs.evtTools.network.sendDeprecatedSynchronousRequest");
|
||||
GetAllActions()["SendAsyncRequest"].SetFunctionName(
|
||||
"gdjs.evtTools.network.sendAsyncRequest");
|
||||
GetAllActions()["EnableMetrics"].SetFunctionName(
|
||||
"gdjs.evtTools.network.enableMetrics");
|
||||
GetAllActions()["JSONToVariableStructure"].SetFunctionName(
|
||||
"gdjs.evtTools.network.jsonToVariableStructure");
|
||||
GetAllActions()["JSONToGlobalVariableStructure"].SetFunctionName(
|
||||
|
@@ -17,6 +17,8 @@ WindowExtension::WindowExtension() {
|
||||
|
||||
GetAllActions()["SetFullScreen"].SetFunctionName(
|
||||
"gdjs.evtTools.window.setFullScreen");
|
||||
GetAllConditions()["IsFullScreen"].SetFunctionName(
|
||||
"gdjs.evtTools.window.isFullScreen");
|
||||
GetAllActions()["SetWindowMargins"].SetFunctionName(
|
||||
"gdjs.evtTools.window.setMargins");
|
||||
GetAllActions()["SetWindowTitle"].SetFunctionName(
|
||||
|
@@ -122,8 +122,12 @@ bool Exporter::ExportWholePixiProject(
|
||||
else if (exportForFacebookInstantGames)
|
||||
source = gdjsRoot + "/Runtime/FacebookInstantGames/index.html";
|
||||
|
||||
if (!helper.ExportPixiIndexFile(
|
||||
exportedProject, source, exportDir, includesFiles, "")) {
|
||||
if (!helper.ExportPixiIndexFile(exportedProject,
|
||||
source,
|
||||
exportDir,
|
||||
includesFiles,
|
||||
/*nonRuntimeScriptsCacheBurst=*/0,
|
||||
"")) {
|
||||
gd::LogError(_("Error during export:\n") + lastError);
|
||||
return false;
|
||||
}
|
||||
@@ -211,7 +215,7 @@ bool Exporter::ExportWholeCocos2dProject(gd::Project& project,
|
||||
gd::ProjectStripper::StripProjectForExport(exportedProject);
|
||||
|
||||
//...and export it
|
||||
gd::SerializerElement noRuntimeGameOptions;
|
||||
gd::SerializerElement noRuntimeGameOptions;
|
||||
helper.ExportProjectData(
|
||||
fs, exportedProject, codeOutputDir + "/data.js", noRuntimeGameOptions);
|
||||
includesFiles.push_back(codeOutputDir + "/data.js");
|
||||
|
@@ -58,8 +58,8 @@ std::map<gd::String, gd::String> GetExtensionDependencyExtraSettingValues(
|
||||
return values;
|
||||
};
|
||||
|
||||
bool AreMapKeysMissingElementOfSet(std::map<gd::String, gd::String> map,
|
||||
std::set<gd::String> set) {
|
||||
bool AreMapKeysMissingElementOfSet(const std::map<gd::String, gd::String> &map,
|
||||
const std::set<gd::String> &set) {
|
||||
bool missingKey = false;
|
||||
for (auto &key : set) {
|
||||
if (map.find(key) == map.end()) {
|
||||
@@ -182,6 +182,7 @@ bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
gdjsRoot + "/Runtime/index.html",
|
||||
options.exportPath,
|
||||
includesFiles,
|
||||
options.nonRuntimeScriptsCacheBurst,
|
||||
"gdjs.runtimeGameOptions"))
|
||||
return false;
|
||||
|
||||
@@ -213,11 +214,16 @@ bool ExporterHelper::ExportPixiIndexFile(
|
||||
gd::String source,
|
||||
gd::String exportDir,
|
||||
const std::vector<gd::String> &includesFiles,
|
||||
unsigned int nonRuntimeScriptsCacheBurst,
|
||||
gd::String additionalSpec) {
|
||||
gd::String str = fs.ReadFile(source);
|
||||
|
||||
// Generate the file
|
||||
if (!CompleteIndexFile(str, exportDir, includesFiles, additionalSpec))
|
||||
if (!CompleteIndexFile(str,
|
||||
exportDir,
|
||||
includesFiles,
|
||||
nonRuntimeScriptsCacheBurst,
|
||||
additionalSpec))
|
||||
return false;
|
||||
|
||||
// Write the index.html file
|
||||
@@ -297,7 +303,6 @@ bool ExporterHelper::ExportCordovaFiles(const gd::Project &project,
|
||||
.FindAndReplace(
|
||||
"GDJS_PACKAGENAME",
|
||||
gd::Serializer::ToEscapedXMLString(project.GetPackageName()))
|
||||
.FindAndReplace("GDJS_ORIENTATION", project.GetOrientation())
|
||||
.FindAndReplace("GDJS_PROJECTVERSION", project.GetVersion())
|
||||
.FindAndReplace("<!-- GDJS_ICONS_ANDROID -->", makeIconsAndroid())
|
||||
.FindAndReplace("<!-- GDJS_ICONS_IOS -->", makeIconsIos());
|
||||
@@ -397,7 +402,11 @@ bool ExporterHelper::ExportCocos2dFiles(
|
||||
|
||||
// Generate the file
|
||||
std::vector<gd::String> noIncludesInThisFile;
|
||||
if (!CompleteIndexFile(str, exportDir, noIncludesInThisFile, "")) {
|
||||
if (!CompleteIndexFile(str,
|
||||
exportDir,
|
||||
noIncludesInThisFile,
|
||||
/*nonRuntimeScriptsCacheBurst=*/0,
|
||||
"")) {
|
||||
lastError = "Unable to complete Cocos2d-JS index.html file.";
|
||||
return false;
|
||||
}
|
||||
@@ -512,12 +521,10 @@ bool ExporterHelper::ExportElectronFiles(const gd::Project &project,
|
||||
}
|
||||
}
|
||||
|
||||
packages = packages.substr(
|
||||
1, packages.size()); // Remove first line break for esthetic.
|
||||
packages = packages.substr(
|
||||
0,
|
||||
packages.size() -
|
||||
1); // Remove the , at the end as last item cannot have , in JSON.
|
||||
if (!packages.empty()) {
|
||||
// Remove the , at the end as last item cannot have , in JSON.
|
||||
packages = packages.substr(0, packages.size() - 1);
|
||||
}
|
||||
|
||||
str = str.FindAndReplace("\"GDJS_EXTENSION_NPM_DEPENDENCY\": \"0\"",
|
||||
packages);
|
||||
@@ -567,12 +574,14 @@ bool ExporterHelper::CompleteIndexFile(
|
||||
gd::String &str,
|
||||
gd::String exportDir,
|
||||
const std::vector<gd::String> &includesFiles,
|
||||
unsigned int nonRuntimeScriptsCacheBurst,
|
||||
gd::String additionalSpec) {
|
||||
if (additionalSpec.empty()) additionalSpec = "{}";
|
||||
|
||||
gd::String codeFilesIncludes;
|
||||
for (auto &include : includesFiles) {
|
||||
gd::String scriptSrc = GetExportedIncludeFilename(include);
|
||||
gd::String scriptSrc =
|
||||
GetExportedIncludeFilename(include, nonRuntimeScriptsCacheBurst);
|
||||
|
||||
// Sanity check if the file exists - if not skip it to avoid
|
||||
// including it in the list of scripts.
|
||||
@@ -775,7 +784,14 @@ bool ExporterHelper::ExportExternalSourceFiles(
|
||||
}
|
||||
|
||||
gd::String ExporterHelper::GetExportedIncludeFilename(
|
||||
const gd::String &include) {
|
||||
const gd::String &include, unsigned int nonRuntimeScriptsCacheBurst) {
|
||||
auto addSearchParameterToUrl = [](const gd::String &url,
|
||||
const gd::String &urlEncodedParameterName,
|
||||
const gd::String &urlEncodedValue) {
|
||||
gd::String separator = url.find("?") == gd::String::npos ? "?" : "&";
|
||||
return url + separator + urlEncodedParameterName + "=" + urlEncodedValue;
|
||||
};
|
||||
|
||||
if (!fs.IsAbsolute(include)) {
|
||||
// By convention, an include file that is relative is relative to
|
||||
// the "<GDJS Root>/Runtime" folder, and will have the same relative
|
||||
@@ -790,7 +806,19 @@ gd::String ExporterHelper::GetExportedIncludeFilename(
|
||||
} else {
|
||||
// Note: all the code generated from events are generated in another
|
||||
// folder and fall in this case:
|
||||
return fs.FileNameFrom(include);
|
||||
gd::String resolvedInclude = fs.FileNameFrom(include);
|
||||
|
||||
if (nonRuntimeScriptsCacheBurst == 0) {
|
||||
return resolvedInclude;
|
||||
}
|
||||
|
||||
// Add the parameter to force the browser to reload the code - useful
|
||||
// for cases where the browser is caching files that are getting
|
||||
// overwritten.
|
||||
return addSearchParameterToUrl(
|
||||
resolvedInclude,
|
||||
"gdCacheBurst",
|
||||
gd::String::From(nonRuntimeScriptsCacheBurst));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -32,13 +32,17 @@ struct PreviewExportOptions {
|
||||
* \param exportPath_ The path in the filesystem where to export the files
|
||||
*/
|
||||
PreviewExportOptions(gd::Project &project_, const gd::String &exportPath_)
|
||||
: project(project_), exportPath(exportPath_), projectDataOnlyExport(false) {};
|
||||
: project(project_),
|
||||
exportPath(exportPath_),
|
||||
projectDataOnlyExport(false),
|
||||
nonRuntimeScriptsCacheBurst(0) {};
|
||||
|
||||
/**
|
||||
* \brief Set the address of the debugger server that the game should reach out to,
|
||||
* using WebSockets.
|
||||
* \brief Set the address of the debugger server that the game should reach
|
||||
* out to, using WebSockets.
|
||||
*/
|
||||
PreviewExportOptions &SetDebuggerServerAddress(const gd::String& address, const gd::String& port) {
|
||||
PreviewExportOptions &SetDebuggerServerAddress(const gd::String &address,
|
||||
const gd::String &port) {
|
||||
debuggerServerAddress = address;
|
||||
debuggerServerPort = port;
|
||||
return *this;
|
||||
@@ -76,11 +80,21 @@ struct PreviewExportOptions {
|
||||
* \brief Set if the export should only export the project data, not
|
||||
* exporting events code.
|
||||
*/
|
||||
PreviewExportOptions& SetProjectDataOnlyExport(bool enable) {
|
||||
PreviewExportOptions &SetProjectDataOnlyExport(bool enable) {
|
||||
projectDataOnlyExport = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief If set to a non zero value, the exported script URLs will have an
|
||||
* extra search parameter added (with the given value) to ensure browser cache
|
||||
* is bypassed when they are loaded.
|
||||
*/
|
||||
PreviewExportOptions &SetNonRuntimeScriptsCacheBurst(unsigned int value) {
|
||||
nonRuntimeScriptsCacheBurst = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
gd::Project &project;
|
||||
gd::String exportPath;
|
||||
gd::String debuggerServerAddress;
|
||||
@@ -89,6 +103,7 @@ struct PreviewExportOptions {
|
||||
gd::String externalLayoutName;
|
||||
std::map<gd::String, int> includeFileHashes;
|
||||
bool projectDataOnlyExport;
|
||||
unsigned int nonRuntimeScriptsCacheBurst;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -154,7 +169,8 @@ class ExporterHelper {
|
||||
|
||||
/**
|
||||
* \brief Copy all the specified files to the
|
||||
* export directory. Relative files are copied from "<GDJS root>/Runtime" directory.
|
||||
* export directory. Relative files are copied from "<GDJS root>/Runtime"
|
||||
* directory.
|
||||
*
|
||||
* \param includesFiles A vector with filenames to be copied.
|
||||
* \param exportDir The directory where the files mus tbe copied.
|
||||
@@ -186,8 +202,8 @@ class ExporterHelper {
|
||||
* \brief Add the include files for all the objects of the project
|
||||
* and their behaviors.
|
||||
*/
|
||||
void ExportObjectAndBehaviorsIncludes(
|
||||
gd::Project &project, std::vector<gd::String> &includesFiles);
|
||||
void ExportObjectAndBehaviorsIncludes(gd::Project &project,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
|
||||
/**
|
||||
* \brief Copy the external source files used by the game into the export
|
||||
@@ -214,13 +230,18 @@ class ExporterHelper {
|
||||
* \param source The file to be used as a template for the final file.
|
||||
* \param exportDir The directory where the preview must be created.
|
||||
* \param includesFiles The JS files to be included in the HTML file. Order is
|
||||
* important. \param additionalSpec JSON string that will be passed to the
|
||||
* important.
|
||||
* \param nonRuntimeScriptsCacheBurst If non zero, add an additional cache
|
||||
* bursting parameter to scripts, that are not part of the runtime/extensions,
|
||||
* to force the browser to reload them.
|
||||
* \param additionalSpec JSON string that will be passed to the
|
||||
* gdjs.RuntimeGame object.
|
||||
*/
|
||||
bool ExportPixiIndexFile(const gd::Project &project,
|
||||
gd::String source,
|
||||
gd::String exportDir,
|
||||
const std::vector<gd::String> &includesFiles,
|
||||
unsigned int nonRuntimeScriptsCacheBurst,
|
||||
gd::String additionalSpec = "");
|
||||
|
||||
/**
|
||||
@@ -232,6 +253,9 @@ class ExporterHelper {
|
||||
* \param includesFiles "<!--GDJS_CODE_FILES -->" will be
|
||||
* replaced by HTML tags to include the filenames
|
||||
* contained inside the vector.
|
||||
* \param nonRuntimeScriptsCacheBurst If non zero, add an additional cache
|
||||
* bursting parameter to scripts, that are not part of the runtime/extensions,
|
||||
* to force the browser to reload them.
|
||||
* \param additionalSpec The string "GDJS_ADDITIONAL_SPEC"
|
||||
* surrounded by comments marks will be replaced by the
|
||||
* content of this string.
|
||||
@@ -239,6 +263,7 @@ class ExporterHelper {
|
||||
bool CompleteIndexFile(gd::String &indexFileContent,
|
||||
gd::String exportDir,
|
||||
const std::vector<gd::String> &includesFiles,
|
||||
unsigned int nonRuntimeScriptsCacheBurst,
|
||||
gd::String additionalSpec);
|
||||
|
||||
/**
|
||||
@@ -290,7 +315,8 @@ class ExporterHelper {
|
||||
* \brief Given an include file, returns the name of the file to reference
|
||||
* in the exported game.
|
||||
*/
|
||||
gd::String GetExportedIncludeFilename(const gd::String& include);
|
||||
gd::String GetExportedIncludeFilename(
|
||||
const gd::String &include, unsigned int nonRuntimeScriptsCacheBurst = 0);
|
||||
|
||||
/**
|
||||
* \brief Change the directory where code files are generated.
|
||||
@@ -302,10 +328,10 @@ class ExporterHelper {
|
||||
}
|
||||
|
||||
static void AddDeprecatedFontFilesToFontResources(
|
||||
gd::AbstractFileSystem &fs,
|
||||
gd::ResourcesManager &resourcesManager,
|
||||
const gd::String &exportDir,
|
||||
gd::String urlPrefix = "");
|
||||
gd::AbstractFileSystem &fs,
|
||||
gd::ResourcesManager &resourcesManager,
|
||||
const gd::String &exportDir,
|
||||
gd::String urlPrefix = "");
|
||||
|
||||
gd::AbstractFileSystem
|
||||
&fs; ///< The abstract file system to be used for exportation.
|
||||
|
@@ -3,6 +3,7 @@
|
||||
<name>GDJS_PROJECTNAME</name>
|
||||
<content src="index.html" />
|
||||
<plugin name="cordova-plugin-whitelist" version="1" />
|
||||
<plugin name="cordova-plugin-screen-orientation" version="3.0.2" />
|
||||
<access origin="*" />
|
||||
<allow-intent href="http://*/*" />
|
||||
<allow-intent href="https://*/*" />
|
||||
@@ -21,7 +22,6 @@
|
||||
|
||||
<!-- GDJS_ICONS_IOS -->
|
||||
</platform>
|
||||
<preference name="orientation" value="GDJS_ORIENTATION" />
|
||||
<preference name="BackgroundColor" value="0xff000000"/>
|
||||
|
||||
<!-- Android Fullscreen -->
|
||||
|
@@ -49,6 +49,17 @@ gdjs.RuntimeGameCocosRenderer.prototype.setFullScreen = function(enable) {
|
||||
console.warn("Fullscreen is not implemented yet.");
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the game is in full screen.
|
||||
*/
|
||||
gdjs.RuntimeGameCocosRenderer.prototype.isFullScreen = function() {
|
||||
var electron = this.getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.getCurrentWindow().isFullScreen();
|
||||
}
|
||||
return false; // Unsupported
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the window size, if possible.
|
||||
* @param {number} width The new width, in pixels.
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// @ts-check
|
||||
/*
|
||||
* GDevelop JS Platform
|
||||
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
@@ -11,116 +12,270 @@
|
||||
*/
|
||||
gdjs.evtTools.camera = gdjs.evtTools.camera || {};
|
||||
|
||||
gdjs.evtTools.camera.setCameraX = function(runtimeScene, x, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {number} x
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
*/
|
||||
gdjs.evtTools.camera.setCameraX = function (runtimeScene, x, layer, cameraId) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
runtimeScene.getLayer(layer).setCameraX(x, cameraId);
|
||||
}
|
||||
runtimeScene.getLayer(layer).setCameraX(x, cameraId);
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.setCameraY = function(runtimeScene, y, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {number} y
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
*/
|
||||
gdjs.evtTools.camera.setCameraY = function (runtimeScene, y, layer, cameraId) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
runtimeScene.getLayer(layer).setCameraY(y, cameraId);
|
||||
}
|
||||
runtimeScene.getLayer(layer).setCameraY(y, cameraId);
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.getCameraX = function(runtimeScene, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return 0; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.camera.getCameraX = function (runtimeScene, layer, cameraId) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).getCameraX();
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraX();
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.getCameraY = function(runtimeScene, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return 0; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.camera.getCameraY = function (runtimeScene, layer, cameraId) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).getCameraY();
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraY();
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.getCameraWidth = function(runtimeScene, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return 0; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.camera.getCameraWidth = function (runtimeScene, layer, cameraId) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).getCameraWidth();
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraWidth();
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.getCameraHeight = function(runtimeScene, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return 0; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.camera.getCameraHeight = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
cameraId
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).getCameraHeight();
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraHeight();
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.showLayer = function(runtimeScene, layer) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
*/
|
||||
gdjs.evtTools.camera.showLayer = function (runtimeScene, layer) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).show(true);
|
||||
}
|
||||
return runtimeScene.getLayer(layer).show(true);
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.hideLayer = function(runtimeScene, layer) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
*/
|
||||
gdjs.evtTools.camera.hideLayer = function (runtimeScene, layer) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).show(false);
|
||||
}
|
||||
return runtimeScene.getLayer(layer).show(false);
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.layerIsVisible = function(runtimeScene, layer) {
|
||||
return runtimeScene.hasLayer(layer) && runtimeScene.getLayer(layer).isVisible();
|
||||
}
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.camera.layerIsVisible = function (runtimeScene, layer) {
|
||||
return (
|
||||
runtimeScene.hasLayer(layer) && runtimeScene.getLayer(layer).isVisible()
|
||||
);
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.setCameraRotation = function(runtimeScene, rotation, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {number} rotation
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
*/
|
||||
gdjs.evtTools.camera.setCameraRotation = function (
|
||||
runtimeScene,
|
||||
rotation,
|
||||
layer,
|
||||
cameraId
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).setCameraRotation(rotation, cameraId);
|
||||
}
|
||||
gdjs.evtTools.camera.getCameraRotation = function(runtimeScene, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return 0; }
|
||||
return runtimeScene.getLayer(layer).setCameraRotation(rotation, cameraId);
|
||||
};
|
||||
|
||||
return runtimeScene.getLayer(layer).getCameraRotation(cameraId);
|
||||
}
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.camera.getCameraRotation = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
cameraId
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gdjs.evtTools.camera.setCameraZoom = function(runtimeScene, newZoom, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
return runtimeScene.getLayer(layer).getCameraRotation(cameraId);
|
||||
};
|
||||
|
||||
return runtimeScene.getLayer(layer).setCameraZoom(newZoom, cameraId);
|
||||
}
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {number} newZoom
|
||||
* @param {string} layer
|
||||
* @param {number} cameraId
|
||||
*/
|
||||
gdjs.evtTools.camera.setCameraZoom = function (
|
||||
runtimeScene,
|
||||
newZoom,
|
||||
layer,
|
||||
cameraId
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gdjs.evtTools.camera.centerCamera = function(runtimeScene, object, anticipateMove, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) || object == null ) { return; }
|
||||
return runtimeScene.getLayer(layer).setCameraZoom(newZoom, cameraId);
|
||||
};
|
||||
|
||||
var layer = runtimeScene.getLayer(layer);
|
||||
var xOffset = 0; var yOffset = 0;
|
||||
if ( anticipateMove && !object.hasNoForces() ) {
|
||||
var objectAverageForce = object.getAverageForce();
|
||||
var elapsedTimeInSeconds = object.getElapsedTime(runtimeScene) / 1000;
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {?gdjs.RuntimeObject} object
|
||||
* @param {boolean} anticipateMove
|
||||
* @param {string} layerName
|
||||
* @param {number} cameraId
|
||||
*/
|
||||
gdjs.evtTools.camera.centerCamera = function (
|
||||
runtimeScene,
|
||||
object,
|
||||
anticipateMove,
|
||||
layerName,
|
||||
cameraId
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layerName) || object == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
xOffset = objectAverageForce.getX() * elapsedTimeInSeconds;
|
||||
yOffset = objectAverageForce.getY() * elapsedTimeInSeconds;
|
||||
}
|
||||
var layer = runtimeScene.getLayer(layerName);
|
||||
var xOffset = 0;
|
||||
var yOffset = 0;
|
||||
if (anticipateMove && !object.hasNoForces()) {
|
||||
var objectAverageForce = object.getAverageForce();
|
||||
var elapsedTimeInSeconds = object.getElapsedTime(runtimeScene) / 1000;
|
||||
|
||||
layer.setCameraX(object.getDrawableX()+object.getCenterX(), cameraId);
|
||||
layer.setCameraY(object.getDrawableY()+object.getCenterY(), cameraId);
|
||||
}
|
||||
xOffset = objectAverageForce.getX() * elapsedTimeInSeconds;
|
||||
yOffset = objectAverageForce.getY() * elapsedTimeInSeconds;
|
||||
}
|
||||
|
||||
gdjs.evtTools.camera.centerCameraWithinLimits = function(runtimeScene, object, left, top, right, bottom, anticipateMove, layer, cameraId) {
|
||||
if ( !runtimeScene.hasLayer(layer) || object == null ) { return; }
|
||||
layer.setCameraX(object.getDrawableX() + object.getCenterX(), cameraId);
|
||||
layer.setCameraY(object.getDrawableY() + object.getCenterY(), cameraId);
|
||||
};
|
||||
|
||||
var layer = runtimeScene.getLayer(layer);
|
||||
var xOffset = 0; var yOffset = 0;
|
||||
if ( anticipateMove && !object.hasNoForces() ) {
|
||||
var objectAverageForce = object.getAverageForce();
|
||||
var elapsedTimeInSeconds = object.getElapsedTime(runtimeScene) / 1000;
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {?gdjs.RuntimeObject} object
|
||||
* @param {number} left
|
||||
* @param {number} top
|
||||
* @param {number} right
|
||||
* @param {number} bottom
|
||||
* @param {boolean} anticipateMove
|
||||
* @param {string} layerName
|
||||
* @param {number} cameraId
|
||||
*/
|
||||
gdjs.evtTools.camera.centerCameraWithinLimits = function (
|
||||
runtimeScene,
|
||||
object,
|
||||
left,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
anticipateMove,
|
||||
layerName,
|
||||
cameraId
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layerName) || object == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
xOffset = objectAverageForce.getX() * elapsedTimeInSeconds;
|
||||
yOffset = objectAverageForce.getY() * elapsedTimeInSeconds;
|
||||
}
|
||||
var layer = runtimeScene.getLayer(layerName);
|
||||
var xOffset = 0;
|
||||
var yOffset = 0;
|
||||
if (anticipateMove && !object.hasNoForces()) {
|
||||
var objectAverageForce = object.getAverageForce();
|
||||
var elapsedTimeInSeconds = object.getElapsedTime(runtimeScene) / 1000;
|
||||
|
||||
var newX = object.getDrawableX()+object.getCenterX()+xOffset;
|
||||
if ( newX < left +layer.getCameraWidth(cameraId)/2 ) newX = left+layer.getCameraWidth(cameraId)/2;
|
||||
if ( newX > right-layer.getCameraWidth(cameraId)/2 ) newX = right-layer.getCameraWidth(cameraId)/2;
|
||||
xOffset = objectAverageForce.getX() * elapsedTimeInSeconds;
|
||||
yOffset = objectAverageForce.getY() * elapsedTimeInSeconds;
|
||||
}
|
||||
|
||||
var newY = object.getDrawableY()+object.getCenterY()+yOffset;
|
||||
if ( newY < top +layer.getCameraHeight(cameraId)/2 ) newY = top+layer.getCameraHeight(cameraId)/2;
|
||||
if ( newY > bottom-layer.getCameraHeight(cameraId)/2 ) newY = bottom-layer.getCameraHeight(cameraId)/2;
|
||||
var newX = object.getDrawableX() + object.getCenterX() + xOffset;
|
||||
if (newX < left + layer.getCameraWidth(cameraId) / 2)
|
||||
newX = left + layer.getCameraWidth(cameraId) / 2;
|
||||
if (newX > right - layer.getCameraWidth(cameraId) / 2)
|
||||
newX = right - layer.getCameraWidth(cameraId) / 2;
|
||||
|
||||
layer.setCameraX(newX, cameraId);
|
||||
layer.setCameraY(newY, cameraId);
|
||||
}
|
||||
var newY = object.getDrawableY() + object.getCenterY() + yOffset;
|
||||
if (newY < top + layer.getCameraHeight(cameraId) / 2)
|
||||
newY = top + layer.getCameraHeight(cameraId) / 2;
|
||||
if (newY > bottom - layer.getCameraHeight(cameraId) / 2)
|
||||
newY = bottom - layer.getCameraHeight(cameraId) / 2;
|
||||
|
||||
layer.setCameraX(newX, cameraId);
|
||||
layer.setCameraY(newY, cameraId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update a layer effect parameter (with a number).
|
||||
@@ -130,11 +285,21 @@ gdjs.evtTools.camera.centerCameraWithinLimits = function(runtimeScene, object, l
|
||||
* @param {string} parameter The parameter to update
|
||||
* @param {number} value The new value
|
||||
*/
|
||||
gdjs.evtTools.camera.setLayerEffectDoubleParameter = function(runtimeScene, layer, effect, parameter, value) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
gdjs.evtTools.camera.setLayerEffectDoubleParameter = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
effect,
|
||||
parameter,
|
||||
value
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).setEffectDoubleParameter(effect, parameter, value);
|
||||
}
|
||||
return runtimeScene
|
||||
.getLayer(layer)
|
||||
.setEffectDoubleParameter(effect, parameter, value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update a layer effect parameter (with a string).
|
||||
@@ -144,11 +309,21 @@ gdjs.evtTools.camera.setLayerEffectDoubleParameter = function(runtimeScene, laye
|
||||
* @param {string} parameter The parameter to update
|
||||
* @param {string} value The new value
|
||||
*/
|
||||
gdjs.evtTools.camera.setLayerEffectStringParameter = function(runtimeScene, layer, effect, parameter, value) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
gdjs.evtTools.camera.setLayerEffectStringParameter = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
effect,
|
||||
parameter,
|
||||
value
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).setEffectStringParameter(effect, parameter, value);
|
||||
}
|
||||
return runtimeScene
|
||||
.getLayer(layer)
|
||||
.setEffectStringParameter(effect, parameter, value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable or disable a layer effect parameter (boolean).
|
||||
@@ -158,11 +333,21 @@ gdjs.evtTools.camera.setLayerEffectStringParameter = function(runtimeScene, laye
|
||||
* @param {string} parameter The parameter to update
|
||||
* @param {boolean} value The new value
|
||||
*/
|
||||
gdjs.evtTools.camera.setLayerEffectBooleanParameter = function(runtimeScene, layer, effect, parameter, value) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
gdjs.evtTools.camera.setLayerEffectBooleanParameter = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
effect,
|
||||
parameter,
|
||||
value
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).setEffectBooleanParameter(effect, parameter, value);
|
||||
}
|
||||
return runtimeScene
|
||||
.getLayer(layer)
|
||||
.setEffectBooleanParameter(effect, parameter, value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable, or disable, an effect of a layer.
|
||||
@@ -171,11 +356,18 @@ gdjs.evtTools.camera.setLayerEffectBooleanParameter = function(runtimeScene, lay
|
||||
* @param {string} effect The name of the effect
|
||||
* @param {boolean} enabled true to enable, false to disable.
|
||||
*/
|
||||
gdjs.evtTools.camera.enableLayerEffect = function(runtimeScene, layer, effect, enabled) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
gdjs.evtTools.camera.enableLayerEffect = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
effect,
|
||||
enabled
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
runtimeScene.getLayer(layer).enableEffect(effect, enabled);
|
||||
}
|
||||
runtimeScene.getLayer(layer).enableEffect(effect, enabled);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if an effect is enabled.
|
||||
@@ -184,18 +376,70 @@ gdjs.evtTools.camera.enableLayerEffect = function(runtimeScene, layer, effect, e
|
||||
* @param {string} effect The name of the effect
|
||||
* @return {boolean} true if the effect is enabled, false otherwise.
|
||||
*/
|
||||
gdjs.evtTools.camera.layerEffectEnabled = function(runtimeScene, layer, effect) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return true; }
|
||||
gdjs.evtTools.camera.layerEffectEnabled = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
effect
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return runtimeScene.getLayer(layer).isEffectEnabled(effect);
|
||||
}
|
||||
return runtimeScene.getLayer(layer).isEffectEnabled(effect);
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.setLayerTimeScale = function(runtimeScene, layer, timeScale) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return; }
|
||||
return runtimeScene.getLayer(layer).setTimeScale(timeScale);
|
||||
}
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @param {number} timeScale
|
||||
*/
|
||||
gdjs.evtTools.camera.setLayerTimeScale = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
timeScale
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
return runtimeScene.getLayer(layer).setTimeScale(timeScale);
|
||||
};
|
||||
|
||||
gdjs.evtTools.camera.getLayerTimeScale = function(runtimeScene, layer) {
|
||||
if ( !runtimeScene.hasLayer(layer) ) { return 1; }
|
||||
return runtimeScene.getLayer(layer).getTimeScale();
|
||||
}
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.camera.getLayerTimeScale = function (runtimeScene, layer) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return 1;
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getTimeScale();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @param {number} defaultZOrder
|
||||
*/
|
||||
gdjs.evtTools.camera.setLayerDefaultZOrder = function (
|
||||
runtimeScene,
|
||||
layer,
|
||||
defaultZOrder
|
||||
) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return;
|
||||
}
|
||||
return runtimeScene.getLayer(layer).setDefaultZOrder(defaultZOrder);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} layer
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.camera.getLayerDefaultZOrder = function (runtimeScene, layer) {
|
||||
if (!runtimeScene.hasLayer(layer)) {
|
||||
return 0;
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getDefaultZOrder();
|
||||
};
|
||||
|
@@ -17,7 +17,7 @@ gdjs.evtTools.common = gdjs.evtTools.common || {};
|
||||
* @returns {number} The content of the variable, as a number.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.getVariableNumber = function(variable) {
|
||||
gdjs.evtTools.common.getVariableNumber = function (variable) {
|
||||
return variable.getAsNumber();
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ gdjs.evtTools.common.getVariableNumber = function(variable) {
|
||||
* @returns {string} The content of the variable, as a string.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.getVariableString = function(variable) {
|
||||
gdjs.evtTools.common.getVariableString = function (variable) {
|
||||
return variable.getAsString();
|
||||
};
|
||||
|
||||
@@ -38,7 +38,10 @@ gdjs.evtTools.common.getVariableString = function(variable) {
|
||||
* @returns {boolean} true if the scene variable exits, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.sceneVariableExists = function(runtimeScene, variableName) {
|
||||
gdjs.evtTools.common.sceneVariableExists = function (
|
||||
runtimeScene,
|
||||
variableName
|
||||
) {
|
||||
return runtimeScene.getVariables().has(variableName);
|
||||
};
|
||||
|
||||
@@ -49,7 +52,10 @@ gdjs.evtTools.common.sceneVariableExists = function(runtimeScene, variableName)
|
||||
* @returns {boolean} true if the global variable exits, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.globalVariableExists = function(runtimeScene, variableName) {
|
||||
gdjs.evtTools.common.globalVariableExists = function (
|
||||
runtimeScene,
|
||||
variableName
|
||||
) {
|
||||
return runtimeScene.getGame().getVariables().has(variableName);
|
||||
};
|
||||
|
||||
@@ -60,7 +66,7 @@ gdjs.evtTools.common.globalVariableExists = function(runtimeScene, variableName)
|
||||
* @returns {boolean} true if child exist in the variable, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.variableChildExists = function(variable, childName) {
|
||||
gdjs.evtTools.common.variableChildExists = function (variable, childName) {
|
||||
return variable.hasChild(childName);
|
||||
};
|
||||
|
||||
@@ -71,7 +77,7 @@ gdjs.evtTools.common.variableChildExists = function(variable, childName) {
|
||||
* @returns {gdjs.Variable} The new variable, with the child removed.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.variableRemoveChild = function(variable, childName) {
|
||||
gdjs.evtTools.common.variableRemoveChild = function (variable, childName) {
|
||||
return variable.removeChild(childName);
|
||||
};
|
||||
|
||||
@@ -80,7 +86,7 @@ gdjs.evtTools.common.variableRemoveChild = function(variable, childName) {
|
||||
* @param {gdjs.Variable} variable Variable.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.variableClearChildren = function(variable) {
|
||||
gdjs.evtTools.common.variableClearChildren = function (variable) {
|
||||
variable.clearChildren();
|
||||
};
|
||||
|
||||
@@ -90,7 +96,7 @@ gdjs.evtTools.common.variableClearChildren = function(variable) {
|
||||
* @returns {number} The number of children in the variable.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.getVariableChildCount = function(variable) {
|
||||
gdjs.evtTools.common.getVariableChildCount = function (variable) {
|
||||
if (variable.isStructure() == false) return 0;
|
||||
return Object.keys(variable.getAllChildren()).length;
|
||||
};
|
||||
@@ -101,7 +107,7 @@ gdjs.evtTools.common.getVariableChildCount = function(variable) {
|
||||
* @returns {number} The parsed number, or NaN if invalid.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.toNumber = function(str) {
|
||||
gdjs.evtTools.common.toNumber = function (str) {
|
||||
return parseFloat(str);
|
||||
};
|
||||
|
||||
@@ -111,7 +117,7 @@ gdjs.evtTools.common.toNumber = function(str) {
|
||||
* @returns {string} The value as a string.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.toString = function(num) {
|
||||
gdjs.evtTools.common.toString = function (num) {
|
||||
//Using String literal is fastest than using toString according to
|
||||
//http://jsperf.com/number-to-string/2 and http://jsben.ch/#/ghQYR
|
||||
return '' + num;
|
||||
@@ -123,7 +129,7 @@ gdjs.evtTools.common.toString = function(num) {
|
||||
* @returns {boolean} The negated value.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.common.logicalNegation = function(bool) {
|
||||
gdjs.evtTools.common.logicalNegation = function (bool) {
|
||||
return !bool;
|
||||
};
|
||||
|
||||
@@ -134,7 +140,7 @@ gdjs.evtTools.common.logicalNegation = function(bool) {
|
||||
* @param {number} max The maximum value.
|
||||
* @returns {number} The new value.
|
||||
*/
|
||||
gdjs.evtTools.common.clamp = function(x, min, max) {
|
||||
gdjs.evtTools.common.clamp = function (x, min, max) {
|
||||
return Math.min(Math.max(x, min), max);
|
||||
};
|
||||
|
||||
@@ -143,7 +149,7 @@ gdjs.evtTools.common.clamp = function(x, min, max) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The hyperbolic arc-cosine for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.acosh = function(arg) {
|
||||
gdjs.evtTools.common.acosh = function (arg) {
|
||||
// http://kevin.vanzonneveld.net
|
||||
// + original by: Onno Marsman
|
||||
return Math.log(arg + Math.sqrt(arg * arg - 1));
|
||||
@@ -154,7 +160,7 @@ gdjs.evtTools.common.acosh = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The hyperbolic arcsine for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.asinh = function(arg) {
|
||||
gdjs.evtTools.common.asinh = function (arg) {
|
||||
// http://kevin.vanzonneveld.net
|
||||
// + original by: Onno Marsman
|
||||
return Math.log(arg + Math.sqrt(arg * arg + 1));
|
||||
@@ -165,7 +171,7 @@ gdjs.evtTools.common.asinh = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The hyperbolic arctangent for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.atanh = function(arg) {
|
||||
gdjs.evtTools.common.atanh = function (arg) {
|
||||
// http://kevin.vanzonneveld.net
|
||||
// + original by: Onno Marsman
|
||||
return 0.5 * Math.log((1 + arg) / (1 - arg));
|
||||
@@ -176,7 +182,7 @@ gdjs.evtTools.common.atanh = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The hyperbolic cosine for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.cosh = function(arg) {
|
||||
gdjs.evtTools.common.cosh = function (arg) {
|
||||
return (Math.exp(arg) + Math.exp(-arg)) / 2;
|
||||
};
|
||||
|
||||
@@ -185,7 +191,7 @@ gdjs.evtTools.common.cosh = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The hyperbolic sine for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.sinh = function(arg) {
|
||||
gdjs.evtTools.common.sinh = function (arg) {
|
||||
return (Math.exp(arg) - Math.exp(-arg)) / 2;
|
||||
};
|
||||
|
||||
@@ -194,7 +200,7 @@ gdjs.evtTools.common.sinh = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The hyperbolic tangent for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.tanh = function(arg) {
|
||||
gdjs.evtTools.common.tanh = function (arg) {
|
||||
return (Math.exp(arg) - Math.exp(-arg)) / (Math.exp(arg) + Math.exp(-arg));
|
||||
};
|
||||
|
||||
@@ -203,7 +209,7 @@ gdjs.evtTools.common.tanh = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The cotangent for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.cot = function(arg) {
|
||||
gdjs.evtTools.common.cot = function (arg) {
|
||||
return 1 / Math.tan(arg);
|
||||
};
|
||||
|
||||
@@ -212,7 +218,7 @@ gdjs.evtTools.common.cot = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The cosecant for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.csc = function(arg) {
|
||||
gdjs.evtTools.common.csc = function (arg) {
|
||||
return 1 / Math.sin(arg);
|
||||
};
|
||||
|
||||
@@ -221,7 +227,7 @@ gdjs.evtTools.common.csc = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The secant for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.sec = function(arg) {
|
||||
gdjs.evtTools.common.sec = function (arg) {
|
||||
return 1 / Math.cos(arg);
|
||||
};
|
||||
|
||||
@@ -230,7 +236,7 @@ gdjs.evtTools.common.sec = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The base-10 logarithm for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.log10 = function(arg) {
|
||||
gdjs.evtTools.common.log10 = function (arg) {
|
||||
return Math.log(arg) / Math.LN10;
|
||||
};
|
||||
|
||||
@@ -239,7 +245,7 @@ gdjs.evtTools.common.log10 = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} The base-2 logarithm for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.log2 = function(arg) {
|
||||
gdjs.evtTools.common.log2 = function (arg) {
|
||||
return Math.log(arg) / Math.LN2;
|
||||
};
|
||||
|
||||
@@ -248,7 +254,7 @@ gdjs.evtTools.common.log2 = function(arg) {
|
||||
* @param {number} arg Value.
|
||||
* @returns {number} Return the sign for the value (1, -1 or 0).
|
||||
*/
|
||||
gdjs.evtTools.common.sign = function(arg) {
|
||||
gdjs.evtTools.common.sign = function (arg) {
|
||||
if (arg === 0) return 0;
|
||||
|
||||
return arg > 0 ? +1 : -1;
|
||||
@@ -259,7 +265,7 @@ gdjs.evtTools.common.sign = function(arg) {
|
||||
* @param {number} x Value.
|
||||
* @returns {number} Return the cube root for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.cbrt = function(x) {
|
||||
gdjs.evtTools.common.cbrt = function (x) {
|
||||
return Math.pow(x, 1 / 3);
|
||||
};
|
||||
|
||||
@@ -269,7 +275,7 @@ gdjs.evtTools.common.cbrt = function(x) {
|
||||
* @param {number} n Exponent value.
|
||||
* @returns {number} Return the n-th root for the value.
|
||||
*/
|
||||
gdjs.evtTools.common.nthroot = function(x, n) {
|
||||
gdjs.evtTools.common.nthroot = function (x, n) {
|
||||
return Math.pow(x, 1 / n);
|
||||
};
|
||||
|
||||
@@ -279,7 +285,7 @@ gdjs.evtTools.common.nthroot = function(x, n) {
|
||||
* @param {number} y Divisor value.
|
||||
* @returns {number} Return the remainder for the values.
|
||||
*/
|
||||
gdjs.evtTools.common.mod = function(x, y) {
|
||||
gdjs.evtTools.common.mod = function (x, y) {
|
||||
return x - y * Math.floor(x / y);
|
||||
};
|
||||
|
||||
@@ -289,8 +295,37 @@ gdjs.evtTools.common.mod = function(x, y) {
|
||||
* @param {number} angle2 Second angle, in degrees.
|
||||
* @returns {number} Return the difference of the angles, in degrees.
|
||||
*/
|
||||
gdjs.evtTools.common.angleDifference = function(angle1, angle2) {
|
||||
return gdjs.evtTools.common.mod(gdjs.evtTools.common.mod(angle1 - angle2, 360.0) + 180.0, 360.0) - 180.0;
|
||||
gdjs.evtTools.common.angleDifference = function (angle1, angle2) {
|
||||
return (
|
||||
gdjs.evtTools.common.mod(
|
||||
gdjs.evtTools.common.mod(angle1 - angle2, 360.0) + 180.0,
|
||||
360.0
|
||||
) - 180.0
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the angle, in degrees, between two positions.
|
||||
* @param {number} x1 First point X position.
|
||||
* @param {number} y1 First point Y position.
|
||||
* @param {number} x2 Second point X position.
|
||||
* @param {number} y2 Second point Y position.
|
||||
* @returns {number} The angle between the positions, in degrees.
|
||||
*/
|
||||
gdjs.evtTools.common.angleBetweenPositions = function (x1, y1, x2, y2) {
|
||||
return (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the distance, in pixels, between two positions.
|
||||
* @param {number} x1 First point X position.
|
||||
* @param {number} y1 First point Y position.
|
||||
* @param {number} x2 Second point X position.
|
||||
* @param {number} y2 Second point Y position.
|
||||
* @returns {number} The distance between the positions, in pixels.
|
||||
*/
|
||||
gdjs.evtTools.common.distanceBetweenPositions = function (x1, y1, x2, y2) {
|
||||
return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -300,7 +335,7 @@ gdjs.evtTools.common.angleDifference = function(angle1, angle2) {
|
||||
* @param {number} x The interpolation value between 0 and 1.
|
||||
* @returns {number} The interpolated value, now between a and b.
|
||||
*/
|
||||
gdjs.evtTools.common.lerp = function(a, b, x) {
|
||||
gdjs.evtTools.common.lerp = function (a, b, x) {
|
||||
return a + (b - a) * x;
|
||||
};
|
||||
|
||||
@@ -309,6 +344,6 @@ gdjs.evtTools.common.lerp = function(a, b, x) {
|
||||
* @param {number} x Value.
|
||||
* @returns {number} Return the value with all decimal places dropped.
|
||||
*/
|
||||
gdjs.evtTools.common.trunc = function(x) {
|
||||
gdjs.evtTools.common.trunc = function (x) {
|
||||
return x | 0;
|
||||
};
|
||||
|
@@ -102,6 +102,14 @@ gdjs.evtTools.network.sendDeprecatedSynchronousRequest = function (
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {boolean} enable
|
||||
*/
|
||||
gdjs.evtTools.network.enableMetrics = function(runtimeScene, enable) {
|
||||
runtimeScene.getGame().enableMetrics(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a variable to JSON.
|
||||
* TODO: Move to gdjs.Variable static
|
||||
@@ -176,7 +184,7 @@ gdjs.evtTools.network.jsonToVariableStructure = function (jsonStr, variable) {
|
||||
gdjs.evtTools.network._objectToVariable(obj, variable);
|
||||
return true;
|
||||
} catch (e) {
|
||||
//Do nothing iF JSON was not properly parsed;
|
||||
// Do nothing if JSON was not properly parsed.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@@ -319,7 +319,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);
|
||||
var distance = object.getSqDistanceToPosition(x, y);
|
||||
if( first || (distance < best ^ inverted)) {
|
||||
best = distance;
|
||||
bestObject = object;
|
||||
@@ -389,18 +389,26 @@ gdjs.evtTools.object.raycastObjectToPosition = function(objectsLists, x, y, endX
|
||||
/**
|
||||
* Do the work of creating a new object
|
||||
* @private
|
||||
* @param {EventsFunctionContext | gdjs.RuntimeScene} objectsContext
|
||||
* @param {string} objectName
|
||||
* @param {Hashtable} objectsLists
|
||||
* @param {x} number
|
||||
* @param {y} number
|
||||
* @param {string} layerName
|
||||
*/
|
||||
gdjs.evtTools.object.doCreateObjectOnScene = function(objectsContext, objectName, objectsLists, x, y, layer) {
|
||||
gdjs.evtTools.object.doCreateObjectOnScene = function(objectsContext, objectName, objectsLists, x, y, layerName) {
|
||||
// objectsContext will either be the gdjs.RuntimeScene or, in an events function, the
|
||||
// eventsFunctionContext. We can't directly use runtimeScene because the object name could
|
||||
// be different than the real object name (this is the case in a function. The eventsFunctionContext
|
||||
// will take care of this in createObject).
|
||||
var obj = objectsContext.createObject(objectName);
|
||||
var layer = objectsContext.getLayer(layerName);
|
||||
|
||||
if ( obj !== null ) {
|
||||
//Do some extra setup
|
||||
obj.setPosition(x,y);
|
||||
obj.setLayer(layer);
|
||||
obj.setLayer(layerName);
|
||||
obj.setZOrder(layer.getDefaultZOrder());
|
||||
|
||||
//Let the new object be picked by next actions/conditions.
|
||||
if ( objectsLists.containsKey(objectName) ) {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// @ts-check
|
||||
/*
|
||||
* GDevelop JS Platform
|
||||
* Copyright 2013-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
@@ -13,68 +14,161 @@
|
||||
*/
|
||||
gdjs.evtTools.window = gdjs.evtTools.window || {};
|
||||
|
||||
gdjs.evtTools.window.setMargins = function(runtimeScene, top, right, bottom, left) {
|
||||
runtimeScene.getGame().getRenderer().setMargins(top, right, bottom, left);
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {number} top
|
||||
* @param {number} right
|
||||
* @param {number} bottom
|
||||
* @param {number} left
|
||||
*/
|
||||
gdjs.evtTools.window.setMargins = function (
|
||||
runtimeScene,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
left
|
||||
) {
|
||||
runtimeScene.getGame().getRenderer().setMargins(top, right, bottom, left);
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.setFullScreen = function(runtimeScene, enable, keepAspectRatio) {
|
||||
runtimeScene.getGame().getRenderer().keepAspectRatio(keepAspectRatio);
|
||||
runtimeScene.getGame().getRenderer().setFullScreen(enable);
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {boolean} enable
|
||||
* @param {boolean} keepAspectRatio
|
||||
*/
|
||||
gdjs.evtTools.window.setFullScreen = function (
|
||||
runtimeScene,
|
||||
enable,
|
||||
keepAspectRatio
|
||||
) {
|
||||
runtimeScene.getGame().getRenderer().keepAspectRatio(keepAspectRatio);
|
||||
runtimeScene.getGame().getRenderer().setFullScreen(enable);
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.setWindowSize = function(runtimeScene, width, height, updateGameResolution) {
|
||||
runtimeScene.getGame().getRenderer().setWindowSize(width, height);
|
||||
if (updateGameResolution) {
|
||||
runtimeScene.getGame().setGameResolutionSize(width, height);
|
||||
}
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.window.isFullScreen = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getRenderer().isFullScreen();
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.centerWindow = function(runtimeScene) {
|
||||
runtimeScene.getGame().getRenderer().centerWindow();
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {boolean} updateGameResolution
|
||||
*/
|
||||
gdjs.evtTools.window.setWindowSize = function (
|
||||
runtimeScene,
|
||||
width,
|
||||
height,
|
||||
updateGameResolution
|
||||
) {
|
||||
runtimeScene.getGame().getRenderer().setWindowSize(width, height);
|
||||
if (updateGameResolution) {
|
||||
runtimeScene.getGame().setGameResolutionSize(width, height);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.setGameResolutionSize = function(runtimeScene, width, height) {
|
||||
runtimeScene.getGame().setGameResolutionSize(width, height);
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
*/
|
||||
gdjs.evtTools.window.centerWindow = function (runtimeScene) {
|
||||
runtimeScene.getGame().getRenderer().centerWindow();
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.setGameResolutionResizeMode = function(runtimeScene, resizeMode) {
|
||||
runtimeScene.getGame().setGameResolutionResizeMode(resizeMode);
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
*/
|
||||
gdjs.evtTools.window.setGameResolutionSize = function (
|
||||
runtimeScene,
|
||||
width,
|
||||
height
|
||||
) {
|
||||
runtimeScene.getGame().setGameResolutionSize(width, height);
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.setAdaptGameResolutionAtRuntime = function(runtimeScene, enable) {
|
||||
runtimeScene.getGame().setAdaptGameResolutionAtRuntime(enable);
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} resizeMode
|
||||
*/
|
||||
gdjs.evtTools.window.setGameResolutionResizeMode = function (
|
||||
runtimeScene,
|
||||
resizeMode
|
||||
) {
|
||||
runtimeScene.getGame().setGameResolutionResizeMode(resizeMode);
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.setWindowTitle = function(runtimeScene, title) {
|
||||
runtimeScene.getGame().getRenderer().setWindowTitle(title);
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {boolean} enable
|
||||
*/
|
||||
gdjs.evtTools.window.setAdaptGameResolutionAtRuntime = function (
|
||||
runtimeScene,
|
||||
enable
|
||||
) {
|
||||
runtimeScene.getGame().setAdaptGameResolutionAtRuntime(enable);
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.getWindowTitle = function(runtimeScene) {
|
||||
runtimeScene.getGame().getRenderer().getWindowTitle();
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @param {string} title
|
||||
*/
|
||||
gdjs.evtTools.window.setWindowTitle = function (runtimeScene, title) {
|
||||
runtimeScene.getGame().getRenderer().setWindowTitle(title);
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.getWindowInnerWidth = function() {
|
||||
if (gdjs.RuntimeGameRenderer && gdjs.RuntimeGameRenderer.getWindowInnerWidth)
|
||||
return gdjs.RuntimeGameRenderer.getWindowInnerWidth();
|
||||
|
||||
return (typeof window !== "undefined") ? window.innerWidth : 800;
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {string}
|
||||
*/
|
||||
gdjs.evtTools.window.getWindowTitle = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getRenderer().getWindowTitle();
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.getWindowInnerHeight = function() {
|
||||
if (gdjs.RuntimeGameRenderer && gdjs.RuntimeGameRenderer.getWindowInnerHeight)
|
||||
return gdjs.RuntimeGameRenderer.getWindowInnerHeight();
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.window.getWindowInnerWidth = function () {
|
||||
if (gdjs.RuntimeGameRenderer && gdjs.RuntimeGameRenderer.getWindowInnerWidth)
|
||||
return gdjs.RuntimeGameRenderer.getWindowInnerWidth();
|
||||
|
||||
return (typeof window !== "undefined") ? window.innerHeight : 800;
|
||||
return typeof window !== 'undefined' ? window.innerWidth : 800;
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.getGameResolutionWidth = function(runtimeScene) {
|
||||
return runtimeScene.getGame().getGameResolutionWidth();
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.window.getWindowInnerHeight = function () {
|
||||
if (gdjs.RuntimeGameRenderer && gdjs.RuntimeGameRenderer.getWindowInnerHeight)
|
||||
return gdjs.RuntimeGameRenderer.getWindowInnerHeight();
|
||||
|
||||
return typeof window !== 'undefined' ? window.innerHeight : 800;
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.getGameResolutionHeight = function(runtimeScene) {
|
||||
return runtimeScene.getGame().getGameResolutionHeight();
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.window.getGameResolutionWidth = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getGameResolutionWidth();
|
||||
};
|
||||
|
||||
gdjs.evtTools.window.openURL = function(url, runtimeScene) {
|
||||
return runtimeScene.getGame().getRenderer().openURL(url);
|
||||
/**
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.evtTools.window.getGameResolutionHeight = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getGameResolutionHeight();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
*/
|
||||
gdjs.evtTools.window.openURL = function (url, runtimeScene) {
|
||||
return runtimeScene.getGame().getRenderer().openURL(url);
|
||||
};
|
||||
|
@@ -7,7 +7,7 @@
|
||||
|
||||
/**
|
||||
* The `gdjs` namespace contains all classes and objects of the game engine.
|
||||
* @namespace
|
||||
* @namespace gdjs
|
||||
*/
|
||||
// @ts-ignore - creating the global object acting as a namespace
|
||||
window.gdjs = {};
|
||||
@@ -359,6 +359,66 @@ gdjs.copyArray = function (src, dst) {
|
||||
dst.length = len;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a UUID v4.
|
||||
* @returns {string} The generated UUID.
|
||||
*/
|
||||
gdjs.makeUuid = function () {
|
||||
// Fallback to non cryptographically secure UUIDs if not supported
|
||||
if (typeof crypto === 'undefined' || !crypto.getRandomValues) {
|
||||
const makeMathRandomUuid = (a) => {
|
||||
return a
|
||||
? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
|
||||
: (""+ 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(
|
||||
/[018]/g,
|
||||
makeMathRandomUuid
|
||||
);
|
||||
};
|
||||
|
||||
return makeMathRandomUuid();
|
||||
}
|
||||
|
||||
// @ts-ignore - TS does not like properties added on functions
|
||||
if (!gdjs.makeUuid.hex) {
|
||||
// @ts-ignore - TS does not like properties added on functions
|
||||
gdjs.makeUuid.hex = [];
|
||||
|
||||
for (var i = 0; i < 256; i++) {
|
||||
// @ts-ignore - TS does not like properties added on functions
|
||||
gdjs.makeUuid.hex[i] = (i < 16 ? '0' : '') + i.toString(16);
|
||||
}
|
||||
}
|
||||
// @ts-ignore - TS does not like properties added on functions
|
||||
const hex = gdjs.makeUuid.hex;
|
||||
|
||||
var r = crypto.getRandomValues(new Uint8Array(16));
|
||||
r[6] = (r[6] & 0x0f) | 0x40;
|
||||
r[8] = (r[8] & 0x3f) | 0x80;
|
||||
|
||||
return (
|
||||
hex[r[0]] +
|
||||
hex[r[1]] +
|
||||
hex[r[2]] +
|
||||
hex[r[3]] +
|
||||
'-' +
|
||||
hex[r[4]] +
|
||||
hex[r[5]] +
|
||||
'-' +
|
||||
hex[r[6]] +
|
||||
hex[r[7]] +
|
||||
'-' +
|
||||
hex[r[8]] +
|
||||
hex[r[9]] +
|
||||
'-' +
|
||||
hex[r[10]] +
|
||||
hex[r[11]] +
|
||||
hex[r[12]] +
|
||||
hex[r[13]] +
|
||||
hex[r[14]] +
|
||||
hex[r[15]]
|
||||
);
|
||||
};
|
||||
|
||||
//Make sure console.warn and console.error are available.
|
||||
console.warn = console.warn || console.log;
|
||||
console.error = console.error || console.log;
|
||||
|
File diff suppressed because one or more lines are too long
@@ -20,6 +20,7 @@ gdjs.Layer = function (layerData, runtimeScene) {
|
||||
this._cameraRotation = 0;
|
||||
this._zoomFactor = 1;
|
||||
this._timeScale = 1;
|
||||
this._defaultZOrder = 0;
|
||||
this._hidden = !layerData.visibility;
|
||||
this._initialEffectsData = layerData.effects || [];
|
||||
this._cameraX = runtimeScene.getGame().getGameResolutionWidth() / 2;
|
||||
@@ -55,6 +56,23 @@ gdjs.Layer.prototype.getRenderer = function () {
|
||||
return this._renderer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the default Z order to be attributed to objects created on this layer
|
||||
* (usually from events generated code).
|
||||
* @returns {number}
|
||||
*/
|
||||
gdjs.Layer.prototype.getDefaultZOrder = function () {
|
||||
return this._defaultZOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default Z order to be attributed to objects created on this layer.
|
||||
* @param {number} defaultZOrder The Z order to use when creating a new object from events.
|
||||
*/
|
||||
gdjs.Layer.prototype.setDefaultZOrder = function (defaultZOrder) {
|
||||
this._defaultZOrder = defaultZOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the RuntimeScene whenever the game resolution size is changed.
|
||||
* Updates the layer width/height and position.
|
||||
|
@@ -284,7 +284,7 @@ gdjs.LayerPixiRenderer.prototype.updateClearColor = function () {
|
||||
* Also, render texture is cleared with a specified clear color.
|
||||
*/
|
||||
gdjs.LayerPixiRenderer.prototype._updateRenderTexture = function () {
|
||||
if (!this._pixiRenderer) return;
|
||||
if (!this._pixiRenderer || this._pixiRenderer.type !== PIXI.RENDERER_TYPE.WEBGL) return;
|
||||
|
||||
if (!this._renderTexture) {
|
||||
this._oldWidth = this._pixiRenderer.screen.width;
|
||||
@@ -334,7 +334,7 @@ gdjs.LayerPixiRenderer.prototype._updateRenderTexture = function () {
|
||||
* @private used only in lighting for now as the sprite could have MULTIPLY blend mode.
|
||||
*/
|
||||
gdjs.LayerPixiRenderer.prototype._replaceContainerWithSprite = function () {
|
||||
if (!this._pixiRenderer) return;
|
||||
if (!this._pixiRenderer || this._pixiRenderer.type !== PIXI.RENDERER_TYPE.WEBGL) return;
|
||||
|
||||
this._updateRenderTexture();
|
||||
if (!this._renderTexture) return;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* @param {gdjs.RuntimeGame} game The game that is being rendered
|
||||
* @param {boolean} forceFullscreen If fullscreen should be always activated
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer = function(game, forceFullscreen) {
|
||||
gdjs.RuntimeGamePixiRenderer = function (game, forceFullscreen) {
|
||||
this._game = game;
|
||||
|
||||
this._isFullPage = true; //Used to track if the canvas is displayed on the full page.
|
||||
@@ -18,6 +18,8 @@ gdjs.RuntimeGamePixiRenderer = function(game, forceFullscreen) {
|
||||
this._canvasHeight = 0; // Current height of the canvas (might be scaled down/up compared to renderer)
|
||||
this._keepRatio = true;
|
||||
this._marginLeft = this._marginTop = this._marginRight = this._marginBottom = 0;
|
||||
|
||||
this._setupOrientation();
|
||||
};
|
||||
|
||||
gdjs.RuntimeGameRenderer = gdjs.RuntimeGamePixiRenderer; //Register the class to let the engine use it.
|
||||
@@ -26,19 +28,17 @@ gdjs.RuntimeGameRenderer = gdjs.RuntimeGamePixiRenderer; //Register the class to
|
||||
* Create a standard canvas inside canvasArea.
|
||||
*
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.createStandardCanvas = function(
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.createStandardCanvas = function (
|
||||
parentElement
|
||||
) {
|
||||
//Create the renderer and setup the rendering area
|
||||
//"preserveDrawingBuffer: true" is needed to avoid flickering and background issues on some mobile phones (see #585 #572 #566 #463)
|
||||
this._pixiRenderer = PIXI.autoDetectRenderer(
|
||||
{
|
||||
width: this._game.getGameResolutionWidth(),
|
||||
height: this._game.getGameResolutionHeight(),
|
||||
preserveDrawingBuffer: true,
|
||||
antialias: false,
|
||||
}
|
||||
);
|
||||
this._pixiRenderer = PIXI.autoDetectRenderer({
|
||||
width: this._game.getGameResolutionWidth(),
|
||||
height: this._game.getGameResolutionHeight(),
|
||||
preserveDrawingBuffer: true,
|
||||
antialias: false,
|
||||
});
|
||||
parentElement.appendChild(this._pixiRenderer.view); // add the renderer view element to the DOM
|
||||
this._pixiRenderer.view.style['position'] = 'absolute';
|
||||
this._pixiRenderer.view.tabIndex = 1; //Ensure that the canvas has the focus.
|
||||
@@ -55,7 +55,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.createStandardCanvas = function(
|
||||
|
||||
//Handle resize
|
||||
var that = this;
|
||||
window.addEventListener('resize', function() {
|
||||
window.addEventListener('resize', function () {
|
||||
that._game.onWindowInnerSizeChanged();
|
||||
that._resizeCanvas();
|
||||
that._game._notifySceneForResize = true;
|
||||
@@ -64,11 +64,11 @@ gdjs.RuntimeGamePixiRenderer.prototype.createStandardCanvas = function(
|
||||
return this._pixiRenderer;
|
||||
};
|
||||
|
||||
gdjs.RuntimeGamePixiRenderer.getWindowInnerWidth = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.getWindowInnerWidth = function () {
|
||||
return typeof window !== 'undefined' ? window.innerWidth : 800;
|
||||
};
|
||||
|
||||
gdjs.RuntimeGamePixiRenderer.getWindowInnerHeight = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.getWindowInnerHeight = function () {
|
||||
return typeof window !== 'undefined' ? window.innerHeight : 800;
|
||||
};
|
||||
|
||||
@@ -79,17 +79,42 @@ gdjs.RuntimeGamePixiRenderer.getWindowInnerHeight = function() {
|
||||
* Note that if the canvas is fullscreen, it won't be resized, but when going back to
|
||||
* non fullscreen mode, the requested size will be used.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.updateRendererSize = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.updateRendererSize = function () {
|
||||
this._resizeCanvas();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the proper screen orientation from the project properties.
|
||||
* @private
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype._setupOrientation = function () {
|
||||
if (
|
||||
typeof window === 'undefined' ||
|
||||
!window.screen ||
|
||||
!window.screen.orientation
|
||||
)
|
||||
return;
|
||||
|
||||
var gameOrientation = this._game.getGameData().properties.orientation;
|
||||
try {
|
||||
// We ignore the error as some platforms may not supporting locking (i.e: desktop).
|
||||
if (gameOrientation === 'default') {
|
||||
window.screen.orientation.unlock().catch(() => {});
|
||||
} else {
|
||||
window.screen.orientation.lock(gameOrientation).catch(() => {});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Unexpected error while setting up orientation: ', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize the renderer (the "game resolution") and the canvas (which can be larger
|
||||
* or smaller to fill the page, with optional margins).
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype._resizeCanvas = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype._resizeCanvas = function () {
|
||||
// Set the Pixi renderer size to the game size.
|
||||
// There is no "smart" resizing to be done here: the rendering of the game
|
||||
// should be done with the size set on the game.
|
||||
@@ -146,7 +171,7 @@ gdjs.RuntimeGamePixiRenderer.prototype._resizeCanvas = function() {
|
||||
* Set if the aspect ratio must be kept when the game canvas is resized to fill
|
||||
* the page.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.keepAspectRatio = function(enable) {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.keepAspectRatio = function (enable) {
|
||||
if (this._keepRatio === enable) return;
|
||||
|
||||
this._keepRatio = enable;
|
||||
@@ -157,7 +182,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.keepAspectRatio = function(enable) {
|
||||
/**
|
||||
* Change the margin that must be preserved around the game canvas.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setMargins = function(
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setMargins = function (
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
@@ -184,7 +209,10 @@ gdjs.RuntimeGamePixiRenderer.prototype.setMargins = function(
|
||||
* @param {number} width The new width, in pixels.
|
||||
* @param {number} height The new height, in pixels.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setWindowSize = function(width, height) {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setWindowSize = function (
|
||||
width,
|
||||
height
|
||||
) {
|
||||
var electron = this.getElectron();
|
||||
if (electron) {
|
||||
// Use Electron BrowserWindow API
|
||||
@@ -200,7 +228,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.setWindowSize = function(width, height) {
|
||||
/**
|
||||
* Center the window on screen.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.centerWindow = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.centerWindow = function () {
|
||||
var electron = this.getElectron();
|
||||
if (electron) {
|
||||
// Use Electron BrowserWindow API
|
||||
@@ -216,7 +244,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.centerWindow = function() {
|
||||
/**
|
||||
* De/activate fullscreen for the game.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setFullScreen = function(enable) {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setFullScreen = function (enable) {
|
||||
if (this._forceFullscreen) return;
|
||||
|
||||
if (this._isFullscreen !== enable) {
|
||||
@@ -256,10 +284,22 @@ gdjs.RuntimeGamePixiRenderer.prototype.setFullScreen = function(enable) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the game is in full screen.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.isFullScreen = function () {
|
||||
var electron = this.getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.getCurrentWindow().isFullScreen();
|
||||
}
|
||||
// Height check is used to detect user triggered full screen (for example F11 shortcut).
|
||||
return this._isFullscreen || window.screen.height === window.innerHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the standard events handler.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function(
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function (
|
||||
manager,
|
||||
window,
|
||||
document
|
||||
@@ -323,18 +363,18 @@ gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function(
|
||||
})();
|
||||
|
||||
//Keyboard
|
||||
document.onkeydown = function(e) {
|
||||
document.onkeydown = function (e) {
|
||||
manager.onKeyPressed(e.keyCode, e.location);
|
||||
};
|
||||
document.onkeyup = function(e) {
|
||||
document.onkeyup = function (e) {
|
||||
manager.onKeyReleased(e.keyCode, e.location);
|
||||
};
|
||||
//Mouse
|
||||
renderer.view.onmousemove = function(e) {
|
||||
renderer.view.onmousemove = function (e) {
|
||||
var pos = getEventPosition(e);
|
||||
manager.onMouseMove(pos[0], pos[1]);
|
||||
};
|
||||
renderer.view.onmousedown = function(e) {
|
||||
renderer.view.onmousedown = function (e) {
|
||||
manager.onMouseButtonPressed(
|
||||
e.button === 2
|
||||
? gdjs.InputManager.MOUSE_RIGHT_BUTTON
|
||||
@@ -345,7 +385,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function(
|
||||
if (window.focus !== undefined) window.focus();
|
||||
return false;
|
||||
};
|
||||
renderer.view.onmouseup = function(e) {
|
||||
renderer.view.onmouseup = function (e) {
|
||||
manager.onMouseButtonReleased(
|
||||
e.button === 2
|
||||
? gdjs.InputManager.MOUSE_RIGHT_BUTTON
|
||||
@@ -357,24 +397,24 @@ gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function(
|
||||
};
|
||||
window.addEventListener(
|
||||
'click',
|
||||
function(e) {
|
||||
function (e) {
|
||||
if (window.focus !== undefined) window.focus();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
},
|
||||
false
|
||||
);
|
||||
renderer.view.oncontextmenu = function(event) {
|
||||
renderer.view.oncontextmenu = function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
renderer.view.onmousewheel = function(event) {
|
||||
renderer.view.onmousewheel = function (event) {
|
||||
manager.onMouseWheel(event.wheelDelta);
|
||||
};
|
||||
//Touches
|
||||
//Also simulate mouse events when receiving touch events
|
||||
window.addEventListener('touchmove', function(e) {
|
||||
window.addEventListener('touchmove', function (e) {
|
||||
e.preventDefault();
|
||||
if (e.changedTouches) {
|
||||
for (var i = 0; i < e.changedTouches.length; ++i) {
|
||||
@@ -383,7 +423,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function(
|
||||
}
|
||||
}
|
||||
});
|
||||
window.addEventListener('touchstart', function(e) {
|
||||
window.addEventListener('touchstart', function (e) {
|
||||
e.preventDefault();
|
||||
if (e.changedTouches) {
|
||||
for (var i = 0; i < e.changedTouches.length; ++i) {
|
||||
@@ -393,7 +433,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function(
|
||||
}
|
||||
return false;
|
||||
});
|
||||
window.addEventListener('touchend', function(e) {
|
||||
window.addEventListener('touchend', function (e) {
|
||||
e.preventDefault();
|
||||
if (e.changedTouches) {
|
||||
for (var i = 0; i < e.changedTouches.length; ++i) {
|
||||
@@ -405,15 +445,15 @@ gdjs.RuntimeGamePixiRenderer.prototype.bindStandardEvents = function(
|
||||
});
|
||||
};
|
||||
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setWindowTitle = function(title) {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.setWindowTitle = function (title) {
|
||||
if (typeof document !== 'undefined') document.title = title;
|
||||
};
|
||||
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getWindowTitle = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getWindowTitle = function () {
|
||||
return typeof document !== 'undefined' ? document.title : '';
|
||||
};
|
||||
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.startGameLoop = function(fn) {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.startGameLoop = function (fn) {
|
||||
requestAnimationFrame(gameLoop);
|
||||
|
||||
var oldTime = 0;
|
||||
@@ -425,14 +465,14 @@ gdjs.RuntimeGamePixiRenderer.prototype.startGameLoop = function(fn) {
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getPIXIRenderer = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getPIXIRenderer = function () {
|
||||
return this._pixiRenderer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the given URL in the system browser (or a new tab)
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.openURL = function(url) {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.openURL = function (url) {
|
||||
// Try to detect the environment to use the most adapted
|
||||
// way of opening an URL.
|
||||
if (typeof Cocoon !== 'undefined' && Cocoon.App && Cocoon.App.openURL) {
|
||||
@@ -446,7 +486,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.openURL = function(url) {
|
||||
/**
|
||||
* Close the game, if applicable
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.stopGame = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.stopGame = function () {
|
||||
// Try to detect the environment to use the most adapted
|
||||
// way of closing the app
|
||||
var electron = this.getElectron();
|
||||
@@ -469,7 +509,7 @@ gdjs.RuntimeGamePixiRenderer.prototype.stopGame = function() {
|
||||
/**
|
||||
* Get the canvas DOM element.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getCanvas = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getCanvas = function () {
|
||||
return this._pixiRenderer.view;
|
||||
};
|
||||
|
||||
@@ -477,14 +517,14 @@ gdjs.RuntimeGamePixiRenderer.prototype.getCanvas = function() {
|
||||
* Check if the device supports WebGL.
|
||||
* @returns {boolean} true if WebGL is supported
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.isWebGLSupported = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.isWebGLSupported = function () {
|
||||
return this._pixiRenderer.type === PIXI.RENDERER_TYPE.WEBGL;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the electron module, if running as a electron renderer process.
|
||||
*/
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getElectron = function() {
|
||||
gdjs.RuntimeGamePixiRenderer.prototype.getElectron = function () {
|
||||
if (typeof require !== 'undefined') {
|
||||
return require('electron');
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ gdjs.SpriteRuntimeObjectPixiRenderer.prototype._updatePIXISprite = function() {
|
||||
this._sprite.rotation = gdjs.toRad(this._object.angle);
|
||||
this._sprite.visible = !this._object.hidden;
|
||||
this._sprite.blendMode = this._object._blendMode;
|
||||
this._sprite.alpha = this._sprite.visible ? this._object.opacity/255 : 0; //TODO: Workaround not working property in PIXI.js
|
||||
this._sprite.alpha = this._object.opacity/255;
|
||||
this._sprite.scale.x = this._object._scaleX;
|
||||
this._sprite.scale.y = this._object._scaleY;
|
||||
this._cachedWidth = Math.abs(this._sprite.width);
|
||||
@@ -83,15 +83,11 @@ gdjs.SpriteRuntimeObjectPixiRenderer.prototype.updateAngle = function() {
|
||||
}
|
||||
|
||||
gdjs.SpriteRuntimeObjectPixiRenderer.prototype.updateOpacity = function() {
|
||||
//TODO: Workaround a not working property in PIXI.js:
|
||||
this._sprite.alpha = this._sprite.visible ? this._object.opacity/255 : 0;
|
||||
this._sprite.alpha = this._object.opacity/255;
|
||||
}
|
||||
|
||||
gdjs.SpriteRuntimeObjectPixiRenderer.prototype.updateVisibility = function() {
|
||||
this._sprite.visible = !this._object.hidden;
|
||||
|
||||
//TODO: Workaround a not working property in PIXI.js:
|
||||
this._sprite.alpha = this._sprite.visible ? this._object.opacity/255 : 0;
|
||||
}
|
||||
|
||||
gdjs.SpriteRuntimeObjectPixiRenderer.prototype.setColor = function(rgbColor) {
|
||||
|
@@ -30,23 +30,15 @@
|
||||
* @param {ProjectData} data The object (usually stored in data.json) containing the full project data
|
||||
* @param {RuntimeGameOptions=} options Optional object for specifiying additional options: {forceFullscreen: ...}
|
||||
*/
|
||||
gdjs.RuntimeGame = function(data, options) {
|
||||
gdjs.RuntimeGame = function (data, options) {
|
||||
options = options || {};
|
||||
|
||||
this._variables = new gdjs.VariablesContainer(data.variables);
|
||||
this._data = data;
|
||||
this._imageManager = new gdjs.ImageManager(
|
||||
this._data.resources.resources
|
||||
);
|
||||
this._soundManager = new gdjs.SoundManager(
|
||||
this._data.resources.resources
|
||||
);
|
||||
this._fontManager = new gdjs.FontManager(
|
||||
this._data.resources.resources
|
||||
);
|
||||
this._jsonManager = new gdjs.JsonManager(
|
||||
this._data.resources.resources
|
||||
);
|
||||
this._imageManager = new gdjs.ImageManager(this._data.resources.resources);
|
||||
this._soundManager = new gdjs.SoundManager(this._data.resources.resources);
|
||||
this._fontManager = new gdjs.FontManager(this._data.resources.resources);
|
||||
this._jsonManager = new gdjs.JsonManager(this._data.resources.resources);
|
||||
this._maxFPS = this._data ? this._data.properties.maxFPS : 60;
|
||||
this._minFPS = this._data ? this._data.properties.minFPS : 15;
|
||||
|
||||
@@ -55,8 +47,7 @@ gdjs.RuntimeGame = function(data, options) {
|
||||
this._originalWidth = this._gameResolutionWidth;
|
||||
this._originalHeight = this._gameResolutionHeight;
|
||||
this._resizeMode = this._data.properties.sizeOnStartupMode;
|
||||
this._adaptGameResolutionAtRuntime =
|
||||
this._data.properties.adaptGameResolutionAtRuntime;
|
||||
this._adaptGameResolutionAtRuntime = this._data.properties.adaptGameResolutionAtRuntime;
|
||||
/** @type {string} */
|
||||
this._scaleMode = data.properties.scaleMode || 'linear';
|
||||
this._renderer = new gdjs.RuntimeGameRenderer(
|
||||
@@ -84,6 +75,12 @@ gdjs.RuntimeGame = function(data, options) {
|
||||
? new gdjs.DebuggerClient(this)
|
||||
: null;
|
||||
|
||||
/** @type {boolean} */
|
||||
this._sessionMetricsInitialized = false;
|
||||
|
||||
/** @type {boolean} */
|
||||
this._disableMetrics = false;
|
||||
|
||||
/** @type {boolean} */
|
||||
this._isPreview = options.isPreview || false;
|
||||
};
|
||||
@@ -93,32 +90,24 @@ gdjs.RuntimeGame = function(data, options) {
|
||||
*
|
||||
* @param {ProjectData} projectData The object (usually stored in data.json) containing the full project data
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.setProjectData = function(projectData) {
|
||||
gdjs.RuntimeGame.prototype.setProjectData = function (projectData) {
|
||||
this._data = projectData;
|
||||
|
||||
this._imageManager.setResources(
|
||||
this._data.resources.resources
|
||||
);
|
||||
this._soundManager.setResources(
|
||||
this._data.resources.resources
|
||||
);
|
||||
this._fontManager.setResources(
|
||||
this._data.resources.resources
|
||||
);
|
||||
this._jsonManager.setResources(
|
||||
this._data.resources.resources
|
||||
);
|
||||
}
|
||||
this._imageManager.setResources(this._data.resources.resources);
|
||||
this._soundManager.setResources(this._data.resources.resources);
|
||||
this._fontManager.setResources(this._data.resources.resources);
|
||||
this._jsonManager.setResources(this._data.resources.resources);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the additional options passed to the RuntimeGame when created.
|
||||
* @returns {?RuntimeGameOptions} The additional options, if any.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getAdditionalOptions = function() {
|
||||
gdjs.RuntimeGame.prototype.getAdditionalOptions = function () {
|
||||
return this._options;
|
||||
};
|
||||
|
||||
gdjs.RuntimeGame.prototype.getRenderer = function() {
|
||||
gdjs.RuntimeGame.prototype.getRenderer = function () {
|
||||
return this._renderer;
|
||||
};
|
||||
|
||||
@@ -126,7 +115,7 @@ gdjs.RuntimeGame.prototype.getRenderer = function() {
|
||||
* Get the variables of the RuntimeGame.
|
||||
* @return {gdjs.VariablesContainer} The global variables
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getVariables = function() {
|
||||
gdjs.RuntimeGame.prototype.getVariables = function () {
|
||||
return this._variables;
|
||||
};
|
||||
|
||||
@@ -134,7 +123,7 @@ gdjs.RuntimeGame.prototype.getVariables = function() {
|
||||
* Get the gdjs.SoundManager of the RuntimeGame.
|
||||
* @return {gdjs.HowlerSoundManager | gdjs.CocosSoundManager} The sound manager.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getSoundManager = function() {
|
||||
gdjs.RuntimeGame.prototype.getSoundManager = function () {
|
||||
// @ts-ignore
|
||||
return this._soundManager;
|
||||
};
|
||||
@@ -143,7 +132,7 @@ gdjs.RuntimeGame.prototype.getSoundManager = function() {
|
||||
* Get the gdjs.ImageManager of the RuntimeGame.
|
||||
* @return {gdjs.PixiImageManager | gdjs.CocosImageManager} The image manager.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getImageManager = function() {
|
||||
gdjs.RuntimeGame.prototype.getImageManager = function () {
|
||||
// @ts-ignore
|
||||
return this._imageManager;
|
||||
};
|
||||
@@ -152,7 +141,7 @@ gdjs.RuntimeGame.prototype.getImageManager = function() {
|
||||
* Get the gdjs.FontManager of the RuntimeGame.
|
||||
* @return {gdjs.FontFaceObserverFontManager} The font manager.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getFontManager = function() {
|
||||
gdjs.RuntimeGame.prototype.getFontManager = function () {
|
||||
// @ts-ignore
|
||||
return this._fontManager;
|
||||
};
|
||||
@@ -162,7 +151,7 @@ gdjs.RuntimeGame.prototype.getFontManager = function() {
|
||||
* and touches states.
|
||||
* @return {gdjs.InputManager} The input manager owned by the game
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getInputManager = function() {
|
||||
gdjs.RuntimeGame.prototype.getInputManager = function () {
|
||||
return this._inputManager;
|
||||
};
|
||||
|
||||
@@ -171,7 +160,7 @@ gdjs.RuntimeGame.prototype.getInputManager = function() {
|
||||
* resources.
|
||||
* @return {gdjs.JsonManager} The json manager for the game
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getJsonManager = function() {
|
||||
gdjs.RuntimeGame.prototype.getJsonManager = function () {
|
||||
return this._jsonManager;
|
||||
};
|
||||
|
||||
@@ -179,7 +168,7 @@ gdjs.RuntimeGame.prototype.getJsonManager = function() {
|
||||
* Get the object containing the game data
|
||||
* @return {ProjectData} The object associated to the game.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getGameData = function() {
|
||||
gdjs.RuntimeGame.prototype.getGameData = function () {
|
||||
return this._data;
|
||||
};
|
||||
|
||||
@@ -189,7 +178,7 @@ gdjs.RuntimeGame.prototype.getGameData = function() {
|
||||
* @param {string=} sceneName The name of the scene. If not defined, the first scene will be returned.
|
||||
* @return {?LayoutData} The data associated to the scene.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getSceneData = function(sceneName) {
|
||||
gdjs.RuntimeGame.prototype.getSceneData = function (sceneName) {
|
||||
var scene = null;
|
||||
for (var i = 0, len = this._data.layouts.length; i < len; ++i) {
|
||||
var sceneData = this._data.layouts[i];
|
||||
@@ -212,7 +201,7 @@ gdjs.RuntimeGame.prototype.getSceneData = function(sceneName) {
|
||||
* @param {string=} sceneName The name of the scene to search.
|
||||
* @return {boolean} true if the scene exists. If sceneName is undefined, true if the game has a scene.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.hasScene = function(sceneName) {
|
||||
gdjs.RuntimeGame.prototype.hasScene = function (sceneName) {
|
||||
var isTrue = false;
|
||||
for (var i = 0, len = this._data.layouts.length; i < len; ++i) {
|
||||
var sceneData = this._data.layouts[i];
|
||||
@@ -232,7 +221,7 @@ gdjs.RuntimeGame.prototype.hasScene = function(sceneName) {
|
||||
* @param {string} name The name of the external layout.
|
||||
* @return {?ExternalLayoutData} The data associated to the external layout or null if not found.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getExternalLayoutData = function(name) {
|
||||
gdjs.RuntimeGame.prototype.getExternalLayoutData = function (name) {
|
||||
var externalLayout = null;
|
||||
for (var i = 0, len = this._data.externalLayouts.length; i < len; ++i) {
|
||||
var layoutData = this._data.externalLayouts[i];
|
||||
@@ -250,7 +239,7 @@ gdjs.RuntimeGame.prototype.getExternalLayoutData = function(name) {
|
||||
* Get the data representing all the global objects of the game.
|
||||
* @return {ObjectData[]} The data associated to the global objects.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getInitialObjectsData = function() {
|
||||
gdjs.RuntimeGame.prototype.getInitialObjectsData = function () {
|
||||
return this._data.objects || [];
|
||||
};
|
||||
|
||||
@@ -259,7 +248,7 @@ gdjs.RuntimeGame.prototype.getInitialObjectsData = function() {
|
||||
*
|
||||
* This is guaranteed to never change, even if the size of the game is changed afterwards.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getOriginalWidth = function() {
|
||||
gdjs.RuntimeGame.prototype.getOriginalWidth = function () {
|
||||
return this._originalWidth;
|
||||
};
|
||||
|
||||
@@ -268,7 +257,7 @@ gdjs.RuntimeGame.prototype.getOriginalWidth = function() {
|
||||
*
|
||||
* This is guaranteed to never change, even if the size of the game is changed afterwards.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getOriginalHeight = function() {
|
||||
gdjs.RuntimeGame.prototype.getOriginalHeight = function () {
|
||||
return this._originalHeight;
|
||||
};
|
||||
|
||||
@@ -276,7 +265,7 @@ gdjs.RuntimeGame.prototype.getOriginalHeight = function() {
|
||||
* Get the game resolution (the size at which the game is played and rendered) width.
|
||||
* @returns {number} The game resolution width, in pixels.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getGameResolutionWidth = function() {
|
||||
gdjs.RuntimeGame.prototype.getGameResolutionWidth = function () {
|
||||
return this._gameResolutionWidth;
|
||||
};
|
||||
|
||||
@@ -284,7 +273,7 @@ gdjs.RuntimeGame.prototype.getGameResolutionWidth = function() {
|
||||
* Get the game resolution (the size at which the game is played and rendered) height.
|
||||
* @returns {number} The game resolution height, in pixels.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getGameResolutionHeight = function() {
|
||||
gdjs.RuntimeGame.prototype.getGameResolutionHeight = function () {
|
||||
return this._gameResolutionHeight;
|
||||
};
|
||||
|
||||
@@ -294,7 +283,7 @@ gdjs.RuntimeGame.prototype.getGameResolutionHeight = function() {
|
||||
* @param {number} width The new width
|
||||
* @param {number} height The new height
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.setGameResolutionSize = function(width, height) {
|
||||
gdjs.RuntimeGame.prototype.setGameResolutionSize = function (width, height) {
|
||||
this._gameResolutionWidth = width;
|
||||
this._gameResolutionHeight = height;
|
||||
|
||||
@@ -338,7 +327,7 @@ gdjs.RuntimeGame.prototype.setGameResolutionSize = function(width, height) {
|
||||
*
|
||||
* @param {string} resizeMode Either "" (don't change game resolution), "adaptWidth" or "adaptHeight".
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.setGameResolutionResizeMode = function(resizeMode) {
|
||||
gdjs.RuntimeGame.prototype.setGameResolutionResizeMode = function (resizeMode) {
|
||||
this._resizeMode = resizeMode;
|
||||
this._forceGameResolutionUpdate();
|
||||
};
|
||||
@@ -350,7 +339,7 @@ gdjs.RuntimeGame.prototype.setGameResolutionResizeMode = function(resizeMode) {
|
||||
*
|
||||
* @returns {string} Either "" (don't change game resolution), "adaptWidth" or "adaptHeight".
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getGameResolutionResizeMode = function() {
|
||||
gdjs.RuntimeGame.prototype.getGameResolutionResizeMode = function () {
|
||||
return this._resizeMode;
|
||||
};
|
||||
|
||||
@@ -361,7 +350,7 @@ gdjs.RuntimeGame.prototype.getGameResolutionResizeMode = function() {
|
||||
* configured to adapt the width or the height of the game.
|
||||
* @param {boolean} enable true to change the game resolution according to the window/screen size.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.setAdaptGameResolutionAtRuntime = function(enable) {
|
||||
gdjs.RuntimeGame.prototype.setAdaptGameResolutionAtRuntime = function (enable) {
|
||||
this._adaptGameResolutionAtRuntime = enable;
|
||||
this._forceGameResolutionUpdate();
|
||||
};
|
||||
@@ -373,7 +362,7 @@ gdjs.RuntimeGame.prototype.setAdaptGameResolutionAtRuntime = function(enable) {
|
||||
* configured to adapt the width or the height of the game.
|
||||
* @returns {boolean} true if the game resolution is automatically changed according to the window/screen size.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getAdaptGameResolutionAtRuntime = function() {
|
||||
gdjs.RuntimeGame.prototype.getAdaptGameResolutionAtRuntime = function () {
|
||||
return this._adaptGameResolutionAtRuntime;
|
||||
};
|
||||
|
||||
@@ -381,14 +370,14 @@ gdjs.RuntimeGame.prototype.getAdaptGameResolutionAtRuntime = function() {
|
||||
* Return the minimal fps that must be guaranteed by the game
|
||||
* (otherwise, game is slowed down).
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getMinimalFramerate = function() {
|
||||
gdjs.RuntimeGame.prototype.getMinimalFramerate = function () {
|
||||
return this._minFPS;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the scale mode of the game ("linear" or "nearest").
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getScaleMode = function() {
|
||||
gdjs.RuntimeGame.prototype.getScaleMode = function () {
|
||||
return this._scaleMode;
|
||||
};
|
||||
|
||||
@@ -397,14 +386,14 @@ gdjs.RuntimeGame.prototype.getScaleMode = function() {
|
||||
* When paused, the game won't step and will be freezed. Useful for debugging.
|
||||
* @param {boolean} enable true to pause the game, false to unpause
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.pause = function(enable) {
|
||||
gdjs.RuntimeGame.prototype.pause = function (enable) {
|
||||
this._paused = enable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load all assets, displaying progress in renderer.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.loadAllAssets = function(
|
||||
gdjs.RuntimeGame.prototype.loadAllAssets = function (
|
||||
callback,
|
||||
progressCallback
|
||||
) {
|
||||
@@ -416,23 +405,23 @@ gdjs.RuntimeGame.prototype.loadAllAssets = function(
|
||||
|
||||
var that = this;
|
||||
this._imageManager.loadTextures(
|
||||
function(count, total) {
|
||||
function (count, total) {
|
||||
var percent = Math.floor((count / allAssetsTotal) * 100);
|
||||
loadingScreen.render(percent);
|
||||
if (progressCallback) progressCallback(percent);
|
||||
},
|
||||
function(texturesTotalCount) {
|
||||
function (texturesTotalCount) {
|
||||
that._soundManager.preloadAudio(
|
||||
function(count, total) {
|
||||
function (count, total) {
|
||||
var percent = Math.floor(
|
||||
((texturesTotalCount + count) / allAssetsTotal) * 100
|
||||
);
|
||||
loadingScreen.render(percent);
|
||||
if (progressCallback) progressCallback(percent);
|
||||
},
|
||||
function(audioTotalCount) {
|
||||
function (audioTotalCount) {
|
||||
that._fontManager.loadFonts(
|
||||
function(count, total) {
|
||||
function (count, total) {
|
||||
var percent = Math.floor(
|
||||
((texturesTotalCount + audioTotalCount + count) /
|
||||
allAssetsTotal) *
|
||||
@@ -441,9 +430,9 @@ gdjs.RuntimeGame.prototype.loadAllAssets = function(
|
||||
loadingScreen.render(percent);
|
||||
if (progressCallback) progressCallback(percent);
|
||||
},
|
||||
function(fontTotalCount) {
|
||||
function (fontTotalCount) {
|
||||
that._jsonManager.preloadJsons(
|
||||
function(count, total) {
|
||||
function (count, total) {
|
||||
var percent = Math.floor(
|
||||
((texturesTotalCount +
|
||||
audioTotalCount +
|
||||
@@ -455,7 +444,7 @@ gdjs.RuntimeGame.prototype.loadAllAssets = function(
|
||||
loadingScreen.render(percent);
|
||||
if (progressCallback) progressCallback(percent);
|
||||
},
|
||||
function() {
|
||||
function () {
|
||||
loadingScreen.unload();
|
||||
callback();
|
||||
}
|
||||
@@ -471,7 +460,7 @@ gdjs.RuntimeGame.prototype.loadAllAssets = function(
|
||||
/**
|
||||
* Start the game loop, to be called once assets are loaded.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.startGameLoop = function() {
|
||||
gdjs.RuntimeGame.prototype.startGameLoop = function () {
|
||||
if (!this.hasScene()) {
|
||||
console.log('The game has no scene.');
|
||||
return;
|
||||
@@ -502,7 +491,7 @@ gdjs.RuntimeGame.prototype.startGameLoop = function() {
|
||||
//The standard game loop
|
||||
var that = this;
|
||||
var accumulatedElapsedTime = 0;
|
||||
this._renderer.startGameLoop(function(lastCallElapsedTime) {
|
||||
this._renderer.startGameLoop(function (lastCallElapsedTime) {
|
||||
if (that._paused) return true;
|
||||
|
||||
// Skip the frame if we rendering frames too fast
|
||||
@@ -534,6 +523,136 @@ gdjs.RuntimeGame.prototype.startGameLoop = function() {
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this._setupSessionMetrics();
|
||||
}, 10000);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set if the session should be registered.
|
||||
* @param {boolean} enable
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.enableMetrics = function (enable) {
|
||||
this._disableMetrics = !enable;
|
||||
if (enable) { this._setupSessionMetrics(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new session for the game, and set up listeners to follow the session
|
||||
* time.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype._setupSessionMetrics = function () {
|
||||
if (this._sessionMetricsInitialized) return;
|
||||
if (this._disableMetrics) return;
|
||||
if (this.isPreview()) return;
|
||||
if (typeof fetch === 'undefined') return;
|
||||
if (!this._data.properties.projectUuid) return;
|
||||
|
||||
const baseUrl = 'https://api.gdevelop-app.com/analytics';
|
||||
const playerId = this._getPlayerUuid();
|
||||
let sessionId = null;
|
||||
let lastSessionHitTime = Date.now();
|
||||
|
||||
fetch(baseUrl + '/session', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
// It's important to ensure that the data sent here does not contain
|
||||
// any personal information from the player or that would allow to
|
||||
// precisely identify someone.
|
||||
body: JSON.stringify({
|
||||
gameId: this._data.properties.projectUuid,
|
||||
playerId: playerId,
|
||||
game: {
|
||||
name: this._data.properties.name || '',
|
||||
packageName: this._data.properties.packageName || '',
|
||||
version: this._data.properties.version || '',
|
||||
location: window.location.href,
|
||||
},
|
||||
platform: {
|
||||
// @ts-ignore
|
||||
isCordova: !!window.cordova,
|
||||
devicePlatform:
|
||||
// @ts-ignore
|
||||
typeof device !== 'undefined' ? device.platform || '' : '',
|
||||
navigatorPlatform:
|
||||
typeof navigator !== 'undefined' ? navigator.platform : '',
|
||||
hasTouch:
|
||||
typeof navigator !== 'undefined'
|
||||
? !!navigator.maxTouchPoints && navigator.maxTouchPoints > 2
|
||||
: false,
|
||||
},
|
||||
}),
|
||||
})
|
||||
.then((response) => response.text())
|
||||
.then((returnedSessionId) => {
|
||||
sessionId = returnedSessionId;
|
||||
})
|
||||
.catch(() => {
|
||||
/* Ignore any error */
|
||||
});
|
||||
|
||||
const sendSessionHit = () => {
|
||||
if (!sessionId) return;
|
||||
|
||||
// Group repeated calls to sendSessionHit - which could
|
||||
// happen because of multiple event listeners being fired.
|
||||
if (Date.now() - lastSessionHitTime < 3 * 1000) return;
|
||||
lastSessionHitTime = Date.now();
|
||||
|
||||
navigator.sendBeacon(
|
||||
baseUrl + '/session-hit',
|
||||
JSON.stringify({
|
||||
gameId: this._data.properties.projectUuid,
|
||||
playerId: playerId,
|
||||
sessionId: sessionId,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof navigator !== 'undefined' && typeof document !== 'undefined') {
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
sendSessionHit();
|
||||
});
|
||||
window.addEventListener(
|
||||
'pagehide',
|
||||
() => {
|
||||
sendSessionHit();
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Detect Safari to work around Safari-specific bugs:
|
||||
// - https://bugs.webkit.org/show_bug.cgi?id=151610
|
||||
// - https://bugs.webkit.org/show_bug.cgi?id=151234
|
||||
// @ts-ignore
|
||||
const isSafari = typeof safari === 'object' && safari.pushNotification;
|
||||
const isElectron = /electron/i.test(navigator.userAgent);
|
||||
if (isSafari || isElectron) {
|
||||
window.addEventListener('beforeunload', () => {
|
||||
sendSessionHit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this._sessionMetricsInitialized = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate an anonymous unique identifier to differentiate
|
||||
* the player from others in the game metrics.
|
||||
* @returns {string}
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype._getPlayerUuid = function () {
|
||||
const key = 'GDJS-internal-player-uuid';
|
||||
const existingPlayerUuid = localStorage.getItem(key);
|
||||
if (existingPlayerUuid) return existingPlayerUuid;
|
||||
|
||||
const newPlayerUuid = gdjs.makeUuid();
|
||||
localStorage.setItem(key, newPlayerUuid);
|
||||
return newPlayerUuid;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -541,14 +660,14 @@ gdjs.RuntimeGame.prototype.startGameLoop = function() {
|
||||
* has changed size (this can result from a resize of the window,
|
||||
* but also other factors like a device orientation change on mobile).
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.onWindowInnerSizeChanged = function() {
|
||||
gdjs.RuntimeGame.prototype.onWindowInnerSizeChanged = function () {
|
||||
this._forceGameResolutionUpdate();
|
||||
};
|
||||
|
||||
/**
|
||||
* Enlarge/reduce the width (or the height) of the game to fill the inner window.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype._forceGameResolutionUpdate = function() {
|
||||
gdjs.RuntimeGame.prototype._forceGameResolutionUpdate = function () {
|
||||
this.setGameResolutionSize(
|
||||
this._gameResolutionWidth,
|
||||
this._gameResolutionHeight
|
||||
@@ -559,7 +678,7 @@ gdjs.RuntimeGame.prototype._forceGameResolutionUpdate = function() {
|
||||
* Start a profiler for the currently running scene.
|
||||
* @param {Function} onProfilerStopped Function to be called when the profiler is stopped. Will be passed the profiler as argument.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.startCurrentSceneProfiler = function(
|
||||
gdjs.RuntimeGame.prototype.startCurrentSceneProfiler = function (
|
||||
onProfilerStopped
|
||||
) {
|
||||
var currentScene = this._sceneStack.getCurrentScene();
|
||||
@@ -572,7 +691,7 @@ gdjs.RuntimeGame.prototype.startCurrentSceneProfiler = function(
|
||||
/**
|
||||
* Stop the profiler for the currently running scene.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.stopCurrentSceneProfiler = function() {
|
||||
gdjs.RuntimeGame.prototype.stopCurrentSceneProfiler = function () {
|
||||
var currentScene = this._sceneStack.getCurrentScene();
|
||||
if (!currentScene) return;
|
||||
|
||||
@@ -582,25 +701,25 @@ gdjs.RuntimeGame.prototype.stopCurrentSceneProfiler = function() {
|
||||
/**
|
||||
* Return true if a scene was loaded, false otherwise (i.e: game not yet started).
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.wasFirstSceneLoaded = function() {
|
||||
gdjs.RuntimeGame.prototype.wasFirstSceneLoaded = function () {
|
||||
return this._sceneStack.wasFirstSceneLoaded();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the stack of {@link gdjs.RuntimeScene} being played.
|
||||
* @returns {gdjs.SceneStack}
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getSceneStack = function() {
|
||||
gdjs.RuntimeGame.prototype.getSceneStack = function () {
|
||||
return this._sceneStack;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the game is running as a preview, launched from an editor.
|
||||
* @returns {boolean} true if the current game is a preview.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.isPreview = function() {
|
||||
gdjs.RuntimeGame.prototype.isPreview = function () {
|
||||
return this._isPreview;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an extension property from the project data.
|
||||
@@ -608,9 +727,16 @@ gdjs.RuntimeGame.prototype.isPreview = function() {
|
||||
* @param {string} propertyName The property name.
|
||||
* @return {?string} The property value.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getExtensionProperty = function(extensionName, propertyName) {
|
||||
for(let property of this._data.properties.extensionProperties) {
|
||||
if(property.extension === extensionName && property.property === propertyName) return property.value;
|
||||
gdjs.RuntimeGame.prototype.getExtensionProperty = function (
|
||||
extensionName,
|
||||
propertyName
|
||||
) {
|
||||
for (let property of this._data.properties.extensionProperties) {
|
||||
if (
|
||||
property.extension === extensionName &&
|
||||
property.property === propertyName
|
||||
)
|
||||
return property.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@@ -318,7 +318,11 @@ gdjs.RuntimeObject.prototype.deleteFromScene = function(runtimeScene) {
|
||||
*/
|
||||
gdjs.RuntimeObject.prototype.onDestroyFromScene = function(runtimeScene) {
|
||||
var theLayer = runtimeScene.getLayer(this.layer);
|
||||
theLayer.getRenderer().removeRendererObject(this.getRendererObject());
|
||||
|
||||
var rendererObject = this.getRendererObject();
|
||||
if (rendererObject) {
|
||||
theLayer.getRenderer().removeRendererObject(rendererObject);
|
||||
}
|
||||
|
||||
for(var j = 0, lenj = this._behaviors.length;j<lenj;++j) {
|
||||
this._behaviors[j].onDestroy();
|
||||
@@ -516,8 +520,10 @@ gdjs.RuntimeObject.prototype.setLayer = function(layer) {
|
||||
var newLayer = this._runtimeScene.getLayer(this.layer);
|
||||
|
||||
var rendererObject = this.getRendererObject();
|
||||
oldLayer.getRenderer().removeRendererObject(rendererObject);
|
||||
newLayer.getRenderer().addRendererObject(rendererObject, this.zOrder);
|
||||
if (rendererObject) {
|
||||
oldLayer.getRenderer().removeRendererObject(rendererObject);
|
||||
newLayer.getRenderer().addRendererObject(rendererObject, this.zOrder);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1364,17 +1370,59 @@ gdjs.RuntimeObject.prototype.getSqDistanceToObject = function(otherObject) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the squared distance, in pixels, from the *object center* to a position.
|
||||
* @param {number} pointX X position
|
||||
* @param {number} pointY Y position
|
||||
* Get the distance, in pixels, between *the center* of this object and a position.
|
||||
* @param {number} targetX Target X position
|
||||
* @param {number} targetY Target Y position
|
||||
*/
|
||||
gdjs.RuntimeObject.prototype.getSqDistanceTo = function(pointX, pointY) {
|
||||
var x = this.getDrawableX()+this.getCenterX() - pointX;
|
||||
var y = this.getDrawableY()+this.getCenterY() - pointY;
|
||||
gdjs.RuntimeObject.prototype.getDistanceToPosition = function(targetX, targetY) {
|
||||
return Math.sqrt(this.getSqDistanceToPosition(targetX, targetY));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the squared distance, in pixels, between *the center* of this object and a position.
|
||||
* @param {number} targetX Target X position
|
||||
* @param {number} targetY Target Y position
|
||||
*/
|
||||
gdjs.RuntimeObject.prototype.getSqDistanceToPosition = function(targetX, targetY) {
|
||||
var x = this.getDrawableX()+this.getCenterX() - targetX;
|
||||
var y = this.getDrawableY()+this.getCenterY() - targetY;
|
||||
|
||||
return x*x+y*y;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the squared distance, in pixels, from the *object center* to a position.
|
||||
* @param {number} pointX X position
|
||||
* @param {number} pointY Y position
|
||||
* @deprecated Use `getSqDistanceToPosition` instead.
|
||||
*/
|
||||
gdjs.RuntimeObject.prototype.getSqDistanceTo = gdjs.RuntimeObject.prototype.getSqDistanceToPosition;
|
||||
|
||||
/**
|
||||
* Get the angle, in degrees, from the *object center* to another object.
|
||||
* @param {gdjs.RuntimeObject} otherObject The other object
|
||||
*/
|
||||
gdjs.RuntimeObject.prototype.getAngleToObject = function(otherObject) {
|
||||
if ( otherObject === null ) return 0;
|
||||
|
||||
var x = this.getDrawableX()+this.getCenterX() - (otherObject.getDrawableX()+otherObject.getCenterX());
|
||||
var y = this.getDrawableY()+this.getCenterY() - (otherObject.getDrawableY()+otherObject.getCenterY());
|
||||
|
||||
return Math.atan2(-y, -x)*180/Math.PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the angle, in degrees, from the *object center* to a position.
|
||||
* @param {number} targetX Target X position
|
||||
* @param {number} targetY Target Y position
|
||||
*/
|
||||
gdjs.RuntimeObject.prototype.getAngleToPosition = function(targetX, targetY) {
|
||||
var x = this.getDrawableX()+this.getCenterX() - targetX;
|
||||
var y = this.getDrawableY()+this.getCenterY() - targetY;
|
||||
|
||||
return Math.atan2(-y, -x)*180/Math.PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the object around a position, with a specific distance and angle.
|
||||
* The distance and angle are computed between the position and *the center of the object*.
|
||||
|
@@ -119,6 +119,9 @@ gdjs.RuntimeScene.prototype.loadFromScene = function(sceneData) {
|
||||
//Create initial instances of objects
|
||||
this.createObjectsFrom(sceneData.instances, 0, 0, /*trackByPersistentUuid=*/ true);
|
||||
|
||||
// Set up the default z order (for objects created from events)
|
||||
this._setLayerDefaultZOrders();
|
||||
|
||||
//Set up the function to be executed at each tick
|
||||
this.setEventsGeneratedCodeFunction(sceneData);
|
||||
|
||||
@@ -315,6 +318,36 @@ gdjs.RuntimeScene.prototype.createObjectsFrom = function(data, xPos, yPos, track
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the default Z order for each layer, which is the highest Z order found on each layer.
|
||||
* Useful as it ensures that instances created from events are, by default, shown in front
|
||||
* of other instances.
|
||||
* @private
|
||||
*/
|
||||
gdjs.RuntimeScene.prototype._setLayerDefaultZOrders = function() {
|
||||
if (this._runtimeGame.getGameData().properties.useDeprecatedZeroAsDefaultZOrder) {
|
||||
// Deprecated option to still support games that were made considered 0 as the
|
||||
// default Z order for all layers.
|
||||
return;
|
||||
}
|
||||
|
||||
/** @type {Object.<string, number>} */
|
||||
var layerHighestZOrders = {};
|
||||
|
||||
var allInstances = this.getAdhocListOfAllInstances();
|
||||
for(var i = 0, len = allInstances.length;i<len;++i) {
|
||||
var object = allInstances[i];
|
||||
var layerName = object.getLayer();
|
||||
var zOrder = object.getZOrder();
|
||||
|
||||
if (layerHighestZOrders[layerName] === undefined || layerHighestZOrders[layerName] < zOrder)
|
||||
layerHighestZOrders[layerName] = zOrder;
|
||||
}
|
||||
|
||||
for(var layerName in layerHighestZOrders) {
|
||||
this.getLayer(layerName).setDefaultZOrder(layerHighestZOrders[layerName] + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the function called each time the scene is stepped to be the events generated code,
|
||||
|
@@ -903,7 +903,7 @@ gdjs.SpriteRuntimeObject.prototype.setColor = function(rgbColor) {
|
||||
/**
|
||||
* Get the tint of the sprite object.
|
||||
*
|
||||
* @returns {string} rgbColor The color, in RGB format ("128;200;255").
|
||||
* @returns {string} The color, in RGB format ("128;200;255").
|
||||
*/
|
||||
gdjs.SpriteRuntimeObject.prototype.getColor = function() {
|
||||
return this._renderer.getColor();
|
||||
|
@@ -5,24 +5,98 @@
|
||||
*/
|
||||
|
||||
// Import all the types as global typedefs so that they can be used
|
||||
// in any JS file of the game engine/extensions/tests. This file is not read by JSDoc
|
||||
// because it's not compatible with these TypeScript definitions and import.
|
||||
// in any JS file of the game engine/extensions/tests.
|
||||
|
||||
/** @typedef { import("./project-data").ProjectData } ProjectData */
|
||||
/** @typedef { import("./project-data").ProjectPropertiesData } ProjectPropertiesData */
|
||||
/** @typedef { import("./project-data").LoadingScreenData } LoadingScreenData */
|
||||
/** @typedef { import("./project-data").LayoutData } LayoutData */
|
||||
/** @typedef { import("./project-data").ExternalLayoutData } ExternalLayoutData */
|
||||
/** @typedef { import("./project-data").InstanceData } InstanceData */
|
||||
/** @typedef { import("./project-data").LayerData } LayerData */
|
||||
/** @typedef { import("./project-data").CameraData } CameraData */
|
||||
/** @typedef { import("./project-data").EffectData } EffectData */
|
||||
/** @typedef { import("./project-data").ResourceData } ResourceData */
|
||||
/** @typedef { import("./project-data").ResourcesData } ResourcesData */
|
||||
/** @typedef { import("./project-data").BehaviorSharedData } BehaviorSharedData */
|
||||
|
||||
/** @typedef { import("pixi.js") } PIXI */
|
||||
|
||||
// Also declare the context that is passed to JavaScript functions in events:
|
||||
|
||||
/**
|
||||
* @typedef { import("./project-data").ProjectData } ProjectData
|
||||
* @typedef { import("./project-data").ProjectPropertiesData } ProjectPropertiesData
|
||||
* @typedef { import("./project-data").LoadingScreenData } LoadingScreenData
|
||||
* @typedef { import("./project-data").LayoutData } LayoutData
|
||||
* @typedef { import("./project-data").ExternalLayoutData } ExternalLayoutData
|
||||
* @typedef { import("./project-data").InstanceData } InstanceData
|
||||
* @typedef { import("./project-data").LayerData } LayerData
|
||||
* @typedef { import("./project-data").CameraData } CameraData
|
||||
* @typedef { import("./project-data").EffectData } EffectData
|
||||
* @typedef { import("./project-data").ResourceData } ResourceData
|
||||
* @typedef { import("./project-data").ResourcesData } ResourcesData
|
||||
* @typedef { import("./project-data").BehaviorSharedData } BehaviorSharedData
|
||||
* Function returning the list of instances of the specified object.
|
||||
*
|
||||
* @callback GetObjectsFunction
|
||||
* @param {string} objectName The name of the object for which instances must be returned.
|
||||
* @return {gdjs.RuntimeObject[]} Instances of the specified object.
|
||||
* @see EventsFunctionContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef { import("pixi.js") } PIXI
|
||||
* Function returning the Hashtable containing the lists of instances of the specified object.
|
||||
*
|
||||
* You can alter the list and this will alter the objects picked for the next conditions/actions/events.
|
||||
* If you don't need this, prefer using `getObjects`.
|
||||
*
|
||||
* @callback GetObjectsListsFunction
|
||||
* @param {string} objectName The name of the object for which instances must be returned.
|
||||
* @return {?Hashtable} Hashtable containing the lists of instances (keys are object names in the current context), or `null` if not found
|
||||
* @see EventsFunctionContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function creating a new object from its name. The object is added to the instances
|
||||
* living on the scene.
|
||||
*
|
||||
* @callback CreateObjectFunction
|
||||
* @param {string} objectName The name of the object to be created
|
||||
* @return {gdjs.RuntimeObject} The created object
|
||||
* @see EventsFunctionContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to get the "real" behavior name, that can be used with `getBehavior`. For example:
|
||||
* `object.getBehavior(eventsFunctionContext.getBehaviorName("MyBehavior"))`
|
||||
*
|
||||
* @callback GetBehaviorNameFunction
|
||||
* @param {string} behaviorName The name of the behavior, as specified in the parameters of the function.
|
||||
* @return {string} The name that can be passed to `getBehavior`.
|
||||
* @see EventsFunctionContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function returning the value (string or number) of an argument that was passed to the events function.
|
||||
* To get objects, use `getObjects`.
|
||||
*
|
||||
* @callback GetArgumentFunction
|
||||
* @param {string} argumentName The name of the argument, as specified in the parameters of the function.
|
||||
* @return {string|number} The string or number passed for this argument
|
||||
* @see EventsFunctionContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function returning the layer with the given name
|
||||
*
|
||||
* @callback GetLayerFunction
|
||||
* @param {string} name The name of the layer.
|
||||
* @return {gdjs.Layer} The layer with the given name, or the base layer if not found.
|
||||
* @see EventsFunctionContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the context of the events function (or the behavior method),
|
||||
* if any. If the JavaScript code is running in a scene, this will be undefined (so you can't use this in a scene).
|
||||
*
|
||||
* @typedef {Object} EventsFunctionContext
|
||||
* @property {GetObjectsFunction} getObjects Get the list of instances of the specified object.
|
||||
* @property {GetLayerFunction} getLayer Use `runtimeScene.getLayer` instead.
|
||||
* @property {GetObjectsListsFunction} getObjectsLists Get the Hashtable containing the lists of instances of the specified object.
|
||||
*
|
||||
* You can alter the list and this will alter the objects picked for the next conditions/actions/events.
|
||||
* If you don't need this, prefer using `getObjects`.
|
||||
* @property {GetBehaviorNameFunction} getBehaviorName Get the "real" behavior name, that can be used with `getBehavior`. For example: `object.getBehavior(eventsFunctionContext.getBehaviorName("MyBehavior"))`
|
||||
* @property {CreateObjectFunction} createObject Create a new object from its name. The object is added to the instances living on the scene.
|
||||
* @property {GetArgumentFunction} getArgument Get the value (string or number) of an argument that was passed to the events function. To get objects, use `getObjects`.
|
||||
* @property {boolean | number | string} returnValue The return value that should be returned by the expression or the condition.
|
||||
*/
|
||||
|
7
GDJS/Runtime/types/project-data.d.ts
vendored
7
GDJS/Runtime/types/project-data.d.ts
vendored
@@ -121,11 +121,8 @@ export interface EffectData {
|
||||
}
|
||||
|
||||
export interface ProjectPropertiesData {
|
||||
adMobAppId: string;
|
||||
adaptGameResolutionAtRuntime: boolean;
|
||||
folderProject: boolean;
|
||||
linuxExecutableFilename: string;
|
||||
macExecutableFilename: string;
|
||||
orientation: string;
|
||||
packageName: string;
|
||||
projectFile: string;
|
||||
@@ -133,8 +130,6 @@ export interface ProjectPropertiesData {
|
||||
sizeOnStartupMode: string;
|
||||
useExternalSourceFiles: boolean;
|
||||
version: string;
|
||||
winExecutableFilename: string;
|
||||
winExecutableIconFile: string;
|
||||
name: string;
|
||||
author: string;
|
||||
windowWidth: number;
|
||||
@@ -146,6 +141,8 @@ export interface ProjectPropertiesData {
|
||||
loadingScreen: LoadingScreenData;
|
||||
currentPlatform: string;
|
||||
extensionProperties: Array<ExtensionProperty>;
|
||||
useDeprecatedZeroAsDefaultZOrder?: boolean;
|
||||
projectUuid?: string;
|
||||
}
|
||||
|
||||
export interface ExtensionProperty {
|
||||
|
2
GDJS/docs/jaguarjs-jsdoc/.gitignore
vendored
2
GDJS/docs/jaguarjs-jsdoc/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
node_modules/
|
||||
demo/dist/
|
@@ -1,128 +0,0 @@
|
||||
/**
|
||||
* http://gruntjs.com/configuring-tasks
|
||||
*/
|
||||
module.exports = function (grunt) {
|
||||
var path = require('path');
|
||||
var DEMO_PATH = 'demo/dist';
|
||||
var DEMO_SAMPLE_PATH = 'demo/sample';
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
connect: {
|
||||
options: {
|
||||
hostname: '*'
|
||||
},
|
||||
demo: {
|
||||
options: {
|
||||
port: 8000,
|
||||
base: DEMO_PATH,
|
||||
middleware: function (connect, options) {
|
||||
return [
|
||||
require('connect-livereload')(),
|
||||
connect.static(path.resolve(options.base))
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
options: {
|
||||
livereload: true
|
||||
},
|
||||
less: {
|
||||
files: ['less/**/*.less'],
|
||||
tasks: ['less']
|
||||
},
|
||||
|
||||
lesscopy: {
|
||||
files: ['static/styles/jaguar.css'],
|
||||
tasks: ['copy:css']
|
||||
},
|
||||
|
||||
jscopy: {
|
||||
files: ['static/scripts/main.js'],
|
||||
tasks: ['copy:js']
|
||||
},
|
||||
|
||||
jsdoc: {
|
||||
files: ['**/*.tmpl', '*.js'],
|
||||
tasks: ['jsdoc']
|
||||
},
|
||||
|
||||
demo: {
|
||||
files: ['demo/sample/**/*.js'],
|
||||
tasks: ['demo']
|
||||
}
|
||||
},
|
||||
|
||||
clean: {
|
||||
demo: {
|
||||
src: DEMO_PATH
|
||||
}
|
||||
},
|
||||
|
||||
jsdoc: {
|
||||
demo: {
|
||||
src: [
|
||||
DEMO_SAMPLE_PATH + '/**/*.js',
|
||||
|
||||
// You can add README.md file for index page at documentations.
|
||||
'README.md'
|
||||
],
|
||||
options: {
|
||||
verbose: true,
|
||||
destination: DEMO_PATH,
|
||||
configure: 'conf.json',
|
||||
template: './',
|
||||
'private': false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
less: {
|
||||
dist: {
|
||||
src: 'less/**/jaguar.less',
|
||||
dest: 'static/styles/jaguar.css'
|
||||
}
|
||||
},
|
||||
|
||||
copy: {
|
||||
css: {
|
||||
src: 'static/styles/jaguar.css',
|
||||
dest: DEMO_PATH + '/styles/jaguar.css'
|
||||
},
|
||||
|
||||
js: {
|
||||
src: 'static/scripts/main.js',
|
||||
dest: DEMO_PATH + '/scripts/main.js'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Load task libraries
|
||||
[
|
||||
'grunt-contrib-connect',
|
||||
'grunt-contrib-watch',
|
||||
'grunt-contrib-copy',
|
||||
'grunt-contrib-clean',
|
||||
'grunt-contrib-less',
|
||||
'grunt-jsdoc',
|
||||
].forEach(function (taskName) {
|
||||
grunt.loadNpmTasks(taskName);
|
||||
});
|
||||
|
||||
// Definitions of tasks
|
||||
grunt.registerTask('default', 'Watch project files', [
|
||||
'demo',
|
||||
'connect:demo',
|
||||
'watch'
|
||||
]);
|
||||
|
||||
grunt.registerTask('demo', 'Create documentations for demo', [
|
||||
'less',
|
||||
'clean:demo',
|
||||
'jsdoc:demo'
|
||||
]);
|
||||
};
|
@@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Sangmin, Shim
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,56 +0,0 @@
|
||||
Jaguar.js template for JSDoc 3
|
||||
---
|
||||
- [Jaguar.js](https://davidshimjs.github.io/jaguarjs/)
|
||||
- [Jaguar.js Documentations](https://davidshimjs.github.io/jaguarjs/doc/)
|
||||
- [JSDoc3](https://github.com/jsdoc3/jsdoc)
|
||||
- [JSDoc3 API Documentations](http://usejsdoc.org)
|
||||
|
||||
Usage
|
||||
---
|
||||
1. If you want to create documentations with sample files, you can use commands below.
|
||||
```
|
||||
$ npm install
|
||||
$ grunt demo
|
||||
```
|
||||
|
||||
2. You can see any output related jsdoc process with a `--debug` flag.
|
||||
```
|
||||
$ grunt demo --debug
|
||||
```
|
||||
|
||||
3. If you already have jsdoc system, you can use this project as jsdoc template.
|
||||
```
|
||||
$ jsdoc -t `project folder` -c `configuration file` `source files` `README.md file`
|
||||
```
|
||||
|
||||
conf.json
|
||||
---
|
||||
You can set options for customizing your documentations.
|
||||
|
||||
```
|
||||
"templates": {
|
||||
"applicationName": "Demo",
|
||||
"disqus": "",
|
||||
"googleAnalytics": "",
|
||||
"openGraph": {
|
||||
"title": "",
|
||||
"type": "website",
|
||||
"image": "",
|
||||
"site_name": "",
|
||||
"url": ""
|
||||
},
|
||||
"meta": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"keyword": ""
|
||||
},
|
||||
"linenums": true
|
||||
}
|
||||
```
|
||||
|
||||
License
|
||||
---
|
||||
This project under the MIT License. and this project refered by default template for JSDoc 3.
|
||||
|
||||
[](https://bitdeli.com/free "Bitdeli Badge")
|
||||
|
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"tags": {
|
||||
"allowUnknownTags" : true
|
||||
},
|
||||
"plugins": ["plugins/markdown"],
|
||||
"templates": {
|
||||
"cleverLinks": true,
|
||||
"monospaceLinks": true,
|
||||
"default": {
|
||||
"outputSourceFiles" : true
|
||||
},
|
||||
"applicationName": "Demo",
|
||||
"disqus": "",
|
||||
"googleAnalytics": "",
|
||||
"openGraph": {
|
||||
"title": "",
|
||||
"type": "website",
|
||||
"image": "",
|
||||
"site_name": "",
|
||||
"url": ""
|
||||
},
|
||||
"meta": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"keyword": ""
|
||||
},
|
||||
"linenums": false
|
||||
},
|
||||
"markdown": {
|
||||
"parser": "gfm",
|
||||
"hardwrap": true,
|
||||
"tags": ["examples"]
|
||||
}
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
(function (w) {
|
||||
/**
|
||||
* quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
* @class
|
||||
* @name namespace.Car
|
||||
*/
|
||||
w.namespace.Car = function () {
|
||||
};
|
||||
|
||||
w.namespace.Car.prototype = /** @lends namespace.Car.prototype */{
|
||||
/**
|
||||
* Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
*/
|
||||
testMethod: function () {
|
||||
},
|
||||
|
||||
testMethodUnNotated: function () {
|
||||
},
|
||||
|
||||
testEvent: function () {
|
||||
/**
|
||||
* tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
* @name namespace.Car#testEvent
|
||||
* @event
|
||||
* @param {Event} e
|
||||
*/
|
||||
test.trigger();
|
||||
}
|
||||
};
|
||||
})(window);
|
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
|
||||
* @class
|
||||
* @extends Parent
|
||||
*/
|
||||
var Child = function () {
|
||||
};
|
||||
|
||||
Child.prototype = /** @lends Child.prototype */{
|
||||
/**
|
||||
* cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidata
|
||||
* @property {Boolean}
|
||||
*/
|
||||
testPropertyInChild: '',
|
||||
|
||||
/**
|
||||
* cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
*/
|
||||
testMethodInChild: function (paramUnNotation) {
|
||||
return {};
|
||||
},
|
||||
|
||||
/**
|
||||
* proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
* @return {Object} result
|
||||
* @return {String} [result.property]
|
||||
* @return {Number} result.property2=123 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
*/
|
||||
returnObject: function () {
|
||||
}
|
||||
};
|
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
var namespace = namespace || {};
|
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
* Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
|
||||
* @class
|
||||
*/
|
||||
var Parent = function () {
|
||||
};
|
||||
|
||||
Parent.prototype = /** @lends Parent.prototype */{
|
||||
/**
|
||||
* cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidata
|
||||
* @property {String}
|
||||
*/
|
||||
testProperty: '',
|
||||
|
||||
/**
|
||||
* Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
* @param {String|String[]} [paramA=Default Value] tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
|
||||
* @param {namespace.Car} [paramB] quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
* @param {Function} [paramCallback]
|
||||
* @param {String} paramCallback.firstParam
|
||||
* @param {String} paramCallback.secondParam
|
||||
* @return {Array|Object} Return value as non-object type. (or an object without properties)
|
||||
*/
|
||||
testMethod: function (paramA, paramB, paramCallback) {
|
||||
return {};
|
||||
},
|
||||
|
||||
/**
|
||||
* This method will return object value.
|
||||
* @return {Object} test returns object.
|
||||
* @return {Boolean} test.foo property description
|
||||
* @return {Number} test.bar optional property
|
||||
*/
|
||||
testReturnValue: function () {
|
||||
},
|
||||
|
||||
/**
|
||||
* @return Plain Text without type definition
|
||||
*/
|
||||
testReturnPlainText: function () {
|
||||
},
|
||||
|
||||
/**
|
||||
* @example
|
||||
* <caption>JSDoc3 Captions</caption>
|
||||
* var a = 0;
|
||||
*
|
||||
* for (var i = 0; i < 10; i++) {
|
||||
* a++;
|
||||
* }
|
||||
*
|
||||
* @example
|
||||
* jaguarjs-doc uses markdown style.
|
||||
*
|
||||
* ```
|
||||
* var a = 0;
|
||||
*
|
||||
* for (var i = 0; i < 10; i++) {
|
||||
* a++;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
testExample: function () {
|
||||
}
|
||||
};
|
@@ -1,9 +0,0 @@
|
||||
@navWidth: 250px;
|
||||
@colorSubtitle: rgb(119, 156, 52);
|
||||
@colorRed: rgb(238, 125, 125);
|
||||
@colorLink: #2a6496;
|
||||
@colorBgNavi: #1a1a1a;
|
||||
|
||||
.font-description () {
|
||||
font-family: "freight-text-pro",Georgia,Cambria,"Times New Roman",Times,serif
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
@import "common.less";
|
||||
|
||||
footer {
|
||||
margin: 15px 0;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #e1e1e1;
|
||||
.font-description();
|
||||
font-size: 0.8em;
|
||||
color: gray;
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
@import "common.less";
|
||||
|
||||
// normalize
|
||||
html, body {
|
||||
font: 1em "jaf-bernino-sans","Lucida Grande","Lucida Sans Unicode","Lucida Sans",Geneva,Verdana,sans-serif;
|
||||
background-color: #fff;
|
||||
}
|
||||
ul, ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
#wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@import "navigation.less";
|
||||
@import "main.less";
|
||||
@import "footer.less";
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user