Compare commits

...

54 Commits

Author SHA1 Message Date
D8H
6e24dfa9b8 Fix object selection for deprecated instructions (#5816) 2023-10-20 17:13:20 +02:00
D8H
a3cd00dc94 Fix a typo in the scale tween action (#5815) 2023-10-20 15:47:29 +02:00
Florian Rival
300c011151 Bump newIDE version (#5813) 2023-10-20 15:24:18 +02:00
D8H
230d410469 Fix missing exported files for scene tweens (#5812) 2023-10-20 15:20:16 +02:00
D8H
402e54f706 Fix the Ease expression of the Tween extension (#5810)
Don't show in changelog
2023-10-20 11:07:19 +02:00
github-actions[bot]
dc29c27272 Update translations [skip ci] (#5803) 2023-10-20 09:01:47 +02:00
Florian Rival
462bb84c51 Fix exporting not shown on iOS (#5808) 2023-10-19 17:26:25 +02:00
AlexandreS
a775e79bae Catch instance rendering process in scene editor (#5806)
Don't show in changelog
2023-10-19 16:32:57 +02:00
Florian Rival
bc8c867f23 Fix parameters not accessible in expressions for 'Action With Operator' functions (#5805) 2023-10-19 15:55:55 +02:00
AlexandreS
f34bf2b7b4 Focus confirm delete button (#5804)
Don't show in changelog
2023-10-19 15:52:18 +02:00
Florian Rival
e2d482e1aa Fix long formulas/expressions going out of the screen in the events sheet 2023-10-19 14:51:21 +02:00
AlexandreS
0724ae34d9 Use electron remote shell to open project folder (#5801)
Don't show in changelog
2023-10-19 14:47:31 +02:00
github-actions[bot]
2fc1c2fd86 Update translations [skip ci] (#5774) 2023-10-19 12:19:58 +02:00
D8H
9a42ae11ad Tween extension rework (#5710)
Fix bugs and change implementation for a better maintainability.
2023-10-19 11:24:32 +02:00
Florian Rival
32773e06f6 Improve error message when exception at runtime (#5800) 2023-10-19 10:20:08 +02:00
Florian Rival
00508df014 Don't show an undeclared variable as an error in action/condition editor 2023-10-18 17:22:07 +02:00
Florian Rival
c3cf5b7002 Display an error message in game when an exception/crash is detected (#5799) 2023-10-18 17:19:11 +02:00
AlexandreS
df7fab84b8 Bump newIDE version (#5798) 2023-10-18 16:39:32 +02:00
AlexandreS
95a0012c5e Load texture in runtime even if filename does not have an extension (#5797)
Don't show in changelog
2023-10-18 16:38:25 +02:00
AlexandreS
4bf644f9f2 Add "Help > About GDevelop" menu option for non-Mac users (#5796)
---------

Co-authored-by: Tristan Rhodes <tristan.rhodes@gmail.com>
2023-10-18 13:01:02 +02:00
AlexandreS
79cad1da3a Fix error message not cleared after choosing a color in a color picker (#5794) 2023-10-18 12:47:57 +02:00
AlexandreS
ffc6f5786b Do not clear selection when panning with middle mouse button (#5795) 2023-10-18 12:24:08 +02:00
Florian Rival
07df65f8c2 Fix a potential crash by ensuring selection of instances does not contain deleted global objects (#5791)
- Also keep the selection of objects/folders when changing between scene tabs (unless they have been deleted)
2023-10-18 11:12:19 +02:00
D8H
61f8f0ed66 Fix Bitmap text resource action parameter type (#5793) 2023-10-18 10:55:20 +02:00
D8H
c24e2e5ace Use similar wording for angle conditions (#5792)
* Don't show in changelog
2023-10-17 18:45:17 +02:00
D8H
25c72a6d1f Optimize evaluation of several forces on 1 object (#5789) 2023-10-17 17:09:27 +02:00
AlexandreS
6153b23e7d Improve data sent to automatic error report (#5790)
Also, attempt to fix a crash at GDevelop editor opening.
2023-10-17 16:48:47 +02:00
Florian Rival
1b7ccfded3 Fix warning 2023-10-17 14:00:37 +02:00
Florian Rival
ec57a0a80d Improve the Share/Publish dialog: larger window, clearer sections and wording (#5785) 2023-10-17 11:28:29 +02:00
D8H
95a9e37aba Add animation time control for sprites and 3D models (#5777) 2023-10-17 10:02:49 +02:00
D8H
787274f7fa Fix 3D distance sorting issues by using a higher default near plane (#5784) 2023-10-17 09:55:23 +02:00
D8H
ceb24f0edb Unify text expressions conditions and actions between objects (#5778) 2023-10-16 18:17:50 +02:00
D8H
028bf7a70d Fix Physics behavior forces effect under 60 fps (#5783) 2023-10-16 17:50:52 +02:00
AlexandreS
08471d0356 Use componentWillReceiveProps rather than componentWillUpdate (#5782)
Don't show in changelog
2023-10-16 17:15:27 +02:00
AlexandreS
921add6665 Organize your objects into folders (#5655)
You can now create folders as a means to organize your objects when editing a scene or an external layout.

Thanks to @Silver-Streak, Matt Pin, @arthuro555, SnailMail, @TheGemDev, Peeble, Rasterisko for all the help designing and testing the feature.

Note that object tags have been dropped in this version since they were not practical to use thus not widespread used.
2023-10-16 17:04:20 +02:00
AlexandreS
dabff06891 Add error message when trying to login without connection to internet (#5780) 2023-10-16 11:37:43 +02:00
AlexandreS
967033c407 Fix scene loading for video resources (#5772)
Listen error event on base texture loading
Also makes file watcher listen on addition and removal of files.
2023-10-13 15:03:57 +02:00
Florian Rival
0809749ddc Hide expressions GetArgumentAsString and GetArgumentAsNumber as they are now replaced by just being able to write the parameter name in an expression (#5773) 2023-10-13 10:14:28 +02:00
github-actions[bot]
8a27801355 Update translations [skip ci] (#5766)
Co-authored-by: AlexandreSi <AlexandreSi@users.noreply.github.com>
2023-10-12 18:30:18 +02:00
AlexandreS
20cba9d7ed Fix linter and types (#5770)
Don't show in changelog
2023-10-12 18:00:31 +02:00
AlexandreS
3878b93c94 Fix: Prevent loading of forbidden GIF file from crashing a game loading screen (#5769) 2023-10-12 17:01:10 +02:00
D8H
645d5331cb Add a setting to show warnings about deprecated instructions (#5755) 2023-10-12 16:55:02 +02:00
AlexandreS
91db750632 Reload resources in the editor when the resource changes (#5631)
GDevelop now refreshes resources (images, videos, 3D models, fonts, etc.) when a change is detected on the filesystem so that you can immediately see the changes.

This allows to efficiently use GDevelop alongside other tools (Tiled or LDtk for instance).

Notes:
- This logically only affects the desktop version for projects saved on the filesystem;
- You can deactivate it in the preferences.
2023-10-12 16:01:01 +02:00
Clément Pasteau
740485b54a Activate support for unicode characters (including emojis) for all names (objects, groups, variables, functions, parameters) on all projects (#5703) 2023-10-12 15:25:37 +02:00
Florian Rival
e960fe7c5b Fix unicode/emojis not supported in function parameter names (#5768) 2023-10-12 15:20:12 +02:00
AlexandreS
0633c7b474 Fix: Prevent root variable from having white spaces (#5767) 2023-10-12 15:13:18 +02:00
AlexandreS
704bfd40cb Fix example opening wrongfully opening "Create from scratch" dialog (#5765) 2023-10-12 14:34:24 +02:00
github-actions[bot]
310abe7a13 Update translations [skip ci] (#5759)
Co-authored-by: D8H <D8H@users.noreply.github.com>
2023-10-12 14:11:12 +02:00
Daniel R
b0f9bed273 Add string condition operators: starts with, ends with and contains (#4970)
- Thanks @danired
2023-10-12 13:33:32 +02:00
Clément Pasteau
766a62ad9b Invalidate cache when updating Panel Sprite opacity (#5764)
* This fixes a bug where creating a panel sprite with low opacity would prevent changing its opacity afterwards
2023-10-12 13:27:08 +02:00
D8H
ec6f669d94 Add HSL adjustment, motion blur and shockwave effects (#5760) 2023-10-12 10:49:29 +02:00
D8H
36a2408be0 Fix particles angle when the speed is negative (#5762) 2023-10-12 10:48:23 +02:00
Clément Pasteau
1343210a2b Fix "Locate file" for resource to open the folder in front of the app (#5758) 2023-10-11 15:52:27 +02:00
github-actions[bot]
1e76fedd7b Update translations [skip ci] (#5757)
Co-authored-by: ClementPasteau <ClementPasteau@users.noreply.github.com>
2023-10-11 15:15:25 +02:00
383 changed files with 32392 additions and 5663 deletions

View File

@@ -69,8 +69,36 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
}
}
return callStartString + "(" + argumentsStr + ") " + relationalOperator +
" " + rhs;
auto lhs = callStartString + "(" + argumentsStr + ")";
return GenerateRelationalOperation(relationalOperator, lhs, rhs);
}
/**
* @brief Generate a relational operation
*
* @param relationalOperator the operator
* @param lhs the left hand operand
* @param rhs the right hand operand
* @return gd::String
*/
gd::String EventsCodeGenerator::GenerateRelationalOperation(
const gd::String& relationalOperator,
const gd::String& lhs,
const gd::String& rhs) {
return lhs + " " + GenerateRelationalOperatorCodes(relationalOperator) + " " + rhs;
}
const gd::String EventsCodeGenerator::GenerateRelationalOperatorCodes(const gd::String &operatorString) {
if (operatorString == "=") {
return "==";
}
if (operatorString != "<" && operatorString != ">" &&
operatorString != "<=" && operatorString != ">=" && operatorString != "!=" &&
operatorString != "startsWith" && operatorString != "endsWith" && operatorString != "contains") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
return "==";
}
return operatorString;
}
/**
@@ -638,18 +666,6 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
return outputCode;
}
const gd::String EventsCodeGenerator::GenerateRelationalOperatorCodes(const gd::String &operatorString) {
if (operatorString == "=") {
return "==";
}
if (operatorString != "<" && operatorString != ">" &&
operatorString != "<=" && operatorString != ">=" && operatorString != "!=") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
return "==";
}
return operatorString;
}
gd::String EventsCodeGenerator::GenerateParameterCodes(
const gd::Expression& parameter,
const gd::ParameterMetadata& metadata,
@@ -674,7 +690,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
argOutput =
GenerateObject(parameter.GetPlainString(), metadata.GetType(), context);
} else if (metadata.GetType() == "relationalOperator") {
argOutput += GenerateRelationalOperatorCodes(parameter.GetPlainString());
argOutput += parameter.GetPlainString();
argOutput = "\"" + argOutput + "\"";
} else if (metadata.GetType() == "operator") {
argOutput += parameter.GetPlainString();

View File

@@ -473,10 +473,15 @@ class GD_CORE_API EventsCodeGenerator {
*/
size_t GenerateSingleUsageUniqueIdForEventsList();
virtual gd::String GenerateRelationalOperation(
const gd::String& relationalOperator,
const gd::String& lhs,
const gd::String& rhs);
protected:
virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString);
protected:
/**
* \brief Generate the code for a single parameter.
*
@@ -732,6 +737,7 @@ class GD_CORE_API EventsCodeGenerator {
const std::vector<gd::String>& arguments,
const gd::String& callStartString,
std::size_t startFromArgument = 0);
gd::String GenerateOperatorCall(const gd::InstructionMetadata& instrInfos,
const std::vector<gd::String>& arguments,
const gd::String& callStartString,

View File

@@ -115,21 +115,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddExpression(
"GetArgumentAsNumber",
_("Get function parameter value"),
_("Get function parameter (also called \"argument\") value."),
_("Get function parameter (also called \"argument\") value. You don't need this most of the time as you can simply write the parameter name in an expression."),
"",
"res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression(
"GetArgumentAsString",
_("Get function parameter text"),
_("Get function parameter (also called \"argument\") text."),
_("Get function parameter (also called \"argument\") text. You don't need this most of the time as you can simply write the parameter name in an expression."),
"",
"res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition(

View File

@@ -49,6 +49,7 @@ class GD_CORE_API BuiltinExtensionsImplementer {
static void ImplementsAnimatableExtension(gd::PlatformExtension& extension);
static void ImplementsEffectExtension(gd::PlatformExtension& extension);
static void ImplementsOpacityExtension(gd::PlatformExtension& extension);
static void ImplementsTextContainerExtension(gd::PlatformExtension& extension);
};
} // namespace gd

View File

@@ -617,6 +617,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
// Deprecated
obj.AddCondition("AngleOfDisplacement",
_("Angle of movement (using forces)"),
_("Compare the angle of movement of an object according to "
@@ -626,7 +627,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/conditions/vitesse24.png",
"res/conditions/vitesse.png")
.SetHidden()
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))
.MarkAsAdvanced();
obj.AddCondition("IsTotalForceAngleAround",
_("Angle of movement (using forces)"),
_("Compare the angle of movement of an object according to "
"the forces applied on it."),
_("Angle of movement of _PARAM0_ is _PARAM1_ ± _PARAM2_°"),
_("Movement using forces"),
"res/conditions/vitesse24.png",
"res/conditions/vitesse.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))

View File

@@ -23,6 +23,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Animatable capability"))
.SetIcon("res/actions/animation24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
.SetIcon("res/actions/animation24.png");
@@ -53,6 +55,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Animation index")))
.MarkAsSimple();
aut.GetAllExpressions()["Index"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"string",
@@ -69,6 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"objectAnimationName", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Animation name")))
.MarkAsSimple();
aut.GetAllStrExpressions()["Name"].SetGroup("");
aut.AddScopedAction("PauseAnimation",
_("Pause the animation"),
@@ -107,6 +111,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Speed scale")))
.MarkAsSimple();
aut.GetAllExpressions()["SpeedScale"].SetGroup("");
aut.AddScopedCondition("IsAnimationPaused",
_("Animation paused"),
@@ -130,6 +135,31 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.MarkAsSimple();
aut.AddExpressionAndConditionAndAction(
"number",
"ElapsedTime",
_("Animation elapsed time"),
_("the elapsed time from the beginning of the animation (in seconds)"),
_("the animation elapsed time"),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.UseStandardParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Elapsed time (in seconds)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["ElapsedTime"].SetGroup("");
aut.AddExpression(
"Duration",
_("Animation duration"),
_("Return the current animation duration (in seconds)."),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior");
}
} // namespace gd

View File

@@ -23,6 +23,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Opacity capability"))
.SetIcon("res/actions/opacity24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
.SetIcon("res/actions/opacity24.png");
@@ -54,6 +56,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
_("Opacity (0-255)")))
.SetFunctionName("setOpacity")
.SetGetter("getOpacity");
aut.GetAllExpressions()["Value"].SetGroup("");
}
} // namespace gd

View File

@@ -23,6 +23,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable capability"))
.SetIcon("res/actions/scale24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
.SetIcon("res/actions/scale24_black.png");
@@ -53,6 +55,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["Value"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"number",
@@ -69,6 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["X"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"number",
@@ -85,6 +89,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["Y"].SetGroup("");
}
} // namespace gd

View File

@@ -0,0 +1,58 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("TextContainerCapability",
_("Text capability"),
_("Animate objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Text capability"))
.SetIcon("res/conditions/text24_black.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"TextContainerBehavior",
_("Text capability"),
"Text",
_("Access objects text."),
"",
"res/conditions/text24_black.png",
"TextContainerBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddExpressionAndConditionAndAction(
"string",
"Value",
_("Text"),
_("the text"),
_("the text"),
"",
"res/conditions/text24_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "TextContainerBehavior")
.UseStandardParameters(
"string", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Text")))
.MarkAsSimple();
aut.GetAllStrExpressions()["Value"].SetGroup("");
}
} // namespace gd

View File

@@ -293,8 +293,8 @@ void ResourceWorkerInObjectsWorker::DoVisitBehavior(gd::Behavior &behavior){
gd::ResourceWorkerInObjectsWorker
GetResourceWorkerOnObjects(const gd::Project &project,
gd::ArbitraryResourceWorker &worker) {
gd::ResourceWorkerInObjectsWorker eventsWorker(project, worker);
return eventsWorker;
gd::ResourceWorkerInObjectsWorker resourcesWorker(project, worker);
return resourcesWorker;
}
} // namespace gd

View File

@@ -0,0 +1,19 @@
#include "ObjectsUsingResourceCollector.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
namespace gd {
void ObjectsUsingResourceCollector::DoVisitObject(gd::Object& object) {
gd::ResourceNameMatcher resourceNameMatcher(resourceName);
object.GetConfiguration().ExposeResources(resourceNameMatcher);
if (resourceNameMatcher.AnyResourceMatches()) {
objectNames.push_back(object.GetName());
}
};
ObjectsUsingResourceCollector::~ObjectsUsingResourceCollector() {}
} // namespace gd

View File

@@ -0,0 +1,89 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef ProjectObjectsUsingResourceCollector_H
#define ProjectObjectsUsingResourceCollector_H
#include <vector>
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/String.h"
namespace gd {
class Object;
} // namespace gd
namespace gd {
class GD_CORE_API ObjectsUsingResourceCollector
: public ArbitraryObjectsWorker {
public:
ObjectsUsingResourceCollector(const gd::String& resourceName_)
: resourceName(resourceName_){};
virtual ~ObjectsUsingResourceCollector();
std::vector<gd::String>& GetObjectNames() { return objectNames; }
private:
void DoVisitObject(gd::Object& object) override;
std::vector<gd::String> objectNames;
gd::String resourceName;
};
class GD_CORE_API ResourceNameMatcher : public ArbitraryResourceWorker {
public:
ResourceNameMatcher(const gd::String& resourceName_)
: resourceName(resourceName_), matchesResourceName(false){};
virtual ~ResourceNameMatcher(){};
bool AnyResourceMatches() { return matchesResourceName; }
void Reset() { matchesResourceName = false; }
private:
virtual void ExposeFile(gd::String& resource) override{
/*Don't care, we just read resource names*/
};
virtual void ExposeImage(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeAudio(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeFont(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeJson(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeTilemap(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeTileset(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeVideo(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeBitmapFont(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeModel3D(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
void MatchResourceName(gd::String& otherResourceName) {
if (otherResourceName == resourceName) matchesResourceName = true;
}
gd::String resourceName;
bool matchesResourceName;
};
}; // namespace gd
#endif // ProjectObjectsUsingResourceCollector_H

View File

@@ -140,7 +140,7 @@ void ProjectBrowserHelper::ExposeProjectEvents(
globalObjectsAndGroups, objectsAndGroups);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(globalObjectsAndGroups, objectsAndGroups);
projectScopedContainers.AddParameters(eventsFunction->GetParameters());
projectScopedContainers.AddParameters(eventsFunction->GetParametersForEvents(eventsFunctionsExtension));
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -183,7 +183,7 @@ void ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(globalObjectsAndGroups, objectsAndGroups);
projectScopedContainers.AddPropertiesContainer(eventsBasedBehavior.GetSharedPropertyDescriptors());
projectScopedContainers.AddPropertiesContainer(eventsBasedBehavior.GetPropertyDescriptors());
projectScopedContainers.AddParameters(eventsFunction->GetParameters());
projectScopedContainers.AddParameters(eventsFunction->GetParametersForEvents(eventsBasedBehavior.GetEventsFunctions()));
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -202,7 +202,7 @@ void ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(globalObjectsAndGroups, objectsAndGroups);
projectScopedContainers.AddPropertiesContainer(eventsBasedObject.GetPropertyDescriptors());
projectScopedContainers.AddParameters(eventsFunction->GetParameters());
projectScopedContainers.AddParameters(eventsFunction->GetParametersForEvents(eventsBasedObject.GetEventsFunctions()));
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}

View File

@@ -17,7 +17,7 @@ EventsBasedObject::EventsBasedObject()
}
EventsBasedObject::~EventsBasedObject() {}
EventsBasedObject::EventsBasedObject(const gd::EventsBasedObject &_eventBasedObject)
: AbstractEventsBasedEntity(_eventBasedObject) {
// TODO Add a copy constructor in ObjectsContainer.
@@ -30,14 +30,19 @@ void EventsBasedObject::SerializeTo(SerializerElement& element) const {
AbstractEventsBasedEntity::SerializeTo(element);
SerializeObjectsTo(element.AddChild("objects"));
SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
}
void EventsBasedObject::UnserializeFrom(gd::Project& project,
const SerializerElement& element) {
const SerializerElement& element) {
defaultName = element.GetStringAttribute("defaultName");
AbstractEventsBasedEntity::UnserializeFrom(project, element);
UnserializeObjectsFrom(project, element.GetChild("objects"));
if (element.HasChild("objectsFolderStructure")) {
UnserializeFoldersFrom(project, element.GetChild("objectsFolderStructure", 0));
}
AddMissingObjectsInRootFolder();
}
} // namespace gd

View File

@@ -19,7 +19,7 @@ Layer::Layer()
isLocked(false),
isLightingLayer(false),
followBaseLayerCamera(false),
camera3DNearPlaneDistance(0.1),
camera3DNearPlaneDistance(3),
camera3DFarPlaneDistance(10000),
camera3DFieldOfView(45),
ambientLightColorR(200),

View File

@@ -294,6 +294,7 @@ void Layout::SerializeTo(SerializerElement& element) const {
GetVariables().SerializeTo(element.AddChild("variables"));
GetInitialInstances().SerializeTo(element.AddChild("instances"));
SerializeObjectsTo(element.AddChild("objects"));
SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
@@ -353,6 +354,11 @@ void Layout::UnserializeFrom(gd::Project& project,
project, GetEvents(), element.GetChild("events", 0, "Events"));
UnserializeObjectsFrom(project, element.GetChild("objects", 0, "Objets"));
if (element.HasChild("objectsFolderStructure")) {
UnserializeFoldersFrom(project, element.GetChild("objectsFolderStructure", 0));
}
AddMissingObjectsInRootFolder();
initialInstances.UnserializeFrom(
element.GetChild("instances", 0, "Positions"));
variables.UnserializeFrom(element.GetChild("variables", 0, "Variables"));

View File

@@ -40,7 +40,6 @@ void Object::Init(const gd::Object& object) {
name = object.name;
assetStoreId = object.assetStoreId;
objectVariables = object.objectVariables;
tags = object.tags;
effectsContainer = object.effectsContainer;
behaviors.clear();
@@ -134,7 +133,6 @@ void Object::UnserializeFrom(gd::Project& project,
SetType(element.GetStringAttribute("type"));
assetStoreId = element.GetStringAttribute("assetStoreId");
name = element.GetStringAttribute("name", name, "nom");
tags = element.GetStringAttribute("tags");
objectVariables.UnserializeFrom(
element.GetChild("variables", 0, "Variables"));
@@ -207,7 +205,6 @@ void Object::SerializeTo(SerializerElement& element) const {
element.SetAttribute("name", GetName());
element.SetAttribute("assetStoreId", GetAssetStoreId());
element.SetAttribute("type", GetType());
element.SetAttribute("tags", GetTags());
objectVariables.SerializeTo(element.AddChild("variables"));
effectsContainer.SerializeTo(element.AddChild("effects"));

View File

@@ -120,14 +120,6 @@ class GD_CORE_API Object {
*/
const gd::String& GetType() const { return configuration->GetType(); }
/** \brief Change the tags of the object.
*/
void SetTags(const gd::String& tags_) { tags = tags_; }
/** \brief Return the tags of the object.
*/
const gd::String& GetTags() const { return tags; }
/** \brief Shortcut to check if the object is a 3D object.
*/
bool Is3DObject() const { return configuration->Is3DObject(); }
@@ -268,7 +260,6 @@ class GD_CORE_API Object {
///< object.
gd::VariablesContainer
objectVariables; ///< List of the variables of the object
gd::String tags; ///< Comma-separated list of tags
gd::EffectsContainer
effectsContainer; ///< The effects container for the object.
mutable gd::String persistentUuid; ///< A persistent random version 4 UUID,

View File

@@ -0,0 +1,248 @@
/*
* GDevelop Core
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Project/ObjectFolderOrObject.h"
#include <memory>
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Log.h"
using namespace std;
namespace gd {
ObjectFolderOrObject ObjectFolderOrObject::badObjectFolderOrObject;
ObjectFolderOrObject::ObjectFolderOrObject()
: folderName("__NULL"), object(nullptr) {}
ObjectFolderOrObject::ObjectFolderOrObject(gd::String folderName_,
ObjectFolderOrObject* parent_)
: folderName(folderName_), parent(parent_), object(nullptr) {}
ObjectFolderOrObject::ObjectFolderOrObject(gd::Object* object_,
ObjectFolderOrObject* parent_)
: object(object_), parent(parent_) {}
ObjectFolderOrObject::~ObjectFolderOrObject() {}
bool ObjectFolderOrObject::HasObjectNamed(const gd::String& name) {
if (IsFolder()) {
return std::any_of(
children.begin(),
children.end(),
[&name](
std::unique_ptr<gd::ObjectFolderOrObject>& objectFolderOrObject) {
return objectFolderOrObject->HasObjectNamed(name);
});
}
if (!object) return false;
return object->GetName() == name;
}
ObjectFolderOrObject& ObjectFolderOrObject::GetObjectNamed(
const gd::String& name) {
if (object && object->GetName() == name) {
return *this;
}
if (IsFolder()) {
for (std::size_t j = 0; j < children.size(); j++) {
ObjectFolderOrObject& foundInChild = children[j]->GetObjectNamed(name);
if (&(foundInChild) != &badObjectFolderOrObject) {
return foundInChild;
}
}
}
return badObjectFolderOrObject;
}
void ObjectFolderOrObject::SetFolderName(const gd::String& name) {
if (!IsFolder()) return;
folderName = name;
}
ObjectFolderOrObject& ObjectFolderOrObject::GetChildAt(std::size_t index) {
if (index >= children.size()) return badObjectFolderOrObject;
return *children[index];
}
const ObjectFolderOrObject& ObjectFolderOrObject::GetChildAt(std::size_t index) const {
if (index >= children.size()) return badObjectFolderOrObject;
return *children[index];
}
ObjectFolderOrObject& ObjectFolderOrObject::GetObjectChild(
const gd::String& name) {
for (std::size_t j = 0; j < children.size(); j++) {
if (!children[j]->IsFolder()) {
if (children[j]->GetObject().GetName() == name) return *children[j];
};
}
return badObjectFolderOrObject;
}
void ObjectFolderOrObject::InsertObject(gd::Object* insertedObject,
std::size_t position) {
auto objectFolderOrObject =
gd::make_unique<ObjectFolderOrObject>(insertedObject, this);
if (position < children.size()) {
children.insert(children.begin() + position,
std::move(objectFolderOrObject));
} else {
children.push_back(std::move(objectFolderOrObject));
}
}
std::size_t ObjectFolderOrObject::GetChildPosition(
const ObjectFolderOrObject& child) const {
for (std::size_t j = 0; j < children.size(); j++) {
if (children[j].get() == &child) return j;
}
return gd::String::npos;
}
ObjectFolderOrObject& ObjectFolderOrObject::InsertNewFolder(
const gd::String& newFolderName, std::size_t position) {
auto newFolderPtr =
gd::make_unique<ObjectFolderOrObject>(newFolderName, this);
gd::ObjectFolderOrObject& newFolder = *(*(children.insert(
position < children.size() ? children.begin() + position : children.end(),
std::move(newFolderPtr))));
return newFolder;
};
void ObjectFolderOrObject::RemoveRecursivelyObjectNamed(
const gd::String& name) {
if (IsFolder()) {
children.erase(
std::remove_if(children.begin(),
children.end(),
[&name](std::unique_ptr<gd::ObjectFolderOrObject>&
objectFolderOrObject) {
return !objectFolderOrObject->IsFolder() &&
objectFolderOrObject->GetObject().GetName() ==
name;
}),
children.end());
for (auto& it : children) {
it->RemoveRecursivelyObjectNamed(name);
}
}
};
bool ObjectFolderOrObject::IsADescendantOf(
const ObjectFolderOrObject& otherObjectFolderOrObject) {
if (parent == nullptr) return false;
if (&(*parent) == &otherObjectFolderOrObject) return true;
return parent->IsADescendantOf(otherObjectFolderOrObject);
}
void ObjectFolderOrObject::MoveChild(std::size_t oldIndex,
std::size_t newIndex) {
if (!IsFolder()) return;
if (oldIndex >= children.size() || newIndex >= children.size()) return;
std::unique_ptr<gd::ObjectFolderOrObject> objectFolderOrObject =
std::move(children[oldIndex]);
children.erase(children.begin() + oldIndex);
children.insert(children.begin() + newIndex, std::move(objectFolderOrObject));
}
void ObjectFolderOrObject::RemoveFolderChild(
const ObjectFolderOrObject& childToRemove) {
if (!IsFolder() || !childToRemove.IsFolder() ||
childToRemove.GetChildrenCount() > 0) {
return;
}
std::vector<std::unique_ptr<gd::ObjectFolderOrObject>>::iterator it = find_if(
children.begin(),
children.end(),
[&childToRemove](std::unique_ptr<gd::ObjectFolderOrObject>& child) {
return child.get() == &childToRemove;
});
if (it == children.end()) return;
children.erase(it);
}
void ObjectFolderOrObject::MoveObjectFolderOrObjectToAnotherFolder(
gd::ObjectFolderOrObject& objectFolderOrObject,
gd::ObjectFolderOrObject& newParentFolder,
std::size_t newPosition) {
if (!newParentFolder.IsFolder()) return;
if (newParentFolder.IsADescendantOf(objectFolderOrObject)) return;
std::vector<std::unique_ptr<gd::ObjectFolderOrObject>>::iterator it =
find_if(children.begin(),
children.end(),
[&objectFolderOrObject](std::unique_ptr<gd::ObjectFolderOrObject>&
childObjectFolderOrObject) {
return childObjectFolderOrObject.get() == &objectFolderOrObject;
});
if (it == children.end()) return;
std::unique_ptr<gd::ObjectFolderOrObject> objectFolderOrObjectPtr =
std::move(*it);
children.erase(it);
objectFolderOrObjectPtr->parent = &newParentFolder;
newParentFolder.children.insert(
newPosition < newParentFolder.children.size()
? newParentFolder.children.begin() + newPosition
: newParentFolder.children.end(),
std::move(objectFolderOrObjectPtr));
}
void ObjectFolderOrObject::SerializeTo(SerializerElement& element) const {
if (IsFolder()) {
element.SetAttribute("folderName", GetFolderName());
if (children.size() > 0) {
SerializerElement& childrenElement = element.AddChild("children");
childrenElement.ConsiderAsArrayOf("objectFolderOrObject");
for (std::size_t j = 0; j < children.size(); j++) {
children[j]->SerializeTo(
childrenElement.AddChild("objectFolderOrObject"));
}
}
} else {
element.SetAttribute("objectName", GetObject().GetName());
}
}
void ObjectFolderOrObject::UnserializeFrom(
gd::Project& project,
const SerializerElement& element,
gd::ObjectsContainer& objectsContainer) {
children.clear();
gd::String potentialFolderName = element.GetStringAttribute("folderName", "");
if (!potentialFolderName.empty()) {
object = nullptr;
folderName = potentialFolderName;
if (element.HasChild("children")) {
const SerializerElement& childrenElements =
element.GetChild("children", 0);
childrenElements.ConsiderAsArrayOf("objectFolderOrObject");
for (std::size_t i = 0; i < childrenElements.GetChildrenCount(); ++i) {
std::unique_ptr<ObjectFolderOrObject> childObjectFolderOrObject =
make_unique<ObjectFolderOrObject>();
childObjectFolderOrObject->UnserializeFrom(
project, childrenElements.GetChild(i), objectsContainer);
childObjectFolderOrObject->parent = this;
children.push_back(std::move(childObjectFolderOrObject));
}
}
} else {
folderName = "";
gd::String objectName = element.GetStringAttribute("objectName");
if (objectsContainer.HasObjectNamed(objectName)) {
object = &objectsContainer.GetObject(objectName);
} else {
gd::LogError("Object with name " + objectName +
" not found in objects container.");
object = nullptr;
}
}
};
} // namespace gd

View File

@@ -0,0 +1,203 @@
/*
* GDevelop Core
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef GDCORE_OBJECTFOLDEROROBJECT_H
#define GDCORE_OBJECTFOLDEROROBJECT_H
#include <memory>
#include <vector>
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/String.h"
namespace gd {
class Project;
class Object;
class SerializerElement;
class ObjectsContainer;
} // namespace gd
namespace gd {
/**
* \brief Class representing a folder structure in order to organize objects
* in folders (to be used with an ObjectsContainer.)
*
* \see gd::ObjectsContainer
*/
class GD_CORE_API ObjectFolderOrObject {
public:
/**
* \brief Default constructor creating an empty instance. Useful for the null
* object pattern.
*/
ObjectFolderOrObject();
virtual ~ObjectFolderOrObject();
/**
* \brief Constructor for creating an instance representing a folder.
*/
ObjectFolderOrObject(gd::String folderName_,
ObjectFolderOrObject* parent_ = nullptr);
/**
* \brief Constructor for creating an instance representing an object.
*/
ObjectFolderOrObject(gd::Object* object_,
ObjectFolderOrObject* parent_ = nullptr);
/**
* \brief Returns the object behind the instance.
*/
gd::Object& GetObject() const { return *object; }
/**
* \brief Returns true if the instance represents a folder.
*/
bool IsFolder() const { return !folderName.empty(); }
/**
* \brief Returns the name of the folder.
*/
const gd::String& GetFolderName() const { return folderName; }
/**
* \brief Set the folder name. Does nothing if called on an instance not
* representing a folder.
*/
void SetFolderName(const gd::String& name);
/**
* \brief Returns true if the instance represents the object with the given
* name or if any of the children does (recursive search).
*/
bool HasObjectNamed(const gd::String& name);
/**
* \brief Returns the child instance holding the object with the given name
* (recursive search).
*/
ObjectFolderOrObject& GetObjectNamed(const gd::String& name);
/**
* \brief Returns the number of children. Returns 0 if the instance represents
* an object.
*/
std::size_t GetChildrenCount() const {
if (IsFolder()) return children.size();
return 0;
}
/**
* \brief Returns the child ObjectFolderOrObject at the given index.
*/
ObjectFolderOrObject& GetChildAt(std::size_t index);
/**
* \brief Returns the child ObjectFolderOrObject at the given index.
*/
const ObjectFolderOrObject& GetChildAt(std::size_t index) const;
/**
* \brief Returns the child ObjectFolderOrObject that represents the object
* with the given name. To use only if sure that the instance holds the object
* in its direct children (no recursive search).
*
* \note The equivalent method to get a folder by its name cannot be
* implemented because there is no unicity enforced on the folder name.
*/
ObjectFolderOrObject& GetObjectChild(const gd::String& name);
/**
* \brief Returns the parent of the instance. If the instance has no parent
* (root folder), the null object is returned.
*/
ObjectFolderOrObject& GetParent() {
if (parent == nullptr) {
return badObjectFolderOrObject;
}
return *parent;
};
/**
* \brief Returns true if the instance is a root folder (that's to say it
* has no parent).
*/
bool IsRootFolder() { return !object && !parent; }
/**
* \brief Moves a child from a position to a new one.
*/
void MoveChild(std::size_t oldIndex, std::size_t newIndex);
/**
* \brief Removes the given child from the instance's children. If the given
* child contains children of its own, does nothing.
*/
void RemoveFolderChild(const ObjectFolderOrObject& childToRemove);
/**
* \brief Removes the child representing the object with the given name from
* the instance children and recursively does it for every folder children.
*/
void RemoveRecursivelyObjectNamed(const gd::String& name);
/**
* \brief Inserts an instance representing the given object at the given
* position.
*/
void InsertObject(gd::Object* insertedObject,
std::size_t position = (size_t)-1);
/**
* \brief Inserts an instance representing a folder with the given name at the
* given position.
*/
ObjectFolderOrObject& InsertNewFolder(const gd::String& newFolderName,
std::size_t position);
/**
* \brief Returns true if the instance is a descendant of the given instance
* of ObjectFolderOrObject.
*/
bool IsADescendantOf(const ObjectFolderOrObject& otherObjectFolderOrObject);
/**
* \brief Returns the position of the given instance of ObjectFolderOrObject
* in the instance's children.
*/
std::size_t GetChildPosition(const ObjectFolderOrObject& child) const;
/**
* \brief Moves the given child ObjectFolderOrObject to the given folder at
* the given position.
*/
void MoveObjectFolderOrObjectToAnotherFolder(
gd::ObjectFolderOrObject& objectFolderOrObject,
gd::ObjectFolderOrObject& newParentFolder,
std::size_t newPosition);
/** \name Saving and loading
* Members functions related to saving and loading the objects of the class.
*/
///@{
/**
* \brief Serialize the ObjectFolderOrObject instance.
*/
void SerializeTo(SerializerElement& element) const;
/**
* \brief Unserialize the ObjectFolderOrObject instance.
*/
void UnserializeFrom(gd::Project& project,
const SerializerElement& element,
ObjectsContainer& objectsContainer);
///@}
private:
static gd::ObjectFolderOrObject badObjectFolderOrObject;
gd::ObjectFolderOrObject*
parent; // nullptr if root folder, points to the parent folder otherwise.
// Representing an object:
gd::Object* object; // nullptr if folderName is set.
// or representing a folder:
gd::String folderName; // Empty if object is set.
std::vector<std::unique_ptr<ObjectFolderOrObject>>
children; // Folder children.
};
} // namespace gd
#endif // GDCORE_OBJECTFOLDEROROBJECT_H

View File

@@ -9,12 +9,15 @@
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectFolderOrObject.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
ObjectsContainer::ObjectsContainer() {}
ObjectsContainer::ObjectsContainer() {
rootFolder = gd::make_unique<gd::ObjectFolderOrObject>("__ROOT");
}
ObjectsContainer::~ObjectsContainer() {}
@@ -24,6 +27,22 @@ void ObjectsContainer::SerializeObjectsTo(SerializerElement& element) const {
initialObjects[j]->SerializeTo(element.AddChild("object"));
}
}
void ObjectsContainer::SerializeFoldersTo(SerializerElement& element) const {
rootFolder->SerializeTo(element);
}
void ObjectsContainer::UnserializeFoldersFrom(
gd::Project& project, const SerializerElement& element) {
rootFolder->UnserializeFrom(project, element, *this);
}
void ObjectsContainer::AddMissingObjectsInRootFolder() {
for (std::size_t i = 0; i < initialObjects.size(); ++i) {
if (!rootFolder->HasObjectNamed(initialObjects[i]->GetName())) {
rootFolder->InsertObject(&(*initialObjects[i]));
}
}
}
void ObjectsContainer::UnserializeObjectsFrom(
gd::Project& project, const SerializerElement& element) {
@@ -48,17 +67,23 @@ void ObjectsContainer::UnserializeObjectsFrom(
bool ObjectsContainer::HasObjectNamed(const gd::String& name) const {
return (find_if(initialObjects.begin(),
initialObjects.end(),
[&](const std::unique_ptr<gd::Object>& object) { return object->GetName() == name; }) != initialObjects.end());
[&](const std::unique_ptr<gd::Object>& object) {
return object->GetName() == name;
}) != initialObjects.end());
}
gd::Object& ObjectsContainer::GetObject(const gd::String& name) {
return *(*find_if(initialObjects.begin(),
initialObjects.end(),
[&](const std::unique_ptr<gd::Object>& object) { return object->GetName() == name; }));
[&](const std::unique_ptr<gd::Object>& object) {
return object->GetName() == name;
}));
}
const gd::Object& ObjectsContainer::GetObject(const gd::String& name) const {
return *(*find_if(initialObjects.begin(),
initialObjects.end(),
[&](const std::unique_ptr<gd::Object>& object) { return object->GetName() == name; }));
[&](const std::unique_ptr<gd::Object>& object) {
return object->GetName() == name;
}));
}
gd::Object& ObjectsContainer::GetObject(std::size_t index) {
return *initialObjects[index];
@@ -84,6 +109,22 @@ gd::Object& ObjectsContainer::InsertNewObject(const gd::Project& project,
: initialObjects.end(),
project.CreateObject(objectType, name))));
rootFolder->InsertObject(&newlyCreatedObject);
return newlyCreatedObject;
}
gd::Object& ObjectsContainer::InsertNewObjectInFolder(
const gd::Project& project,
const gd::String& objectType,
const gd::String& name,
gd::ObjectFolderOrObject& objectFolderOrObject,
std::size_t position) {
gd::Object& newlyCreatedObject = *(*(initialObjects.insert(
initialObjects.end(), project.CreateObject(objectType, name))));
objectFolderOrObject.InsertObject(&newlyCreatedObject, position);
return newlyCreatedObject;
}
@@ -97,16 +138,6 @@ gd::Object& ObjectsContainer::InsertObject(const gd::Object& object,
return newlyCreatedObject;
}
void ObjectsContainer::SwapObjects(std::size_t firstObjectIndex,
std::size_t secondObjectIndex) {
if (firstObjectIndex >= initialObjects.size() ||
secondObjectIndex >= initialObjects.size())
return;
std::iter_swap(initialObjects.begin() + firstObjectIndex,
initialObjects.begin() + secondObjectIndex);
}
void ObjectsContainer::MoveObject(std::size_t oldIndex, std::size_t newIndex) {
if (oldIndex >= initialObjects.size() || newIndex >= initialObjects.size())
return;
@@ -120,30 +151,59 @@ void ObjectsContainer::RemoveObject(const gd::String& name) {
std::vector<std::unique_ptr<gd::Object>>::iterator objectIt =
find_if(initialObjects.begin(),
initialObjects.end(),
[&](const std::unique_ptr<gd::Object>& object) { return object->GetName() == name; });
[&](const std::unique_ptr<gd::Object>& object) {
return object->GetName() == name;
});
if (objectIt == initialObjects.end()) return;
rootFolder->RemoveRecursivelyObjectNamed(name);
initialObjects.erase(objectIt);
}
void ObjectsContainer::MoveObjectToAnotherContainer(
const gd::String& name,
void ObjectsContainer::MoveObjectFolderOrObjectToAnotherContainerInFolder(
gd::ObjectFolderOrObject& objectFolderOrObject,
gd::ObjectsContainer& newContainer,
gd::ObjectFolderOrObject& newParentFolder,
std::size_t newPosition) {
std::vector<std::unique_ptr<gd::Object>>::iterator objectIt =
find_if(initialObjects.begin(),
initialObjects.end(),
[&](const std::unique_ptr<gd::Object>& object) { return object->GetName() == name; });
if (objectFolderOrObject.IsFolder() || !newParentFolder.IsFolder()) return;
std::vector<std::unique_ptr<gd::Object>>::iterator objectIt = find_if(
initialObjects.begin(),
initialObjects.end(),
[&objectFolderOrObject](std::unique_ptr<gd::Object>& object) {
return object->GetName() == objectFolderOrObject.GetObject().GetName();
});
if (objectIt == initialObjects.end()) return;
std::unique_ptr<gd::Object> object = std::move(*objectIt);
initialObjects.erase(objectIt);
newContainer.initialObjects.insert(
newPosition < newContainer.initialObjects.size()
? newContainer.initialObjects.begin() + newPosition
: newContainer.initialObjects.end(),
std::move(object));
newContainer.initialObjects.push_back(std::move(object));
objectFolderOrObject.GetParent().MoveObjectFolderOrObjectToAnotherFolder(
objectFolderOrObject, newParentFolder, newPosition);
}
std::vector<const ObjectFolderOrObject*>
ObjectsContainer::GetAllObjectFolderOrObjects() const {
std::vector<const ObjectFolderOrObject*> results;
std::function<void(const ObjectFolderOrObject& folder)> addChildrenOfFolder =
[&](const ObjectFolderOrObject& folder) {
for (size_t i = 0; i < folder.GetChildrenCount(); ++i) {
const auto& child = folder.GetChildAt(i);
results.push_back(&child);
if (child.IsFolder()) {
addChildrenOfFolder(child);
}
}
};
addChildrenOfFolder(*rootFolder);
return results;
}
} // namespace gd

View File

@@ -9,11 +9,12 @@
#include <vector>
#include "GDCore/String.h"
#include "GDCore/Project/ObjectGroupsContainer.h"
#include "GDCore/Project/ObjectFolderOrObject.h"
namespace gd {
class Object;
class Project;
class SerializerElement;
}
} // namespace gd
#undef GetObject // Disable an annoying macro
namespace gd {
@@ -98,6 +99,19 @@ class GD_CORE_API ObjectsContainer {
const gd::String& objectType,
const gd::String& name,
std::size_t position);
/**
* \brief Add a new empty object of type \a objectType called \a name in the
* given folder at the specified position.<br>
*
* \note The object is created using the project's current platform.
* \return A reference to the object in the list.
*/
gd::Object& InsertNewObjectInFolder(
const gd::Project& project,
const gd::String& objectType,
const gd::String& name,
gd::ObjectFolderOrObject& objectFolderOrObject,
std::size_t position);
/**
* \brief Add a new object to the list
@@ -125,18 +139,18 @@ class GD_CORE_API ObjectsContainer {
void MoveObject(std::size_t oldIndex, std::size_t newIndex);
/**
* \brief Swap the position of the specified objects.
*/
void SwapObjects(std::size_t firstObjectIndex, std::size_t secondObjectIndex);
/**
* Move the specified object to another container, removing it from the current one
* and adding it to the new one at the specified position.
* Move the specified object to another container, removing it from the
* current one and adding it to the new one at the specified position in the
* given folder.
*
* \note This does not invalidate the references to the object (object is not moved in memory,
* as referenced by smart pointers internally).
* \note This does not invalidate the references to the object (object is not
* moved in memory, as referenced by smart pointers internally).
*/
void MoveObjectToAnotherContainer(const gd::String& name, gd::ObjectsContainer & newContainer, std::size_t newPosition);
void MoveObjectFolderOrObjectToAnotherContainerInFolder(
gd::ObjectFolderOrObject& objectFolderOrObject,
gd::ObjectsContainer& newContainer,
gd::ObjectFolderOrObject& newParentFolder,
std::size_t newPosition);
/**
* Provide a raw access to the vector containing the objects
@@ -153,20 +167,43 @@ class GD_CORE_API ObjectsContainer {
}
///@}
/**
* Returns a vector containing all object and folders in this container.
* Only use this for checking if you hold a valid `ObjectFolderOrObject` -
* don't use this for rendering or anything else.
*/
std::vector<const ObjectFolderOrObject*> GetAllObjectFolderOrObjects() const;
gd::ObjectFolderOrObject& GetRootFolder() {
return *rootFolder;
}
void AddMissingObjectsInRootFolder();
/** \name Saving and loading
* Members functions related to saving and loading the objects of the class.
*/
///@{
/**
* \brief Serialize instances container.
* \brief Serialize the objects container.
*/
void SerializeObjectsTo(SerializerElement& element) const;
/**
* \brief Unserialize the instances container.
* \brief Unserialize the objects container.
*/
void UnserializeObjectsFrom(gd::Project& project,
const SerializerElement& element);
/**
* \brief Serialize folder structure.
*/
void SerializeFoldersTo(SerializerElement& element) const;
/**
* \brief Unserialize folder structure.
*/
void UnserializeFoldersFrom(gd::Project& project,
const SerializerElement& element);
///@}
/** \name Objects groups management
@@ -190,6 +227,9 @@ class GD_CORE_API ObjectsContainer {
std::vector<std::unique_ptr<gd::Object> >
initialObjects; ///< Objects contained.
gd::ObjectGroupsContainer objectGroups;
private:
std::unique_ptr<gd::ObjectFolderOrObject> rootFolder;
};
} // namespace gd

View File

@@ -48,11 +48,6 @@ using namespace std;
namespace gd {
// By default, disallow unicode in identifiers, but this can be set to true
// by the IDE. In the future, this will be set to true by default, keeping backward compatibility.
// We keep it disabled by default to progressively ask users to test it in real projects.
bool Project::allowUsageOfUnicodeIdentifierNames = false;
Project::Project()
: name(_("Project")),
version("1.0.0"),
@@ -86,26 +81,24 @@ Project::~Project() {}
void Project::ResetProjectUuid() { projectUuid = UUID::MakeUuid4(); }
std::unique_ptr<gd::Object>
Project::CreateObject(const gd::String &objectType, const gd::String &name) const {
std::unique_ptr<gd::Object> object =
gd::make_unique<Object>(name, objectType, CreateObjectConfiguration(objectType));
std::unique_ptr<gd::Object> Project::CreateObject(
const gd::String& objectType, const gd::String& name) const {
std::unique_ptr<gd::Object> object = gd::make_unique<Object>(
name, objectType, CreateObjectConfiguration(objectType));
auto &platform = GetCurrentPlatform();
auto &project = *this;
auto addDefaultBehavior =
[&platform,
&project,
&object,
&objectType](const gd::String& behaviorType) {
auto &behaviorMetadata =
auto& platform = GetCurrentPlatform();
auto& project = *this;
auto addDefaultBehavior = [&platform, &project, &object, &objectType](
const gd::String& behaviorType) {
auto& behaviorMetadata =
gd::MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
if (MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
gd::LogWarning("Object: " + objectType + " has an unknown default behavior: " + behaviorType);
gd::LogWarning("Object: " + objectType +
" has an unknown default behavior: " + behaviorType);
return;
}
auto* behavior = object->AddNewBehavior(project, behaviorType,
behaviorMetadata.GetDefaultName());
auto* behavior = object->AddNewBehavior(
project, behaviorType, behaviorMetadata.GetDefaultName());
behavior->SetDefaultBehavior(true);
};
@@ -114,18 +107,17 @@ Project::CreateObject(const gd::String &objectType, const gd::String &name) cons
addDefaultBehavior("ResizableCapability::ResizableBehavior");
addDefaultBehavior("ScalableCapability::ScalableBehavior");
addDefaultBehavior("FlippableCapability::FlippableBehavior");
}
else {
auto &objectMetadata = gd::MetadataProvider::GetObjectMetadata(platform, objectType);
} else {
auto& objectMetadata =
gd::MetadataProvider::GetObjectMetadata(platform, objectType);
if (MetadataProvider::IsBadObjectMetadata(objectMetadata)) {
gd::LogWarning("Object: " + name + " has an unknown type: " + objectType);
}
for (auto &behaviorType : objectMetadata.GetDefaultBehaviors()) {
for (auto& behaviorType : objectMetadata.GetDefaultBehaviors()) {
addDefaultBehavior(behaviorType);
}
}
return std::move(object);
}
@@ -849,6 +841,11 @@ void Project::UnserializeFrom(const SerializerElement& element) {
resourcesManager.UnserializeFrom(
element.GetChild("resources", 0, "Resources"));
UnserializeObjectsFrom(*this, element.GetChild("objects", 0, "Objects"));
if (element.HasChild("objectsFolderStructure")) {
UnserializeFoldersFrom(*this, element.GetChild("objectsFolderStructure", 0));
}
AddMissingObjectsInRootFolder();
GetVariables().UnserializeFrom(element.GetChild("variables", 0, "Variables"));
scenes.clear();
@@ -1000,6 +997,7 @@ void Project::SerializeTo(SerializerElement& element) const {
resourcesManager.SerializeTo(element.AddChild("resources"));
SerializeObjectsTo(element.AddChild("objects"));
SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
GetVariables().SerializeTo(element.AddChild("variables"));
@@ -1038,28 +1036,18 @@ void Project::SerializeTo(SerializerElement& element) const {
externalSourceFilesElement.AddChild("sourceFile"));
}
void Project::AllowUsageOfUnicodeIdentifierNames(bool enable) {
allowUsageOfUnicodeIdentifierNames = enable;
}
bool Project::IsNameSafe(const gd::String& name) {
if (name.empty()) return false;
if (isdigit(name[0])) return false;
if (!allowUsageOfUnicodeIdentifierNames) {
gd::String legacyAllowedCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
return !(name.find_first_not_of(legacyAllowedCharacters) != gd::String::npos);
} else {
for (auto character : name) {
if (!GrammarTerminals::IsAllowedInIdentifier(character)) {
return false;
}
for (auto character : name) {
if (!GrammarTerminals::IsAllowedInIdentifier(character)) {
return false;
}
return true;
}
return true;
}
gd::String Project::GetSafeName(const gd::String& name) {
@@ -1069,18 +1057,13 @@ gd::String Project::GetSafeName(const gd::String& name) {
if (isdigit(name[0])) newName = "_" + newName;
gd::String legacyAllowedCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
for (size_t i = 0;i < newName.size();++i) {
// Note that iterating on the characters is not super efficient (O(n^2), which
// could be avoided with an iterator), but this function is not critical for performance
// (only used to generate a name when a user creates a new entity or rename one).
for (size_t i = 0; i < newName.size(); ++i) {
// Note that iterating on the characters is not super efficient (O(n^2),
// which could be avoided with an iterator), but this function is not
// critical for performance (only used to generate a name when a user
// creates a new entity or rename one).
auto character = newName[i];
bool isAllowed =
allowUsageOfUnicodeIdentifierNames
? GrammarTerminals::IsAllowedInIdentifier(character)
: legacyAllowedCharacters.find(character) != gd::String::npos;
bool isAllowed = GrammarTerminals::IsAllowedInIdentifier(character);
// Replace all unallowed letters by an underscore.
if (!isAllowed) {

View File

@@ -11,12 +11,12 @@
#include "GDCore/Project/ExtensionProperties.h"
#include "GDCore/Project/LoadingScreen.h"
#include "GDCore/Project/Watermark.h"
#include "GDCore/Project/ObjectGroupsContainer.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/PlatformSpecificAssets.h"
#include "GDCore/Project/ResourcesManager.h"
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/Project/Watermark.h"
#include "GDCore/String.h"
namespace gd {
class Platform;
@@ -82,7 +82,9 @@ class GD_CORE_API Project : public ObjectsContainer {
/**
* \brief Change the project description
*/
void SetDescription(const gd::String& description_) { description = description_; };
void SetDescription(const gd::String& description_) {
description = description_;
};
/**
* \brief Get the project description
@@ -124,7 +126,9 @@ class GD_CORE_API Project : public ObjectsContainer {
/**
* \brief Get the author usernames of the project.
*/
const std::vector<gd::String>& GetAuthorUsernames() const { return authorUsernames; };
const std::vector<gd::String>& GetAuthorUsernames() const {
return authorUsernames;
};
/**
* \brief Get the author usernames of the project, to modify them (non-const).
@@ -135,7 +139,9 @@ class GD_CORE_API Project : public ObjectsContainer {
* Define the project as playable with a keyboard.
* \param enable True to define the project as playable with a keyboard.
*/
void SetPlayableWithKeyboard(bool playable = true) { isPlayableWithKeyboard = playable; }
void SetPlayableWithKeyboard(bool playable = true) {
isPlayableWithKeyboard = playable;
}
/**
* Check if the project is defined as playable with a keyboard.
@@ -146,7 +152,9 @@ class GD_CORE_API Project : public ObjectsContainer {
* Define the project as playable with a gamepad.
* \param enable True to define the project as playable with a gamepad.
*/
void SetPlayableWithGamepad(bool playable = true) { isPlayableWithGamepad = playable; }
void SetPlayableWithGamepad(bool playable = true) {
isPlayableWithGamepad = playable;
}
/**
* Check if the project is defined as playable with a gamepad.
@@ -157,7 +165,9 @@ class GD_CORE_API Project : public ObjectsContainer {
* Define the project as playable on a mobile.
* \param enable True to define the project as playable on a mobile.
*/
void SetPlayableWithMobile(bool playable = true) { isPlayableWithMobile = playable; }
void SetPlayableWithMobile(bool playable = true) {
isPlayableWithMobile = playable;
}
/**
* Check if the project is defined as playable on a mobile.
@@ -391,17 +401,23 @@ class GD_CORE_API Project : public ObjectsContainer {
/**
* Set the antialiasing mode used by the game ("none" or "MSAA").
*/
void SetAntialiasingMode(const gd::String& antialiasingMode_) { antialiasingMode = antialiasingMode_; }
void SetAntialiasingMode(const gd::String& antialiasingMode_) {
antialiasingMode = antialiasingMode_;
}
/**
* Return true if antialising is enabled on mobiles.
*/
bool IsAntialisingEnabledOnMobile() const { return isAntialisingEnabledOnMobile; }
bool IsAntialisingEnabledOnMobile() const {
return isAntialisingEnabledOnMobile;
}
/**
* Set whether antialising is enabled on mobiles or not.
*/
void SetAntialisingEnabledOnMobile(bool enable) { isAntialisingEnabledOnMobile = enable; }
void SetAntialisingEnabledOnMobile(bool enable) {
isAntialisingEnabledOnMobile = enable;
}
/**
* \brief Return if the project should set 0 as Z-order for objects created
@@ -905,7 +921,8 @@ class GD_CORE_API Project : public ObjectsContainer {
/**
* \brief Return the events based object with a given type.
*/
const gd::EventsBasedObject& GetEventsBasedObject(const gd::String& type) const;
const gd::EventsBasedObject& GetEventsBasedObject(
const gd::String& type) const;
/**
* \brief Check if events based behavior with a given type exists.
@@ -920,7 +937,8 @@ class GD_CORE_API Project : public ObjectsContainer {
/**
* \brief Return the events based behavior with a given type.
*/
const gd::EventsBasedBehavior& GetEventsBasedBehavior(const gd::String& type) const;
const gd::EventsBasedBehavior& GetEventsBasedBehavior(
const gd::String& type) const;
///@}
@@ -969,20 +987,6 @@ class GD_CORE_API Project : public ObjectsContainer {
*/
///@{
/**
* Check if unicode names are allowed in identifier names.
* \see IsNameSafe
* \see GetSafeName
*/
static bool IsUsageOfUnicodeIdentifierNamesAllowed() { return allowUsageOfUnicodeIdentifierNames; };
/**
* Set if unicode names are allowed in identifier names.
* \see IsNameSafe
* \see GetSafeName
*/
static void AllowUsageOfUnicodeIdentifierNames(bool enable);
/**
* Return true if \a name is valid (can be used safely for an object,
* behavior, events function name, etc...).
@@ -990,8 +994,8 @@ class GD_CORE_API Project : public ObjectsContainer {
static bool IsNameSafe(const gd::String& name);
/**
* Return a name, based on the one passed in parameter, that can be safely used
* for an object, behavior, events function name, etc...
* Return a name, based on the one passed in parameter, that can be safely
* used for an object, behavior, events function name, etc...
*/
static gd::String GetSafeName(const gd::String& name);
///@}
@@ -1068,8 +1072,8 @@ 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 antialiasingMode;
bool isAntialisingEnabledOnMobile;
gd::String projectUuid; ///< UUID useful to identify the game in online
@@ -1095,19 +1099,18 @@ class GD_CORE_API Project : public ObjectsContainer {
externalSourceFiles; ///< List of external source files used.
gd::String author; ///< Game author name, for publishing purpose.
std::vector<gd::String>
authorIds; ///< Game author ids, from GDevelop users DB.
authorIds; ///< Game author ids, from GDevelop users DB.
std::vector<gd::String>
authorUsernames; ///< Game author usernames, from GDevelop users DB.
std::vector<gd::String>
categories; ///< Game categories
bool isPlayableWithKeyboard; ///< The project is playable with a keyboard.
bool isPlayableWithGamepad; ///< The project is playable with a gamepad.
bool isPlayableWithMobile; ///< The project is playable on a mobile.
gd::String packageName; ///< Game package name
gd::String templateSlug; ///< The slug of the template from which the game is
///< created.
gd::String orientation; ///< Lock game orientation (on mobile devices).
///< "default", "landscape" or "portrait".
authorUsernames; ///< Game author usernames, from GDevelop users DB.
std::vector<gd::String> categories; ///< Game categories
bool isPlayableWithKeyboard; ///< The project is playable with a keyboard.
bool isPlayableWithGamepad; ///< The project is playable with a gamepad.
bool isPlayableWithMobile; ///< The project is playable on a mobile.
gd::String packageName; ///< Game package name
gd::String templateSlug; ///< The slug of the template from which the game is
///< created.
gd::String orientation; ///< Lock game orientation (on mobile devices).
///< "default", "landscape" or "portrait".
bool
folderProject; ///< True if folder project, false if single file project.
gd::String
@@ -1128,8 +1131,6 @@ class GD_CORE_API Project : public ObjectsContainer {
///< time the project was saved.
mutable unsigned int gdBuildVersion; ///< The GD build version used the last
///< time the project was saved.
static bool allowUsageOfUnicodeIdentifierNames;
};
} // namespace gd

View File

@@ -221,6 +221,9 @@ namespace gdjs {
const animation = this._animations[animationIndex];
this._currentAnimationIndex = animationIndex;
this._renderer.playAnimation(animation.source, animation.loop);
if (this._animationPaused) {
this._renderer.pauseAnimation();
}
}
}
@@ -272,12 +275,12 @@ namespace gdjs {
pauseAnimation() {
this._animationPaused = true;
return this._renderer.pauseAnimation();
this._renderer.pauseAnimation();
}
resumeAnimation() {
this._animationPaused = false;
return this._renderer.resumeAnimation();
this._renderer.resumeAnimation();
}
getAnimationSpeedScale() {
@@ -288,6 +291,20 @@ namespace gdjs {
this._animationSpeedScale = ratio;
}
getAnimationElapsedTime(): float {
return this._renderer.getAnimationElapsedTime();
}
setAnimationElapsedTime(time: float): void {
this._renderer.setAnimationElapsedTime(time);
}
getAnimationDuration(): float {
return this._renderer.getAnimationDuration(
this._animations[this._currentAnimationIndex].source
);
}
getCenterX(): float {
const centerPoint = this._renderer.getCenterPoint();
return this.getWidth() * centerPoint[0];

View File

@@ -348,6 +348,24 @@ namespace gdjs {
// Make sure the first frame is displayed.
this._animationMixer.update(0);
}
getAnimationElapsedTime(): float {
return this._action ? this._action.time : 0;
}
setAnimationElapsedTime(time: float): void {
if (this._action) {
this._action.time = time;
}
}
getAnimationDuration(animationName: string): float {
const clip = THREE.AnimationClip.findByName(
this._originalModel.animations,
animationName
);
return clip ? clip.duration : 0;
}
}
export const Model3DRuntimeObjectRenderer = Model3DRuntimeObject3DRenderer;

View File

@@ -176,10 +176,12 @@ module.exports = {
'Extensions/BitmapText/bitmaptextruntimeobject-pixi-renderer.js'
)
.setCategoryFullName(_('Text'))
.addDefaultBehavior("TextContainerCapability::TextContainerBehavior")
.addDefaultBehavior('EffectCapability::EffectBehavior')
.addDefaultBehavior('OpacityCapability::OpacityBehavior')
.addDefaultBehavior('ScalableCapability::ScalableBehavior');
// Deprecated
object
.addExpressionAndConditionAndAction(
'string',
@@ -190,11 +192,23 @@ module.exports = {
'',
'res/conditions/text24_black.png'
)
.setHidden()
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.useStandardParameters('string', gd.ParameterOptions.makeNewOptions())
.setFunctionName('setText')
.setGetter('getText');
object
.addStrExpression(
'Text',
_('Text'),
_('Return the text.'),
'',
'res/conditions/text24_black.png'
)
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.setFunctionName('getText');
// Deprecated
object
.addExpressionAndConditionAndAction(
@@ -282,6 +296,7 @@ module.exports = {
.getCodeExtraInformation()
.setFunctionName('setTint');
// Deprecated
object
.addAction(
'SetBitmapFontAndTextureAtlasResourceName',
@@ -294,6 +309,7 @@ module.exports = {
'res/actions/font24.png',
'res/actions/font.png'
)
.setHidden()
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.addParameter(
'bitmapFontResource',
@@ -311,6 +327,34 @@ module.exports = {
.getCodeExtraInformation()
.setFunctionName('setBitmapFontAndTextureAtlasResourceName');
object
.addAction(
'SetBitmapFontAndTextureAtlasResourceName2',
_('Bitmap files resources'),
_('Change the Bitmap Font and/or the atlas image used by the object.'),
_(
'Set the bitmap font of _PARAM0_ to _PARAM1_ and the atlas to _PARAM2_'
),
'',
'res/actions/font24.png',
'res/actions/font.png'
)
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.addParameter(
'bitmapFontResource',
_('Bitmap font resource name'),
'',
false
)
.addParameter(
'imageResource',
_('Texture atlas resource name'),
'',
false
)
.getCodeExtraInformation()
.setFunctionName('setBitmapFontAndTextureAtlasResourceName');
object
.addExpressionAndCondition(
'string',

View File

@@ -37,7 +37,7 @@ namespace gdjs {
*/
export class BitmapTextRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.OpacityHandler, gdjs.Scalable {
implements gdjs.TextContainer, gdjs.OpacityHandler, gdjs.Scalable {
_opacity: float;
_text: string;
/** color in format [r, g, b], where each component is in the range [0, 255] */

View File

@@ -725,6 +725,44 @@ module.exports = {
.setType('number')
.setDescription(_('Padding for the visual effect area'));
const hslAdjustmentEffect = extension
.addEffect('HslAdjustment')
.setFullName(_('HSL Adjustment'))
.setDescription(
_(
'Adjust hue, saturation and lightness.'
)
)
.markAsOnlyWorkingFor2D()
.addIncludeFile('Extensions/Effects/pixi-filters/filter-hsl-adjustment.js')
.addIncludeFile('Extensions/Effects/hsl-adjustment-pixi-filter.js');
const hslAdjustmentProperties = hslAdjustmentEffect.getProperties();
hslAdjustmentProperties
.getOrCreate('hue')
.setValue('0')
.setLabel(_('Hue in degrees (between -180 and 180)'))
.setType('number');
hslAdjustmentProperties
.getOrCreate('saturation')
.setValue('0')
.setLabel(_('Saturation (between -1 and 1)'))
.setType('number');
hslAdjustmentProperties
.getOrCreate('lightness')
.setValue('0')
.setLabel(_('Lightness (between -1 and 1)'))
.setType('number');
hslAdjustmentProperties
.getOrCreate('colorize')
.setValue('false')
.setLabel(_('Colorize from the grayscale image'))
.setType('boolean');
hslAdjustmentProperties
.getOrCreate('alpha')
.setValue('1')
.setLabel(_('Alpha (between 0 and 1, 0 is transparent)'))
.setType('number');
const kawaseBlurEffect = extension
.addEffect('KawaseBlur')
.setFullName(_('Blur (Kawase, fast)'))
@@ -775,6 +813,38 @@ module.exports = {
.setLabel(_('Opacity (between 0 and 1)'))
.setType('number');
const motionBlurEffect = extension
.addEffect('MotionBlur')
.setFullName(_('Motion Blur'))
.setDescription(
_('Blur the rendered image to give a feeling of speed.')
)
.markAsOnlyWorkingFor2D()
.addIncludeFile('Extensions/Effects/pixi-filters/filter-motion-blur.js')
.addIncludeFile('Extensions/Effects/motion-blur-pixi-filter.js');
const motionBlurProperties = motionBlurEffect.getProperties();
motionBlurProperties
.getOrCreate('velocityX')
.setValue('0')
.setLabel(_('Velocity on X axis'))
.setType('number');
motionBlurProperties
.getOrCreate('velocityY')
.setValue('0')
.setLabel(_('Velocity on Y axis'))
.setType('number');
motionBlurProperties
.getOrCreate('kernelSize')
.setValue('5')
.setLabel(_('Kernel size (odd number between 3 and 25)'))
.setType('number')
.setDescription(_('Quality of the blur.'));
motionBlurProperties
.getOrCreate('offset')
.setValue('0')
.setLabel(_('Offset'))
.setType('number');
const nightEffect = extension
.addEffect('Night')
.setFullName(_('Dark Night'))
@@ -1089,6 +1159,59 @@ module.exports = {
.setLabel(_('Opacity (between 0 and 1)'))
.setType('number');
const shockwaveEffect = extension
.addEffect('Shockwave')
.setFullName(_('Shockwave'))
.setDescription(
_('Deform the image the way a drop deforms a water surface.')
)
.markAsOnlyWorkingFor2D()
.addIncludeFile('Extensions/Effects/pixi-filters/filter-shockwave.js')
.addIncludeFile('Extensions/Effects/shockwave-pixi-filter.js');
const shockwaveEffectProperties = shockwaveEffect.getProperties();
shockwaveEffectProperties
.getOrCreate('time')
.setValue('0')
.setLabel(_('Elapsed time'))
.setType('number')
.setDescription('It can be set back to 0 to play the shockwave animation again.');
shockwaveEffectProperties
.getOrCreate('speed')
.setValue('500')
.setLabel(_('Spreading speed (in pixels per second)'))
.setType('number');
shockwaveEffectProperties
.getOrCreate('amplitude')
.setValue('50')
.setLabel(_('Amplitude'))
.setType('number');
shockwaveEffectProperties
.getOrCreate('wavelength')
.setValue('200')
.setLabel(_('Wavelength'))
.setType('number');
shockwaveEffectProperties
.getOrCreate('brightness')
.setValue('1')
.setLabel(_('Brightness'))
.setType('number');
shockwaveEffectProperties
.getOrCreate('radius')
.setValue('0')
.setLabel(_('Maximum radius (0 for infinity)'))
.setType('number');
shockwaveEffectProperties
.getOrCreate('centerX')
.setValue('0.5')
.setLabel(_('Center on X axis'))
.setType('number');
shockwaveEffectProperties
.getOrCreate('centerY')
.setValue('0.5')
.setLabel(_('Center on Y axis'))
.setType('number')
.setDescription('(0,0) is the top-left and (1,1) is the bottom right.');
const tiltShiftEffect = extension
.addEffect('TiltShift')
.setFullName(_('Tilt shift'))

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Adjustment',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const adjustmentFilter = new PIXI.filters.AdjustmentFilter();
return adjustmentFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
if (parameterName === 'gamma') {
adjustmentFilter.gamma = value;
@@ -27,8 +31,16 @@ namespace gdjs {
adjustmentFilter.alpha = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'AdvancedBloom',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const advancedBloomFilter = new PIXI.filters.AdvancedBloomFilter();
return advancedBloomFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
if (parameterName === 'threshold') {
advancedBloomFilter.threshold = value;
@@ -23,8 +27,16 @@ namespace gdjs {
advancedBloomFilter.padding = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,19 +2,31 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Ascii',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const asciiFilter = new PIXI.filters.AsciiFilter();
return asciiFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
if (parameterName === 'size') {
asciiFilter.size = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Bevel',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const bevelFilter = new PIXI.filters.BevelFilter();
return bevelFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
if (parameterName === 'rotation') {
bevelFilter.rotation = value;
@@ -22,7 +26,11 @@ namespace gdjs {
bevelFilter.shadowAlpha = value;
}
}
updateStringParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
if (parameterName === 'lightColor') {
bevelFilter.lightColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
@@ -35,7 +43,11 @@ namespace gdjs {
);
}
}
updateBooleanParameter(filter, parameterName, value) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,21 +2,33 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'BlackAndWhite',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const colorMatrix = new PIXI.ColorMatrixFilter();
colorMatrix.blackAndWhite(false);
return colorMatrix;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const colorMatrix = (filter as unknown) as PIXI.ColorMatrixFilter;
if (parameterName !== 'opacity') {
return;
}
colorMatrix.alpha = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'BlendingMode',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const blendingModeFilter = new PIXI.AlphaFilter();
return blendingModeFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const blendingModeFilter = (filter as unknown) as PIXI.AlphaFilter;
if (parameterName === 'alpha') {
blendingModeFilter.alpha = value;
@@ -15,8 +19,16 @@ namespace gdjs {
blendingModeFilter.blendMode = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Blur',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const blur = new PIXI.BlurFilter();
return blur;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (
parameterName !== 'blur' &&
parameterName !== 'quality' &&
@@ -21,8 +25,16 @@ namespace gdjs {
}
filter[parameterName] = value;
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,13 +2,17 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Brightness',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const brightness = new PIXI.ColorMatrixFilter();
brightness.brightness(1, false);
return brightness;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter;
if (parameterName !== 'brightness') {
return;
@@ -18,8 +22,16 @@ namespace gdjs {
false
);
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'BulgePinch',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const bulgePinchFilter = new PIXI.filters.BulgePinchFilter();
return bulgePinchFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
if (parameterName === 'centerX') {
bulgePinchFilter.center[0] = value;
@@ -23,8 +27,16 @@ namespace gdjs {
);
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,7 +2,7 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'ColorMap',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const colorMapTexture = target
.getRuntimeScene()
.getGame()
@@ -19,8 +19,12 @@ namespace gdjs {
);
return colorMapFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
if (parameterName === 'mix') {
colorMapFilter.mix = gdjs.PixiFiltersTools.clampValue(
@@ -30,8 +34,16 @@ namespace gdjs {
);
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
if (parameterName === 'nearest') {
colorMapFilter.nearest = value;

View File

@@ -2,18 +2,26 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'ColorReplace',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const colorReplaceFilter = new PIXI.filters.ColorReplaceFilter();
return colorReplaceFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
if (parameterName === 'epsilon') {
colorReplaceFilter.epsilon = value;
}
}
updateStringParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
if (parameterName === 'originalColor') {
colorReplaceFilter.originalColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
@@ -25,7 +33,11 @@ namespace gdjs {
);
}
}
updateBooleanParameter(filter, parameterName, value) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -9,7 +9,7 @@ namespace gdjs {
crtFilter._animationTimer = 0;
return crtFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
if (filter.animationSpeed !== 0) {
// Multiply by 10 so that the default value is a sensible speed
filter.time +=
@@ -23,7 +23,11 @@ namespace gdjs {
}
}
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName === 'lineWidth') {
filter.lineWidth = value;
} else if (parameterName === 'lineContrast') {
@@ -48,8 +52,16 @@ namespace gdjs {
filter.padding = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
if (parameterName === 'verticalLine') {
filter.verticalLine = value;
}

View File

@@ -2,7 +2,7 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Displacement',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const displacementMapTexture = target
.getRuntimeScene()
.getGame()
@@ -15,8 +15,12 @@ namespace gdjs {
);
return displacementFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const displacementFilter = (filter as unknown) as PIXI.DisplacementFilter;
if (parameterName === 'scaleX') {
displacementFilter.scale.x = value;
@@ -25,8 +29,16 @@ namespace gdjs {
displacementFilter.scale.y = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Dot',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const dotFilter = new PIXI.filters.DotFilter();
return dotFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
if (parameterName === 'scale') {
dotFilter.scale = value;
@@ -15,8 +19,16 @@ namespace gdjs {
dotFilter.angle = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'DropShadow',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const dropShadowFilter = new PIXI.filters.DropShadowFilter();
return dropShadowFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
if (parameterName === 'blur') {
dropShadowFilter.blur = value;
@@ -23,7 +27,11 @@ namespace gdjs {
dropShadowFilter.padding = value;
}
}
updateStringParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
if (parameterName === 'color') {
dropShadowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
@@ -31,7 +39,11 @@ namespace gdjs {
);
}
}
updateBooleanParameter(filter, parameterName, value) {
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
if (parameterName === 'shadowOnly') {
dropShadowFilter.shadowOnly = value;

View File

@@ -9,7 +9,7 @@ namespace gdjs {
glitchFilter._animationTimer = 0;
return glitchFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
if (filter.animationFrequency !== 0) {
filter._animationTimer += target.getElapsedTime() / 1000;
if (filter._animationTimer >= 1 / filter.animationFrequency) {
@@ -18,7 +18,11 @@ namespace gdjs {
}
}
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName === 'slices') {
filter.slices = value;
} else if (parameterName === 'offset') {
@@ -47,8 +51,16 @@ namespace gdjs {
filter.animationFrequency = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
if (parameterName === 'average') {
filter.average = value;
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Glow',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const glowFilter = new PIXI.filters.GlowFilter();
return glowFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
if (parameterName === 'innerStrength') {
glowFilter.innerStrength = value;
@@ -18,13 +22,21 @@ namespace gdjs {
glowFilter.distance = value;
}
}
updateStringParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
if (parameterName === 'color') {
glowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}
}
updateBooleanParameter(filter, parameterName, value) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -8,13 +8,17 @@ namespace gdjs {
const godrayFilter = new PIXI.filters.GodrayFilter();
return godrayFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
if (filter.animationSpeed !== 0) {
filter.time +=
(target.getElapsedTime() / 1000) * filter.animationSpeed;
}
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName === 'lacunarity') {
filter.lacunarity = value;
} else if (parameterName === 'angle') {
@@ -33,8 +37,16 @@ namespace gdjs {
filter.padding = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
if (parameterName === 'parallel') {
filter.parallel = value;
}

View File

@@ -0,0 +1,43 @@
namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'HslAdjustment',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target: EffectsTarget, effectData) {
const hslAdjustmentFilter = new PIXI.filters.HslAdjustmentFilter();
return hslAdjustmentFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const hslAdjustmentFilter = filter as PIXI.filters.HslAdjustmentFilter;
if (parameterName === 'hue') {
hslAdjustmentFilter.hue = value;
} else if (parameterName === 'saturation') {
hslAdjustmentFilter.saturation = value;
} else if (parameterName === 'lightness') {
hslAdjustmentFilter.lightness = value;
} else if (parameterName === 'alpha') {
hslAdjustmentFilter.alpha = value;
}
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
const hslAdjustmentFilter = filter as PIXI.filters.HslAdjustmentFilter;
if (parameterName === 'colorize') {
hslAdjustmentFilter.colorize = value;
}
}
})()
);
}

View File

@@ -2,27 +2,37 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'KawaseBlur',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const kawaseBlurFilter = new PIXI.filters.KawaseBlurFilter();
return kawaseBlurFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const kawaseBlurFilter = (filter as unknown) as PIXI.filters.KawaseBlurFilter;
if (parameterName === 'pixelizeX') {
// @ts-ignore: fix these wrong parameters
kawaseBlurFilter.pixelizeX = value;
kawaseBlurFilter.pixelSize[0] = value;
} else if (parameterName === 'pixelizeY') {
// @ts-ignore: fix these wrong parameters
kawaseBlurFilter.pixelizeY = value;
kawaseBlurFilter.pixelSize[1] = value;
} else if (parameterName === 'blur') {
kawaseBlurFilter.blur = value;
} else if (parameterName === 'quality') {
kawaseBlurFilter.quality = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -24,19 +24,31 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'LightNight',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const filter = new gdjs.LightNightPixiFilter();
return filter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName !== 'opacity') {
return;
}
filter.uniforms.opacity = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -0,0 +1,40 @@
namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'MotionBlur',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target: EffectsTarget, effectData) {
const motionBlurFilter = new PIXI.filters.MotionBlurFilter([0, 0]);
return motionBlurFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const motionBlurFilter = filter as PIXI.filters.MotionBlurFilter;
if (parameterName === 'velocityX') {
// @ts-ignore Using the private member avoids to instantiate Arrays.
motionBlurFilter._velocity.x = value;
} else if (parameterName === 'velocityY') {
// @ts-ignore Using the private member avoids to instantiate Arrays.
motionBlurFilter._velocity.y = value;
} else if (parameterName === 'kernelSize') {
motionBlurFilter.kernelSize = value;
} else if (parameterName === 'offset') {
motionBlurFilter.offset = value;
}
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -28,12 +28,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Night',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const filter = new gdjs.NightPixiFilter();
return filter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName !== 'intensity' && parameterName !== 'opacity') {
return;
}
@@ -43,8 +47,16 @@ namespace gdjs {
1
);
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,20 +2,32 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Noise',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const noiseFilter = new PIXI.NoiseFilter();
return noiseFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const noiseFilter = (filter as unknown) as PIXI.NoiseFilter;
if (parameterName !== 'noise') {
return;
}
noiseFilter.noise = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -9,7 +9,7 @@ namespace gdjs {
oldFilmFilter._animationTimer = 0;
return oldFilmFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
if (filter.animationFrequency !== 0) {
filter._animationTimer += target.getElapsedTime() / 1000;
if (filter._animationTimer >= 1 / filter.animationFrequency) {
@@ -18,7 +18,11 @@ namespace gdjs {
}
}
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName === 'sepia') {
filter.sepia = value;
} else if (parameterName === 'noise') {
@@ -41,8 +45,16 @@ namespace gdjs {
filter.animationFrequency = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Outline',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const outlineFilter = new PIXI.filters.OutlineFilter();
return outlineFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const outlineFilter = (filter as unknown) as PIXI.filters.OutlineFilter;
if (parameterName === 'thickness') {
outlineFilter.thickness = value;
@@ -15,7 +19,11 @@ namespace gdjs {
outlineFilter.padding = value;
}
}
updateStringParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const outlineFilter = (filter as unknown) as PIXI.filters.OutlineFilter;
if (parameterName === 'color') {
outlineFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
@@ -23,7 +31,11 @@ namespace gdjs {
);
}
}
updateBooleanParameter(filter, parameterName, value) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,21 +2,33 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Pixelate',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const pixelateFilter = new PIXI.filters.PixelateFilter(
effectData.doubleParameters.size
);
return pixelateFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const pixelateFilter = (filter as unknown) as PIXI.filters.PixelateFilter;
if (parameterName === 'size') {
pixelateFilter.size = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -1,3 +1,4 @@
// This filter is probably made useless by advanced-bloom.
/*!
* @pixi/filter-bloom - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,5 @@
// TODO This filter can be interesting to make a gradient shadow over sprites.
// It can work with only 2 colors but maybe it would be better to wait that property list are handled.
/*!
* @pixi/filter-color-gradient - v5.2.0
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,4 @@
// It doesn't seem very useful.
/*!
* @pixi/filter-color-overlay - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,4 @@
// It's probably too complicated to use.
/*!
* @pixi/filter-convolution - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,4 @@
// This filter is maybe too much specific.
/*!
* @pixi/filter-cross-hatch - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,4 @@
// It probably needs to be blend to be useful.
/*!
* @pixi/filter-emboss - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,4 @@
// There is already a black-and-white effect that has more features.
/*!
* @pixi/filter-grayscale - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,4 @@
// This filter doesn't seem useful and need property list.
/*!
* @pixi/filter-multi-color-replace - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -1,3 +1,4 @@
// This filter is probably not very useful.
/*!
* @pixi/filter-simple-lightmap - v5.1.1
* Compiled Thu, 31 Aug 2023 09:18:38 UTC

View File

@@ -0,0 +1,63 @@
declare namespace PIXI.filters {
export interface HslAdjustmentFilterOptions {
hue: number;
saturation: number;
lightness: number;
colorize: boolean;
alpha: number;
}
/**
* @class
* @extends PIXI.Filter
* @see {@link https://www.npmjs.com/package/@pixi/filter-hsl-adjustment|@pixi/filter-hsl-adjustment}
* @see {@link https://www.npmjs.com/package/pixi-filters|pixi-filters}
*/
export class HslAdjustmentFilter extends PIXI.Filter {
private _hue;
/** Default values for options. */
static readonly defaults: HslAdjustmentFilterOptions;
/**
* @param options - The optional parameters of the filter.
* @param {number} [options.hue=0] - The amount of hue in degrees (-180 to 180)
* @param {number} [options.saturation=0] - The amount of color saturation (-1 to 1)
* @param {number} [options.lightness=0] - The amount of lightness (-1 to 1)
* @param {boolean} [options.colorize=false] - Whether to colorize the image
* @param {number} [options.alpha=1] - The amount of alpha (0 to 1)
*/
constructor(options?: Partial<HslAdjustmentFilterOptions>);
/**
* Hue (-180 to 180)
* @default 0
*/
get hue(): number;
set hue(value: number);
/**
* Alpha (0-1)
* @default 1
*/
get alpha(): number;
set alpha(value: number);
/**
* Colorize (render as a single color)
* @default false
*/
get colorize(): boolean;
set colorize(value: boolean);
/**
* Lightness (-1 to 1)
* @default 0
*/
get lightness(): number;
set lightness(value: number);
/**
* Saturation (-1 to 1)
* @default 0
*/
get saturation(): number;
set saturation(value: number);
}
}
declare module '@pixi/filter-hsl-adjustment' {
export import HslAdjustmentFilter = PIXI.filters.HslAdjustmentFilter;
export import HslAdjustmentFilterOptions = PIXI.filters.HslAdjustmentFilterOptions;
}

View File

@@ -1,20 +1,84 @@
declare namespace PIXI.filters {
export type PointLike = PIXI.Point | number[];
interface ShockwaveFilterOptions {
amplitude: number;
wavelength: number;
speed: number;
brightness: number;
radius: number;
}
/**
* The ShockwaveFilter class lets you apply a shockwave effect.<br>
*
* @class
* @extends PIXI.Filter
* @see {@link https://www.npmjs.com/package/@pixi/filter-shockwave|@pixi/filter-shockwave}
* @see {@link https://www.npmjs.com/package/pixi-filters|pixi-filters}
*/
export class ShockwaveFilter extends PIXI.Filter {
/** Default constructor options. */
static readonly defaults: ShockwaveFilterOptions;
/**
* Sets the elapsed time of the shockwave.
* It could control the current size of shockwave.
*/
time: number;
/**
* @param {PIXI.Point|number[]} [center=[0.5, 0.5]] - See `center` property.
* @param {object} [options] - The optional parameters of shockwave filter.
* @param {number} [options.amplitude=0.5] - See `amplitude`` property.
* @param {number} [options.wavelength=1.0] - See `wavelength` property.
* @param {number} [options.speed=500.0] - See `speed` property.
* @param {number} [options.brightness=8] - See `brightness` property.
* @param {number} [options.radius=4] - See `radius` property.
* @param {number} [time=0] - See `time` property.
*/
constructor(
center?: PIXI.Point | number[],
options?: ShockwaveFilterOptions,
center?: PointLike,
options?: Partial<ShockwaveFilterOptions>,
time?: number
);
center: PIXI.Point | number[];
options: ShockwaveFilterOptions;
time: number;
}
export interface ShockwaveFilterOptions {
amplitude?: number;
wavelength?: number;
brightness?: number;
speed?: number;
radius?: number;
apply(
filterManager: PIXI.FilterSystem,
input: PIXI.RenderTexture,
output: PIXI.RenderTexture,
clear: PIXI.CLEAR_MODES
): void;
/**
* Sets the center of the shockwave in normalized screen coords. That is
* (0,0) is the top-left and (1,1) is the bottom right.
*
* @member {PIXI.Point|number[]}
*/
get center(): PointLike;
set center(value: PointLike);
/**
* The amplitude of the shockwave.
*/
get amplitude(): number;
set amplitude(value: number);
/**
* The wavelength of the shockwave.
*/
get wavelength(): number;
set wavelength(value: number);
/**
* The brightness of the shockwave.
*/
get brightness(): number;
set brightness(value: number);
/**
* The speed about the shockwave ripples out.
* The unit is `pixel/second`
*/
get speed(): number;
set speed(value: number);
/**
* The maximum radius of shockwave.
* `< 0.0` means it's infinity.
*/
get radius(): number;
set radius(value: number);
}
}

View File

@@ -2,11 +2,11 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'RadialBlur',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const radialBlurFilter = new PIXI.filters.RadialBlurFilter();
return radialBlurFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const radialBlurFilter = (filter as unknown) as PIXI.filters.RadialBlurFilter;
radialBlurFilter.center[0] = Math.round(
// @ts-ignore - extra properties are stored on the filter.
@@ -17,7 +17,11 @@ namespace gdjs {
radialBlurFilter._centerY * target.getHeight()
);
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const radialBlurFilter = (filter as unknown) as PIXI.filters.RadialBlurFilter;
if (parameterName === 'radius') {
radialBlurFilter.radius = value < 0 ? -1 : value;
@@ -39,8 +43,16 @@ namespace gdjs {
radialBlurFilter.padding = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -25,13 +25,17 @@ namespace gdjs {
);
return reflectionFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
if (filter.animationSpeed !== 0) {
filter.time +=
(target.getElapsedTime() / 1000) * filter.animationSpeed;
}
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName === 'boundary') {
filter.boundary = value;
}
@@ -57,8 +61,16 @@ namespace gdjs {
filter.animationSpeed = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
if (parameterName === 'mirror') {
filter.mirror = value;
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'RGBSplit',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const rgbSplitFilter = new PIXI.filters.RGBSplitFilter();
return rgbSplitFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const rgbSplitFilter = (filter as unknown) as PIXI.filters.RGBSplitFilter;
if (parameterName === 'redX') {
rgbSplitFilter.red.x = value;
@@ -23,8 +27,16 @@ namespace gdjs {
rgbSplitFilter.blue.y = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,21 +2,33 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Sepia',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const colorMatrixFilter = new PIXI.ColorMatrixFilter();
colorMatrixFilter.sepia(false);
return colorMatrixFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const colorMatrixFilter = (filter as unknown) as PIXI.ColorMatrixFilter;
if (parameterName !== 'opacity') {
return;
}
colorMatrixFilter.alpha = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -0,0 +1,61 @@
namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Shockwave',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target: EffectsTarget, effectData) {
const shockwaveFilter = new PIXI.filters.ShockwaveFilter([0.5, 0.5]);
return shockwaveFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const shockwaveFilter = (filter as unknown) as PIXI.filters.ShockwaveFilter;
if (shockwaveFilter.speed !== 0) {
shockwaveFilter.time += target.getElapsedTime() / 1000;
}
shockwaveFilter.center[0] = Math.round(
// @ts-ignore - extra properties are stored on the filter.
shockwaveFilter._centerX * target.getWidth()
);
shockwaveFilter.center[1] = Math.round(
// @ts-ignore - extra properties are stored on the filter.
shockwaveFilter._centerY * target.getHeight()
);
}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const shockwaveFilter = filter as PIXI.filters.ShockwaveFilter;
if (parameterName === 'centerX') {
// @ts-ignore - extra properties are stored on the filter.
shockwaveFilter._centerX = value;
} else if (parameterName === 'centerY') {
// @ts-ignore - extra properties are stored on the filter.
shockwaveFilter._centerY = value;
} else if (parameterName === 'time') {
shockwaveFilter.time = value;
} else if (parameterName === 'speed') {
shockwaveFilter.speed = value;
} else if (parameterName === 'amplitude') {
shockwaveFilter.amplitude = value;
} else if (parameterName === 'wavelength') {
shockwaveFilter.wavelength = value;
} else if (parameterName === 'brightness') {
shockwaveFilter.brightness = value;
} else if (parameterName === 'radius') {
shockwaveFilter.radius = value;
}
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,16 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'TiltShift',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const tiltShiftFilter = new PIXI.filters.TiltShiftFilter();
return tiltShiftFilter;
}
updatePreRender(filter, target) {}
updateDoubleParameter(filter, parameterName, value) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {}
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const tiltShiftFilter = (filter as unknown) as PIXI.filters.TiltShiftFilter;
if (parameterName === 'blur') {
tiltShiftFilter.blur = value;
@@ -15,8 +19,16 @@ namespace gdjs {
tiltShiftFilter.gradientBlur = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,12 +2,12 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'Twist',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const twistFilter = new PIXI.filters.TwistFilter();
twistFilter.offset = new PIXI.Point(0, 0);
return twistFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const twistFilter = (filter as unknown) as PIXI.filters.TwistFilter;
twistFilter.offset.x = Math.round(
// @ts-ignore - extra properties are stored on the filter.
@@ -18,7 +18,11 @@ namespace gdjs {
twistFilter._offsetY * target.getHeight()
);
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const twistFilter = (filter as unknown) as PIXI.filters.TwistFilter;
if (parameterName === 'radius') {
twistFilter.radius = value;
@@ -34,8 +38,16 @@ namespace gdjs {
twistFilter._offsetY = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -2,11 +2,11 @@ namespace gdjs {
gdjs.PixiFiltersTools.registerFilterCreator(
'ZoomBlur',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(target, effectData) {
makePIXIFilter(target: EffectsTarget, effectData) {
const zoomBlurFilter = new PIXI.filters.ZoomBlurFilter();
return zoomBlurFilter;
}
updatePreRender(filter, target) {
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const zoomBlurFilter = (filter as unknown) as PIXI.filters.ZoomBlurFilter;
zoomBlurFilter.center[0] = Math.round(
// @ts-ignore - extra properties are stored on the filter.
@@ -17,7 +17,11 @@ namespace gdjs {
zoomBlurFilter._centerY * target.getHeight()
);
}
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
const zoomBlurFilter = (filter as unknown) as PIXI.filters.ZoomBlurFilter;
if (parameterName === 'centerX') {
// @ts-ignore - extra properties are stored on the filter.
@@ -37,8 +41,16 @@ namespace gdjs {
zoomBlurFilter.padding = value;
}
}
updateStringParameter(filter, parameterName, value) {}
updateBooleanParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -66,7 +66,11 @@ namespace gdjs {
// You can update the uniforms or other state of the filter.
}
// Function that will be called to update a (number) parameter of the PIXI filter with a new value
updateDoubleParameter(filter, parameterName, value) {
updateDoubleParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
) {
if (parameterName === 'opacity') {
filter.uniforms.opacity = gdjs.PixiFiltersTools.clampValue(
value,
@@ -76,9 +80,17 @@ namespace gdjs {
}
}
// Function that will be called to update a (string) parameter of the PIXI filter with a new value
updateStringParameter(filter, parameterName, value) {}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
// Function that will be called to update a (boolean) parameter of the PIXI filter with a new value
updateBooleanParameter(filter, parameterName, value) {}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {}
})()
);
}

View File

@@ -26,6 +26,7 @@ export type ObjectsRenderingService = {
requireModule: (dirname: string, moduleName: string) => any,
getThumbnail: (project: gdProject, objectConfiguration: gdObjectConfiguration) => string,
rgbOrHexToHexNumber: (value: string) => number,
registerClearCache: (clearCache: any => void) => void,
};
export type ObjectsEditorService = {
registerEditorConfiguration: (objectType: string, editorConfiguration: any) => void,

View File

@@ -95,6 +95,10 @@ namespace gdjs {
// in Pixi will create a flicker when cacheAsBitmap is set to true.
// (see https://github.com/pixijs/pixijs/issues/4610)
this._wrapperContainer.alpha = this._object.opacity / 255;
// When the opacity is updated, the cache must be invalidated, otherwise
// there is a risk of the panel sprite has been cached previously with a
// different opacity (and cannot be updated anymore).
this._spritesContainer.cacheAsBitmap = false;
}
updateAngle(): void {

View File

@@ -119,11 +119,14 @@ namespace gdjs {
},
minStart: objectData.emitterForceMin,
maxStart: objectData.emitterForceMax,
// See _updateRotateFlagFromSpeed
rotate:
(objectData.particleGravityX !== 0 ||
objectData.particleGravityY !== 0) &&
objectData.particleAngle1 === 0 &&
objectData.particleAngle2 === 0,
objectData.particleAngle2 === 0 &&
(objectData.particleGravityX !== 0 ||
objectData.particleGravityY !== 0 ||
objectData.emitterForceMin < 0 ||
objectData.emitterForceMax < 0),
},
},
{
@@ -277,7 +280,7 @@ namespace gdjs {
const behavior: any = this.emitter.getBehavior('moveAcceleration');
behavior.accel.x = x;
behavior.accel.y = y;
this._updateRotateFromSpeedFlag();
this._updateRotateFlagFromSpeed();
}
/**
@@ -285,15 +288,21 @@ namespace gdjs {
* according to the speed direction. This is overriding the particle
* rotation calculated by from `rotation`.
*/
private _updateRotateFromSpeedFlag() {
private _updateRotateFlagFromSpeed() {
const rotation: any = this.emitter.getBehavior('rotation');
const moveAcceleration: any = this.emitter.getBehavior(
'moveAcceleration'
);
moveAcceleration.rotate =
(moveAcceleration.accel.x !== 0 || moveAcceleration.accel.y !== 0) &&
rotation.minSpeed === 0 &&
rotation.maxSpeed === 0;
rotation.maxSpeed === 0 &&
// This part is to avoid to do `atan` every frame when the object
// direction doesn't change.
(moveAcceleration.accel.x !== 0 ||
moveAcceleration.accel.y !== 0 ||
// Negative speeds need a 180° rotation.
moveAcceleration.minStart < 0 ||
moveAcceleration.maxStart < 0);
}
setColor(
@@ -334,7 +343,7 @@ namespace gdjs {
const behavior: any = this.emitter.getBehavior('rotation');
behavior.minSpeed = gdjs.toRad(min);
behavior.maxSpeed = gdjs.toRad(max);
this._updateRotateFromSpeedFlag();
this._updateRotateFlagFromSpeed();
}
setMaxParticlesCount(count: float): void {

View File

@@ -237,8 +237,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
"MovementAngleIsAround",
_("Angle of movement on its path"),
_("Compare the angle of movement of an object on its path."),
_("Angle of movement of _PARAM0_ is _PARAM2_ (tolerance"
": _PARAM3_ degrees)"),
_("Angle of movement of _PARAM0_ is _PARAM2_ ± _PARAM3_°"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")

View File

@@ -47,6 +47,7 @@ namespace gdjs {
this.world = new Box2D.b2World(
new Box2D.b2Vec2(this.gravityX, this.gravityY)
);
this.world.SetAutoClearForces(false);
this.staticBody = this.world.CreateBody(new Box2D.b2BodyDef());
this.contactListener = new Box2D.JSContactListener();
this.contactListener.BeginContact = function (contactPtr) {

View File

@@ -288,10 +288,13 @@ module.exports = {
.addIncludeFile(
'Extensions/TextInput/textinputruntimeobject-pixi-renderer.js'
)
.addDefaultBehavior("TextContainerCapability::TextContainerBehavior")
.addDefaultBehavior('ResizableCapability::ResizableBehavior')
.addDefaultBehavior('OpacityCapability::OpacityBehavior');
// Properties expressions/conditions/actions:
// Deprecated
object
.addExpressionAndConditionAndAction(
'string',
@@ -302,13 +305,25 @@ module.exports = {
'',
'res/conditions/text24_black.png'
)
.setHidden()
.addParameter('object', _('Text input'), 'TextInputObject', false)
.useStandardParameters(
'string',
gd.ParameterOptions.makeNewOptions().setDescription(_('Text'))
)
.setFunctionName('setString')
.setGetter('getString');
.setFunctionName('setText')
.setGetter('getText');
object
.addStrExpression(
'Text',
_('Text'),
_('Return the text.'),
'',
'res/conditions/text24_black.png'
)
.addParameter('object', _('Text input'), 'TextInputObject', false)
.setFunctionName('getText');
object
.addExpressionAndConditionAndAction(

View File

@@ -50,7 +50,7 @@ namespace gdjs {
*/
export class TextInputRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.Resizable, gdjs.OpacityHandler {
implements gdjs.TextContainer, gdjs.Resizable, gdjs.OpacityHandler {
private _string: string;
private _placeholder: string;
private opacity: float = 255;
@@ -244,15 +244,25 @@ namespace gdjs {
/**
* Get the text entered in the text input.
* @deprecated use `getText` instead
*/
getString() {
return this._string;
return this.getText();
}
/**
* Replace the text inside the text input.
* @deprecated use `setText` instead
*/
setString(newString: string) {
setString(text: string) {
this.setText(text);
}
getText() {
return this._string;
}
setText(newString: string) {
if (newString === this._string) return;
this._string = newString;

View File

@@ -35,10 +35,12 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
_("Displays a text on the screen."),
"CppPlatform/Extensions/texticon.png")
.SetCategoryFullName(_("Text"))
.AddDefaultBehavior("TextContainerCapability::TextContainerBehavior")
.AddDefaultBehavior("EffectCapability::EffectBehavior")
.AddDefaultBehavior("ScalableCapability::ScalableBehavior")
.AddDefaultBehavior("OpacityCapability::OpacityBehavior");
// Deprecated
obj.AddAction("String",
_("Modify the text"),
_("Modify the text of a Text object."),
@@ -46,7 +48,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
"",
"res/actions/text24_black.png",
"res/actions/text_black.png")
.SetHidden()
.AddParameter("object", _("Object"), "Text")
.UseStandardOperatorParameters(
"string",
@@ -54,6 +56,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
.SetFunctionName("SetString")
.SetGetter("GetString");
// Deprecated
obj.AddCondition("String",
_("Compare the text"),
_("Compare the text of a Text object."),
@@ -61,7 +64,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
"",
"res/conditions/text24_black.png",
"res/conditions/text_black.png")
.SetHidden()
.AddParameter("object", _("Object"), "Text")
.UseStandardRelationalOperatorParameters(
"string",

View File

@@ -36,7 +36,7 @@ namespace gdjs {
*/
export class TextRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.OpacityHandler {
implements gdjs.TextContainer, gdjs.OpacityHandler {
_characterSize: number;
_fontName: string;
_bold: boolean;
@@ -213,20 +213,37 @@ namespace gdjs {
/**
* Get the string displayed by the object.
* @deprecated use `getText` instead
*/
getString(): string {
return this.getText();
}
/**
* Set the string displayed by the object.
* @param text The new text
* @deprecated use `setText` instead
*/
setString(text: string): void {
this.setText(text);
}
/**
* Get the string displayed by the object.
*/
getText(): string {
return this._str;
}
/**
* Set the string displayed by the object.
* @param str The new text
* @param text The new text
*/
setString(str: string): void {
if (str === this._str) {
setText(text: string): void {
if (text === this._str) {
return;
}
this._str = str;
this._str = text;
this._renderer.updateString();
this._updateTextPosition();
}

View File

@@ -1044,7 +1044,9 @@ module.exports = {
.setExtensionInformation(
'TileMap',
_('Tilemap'),
"The Tilemap object can be used to display tile-based objects. It's a good way to create maps for RPG, strategy games or create objects by assembling tiles, useful for platformer, retro-looking games, etc...",
_(
"The Tilemap object can be used to display tile-based objects. It's a good way to create maps for RPG, strategy games or create objects by assembling tiles, useful for platformer, retro-looking games, etc..."
),
'Todor Imreorov',
'Open source (MIT License)'
)
@@ -1061,6 +1063,25 @@ module.exports = {
return extension;
},
registerClearCache: function (
objectsRenderingService /*: ObjectsRenderingService */
) {
const TilemapHelper = objectsRenderingService.requireModule(
__dirname,
'helper/TileMapHelper'
);
const clearCaches = (
project /* InstanceHolder - gdProject in the editor */
) => {
/** @type {TileMapHelper.TileMapManager} */
const manager = TilemapHelper.TileMapManager.getManager(project);
manager.clearCaches();
};
objectsRenderingService.registerClearCache(clearCaches);
},
/**
* You can optionally add sanity tests that will check the basic working
* of your extension behaviors/objects by instantiating behaviors/objects

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
import { LDtkTileMap } from '../load/ldtk/LDtkFormat';
import { TiledTileMap } from '../load/tiled/TiledFormat';
export declare type TileMapFileContent =
export type TileMapFileContent =
| {
kind: 'tiled';
data: TiledTileMap;

View File

@@ -1 +1 @@
{"version":3,"file":"TileMapFileContent.d.ts","sourceRoot":"","sources":["../../src/load/TileMapFileContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,oBAAY,kBAAkB,GAC1B;IACE,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;CACpB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC"}
{"version":3,"file":"TileMapFileContent.d.ts","sourceRoot":"","sources":["../../src/load/TileMapFileContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;CACpB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC"}

View File

@@ -2,7 +2,7 @@ import { integer } from '../../model/CommonTypes';
/**
* version 1.1.3 - https://github.com/deepnight/ldtk/blob/66fff7199932357f3ab9b044c2fc2a856f527831/docs/JSON_SCHEMA.json
*/
export declare type LDtkTileMap = {
export type LDtkTileMap = {
/** LDtk application build identifier.<br/> This is only used to identify the LDtk version that generated this particular project file, which can be useful for specific bug fixing. Note that the build identifier is just the date of the release, so it's not unique to each user (one single global ID per LDtk public release), and as a result, completely anonymous. */
appBuildId: number;
/** Number of backup files to keep, if the `backupOnSave` is TRUE */
@@ -72,7 +72,7 @@ export declare type LDtkTileMap = {
| null;
};
/** Auto-layer rule group */
declare type LDtkAutoLayerRuleGroup = {
type LDtkAutoLayerRuleGroup = {
/** */
active: boolean;
/** *This field was removed in 1.0.0 and should no longer be used.* */
@@ -87,9 +87,9 @@ declare type LDtkAutoLayerRuleGroup = {
uid: integer;
};
/** This complex section isn't meant to be used by game devs at all, as these rules are completely resolved internally by the editor before any saving. You should just ignore this part. */
declare type LDtkAutoRuleDef = {};
type LDtkAutoRuleDef = {};
/** If you're writing your own LDtk importer, you should probably just ignore *most* stuff in the `defs` section, as it contains data that are mostly important to the editor. To keep you away from the `defs` section and avoid some unnecessary JSON parsing, important data from definitions is often duplicated in fields prefixed with a double underscore (eg. `__identifier` or `__type`). The 2 only definition types you might need here are **Tilesets** and **Enums**. */
declare type LDtkDefinition = {
type LDtkDefinition = {
/** All entities definitions, including their custom fields */
entities: LDtkEntityDef[];
/** All internal enums */
@@ -104,7 +104,7 @@ declare type LDtkDefinition = {
tilesets: LDtkTilesetDef[];
};
/** Entity definition */
declare type LDtkEntityDef = {
type LDtkEntityDef = {
/** Base entity color */
color: string;
/** Array of field definitions */
@@ -166,7 +166,7 @@ declare type LDtkEntityDef = {
width: integer;
};
/** Entity instance */
declare type LDtkEntityInstance = {
type LDtkEntityInstance = {
/** Grid-based coordinates (`[x,y]` format) */
__grid: integer[];
/** Entity definition identifier */
@@ -193,7 +193,7 @@ declare type LDtkEntityInstance = {
width: integer;
};
/** Enum definition */
declare type LDtkEnumDef = {
type LDtkEnumDef = {
/** */
externalFileChecksum: string | null;
/** Relative path to the external file providing this Enum */
@@ -210,7 +210,7 @@ declare type LDtkEnumDef = {
values: LDtkEnumDefValues[];
};
/** Enum value definition */
declare type LDtkEnumDefValues = {
type LDtkEnumDefValues = {
/** An array of 4 Int values that refers to the tile in the tileset image: `[ x, y, width, height ]` */
__tileSrcRect: integer[] | null;
/** Optional color */
@@ -221,14 +221,14 @@ declare type LDtkEnumDefValues = {
tileId: integer | null;
};
/** In a tileset definition, enum based tag infos */
declare type LDtkEnumTagValue = {
type LDtkEnumTagValue = {
/** */
enumValueId: string;
/** */
tileIds: integer[];
};
/** This section is mostly only intended for the LDtk editor app itself. You can safely ignore it. */
declare type LDtkFieldDef = {
type LDtkFieldDef = {
/** Human readable value type. Possible values: `Int, Float, String, Bool, Color, ExternEnum.XXX, LocalEnum.XXX, Point, FilePath`.<br/> If the field is an array, this field will look like `Array<...>` (eg. `Array<Int>`, `Array<Point>` etc.)<br/> NOTE: if you enable the advanced option **Use Multilines type**, you will have \"*Multilines*\" instead of \"*String*\" when relevant. */
__type: string;
/** Optional list of accepted file extensions for FilePath value type. Includes the dot: `.ext` */
@@ -310,7 +310,7 @@ declare type LDtkFieldDef = {
useForSmartColor: boolean;
};
/** Field instance */
declare type LDtkFieldInstance = {
type LDtkFieldInstance = {
/** Field definition identifier */
__identifier: string;
/** Optional TilesetRect used to display this field (this can be the field own Tile, or some other Tile guessed from the value, like an Enum). */
@@ -324,7 +324,7 @@ declare type LDtkFieldInstance = {
/** Editor internal raw values */
realEditorValues: any[];
};
declare type LDtkFlag =
type LDtkFlag =
| 'DiscardPreCsvIntGrid'
| 'ExportPreCsvIntGridFormat'
| 'IgnoreBackupSuggest'
@@ -332,7 +332,7 @@ declare type LDtkFlag =
| 'MultiWorlds'
| 'UseMultilinesType';
/** IntGrid value definition */
declare type LDtkIntGridValueDef = {
type LDtkIntGridValueDef = {
/** */
color: string;
/** User defined unique identifier */
@@ -341,14 +341,14 @@ declare type LDtkIntGridValueDef = {
value: integer;
};
/** IntGrid value instance */
declare type LDtkIntGridValueInstance = {
type LDtkIntGridValueInstance = {
/** Coordinate ID in the layer grid */
coordId: integer;
/** IntGrid value */
v: integer;
};
/** Layer definition */
declare type LDtkLayerDef = {
type LDtkLayerDef = {
/** Type of the layer (*IntGrid, Entities, Tiles or AutoLayer*) */
__type: string;
/** Contains all the auto-layer rule definitions. */
@@ -401,7 +401,7 @@ declare type LDtkLayerDef = {
uid: integer;
};
/** Layer instance */
declare type LDtkLayerInstance = {
type LDtkLayerInstance = {
/** Grid-based height */
__cHei: integer;
/** Grid-based width */
@@ -452,7 +452,7 @@ declare type LDtkLayerInstance = {
visible: boolean;
};
/** This section contains all the level data. It can be found in 2 distinct forms, depending on Project current settings: - If \"*Separate level files*\" is **disabled** (default): full level data is *embedded* inside the main Project JSON file, - If \"*Separate level files*\" is **enabled**: level data is stored in *separate* standalone `.ldtkl` files (one per level). In this case, the main Project JSON file will still contain most level data, except heavy sections, like the `layerInstances` array (which will be null). The `externalRelPath` string points to the `ldtkl` file. A `ldtkl` file is just a JSON file containing exactly what is described below. */
declare type LDtkLevel = {
type LDtkLevel = {
/** Background color of the level (same as `bgColor`, except the default value is automatically used here if its value is `null`) */
__bgColor: string;
/** Position informations of the background image, if there is one. */
@@ -497,7 +497,7 @@ declare type LDtkLevel = {
worldY: integer;
};
/** Level background image position info */
declare type LDtkLevelBgPosInfos = {
type LDtkLevelBgPosInfos = {
/** An array of 4 float values describing the cropped sub-rectangle of the displayed background image. This cropping happens when original is larger than the level bounds. Array format: `[ cropX, cropY, cropWidth, cropHeight ]` */
cropRect: number[];
/** An array containing the `[scaleX,scaleY]` values of the **cropped** background image, depending on `bgPos` option. */
@@ -506,7 +506,7 @@ declare type LDtkLevelBgPosInfos = {
topLeftPx: integer[];
};
/** Nearby level info */
declare type LDtkNeighbourLevel = {
type LDtkNeighbourLevel = {
/** A single lowercase character tipping on the level location (`n`orth, `s`outh, `w`est, `e`ast). */
dir: string;
/** Neighbour Instance Identifier */
@@ -515,7 +515,7 @@ declare type LDtkNeighbourLevel = {
levelUid: integer;
};
/** This structure represents a single tile from a given Tileset. */
declare type LDtkTile = {
type LDtkTile = {
/** Internal data used by the editor.<br/> For auto-layer tiles: `[ruleId, coordId]`.<br/> For tile-layer tiles: `[coordId]`. */
d: integer[];
/** \"Flip bits\", a 2-bits integer to represent the mirror transformations of the tile.<br/> - Bit 0 = X flip<br/> - Bit 1 = Y flip<br/> Examples: f=0 (no flip), f=1 (X flip only), f=2 (Y flip only), f=3 (both flips) */
@@ -528,7 +528,7 @@ declare type LDtkTile = {
t: integer;
};
/** The `Tileset` definition is the most important part among project definitions. It contains some extra informations about each integrated tileset. If you only had to parse one definition section, that would be the one. */
export declare type LDtkTilesetDef = {
export type LDtkTilesetDef = {
/** Grid-based height */
__cHei: integer;
/** Grid-based width */
@@ -565,14 +565,14 @@ export declare type LDtkTilesetDef = {
uid: integer;
};
/** In a tileset definition, user defined meta-data of a tile. */
declare type LDtkTileCustomMetadata = {
type LDtkTileCustomMetadata = {
/** */
data: string;
/** */
tileId: integer;
};
/** This object represents a custom sub rectangle in a Tileset image. */
declare type LDtkTilesetRect = {
type LDtkTilesetRect = {
/** Height in pixels */
h: integer;
/** UID of the tileset */
@@ -584,6 +584,6 @@ declare type LDtkTilesetRect = {
/** Y pixels coordinate of the top-left corner in the Tileset image */
y: integer;
};
declare type LDtkWorld = {};
type LDtkWorld = {};
export {};
//# sourceMappingURL=LDtkFormat.d.ts.map

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@ import { float, integer } from '../../model/CommonTypes';
/**
* Tiled JSON format (https://github.com/mapeditor/tiled/blob/master/docs/reference/json-map-format.rst).
*/
export declare type TiledTileMap = {
export type TiledTileMap = {
/** Hex-formatted color (#RRGGBB or #AARRGGBB) (optional) */
backgroundcolor?: string;
/** The compression level to use for tile layer data (defaults to -1, which means to use the algorithm default) */
@@ -44,7 +44,7 @@ export declare type TiledTileMap = {
/** Number of tile columns */
width: integer;
};
export declare type TiledLayer = {
export type TiledLayer = {
/** Array of {@link TiledChunk} (optional). `tilelayer` only. */
chunks?: Array<TiledChunk>;
/** `zlib`, `gzip`, `zstd` (since Tiled 1.3) or empty (default). `tilelayer` only. */
@@ -98,7 +98,7 @@ export declare type TiledLayer = {
/** Vertical layer offset in tiles. Always 0. */
y: integer;
};
export declare type TiledChunk = {
export type TiledChunk = {
/** Array of `unsigned` `integer` (GIDs) or base64-encoded data */
data: Array<integer> | string;
/** Height in tiles */
@@ -110,7 +110,7 @@ export declare type TiledChunk = {
/** Y coordinate in tiles */
y: integer;
};
export declare type TiledObject = {
export type TiledObject = {
/** The class of the object (was saved as class in 1.9, optional) */
type?: string;
/** The class of the object (used only in 1.9, optional) */
@@ -148,7 +148,7 @@ export declare type TiledObject = {
/** Y coordinate in pixels */
y: float;
};
export declare type TiledText = {
export type TiledText = {
/** Whether to use a bold font (default: `false`) */
bold: boolean;
/** Hex-formatted color (#RRGGBB or #AARRGGBB) (default: `#000000`) */
@@ -174,7 +174,7 @@ export declare type TiledText = {
/** Whether the text is wrapped within the object bounds (default: `false`) */
wrap: boolean;
};
export declare type TiledTileset = {
export type TiledTileset = {
/** Hex-formatted color (#RRGGBB or #AARRGGBB) (optional) */
backgroundcolor?: string;
/** The number of tile columns in the tileset */
@@ -226,7 +226,7 @@ export declare type TiledTileset = {
/** Array of {@link TiledWangSet} (since 1.1.5) */
wangsets?: Array<TiledWangSet>;
};
export declare type TiledGrid = {
export type TiledGrid = {
/** Cell height of tile grid */
height: integer;
/** `orthogonal` (default) or `isometric` */
@@ -234,13 +234,13 @@ export declare type TiledGrid = {
/** Cell width of tile grid */
width: integer;
};
export declare type TileOffset = {
export type TileOffset = {
/** Horizontal offset in pixels */
x: integer;
/** Vertical offset in pixels (positive is down) */
y: integer;
};
export declare type TiledTransformations = {
export type TiledTransformations = {
/** Tiles can be flipped horizontally */
hflip: boolean;
/** Tiles can be flipped vertically */
@@ -250,7 +250,7 @@ export declare type TiledTransformations = {
/** Whether untransformed tiles remain preferred, otherwise transformed tiles are used to produce more variations */
preferuntransformed: boolean;
};
export declare type TiledTileDefinition = {
export type TiledTileDefinition = {
/** Array of {@link TiledTiles} */
animation?: Array<TiledTileDefinition>;
/** The class of the object (was saved as class in 1.9, optional) */
@@ -274,13 +274,13 @@ export declare type TiledTileDefinition = {
/** Index of terrain for each corner of tile (optional) */
terrain?: Array<integer>;
};
export declare type TiledFrame = {
export type TiledFrame = {
/** Frame duration in milliseconds */
duration: integer;
/** Local tile ID representing this frame */
tileid: integer;
};
export declare type TiledTerrain = {
export type TiledTerrain = {
/** Name of terrain */
name: string;
/** Array of {@link TiledProperty} */
@@ -288,7 +288,7 @@ export declare type TiledTerrain = {
/** Local ID of tile representing terrain */
tile: integer;
};
export declare type TiledWangSet = {
export type TiledWangSet = {
/** Array of {@link TiledWangColor} */
colors: Array<TiledWangColor>;
/** Name of the Wang set */
@@ -300,7 +300,7 @@ export declare type TiledWangSet = {
/** Array of {@link TiledWangTile} */
wangtiles: Array<TiledWangTile>;
};
export declare type TiledWangColor = {
export type TiledWangColor = {
/** Hex-formatted color (#RRGGBB or #AARRGGBB) */
color: string;
/** Name of the Wang color */
@@ -312,13 +312,13 @@ export declare type TiledWangColor = {
/** Local ID of tile representing the Wang color */
tile: integer;
};
export declare type TiledWangTile = {
export type TiledWangTile = {
/** Local ID of tile */
tileid: integer;
/** Array of Wang color indexes (`uchar[8]`) */
wangid: Array<integer>;
};
export declare type TiledObjectTemplate = {
export type TiledObjectTemplate = {
/** `template` */
type: string;
/** External tileset used by the template (optional) */
@@ -326,7 +326,7 @@ export declare type TiledObjectTemplate = {
/** The object instantiated by this template */
object: Object;
};
export declare type TiledProperty = {
export type TiledProperty = {
/** Name of the property */
name: string;
/** type of the property (`string` (default), `integer`, `float`, `boolean`, `color` or `file` (since 0.16, with `color` and `file` added in 0.17)) */
@@ -334,7 +334,7 @@ export declare type TiledProperty = {
/** Value of the property */
value: string | number;
};
export declare type TiledPoint = {
export type TiledPoint = {
/** X coordinate in pixels */
x: float;
/** Y coordinate in pixels */

File diff suppressed because one or more lines are too long

View File

@@ -12,7 +12,7 @@ export declare const decodeBase64LayerData: (
pako: any,
tiledLayer: TiledLayer
) => number[];
export declare type TiledGID = {
export type TiledGID = {
id: integer;
flippedHorizontally: boolean;
flippedVertically: boolean;

View File

@@ -1 +1 @@
{"version":3,"file":"TiledTileMapLoaderHelper.d.ts","sourceRoot":"","sources":["../../../src/load/tiled/TiledTileMapLoaderHelper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,SAAU,GAAG,cAAc,UAAU,aAgDtE,CAAC;AAEF,oBAAY,QAAQ,GAAG;IACrB,EAAE,EAAE,OAAO,CAAC;IACZ,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,kBACvB,OAAO,KACrB,QAmBF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAEpB"}
{"version":3,"file":"TiledTileMapLoaderHelper.d.ts","sourceRoot":"","sources":["../../../src/load/tiled/TiledTileMapLoaderHelper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,SAAU,GAAG,cAAc,UAAU,aAgDtE,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,OAAO,CAAC;IACZ,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,kBACvB,OAAO,KACrB,QAmBF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAEpB"}

View File

@@ -1,5 +1,5 @@
export declare type integer = number;
export declare type float = number;
export declare type FloatPoint = [float, float];
export declare type PolygonVertices = FloatPoint[];
export type FloatPoint = [float, float];
export type PolygonVertices = FloatPoint[];
//# sourceMappingURL=CommonTypes.d.ts.map

View File

@@ -1 +1 @@
{"version":3,"file":"CommonTypes.d.ts","sourceRoot":"","sources":["../../src/model/CommonTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,MAAM,OAAO,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,OAAO,MAAM,KAAK,GAAG,MAAM,CAAC;AACnC,oBAAY,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAExC,oBAAY,eAAe,GAAG,UAAU,EAAE,CAAC"}
{"version":3,"file":"CommonTypes.d.ts","sourceRoot":"","sources":["../../src/model/CommonTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,MAAM,OAAO,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,OAAO,MAAM,KAAK,GAAG,MAAM,CAAC;AACnC,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAExC,MAAM,MAAM,eAAe,GAAG,UAAU,EAAE,CAAC"}

View File

@@ -65,5 +65,6 @@ export declare class TileMapManager {
levelIndex: number,
callback: (textureCache: TileTextureCache | null) => void
): void;
clearCaches(): void;
}
//# sourceMappingURL=TileMapManager.d.ts.map

View File

@@ -1 +1 @@
{"version":3,"file":"TileMapManager.d.ts","sourceRoot":"","sources":["../../src/render/TileMapManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,mBAAmB,CAAkC;;IAO7D;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc;IAWzD;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,kBAAkB,GAAG,IAAI;IAwBrD;;;;;;;OAOG;IACH,gBAAgB,CACd,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,GAClD,IAAI;IAiCP;;;;;;;;OAQG;IACH,qBAAqB,CACnB,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpE,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GACxD,IAAI;CAuCR"}
{"version":3,"file":"TileMapManager.d.ts","sourceRoot":"","sources":["../../src/render/TileMapManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,mBAAmB,CAAkC;;IAO7D;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc;IAWzD;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,kBAAkB,GAAG,IAAI;IAwBrD;;;;;;;OAOG;IACH,gBAAgB,CACd,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,GAClD,IAAI;IAiCP;;;;;;;;OAQG;IACH,qBAAqB,CACnB,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpE,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GACxD,IAAI;IAwCP,WAAW,IAAI,IAAI;CAIpB"}

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