mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
1 Commits
v5.3.195
...
fix-image-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
dd8ef4058f |
4
.github/workflows/update-translations.yml
vendored
4
.github/workflows/update-translations.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 16
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Create a Pull Request with the changes
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Update translations [skip ci]
|
||||
branch: chore/update-translations
|
||||
|
@@ -56,7 +56,6 @@ blocks:
|
||||
- name: GDJS typing and documentation generation
|
||||
commands:
|
||||
- checkout
|
||||
- cache restore newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json)
|
||||
- cache restore GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json)
|
||||
- cache restore GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json)
|
||||
- cd GDJS
|
||||
|
1
.vscode/tasks.json
vendored
1
.vscode/tasks.json
vendored
@@ -8,7 +8,6 @@
|
||||
"group": "build",
|
||||
"label": "Start development server",
|
||||
"detail": "Starts the GDevelop development server.",
|
||||
"options": { "env": { "NODE_OPTIONS": "--max-old-space-size=8192" } },
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "cra",
|
||||
|
@@ -114,8 +114,6 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
@@ -13,15 +13,12 @@
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
const std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::badProperties;
|
||||
|
||||
BehaviorMetadata::BehaviorMetadata(
|
||||
const gd::String& extensionNamespace_,
|
||||
const gd::String& nameWithNamespace,
|
||||
@@ -50,14 +47,8 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
"BehaviorMetadata is valid for: " + nameWithNamespace);
|
||||
}
|
||||
|
||||
if (instance) {
|
||||
instance->SetTypeName(nameWithNamespace);
|
||||
instance->InitializeContent();
|
||||
}
|
||||
if (sharedDatasInstance) {
|
||||
sharedDatasInstance->SetTypeName(nameWithNamespace);
|
||||
sharedDatasInstance->InitializeContent();
|
||||
}
|
||||
if (instance) instance->SetTypeName(nameWithNamespace);
|
||||
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(nameWithNamespace);
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddCondition(
|
||||
@@ -414,30 +405,10 @@ gd::Behavior& BehaviorMetadata::Get() const {
|
||||
return *instance;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetProperties() const {
|
||||
if (!instance) {
|
||||
return badProperties;
|
||||
}
|
||||
// TODO Properties should be declared on BehaviorMetadata directly.
|
||||
// - Add 2 `properties` members (one for shared properties)
|
||||
// - Add methods to declare new properties
|
||||
return instance->GetProperties();
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
return sharedDatasInstance.get();
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetSharedProperties() const {
|
||||
if (!sharedDatasInstance) {
|
||||
return badProperties;
|
||||
}
|
||||
// TODO Properties should be declared on BehaviorMetadata directly.
|
||||
// - Add 2 `properties` members (one for shared properties)
|
||||
// - Add methods to declare new properties
|
||||
return sharedDatasInstance->GetProperties();
|
||||
}
|
||||
|
||||
const std::vector<gd::String>& BehaviorMetadata::GetRequiredBehaviorTypes() const {
|
||||
requiredBehaviors.clear();
|
||||
for (auto& property : Get().GetProperties()) {
|
||||
|
@@ -18,7 +18,6 @@ class BehaviorsSharedData;
|
||||
class MultipleInstructionMetadata;
|
||||
class InstructionMetadata;
|
||||
class ExpressionMetadata;
|
||||
class PropertyDescriptor;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -205,8 +204,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the behavior.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
BehaviorMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
@@ -305,15 +302,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
*/
|
||||
gd::Behavior& Get() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
* behavior.
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Return the associated gd::BehaviorsSharedData, handling behavior
|
||||
* shared data, if any (nullptr if none).
|
||||
@@ -323,15 +311,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
*/
|
||||
gd::BehaviorsSharedData* GetSharedDataInstance() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom shared properties
|
||||
* of the behavior.
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetSharedProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
@@ -378,8 +357,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
|
||||
std::shared_ptr<gd::Behavior> instance;
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance;
|
||||
|
||||
static const std::map<gd::String, gd::PropertyDescriptor> badProperties;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -65,8 +65,6 @@ class GD_CORE_API EffectMetadata {
|
||||
|
||||
/**
|
||||
* \brief Clear any existing include file and add the specified include file.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
EffectMetadata& SetIncludeFile(const gd::String& includeFile);
|
||||
|
||||
|
@@ -288,8 +288,6 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
ExpressionMetadata& SetIncludeFile(
|
||||
const gd::String& includeFile) override {
|
||||
|
@@ -494,8 +494,6 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
codeExtraInformation.includeFiles.clear();
|
||||
|
@@ -142,8 +142,6 @@ public:
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the behavior.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
@@ -150,10 +150,6 @@ class GD_CORE_API MultipleInstructionMetadata : public AbstractFunctionMetadata
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
if (expression)
|
||||
expression->SetIncludeFile(includeFile);
|
||||
|
@@ -264,8 +264,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the object.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
ObjectMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
|
@@ -285,6 +285,22 @@ class GD_CORE_API PlatformExtension {
|
||||
std::shared_ptr<gd::Behavior> instance,
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
|
||||
|
||||
/**
|
||||
* \brief Declare a new events based behavior as being part of the extension.
|
||||
*
|
||||
* \param name The name of the behavior
|
||||
* \param fullname The user friendly name of the behavior
|
||||
* \param description The user friendly description of the behavior
|
||||
* \param group The behavior category label
|
||||
* \param icon The icon of the behavior.
|
||||
*/
|
||||
gd::BehaviorMetadata& AddEventsBasedBehavior(
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_);
|
||||
|
||||
/**
|
||||
* \brief Declare a new effect as being part of the extension.
|
||||
* \param name The internal name of the effect (also called effect type).
|
||||
|
@@ -5,8 +5,6 @@
|
||||
*/
|
||||
#include "ObjectAssetSerializer.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
@@ -39,7 +37,7 @@ ObjectAssetSerializer::GetObjectExtensionName(const gd::Object &object) {
|
||||
void ObjectAssetSerializer::SerializeTo(
|
||||
gd::Project &project, const gd::Object &object,
|
||||
const gd::String &objectFullName, SerializerElement &element,
|
||||
std::vector<gd::String> &usedResourceNames) {
|
||||
std::map<gd::String, gd::String> &resourcesFileNameMap) {
|
||||
auto cleanObject = object.Clone();
|
||||
cleanObject->GetVariables().Clear();
|
||||
cleanObject->GetEffects().Clear();
|
||||
@@ -49,6 +47,11 @@ void ObjectAssetSerializer::SerializeTo(
|
||||
|
||||
gd::String extensionName = GetObjectExtensionName(*cleanObject);
|
||||
|
||||
std::map<gd::String, gd::String> resourcesNameReverseMap;
|
||||
gd::ObjectAssetSerializer::RenameObjectResourceFiles(
|
||||
project, *cleanObject, "", objectFullName, resourcesFileNameMap,
|
||||
resourcesNameReverseMap);
|
||||
|
||||
element.SetAttribute("id", "");
|
||||
element.SetAttribute("name", "");
|
||||
element.SetAttribute("license", "");
|
||||
@@ -81,16 +84,27 @@ void ObjectAssetSerializer::SerializeTo(
|
||||
auto &resourcesManager = project.GetResourcesManager();
|
||||
gd::ResourcesInUseHelper resourcesInUse(resourcesManager);
|
||||
cleanObject->GetConfiguration().ExposeResources(resourcesInUse);
|
||||
for (auto &&resourceName : resourcesInUse.GetAllResources()) {
|
||||
if (resourceName.length() == 0) {
|
||||
for (auto &&newResourceName : resourcesInUse.GetAllResources()) {
|
||||
if (newResourceName.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
usedResourceNames.push_back(resourceName);
|
||||
auto &resource = resourcesManager.GetResource(resourceName);
|
||||
auto &resource = resourcesManager.GetResource(
|
||||
resourcesNameReverseMap.find(newResourceName) !=
|
||||
resourcesNameReverseMap.end()
|
||||
? resourcesNameReverseMap[newResourceName]
|
||||
: newResourceName);
|
||||
SerializerElement &resourceElement = resourcesElement.AddChild("resource");
|
||||
resource.SerializeTo(resourceElement);
|
||||
// Override name and file because the project and the asset don't use the
|
||||
// same one.
|
||||
resourceElement.SetAttribute("kind", resource.GetKind());
|
||||
resourceElement.SetAttribute("name", resource.GetName());
|
||||
resourceElement.SetAttribute("name", newResourceName);
|
||||
auto &oldFilePath = resource.GetFile();
|
||||
resourceElement.SetAttribute("file",
|
||||
resourcesFileNameMap.find(oldFilePath) !=
|
||||
resourcesFileNameMap.end()
|
||||
? resourcesFileNameMap[oldFilePath]
|
||||
: oldFilePath);
|
||||
}
|
||||
|
||||
SerializerElement &requiredExtensionsElement =
|
||||
@@ -108,4 +122,101 @@ void ObjectAssetSerializer::SerializeTo(
|
||||
objectAssetElement.AddChild("customization");
|
||||
customizationElement.ConsiderAsArrayOf("empty");
|
||||
}
|
||||
|
||||
void ObjectAssetSerializer::RenameObjectResourceFiles(
|
||||
gd::Project &project, gd::Object &object,
|
||||
const gd::String &destinationDirectory, const gd::String &objectFullName,
|
||||
std::map<gd::String, gd::String> &resourcesFileNameMap,
|
||||
std::map<gd::String, gd::String> &resourcesNameReverseMap) {
|
||||
gd::AssetResourcePathCleaner assetResourcePathCleaner(
|
||||
project.GetResourcesManager(), resourcesFileNameMap,
|
||||
resourcesNameReverseMap);
|
||||
object.GetConfiguration().ExposeResources(assetResourcePathCleaner);
|
||||
|
||||
// Use asset store script naming conventions for sprite resource files.
|
||||
if (object.GetConfiguration().GetType() == "Sprite") {
|
||||
gd::SpriteObject &spriteConfiguration =
|
||||
dynamic_cast<gd::SpriteObject &>(object.GetConfiguration());
|
||||
std::map<gd::String, gd::String> normalizedFileNames;
|
||||
|
||||
for (std::size_t animationIndex = 0;
|
||||
animationIndex < spriteConfiguration.GetAnimationsCount();
|
||||
animationIndex++) {
|
||||
auto &animation = spriteConfiguration.GetAnimation(animationIndex);
|
||||
auto &direction = animation.GetDirection(0);
|
||||
|
||||
const gd::String &animationName =
|
||||
animation.GetName().empty()
|
||||
? gd::String::From(animationIndex)
|
||||
: animation.GetName().FindAndReplace("_", " ", true);
|
||||
|
||||
// Search frames that share the same resource.
|
||||
std::map<gd::String, std::vector<int>> frameIndexes;
|
||||
for (std::size_t frameIndex = 0; frameIndex < direction.GetSpritesCount();
|
||||
frameIndex++) {
|
||||
auto &frame = direction.GetSprite(frameIndex);
|
||||
|
||||
if (frameIndexes.find(frame.GetImageName()) == frameIndexes.end()) {
|
||||
std::vector<int> emptyVector;
|
||||
frameIndexes[frame.GetImageName()] = emptyVector;
|
||||
}
|
||||
auto &indexes = frameIndexes[frame.GetImageName()];
|
||||
indexes.push_back(frameIndex);
|
||||
}
|
||||
|
||||
for (std::size_t frameIndex = 0; frameIndex < direction.GetSpritesCount();
|
||||
frameIndex++) {
|
||||
auto &frame = direction.GetSprite(frameIndex);
|
||||
auto oldName = frame.GetImageName();
|
||||
|
||||
if (normalizedFileNames.find(oldName) != normalizedFileNames.end()) {
|
||||
gd::LogWarning("The resource \"" + oldName +
|
||||
"\" is shared by several animations.");
|
||||
continue;
|
||||
}
|
||||
|
||||
gd::String newName = objectFullName;
|
||||
if (spriteConfiguration.GetAnimationsCount() > 1) {
|
||||
newName += "_" + animationName;
|
||||
}
|
||||
if (direction.GetSpritesCount() > 1) {
|
||||
newName += "_";
|
||||
auto &indexes = frameIndexes[frame.GetImageName()];
|
||||
for (size_t i = 0; i < indexes.size(); i++) {
|
||||
newName += gd::String::From(indexes.at(i) + 1);
|
||||
if (i < indexes.size() - 1) {
|
||||
newName += ";";
|
||||
}
|
||||
}
|
||||
}
|
||||
gd::String extension = oldName.substr(oldName.find_last_of("."));
|
||||
newName += extension;
|
||||
|
||||
frame.SetImageName(newName);
|
||||
normalizedFileNames[oldName] = newName;
|
||||
}
|
||||
}
|
||||
for (std::map<gd::String, gd::String>::const_iterator it =
|
||||
resourcesFileNameMap.begin();
|
||||
it != resourcesFileNameMap.end(); ++it) {
|
||||
if (!it->first.empty()) {
|
||||
gd::String originFile = it->first;
|
||||
gd::String destinationFile = it->second;
|
||||
resourcesFileNameMap[originFile] = normalizedFileNames[destinationFile];
|
||||
}
|
||||
}
|
||||
auto clonedResourcesNameReverseMap = resourcesNameReverseMap;
|
||||
resourcesNameReverseMap.clear();
|
||||
for (std::map<gd::String, gd::String>::const_iterator it =
|
||||
clonedResourcesNameReverseMap.begin();
|
||||
it != clonedResourcesNameReverseMap.end(); ++it) {
|
||||
if (!it->first.empty()) {
|
||||
gd::String newResourceName = it->first;
|
||||
gd::String oldResourceName = it->second;
|
||||
resourcesNameReverseMap[normalizedFileNames[newResourceName]] =
|
||||
oldResourceName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace gd
|
||||
|
@@ -39,18 +39,25 @@ public:
|
||||
* \param object The object to serialize as an asset.
|
||||
* \param objectFullName The object name with spaces instead of PascalCase.
|
||||
* \param element The element where the asset is serialize.
|
||||
* \param usedResourceNames Return the names of the resources used by the asset.
|
||||
* \param resourcesFileNameMap The map from project resource file paths to
|
||||
* asset resource file paths.
|
||||
*/
|
||||
static void
|
||||
SerializeTo(gd::Project &project, const gd::Object &object,
|
||||
const gd::String &objectFullName, SerializerElement &element,
|
||||
std::vector<gd::String> &usedResourceNames);
|
||||
std::map<gd::String, gd::String> &resourcesFileNameMap);
|
||||
|
||||
~ObjectAssetSerializer(){};
|
||||
|
||||
private:
|
||||
ObjectAssetSerializer(){};
|
||||
|
||||
static void RenameObjectResourceFiles(
|
||||
gd::Project &project, gd::Object &object,
|
||||
const gd::String &destinationDirectory, const gd::String &objectFullName,
|
||||
std::map<gd::String, gd::String> &resourcesFileNameMap,
|
||||
std::map<gd::String, gd::String> &resourcesNameReverseMap);
|
||||
|
||||
static gd::String GetObjectExtensionName(const gd::Object &object);
|
||||
};
|
||||
|
||||
|
@@ -4,6 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include <iostream>
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
|
@@ -13,9 +13,7 @@ EventsBasedObject::EventsBasedObject()
|
||||
: AbstractEventsBasedEntity(
|
||||
"MyObject",
|
||||
gd::EventsFunctionsContainer::FunctionOwner::Object),
|
||||
ObjectsContainer(),
|
||||
isRenderedIn3D(false),
|
||||
isTextContainer(false) {
|
||||
ObjectsContainer() {
|
||||
}
|
||||
|
||||
EventsBasedObject::~EventsBasedObject() {}
|
||||
@@ -32,9 +30,6 @@ void EventsBasedObject::SerializeTo(SerializerElement& element) const {
|
||||
if (isRenderedIn3D) {
|
||||
element.SetBoolAttribute("is3D", true);
|
||||
}
|
||||
if (isTextContainer) {
|
||||
element.SetBoolAttribute("isTextContainer", true);
|
||||
}
|
||||
|
||||
AbstractEventsBasedEntity::SerializeTo(element);
|
||||
SerializeObjectsTo(element.AddChild("objects"));
|
||||
@@ -45,7 +40,6 @@ void EventsBasedObject::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
defaultName = element.GetStringAttribute("defaultName");
|
||||
isRenderedIn3D = element.GetBoolAttribute("is3D", false);
|
||||
isTextContainer = element.GetBoolAttribute("isTextContainer", false);
|
||||
|
||||
AbstractEventsBasedEntity::UnserializeFrom(project, element);
|
||||
UnserializeObjectsFrom(project, element.GetChild("objects"));
|
||||
|
@@ -85,19 +85,6 @@ class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity, public Ob
|
||||
*/
|
||||
bool IsRenderedIn3D() const { return isRenderedIn3D; }
|
||||
|
||||
/**
|
||||
* \brief Declare a TextContainer capability.
|
||||
*/
|
||||
EventsBasedObject& MarkAsTextContainer(bool isTextContainer_) {
|
||||
isTextContainer = isTextContainer_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the object needs a TextContainer capability.
|
||||
*/
|
||||
bool IsTextContainer() const { return isTextContainer; }
|
||||
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
@@ -106,7 +93,6 @@ class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity, public Ob
|
||||
private:
|
||||
gd::String defaultName;
|
||||
bool isRenderedIn3D;
|
||||
bool isTextContainer;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -120,6 +120,9 @@ class GD_CORE_API Object {
|
||||
*/
|
||||
const gd::String& GetType() const { return configuration->GetType(); }
|
||||
|
||||
/** \brief Shortcut to check if the object is a 3D object.
|
||||
*/
|
||||
bool Is3DObject() const { return configuration->Is3DObject(); }
|
||||
///@}
|
||||
|
||||
/** \name Behaviors management
|
||||
|
@@ -5,8 +5,11 @@
|
||||
*/
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/CustomBehavior.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -17,7 +20,7 @@ namespace gd {
|
||||
|
||||
ObjectConfiguration::~ObjectConfiguration() {}
|
||||
|
||||
ObjectConfiguration::ObjectConfiguration() {}
|
||||
ObjectConfiguration::ObjectConfiguration(): is3DObject(false) {}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> ObjectConfiguration::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
|
@@ -63,12 +63,20 @@ class GD_CORE_API ObjectConfiguration {
|
||||
*/
|
||||
void SetType(const gd::String& type_) {
|
||||
type = type_;
|
||||
|
||||
// For now, as a shortcut, consider only the objects from the built-in 3D extension
|
||||
// to be 3D object.
|
||||
is3DObject = type.find("Scene3D::") == 0;
|
||||
}
|
||||
|
||||
/** \brief Return the type of the object.
|
||||
*/
|
||||
const gd::String& GetType() const { return type; }
|
||||
|
||||
/** \brief Shortcut to check if the object is a 3D object.
|
||||
*/
|
||||
bool Is3DObject() const { return is3DObject; }
|
||||
|
||||
/** \name Object properties
|
||||
* Reading and updating object configuration properties
|
||||
*/
|
||||
@@ -172,6 +180,7 @@ class GD_CORE_API ObjectConfiguration {
|
||||
protected:
|
||||
gd::String type; ///< Which type of object is represented by this
|
||||
///< configuration.
|
||||
bool is3DObject;
|
||||
|
||||
/**
|
||||
* \brief Derived object configuration can redefine this method to load
|
||||
|
@@ -102,19 +102,21 @@ std::unique_ptr<gd::Object> Project::CreateObject(
|
||||
behavior->SetDefaultBehavior(true);
|
||||
};
|
||||
|
||||
auto &objectMetadata =
|
||||
gd::MetadataProvider::GetObjectMetadata(platform, objectType);
|
||||
if (!MetadataProvider::IsBadObjectMetadata(objectMetadata)) {
|
||||
for (auto &behaviorType : objectMetadata.GetDefaultBehaviors()) {
|
||||
if (Project::HasEventsBasedObject(objectType)) {
|
||||
addDefaultBehavior("EffectCapability::EffectBehavior");
|
||||
addDefaultBehavior("ResizableCapability::ResizableBehavior");
|
||||
addDefaultBehavior("ScalableCapability::ScalableBehavior");
|
||||
addDefaultBehavior("FlippableCapability::FlippableBehavior");
|
||||
} 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()) {
|
||||
addDefaultBehavior(behaviorType);
|
||||
}
|
||||
}
|
||||
// During project deserialization, event-based object metadata are not yet
|
||||
// generated. Default behaviors will be added by
|
||||
// MetadataDeclarationHelper::UpdateCustomObjectDefaultBehaviors
|
||||
else if (!project.HasEventsBasedObject(objectType)) {
|
||||
gd::LogWarning("Object: " + name + " has an unknown type: " + objectType);
|
||||
}
|
||||
|
||||
return std::move(object);
|
||||
}
|
||||
|
@@ -29,15 +29,10 @@ void PropertyDescriptor::SerializeTo(SerializerElement& element) const {
|
||||
for (const gd::String& information : extraInformation) {
|
||||
extraInformationElement.AddChild("").SetStringValue(information);
|
||||
}
|
||||
if (hidden) {
|
||||
element.AddChild("hidden").SetBoolValue(hidden);
|
||||
}
|
||||
element.AddChild("hidden").SetBoolValue(hidden);
|
||||
if (deprecated) {
|
||||
element.AddChild("deprecated").SetBoolValue(deprecated);
|
||||
}
|
||||
if (advanced) {
|
||||
element.AddChild("advanced").SetBoolValue(advanced);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
|
||||
@@ -69,9 +64,6 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
|
||||
deprecated = element.HasChild("deprecated")
|
||||
? element.GetChild("deprecated").GetBoolValue()
|
||||
: false;
|
||||
advanced = element.HasChild("advanced")
|
||||
? element.GetChild("advanced").GetBoolValue()
|
||||
: false;
|
||||
}
|
||||
|
||||
void PropertyDescriptor::SerializeValuesTo(SerializerElement& element) const {
|
||||
|
@@ -31,14 +31,14 @@ class GD_CORE_API PropertyDescriptor {
|
||||
*/
|
||||
PropertyDescriptor(gd::String propertyValue)
|
||||
: currentValue(propertyValue), type("string"), label(""), hidden(false),
|
||||
deprecated(false), advanced(false),
|
||||
deprecated(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()) {}
|
||||
|
||||
/**
|
||||
* \brief Empty constructor creating an empty property to be displayed.
|
||||
*/
|
||||
PropertyDescriptor()
|
||||
: hidden(false), deprecated(false), advanced(false),
|
||||
: hidden(false), deprecated(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()){};
|
||||
|
||||
/**
|
||||
@@ -159,19 +159,6 @@ class GD_CORE_API PropertyDescriptor {
|
||||
*/
|
||||
bool IsDeprecated() const { return deprecated; }
|
||||
|
||||
/**
|
||||
* \brief Set if the property is marked as advanced.
|
||||
*/
|
||||
PropertyDescriptor& SetAdvanced(bool enable = true) {
|
||||
advanced = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the property is marked as advanced.
|
||||
*/
|
||||
bool IsAdvanced() const { return advanced; }
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
@@ -210,7 +197,6 @@ class GD_CORE_API PropertyDescriptor {
|
||||
///< box.
|
||||
bool hidden;
|
||||
bool deprecated;
|
||||
bool advanced;
|
||||
gd::MeasurementUnit measurementUnit; //< The unit of measurement of the property vale.
|
||||
};
|
||||
|
||||
|
@@ -75,13 +75,14 @@ TEST_CASE("ObjectAssetSerializer", "[common]") {
|
||||
}
|
||||
|
||||
SerializerElement assetElement;
|
||||
std::vector<gd::String> usedResourceNames;
|
||||
std::map<gd::String, gd::String> resourcesFileNameMap;
|
||||
ObjectAssetSerializer::SerializeTo(project, object, "My Object",
|
||||
assetElement, usedResourceNames);
|
||||
assetElement, resourcesFileNameMap);
|
||||
|
||||
// This list is used to copy resource files.
|
||||
REQUIRE(usedResourceNames.size() == 1);
|
||||
REQUIRE(usedResourceNames[0] == "assets/Idle.png");
|
||||
// This mapping is used to copy resource files.
|
||||
REQUIRE(resourcesFileNameMap.find("assets/Idle.png") !=
|
||||
resourcesFileNameMap.end());
|
||||
REQUIRE(resourcesFileNameMap["assets/Idle.png"] == "Idle.png");
|
||||
|
||||
// Check that the project is left untouched.
|
||||
REQUIRE(resourceManager.HasResource("assets/Idle.png"));
|
||||
@@ -111,8 +112,8 @@ TEST_CASE("ObjectAssetSerializer", "[common]") {
|
||||
REQUIRE(resourcesElement.GetChildrenCount() == 1);
|
||||
{
|
||||
auto &resourceElement = resourcesElement.GetChild(0);
|
||||
REQUIRE(resourceElement.GetStringAttribute("name") == "assets/Idle.png");
|
||||
REQUIRE(resourceElement.GetStringAttribute("file") == "assets/Idle.png");
|
||||
REQUIRE(resourceElement.GetStringAttribute("name") == "Idle.png");
|
||||
REQUIRE(resourceElement.GetStringAttribute("file") == "Idle.png");
|
||||
REQUIRE(resourceElement.GetStringAttribute("kind") == "image");
|
||||
REQUIRE(resourceElement.GetBoolAttribute("smoothed") == true);
|
||||
}
|
||||
@@ -142,6 +143,6 @@ TEST_CASE("ObjectAssetSerializer", "[common]") {
|
||||
spritesElement.ConsiderAsArrayOf("sprite");
|
||||
REQUIRE(spritesElement.GetChildrenCount() == 1);
|
||||
auto &spriteElement = spritesElement.GetChild(0);
|
||||
REQUIRE(spriteElement.GetStringAttribute("image") == "assets/Idle.png");
|
||||
REQUIRE(spriteElement.GetStringAttribute("image") == "Idle.png");
|
||||
}
|
||||
}
|
||||
|
1
Extensions/.gitignore
vendored
Normal file
1
Extensions/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Spine/pixi-spine
|
@@ -154,23 +154,7 @@ namespace gdjs {
|
||||
* @return The Z position of the rendered object.
|
||||
*/
|
||||
getDrawableZ(): float {
|
||||
return this._z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bottom Z of the object.
|
||||
* Rotations around X and Y are not taken into account.
|
||||
*/
|
||||
getUnrotatedAABBMinZ(): number {
|
||||
return this.getDrawableZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the top Z of the object.
|
||||
* Rotations around X and Y are not taken into account.
|
||||
*/
|
||||
getUnrotatedAABBMaxZ(): number {
|
||||
return this.getDrawableZ() + this.getDepth();
|
||||
return this.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -24,8 +24,8 @@ namespace gdjs {
|
||||
|
||||
updatePosition() {
|
||||
this._threeObject3D.position.set(
|
||||
this._object.getX() + this._object.getWidth() / 2,
|
||||
this._object.getY() + this._object.getHeight() / 2,
|
||||
this._object.x + this._object.getWidth() / 2,
|
||||
this._object.y + this._object.getHeight() / 2,
|
||||
this._object.getZ() + this._object.getDepth() / 2
|
||||
);
|
||||
}
|
||||
|
@@ -103,27 +103,6 @@ namespace gdjs {
|
||||
flipZ(enable: boolean): void;
|
||||
|
||||
isFlippedZ(): boolean;
|
||||
|
||||
/**
|
||||
* Return the bottom Z of the object.
|
||||
* Rotations around X and Y are not taken into account.
|
||||
*/
|
||||
getUnrotatedAABBMinZ(): number;
|
||||
|
||||
/**
|
||||
* Return the top Z of the object.
|
||||
* Rotations around X and Y are not taken into account.
|
||||
*/
|
||||
getUnrotatedAABBMaxZ(): number;
|
||||
}
|
||||
|
||||
export namespace Base3DHandler {
|
||||
export const is3D = (
|
||||
object: gdjs.RuntimeObject
|
||||
): object is gdjs.RuntimeObject & gdjs.Base3DHandler => {
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
return object.getZ && object.setZ;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,14 +202,6 @@ namespace gdjs {
|
||||
isFlippedZ(): boolean {
|
||||
return this.object.isFlippedZ();
|
||||
}
|
||||
|
||||
getUnrotatedAABBMinZ(): number {
|
||||
return this.object.getUnrotatedAABBMinZ();
|
||||
}
|
||||
|
||||
getUnrotatedAABBMaxZ(): number {
|
||||
return this.object.getUnrotatedAABBMaxZ();
|
||||
}
|
||||
}
|
||||
|
||||
gdjs.registerBehavior('Scene3D::Base3DBehavior', gdjs.Base3DBehavior);
|
||||
|
@@ -1,89 +0,0 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator(
|
||||
'Scene3D::Bloom',
|
||||
new (class implements gdjs.PixiFiltersTools.FilterCreator {
|
||||
makeFilter(
|
||||
target: EffectsTarget,
|
||||
effectData: EffectData
|
||||
): gdjs.PixiFiltersTools.Filter {
|
||||
if (typeof THREE === 'undefined') {
|
||||
return new gdjs.PixiFiltersTools.EmptyFilter();
|
||||
}
|
||||
return new (class implements gdjs.PixiFiltersTools.Filter {
|
||||
shaderPass: THREE_ADDONS.UnrealBloomPass;
|
||||
_isEnabled: boolean;
|
||||
|
||||
constructor() {
|
||||
this.shaderPass = new THREE_ADDONS.UnrealBloomPass(
|
||||
new THREE.Vector2(256, 256),
|
||||
1,
|
||||
0,
|
||||
0
|
||||
);
|
||||
this._isEnabled = false;
|
||||
}
|
||||
|
||||
isEnabled(target: EffectsTarget): boolean {
|
||||
return this._isEnabled;
|
||||
}
|
||||
setEnabled(target: EffectsTarget, enabled: boolean): boolean {
|
||||
if (this._isEnabled === enabled) {
|
||||
return true;
|
||||
}
|
||||
if (enabled) {
|
||||
return this.applyEffect(target);
|
||||
} else {
|
||||
return this.removeEffect(target);
|
||||
}
|
||||
}
|
||||
applyEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().addPostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = true;
|
||||
return true;
|
||||
}
|
||||
removeEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().removePostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = false;
|
||||
return true;
|
||||
}
|
||||
updatePreRender(target: gdjs.EffectsTarget): any {}
|
||||
updateDoubleParameter(parameterName: string, value: number): void {
|
||||
if (parameterName === 'strength') {
|
||||
this.shaderPass.strength = value;
|
||||
}
|
||||
if (parameterName === 'radius') {
|
||||
this.shaderPass.radius = value;
|
||||
}
|
||||
if (parameterName === 'threshold') {
|
||||
this.shaderPass.threshold = value;
|
||||
}
|
||||
}
|
||||
getDoubleParameter(parameterName: string): number {
|
||||
if (parameterName === 'strength') {
|
||||
return this.shaderPass.strength;
|
||||
}
|
||||
if (parameterName === 'radius') {
|
||||
return this.shaderPass.radius;
|
||||
}
|
||||
if (parameterName === 'threshold') {
|
||||
return this.shaderPass.threshold;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
updateStringParameter(parameterName: string, value: string): void {}
|
||||
updateColorParameter(parameterName: string, value: number): void {}
|
||||
getColorParameter(parameterName: string): number {
|
||||
return 0;
|
||||
}
|
||||
updateBooleanParameter(parameterName: string, value: boolean): void {}
|
||||
})();
|
||||
}
|
||||
})()
|
||||
);
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator(
|
||||
'Scene3D::BrightnessAndContrast',
|
||||
new (class implements gdjs.PixiFiltersTools.FilterCreator {
|
||||
makeFilter(
|
||||
target: EffectsTarget,
|
||||
effectData: EffectData
|
||||
): gdjs.PixiFiltersTools.Filter {
|
||||
if (typeof THREE === 'undefined') {
|
||||
return new gdjs.PixiFiltersTools.EmptyFilter();
|
||||
}
|
||||
return new (class implements gdjs.PixiFiltersTools.Filter {
|
||||
shaderPass: THREE_ADDONS.ShaderPass;
|
||||
_isEnabled: boolean;
|
||||
|
||||
constructor() {
|
||||
this.shaderPass = new THREE_ADDONS.ShaderPass(
|
||||
THREE_ADDONS.BrightnessContrastShader
|
||||
);
|
||||
this._isEnabled = false;
|
||||
}
|
||||
|
||||
isEnabled(target: EffectsTarget): boolean {
|
||||
return this._isEnabled;
|
||||
}
|
||||
setEnabled(target: EffectsTarget, enabled: boolean): boolean {
|
||||
if (this._isEnabled === enabled) {
|
||||
return true;
|
||||
}
|
||||
if (enabled) {
|
||||
return this.applyEffect(target);
|
||||
} else {
|
||||
return this.removeEffect(target);
|
||||
}
|
||||
}
|
||||
applyEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().addPostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = true;
|
||||
return true;
|
||||
}
|
||||
removeEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().removePostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = false;
|
||||
return true;
|
||||
}
|
||||
updatePreRender(target: gdjs.EffectsTarget): any {}
|
||||
updateDoubleParameter(parameterName: string, value: number): void {
|
||||
if (parameterName === 'brightness') {
|
||||
this.shaderPass.uniforms[parameterName].value = value;
|
||||
}
|
||||
if (parameterName === 'contrast') {
|
||||
this.shaderPass.uniforms[parameterName].value = value;
|
||||
}
|
||||
}
|
||||
getDoubleParameter(parameterName: string): number {
|
||||
if (parameterName === 'brightness') {
|
||||
return this.shaderPass.uniforms[parameterName].value;
|
||||
}
|
||||
if (parameterName === 'contrast') {
|
||||
return this.shaderPass.uniforms[parameterName].value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
updateStringParameter(parameterName: string, value: string): void {}
|
||||
updateColorParameter(parameterName: string, value: number): void {}
|
||||
getColorParameter(parameterName: string): number {
|
||||
return 0;
|
||||
}
|
||||
updateBooleanParameter(parameterName: string, value: boolean): void {}
|
||||
})();
|
||||
}
|
||||
})()
|
||||
);
|
||||
}
|
@@ -1,373 +0,0 @@
|
||||
namespace gdjs {
|
||||
export interface Object3DDataContent {
|
||||
width: float;
|
||||
height: float;
|
||||
depth: float;
|
||||
}
|
||||
/** Base parameters for {@link gdjs.RuntimeObject3D} */
|
||||
export interface Object3DData extends ObjectData {
|
||||
/** The base parameters of the RuntimeObject3D */
|
||||
content: Object3DDataContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for 3D custom objects.
|
||||
*/
|
||||
export class CustomRuntimeObject3D
|
||||
extends gdjs.CustomRuntimeObject
|
||||
implements gdjs.Base3DHandler {
|
||||
/**
|
||||
* Position on the Z axis.
|
||||
*/
|
||||
private _z: float = 0;
|
||||
private _minZ: float = 0;
|
||||
private _maxZ: float = 0;
|
||||
private _scaleZ: float = 1;
|
||||
private _flippedZ: boolean = false;
|
||||
/**
|
||||
* Euler angle with the `ZYX` order.
|
||||
*
|
||||
* Note that `_rotationZ` is `angle` from `gdjs.RuntimeObject`.
|
||||
*/
|
||||
private _rotationX: float = 0;
|
||||
/**
|
||||
* Euler angle with the `ZYX` order.
|
||||
*
|
||||
* Note that `_rotationZ` is `angle` from `gdjs.RuntimeObject`.
|
||||
*/
|
||||
private _rotationY: float = 0;
|
||||
private _customCenterZ: float = 0;
|
||||
private static _temporaryVector = new THREE.Vector3();
|
||||
|
||||
constructor(
|
||||
parent: gdjs.RuntimeInstanceContainer,
|
||||
objectData: Object3DData & CustomObjectConfiguration
|
||||
) {
|
||||
super(parent, objectData);
|
||||
this._renderer.reinitialize(this, parent);
|
||||
}
|
||||
|
||||
protected _createRender() {
|
||||
const parent = this._runtimeScene;
|
||||
return new gdjs.CustomRuntimeObject3DRenderer(
|
||||
this,
|
||||
this._instanceContainer,
|
||||
parent
|
||||
);
|
||||
}
|
||||
|
||||
protected _reinitializeRenderer(): void {
|
||||
this.getRenderer().reinitialize(this, this.getParent());
|
||||
}
|
||||
|
||||
getRenderer(): gdjs.CustomRuntimeObject3DRenderer {
|
||||
return super.getRenderer() as gdjs.CustomRuntimeObject3DRenderer;
|
||||
}
|
||||
|
||||
get3DRendererObject() {
|
||||
// It can't be null because Three.js is always loaded
|
||||
// when a custom 3D object is used.
|
||||
return this.getRenderer().get3DRendererObject()!;
|
||||
}
|
||||
|
||||
extraInitializationFromInitialInstance(initialInstanceData: InstanceData) {
|
||||
super.extraInitializationFromInitialInstance(initialInstanceData);
|
||||
if (initialInstanceData.depth !== undefined)
|
||||
this.setDepth(initialInstanceData.depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object position on the Z axis.
|
||||
*/
|
||||
setZ(z: float): void {
|
||||
if (z === this._z) return;
|
||||
this._z = z;
|
||||
this.getRenderer().updatePosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object position on the Z axis.
|
||||
*/
|
||||
getZ(): float {
|
||||
return this._z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Z position of the rendered object.
|
||||
*
|
||||
* For most objects, this will returns the same value as getZ(). But if the
|
||||
* object has an origin that is not the same as the point (0,0,0) of the
|
||||
* object displayed, getDrawableZ will differ.
|
||||
*
|
||||
* @return The Z position of the rendered object.
|
||||
*/
|
||||
getDrawableZ(): float {
|
||||
if (this._isUntransformedHitBoxesDirty) {
|
||||
this._updateUntransformedHitBoxes();
|
||||
}
|
||||
return this._z + this._minZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Z position of the object center, **relative to the object Z
|
||||
* position** (`getDrawableX`).
|
||||
*
|
||||
* Use `getCenterZInScene` to get the position of the center in the scene.
|
||||
*
|
||||
* @return the Z position of the object center, relative to
|
||||
* `getDrawableZ()`.
|
||||
*/
|
||||
getCenterZ(): float {
|
||||
return this.getDepth() / 2;
|
||||
}
|
||||
|
||||
getCenterZInScene(): float {
|
||||
return this.getDrawableZ() + this.getCenterZ();
|
||||
}
|
||||
|
||||
setCenterZInScene(z: float): void {
|
||||
this.setZ(z + this._z - (this.getDrawableZ() + this.getCenterZ()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bottom Z of the object.
|
||||
* Rotations around X and Y are not taken into account.
|
||||
*/
|
||||
getUnrotatedAABBMinZ(): number {
|
||||
return this.getDrawableZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the top Z of the object.
|
||||
* Rotations around X and Y are not taken into account.
|
||||
*/
|
||||
getUnrotatedAABBMaxZ(): number {
|
||||
return this.getDrawableZ() + this.getDepth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object rotation on the X axis.
|
||||
*
|
||||
* This is an Euler angle. Objects use the `ZYX` order.
|
||||
*/
|
||||
setRotationX(angle: float): void {
|
||||
this._rotationX = angle;
|
||||
this.getRenderer().updateRotation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object rotation on the Y axis.
|
||||
*
|
||||
* This is an Euler angle. Objects use the `ZYX` order.
|
||||
*/
|
||||
setRotationY(angle: float): void {
|
||||
this._rotationY = angle;
|
||||
this.getRenderer().updateRotation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object rotation on the X axis.
|
||||
*
|
||||
* This is an Euler angle. Objects use the `ZYX` order.
|
||||
*/
|
||||
getRotationX(): float {
|
||||
return this._rotationX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object rotation on the Y axis.
|
||||
*
|
||||
* This is an Euler angle. Objects use the `ZYX` order.
|
||||
*/
|
||||
getRotationY(): float {
|
||||
return this._rotationY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the object around the scene x axis at its center.
|
||||
* @param deltaAngle the rotation angle
|
||||
*/
|
||||
turnAroundX(deltaAngle: float): void {
|
||||
const axisX = gdjs.CustomRuntimeObject3D._temporaryVector;
|
||||
axisX.set(1, 0, 0);
|
||||
|
||||
const mesh = this.get3DRendererObject();
|
||||
mesh.rotateOnWorldAxis(axisX, gdjs.toRad(deltaAngle));
|
||||
this._rotationX = gdjs.toDegrees(mesh.rotation.x);
|
||||
this._rotationY = gdjs.toDegrees(mesh.rotation.y);
|
||||
this.setAngle(gdjs.toDegrees(mesh.rotation.z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the object around the scene y axis at its center.
|
||||
* @param deltaAngle the rotation angle
|
||||
*/
|
||||
turnAroundY(deltaAngle: float): void {
|
||||
const axisY = gdjs.CustomRuntimeObject3D._temporaryVector;
|
||||
axisY.set(0, 1, 0);
|
||||
|
||||
const mesh = this.get3DRendererObject();
|
||||
mesh.rotateOnWorldAxis(axisY, gdjs.toRad(deltaAngle));
|
||||
this._rotationX = gdjs.toDegrees(mesh.rotation.x);
|
||||
this._rotationY = gdjs.toDegrees(mesh.rotation.y);
|
||||
this.setAngle(gdjs.toDegrees(mesh.rotation.z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the object around the scene z axis at its center.
|
||||
* @param deltaAngle the rotation angle
|
||||
*/
|
||||
turnAroundZ(deltaAngle: float): void {
|
||||
const axisZ = gdjs.CustomRuntimeObject3D._temporaryVector;
|
||||
axisZ.set(0, 0, 1);
|
||||
|
||||
const mesh = this.get3DRendererObject();
|
||||
mesh.rotateOnWorldAxis(axisZ, gdjs.toRad(deltaAngle));
|
||||
this._rotationX = gdjs.toDegrees(mesh.rotation.x);
|
||||
this._rotationY = gdjs.toDegrees(mesh.rotation.y);
|
||||
this.setAngle(gdjs.toDegrees(mesh.rotation.z));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the internal width of the object according to its children.
|
||||
*/
|
||||
getUnscaledDepth(): float {
|
||||
if (this._isUntransformedHitBoxesDirty) {
|
||||
this._updateUntransformedHitBoxes();
|
||||
}
|
||||
return this._maxZ - this._minZ;
|
||||
}
|
||||
|
||||
_updateUntransformedHitBoxes(): void {
|
||||
super._updateUntransformedHitBoxes();
|
||||
|
||||
let minZ = Number.MAX_VALUE;
|
||||
let maxZ = -Number.MAX_VALUE;
|
||||
for (const childInstance of this._instanceContainer.getAdhocListOfAllInstances()) {
|
||||
if (!childInstance.isIncludedInParentCollisionMask()) {
|
||||
continue;
|
||||
}
|
||||
if (!gdjs.Base3DHandler.is3D(childInstance)) {
|
||||
continue;
|
||||
}
|
||||
minZ = Math.min(minZ, childInstance.getUnrotatedAABBMinZ());
|
||||
maxZ = Math.max(maxZ, childInstance.getUnrotatedAABBMaxZ());
|
||||
}
|
||||
if (minZ === Number.MAX_VALUE) {
|
||||
// The unscaled size can't be 0 because setWidth and setHeight wouldn't
|
||||
// have any effect.
|
||||
minZ = 0;
|
||||
maxZ = 1;
|
||||
}
|
||||
this._minZ = minZ;
|
||||
this._maxZ = maxZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns the center Z from the local origin (0;0).
|
||||
*/
|
||||
getUnscaledCenterZ(): float {
|
||||
if (this.hasCustomRotationCenter()) {
|
||||
return this._customCenterZ;
|
||||
}
|
||||
if (this._isUntransformedHitBoxesDirty) {
|
||||
this._updateUntransformedHitBoxes();
|
||||
}
|
||||
return (this._minZ + this._maxZ) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* The center of rotation is defined relatively to the origin (the object
|
||||
* position).
|
||||
* This avoids the center to move when children push the bounds.
|
||||
*
|
||||
* When no custom center is defined, it will move
|
||||
* to stay at the center of the children bounds.
|
||||
*
|
||||
* @param x coordinate of the custom center
|
||||
* @param y coordinate of the custom center
|
||||
*/
|
||||
setRotationCenter3D(x: float, y: float, z: float) {
|
||||
this._customCenterZ = z;
|
||||
this.setRotationCenter(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object size on the Z axis (called "depth").
|
||||
*/
|
||||
getDepth(): float {
|
||||
return this.getUnscaledDepth() * this.getScaleZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object size on the Z axis (called "depth").
|
||||
*/
|
||||
setDepth(depth: float): void {
|
||||
const unscaledDepth = this.getUnscaledDepth();
|
||||
if (unscaledDepth !== 0) {
|
||||
this.setScaleZ(depth / unscaledDepth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the scale on X, Y and Z axis of the object.
|
||||
*
|
||||
* @param newScale The new scale (must be greater than 0).
|
||||
*/
|
||||
setScale(newScale: number): void {
|
||||
super.setScale(newScale);
|
||||
this.setScaleZ(newScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the scale on Z axis of the object (changing its height).
|
||||
*
|
||||
* @param newScale The new scale (must be greater than 0).
|
||||
*/
|
||||
setScaleZ(newScale: number): void {
|
||||
if (newScale < 0) {
|
||||
newScale = 0;
|
||||
}
|
||||
if (newScale === Math.abs(this._scaleZ)) {
|
||||
return;
|
||||
}
|
||||
this._scaleZ = newScale * (this._flippedZ ? -1 : 1);
|
||||
this.getRenderer().updateSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scale of the object (or the geometric average of X, Y and Z scale in case they are different).
|
||||
*
|
||||
* @return the scale of the object (or the geometric average of X, Y and Z scale in case they are different).
|
||||
*/
|
||||
getScale(): number {
|
||||
const scaleX = this.getScaleX();
|
||||
const scaleY = this.getScaleY();
|
||||
const scaleZ = this.getScaleZ();
|
||||
return scaleX === scaleY && scaleX === scaleZ
|
||||
? scaleX
|
||||
: Math.pow(scaleX * scaleY * scaleZ, 1 / 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scale of the object on Z axis.
|
||||
*
|
||||
* @return the scale of the object on Z axis
|
||||
*/
|
||||
getScaleZ(): float {
|
||||
return Math.abs(this._scaleZ);
|
||||
}
|
||||
|
||||
flipZ(enable: boolean) {
|
||||
if (enable === this._flippedZ) {
|
||||
return;
|
||||
}
|
||||
this._flippedZ = enable;
|
||||
this.getRenderer().updateSize();
|
||||
}
|
||||
|
||||
isFlippedZ(): boolean {
|
||||
return this._flippedZ;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,135 +0,0 @@
|
||||
namespace gdjs {
|
||||
/**
|
||||
* The renderer for a {@link gdjs.CustomRuntimeObject3D} using Three.js.
|
||||
*/
|
||||
export class CustomRuntimeObject3DRenderer
|
||||
implements gdjs.RuntimeInstanceContainerRenderer {
|
||||
_object: gdjs.CustomRuntimeObject3D;
|
||||
_instanceContainer: gdjs.CustomRuntimeObjectInstanceContainer;
|
||||
_isContainerDirty: boolean = true;
|
||||
_threeGroup: THREE.Group;
|
||||
|
||||
constructor(
|
||||
object: gdjs.CustomRuntimeObject3D,
|
||||
instanceContainer: gdjs.CustomRuntimeObjectInstanceContainer,
|
||||
parent: gdjs.RuntimeInstanceContainer
|
||||
) {
|
||||
this._object = object;
|
||||
this._instanceContainer = instanceContainer;
|
||||
|
||||
this._threeGroup = new THREE.Group();
|
||||
this._threeGroup.rotation.order = 'ZYX';
|
||||
|
||||
const layer = parent.getLayer('');
|
||||
if (layer) {
|
||||
layer.getRenderer().add3DRendererObject(this._threeGroup);
|
||||
}
|
||||
}
|
||||
|
||||
get3DRendererObject(): THREE.Object3D {
|
||||
return this._threeGroup;
|
||||
}
|
||||
|
||||
getRendererObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
reinitialize(
|
||||
object: gdjs.CustomRuntimeObject3D,
|
||||
parent: gdjs.RuntimeInstanceContainer
|
||||
) {
|
||||
this._object = object;
|
||||
this._isContainerDirty = true;
|
||||
const layer = parent.getLayer('');
|
||||
if (layer) {
|
||||
layer.getRenderer().add3DRendererObject(this._threeGroup);
|
||||
}
|
||||
}
|
||||
|
||||
_updateThreeGroup() {
|
||||
const threeObject3D = this.get3DRendererObject();
|
||||
|
||||
const scaleX = this._object.getScaleX();
|
||||
const scaleY = this._object.getScaleY();
|
||||
const scaleZ = this._object.getScaleZ();
|
||||
const pivotX = this._object.getUnscaledCenterX() * scaleX;
|
||||
const pivotY = this._object.getUnscaledCenterY() * scaleY;
|
||||
const pivotZ = this._object.getUnscaledCenterZ() * scaleZ;
|
||||
|
||||
threeObject3D.rotation.set(
|
||||
gdjs.toRad(this._object.getRotationX()),
|
||||
gdjs.toRad(this._object.getRotationY()),
|
||||
gdjs.toRad(this._object.angle)
|
||||
);
|
||||
|
||||
threeObject3D.position.set(
|
||||
this._object.isFlippedX() ? pivotX : -pivotX,
|
||||
this._object.isFlippedY() ? pivotY : -pivotY,
|
||||
this._object.isFlippedZ() ? pivotZ : -pivotZ
|
||||
);
|
||||
threeObject3D.position.applyEuler(threeObject3D.rotation);
|
||||
threeObject3D.position.x += this._object.getX() + pivotX;
|
||||
threeObject3D.position.y += this._object.getY() + pivotY;
|
||||
threeObject3D.position.z += this._object.getZ() + pivotZ;
|
||||
|
||||
threeObject3D.scale.set(
|
||||
this._object.isFlippedX() ? -scaleX : scaleX,
|
||||
this._object.isFlippedY() ? -scaleY : scaleY,
|
||||
this._object.isFlippedZ() ? -scaleZ : scaleZ
|
||||
);
|
||||
|
||||
threeObject3D.visible = !this._object.hidden;
|
||||
|
||||
this._isContainerDirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to make sure the object is ready to be rendered.
|
||||
*/
|
||||
ensureUpToDate() {
|
||||
if (this._isContainerDirty) {
|
||||
this._updateThreeGroup();
|
||||
}
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this._isContainerDirty = true;
|
||||
}
|
||||
|
||||
updateX(): void {
|
||||
this._isContainerDirty = true;
|
||||
}
|
||||
|
||||
updateY(): void {
|
||||
this._isContainerDirty = true;
|
||||
}
|
||||
|
||||
updateAngle(): void {
|
||||
this._isContainerDirty = true;
|
||||
}
|
||||
|
||||
updatePosition() {
|
||||
this._isContainerDirty = true;
|
||||
}
|
||||
|
||||
updateRotation() {
|
||||
this._isContainerDirty = true;
|
||||
}
|
||||
|
||||
updateSize() {
|
||||
this._isContainerDirty = true;
|
||||
}
|
||||
|
||||
updateVisibility(): void {
|
||||
this._threeGroup.visible = !this._object.hidden;
|
||||
}
|
||||
|
||||
updateOpacity(): void {
|
||||
// Opacity is not handled by 3D custom objects.
|
||||
}
|
||||
|
||||
setLayerIndex(layer: gdjs.RuntimeLayer, index: float): void {
|
||||
// Layers are not handled for 3D custom objects.
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,74 +0,0 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator(
|
||||
'Scene3D::Exposure',
|
||||
new (class implements gdjs.PixiFiltersTools.FilterCreator {
|
||||
makeFilter(
|
||||
target: EffectsTarget,
|
||||
effectData: EffectData
|
||||
): gdjs.PixiFiltersTools.Filter {
|
||||
if (typeof THREE === 'undefined') {
|
||||
return new gdjs.PixiFiltersTools.EmptyFilter();
|
||||
}
|
||||
return new (class implements gdjs.PixiFiltersTools.Filter {
|
||||
shaderPass: THREE_ADDONS.ShaderPass;
|
||||
_isEnabled: boolean;
|
||||
|
||||
constructor() {
|
||||
this.shaderPass = new THREE_ADDONS.ShaderPass(
|
||||
THREE_ADDONS.ExposureShader
|
||||
);
|
||||
this._isEnabled = false;
|
||||
}
|
||||
|
||||
isEnabled(target: EffectsTarget): boolean {
|
||||
return this._isEnabled;
|
||||
}
|
||||
setEnabled(target: EffectsTarget, enabled: boolean): boolean {
|
||||
if (this._isEnabled === enabled) {
|
||||
return true;
|
||||
}
|
||||
if (enabled) {
|
||||
return this.applyEffect(target);
|
||||
} else {
|
||||
return this.removeEffect(target);
|
||||
}
|
||||
}
|
||||
applyEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().addPostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = true;
|
||||
return true;
|
||||
}
|
||||
removeEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().removePostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = false;
|
||||
return true;
|
||||
}
|
||||
updatePreRender(target: gdjs.EffectsTarget): any {}
|
||||
updateDoubleParameter(parameterName: string, value: number): void {
|
||||
if (parameterName === 'exposure') {
|
||||
this.shaderPass.uniforms[parameterName].value = value;
|
||||
}
|
||||
}
|
||||
getDoubleParameter(parameterName: string): number {
|
||||
if (parameterName === 'exposure') {
|
||||
return this.shaderPass.uniforms[parameterName].value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
updateStringParameter(parameterName: string, value: string): void {}
|
||||
updateColorParameter(parameterName: string, value: number): void {}
|
||||
getColorParameter(parameterName: string): number {
|
||||
return 0;
|
||||
}
|
||||
updateBooleanParameter(parameterName: string, value: boolean): void {}
|
||||
})();
|
||||
}
|
||||
})()
|
||||
);
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
namespace gdjs {
|
||||
gdjs.PixiFiltersTools.registerFilterCreator(
|
||||
'Scene3D::HueAndSaturation',
|
||||
new (class implements gdjs.PixiFiltersTools.FilterCreator {
|
||||
makeFilter(
|
||||
target: EffectsTarget,
|
||||
effectData: EffectData
|
||||
): gdjs.PixiFiltersTools.Filter {
|
||||
if (typeof THREE === 'undefined') {
|
||||
return new gdjs.PixiFiltersTools.EmptyFilter();
|
||||
}
|
||||
return new (class implements gdjs.PixiFiltersTools.Filter {
|
||||
shaderPass: THREE_ADDONS.ShaderPass;
|
||||
_isEnabled: boolean;
|
||||
|
||||
constructor() {
|
||||
this.shaderPass = new THREE_ADDONS.ShaderPass(
|
||||
THREE_ADDONS.HueSaturationShader
|
||||
);
|
||||
this._isEnabled = false;
|
||||
}
|
||||
|
||||
isEnabled(target: EffectsTarget): boolean {
|
||||
return this._isEnabled;
|
||||
}
|
||||
setEnabled(target: EffectsTarget, enabled: boolean): boolean {
|
||||
if (this._isEnabled === enabled) {
|
||||
return true;
|
||||
}
|
||||
if (enabled) {
|
||||
return this.applyEffect(target);
|
||||
} else {
|
||||
return this.removeEffect(target);
|
||||
}
|
||||
}
|
||||
applyEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().addPostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = true;
|
||||
return true;
|
||||
}
|
||||
removeEffect(target: EffectsTarget): boolean {
|
||||
if (!(target instanceof gdjs.Layer)) {
|
||||
return false;
|
||||
}
|
||||
target.getRenderer().removePostProcessingPass(this.shaderPass);
|
||||
this._isEnabled = false;
|
||||
return true;
|
||||
}
|
||||
updatePreRender(target: gdjs.EffectsTarget): any {}
|
||||
updateDoubleParameter(parameterName: string, value: number): void {
|
||||
if (parameterName === 'hue') {
|
||||
this.shaderPass.uniforms[parameterName].value = value / 180;
|
||||
}
|
||||
if (parameterName === 'saturation') {
|
||||
this.shaderPass.uniforms[parameterName].value = value;
|
||||
}
|
||||
}
|
||||
getDoubleParameter(parameterName: string): number {
|
||||
if (parameterName === 'hue') {
|
||||
return this.shaderPass.uniforms[parameterName].value * 180;
|
||||
}
|
||||
if (parameterName === 'saturation') {
|
||||
return this.shaderPass.uniforms[parameterName].value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
updateStringParameter(parameterName: string, value: string): void {}
|
||||
updateColorParameter(parameterName: string, value: number): void {}
|
||||
getColorParameter(parameterName: string): number {
|
||||
return 0;
|
||||
}
|
||||
updateBooleanParameter(parameterName: string, value: boolean): void {}
|
||||
})();
|
||||
}
|
||||
})()
|
||||
);
|
||||
}
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -803,6 +811,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
const Cube3DObject = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
Cube3DObject.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -851,6 +860,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
Cube3DObject.getProperties = function (objectContent) {
|
||||
const objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -1090,6 +1100,7 @@ module.exports = {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError
|
||||
Cube3DObject.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -1101,6 +1112,7 @@ module.exports = {
|
||||
return false;
|
||||
};
|
||||
|
||||
// $FlowExpectedError
|
||||
Cube3DObject.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -1653,7 +1665,7 @@ module.exports = {
|
||||
'Change the camera rotation to look at an object. The camera top always face the screen.'
|
||||
),
|
||||
_('Change the camera rotation of _PARAM2_ to look at _PARAM1_'),
|
||||
_('Layers and cameras'),
|
||||
_("Layers and cameras"),
|
||||
'res/conditions/3d_box.svg',
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
@@ -1927,86 +1939,6 @@ module.exports = {
|
||||
.setType('number')
|
||||
.setGroup(_('Orientation'));
|
||||
}
|
||||
{
|
||||
const effect = extension
|
||||
.addEffect('HueAndSaturation')
|
||||
.setFullName(_('Hue and saturation'))
|
||||
.setDescription(_('Adjust hue and saturation.'))
|
||||
.markAsNotWorkingForObjects()
|
||||
.markAsOnlyWorkingFor3D()
|
||||
.addIncludeFile('Extensions/3D/HueAndSaturationEffect.js');
|
||||
const properties = effect.getProperties();
|
||||
properties
|
||||
.getOrCreate('hue')
|
||||
.setValue('0')
|
||||
.setLabel(_('Hue in degrees (between -180 and 180)'))
|
||||
.setType('number');
|
||||
properties
|
||||
.getOrCreate('saturation')
|
||||
.setValue('0')
|
||||
.setLabel(_('Saturation (between -1 and 1)'))
|
||||
.setType('number');
|
||||
}
|
||||
{
|
||||
const effect = extension
|
||||
.addEffect('Exposure')
|
||||
.setFullName(_('Exposure'))
|
||||
.setDescription(_('Adjust exposure.'))
|
||||
.markAsNotWorkingForObjects()
|
||||
.markAsOnlyWorkingFor3D()
|
||||
.addIncludeFile('Extensions/3D/ExposureEffect.js');
|
||||
const properties = effect.getProperties();
|
||||
properties
|
||||
.getOrCreate('exposure')
|
||||
.setValue('1')
|
||||
.setLabel(_('Exposure (positive value)'))
|
||||
.setType('number');
|
||||
}
|
||||
{
|
||||
const effect = extension
|
||||
.addEffect('Bloom')
|
||||
.setFullName(_('Bloom'))
|
||||
.setDescription(_('Apply a bloom effect.'))
|
||||
.markAsNotWorkingForObjects()
|
||||
.markAsOnlyWorkingFor3D()
|
||||
.addIncludeFile('Extensions/3D/BloomEffect.js');
|
||||
const properties = effect.getProperties();
|
||||
properties
|
||||
.getOrCreate('strength')
|
||||
.setValue('1')
|
||||
.setLabel(_('Strength (between 0 and 3)'))
|
||||
.setType('number');
|
||||
properties
|
||||
.getOrCreate('radius')
|
||||
.setValue('0')
|
||||
.setLabel(_('Radius (between 0 and 1)'))
|
||||
.setType('number');
|
||||
properties
|
||||
.getOrCreate('threshold')
|
||||
.setValue('0')
|
||||
.setLabel(_('Threshold (between 0 and 1)'))
|
||||
.setType('number');
|
||||
}
|
||||
{
|
||||
const effect = extension
|
||||
.addEffect('BrightnessAndContrast')
|
||||
.setFullName(_('Brightness and contrast.'))
|
||||
.setDescription(_('Adjust brightness and contrast.'))
|
||||
.markAsNotWorkingForObjects()
|
||||
.markAsOnlyWorkingFor3D()
|
||||
.addIncludeFile('Extensions/3D/BrightnessAndContrastEffect.js');
|
||||
const properties = effect.getProperties();
|
||||
properties
|
||||
.getOrCreate('brightness')
|
||||
.setValue('0')
|
||||
.setLabel(_('Brightness (between -1 and 1)'))
|
||||
.setType('number');
|
||||
properties
|
||||
.getOrCreate('contrast')
|
||||
.setValue('0')
|
||||
.setLabel(_('Contrast (between -1 and 1)'))
|
||||
.setType('number');
|
||||
}
|
||||
// Don't forget to update the alert condition in Model3DEditor.js when
|
||||
// adding a new light.
|
||||
|
||||
@@ -2022,7 +1954,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
@@ -2030,13 +1965,17 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations: function (objectsEditorService) {},
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {},
|
||||
/**
|
||||
* Register renderers for instance of objects on the scene editor.
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const Rendered3DInstance = objectsRenderingService.Rendered3DInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
@@ -2044,25 +1983,39 @@ module.exports = {
|
||||
const THREE_ADDONS = objectsRenderingService.THREE_ADDONS;
|
||||
|
||||
const materialIndexToFaceIndex = {
|
||||
// $FlowFixMe
|
||||
0: 3,
|
||||
// $FlowFixMe
|
||||
1: 2,
|
||||
// $FlowFixMe
|
||||
2: 5,
|
||||
// $FlowFixMe
|
||||
3: 4,
|
||||
// $FlowFixMe
|
||||
4: 0,
|
||||
// $FlowFixMe
|
||||
5: 1,
|
||||
};
|
||||
|
||||
const noRepeatTextureVertexIndexToUvMapping = {
|
||||
// $FlowFixMe
|
||||
0: [0, 0],
|
||||
// $FlowFixMe
|
||||
1: [1, 0],
|
||||
// $FlowFixMe
|
||||
2: [0, 1],
|
||||
// $FlowFixMe
|
||||
3: [1, 1],
|
||||
};
|
||||
|
||||
const noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ = {
|
||||
// $FlowFixMe
|
||||
0: [0, 1],
|
||||
// $FlowFixMe
|
||||
1: [0, 0],
|
||||
// $FlowFixMe
|
||||
2: [1, 1],
|
||||
// $FlowFixMe
|
||||
3: [1, 0],
|
||||
};
|
||||
|
||||
@@ -2108,11 +2061,6 @@ module.exports = {
|
||||
};
|
||||
|
||||
class RenderedCube3DObject2DInstance extends RenderedInstance {
|
||||
/** @type {number} */
|
||||
_centerX = 0;
|
||||
/** @type {number} */
|
||||
_centerY = 0;
|
||||
|
||||
constructor(
|
||||
project,
|
||||
layout,
|
||||
@@ -2129,9 +2077,10 @@ module.exports = {
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
|
||||
// Name of the resource that is rendered.
|
||||
// If no face is visible, this will be null.
|
||||
/**
|
||||
* Name of the resource that is rendered.
|
||||
* If no face is visible, this will be null.
|
||||
*/
|
||||
this._renderedResourceName = undefined;
|
||||
const properties = associatedObjectConfiguration.getProperties();
|
||||
this._defaultWidth = parseFloat(properties.get('width').getValue());
|
||||
@@ -2161,9 +2110,12 @@ module.exports = {
|
||||
}
|
||||
|
||||
static getThumbnail(project, resourcesLoader, objectConfiguration) {
|
||||
const textureResourceName = RenderedCube3DObject2DInstance._getResourceNameToDisplay(
|
||||
objectConfiguration
|
||||
);
|
||||
const instance = this._instance;
|
||||
|
||||
const textureResourceName =
|
||||
RenderedCube3DObject2DInstance._getResourceNameToDisplay(
|
||||
objectConfiguration
|
||||
);
|
||||
if (textureResourceName) {
|
||||
return resourcesLoader.getResourceFullUrl(
|
||||
project,
|
||||
@@ -2175,18 +2127,20 @@ module.exports = {
|
||||
}
|
||||
|
||||
updateTextureIfNeeded() {
|
||||
const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay(
|
||||
this._associatedObjectConfiguration
|
||||
);
|
||||
const textureName =
|
||||
RenderedCube3DObject2DInstance._getResourceNameToDisplay(
|
||||
this._associatedObjectConfiguration
|
||||
);
|
||||
if (textureName === this._renderedResourceName) return;
|
||||
|
||||
this.updateTexture();
|
||||
}
|
||||
|
||||
updateTexture() {
|
||||
const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay(
|
||||
this._associatedObjectConfiguration
|
||||
);
|
||||
const textureName =
|
||||
RenderedCube3DObject2DInstance._getResourceNameToDisplay(
|
||||
this._associatedObjectConfiguration
|
||||
);
|
||||
|
||||
if (!textureName) {
|
||||
this._renderFallbackObject = true;
|
||||
@@ -2444,9 +2398,10 @@ module.exports = {
|
||||
continue;
|
||||
}
|
||||
|
||||
const shouldRepeatTexture = this._shouldRepeatTextureOnFace[
|
||||
materialIndexToFaceIndex[materialIndex]
|
||||
];
|
||||
const shouldRepeatTexture =
|
||||
this._shouldRepeatTextureOnFace[
|
||||
materialIndexToFaceIndex[materialIndex]
|
||||
];
|
||||
|
||||
const shouldOrientateFacesTowardsY = this._facesOrientation === 'Y';
|
||||
|
||||
@@ -2481,16 +2436,13 @@ module.exports = {
|
||||
}
|
||||
} else {
|
||||
if (shouldOrientateFacesTowardsY) {
|
||||
[x, y] = noRepeatTextureVertexIndexToUvMapping[
|
||||
vertexIndex % 4
|
||||
];
|
||||
[x, y] =
|
||||
noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4];
|
||||
} else {
|
||||
[
|
||||
x,
|
||||
y,
|
||||
] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
|
||||
vertexIndex % 4
|
||||
];
|
||||
[x, y] =
|
||||
noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
|
||||
vertexIndex % 4
|
||||
];
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2520,16 +2472,13 @@ module.exports = {
|
||||
}
|
||||
} else {
|
||||
if (shouldOrientateFacesTowardsY) {
|
||||
[x, y] = noRepeatTextureVertexIndexToUvMapping[
|
||||
vertexIndex % 4
|
||||
];
|
||||
[x, y] =
|
||||
noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4];
|
||||
} else {
|
||||
[
|
||||
x,
|
||||
y,
|
||||
] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
|
||||
vertexIndex % 4
|
||||
];
|
||||
[x, y] =
|
||||
noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
|
||||
vertexIndex % 4
|
||||
];
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
@@ -2675,8 +2624,6 @@ module.exports = {
|
||||
RenderedCube3DObject3DInstance
|
||||
);
|
||||
|
||||
const epsilon = 1 / (1 << 16);
|
||||
|
||||
class Model3DRendered2DInstance extends RenderedInstance {
|
||||
_modelOriginPoint = [0, 0, 0];
|
||||
|
||||
@@ -2799,24 +2746,13 @@ module.exports = {
|
||||
);
|
||||
threeObject.updateMatrixWorld(true);
|
||||
const boundingBox = new THREE.Box3().setFromObject(threeObject);
|
||||
const shouldKeepModelOrigin = !this._originPoint;
|
||||
if (shouldKeepModelOrigin) {
|
||||
// Keep the origin as part of the model.
|
||||
// For instance, a model can be 1 face of a cube and we want to keep the
|
||||
// inside as part of the object even if it's just void.
|
||||
// It also avoids to have the origin outside of the object box.
|
||||
boundingBox.expandByPoint(new THREE.Vector3(0, 0, 0));
|
||||
}
|
||||
|
||||
const modelWidth = boundingBox.max.x - boundingBox.min.x;
|
||||
const modelHeight = boundingBox.max.y - boundingBox.min.y;
|
||||
const modelDepth = boundingBox.max.z - boundingBox.min.z;
|
||||
this._modelOriginPoint[0] =
|
||||
modelWidth < epsilon ? 0 : -boundingBox.min.x / modelWidth;
|
||||
this._modelOriginPoint[1] =
|
||||
modelHeight < epsilon ? 0 : -boundingBox.min.y / modelHeight;
|
||||
this._modelOriginPoint[2] =
|
||||
modelDepth < epsilon ? 0 : -boundingBox.min.z / modelDepth;
|
||||
this._modelOriginPoint[0] = -boundingBox.min.x / modelWidth;
|
||||
this._modelOriginPoint[1] = -boundingBox.min.y / modelHeight;
|
||||
this._modelOriginPoint[2] = -boundingBox.min.z / modelDepth;
|
||||
|
||||
// The model is flipped on Y axis.
|
||||
this._modelOriginPoint[1] = 1 - this._modelOriginPoint[1];
|
||||
@@ -2825,10 +2761,19 @@ module.exports = {
|
||||
const centerPoint = this._centerPoint;
|
||||
if (centerPoint) {
|
||||
threeObject.position.set(
|
||||
-(boundingBox.min.x + modelWidth * centerPoint[0]),
|
||||
-(
|
||||
boundingBox.min.x +
|
||||
(boundingBox.max.x - boundingBox.min.x) * centerPoint[0]
|
||||
),
|
||||
// The model is flipped on Y axis.
|
||||
-(boundingBox.min.y + modelHeight * (1 - centerPoint[1])),
|
||||
-(boundingBox.min.z + modelDepth * centerPoint[2])
|
||||
-(
|
||||
boundingBox.min.y +
|
||||
(boundingBox.max.y - boundingBox.min.y) * (1 - centerPoint[1])
|
||||
),
|
||||
-(
|
||||
boundingBox.min.z +
|
||||
(boundingBox.max.z - boundingBox.min.z) * centerPoint[2]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2841,9 +2786,9 @@ module.exports = {
|
||||
);
|
||||
|
||||
// Stretch the model in a 1x1x1 cube.
|
||||
const scaleX = modelWidth < epsilon ? 1 : 1 / modelWidth;
|
||||
const scaleY = modelHeight < epsilon ? 1 : 1 / modelHeight;
|
||||
const scaleZ = modelDepth < epsilon ? 1 : 1 / modelDepth;
|
||||
const scaleX = 1 / modelWidth;
|
||||
const scaleY = 1 / modelHeight;
|
||||
const scaleZ = 1 / modelDepth;
|
||||
|
||||
const scaleMatrix = new THREE.Matrix4();
|
||||
// Flip on Y because the Y axis is on the opposite side of direct basis.
|
||||
@@ -2854,22 +2799,10 @@ module.exports = {
|
||||
|
||||
if (keepAspectRatio) {
|
||||
// Reduce the object dimensions to keep aspect ratio.
|
||||
const widthRatio =
|
||||
modelWidth < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalWidth / modelWidth;
|
||||
const heightRatio =
|
||||
modelHeight < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalHeight / modelHeight;
|
||||
const depthRatio =
|
||||
modelDepth < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalDepth / modelDepth;
|
||||
let scaleRatio = Math.min(widthRatio, heightRatio, depthRatio);
|
||||
if (!Number.isFinite(scaleRatio)) {
|
||||
scaleRatio = 1;
|
||||
}
|
||||
const widthRatio = originalWidth / modelWidth;
|
||||
const heightRatio = originalHeight / modelHeight;
|
||||
const depthRatio = originalDepth / modelDepth;
|
||||
const scaleRatio = Math.min(widthRatio, heightRatio, depthRatio);
|
||||
|
||||
this._defaultWidth = scaleRatio * modelWidth;
|
||||
this._defaultHeight = scaleRatio * modelHeight;
|
||||
@@ -3021,11 +2954,6 @@ module.exports = {
|
||||
return this.getHeight() * originPoint[1];
|
||||
}
|
||||
|
||||
getOriginZ() {
|
||||
const originPoint = this.getOriginPoint();
|
||||
return this.getDepth() * originPoint[2];
|
||||
}
|
||||
|
||||
getCenterX() {
|
||||
const centerPoint = this.getCenterPoint();
|
||||
return this.getWidth() * centerPoint[0];
|
||||
@@ -3036,11 +2964,6 @@ module.exports = {
|
||||
return this.getHeight() * centerPoint[1];
|
||||
}
|
||||
|
||||
getCenterZ() {
|
||||
const centerPoint = this.getCenterPoint();
|
||||
return this.getDepth() * centerPoint[2];
|
||||
}
|
||||
|
||||
getOriginPoint() {
|
||||
return this._originPoint || this._modelOriginPoint;
|
||||
}
|
||||
@@ -3067,24 +2990,12 @@ module.exports = {
|
||||
threeObject.updateMatrixWorld(true);
|
||||
const boundingBox = new THREE.Box3().setFromObject(threeObject);
|
||||
|
||||
const shouldKeepModelOrigin = !this._originPoint;
|
||||
if (shouldKeepModelOrigin) {
|
||||
// Keep the origin as part of the model.
|
||||
// For instance, a model can be 1 face of a cube and we want to keep the
|
||||
// inside as part of the object even if it's just void.
|
||||
// It also avoids to have the origin outside of the object box.
|
||||
boundingBox.expandByPoint(new THREE.Vector3(0, 0, 0));
|
||||
}
|
||||
|
||||
const modelWidth = boundingBox.max.x - boundingBox.min.x;
|
||||
const modelHeight = boundingBox.max.y - boundingBox.min.y;
|
||||
const modelDepth = boundingBox.max.z - boundingBox.min.z;
|
||||
this._modelOriginPoint[0] =
|
||||
modelWidth < epsilon ? 0 : -boundingBox.min.x / modelWidth;
|
||||
this._modelOriginPoint[1] =
|
||||
modelHeight < epsilon ? 0 : -boundingBox.min.y / modelHeight;
|
||||
this._modelOriginPoint[2] =
|
||||
modelDepth < epsilon ? 0 : -boundingBox.min.z / modelDepth;
|
||||
this._modelOriginPoint[0] = -boundingBox.min.x / modelWidth;
|
||||
this._modelOriginPoint[1] = -boundingBox.min.y / modelHeight;
|
||||
this._modelOriginPoint[2] = -boundingBox.min.z / modelDepth;
|
||||
|
||||
// The model is flipped on Y axis.
|
||||
this._modelOriginPoint[1] = 1 - this._modelOriginPoint[1];
|
||||
@@ -3093,10 +3004,19 @@ module.exports = {
|
||||
const centerPoint = this._centerPoint;
|
||||
if (centerPoint) {
|
||||
threeObject.position.set(
|
||||
-(boundingBox.min.x + modelWidth * centerPoint[0]),
|
||||
-(
|
||||
boundingBox.min.x +
|
||||
(boundingBox.max.x - boundingBox.min.x) * centerPoint[0]
|
||||
),
|
||||
// The model is flipped on Y axis.
|
||||
-(boundingBox.min.y + modelHeight * (1 - centerPoint[1])),
|
||||
-(boundingBox.min.z + modelDepth * centerPoint[2])
|
||||
-(
|
||||
boundingBox.min.y +
|
||||
(boundingBox.max.y - boundingBox.min.y) * (1 - centerPoint[1])
|
||||
),
|
||||
-(
|
||||
boundingBox.min.z +
|
||||
(boundingBox.max.z - boundingBox.min.z) * centerPoint[2]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3109,9 +3029,9 @@ module.exports = {
|
||||
);
|
||||
|
||||
// Stretch the model in a 1x1x1 cube.
|
||||
const scaleX = modelWidth < epsilon ? 1 : 1 / modelWidth;
|
||||
const scaleY = modelHeight < epsilon ? 1 : 1 / modelHeight;
|
||||
const scaleZ = modelDepth < epsilon ? 1 : 1 / modelDepth;
|
||||
const scaleX = 1 / modelWidth;
|
||||
const scaleY = 1 / modelHeight;
|
||||
const scaleZ = 1 / modelDepth;
|
||||
|
||||
const scaleMatrix = new THREE.Matrix4();
|
||||
// Flip on Y because the Y axis is on the opposite side of direct basis.
|
||||
@@ -3122,22 +3042,10 @@ module.exports = {
|
||||
|
||||
if (keepAspectRatio) {
|
||||
// Reduce the object dimensions to keep aspect ratio.
|
||||
const widthRatio =
|
||||
modelWidth < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalWidth / modelWidth;
|
||||
const heightRatio =
|
||||
modelHeight < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalHeight / modelHeight;
|
||||
const depthRatio =
|
||||
modelDepth < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalDepth / modelDepth;
|
||||
let scaleRatio = Math.min(widthRatio, heightRatio, depthRatio);
|
||||
if (!Number.isFinite(scaleRatio)) {
|
||||
scaleRatio = 1;
|
||||
}
|
||||
const widthRatio = originalWidth / modelWidth;
|
||||
const heightRatio = originalHeight / modelHeight;
|
||||
const depthRatio = originalDepth / modelDepth;
|
||||
const scaleRatio = Math.min(widthRatio, heightRatio, depthRatio);
|
||||
|
||||
this._defaultWidth = scaleRatio * modelWidth;
|
||||
this._defaultHeight = scaleRatio * modelHeight;
|
||||
|
@@ -1,8 +1,6 @@
|
||||
namespace gdjs {
|
||||
type FloatPoint3D = [float, float, float];
|
||||
|
||||
const epsilon = 1 / (1 << 16);
|
||||
|
||||
const removeMetalness = (material: THREE.Material): void => {
|
||||
//@ts-ignore
|
||||
if (material.metalness) {
|
||||
@@ -11,7 +9,7 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
const removeMetalnessFromMesh = (node: THREE.Object3D) => {
|
||||
const removeMetalnessFromMesh = (node: THREE.Object3D<THREE.Event>) => {
|
||||
const mesh = node as THREE.Mesh;
|
||||
if (!mesh.material) {
|
||||
return;
|
||||
@@ -25,8 +23,9 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
const traverseToRemoveMetalnessFromMeshes = (node: THREE.Object3D) =>
|
||||
node.traverse(removeMetalnessFromMesh);
|
||||
const traverseToRemoveMetalnessFromMeshes = (
|
||||
node: THREE.Object3D<THREE.Event>
|
||||
) => node.traverse(removeMetalnessFromMesh);
|
||||
|
||||
const convertToBasicMaterial = (
|
||||
material: THREE.Material
|
||||
@@ -45,7 +44,7 @@ namespace gdjs {
|
||||
return basicMaterial;
|
||||
};
|
||||
|
||||
const setBasicMaterialTo = (node: THREE.Object3D): void => {
|
||||
const setBasicMaterialTo = (node: THREE.Object3D<THREE.Event>): void => {
|
||||
const mesh = node as THREE.Mesh;
|
||||
if (!mesh.material) {
|
||||
return;
|
||||
@@ -60,8 +59,9 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
const traverseToSetBasicMaterialFromMeshes = (node: THREE.Object3D) =>
|
||||
node.traverse(setBasicMaterialTo);
|
||||
const traverseToSetBasicMaterialFromMeshes = (
|
||||
node: THREE.Object3D<THREE.Event>
|
||||
) => node.traverse(setBasicMaterialTo);
|
||||
|
||||
class Model3DRuntimeObject3DRenderer extends gdjs.RuntimeObject3DRenderer {
|
||||
private _model3DRuntimeObject: gdjs.Model3DRuntimeObject;
|
||||
@@ -158,24 +158,12 @@ namespace gdjs {
|
||||
threeObject.updateMatrixWorld(true);
|
||||
const boundingBox = new THREE.Box3().setFromObject(threeObject);
|
||||
|
||||
const shouldKeepModelOrigin = !this._model3DRuntimeObject._originPoint;
|
||||
if (shouldKeepModelOrigin) {
|
||||
// Keep the origin as part of the model.
|
||||
// For instance, a model can be 1 face of a cube and we want to keep the
|
||||
// inside as part of the object even if it's just void.
|
||||
// It also avoids to have the origin outside of the object box.
|
||||
boundingBox.expandByPoint(new THREE.Vector3(0, 0, 0));
|
||||
}
|
||||
|
||||
const modelWidth = boundingBox.max.x - boundingBox.min.x;
|
||||
const modelHeight = boundingBox.max.y - boundingBox.min.y;
|
||||
const modelDepth = boundingBox.max.z - boundingBox.min.z;
|
||||
this._modelOriginPoint[0] =
|
||||
modelWidth < epsilon ? 0 : -boundingBox.min.x / modelWidth;
|
||||
this._modelOriginPoint[1] =
|
||||
modelHeight < epsilon ? 0 : -boundingBox.min.y / modelHeight;
|
||||
this._modelOriginPoint[2] =
|
||||
modelDepth < epsilon ? 0 : -boundingBox.min.z / modelDepth;
|
||||
this._modelOriginPoint[0] = -boundingBox.min.x / modelWidth;
|
||||
this._modelOriginPoint[1] = -boundingBox.min.y / modelHeight;
|
||||
this._modelOriginPoint[2] = -boundingBox.min.z / modelDepth;
|
||||
|
||||
// The model is flipped on Y axis.
|
||||
this._modelOriginPoint[1] = 1 - this._modelOriginPoint[1];
|
||||
@@ -184,10 +172,19 @@ namespace gdjs {
|
||||
const centerPoint = this._model3DRuntimeObject._centerPoint;
|
||||
if (centerPoint) {
|
||||
threeObject.position.set(
|
||||
-(boundingBox.min.x + modelWidth * centerPoint[0]),
|
||||
-(
|
||||
boundingBox.min.x +
|
||||
(boundingBox.max.x - boundingBox.min.x) * centerPoint[0]
|
||||
),
|
||||
// The model is flipped on Y axis.
|
||||
-(boundingBox.min.y + modelHeight * (1 - centerPoint[1])),
|
||||
-(boundingBox.min.z + modelDepth * centerPoint[2])
|
||||
-(
|
||||
boundingBox.min.y +
|
||||
(boundingBox.max.y - boundingBox.min.y) * (1 - centerPoint[1])
|
||||
),
|
||||
-(
|
||||
boundingBox.min.z +
|
||||
(boundingBox.max.z - boundingBox.min.z) * centerPoint[2]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -200,9 +197,9 @@ namespace gdjs {
|
||||
);
|
||||
|
||||
// Stretch the model in a 1x1x1 cube.
|
||||
const scaleX = modelWidth < epsilon ? 1 : 1 / modelWidth;
|
||||
const scaleY = modelHeight < epsilon ? 1 : 1 / modelHeight;
|
||||
const scaleZ = modelDepth < epsilon ? 1 : 1 / modelDepth;
|
||||
const scaleX = 1 / modelWidth;
|
||||
const scaleY = 1 / modelHeight;
|
||||
const scaleZ = 1 / modelDepth;
|
||||
|
||||
const scaleMatrix = new THREE.Matrix4();
|
||||
// Flip on Y because the Y axis is on the opposite side of direct basis.
|
||||
@@ -213,22 +210,10 @@ namespace gdjs {
|
||||
|
||||
if (keepAspectRatio) {
|
||||
// Reduce the object dimensions to keep aspect ratio.
|
||||
const widthRatio =
|
||||
modelWidth < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalWidth / modelWidth;
|
||||
const heightRatio =
|
||||
modelHeight < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalHeight / modelHeight;
|
||||
const depthRatio =
|
||||
modelDepth < epsilon
|
||||
? Number.POSITIVE_INFINITY
|
||||
: originalDepth / modelDepth;
|
||||
let scaleRatio = Math.min(widthRatio, heightRatio, depthRatio);
|
||||
if (!Number.isFinite(scaleRatio)) {
|
||||
scaleRatio = 1;
|
||||
}
|
||||
const widthRatio = originalWidth / modelWidth;
|
||||
const heightRatio = originalHeight / modelHeight;
|
||||
const depthRatio = originalDepth / modelDepth;
|
||||
const scaleRatio = Math.min(widthRatio, heightRatio, depthRatio);
|
||||
|
||||
this._object._setOriginalWidth(scaleRatio * modelWidth);
|
||||
this._object._setOriginalHeight(scaleRatio * modelHeight);
|
||||
|
@@ -11,11 +11,12 @@ namespace gdjs {
|
||||
const layer = runtimeScene.getLayer(layerName);
|
||||
const layerRenderer = layer.getRenderer();
|
||||
const threeCamera = layerRenderer.getThreeCamera();
|
||||
const fov = threeCamera
|
||||
? threeCamera instanceof THREE.OrthographicCamera
|
||||
const fov =
|
||||
threeCamera instanceof THREE.OrthographicCamera
|
||||
? null
|
||||
: threeCamera.fov
|
||||
: assumedFovIn2D;
|
||||
: threeCamera
|
||||
? threeCamera.fov
|
||||
: assumedFovIn2D;
|
||||
return layer.getCameraZ(fov, cameraIndex);
|
||||
};
|
||||
|
||||
@@ -28,11 +29,12 @@ namespace gdjs {
|
||||
const layer = runtimeScene.getLayer(layerName);
|
||||
const layerRenderer = layer.getRenderer();
|
||||
const threeCamera = layerRenderer.getThreeCamera();
|
||||
const fov = threeCamera
|
||||
? threeCamera instanceof THREE.OrthographicCamera
|
||||
const fov =
|
||||
threeCamera instanceof THREE.OrthographicCamera
|
||||
? null
|
||||
: threeCamera.fov
|
||||
: assumedFovIn2D;
|
||||
: threeCamera
|
||||
? threeCamera.fov
|
||||
: assumedFovIn2D;
|
||||
layer.setCameraZ(z, fov, cameraIndex);
|
||||
};
|
||||
|
||||
@@ -221,11 +223,10 @@ namespace gdjs {
|
||||
const layerRenderer = layer.getRenderer();
|
||||
|
||||
const threeCamera = layerRenderer.getThreeCamera();
|
||||
return threeCamera
|
||||
? threeCamera instanceof THREE.OrthographicCamera
|
||||
? 0
|
||||
: threeCamera.fov
|
||||
: assumedFovIn2D;
|
||||
if (!threeCamera) return assumedFovIn2D;
|
||||
return threeCamera instanceof THREE.OrthographicCamera
|
||||
? 0
|
||||
: threeCamera.fov;
|
||||
};
|
||||
|
||||
export const setFov = (
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -781,7 +789,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,11 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -709,7 +710,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,11 +12,20 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
const stringifyOptions = (options) => '["' + options.join('","') + '"]';
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -34,6 +42,7 @@ module.exports = {
|
||||
.setIcon('JsPlatform/Extensions/bbcode32.png');
|
||||
|
||||
var objectBBText = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError
|
||||
objectBBText.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -50,6 +59,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError
|
||||
objectBBText.getProperties = function (objectContent) {
|
||||
const objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -116,8 +126,7 @@ module.exports = {
|
||||
};
|
||||
objectBBText.setRawJSONContent(
|
||||
JSON.stringify({
|
||||
text:
|
||||
'[b]bold[/b] [i]italic[/i] [size=15]smaller[/size] [font=times]times[/font] font\n[spacing=12]spaced out[/spacing]\n[outline=yellow]outlined[/outline] [shadow=red]DropShadow[/shadow] ',
|
||||
text: '[b]bold[/b] [i]italic[/i] [size=15]smaller[/size] [font=times]times[/font] font\n[spacing=12]spaced out[/spacing]\n[outline=yellow]outlined[/outline] [shadow=red]DropShadow[/shadow] ',
|
||||
opacity: 255,
|
||||
fontSize: 20,
|
||||
visible: true,
|
||||
@@ -128,6 +137,7 @@ module.exports = {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError
|
||||
objectBBText.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -138,6 +148,7 @@ module.exports = {
|
||||
) {
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError
|
||||
objectBBText.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -212,9 +223,10 @@ module.exports = {
|
||||
parameterType === 'string' ||
|
||||
parameterType === 'stringWithSelector'
|
||||
) {
|
||||
const parameterOptions = gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
property.paramLabel
|
||||
);
|
||||
const parameterOptions =
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
property.paramLabel
|
||||
);
|
||||
if (property.options) {
|
||||
parameterOptions.setTypeExtraInfo(
|
||||
stringifyOptions(property.options)
|
||||
@@ -264,9 +276,10 @@ module.exports = {
|
||||
parameterType === 'number' ||
|
||||
parameterType === 'stringWithSelector'
|
||||
) {
|
||||
const parameterOptions = gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
property.paramLabel
|
||||
);
|
||||
const parameterOptions =
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
property.paramLabel
|
||||
);
|
||||
if (property.options) {
|
||||
parameterOptions.setTypeExtraInfo(
|
||||
stringifyOptions(property.options)
|
||||
@@ -423,21 +436,6 @@ module.exports = {
|
||||
|
||||
addSettersAndGettersToObject(object, setterAndGetterProperties, 'BBText');
|
||||
|
||||
object
|
||||
.addAction(
|
||||
`SetFontFamily2`,
|
||||
_('Font family'),
|
||||
_('Set font family'),
|
||||
_('Set the font of _PARAM0_ to _PARAM1_'),
|
||||
'',
|
||||
'res/actions/font24.png',
|
||||
'res/actions/font24.png'
|
||||
)
|
||||
.addParameter('object', 'BBText', 'BBText', false)
|
||||
.addParameter('fontResource', _('Font family'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName(`setFontFamily`);
|
||||
|
||||
const actions = object.getAllActions();
|
||||
const conditions = object.getAllConditions();
|
||||
const expressions = object.getAllExpressions();
|
||||
@@ -445,9 +443,6 @@ module.exports = {
|
||||
actions.get('BBText::SetOpacity').setHidden();
|
||||
conditions.get('BBText::IsOpacity').setHidden();
|
||||
expressions.get('GetOpacity').setHidden();
|
||||
// Action deprecated because it's using the `string` type instead of the more
|
||||
// user-friendly `fontResource` type.
|
||||
actions.get('BBText::SetFontFamily').setHidden();
|
||||
|
||||
return extension;
|
||||
},
|
||||
@@ -462,7 +457,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
@@ -470,7 +468,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations: function (objectsEditorService) {
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {
|
||||
objectsEditorService.registerEditorConfiguration(
|
||||
'BBText::BBText',
|
||||
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
|
||||
@@ -483,8 +483,11 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
const MultiStyleText = objectsRenderingService.requireModule(
|
||||
__dirname,
|
||||
'pixi-multistyle-text/dist/pixi-multistyle-text.umd'
|
||||
@@ -493,145 +496,150 @@ module.exports = {
|
||||
/**
|
||||
* Renderer for instances of BBText inside the IDE.
|
||||
*
|
||||
* @extends RenderedInstance
|
||||
* @extends RenderedBBTextInstance
|
||||
* @class RenderedBBTextInstance
|
||||
* @constructor
|
||||
*/
|
||||
class RenderedBBTextInstance extends RenderedInstance {
|
||||
constructor(
|
||||
function RenderedBBTextInstance(
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
RenderedInstance.call(
|
||||
this,
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
super(
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
);
|
||||
|
||||
const bbTextStyles = {
|
||||
default: {
|
||||
// Use a default font family the time for the resource font to be loaded.
|
||||
fontFamily: 'Arial',
|
||||
fontSize: '24px',
|
||||
fill: '#cccccc',
|
||||
tagStyle: 'bbcode',
|
||||
wordWrap: true,
|
||||
wordWrapWidth: 250, // This value is the default wrapping width of the runtime object.
|
||||
align: 'left',
|
||||
},
|
||||
};
|
||||
const bbTextStyles = {
|
||||
default: {
|
||||
// Use a default font family the time for the resource font to be loaded.
|
||||
fontFamily: 'Arial',
|
||||
fontSize: '24px',
|
||||
fill: '#cccccc',
|
||||
tagStyle: 'bbcode',
|
||||
wordWrap: true,
|
||||
wordWrapWidth: 250, // This value is the default wrapping width of the runtime object.
|
||||
align: 'left',
|
||||
},
|
||||
};
|
||||
|
||||
this._pixiObject = new MultiStyleText('', bbTextStyles);
|
||||
this._pixiObject = new MultiStyleText('', bbTextStyles);
|
||||
|
||||
this._pixiObject.anchor.x = 0.5;
|
||||
this._pixiObject.anchor.y = 0.5;
|
||||
this._pixiContainer.addChild(this._pixiObject);
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path to the thumbnail of the specified object.
|
||||
*/
|
||||
static getThumbnail(project, resourcesLoader, objectConfiguration) {
|
||||
return 'JsPlatform/Extensions/bbcode24.png';
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called to update the PIXI object on the scene editor
|
||||
*/
|
||||
update() {
|
||||
const properties = this._associatedObjectConfiguration.getProperties();
|
||||
|
||||
const rawText = properties.get('text').getValue();
|
||||
if (rawText !== this._pixiObject.text) {
|
||||
this._pixiObject.text = rawText;
|
||||
}
|
||||
|
||||
const opacity = +properties.get('opacity').getValue();
|
||||
this._pixiObject.alpha = opacity / 255;
|
||||
|
||||
const color = properties.get('color').getValue();
|
||||
this._pixiObject.textStyles.default.fill = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
color
|
||||
);
|
||||
|
||||
const fontSize = properties.get('fontSize').getValue();
|
||||
this._pixiObject.textStyles.default.fontSize = `${fontSize}px`;
|
||||
|
||||
const fontResourceName = properties.get('fontFamily').getValue();
|
||||
|
||||
if (this._fontResourceName !== fontResourceName) {
|
||||
this._fontResourceName = fontResourceName;
|
||||
|
||||
this._pixiResourcesLoader
|
||||
.loadFontFamily(this._project, fontResourceName)
|
||||
.then((fontFamily) => {
|
||||
// Once the font is loaded, we can use the given fontFamily.
|
||||
this._pixiObject.textStyles.default.fontFamily = fontFamily;
|
||||
this._pixiObject.dirty = true;
|
||||
})
|
||||
.catch((err) => {
|
||||
// Ignore errors
|
||||
console.warn(
|
||||
'Unable to load font family for RenderedBBTextInstance',
|
||||
err
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const wordWrap = properties.get('wordWrap').getValue() === 'true';
|
||||
if (wordWrap !== this._pixiObject._style.wordWrap) {
|
||||
this._pixiObject._style.wordWrap = wordWrap;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
const align = properties.get('align').getValue();
|
||||
if (align !== this._pixiObject._style.align) {
|
||||
this._pixiObject._style.align = align;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
this._pixiObject.position.x =
|
||||
this._instance.getX() + this._pixiObject.width / 2;
|
||||
this._pixiObject.position.y =
|
||||
this._instance.getY() + this._pixiObject.height / 2;
|
||||
this._pixiObject.rotation = RenderedInstance.toRad(
|
||||
this._instance.getAngle()
|
||||
);
|
||||
|
||||
if (this._instance.hasCustomSize() && this._pixiObject) {
|
||||
const customWidth = this.getCustomWidth();
|
||||
if (
|
||||
this._pixiObject &&
|
||||
this._pixiObject._style.wordWrapWidth !== customWidth
|
||||
) {
|
||||
this._pixiObject._style.wordWrapWidth = customWidth;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the width of the instance, when it's not resized.
|
||||
*/
|
||||
getDefaultWidth() {
|
||||
return this._pixiObject.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the height of the instance, when it's not resized.
|
||||
*/
|
||||
getDefaultHeight() {
|
||||
return this._pixiObject.height;
|
||||
}
|
||||
this._pixiObject.anchor.x = 0.5;
|
||||
this._pixiObject.anchor.y = 0.5;
|
||||
this._pixiContainer.addChild(this._pixiObject);
|
||||
this.update();
|
||||
}
|
||||
RenderedBBTextInstance.prototype = Object.create(
|
||||
RenderedInstance.prototype
|
||||
);
|
||||
|
||||
/**
|
||||
* Return the path to the thumbnail of the specified object.
|
||||
*/
|
||||
RenderedBBTextInstance.getThumbnail = function (
|
||||
project,
|
||||
resourcesLoader,
|
||||
objectConfiguration
|
||||
) {
|
||||
return 'JsPlatform/Extensions/bbcode24.png';
|
||||
};
|
||||
|
||||
/**
|
||||
* This is called to update the PIXI object on the scene editor
|
||||
*/
|
||||
RenderedBBTextInstance.prototype.update = function () {
|
||||
const properties = this._associatedObjectConfiguration.getProperties();
|
||||
|
||||
const rawText = properties.get('text').getValue();
|
||||
if (rawText !== this._pixiObject.text) {
|
||||
this._pixiObject.text = rawText;
|
||||
}
|
||||
|
||||
const opacity = properties.get('opacity').getValue();
|
||||
this._pixiObject.alpha = opacity / 255;
|
||||
|
||||
const color = properties.get('color').getValue();
|
||||
this._pixiObject.textStyles.default.fill =
|
||||
objectsRenderingService.rgbOrHexToHexNumber(color);
|
||||
|
||||
const fontSize = properties.get('fontSize').getValue();
|
||||
this._pixiObject.textStyles.default.fontSize = `${fontSize}px`;
|
||||
|
||||
const fontResourceName = properties.get('fontFamily').getValue();
|
||||
|
||||
if (this._fontResourceName !== fontResourceName) {
|
||||
this._fontResourceName = fontResourceName;
|
||||
|
||||
this._pixiResourcesLoader
|
||||
.loadFontFamily(this._project, fontResourceName)
|
||||
.then((fontFamily) => {
|
||||
// Once the font is loaded, we can use the given fontFamily.
|
||||
this._pixiObject.textStyles.default.fontFamily = fontFamily;
|
||||
this._pixiObject.dirty = true;
|
||||
})
|
||||
.catch((err) => {
|
||||
// Ignore errors
|
||||
console.warn(
|
||||
'Unable to load font family for RenderedBBTextInstance',
|
||||
err
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const wordWrap = properties.get('wordWrap').getValue() === 'true';
|
||||
if (wordWrap !== this._pixiObject._style.wordWrap) {
|
||||
this._pixiObject._style.wordWrap = wordWrap;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
const align = properties.get('align').getValue();
|
||||
if (align !== this._pixiObject._style.align) {
|
||||
this._pixiObject._style.align = align;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
this._pixiObject.position.x =
|
||||
this._instance.getX() + this._pixiObject.width / 2;
|
||||
this._pixiObject.position.y =
|
||||
this._instance.getY() + this._pixiObject.height / 2;
|
||||
this._pixiObject.rotation = RenderedInstance.toRad(
|
||||
this._instance.getAngle()
|
||||
);
|
||||
|
||||
if (this._instance.hasCustomSize() && this._pixiObject) {
|
||||
const customWidth = this.getCustomWidth();
|
||||
if (
|
||||
this._pixiObject &&
|
||||
this._pixiObject._style.wordWrapWidth !== customWidth
|
||||
) {
|
||||
this._pixiObject._style.wordWrapWidth = customWidth;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the width of the instance, when it's not resized.
|
||||
*/
|
||||
RenderedBBTextInstance.prototype.getDefaultWidth = function () {
|
||||
return this._pixiObject.width;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the height of the instance, when it's not resized.
|
||||
*/
|
||||
RenderedBBTextInstance.prototype.getDefaultHeight = function () {
|
||||
return this._pixiObject.height;
|
||||
};
|
||||
|
||||
objectsRenderingService.registerInstanceRenderer(
|
||||
'BBText::BBText',
|
||||
|
@@ -141,7 +141,6 @@ namespace gdjs {
|
||||
setBBText(text): void {
|
||||
this._text = text;
|
||||
this._renderer.updateText();
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -34,6 +42,7 @@ module.exports = {
|
||||
.setIcon('JsPlatform/Extensions/bitmapfont32.png');
|
||||
|
||||
const bitmapTextObject = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError
|
||||
bitmapTextObject.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -50,6 +59,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError
|
||||
bitmapTextObject.getProperties = function (objectContent) {
|
||||
const objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -117,8 +127,7 @@ module.exports = {
|
||||
};
|
||||
bitmapTextObject.setRawJSONContent(
|
||||
JSON.stringify({
|
||||
text:
|
||||
'This text use the default bitmap font.\nUse a custom Bitmap Font to create your own texts.',
|
||||
text: 'This text use the default bitmap font.\nUse a custom Bitmap Font to create your own texts.',
|
||||
opacity: 255,
|
||||
scale: 1,
|
||||
fontSize: 20,
|
||||
@@ -130,6 +139,7 @@ module.exports = {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError
|
||||
bitmapTextObject.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -140,6 +150,7 @@ module.exports = {
|
||||
) {
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError
|
||||
bitmapTextObject.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -165,7 +176,7 @@ module.exports = {
|
||||
'Extensions/BitmapText/bitmaptextruntimeobject-pixi-renderer.js'
|
||||
)
|
||||
.setCategoryFullName(_('Text'))
|
||||
.addDefaultBehavior('TextContainerCapability::TextContainerBehavior')
|
||||
.addDefaultBehavior("TextContainerCapability::TextContainerBehavior")
|
||||
.addDefaultBehavior('EffectCapability::EffectBehavior')
|
||||
.addDefaultBehavior('OpacityCapability::OpacityBehavior')
|
||||
.addDefaultBehavior('ScalableCapability::ScalableBehavior');
|
||||
@@ -316,33 +327,33 @@ 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
|
||||
.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(
|
||||
@@ -440,7 +451,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
@@ -448,7 +462,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations: function (objectsEditorService) {
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {
|
||||
objectsEditorService.registerEditorConfiguration(
|
||||
'BitmapText::BitmapTextObject',
|
||||
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
|
||||
@@ -461,7 +477,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
|
||||
@@ -631,144 +649,156 @@ module.exports = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the path to the thumbnail of the specified object.
|
||||
* This is called to update the PIXI object on the scene editor
|
||||
* Renderer for instances of BitmapText inside the IDE.
|
||||
*
|
||||
* @extends RenderedBitmapTextInstance
|
||||
* @class RenderedBitmapTextInstance
|
||||
* @constructor
|
||||
*/
|
||||
class RenderedBitmapTextInstance extends RenderedInstance {
|
||||
static getThumbnail(project, resourcesLoader, objectConfiguration) {
|
||||
return 'JsPlatform/Extensions/bitmapfont24.png';
|
||||
}
|
||||
|
||||
constructor(
|
||||
function RenderedBitmapTextInstance(
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
RenderedInstance.call(
|
||||
this,
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
super(
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
);
|
||||
|
||||
// We'll track changes of the font to trigger the loading of the new font.
|
||||
this._currentBitmapFontResourceName = '';
|
||||
this._currentTextureAtlasResourceName = '';
|
||||
// We'll track changes of the font to trigger the loading of the new font.
|
||||
this._currentBitmapFontResourceName = '';
|
||||
this._currentTextureAtlasResourceName = '';
|
||||
|
||||
this._pixiObject = new PIXI.BitmapText('', {
|
||||
// Use a default font. The proper font will be loaded in `update` method.
|
||||
fontName: getDefaultBitmapFont().font,
|
||||
});
|
||||
this._pixiObject = new PIXI.BitmapText('', {
|
||||
// Use a default font. The proper font will be loaded in `update` method.
|
||||
fontName: getDefaultBitmapFont().font,
|
||||
});
|
||||
|
||||
this._pixiObject.anchor.x = 0.5;
|
||||
this._pixiObject.anchor.y = 0.5;
|
||||
this._pixiContainer.addChild(this._pixiObject);
|
||||
this.update();
|
||||
}
|
||||
|
||||
update() {
|
||||
const properties = this._associatedObjectConfiguration.getProperties();
|
||||
|
||||
// Update the rendered text properties (note: Pixi is only
|
||||
// applying changes if there were changed).
|
||||
const rawText = properties.get('text').getValue();
|
||||
this._pixiObject.text = rawText;
|
||||
|
||||
const opacity = +properties.get('opacity').getValue();
|
||||
this._pixiObject.alpha = opacity / 255;
|
||||
|
||||
const align = properties.get('align').getValue();
|
||||
this._pixiObject.align = align;
|
||||
|
||||
const color = properties.get('tint').getValue();
|
||||
this._pixiObject.tint = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
color
|
||||
);
|
||||
|
||||
const scale = +(properties.get('scale').getValue() || 1);
|
||||
this._pixiObject.scale.set(scale);
|
||||
|
||||
// Track the changes in font to load the new requested font.
|
||||
const bitmapFontResourceName = properties
|
||||
.get('bitmapFontResourceName')
|
||||
.getValue();
|
||||
const textureAtlasResourceName = properties
|
||||
.get('textureAtlasResourceName')
|
||||
.getValue();
|
||||
|
||||
if (
|
||||
this._currentBitmapFontResourceName !== bitmapFontResourceName ||
|
||||
this._currentTextureAtlasResourceName !== textureAtlasResourceName
|
||||
) {
|
||||
// Release the old font (if it was installed).
|
||||
releaseBitmapFont(this._pixiObject.fontName);
|
||||
|
||||
// Temporarily go back to the default font, as the PIXI.BitmapText
|
||||
// object does not support being displayed with a font not installed at all.
|
||||
// It will be replaced as soon as the proper font is loaded.
|
||||
this._pixiObject.fontName = getDefaultBitmapFont().font;
|
||||
|
||||
this._currentBitmapFontResourceName = bitmapFontResourceName;
|
||||
this._currentTextureAtlasResourceName = textureAtlasResourceName;
|
||||
obtainBitmapFont(
|
||||
this._pixiResourcesLoader,
|
||||
this._project,
|
||||
this._currentBitmapFontResourceName,
|
||||
this._currentTextureAtlasResourceName
|
||||
).then((bitmapFont) => {
|
||||
this._pixiObject.fontName = bitmapFont.font;
|
||||
this._pixiObject.fontSize = bitmapFont.size;
|
||||
this._pixiObject.dirty = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Set up the wrapping width if enabled.
|
||||
const wordWrap = properties.get('wordWrap').getValue() === 'true';
|
||||
if (wordWrap && this._instance.hasCustomSize()) {
|
||||
this._pixiObject.maxWidth =
|
||||
this.getCustomWidth() / this._pixiObject.scale.x;
|
||||
this._pixiObject.dirty = true;
|
||||
} else {
|
||||
this._pixiObject.maxWidth = 0;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
this._pixiObject.position.x =
|
||||
this._instance.getX() + (this._pixiObject.textWidth * scale) / 2;
|
||||
this._pixiObject.position.y =
|
||||
this._instance.getY() + (this._pixiObject.textHeight * scale) / 2;
|
||||
this._pixiObject.rotation = RenderedInstance.toRad(
|
||||
this._instance.getAngle()
|
||||
);
|
||||
}
|
||||
|
||||
onRemovedFromScene() {
|
||||
RenderedInstance.prototype.onRemovedFromScene.call(this);
|
||||
|
||||
const fontName = this._pixiObject.fontName;
|
||||
this._pixiObject.destroy();
|
||||
releaseBitmapFont(fontName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the width of the instance, when it's not resized.
|
||||
*/
|
||||
getDefaultWidth() {
|
||||
return this._pixiObject.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the height of the instance, when it's not resized.
|
||||
*/
|
||||
getDefaultHeight() {
|
||||
return this._pixiObject.height;
|
||||
}
|
||||
this._pixiObject.anchor.x = 0.5;
|
||||
this._pixiObject.anchor.y = 0.5;
|
||||
this._pixiContainer.addChild(this._pixiObject);
|
||||
this.update();
|
||||
}
|
||||
RenderedBitmapTextInstance.prototype = Object.create(
|
||||
RenderedInstance.prototype
|
||||
);
|
||||
|
||||
/**
|
||||
* Return the path to the thumbnail of the specified object.
|
||||
*/
|
||||
RenderedBitmapTextInstance.getThumbnail = function (
|
||||
project,
|
||||
resourcesLoader,
|
||||
objectConfiguration
|
||||
) {
|
||||
return 'JsPlatform/Extensions/bitmapfont24.png';
|
||||
};
|
||||
|
||||
// This is called to update the PIXI object on the scene editor
|
||||
RenderedBitmapTextInstance.prototype.update = function () {
|
||||
const properties = this._associatedObjectConfiguration.getProperties();
|
||||
|
||||
// Update the rendered text properties (note: Pixi is only
|
||||
// applying changes if there were changed).
|
||||
const rawText = properties.get('text').getValue();
|
||||
this._pixiObject.text = rawText;
|
||||
|
||||
const opacity = properties.get('opacity').getValue();
|
||||
this._pixiObject.alpha = opacity / 255;
|
||||
|
||||
const align = properties.get('align').getValue();
|
||||
this._pixiObject.align = align;
|
||||
|
||||
const color = properties.get('tint').getValue();
|
||||
this._pixiObject.tint =
|
||||
objectsRenderingService.rgbOrHexToHexNumber(color);
|
||||
|
||||
const scale = properties.get('scale').getValue() || 1;
|
||||
this._pixiObject.scale.set(scale);
|
||||
|
||||
// Track the changes in font to load the new requested font.
|
||||
const bitmapFontResourceName = properties
|
||||
.get('bitmapFontResourceName')
|
||||
.getValue();
|
||||
const textureAtlasResourceName = properties
|
||||
.get('textureAtlasResourceName')
|
||||
.getValue();
|
||||
|
||||
if (
|
||||
this._currentBitmapFontResourceName !== bitmapFontResourceName ||
|
||||
this._currentTextureAtlasResourceName !== textureAtlasResourceName
|
||||
) {
|
||||
// Release the old font (if it was installed).
|
||||
releaseBitmapFont(this._pixiObject.fontName);
|
||||
|
||||
// Temporarily go back to the default font, as the PIXI.BitmapText
|
||||
// object does not support being displayed with a font not installed at all.
|
||||
// It will be replaced as soon as the proper font is loaded.
|
||||
this._pixiObject.fontName = getDefaultBitmapFont().font;
|
||||
|
||||
this._currentBitmapFontResourceName = bitmapFontResourceName;
|
||||
this._currentTextureAtlasResourceName = textureAtlasResourceName;
|
||||
obtainBitmapFont(
|
||||
this._pixiResourcesLoader,
|
||||
this._project,
|
||||
this._currentBitmapFontResourceName,
|
||||
this._currentTextureAtlasResourceName
|
||||
).then((bitmapFont) => {
|
||||
this._pixiObject.fontName = bitmapFont.font;
|
||||
this._pixiObject.fontSize = bitmapFont.size;
|
||||
this._pixiObject.dirty = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Set up the wrapping width if enabled.
|
||||
const wordWrap = properties.get('wordWrap').getValue() === 'true';
|
||||
if (wordWrap && this._instance.hasCustomSize()) {
|
||||
this._pixiObject.maxWidth =
|
||||
this.getCustomWidth() / this._pixiObject.scale.x;
|
||||
this._pixiObject.dirty = true;
|
||||
} else {
|
||||
this._pixiObject.maxWidth = 0;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
this._pixiObject.position.x =
|
||||
this._instance.getX() + (this._pixiObject.textWidth * scale) / 2;
|
||||
this._pixiObject.position.y =
|
||||
this._instance.getY() + (this._pixiObject.textHeight * scale) / 2;
|
||||
this._pixiObject.rotation = RenderedInstance.toRad(
|
||||
this._instance.getAngle()
|
||||
);
|
||||
};
|
||||
|
||||
RenderedBitmapTextInstance.prototype.onRemovedFromScene = function () {
|
||||
RenderedInstance.prototype.onRemovedFromScene.call(this);
|
||||
|
||||
const fontName = this._pixiObject.fontName;
|
||||
this._pixiObject.destroy();
|
||||
releaseBitmapFont(fontName);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the width of the instance, when it's not resized.
|
||||
*/
|
||||
RenderedBitmapTextInstance.prototype.getDefaultWidth = function () {
|
||||
return this._pixiObject.width;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the height of the instance, when it's not resized.
|
||||
*/
|
||||
RenderedBitmapTextInstance.prototype.getDefaultHeight = function () {
|
||||
return this._pixiObject.height;
|
||||
};
|
||||
|
||||
objectsRenderingService.registerInstanceRenderer(
|
||||
'BitmapText::BitmapTextObject',
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -106,7 +114,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,389 +12,450 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function(_/*: (string) => string */, gd/*: libGDevelop */) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
'DeviceSensors',
|
||||
_('Device sensors'),
|
||||
_('Allow the game to access the sensors of a mobile device.'),
|
||||
'Matthias Meike',
|
||||
'Open source (MIT License)'
|
||||
)
|
||||
.setExtensionHelpPath('/all-features/device-sensors')
|
||||
.setCategory('Input');
|
||||
extension
|
||||
.addInstructionOrExpressionGroupMetadata(_('Device sensors'))
|
||||
.setIcon('JsPlatform/Extensions/orientation_active32.png');
|
||||
extension.setExtensionInformation(
|
||||
"DeviceSensors",
|
||||
_("Device sensors"),
|
||||
_(
|
||||
"Allow the game to access the sensors of a mobile device."
|
||||
),
|
||||
"Matthias Meike",
|
||||
"Open source (MIT License)"
|
||||
).setExtensionHelpPath("/all-features/device-sensors")
|
||||
.setCategory('Input');
|
||||
extension.addInstructionOrExpressionGroupMetadata(_("Device sensors"))
|
||||
.setIcon("JsPlatform/Extensions/orientation_active32.png");
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'OrientationSensorActive',
|
||||
_('Sensor active'),
|
||||
"OrientationSensorActive",
|
||||
_("Sensor active"),
|
||||
_(
|
||||
'The condition is true if the device orientation sensor is currently active'
|
||||
"The condition is true if the device orientation sensor is currently active"
|
||||
),
|
||||
_('Orientation sensor is active'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_active32.png',
|
||||
'JsPlatform/Extensions/orientation_active32.png'
|
||||
_("Orientation sensor is active"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_active32.png",
|
||||
"JsPlatform/Extensions/orientation_active32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.isActive');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.isActive");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'OrientationAlpha',
|
||||
_('Compare the value of orientation alpha'),
|
||||
_('Compare the value of orientation alpha. (Range: 0 to 360°)'),
|
||||
_('the orientation alpha'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_alpha32.png',
|
||||
'JsPlatform/Extensions/orientation_alpha32.png'
|
||||
"OrientationAlpha",
|
||||
_("Compare the value of orientation alpha"),
|
||||
_(
|
||||
"Compare the value of orientation alpha. (Range: 0 to 360°)"
|
||||
),
|
||||
_("the orientation alpha"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_alpha32.png",
|
||||
"JsPlatform/Extensions/orientation_alpha32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationAlpha');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationAlpha");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'OrientationBeta',
|
||||
_('Compare the value of orientation beta'),
|
||||
_('Compare the value of orientation beta. (Range: -180 to 180°)'),
|
||||
_('the orientation beta'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_beta32.png',
|
||||
'JsPlatform/Extensions/orientation_beta32.png'
|
||||
"OrientationBeta",
|
||||
_("Compare the value of orientation beta"),
|
||||
_(
|
||||
"Compare the value of orientation beta. (Range: -180 to 180°)"
|
||||
),
|
||||
_("the orientation beta"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_beta32.png",
|
||||
"JsPlatform/Extensions/orientation_beta32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationBeta');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationBeta");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'OrientationGamma',
|
||||
_('Compare the value of orientation gamma'),
|
||||
_('Compare the value of orientation gamma. (Range: -90 to 90°)'),
|
||||
_('the orientation gamma'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_gamma32.png',
|
||||
'JsPlatform/Extensions/orientation_gamma32.png'
|
||||
"OrientationGamma",
|
||||
_("Compare the value of orientation gamma"),
|
||||
_(
|
||||
"Compare the value of orientation gamma. (Range: -90 to 90°)"
|
||||
),
|
||||
_("the orientation gamma"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_gamma32.png",
|
||||
"JsPlatform/Extensions/orientation_gamma32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationGamma');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationGamma");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ActivateOrientationListener',
|
||||
_('Activate orientation sensor'),
|
||||
_('Activate the orientation sensor. (remember to turn it off again)'),
|
||||
_('Activate the orientation sensor.'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_active32.png',
|
||||
'JsPlatform/Extensions/orientation_active32.png'
|
||||
"ActivateOrientationListener",
|
||||
_("Activate orientation sensor"),
|
||||
_("Activate the orientation sensor. (remember to turn it off again)"),
|
||||
_("Activate the orientation sensor."),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_active32.png",
|
||||
"JsPlatform/Extensions/orientation_active32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName(
|
||||
'gdjs.deviceSensors.orientation.activateOrientationSensor'
|
||||
);
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.activateOrientationSensor");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'DeactivateOrientationListener',
|
||||
_('Deactivate orientation sensor'),
|
||||
_('Deactivate the orientation sensor.'),
|
||||
_('Deactivate the orientation sensor.'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_inactive32.png',
|
||||
'JsPlatform/Extensions/orientation_inactive32.png'
|
||||
"DeactivateOrientationListener",
|
||||
_("Deactivate orientation sensor"),
|
||||
_("Deactivate the orientation sensor."),
|
||||
_("Deactivate the orientation sensor."),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_inactive32.png",
|
||||
"JsPlatform/Extensions/orientation_inactive32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName(
|
||||
'gdjs.deviceSensors.orientation.deactivateOrientationSensor'
|
||||
);
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.deactivateOrientationSensor");
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'OrientationAbsolute',
|
||||
_('Is Absolute'),
|
||||
_('Get if the devices orientation is absolute and not relative'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_absolute16.png'
|
||||
"OrientationAbsolute",
|
||||
_("Is Absolute"),
|
||||
_("Get if the devices orientation is absolute and not relative"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_absolute16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationAbsolute');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationAbsolute");
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'OrientationAlpha',
|
||||
_('Alpha value'),
|
||||
_('Get the devices orientation Alpha (compass)'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_alpha16.png'
|
||||
"OrientationAlpha",
|
||||
_("Alpha value"),
|
||||
_("Get the devices orientation Alpha (compass)"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_alpha16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationAlpha');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationAlpha");
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'OrientationBeta',
|
||||
_('Beta value'),
|
||||
_('Get the devices orientation Beta'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_beta16.png'
|
||||
"OrientationBeta",
|
||||
_("Beta value"),
|
||||
_("Get the devices orientation Beta"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_beta16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationBeta');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationBeta");
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'OrientationGamma',
|
||||
_('Gamma value'),
|
||||
_('Get the devices orientation Gamma value'),
|
||||
_('Orientation'),
|
||||
'JsPlatform/Extensions/orientation_gamma16.png'
|
||||
"OrientationGamma",
|
||||
_("Gamma value"),
|
||||
_("Get the devices orientation Gamma value"),
|
||||
_("Orientation"),
|
||||
"JsPlatform/Extensions/orientation_gamma16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationGamma');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationGamma");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'MotionSensorActive',
|
||||
_('Sensor active'),
|
||||
"MotionSensorActive",
|
||||
_("Sensor active"),
|
||||
_(
|
||||
'The condition is true if the device motion sensor is currently active'
|
||||
"The condition is true if the device motion sensor is currently active"
|
||||
),
|
||||
_('Motion sensor is active'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_active32.png',
|
||||
'JsPlatform/Extensions/motion_active32.png'
|
||||
_("Motion sensor is active"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_active32.png",
|
||||
"JsPlatform/Extensions/motion_active32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.isActive');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.isActive");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'RotationAlpha',
|
||||
_('Compare the value of rotation alpha'),
|
||||
"RotationAlpha",
|
||||
_("Compare the value of rotation alpha"),
|
||||
_(
|
||||
'Compare the value of rotation alpha. (Note: few devices support this sensor)'
|
||||
"Compare the value of rotation alpha. (Note: few devices support this sensor)"
|
||||
),
|
||||
_('the rotation alpha'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_rotation_alpha32.png',
|
||||
'JsPlatform/Extensions/motion_rotation_alpha32.png'
|
||||
_("the rotation alpha"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_rotation_alpha32.png",
|
||||
"JsPlatform/Extensions/motion_rotation_alpha32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value (m/s²)'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getRotationAlpha');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getRotationAlpha");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'RotationBeta',
|
||||
_('Compare the value of rotation beta'),
|
||||
"RotationBeta",
|
||||
_("Compare the value of rotation beta"),
|
||||
_(
|
||||
'Compare the value of rotation beta. (Note: few devices support this sensor)'
|
||||
"Compare the value of rotation beta. (Note: few devices support this sensor)"
|
||||
),
|
||||
_('the rotation beta'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_rotation_beta32.png',
|
||||
'JsPlatform/Extensions/motion_rotation_beta32.png'
|
||||
_("the rotation beta"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_rotation_beta32.png",
|
||||
"JsPlatform/Extensions/motion_rotation_beta32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value (m/s²)'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getRotationBeta');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getRotationBeta");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'RotationGamma',
|
||||
_('Compare the value of rotation gamma'),
|
||||
"RotationGamma",
|
||||
_("Compare the value of rotation gamma"),
|
||||
_(
|
||||
'Compare the value of rotation gamma. (Note: few devices support this sensor)'
|
||||
"Compare the value of rotation gamma. (Note: few devices support this sensor)"
|
||||
),
|
||||
_('the rotation gamma'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_rotation_gamma32.png',
|
||||
'JsPlatform/Extensions/motion_rotation_gamma32.png'
|
||||
_("the rotation gamma"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_rotation_gamma32.png",
|
||||
"JsPlatform/Extensions/motion_rotation_gamma32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value (m/s²)'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getRotationGamma');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getRotationGamma");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'AccelerationX',
|
||||
_('Compare the value of acceleration on X-axis'),
|
||||
_('Compare the value of acceleration on the X-axis (m/s²).'),
|
||||
_('the acceleration X'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_acceleration_x32.png',
|
||||
'JsPlatform/Extensions/motion_acceleration_x32.png'
|
||||
"AccelerationX",
|
||||
_("Compare the value of acceleration on X-axis"),
|
||||
_(
|
||||
"Compare the value of acceleration on the X-axis (m/s²)."
|
||||
),
|
||||
_("the acceleration X"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_acceleration_x32.png",
|
||||
"JsPlatform/Extensions/motion_acceleration_x32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value (m/s²)'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationX');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationX");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'AccelerationY',
|
||||
_('Compare the value of acceleration on Y-axis'),
|
||||
_('Compare the value of acceleration on the Y-axis (m/s²).'),
|
||||
_('the acceleration Y'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_acceleration_y32.png',
|
||||
'JsPlatform/Extensions/motion_acceleration_y32.png'
|
||||
"AccelerationY",
|
||||
_("Compare the value of acceleration on Y-axis"),
|
||||
_(
|
||||
"Compare the value of acceleration on the Y-axis (m/s²)."
|
||||
),
|
||||
_("the acceleration Y"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_acceleration_y32.png",
|
||||
"JsPlatform/Extensions/motion_acceleration_y32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value (m/s²)'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationY');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationY");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addCondition(
|
||||
'AccelerationZ',
|
||||
_('Compare the value of acceleration on Z-axis'),
|
||||
_('Compare the value of acceleration on the Z-axis (m/s²).'),
|
||||
_('the acceleration Z'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_acceleration_z32.png',
|
||||
'JsPlatform/Extensions/motion_acceleration_z32.png'
|
||||
"AccelerationZ",
|
||||
_("Compare the value of acceleration on Z-axis"),
|
||||
_(
|
||||
"Compare the value of acceleration on the Z-axis (m/s²)."
|
||||
),
|
||||
_("the acceleration Z"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_acceleration_z32.png",
|
||||
"JsPlatform/Extensions/motion_acceleration_z32.png"
|
||||
)
|
||||
.addParameter('relationalOperator', _('Sign of the test'), 'number')
|
||||
.addParameter('expression', _('Value (m/s²)'))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationZ');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationZ");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ActivateMotionListener',
|
||||
_('Activate motion sensor'),
|
||||
_('Activate the motion sensor. (remember to turn it off again)'),
|
||||
_('Activate the motion sensor.'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_active32.png',
|
||||
'JsPlatform/Extensions/motion_active32.png'
|
||||
"ActivateMotionListener",
|
||||
_("Activate motion sensor"),
|
||||
_("Activate the motion sensor. (remember to turn it off again)"),
|
||||
_("Activate the motion sensor."),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_active32.png",
|
||||
"JsPlatform/Extensions/motion_active32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.activateMotionSensor');
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.activateMotionSensor");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'DeactivateMotionListener',
|
||||
_('Deactivate motion sensor'),
|
||||
_('Deactivate the motion sensor.'),
|
||||
_('Deactivate the motion sensor.'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_inactive32.png',
|
||||
'JsPlatform/Extensions/motion_inactive32.png'
|
||||
"DeactivateMotionListener",
|
||||
_("Deactivate motion sensor"),
|
||||
_("Deactivate the motion sensor."),
|
||||
_("Deactivate the motion sensor."),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_inactive32.png",
|
||||
"JsPlatform/Extensions/motion_inactive32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.deactivateMotionSensor');
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.deactivateMotionSensor");
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'RotationAlpha',
|
||||
_('Alpha value'),
|
||||
_('Get the devices rotation Alpha'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_rotation_alpha16.png'
|
||||
"RotationAlpha",
|
||||
_("Alpha value"),
|
||||
_("Get the devices rotation Alpha"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_rotation_alpha16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getRotationAlpha');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getRotationAlpha");
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'RotationBeta',
|
||||
_('Beta value'),
|
||||
_('Get the devices rotation Beta'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_rotation_beta16.png'
|
||||
"RotationBeta",
|
||||
_("Beta value"),
|
||||
_("Get the devices rotation Beta"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_rotation_beta16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getRotationBeta');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getRotationBeta");
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'RotationGamma',
|
||||
_('Gamma value'),
|
||||
_('Get the devices rotation Gamma'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_rotation_gamma16.png'
|
||||
"RotationGamma",
|
||||
_("Gamma value"),
|
||||
_("Get the devices rotation Gamma"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_rotation_gamma16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getRotationGamma');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getRotationGamma");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addExpression(
|
||||
'AccelerationX',
|
||||
_('Acceleration X value'),
|
||||
_('Get the devices acceleration on the X-axis (m/s²)'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_acceleration_x16.png'
|
||||
"AccelerationX",
|
||||
_("Acceleration X value"),
|
||||
_("Get the devices acceleration on the X-axis (m/s²)"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_acceleration_x16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationX');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationX");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addExpression(
|
||||
'AccelerationY',
|
||||
_('Acceleration Y value'),
|
||||
_('Get the devices acceleration on the Y-axis (m/s²)'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_acceleration_y16.png'
|
||||
"AccelerationY",
|
||||
_("Acceleration Y value"),
|
||||
_("Get the devices acceleration on the Y-axis (m/s²)"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_acceleration_y16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationY');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationY");
|
||||
|
||||
extension
|
||||
extension
|
||||
.addExpression(
|
||||
'AccelerationZ',
|
||||
_('Acceleration Z value'),
|
||||
_('Get the devices acceleration on the Z-axis (m/s²)'),
|
||||
_('Motion'),
|
||||
'JsPlatform/Extensions/motion_acceleration_z16.png'
|
||||
"AccelerationZ",
|
||||
_("Acceleration Z value"),
|
||||
_("Get the devices acceleration on the Z-axis (m/s²)"),
|
||||
_("Motion"),
|
||||
"JsPlatform/Extensions/motion_acceleration_z16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
|
||||
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationZ');
|
||||
.setIncludeFile(
|
||||
"Extensions/DeviceSensors/devicesensortools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationZ");
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
return [];
|
||||
},
|
||||
runExtensionSanityTests: function(gd /*: libGDevelop */, extension /*: gdPlatformExtension*/) { return []; },
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -28,9 +36,8 @@ module.exports = {
|
||||
)
|
||||
.setExtensionHelpPath('/all-features/device-vibration')
|
||||
.setCategory('User interface');
|
||||
extension
|
||||
.addInstructionOrExpressionGroupMetadata(_('Device vibration'))
|
||||
.setIcon('JsPlatform/Extensions/vibration_start32.png');
|
||||
extension.addInstructionOrExpressionGroupMetadata(_("Device vibration"))
|
||||
.setIcon("JsPlatform/Extensions/vibration_start32.png");
|
||||
|
||||
extension
|
||||
.addDependency()
|
||||
@@ -92,7 +99,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -713,7 +721,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,20 +12,28 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
'Effects',
|
||||
'Effects',
|
||||
'Lots of different effects to be used in your game.',
|
||||
'Various contributors from PixiJS, PixiJS filters and GDevelop',
|
||||
'MIT'
|
||||
)
|
||||
.setCategory('Visual effect')
|
||||
.setExtensionHelpPath('/interface/scene-editor/layer-effects');
|
||||
extension.setExtensionInformation(
|
||||
'Effects',
|
||||
'Effects',
|
||||
'Lots of different effects to be used in your game.',
|
||||
'Various contributors from PixiJS, PixiJS filters and GDevelop',
|
||||
'MIT'
|
||||
)
|
||||
.setCategory('Visual effect')
|
||||
.setExtensionHelpPath('/interface/scene-editor/layer-effects');
|
||||
|
||||
// ℹ️ You can declare an effect here. Please order the effects by alphabetical order.
|
||||
// This file is for common effects that are well-known/"battle-tested". If you have an
|
||||
@@ -223,11 +230,7 @@ module.exports = {
|
||||
const blurEffect = extension
|
||||
.addEffect('Blur')
|
||||
.setFullName(_('Blur (Gaussian, slow - prefer to use Kawase blur)'))
|
||||
.setDescription(
|
||||
_(
|
||||
'Blur the rendered image. This is slow, so prefer to use Kawase blur in most cases.'
|
||||
)
|
||||
)
|
||||
.setDescription(_('Blur the rendered image. This is slow, so prefer to use Kawase blur in most cases.'))
|
||||
.markAsOnlyWorkingFor2D()
|
||||
.addIncludeFile('Extensions/Effects/blur-pixi-filter.js');
|
||||
const blurProperties = blurEffect.getProperties();
|
||||
@@ -725,11 +728,13 @@ module.exports = {
|
||||
const hslAdjustmentEffect = extension
|
||||
.addEffect('HslAdjustment')
|
||||
.setFullName(_('HSL Adjustment'))
|
||||
.setDescription(_('Adjust hue, saturation and lightness.'))
|
||||
.markAsOnlyWorkingFor2D()
|
||||
.addIncludeFile(
|
||||
'Extensions/Effects/pixi-filters/filter-hsl-adjustment.js'
|
||||
.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
|
||||
@@ -762,9 +767,7 @@ module.exports = {
|
||||
.addEffect('KawaseBlur')
|
||||
.setFullName(_('Blur (Kawase, fast)'))
|
||||
.setDescription(
|
||||
_(
|
||||
'Blur the rendered image, with much better performance than Gaussian blur.'
|
||||
)
|
||||
_('Blur the rendered image, with much better performance than Gaussian blur.')
|
||||
)
|
||||
.markAsOnlyWorkingFor2D()
|
||||
.addIncludeFile('Extensions/Effects/pixi-filters/filter-kawase-blur.js')
|
||||
@@ -813,7 +816,9 @@ module.exports = {
|
||||
const motionBlurEffect = extension
|
||||
.addEffect('MotionBlur')
|
||||
.setFullName(_('Motion Blur'))
|
||||
.setDescription(_('Blur the rendered image to give a feeling of speed.'))
|
||||
.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');
|
||||
@@ -1169,9 +1174,7 @@ module.exports = {
|
||||
.setValue('0')
|
||||
.setLabel(_('Elapsed time'))
|
||||
.setType('number')
|
||||
.setDescription(
|
||||
'It can be set back to 0 to play the shockwave animation again.'
|
||||
);
|
||||
.setDescription('It can be set back to 0 to play the shockwave animation again.');
|
||||
shockwaveEffectProperties
|
||||
.getOrCreate('speed')
|
||||
.setValue('500')
|
||||
@@ -1308,7 +1311,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension.setExtensionInformation(
|
||||
'MyDummyExtension',
|
||||
@@ -145,6 +153,7 @@ module.exports = {
|
||||
// Everything that is stored inside the behavior is in "behaviorContent" and is automatically
|
||||
// saved/loaded to JSON.
|
||||
var dummyBehavior = new gd.BehaviorJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
dummyBehavior.updateProperty = function (
|
||||
behaviorContent,
|
||||
propertyName,
|
||||
@@ -161,6 +170,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
dummyBehavior.getProperties = function (behaviorContent) {
|
||||
var behaviorProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -177,6 +187,7 @@ module.exports = {
|
||||
|
||||
return behaviorProperties;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
dummyBehavior.initializeContent = function (behaviorContent) {
|
||||
behaviorContent.setStringAttribute('property1', 'Initial value 1');
|
||||
behaviorContent.setBoolAttribute('property2', true);
|
||||
@@ -190,7 +201,6 @@ module.exports = {
|
||||
'',
|
||||
'CppPlatform/Extensions/topdownmovementicon.png',
|
||||
'DummyBehavior',
|
||||
//@ts-ignore The class hierarchy is incorrect leading to a type error, but this is valid.
|
||||
dummyBehavior,
|
||||
new gd.BehaviorsSharedData()
|
||||
)
|
||||
@@ -205,6 +215,7 @@ module.exports = {
|
||||
// Create a new gd.BehaviorSharedDataJsImplementation object and implement the methods
|
||||
// that are called to get and set the properties of the shared data.
|
||||
var dummyBehaviorWithSharedData = new gd.BehaviorJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
dummyBehaviorWithSharedData.updateProperty = function (
|
||||
behaviorContent,
|
||||
propertyName,
|
||||
@@ -217,6 +228,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
dummyBehaviorWithSharedData.getProperties = function (behaviorContent) {
|
||||
var behaviorProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -226,11 +238,13 @@ module.exports = {
|
||||
|
||||
return behaviorProperties;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
dummyBehaviorWithSharedData.initializeContent = function (behaviorContent) {
|
||||
behaviorContent.setStringAttribute('property1', 'Initial value 1');
|
||||
};
|
||||
|
||||
var sharedData = new gd.BehaviorSharedDataJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
sharedData.updateProperty = function (
|
||||
sharedContent,
|
||||
propertyName,
|
||||
@@ -243,6 +257,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
sharedData.getProperties = function (sharedContent) {
|
||||
var sharedProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -252,6 +267,7 @@ module.exports = {
|
||||
|
||||
return sharedProperties;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
sharedData.initializeContent = function (behaviorContent) {
|
||||
behaviorContent.setStringAttribute(
|
||||
'sharedProperty1',
|
||||
@@ -268,7 +284,6 @@ module.exports = {
|
||||
'',
|
||||
'CppPlatform/Extensions/topdownmovementicon.png',
|
||||
'DummyBehaviorWithSharedData',
|
||||
//@ts-ignore The class hierarchy is incorrect leading to a type error, but this is valid.
|
||||
dummyBehaviorWithSharedData,
|
||||
sharedData
|
||||
)
|
||||
@@ -287,6 +302,7 @@ module.exports = {
|
||||
// Everything that is stored inside the object is in "content" and is automatically
|
||||
// saved/loaded to JSON.
|
||||
var dummyObject = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
dummyObject.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -311,6 +327,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
dummyObject.getProperties = function (objectContent) {
|
||||
var objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -345,6 +362,7 @@ module.exports = {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
dummyObject.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -364,6 +382,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
dummyObject.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -427,7 +446,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
const dummyBehavior = extension
|
||||
.getBehaviorMetadata('MyDummyExtension::DummyBehavior')
|
||||
.get();
|
||||
@@ -452,7 +474,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations: function (objectsEditorService) {
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {
|
||||
objectsEditorService.registerEditorConfiguration(
|
||||
'MyDummyExtension::DummyObject',
|
||||
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
|
||||
@@ -465,7 +489,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,414 +12,368 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function(_/*: (string) => string */, gd/*: libGDevelop */) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
'FacebookInstantGames',
|
||||
_('Facebook Instant Games'),
|
||||
"FacebookInstantGames",
|
||||
_("Facebook Instant Games"),
|
||||
_(
|
||||
'Allow your game to send scores and interact with the Facebook Instant Games platform.'
|
||||
"Allow your game to send scores and interact with the Facebook Instant Games platform."
|
||||
),
|
||||
'Florian Rival',
|
||||
'Open source (MIT License)'
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)"
|
||||
)
|
||||
.setExtensionHelpPath('/publishing/publishing-to-facebook-instant-games')
|
||||
.setExtensionHelpPath("/publishing/publishing-to-facebook-instant-games")
|
||||
.setCategory('Third-party');
|
||||
extension
|
||||
.addInstructionOrExpressionGroupMetadata(_('Facebook Instant Games'))
|
||||
.setIcon('JsPlatform/Extensions/facebookicon32.png');
|
||||
extension.addInstructionOrExpressionGroupMetadata(_("Facebook Instant Games"))
|
||||
.setIcon("JsPlatform/Extensions/facebookicon32.png");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SavePlayerData',
|
||||
_('Save player data'),
|
||||
"SavePlayerData",
|
||||
_("Save player data"),
|
||||
_(
|
||||
'Save the content of the given scene variable in the player data, stored on Facebook Instant Games servers'
|
||||
"Save the content of the given scene variable in the player data, stored on Facebook Instant Games servers"
|
||||
),
|
||||
_(
|
||||
'Save the content of _PARAM1_ in key _PARAM0_ of player data (store success message in _PARAM2_ or error in _PARAM3_)'
|
||||
"Save the content of _PARAM1_ in key _PARAM0_ of player data (store success message in _PARAM2_ or error in _PARAM3_)"
|
||||
),
|
||||
_('Player data'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
_("Player data"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter('string', 'Data key name (e.g: "Lives")', '', false)
|
||||
.addParameter("string", 'Data key name (e.g: "Lives")', "", false)
|
||||
.addParameter("scenevar", "Scene variable with the content to save", "", false)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
'Scene variable with the content to save',
|
||||
'',
|
||||
false
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Variable where to store the success message (optional)'),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the success message (optional)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.setPlayerData');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.setPlayerData");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'LoadPlayerData',
|
||||
_('Load player data'),
|
||||
_('Load the player data with the given key in a variable'),
|
||||
"LoadPlayerData",
|
||||
_("Load player data"),
|
||||
_("Load the player data with the given key in a variable"),
|
||||
_(
|
||||
'Load player data with key _PARAM0_ in _PARAM1_ (or error in _PARAM2_)'
|
||||
"Load player data with key _PARAM0_ in _PARAM1_ (or error in _PARAM2_)"
|
||||
),
|
||||
_('Player data'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
_("Player data"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter('string', _('Data key name (e.g: "Lives")'), '', false)
|
||||
.addParameter("string", _('Data key name (e.g: "Lives")'), "", false)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Variable where to store loaded data'),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store loaded data"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.loadPlayerData');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.loadPlayerData");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SavePlayerScore',
|
||||
_('Save player score'),
|
||||
"SavePlayerScore",
|
||||
_("Save player score"),
|
||||
_(
|
||||
'Save the score, and optionally the content of the given variable in the player score, for the given metadata.'
|
||||
"Save the score, and optionally the content of the given variable in the player score, for the given metadata."
|
||||
),
|
||||
_(
|
||||
'In leaderboard _PARAM0_, save score _PARAM1_ for the player and extra data from _PARAM2_ (store success message in _PARAM3_ or error in _PARAM4_)'
|
||||
"In leaderboard _PARAM0_, save score _PARAM1_ for the player and extra data from _PARAM2_ (store success message in _PARAM3_ or error in _PARAM4_)"
|
||||
),
|
||||
_('Leaderboards'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
_("Leaderboards"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter(
|
||||
'string',
|
||||
"string",
|
||||
'Leaderboard name (e.g: "PlayersBestTimes")',
|
||||
'',
|
||||
"",
|
||||
false
|
||||
)
|
||||
.addParameter('expression', 'Score to register for the player', '', false)
|
||||
.addParameter("expression", "Score to register for the player", "", false)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Optional variable with metadata to save'),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Optional variable with metadata to save"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Variable where to store the success message (optional)'),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the success message (optional)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.setPlayerScore');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.setPlayerScore");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'LoadPlayerEntry',
|
||||
_('Load player entry'),
|
||||
_('Load the player entry in the given leaderboard'),
|
||||
"LoadPlayerEntry",
|
||||
_("Load player entry"),
|
||||
_("Load the player entry in the given leaderboard"),
|
||||
_(
|
||||
'Load player entry from leaderboard _PARAM0_. Set rank in _PARAM1_, score in _PARAM2_ (extra data if any in _PARAM3_ and error in _PARAM4_)'
|
||||
"Load player entry from leaderboard _PARAM0_. Set rank in _PARAM1_, score in _PARAM2_ (extra data if any in _PARAM3_ and error in _PARAM4_)"
|
||||
),
|
||||
_('Leaderboards'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
_("Leaderboards"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter(
|
||||
'string',
|
||||
"string",
|
||||
_('Leaderboard name (e.g: "PlayersBestTimes")'),
|
||||
'',
|
||||
"",
|
||||
false
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Variable where to store the player rank (of -1 if not ranked)'),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the player rank (of -1 if not ranked)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Variable where to store the player score (of -1 if no score)'),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the player score (of -1 if no score)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Variable where to store extra data (if any)'),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store extra data (if any)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.getPlayerEntry');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.getPlayerEntry");
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'AreAdsSupported',
|
||||
_('Check if ads are supported'),
|
||||
_(
|
||||
'Check if showing ads is supported on this device (only mobile phones can show ads)'
|
||||
),
|
||||
_('Ads can be shown on this device'),
|
||||
_('Ads'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"AreAdsSupported",
|
||||
_("Check if ads are supported"),
|
||||
_("Check if showing ads is supported on this device (only mobile phones can show ads)"),
|
||||
_("Ads can be shown on this device"),
|
||||
_("Ads"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.areAdsSupported');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.areAdsSupported");
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsInterstitialAdReady',
|
||||
_('Is the interstitial ad ready'),
|
||||
_(
|
||||
'Check if the interstitial ad requested from Facebook is loaded and ready to be shown.'
|
||||
),
|
||||
_('The interstitial ad is loaded and ready to be shown'),
|
||||
_('Ads'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"IsInterstitialAdReady",
|
||||
_("Is the interstitial ad ready"),
|
||||
_("Check if the interstitial ad requested from Facebook is loaded and ready to be shown."),
|
||||
_("The interstitial ad is loaded and ready to be shown"),
|
||||
_("Ads"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName(
|
||||
'gdjs.evtTools.facebookInstantGames.isInterstitialAdReady'
|
||||
);
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.isInterstitialAdReady");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'LoadInterstitialAd',
|
||||
_('Load and prepare an interstitial ad'),
|
||||
_(
|
||||
'Request and load an interstitial ad from Facebook, so that it is ready to be shown.'
|
||||
),
|
||||
_(
|
||||
'Request and load an interstitial ad from Facebook (ad placement id: _PARAM0_, error in _PARAM1_)'
|
||||
),
|
||||
_('Ads'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"LoadInterstitialAd",
|
||||
_("Load and prepare an interstitial ad"),
|
||||
_("Request and load an interstitial ad from Facebook, so that it is ready to be shown."),
|
||||
_("Request and load an interstitial ad from Facebook (ad placement id: _PARAM0_, error in _PARAM1_)"),
|
||||
_("Ads"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter(
|
||||
'string',
|
||||
_(
|
||||
'The Ad Placement id (can be found while setting up the ad on Facebook)'
|
||||
),
|
||||
'',
|
||||
"string",
|
||||
_("The Ad Placement id (can be found while setting up the ad on Facebook)"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.loadInterstitialAd');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.loadInterstitialAd");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ShowInterstitialAd',
|
||||
_('Show the loaded interstitial ad'),
|
||||
_(
|
||||
"Show the interstitial ad previously loaded in memory. This won't work if you did not load the interstitial before."
|
||||
),
|
||||
_(
|
||||
'Show the interstitial ad previously loaded in memory (if any error, store it in _PARAM0_)'
|
||||
),
|
||||
_('Ads'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"ShowInterstitialAd",
|
||||
_("Show the loaded interstitial ad"),
|
||||
_("Show the interstitial ad previously loaded in memory. This won't work if you did not load the interstitial before."),
|
||||
_("Show the interstitial ad previously loaded in memory (if any error, store it in _PARAM0_)"),
|
||||
_("Ads"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.showInterstitialAd');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.showInterstitialAd");
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsRewardedVideoReady',
|
||||
_('Is the rewarded video ready'),
|
||||
_(
|
||||
'Check if the rewarded video requested from Facebook is loaded and ready to be shown.'
|
||||
),
|
||||
_('The rewarded video is loaded and ready to be shown'),
|
||||
_('Ads'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"IsRewardedVideoReady",
|
||||
_("Is the rewarded video ready"),
|
||||
_("Check if the rewarded video requested from Facebook is loaded and ready to be shown."),
|
||||
_("The rewarded video is loaded and ready to be shown"),
|
||||
_("Ads"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName(
|
||||
'gdjs.evtTools.facebookInstantGames.isRewardedVideoReady'
|
||||
);
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.isRewardedVideoReady");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'LoadRewardedVideo',
|
||||
_('Load and prepare a rewarded video'),
|
||||
_(
|
||||
'Request and load a rewarded video from Facebook, so that it is ready to be shown.'
|
||||
),
|
||||
_(
|
||||
'Request and load a rewarded video from Facebook (ad placement id: _PARAM0_, error in _PARAM1_)'
|
||||
),
|
||||
_('Ads'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"LoadRewardedVideo",
|
||||
_("Load and prepare a rewarded video"),
|
||||
_("Request and load a rewarded video from Facebook, so that it is ready to be shown."),
|
||||
_("Request and load a rewarded video from Facebook (ad placement id: _PARAM0_, error in _PARAM1_)"),
|
||||
_("Ads"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter(
|
||||
'string',
|
||||
_(
|
||||
'The Ad Placement id (can be found while setting up the ad on Facebook)'
|
||||
),
|
||||
'',
|
||||
"string",
|
||||
_("The Ad Placement id (can be found while setting up the ad on Facebook)"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.loadRewardedVideo');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.loadRewardedVideo");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ShowRewardedVideo',
|
||||
_('Show the loaded rewarded video'),
|
||||
_(
|
||||
"Show the rewarded video previously loaded in memory. This won't work if you did not load the video before."
|
||||
),
|
||||
_(
|
||||
'Show the rewarded video previously loaded in memory (if any error, store it in _PARAM0_)'
|
||||
),
|
||||
_('Ads'),
|
||||
'JsPlatform/Extensions/facebookicon32.png',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"ShowRewardedVideo",
|
||||
_("Show the loaded rewarded video"),
|
||||
_("Show the rewarded video previously loaded in memory. This won't work if you did not load the video before."),
|
||||
_("Show the rewarded video previously loaded in memory (if any error, store it in _PARAM0_)"),
|
||||
_("Ads"),
|
||||
"JsPlatform/Extensions/facebookicon32.png",
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
"scenevar",
|
||||
_("Variable where to store the error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.showRewardedVideo');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.showRewardedVideo");
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'PlayerId',
|
||||
_('Player identifier'),
|
||||
_('Get the player unique identifier'),
|
||||
"PlayerId",
|
||||
_("Player identifier"),
|
||||
_("Get the player unique identifier"),
|
||||
'',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.getPlayerId');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.getPlayerId");
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'PlayerName',
|
||||
_('Player name'),
|
||||
_('Get the player name'),
|
||||
"PlayerName",
|
||||
_("Player name"),
|
||||
_("Get the player name"),
|
||||
'',
|
||||
'JsPlatform/Extensions/facebookicon32.png'
|
||||
"JsPlatform/Extensions/facebookicon32.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/FacebookInstantGames/facebookinstantgamestools.js'
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.facebookInstantGames.getPlayerName');
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.getPlayerName");
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function(gd /*: libGDevelop */, extension /*: gdPlatformExtension*/) {
|
||||
return [];
|
||||
},
|
||||
}
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -12,10 +11,11 @@
|
||||
*
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
|
||||
extension
|
||||
@@ -2314,7 +2314,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension */
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
225
Extensions/JsExtensionTypes.d.ts
vendored
225
Extensions/JsExtensionTypes.d.ts
vendored
@@ -1,225 +0,0 @@
|
||||
type GDNamespace = typeof import('../GDevelop.js/types');
|
||||
|
||||
// This is necessary for typescript to interpret the identifier PIXI as a namespace
|
||||
// in this file and merge it with the other namespace declarations.
|
||||
declare namespace PIXI {}
|
||||
|
||||
/**
|
||||
* RenderedInstance is the base class used for creating 2D renderers of instances,
|
||||
* which display on the scene editor, using Pixi.js, the instance of an object (see InstancesEditor).
|
||||
*/
|
||||
class RenderedInstance {
|
||||
_project: gd.Project;
|
||||
_layout: gd.Layout;
|
||||
_instance: gd.InitialInstance;
|
||||
_associatedObjectConfiguration: gd.ObjectConfiguration;
|
||||
_pixiContainer: PIXI.Container;
|
||||
_pixiResourcesLoader: Class<PixiResourcesLoader>;
|
||||
_pixiObject: PIXI.DisplayObject;
|
||||
wasUsed: boolean;
|
||||
|
||||
constructor(
|
||||
project: gdProject,
|
||||
layout: gdLayout,
|
||||
instance: gdInitialInstance,
|
||||
associatedObjectConfiguration: gdObjectConfiguration,
|
||||
pixiContainer: PIXI.Container,
|
||||
pixiResourcesLoader: Class<PixiResourcesLoader>
|
||||
);
|
||||
|
||||
/**
|
||||
* Convert an angle from degrees to radians.
|
||||
*/
|
||||
static toRad(angleInDegrees: number): number;
|
||||
|
||||
/**
|
||||
* Called when the scene editor is rendered.
|
||||
*/
|
||||
update(): void;
|
||||
|
||||
getPixiObject(): PIXI.DisplayObject | null;
|
||||
|
||||
getInstance(): gd.InitialInstance;
|
||||
|
||||
/**
|
||||
* Called to notify the instance renderer that its associated instance was removed from
|
||||
* the scene. The PIXI object should probably be removed from the container: This is what
|
||||
* the default implementation of the method does.
|
||||
*/
|
||||
onRemovedFromScene(): void;
|
||||
|
||||
getOriginX(): number;
|
||||
|
||||
getOriginY(): number;
|
||||
|
||||
getCenterX(): number;
|
||||
|
||||
getCenterY(): number;
|
||||
|
||||
getCustomWidth(): number;
|
||||
|
||||
getCustomHeight(): number;
|
||||
|
||||
getWidth(): number;
|
||||
|
||||
getHeight(): number;
|
||||
|
||||
getDepth(): number;
|
||||
|
||||
/**
|
||||
* Return the width of the instance when the instance doesn't have a custom size.
|
||||
*/
|
||||
getDefaultWidth(): number;
|
||||
|
||||
/**
|
||||
* Return the height of the instance when the instance doesn't have a custom size.
|
||||
*/
|
||||
getDefaultHeight(): number;
|
||||
|
||||
getDefaultDepth(): number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendered3DInstance is the base class used for creating 3D renderers of instances,
|
||||
* which display on the scene editor, using Three.js, the instance of an object (see InstancesEditor).
|
||||
* It can also display 2D artifacts on Pixi 2D plane (3D object shadow projected on the plane for instance).
|
||||
*/
|
||||
class Rendered3DInstance {
|
||||
_project: gdProject;
|
||||
_layout: gdLayout;
|
||||
_instance: gdInitialInstance;
|
||||
_associatedObjectConfiguration: gdObjectConfiguration;
|
||||
_pixiContainer: PIXI.Container;
|
||||
_threeGroup: THREE.Group;
|
||||
_pixiResourcesLoader: Class<PixiResourcesLoader>;
|
||||
_pixiObject: PIXI.DisplayObject;
|
||||
_threeObject: THREE.Object3D | null;
|
||||
wasUsed: boolean;
|
||||
|
||||
constructor(
|
||||
project: gdProject,
|
||||
layout: gdLayout,
|
||||
instance: gdInitialInstance,
|
||||
associatedObjectConfiguration: gdObjectConfiguration,
|
||||
pixiContainer: PIXI.Container,
|
||||
threeGroup: THREE.Group,
|
||||
pixiResourcesLoader: Class<PixiResourcesLoader>
|
||||
);
|
||||
|
||||
/**
|
||||
* Convert an angle from degrees to radians.
|
||||
*/
|
||||
static toRad(angleInDegrees: number): number;
|
||||
|
||||
/**
|
||||
* Called when the scene editor is rendered.
|
||||
*/
|
||||
update(): void;
|
||||
|
||||
getPixiObject(): PIXI.DisplayObject;
|
||||
|
||||
getThreeObject(): THREE.Object3D;
|
||||
|
||||
getInstance(): gd.InitialInstance;
|
||||
|
||||
/**
|
||||
* Called to notify the instance renderer that its associated instance was removed from
|
||||
* the scene. The PIXI object should probably be removed from the container: This is what
|
||||
* the default implementation of the method does.
|
||||
*/
|
||||
onRemovedFromScene(): void;
|
||||
|
||||
getOriginX(): number;
|
||||
|
||||
getOriginY(): number;
|
||||
|
||||
getCenterX(): number;
|
||||
|
||||
getCenterY(): number;
|
||||
|
||||
getWidth(): number;
|
||||
|
||||
getHeight(): number;
|
||||
|
||||
getDepth(): number;
|
||||
|
||||
/**
|
||||
* Return the width of the instance when the instance doesn't have a custom size.
|
||||
*/
|
||||
getDefaultWidth(): number;
|
||||
|
||||
/**
|
||||
* Return the height of the instance when the instance doesn't have a custom size.
|
||||
*/
|
||||
getDefaultHeight(): number;
|
||||
|
||||
/**
|
||||
* Return the depth of the instance when the instance doesn't have a custom size.
|
||||
*/
|
||||
getDefaultDepth(): number;
|
||||
}
|
||||
|
||||
declare type ObjectsRenderingService = {
|
||||
gd: GDNamespace;
|
||||
PIXI: PIXI;
|
||||
THREE: typeof import('../newIDE/app/node_modules/three');
|
||||
THREE_ADDONS: { SkeletonUtils: any };
|
||||
RenderedInstance: typeof RenderedInstance;
|
||||
Rendered3DInstance: typeof Rendered3DInstance;
|
||||
registerInstanceRenderer: (objectType: string, renderer: any) => void;
|
||||
registerInstance3DRenderer: (objectType: string, renderer: any) => void;
|
||||
requireModule: (dirname: string, moduleName: string) => any;
|
||||
getThumbnail: (
|
||||
project: gd.Project,
|
||||
objectConfiguration: gd.ObjectConfiguration
|
||||
) => string;
|
||||
rgbOrHexToHexNumber: (value: string) => number;
|
||||
registerClearCache: (clearCache: (_: any) => void) => void;
|
||||
};
|
||||
|
||||
declare type ObjectsEditorService = {
|
||||
registerEditorConfiguration: (
|
||||
objectType: string,
|
||||
editorConfiguration: any
|
||||
) => void;
|
||||
getDefaultObjectJsImplementationPropertiesEditor: ({
|
||||
helpPagePath: string,
|
||||
}) => any;
|
||||
};
|
||||
|
||||
declare type ExtensionModule = {
|
||||
createExtension: (
|
||||
_: (string) => string,
|
||||
gd: GDNamespace
|
||||
) => gd.PlatformExtension;
|
||||
/**
|
||||
* You can optionally add sanity tests that will check the basic working
|
||||
* of your extension behaviors/objects by instantiating behaviors/objects
|
||||
* and setting the property to a given value.
|
||||
*
|
||||
* If you don't have any tests, you can simply return an empty array.
|
||||
*
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: (
|
||||
gd: GDNamespace,
|
||||
extension: gd.PlatformExtension
|
||||
) => string[];
|
||||
/**
|
||||
* Register editors for objects.
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations?: (
|
||||
objectsEditorService: ObjectsEditorService
|
||||
) => void;
|
||||
/**
|
||||
* Register renderers for instance of objects on the scene editor.
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers?: (
|
||||
objectsRenderingService: ObjectsRenderingService
|
||||
) => void;
|
||||
};
|
35
Extensions/JsExtensionTypes.flow.js
Normal file
35
Extensions/JsExtensionTypes.flow.js
Normal file
@@ -0,0 +1,35 @@
|
||||
// @flow
|
||||
|
||||
/**
|
||||
* @file This file contains the (Flow) types that are used in the JavaScript
|
||||
* extensions declaration (i.e: JsExtension.js files).
|
||||
* Extension runtime files are in TypeScript (ts files) and not using Flow.
|
||||
*
|
||||
* If you do changes here, run `node import-GDJS-Runtime.js` (in newIDE/app/scripts),
|
||||
* and be sure that the types declared here are reflecting the types exposed by the editor.
|
||||
*
|
||||
* Note that Flow comments are used to avoid having to preprocess this file and the
|
||||
* JsExtension.js files through Babel. This allows to keep plain JS files, while allowing
|
||||
* Flow static type checking to be run on them when integrated in the editor.
|
||||
*/
|
||||
|
||||
/*::
|
||||
export type ObjectsRenderingService = {
|
||||
gd: libGDevelop,
|
||||
PIXI: any,
|
||||
THREE: any,
|
||||
THREE_ADDONS: {SkeletonUtils: any},
|
||||
RenderedInstance: any,
|
||||
Rendered3DInstance: any,
|
||||
registerInstanceRenderer: (objectType: string, renderer: any) => void,
|
||||
registerInstance3DRenderer: (objectType: string, renderer: any) => void,
|
||||
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,
|
||||
getDefaultObjectJsImplementationPropertiesEditor: ({| helpPagePath: string |}) => any,
|
||||
};
|
||||
*/
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -88,9 +96,7 @@ module.exports = {
|
||||
.setIncludeFile('Extensions/Leaderboards/sha256.js')
|
||||
.addIncludeFile('Extensions/Leaderboards/leaderboardstools.js')
|
||||
.setFunctionName('gdjs.evtTools.leaderboards.saveConnectedPlayerScore')
|
||||
.setAsyncFunctionName(
|
||||
'gdjs.evtTools.leaderboards.saveConnectedPlayerScore'
|
||||
);
|
||||
.setAsyncFunctionName('gdjs.evtTools.leaderboards.saveConnectedPlayerScore');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
@@ -293,7 +299,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,23 +12,32 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
'Lighting',
|
||||
_('Lights'),
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
'This provides a light object, and a behavior to mark other objects as being obstacles for the lights. This is a great way to create a special atmosphere to your game, along with effects, make it more realistic or to create gameplays based on lights.',
|
||||
'Harsimran Virk',
|
||||
'MIT'
|
||||
)
|
||||
.setCategory('Visual effect')
|
||||
.setTags('light');
|
||||
module.exports = {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension.setExtensionInformation(
|
||||
'Lighting',
|
||||
_('Lights'),
|
||||
|
||||
'This provides a light object, and a behavior to mark other objects as being obstacles for the lights. This is a great way to create a special atmosphere to your game, along with effects, make it more realistic or to create gameplays based on lights.',
|
||||
'Harsimran Virk',
|
||||
'MIT'
|
||||
)
|
||||
.setCategory('Visual effect')
|
||||
.setTags("light");
|
||||
|
||||
const lightObstacleBehavior = new gd.BehaviorJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
lightObstacleBehavior.updateProperty = function (
|
||||
behaviorContent,
|
||||
propertyName,
|
||||
@@ -38,12 +46,14 @@ module.exports = {
|
||||
return false;
|
||||
};
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
lightObstacleBehavior.getProperties = function (behaviorContent) {
|
||||
const behaviorProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
return behaviorProperties;
|
||||
};
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
lightObstacleBehavior.initializeContent = function (behaviorContent) {};
|
||||
extension
|
||||
.addBehavior(
|
||||
@@ -56,7 +66,6 @@ module.exports = {
|
||||
'',
|
||||
'CppPlatform/Extensions/lightObstacleIcon32.png',
|
||||
'LightObstacleBehavior',
|
||||
//@ts-ignore The class hierarchy is incorrect leading to a type error, but this is valid.
|
||||
lightObstacleBehavior,
|
||||
new gd.BehaviorsSharedData()
|
||||
)
|
||||
@@ -68,6 +77,7 @@ module.exports = {
|
||||
|
||||
const lightObject = new gd.ObjectJsImplementation();
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object.
|
||||
lightObject.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -96,6 +106,7 @@ module.exports = {
|
||||
return false;
|
||||
};
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object.
|
||||
lightObject.getProperties = function (objectContent) {
|
||||
const objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -149,6 +160,7 @@ module.exports = {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object.
|
||||
lightObject.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -160,6 +172,7 @@ module.exports = {
|
||||
return false;
|
||||
};
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object.
|
||||
lightObject.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -220,11 +233,16 @@ module.exports = {
|
||||
return extension;
|
||||
},
|
||||
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
|
||||
registerEditorConfigurations: function (objectsEditorService) {
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {
|
||||
objectsEditorService.registerEditorConfiguration(
|
||||
'Lighting::LightObject',
|
||||
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
|
||||
@@ -237,7 +255,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
|
||||
@@ -263,34 +283,32 @@ module.exports = {
|
||||
);
|
||||
this._radius = parseFloat(
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('radius')
|
||||
.getValue()
|
||||
);
|
||||
if (this._radius <= 0) this._radius = 1;
|
||||
const color = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('color')
|
||||
.getValue()
|
||||
);
|
||||
|
||||
// The icon in the middle.
|
||||
const lightIconSprite = new PIXI.Sprite(
|
||||
PIXI.Texture.from('CppPlatform/Extensions/lightIcon32.png')
|
||||
);
|
||||
const lightIconSprite = new PIXI.Sprite(PIXI.Texture.from('CppPlatform/Extensions/lightIcon32.png'));
|
||||
lightIconSprite.anchor.x = 0.5;
|
||||
lightIconSprite.anchor.y = 0.5;
|
||||
|
||||
// The circle to show the radius of the light.
|
||||
const radiusBorderWidth = 2;
|
||||
const radiusGraphics = new PIXI.Graphics();
|
||||
radiusGraphics.lineStyle(radiusBorderWidth, color, 0.8);
|
||||
radiusGraphics.drawCircle(
|
||||
0,
|
||||
0,
|
||||
Math.max(1, this._radius - radiusBorderWidth)
|
||||
radiusGraphics.lineStyle(
|
||||
radiusBorderWidth,
|
||||
color,
|
||||
0.8
|
||||
);
|
||||
radiusGraphics.drawCircle(0, 0, Math.max(1, this._radius - radiusBorderWidth));
|
||||
|
||||
this._pixiObject = new PIXI.Container();
|
||||
this._pixiObject.addChild(lightIconSprite);
|
||||
@@ -308,7 +326,11 @@ module.exports = {
|
||||
/**
|
||||
* Return the path to the thumbnail of the specified object.
|
||||
*/
|
||||
static getThumbnail(project, resourcesLoader, objectConfiguration) {
|
||||
static getThumbnail(
|
||||
project,
|
||||
resourcesLoader,
|
||||
objectConfiguration
|
||||
) {
|
||||
return 'CppPlatform/Extensions/lightIcon32.png';
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,6 @@ GDevelop - LinkedObjects Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
namespace gdjs {
|
||||
const logger = new gdjs.Logger('LinkedObjects');
|
||||
/**
|
||||
* Manages the links between objects.
|
||||
*/
|
||||
@@ -115,14 +114,7 @@ namespace gdjs {
|
||||
if (this._links.has(linkedObject.id)) {
|
||||
const otherObjList = this._links
|
||||
.get(linkedObject.id)!
|
||||
.linkedObjectMap.get(removedObject.getName());
|
||||
|
||||
if (!otherObjList) {
|
||||
logger.error(
|
||||
`Can't find link from ${linkedObject.id} (${linkedObject.name}) to ${removedObject.id} (${removedObject.name})`
|
||||
);
|
||||
return;
|
||||
}
|
||||
.linkedObjectMap.get(removedObject.getName())!;
|
||||
|
||||
const index = otherObjList.indexOf(removedObject);
|
||||
if (index !== -1) {
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension /*: gdPlatformExtension */ = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -466,7 +474,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -24,41 +24,58 @@ namespace gdjs {
|
||||
runtimeObject: gdjs.RuntimeObject,
|
||||
objectData: any
|
||||
) {
|
||||
let texture = null;
|
||||
const graphics = new PIXI.Graphics();
|
||||
graphics.lineStyle(0, 0, 0);
|
||||
graphics.beginFill(gdjs.rgbToHexNumber(255, 255, 255), 1);
|
||||
if (objectData.rendererType === 'Point') {
|
||||
graphics.drawCircle(0, 0, objectData.rendererParam1);
|
||||
} else if (objectData.rendererType === 'Line') {
|
||||
graphics.drawRect(
|
||||
0,
|
||||
0,
|
||||
objectData.rendererParam1,
|
||||
objectData.rendererParam2
|
||||
);
|
||||
|
||||
// Draw an almost-invisible rectangle in the left hand to force PIXI to take a full texture with our line at the right hand
|
||||
graphics.beginFill(gdjs.rgbToHexNumber(255, 255, 255), 0.001);
|
||||
graphics.drawRect(
|
||||
0,
|
||||
0,
|
||||
objectData.rendererParam1,
|
||||
objectData.rendererParam2
|
||||
);
|
||||
} else if (objectData.textureParticleName) {
|
||||
const sprite = new PIXI.Sprite(
|
||||
(instanceContainer
|
||||
.getGame()
|
||||
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
|
||||
objectData.textureParticleName
|
||||
)
|
||||
);
|
||||
sprite.width = objectData.rendererParam1;
|
||||
sprite.height = objectData.rendererParam2;
|
||||
graphics.addChild(sprite);
|
||||
} else {
|
||||
graphics.drawRect(
|
||||
0,
|
||||
0,
|
||||
objectData.rendererParam1,
|
||||
objectData.rendererParam2
|
||||
);
|
||||
}
|
||||
graphics.endFill();
|
||||
|
||||
// Render the texture from graphics using the PIXI Renderer.
|
||||
// TODO: could be optimized by generating the texture only once per object type,
|
||||
// instead of at each object creation.
|
||||
const pixiRenderer = instanceContainer
|
||||
.getGame()
|
||||
.getRenderer()
|
||||
.getPIXIRenderer();
|
||||
const imageManager = instanceContainer
|
||||
.getGame()
|
||||
.getImageManager() as gdjs.PixiImageManager;
|
||||
let particleTexture: PIXI.Texture = PIXI.Texture.WHITE;
|
||||
if (pixiRenderer) {
|
||||
if (objectData.rendererType === 'Point') {
|
||||
particleTexture = imageManager.getOrCreateDiskTexture(
|
||||
objectData.rendererParam1,
|
||||
pixiRenderer
|
||||
);
|
||||
} else if (objectData.rendererType === 'Line') {
|
||||
particleTexture = imageManager.getOrCreateRectangleTexture(
|
||||
objectData.rendererParam1,
|
||||
objectData.rendererParam2,
|
||||
pixiRenderer
|
||||
);
|
||||
} else if (objectData.textureParticleName) {
|
||||
particleTexture = imageManager.getOrCreateScaledTexture(
|
||||
objectData.textureParticleName,
|
||||
objectData.rendererParam1,
|
||||
objectData.rendererParam2,
|
||||
pixiRenderer
|
||||
);
|
||||
} else {
|
||||
particleTexture = imageManager.getOrCreateRectangleTexture(
|
||||
objectData.rendererParam1,
|
||||
objectData.rendererParam2,
|
||||
pixiRenderer
|
||||
);
|
||||
}
|
||||
}
|
||||
//@ts-expect-error Pixi has wrong type definitions for this method
|
||||
texture = pixiRenderer.generateTexture(graphics);
|
||||
|
||||
const configuration = {
|
||||
ease: undefined,
|
||||
@@ -181,7 +198,7 @@ namespace gdjs {
|
||||
{
|
||||
type: 'textureSingle',
|
||||
config: {
|
||||
texture: particleTexture,
|
||||
texture: texture,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -219,9 +236,8 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
update(delta: float): void {
|
||||
const wasEmitting = this.emitter.emit;
|
||||
this.emitter.update(delta);
|
||||
if (!this.started && wasEmitting) {
|
||||
if (!this.started && this.getParticleCount() > 0) {
|
||||
this.started = true;
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,6 @@ std::map<gd::String, gd::PropertyDescriptor> PathfindingBehavior::GetProperties(
|
||||
.SetValue(behaviorContent.GetBoolAttribute("allowDiagonals") ? "true"
|
||||
: "false")
|
||||
.SetGroup(_("Path smoothing"))
|
||||
.SetAdvanced()
|
||||
.SetType("Boolean");
|
||||
properties["Acceleration"]
|
||||
.SetLabel(_("Acceleration"))
|
||||
@@ -100,7 +99,6 @@ std::map<gd::String, gd::PropertyDescriptor> PathfindingBehavior::GetProperties(
|
||||
properties["ExtraBorder"]
|
||||
.SetDescription(_("Extra border size"))
|
||||
.SetGroup(_("Collision"))
|
||||
.SetAdvanced()
|
||||
.SetType("Number")
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetPixel())
|
||||
.SetValue(
|
||||
@@ -110,7 +108,6 @@ std::map<gd::String, gd::PropertyDescriptor> PathfindingBehavior::GetProperties(
|
||||
.SetValue(gd::String::From(
|
||||
behaviorContent.GetDoubleAttribute("smoothingMaxCellGap")))
|
||||
.SetGroup(_("Path smoothing"))
|
||||
.SetAdvanced()
|
||||
.SetDescription(_("It's recommended to leave a max gap of 1 cell. "
|
||||
"Setting it to 0 disable the smoothing."));
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -27,12 +35,13 @@ module.exports = {
|
||||
)
|
||||
.setExtensionHelpPath('/behaviors/physics2')
|
||||
.setCategory('Movement')
|
||||
.setTags('physics, gravity, obstacle, collision');
|
||||
.setTags("physics, gravity, obstacle, collision");
|
||||
extension
|
||||
.addInstructionOrExpressionGroupMetadata(_('Physics Engine 2.0'))
|
||||
.setIcon('res/physics32.png');
|
||||
|
||||
var physics2Behavior = new gd.BehaviorJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
physics2Behavior.updateProperty = function (
|
||||
behaviorContent,
|
||||
propertyName,
|
||||
@@ -42,138 +51,104 @@ module.exports = {
|
||||
behaviorContent.getChild('bodyType').setStringValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'bullet') {
|
||||
behaviorContent.getChild('bullet').setBoolValue(newValue === '1');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'fixedRotation') {
|
||||
behaviorContent
|
||||
.getChild('fixedRotation')
|
||||
.setBoolValue(newValue === '1');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'canSleep') {
|
||||
behaviorContent.getChild('canSleep').setBoolValue(newValue === '1');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'shape') {
|
||||
behaviorContent.getChild('shape').setStringValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'shapeDimensionA') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('shapeDimensionA')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('shapeDimensionA').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'shapeDimensionB') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('shapeDimensionB')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('shapeDimensionB').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'shapeOffsetX') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('shapeOffsetX')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('shapeOffsetX').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'shapeOffsetY') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('shapeOffsetY')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('shapeOffsetY').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'polygonOrigin') {
|
||||
behaviorContent.addChild('polygonOrigin').setStringValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'vertices') {
|
||||
behaviorContent.addChild('vertices');
|
||||
// $FlowFixMe
|
||||
behaviorContent.setChild('vertices', gd.Serializer.fromJSON(newValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'density') {
|
||||
behaviorContent
|
||||
.getChild('density')
|
||||
.setDoubleValue(parseFloat(newValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'friction') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent.getChild('friction').setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('friction').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'restitution') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('restitution')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('restitution').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'linearDamping') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('linearDamping')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('linearDamping').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'angularDamping') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('angularDamping')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('angularDamping').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'gravityScale') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('gravityScale')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
behaviorContent.getChild('gravityScale').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'layers') {
|
||||
behaviorContent.getChild('layers').setIntValue(parseInt(newValue, 10));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'masks') {
|
||||
behaviorContent.getChild('masks').setIntValue(parseInt(newValue, 10));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
physics2Behavior.getProperties = function (behaviorContent) {
|
||||
var behaviorProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -337,6 +312,7 @@ module.exports = {
|
||||
return behaviorProperties;
|
||||
};
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
physics2Behavior.initializeContent = function (behaviorContent) {
|
||||
behaviorContent.addChild('bodyType').setStringValue('Dynamic');
|
||||
behaviorContent.addChild('bullet').setBoolValue(false);
|
||||
@@ -360,41 +336,40 @@ module.exports = {
|
||||
};
|
||||
|
||||
var sharedData = new gd.BehaviorSharedDataJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
sharedData.updateProperty = function (
|
||||
sharedContent,
|
||||
propertyName,
|
||||
newValue
|
||||
) {
|
||||
if (propertyName === 'gravityX') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
sharedContent.getChild('gravityX').setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
sharedContent.getChild('gravityX').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'gravityY') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
sharedContent.getChild('gravityY').setDoubleValue(newValueAsNumber);
|
||||
newValue = parseFloat(newValue);
|
||||
if (newValue !== newValue) return false;
|
||||
sharedContent.getChild('gravityY').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'scaleX') {
|
||||
const newValueAsNumber = parseInt(newValue, 10);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
sharedContent.getChild('scaleX').setDoubleValue(newValueAsNumber);
|
||||
newValue = parseInt(newValue, 10);
|
||||
if (newValue !== newValue) return false;
|
||||
sharedContent.getChild('scaleX').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'scaleY') {
|
||||
const newValueAsNumber = parseInt(newValue, 10);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
sharedContent.getChild('scaleY').setDoubleValue(newValueAsNumber);
|
||||
newValue = parseInt(newValue, 10);
|
||||
if (newValue !== newValue) return false;
|
||||
sharedContent.getChild('scaleY').setDoubleValue(newValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
sharedData.getProperties = function (sharedContent) {
|
||||
var sharedProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -427,6 +402,7 @@ module.exports = {
|
||||
|
||||
return sharedProperties;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
sharedData.initializeContent = function (behaviorContent) {
|
||||
behaviorContent.addChild('gravityX').setDoubleValue(0);
|
||||
behaviorContent.addChild('gravityY').setDoubleValue(9.8);
|
||||
@@ -446,7 +422,6 @@ module.exports = {
|
||||
'',
|
||||
'res/physics32.png',
|
||||
'Physics2Behavior',
|
||||
//@ts-ignore The class hierarchy is incorrect leading to a type error, but this is valid.
|
||||
physics2Behavior,
|
||||
sharedData
|
||||
)
|
||||
@@ -800,10 +775,10 @@ module.exports = {
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('setSleepingAllowed');
|
||||
|
||||
|
||||
// Deprecated action (fixed typo):
|
||||
aut
|
||||
.addDuplicatedAction('SetSleepingaAllowed', 'SetSleepingAllowed')
|
||||
.addDuplicatedAction("SetSleepingaAllowed", "SetSleepingAllowed")
|
||||
.setHidden();
|
||||
|
||||
aut
|
||||
@@ -1501,16 +1476,10 @@ module.exports = {
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('X component (N)'))
|
||||
.addParameter('expression', _('Y component (N)'))
|
||||
.setParameterLongDescription(
|
||||
_('A force is like an acceleration but depends on the mass.')
|
||||
)
|
||||
.setParameterLongDescription(_('A force is like an acceleration but depends on the mass.'))
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.setParameterLongDescription(_('Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyForce');
|
||||
|
||||
@@ -1530,16 +1499,10 @@ module.exports = {
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('Angle'))
|
||||
.addParameter('expression', _('Length (N)'))
|
||||
.setParameterLongDescription(
|
||||
_('A force is like an acceleration but depends on the mass.')
|
||||
)
|
||||
.setParameterLongDescription(_('A force is like an acceleration but depends on the mass.'))
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.setParameterLongDescription(_('Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyPolarForce');
|
||||
|
||||
@@ -1560,18 +1523,12 @@ module.exports = {
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('Length (N)'))
|
||||
.setParameterLongDescription(
|
||||
_('A force is like an acceleration but depends on the mass.')
|
||||
)
|
||||
.setParameterLongDescription(_('A force is like an acceleration but depends on the mass.'))
|
||||
.addParameter('expression', _('X position'))
|
||||
.addParameter('expression', _('Y position'))
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.setParameterLongDescription(_('Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyForceTowardPosition');
|
||||
|
||||
@@ -1589,18 +1546,18 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('X component (N·s or kg·m·s⁻¹)'))
|
||||
.addParameter('expression', _('Y component (N·s or kg·m·s⁻¹)'))
|
||||
.setParameterLongDescription(
|
||||
_('An impulse is like a speed addition but depends on the mass.')
|
||||
.addParameter(
|
||||
'expression',
|
||||
_('X component (N·s or kg·m·s⁻¹)')
|
||||
)
|
||||
.addParameter(
|
||||
'expression',
|
||||
_('Y component (N·s or kg·m·s⁻¹)')
|
||||
)
|
||||
.setParameterLongDescription(_('An impulse is like a speed addition but depends on the mass.'))
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.setParameterLongDescription(_('Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyImpulse');
|
||||
|
||||
@@ -1621,17 +1578,14 @@ module.exports = {
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('Angle'))
|
||||
.addParameter('expression', _('Length (N·s or kg·m·s⁻¹)'))
|
||||
.setParameterLongDescription(
|
||||
_('An impulse is like a speed addition but depends on the mass.')
|
||||
.addParameter(
|
||||
'expression',
|
||||
_('Length (N·s or kg·m·s⁻¹)')
|
||||
)
|
||||
.setParameterLongDescription(_('An impulse is like a speed addition but depends on the mass.'))
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.setParameterLongDescription(_('Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyPolarImpulse');
|
||||
|
||||
@@ -1651,19 +1605,16 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('Length (N·s or kg·m·s⁻¹)'))
|
||||
.setParameterLongDescription(
|
||||
_('An impulse is like a speed addition but depends on the mass.')
|
||||
.addParameter(
|
||||
'expression',
|
||||
_('Length (N·s or kg·m·s⁻¹)')
|
||||
)
|
||||
.setParameterLongDescription(_('An impulse is like a speed addition but depends on the mass.'))
|
||||
.addParameter('expression', _('X position'))
|
||||
.addParameter('expression', _('Y position'))
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.setParameterLongDescription(_('Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyImpulseTowardPosition');
|
||||
|
||||
@@ -1682,9 +1633,7 @@ module.exports = {
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('Torque (N·m)'))
|
||||
.setParameterLongDescription(
|
||||
_('A torque is like a rotation acceleration but depends on the mass.')
|
||||
)
|
||||
.setParameterLongDescription(_('A torque is like a rotation acceleration but depends on the mass.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyTorque');
|
||||
|
||||
@@ -1703,11 +1652,7 @@ module.exports = {
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics2Behavior')
|
||||
.addParameter('expression', _('Angular impulse (N·m·s'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'An impulse is like a rotation speed addition but depends on the mass.'
|
||||
)
|
||||
)
|
||||
.setParameterLongDescription(_('An impulse is like a rotation speed addition but depends on the mass.'))
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyAngularImpulse');
|
||||
|
||||
@@ -4116,7 +4061,10 @@ module.exports = {
|
||||
return extension;
|
||||
},
|
||||
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
const dummyBehavior = extension
|
||||
.getBehaviorMetadata('Physics2::Physics2Behavior')
|
||||
.get();
|
||||
|
@@ -1692,15 +1692,13 @@ namespace gdjs {
|
||||
|
||||
beforeUpdatingObstacles(timeDelta: float) {
|
||||
const object = this._behavior.owner;
|
||||
// Stick the object to the floor if its height has changed.
|
||||
//Stick the object to the floor if its height has changed.
|
||||
if (this._oldHeight !== object.getHeight()) {
|
||||
// TODO This should probably be done after the events because
|
||||
// the character stays at the wrong place during 1 frame.
|
||||
const deltaY =
|
||||
((this._oldHeight - object.getHeight()) *
|
||||
(object.getHeight() + object.getDrawableY() - object.getY())) /
|
||||
object.getHeight();
|
||||
object.setY(object.getY() + deltaY);
|
||||
object.setY(
|
||||
this._floorLastY -
|
||||
object.getHeight() +
|
||||
(object.getY() - object.getDrawableY())
|
||||
);
|
||||
}
|
||||
// Directly follow the floor movement on the Y axis by moving the character.
|
||||
// For the X axis, we follow the floor movement using `_requestedDeltaX`
|
||||
|
@@ -501,22 +501,6 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('can stay on a rotated platform when its height changes', function () {
|
||||
const platform = addPlatformObject(runtimeScene);
|
||||
platform.setPosition(0, -10);
|
||||
platform.setAngle(-45);
|
||||
|
||||
object.setPosition(30, -32);
|
||||
// Ensure the object falls on the platform
|
||||
fallOnPlatform(10);
|
||||
const oldY = object.getY();
|
||||
expect(object.getY()).to.be.within(-40, -39);
|
||||
|
||||
object.setHeight(object.getHeight() - 8);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getY()).to.be(oldY + 8);
|
||||
});
|
||||
});
|
||||
|
||||
[0, 25].forEach((slopeMaxAngle) => {
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -64,7 +72,9 @@ module.exports = {
|
||||
.addAction(
|
||||
'HideAuthenticationBanner',
|
||||
_('Hide authentication banner'),
|
||||
_('Hide the authentication banner from the top of the game screen.'),
|
||||
_(
|
||||
'Hide the authentication banner from the top of the game screen.'
|
||||
),
|
||||
_('Hide the authentication banner'),
|
||||
'',
|
||||
'JsPlatform/Extensions/authentication.svg',
|
||||
@@ -216,7 +226,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -124,25 +124,6 @@ void DeclarePrimitiveDrawingExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("expression", _("The height of the ellipse"))
|
||||
.SetFunctionName("DrawEllipse");
|
||||
|
||||
obj.AddAction("FilletRectangle",
|
||||
_("Fillet Rectangle"),
|
||||
_("Draw a fillet rectangle on screen"),
|
||||
_("Draw from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ a fillet "
|
||||
"rectangle (fillet: _PARAM5_)"
|
||||
"with _PARAM0_"),
|
||||
_("Drawing"),
|
||||
"res/actions/filletRectangle24.png",
|
||||
"res/actions/filletRectangle.png")
|
||||
|
||||
.AddParameter("object", _("Shape Painter object"), "Drawer")
|
||||
.AddParameter("expression", _("Left X position"))
|
||||
.AddParameter("expression", _("Top Y position"))
|
||||
.AddParameter("expression", _("Right X position"))
|
||||
.AddParameter("expression", _("Bottom Y position"))
|
||||
.AddParameter("expression", _("Fillet (in pixels)"))
|
||||
.SetFunctionName("DrawFilletRectangle");
|
||||
|
||||
|
||||
obj.AddAction("RoundedRectangle",
|
||||
_("Rounded rectangle"),
|
||||
_("Draw a rounded rectangle on screen"),
|
||||
@@ -182,9 +163,9 @@ void DeclarePrimitiveDrawingExtension(gd::PlatformExtension& extension) {
|
||||
obj.AddAction("Torus",
|
||||
_("Torus"),
|
||||
_("Draw a torus on screen"),
|
||||
_("Draw at _PARAM1_;_PARAM2_ a torus with "
|
||||
"inner radius: _PARAM3_, outer radius: _PARAM4_ and "
|
||||
"with start arc angle: _PARAM5_°, end angle: _PARAM6_° "
|
||||
_("Draw at _PARAM1_;_PARAM2_ a torus with inner radius"
|
||||
"_PARAM3_ and outer radius _PARAM4_ and "
|
||||
"with start arc _PARAM5_° and end arc _PARAM6_°"
|
||||
"with _PARAM0_"),
|
||||
_("Drawing"),
|
||||
"res/actions/torus24.png",
|
||||
|
@@ -47,11 +47,6 @@ class PrimitiveDrawingJsExtension : public gd::PlatformExtension {
|
||||
GetAllActionsForObject(
|
||||
"PrimitiveDrawing::Drawer")["PrimitiveDrawing::Ellipse"]
|
||||
.SetFunctionName("drawEllipse");
|
||||
|
||||
GetAllActionsForObject(
|
||||
"PrimitiveDrawing::Drawer")["PrimitiveDrawing::FilletRectangle"]
|
||||
.SetFunctionName("drawFilletRectangle");
|
||||
|
||||
GetAllActionsForObject(
|
||||
"PrimitiveDrawing::Drawer")["PrimitiveDrawing::RoundedRectangle"]
|
||||
.SetFunctionName("drawRoundedRectangle");
|
||||
|
@@ -136,25 +136,6 @@ namespace gdjs {
|
||||
this.invalidateBounds();
|
||||
}
|
||||
|
||||
drawFilletRectangle(
|
||||
x1: float,
|
||||
y1: float,
|
||||
x2: float,
|
||||
y2: float,
|
||||
fillet: float
|
||||
) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
this._object._fillOpacity / 255
|
||||
);
|
||||
//@ts-ignore from @pixi/graphics-extras
|
||||
this._graphics.drawFilletRect(x1, y1, x2 - x1, y2 - y1, fillet);
|
||||
this._graphics.closePath();
|
||||
this._graphics.endFill();
|
||||
this.invalidateBounds();
|
||||
}
|
||||
|
||||
drawChamferRectangle(
|
||||
x1: float,
|
||||
y1: float,
|
||||
|
@@ -210,22 +210,6 @@ namespace gdjs {
|
||||
this._renderer.drawEllipse(centerX, centerY, width, height);
|
||||
}
|
||||
|
||||
drawFilletRectangle(
|
||||
startX1: float,
|
||||
startY1: float,
|
||||
endX2: float,
|
||||
endY2: float,
|
||||
fillet: float
|
||||
) {
|
||||
this._renderer.drawFilletRectangle(
|
||||
startX1,
|
||||
startY1,
|
||||
endX2,
|
||||
endY2,
|
||||
fillet
|
||||
);
|
||||
}
|
||||
|
||||
drawRoundedRectangle(
|
||||
startX1: float,
|
||||
startY1: float,
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -51,7 +59,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -75,7 +83,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
// @ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
|
||||
extension
|
||||
@@ -86,7 +94,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
@@ -94,13 +105,17 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations: function (objectsEditorService) {},
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {},
|
||||
/**
|
||||
* Register renderers for instance of objects on the scene editor.
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const { PIXI, RenderedInstance, gd } = objectsRenderingService;
|
||||
|
||||
class RenderedSpineInstance extends RenderedInstance {
|
||||
@@ -213,6 +228,7 @@ module.exports = {
|
||||
const animation = configuration.getAnimation(index);
|
||||
const source = animation.getSource();
|
||||
const shouldLoop = animation.shouldLoop();
|
||||
const scale = this.getScale();
|
||||
|
||||
// reset scale to track new animation range
|
||||
// if custom size is set it will be reinitialized in update method
|
||||
|
@@ -138,15 +138,16 @@ namespace gdjs {
|
||||
this._loadedSpineAtlases.set(resource, atlas);
|
||||
callback(null, atlas);
|
||||
};
|
||||
const url = this._resourceLoader.getFullUrl(resource.file);
|
||||
|
||||
PIXI.Assets.setPreferences({
|
||||
preferWorkers: false,
|
||||
crossOrigin: this._resourceLoader.checkIfCredentialsRequired(url)
|
||||
crossOrigin: this._resourceLoader.checkIfCredentialsRequired(
|
||||
resource.file
|
||||
)
|
||||
? 'use-credentials'
|
||||
: 'anonymous',
|
||||
});
|
||||
PIXI.Assets.add(resource.name, url, { images });
|
||||
PIXI.Assets.add(resource.name, resource.file, { images });
|
||||
PIXI.Assets.load<pixi_spine.TextureAtlas | string>(resource.name).then(
|
||||
(atlas) => {
|
||||
/**
|
||||
|
@@ -65,14 +65,15 @@ namespace gdjs {
|
||||
const spineAtlas = await this._spineAtlasManager.getOrLoad(
|
||||
atlasResourceName
|
||||
);
|
||||
const url = this._resourceLoader.getFullUrl(resource.file);
|
||||
PIXI.Assets.setPreferences({
|
||||
preferWorkers: false,
|
||||
crossOrigin: this._resourceLoader.checkIfCredentialsRequired(url)
|
||||
crossOrigin: this._resourceLoader.checkIfCredentialsRequired(
|
||||
resource.file
|
||||
)
|
||||
? 'use-credentials'
|
||||
: 'anonymous',
|
||||
});
|
||||
PIXI.Assets.add(resource.name, url, { spineAtlas });
|
||||
PIXI.Assets.add(resource.name, resource.file, { spineAtlas });
|
||||
const loadedJson = await PIXI.Assets.load(resource.name);
|
||||
|
||||
if (loadedJson.spineData) {
|
||||
|
File diff suppressed because one or more lines are too long
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -1235,7 +1243,10 @@ module.exports = {
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,9 +12,18 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -31,6 +39,7 @@ module.exports = {
|
||||
.setIcon('JsPlatform/Extensions/text_input.svg');
|
||||
|
||||
const textInputObject = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
textInputObject.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -85,6 +94,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
textInputObject.getProperties = function (objectContent) {
|
||||
const objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -222,6 +232,7 @@ module.exports = {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
textInputObject.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -240,6 +251,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
textInputObject.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -276,7 +288,7 @@ module.exports = {
|
||||
.addIncludeFile(
|
||||
'Extensions/TextInput/textinputruntimeobject-pixi-renderer.js'
|
||||
)
|
||||
.addDefaultBehavior('TextContainerCapability::TextContainerBehavior')
|
||||
.addDefaultBehavior("TextContainerCapability::TextContainerBehavior")
|
||||
.addDefaultBehavior('ResizableCapability::ResizableBehavior')
|
||||
.addDefaultBehavior('OpacityCapability::OpacityBehavior');
|
||||
|
||||
@@ -371,7 +383,7 @@ module.exports = {
|
||||
'res/actions/font24.png',
|
||||
'res/actions/font.png'
|
||||
)
|
||||
.addParameter('object', _('Text input'), 'TextInputObject', false)
|
||||
.addParameter('object', _('Bitmap text'), 'TextInputObject', false)
|
||||
.addParameter('fontResource', _('Font resource name'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('setFontResourceName');
|
||||
@@ -388,23 +400,9 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('Text input'), 'TextInputObject', false)
|
||||
.useStandardParameters(
|
||||
'stringWithSelector',
|
||||
gd.ParameterOptions.makeNewOptions()
|
||||
.setDescription(_('Input type'))
|
||||
.setTypeExtraInfo(
|
||||
JSON.stringify([
|
||||
'text',
|
||||
'text area',
|
||||
'email',
|
||||
'password',
|
||||
'number',
|
||||
'telephone number',
|
||||
'url',
|
||||
'search',
|
||||
'email',
|
||||
])
|
||||
)
|
||||
)
|
||||
'string',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(_('Input type'))
|
||||
) // TODO: stringWithSelector?
|
||||
.setFunctionName('setInputType')
|
||||
.setGetter('getInputType');
|
||||
|
||||
@@ -587,9 +585,7 @@ module.exports = {
|
||||
.addScopedAction(
|
||||
'Focus',
|
||||
_('Focus'),
|
||||
_(
|
||||
'Focus the input so that text can be entered (like if it was touched/clicked).'
|
||||
),
|
||||
_('Focus the input so that text can be entered (like if it was touched/clicked).'),
|
||||
_('Focus _PARAM0_'),
|
||||
_(''),
|
||||
'res/conditions/surObjet24.png',
|
||||
@@ -611,7 +607,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
@@ -619,7 +618,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations: function (objectsEditorService) {
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {
|
||||
objectsEditorService.registerEditorConfiguration(
|
||||
'TextInput::TextInputObject',
|
||||
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
|
||||
@@ -632,7 +633,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
|
||||
|
@@ -204,7 +204,6 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("color", _("Third Color"))
|
||||
.AddParameter("color", _("Fourth Color"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetOutline",
|
||||
_("Outline"),
|
||||
_("Change the outline of the text. A thickness of 0 disables "
|
||||
@@ -214,63 +213,20 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
_("Effects"),
|
||||
"res/actions/textOutline24.png",
|
||||
"res/actions/textOutline.png")
|
||||
.SetHidden()
|
||||
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("color", _("Color"))
|
||||
.AddParameter("expression", _("Thickness"));
|
||||
|
||||
obj.AddScopedAction("SetOutlineEnabled",
|
||||
_("Enable outline"),
|
||||
_("Enable or disable the outline of the text."),
|
||||
_("Enable the outline of _PARAM0_: _PARAM1_"),
|
||||
_("Outline"),
|
||||
"res/actions/textOutline24.png",
|
||||
"res/actions/textOutline.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("yesorno", _("Enable outline"), "", true)
|
||||
.SetDefaultValue("yes");
|
||||
|
||||
obj.AddScopedCondition("IsOutlineEnabled",
|
||||
_("Outline enabled"),
|
||||
_("Check if the text outline is enabled."),
|
||||
_("The outline of _PARAM0_ is enabled"),
|
||||
_("Outline"),
|
||||
"res/actions/textOutline24.png",
|
||||
"res/actions/textOutline.png")
|
||||
.AddParameter("object", _("Object"), "Text");
|
||||
|
||||
obj.AddScopedAction("SetOutlineColor",
|
||||
_("Outline color"),
|
||||
_("Change the outline color of the text."),
|
||||
_("Change the text outline color of _PARAM0_ to _PARAM1_"),
|
||||
_("Outline"),
|
||||
"res/actions/textOutline24.png",
|
||||
"res/actions/textOutline.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("color", _("Color"));
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "OutlineThickness",
|
||||
_("Outline thickness"),
|
||||
_("the outline thickness of the text"),
|
||||
_("the text outline thickness"),
|
||||
_("Outline"),
|
||||
"res/actions/textOutline24.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Thickness")));
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetShadow",
|
||||
_("Text shadow"),
|
||||
_("Change the shadow of the text."),
|
||||
_("Change the shadow of _PARAM0_ to color _PARAM1_ distance "
|
||||
"_PARAM2_ blur _PARAM3_ angle _PARAM4_"),
|
||||
_("Shadow"),
|
||||
_("Effects/Shadow"),
|
||||
"res/actions/textShadow24.png",
|
||||
"res/actions/textShadow.png")
|
||||
.SetHidden()
|
||||
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("color", _("Color"))
|
||||
.AddParameter("expression", _("Distance"))
|
||||
@@ -278,82 +234,15 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("expression", _("Angle"));
|
||||
|
||||
obj.AddAction("ShowShadow",
|
||||
_("Enable shadow"),
|
||||
_("Enable or disable the shadow of the text."),
|
||||
_("Enable the shadow of _PARAM0_: _PARAM1_"),
|
||||
_("Shadow"),
|
||||
_("Show Shadow"),
|
||||
_("Show the shadow of the text."),
|
||||
_("Show the shadow of _PARAM0_: _PARAM1_"),
|
||||
_("Effects/Shadow"),
|
||||
"res/actions/textShadow24.png",
|
||||
"res/actions/textShadow.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("yesorno", _("Show the shadow"), "", true)
|
||||
.SetDefaultValue("yes");
|
||||
|
||||
obj.AddScopedCondition("IsShadowEnabled",
|
||||
_("Shadow enabled"),
|
||||
_("Check if the text shadow is enabled."),
|
||||
_("The shadow of _PARAM0_ is enabled"),
|
||||
_("Shadow"),
|
||||
"res/actions/textShadow24.png",
|
||||
"res/actions/textShadow.png")
|
||||
.AddParameter("object", _("Object"), "Text");
|
||||
|
||||
obj.AddScopedAction("SetShadowColor",
|
||||
_("Shadow color"),
|
||||
_("Change the shadow color of the text."),
|
||||
_("Change the shadow color of _PARAM0_ to _PARAM1_"),
|
||||
_("Shadow"),
|
||||
"res/actions/textShadow24.png",
|
||||
"res/actions/textShadow.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("color", _("Color"));
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "ShadowOpacity",
|
||||
_("Shadow opacity"),
|
||||
_("the shadow opacity of the text"),
|
||||
_("the shadow opacity "),
|
||||
_("Shadow"),
|
||||
"res/actions/textShadow24.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity (0 - 255)")));
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "ShadowDistance",
|
||||
_("Shadow distance"),
|
||||
_("the shadow distance of the text"),
|
||||
_("the shadow distance "),
|
||||
_("Shadow"),
|
||||
"res/actions/textShadow24.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Distance")));
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "ShadowAngle",
|
||||
_("Shadow angle"),
|
||||
_("the shadow angle of the text"),
|
||||
_("the shadow angle "),
|
||||
_("Shadow"),
|
||||
"res/actions/textShadow24.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Angle (in degrees)")));
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "ShadowBlurRadius",
|
||||
_("Shadow blur radius"),
|
||||
_("the shadow blur radius of the text"),
|
||||
_("the shadow blur radius "),
|
||||
_("Shadow"),
|
||||
"res/actions/textShadow24.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Blur radius")));
|
||||
.AddParameter("yesorno", _("Show the shadow"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("Opacity",
|
||||
|
@@ -127,60 +127,10 @@ class TextObjectJsExtension : public gd::PlatformExtension {
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::SetOutline"]
|
||||
.SetFunctionName("setOutline");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetOutlineEnabled"]
|
||||
.SetFunctionName("setOutlineEnabled");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::IsOutlineEnabled"]
|
||||
.SetFunctionName("isOutlineEnabled");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetOutlineColor"]
|
||||
.SetFunctionName("setOutlineColor");
|
||||
GetAllExpressionsForObject("TextObject::Text")["TextObject::Text::OutlineThickness"]
|
||||
.SetFunctionName("getOutlineThickness");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::OutlineThickness"]
|
||||
.SetFunctionName("getOutlineThickness");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetOutlineThickness"]
|
||||
.SetFunctionName("setOutlineThickness")
|
||||
.SetGetter("getOutlineThickness");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::SetShadow"]
|
||||
.SetFunctionName("setShadow");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::ShowShadow"]
|
||||
.SetFunctionName("showShadow");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::IsShadowEnabled"]
|
||||
.SetFunctionName("isShadowEnabled");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetShadowColor"]
|
||||
.SetFunctionName("setShadowColor");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["TextObject::Text::ShadowOpacity"]
|
||||
.SetFunctionName("getShadowOpacity");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::ShadowOpacity"]
|
||||
.SetFunctionName("getShadowOpacity");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetShadowOpacity"]
|
||||
.SetFunctionName("setShadowOpacity")
|
||||
.SetGetter("getShadowOpacity");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["TextObject::Text::ShadowDistance"]
|
||||
.SetFunctionName("getShadowDistance");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::ShadowDistance"]
|
||||
.SetFunctionName("getShadowDistance");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetShadowDistance"]
|
||||
.SetFunctionName("setShadowDistance")
|
||||
.SetGetter("getShadowDistance");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["TextObject::Text::ShadowAngle"]
|
||||
.SetFunctionName("getShadowAngle");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::ShadowAngle"]
|
||||
.SetFunctionName("getShadowAngle");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetShadowAngle"]
|
||||
.SetFunctionName("setShadowAngle")
|
||||
.SetGetter("getShadowAngle");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["TextObject::Text::ShadowBlurRadius"]
|
||||
.SetFunctionName("getShadowBlurRadius");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::ShadowBlurRadius"]
|
||||
.SetFunctionName("getShadowBlurRadius");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetShadowBlurRadius"]
|
||||
.SetFunctionName("setShadowBlurRadius")
|
||||
.SetGetter("getShadowBlurRadius");
|
||||
|
||||
// Unimplemented actions and conditions:
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Font"]
|
||||
|
@@ -12,8 +12,10 @@ This project is released under the MIT License.
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "TextObject.h"
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/IDE/AbstractFileSystem.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -25,17 +27,10 @@ TextObject::TextObject()
|
||||
bold(false),
|
||||
italic(false),
|
||||
underlined(false),
|
||||
color("0;0;0"),
|
||||
textAlignment("left"),
|
||||
isOutlineEnabled(false),
|
||||
outlineThickness(2),
|
||||
outlineColor("255;255;255"),
|
||||
isShadowEnabled(false),
|
||||
shadowColor("0;0;0"),
|
||||
shadowOpacity(127),
|
||||
shadowAngle(90),
|
||||
shadowDistance(4),
|
||||
shadowBlurRadius(2)
|
||||
colorR(0),
|
||||
colorG(0),
|
||||
colorB(0),
|
||||
textAlignment("left")
|
||||
{
|
||||
}
|
||||
|
||||
@@ -43,98 +38,41 @@ TextObject::~TextObject(){};
|
||||
|
||||
void TextObject::DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
// Compatibility with GD <= 5.3.188
|
||||
// end of compatibility code
|
||||
bool isLegacy = !element.HasChild("content");
|
||||
auto &content = isLegacy ? element : element.GetChild("content");
|
||||
|
||||
SetFontName(content.GetChild("font", 0, "Font").GetValue().GetString());
|
||||
SetTextAlignment(content.GetChild("textAlignment").GetValue().GetString());
|
||||
SetCharacterSize(content.GetChild("characterSize", 0, "CharacterSize")
|
||||
SetString(element.GetChild("string", 0, "String").GetValue().GetString());
|
||||
SetFontName(element.GetChild("font", 0, "Font").GetValue().GetString());
|
||||
SetTextAlignment(element.GetChild("textAlignment").GetValue().GetString());
|
||||
SetCharacterSize(element.GetChild("characterSize", 0, "CharacterSize")
|
||||
.GetValue()
|
||||
.GetInt());
|
||||
smoothed = content.GetBoolAttribute("smoothed");
|
||||
bold = content.GetBoolAttribute("bold");
|
||||
italic = content.GetBoolAttribute("italic");
|
||||
underlined = content.GetBoolAttribute("underlined");
|
||||
SetColor(element.GetChild("color", 0, "Color").GetIntAttribute("r", 255),
|
||||
element.GetChild("color", 0, "Color").GetIntAttribute("g", 255),
|
||||
element.GetChild("color", 0, "Color").GetIntAttribute("b", 255));
|
||||
|
||||
// Compatibility with GD <= 5.3.188
|
||||
if (isLegacy) {
|
||||
SetText(content.GetChild("string", 0, "String").GetValue().GetString());
|
||||
SetColor(
|
||||
gd::String::From(
|
||||
content.GetChild("color", 0, "Color").GetIntAttribute("r", 255)) +
|
||||
";" +
|
||||
gd::String::From(
|
||||
content.GetChild("color", 0, "Color").GetIntAttribute("g", 255)) +
|
||||
";" +
|
||||
gd::String::From(
|
||||
content.GetChild("color", 0, "Color").GetIntAttribute("b", 255)));
|
||||
} else
|
||||
// end of compatibility code
|
||||
{
|
||||
SetText(content.GetStringAttribute("text"));
|
||||
SetColor(content.GetStringAttribute("color", "0;0;0"));
|
||||
|
||||
SetOutlineEnabled(content.GetBoolAttribute("isOutlineEnabled", false));
|
||||
SetOutlineThickness(content.GetIntAttribute("outlineThickness", 2));
|
||||
SetOutlineColor(content.GetStringAttribute("outlineColor", "255;255;255"));
|
||||
|
||||
SetShadowEnabled(content.GetBoolAttribute("isShadowEnabled", false));
|
||||
SetShadowColor(content.GetStringAttribute("shadowColor", "0;0;0"));
|
||||
SetShadowOpacity(content.GetIntAttribute("shadowOpacity", 127));
|
||||
SetShadowAngle(content.GetIntAttribute("shadowAngle", 90));
|
||||
SetShadowDistance(content.GetIntAttribute("shadowDistance", 4));
|
||||
SetShadowBlurRadius(content.GetIntAttribute("shadowBlurRadius", 2));
|
||||
}
|
||||
smoothed = element.GetBoolAttribute("smoothed");
|
||||
bold = element.GetBoolAttribute("bold");
|
||||
italic = element.GetBoolAttribute("italic");
|
||||
underlined = element.GetBoolAttribute("underlined");
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void TextObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
// Allow users to rollback to 5.3.188 or older releases without loosing their configuration.
|
||||
// TODO Remove this in a few releases.
|
||||
// Compatibility with GD <= 5.3.188
|
||||
{
|
||||
element.AddChild("string").SetValue(GetText());
|
||||
element.AddChild("font").SetValue(GetFontName());
|
||||
element.AddChild("textAlignment").SetValue(GetTextAlignment());
|
||||
element.AddChild("characterSize").SetValue(GetCharacterSize());
|
||||
auto colorComponents = GetColor().Split(';');
|
||||
element.AddChild("color")
|
||||
.SetAttribute("r", colorComponents.size() == 3 ? colorComponents[0].To<int>() : 0)
|
||||
.SetAttribute("g", colorComponents.size() == 3 ? colorComponents[1].To<int>() : 0)
|
||||
.SetAttribute("b", colorComponents.size() == 3 ? colorComponents[2].To<int>() : 0);
|
||||
element.SetAttribute("smoothed", smoothed);
|
||||
element.SetAttribute("bold", bold);
|
||||
element.SetAttribute("italic", italic);
|
||||
element.SetAttribute("underlined", underlined);
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
auto& content = element.AddChild("content");
|
||||
content.AddChild("text").SetValue(GetText());
|
||||
content.AddChild("font").SetValue(GetFontName());
|
||||
content.AddChild("textAlignment").SetValue(GetTextAlignment());
|
||||
content.AddChild("characterSize").SetValue(GetCharacterSize());
|
||||
content.AddChild("color").SetValue(GetColor());
|
||||
element.AddChild("string").SetValue(GetString());
|
||||
element.AddChild("font").SetValue(GetFontName());
|
||||
element.AddChild("textAlignment").SetValue(GetTextAlignment());
|
||||
element.AddChild("characterSize").SetValue(GetCharacterSize());
|
||||
element.AddChild("color")
|
||||
.SetAttribute("r", (int)GetColorR())
|
||||
.SetAttribute("g", (int)GetColorG())
|
||||
.SetAttribute("b", (int)GetColorB());
|
||||
|
||||
content.SetAttribute("smoothed", smoothed);
|
||||
content.SetAttribute("bold", bold);
|
||||
content.SetAttribute("italic", italic);
|
||||
content.SetAttribute("underlined", underlined);
|
||||
|
||||
content.SetAttribute("isOutlineEnabled", isOutlineEnabled);
|
||||
content.SetAttribute("outlineThickness", outlineThickness);
|
||||
content.SetAttribute("outlineColor", outlineColor);
|
||||
|
||||
content.SetAttribute("isShadowEnabled", isShadowEnabled);
|
||||
content.SetAttribute("shadowColor", shadowColor);
|
||||
content.SetAttribute("shadowOpacity", shadowOpacity);
|
||||
content.SetAttribute("shadowAngle", shadowAngle);
|
||||
content.SetAttribute("shadowDistance", shadowDistance);
|
||||
content.SetAttribute("shadowBlurRadius", shadowBlurRadius);
|
||||
element.SetAttribute("smoothed", smoothed);
|
||||
element.SetAttribute("bold", bold);
|
||||
element.SetAttribute("italic", italic);
|
||||
element.SetAttribute("underlined", underlined);
|
||||
}
|
||||
|
||||
void TextObject::ExposeResources(
|
||||
gd::ArbitraryResourceWorker& worker) {
|
||||
worker.ExposeFont(fontName);
|
||||
}
|
||||
#endif
|
||||
|
@@ -5,8 +5,8 @@ Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef TEXTOBJECT_H
|
||||
#define TEXTOBJECT_H
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
namespace gd {
|
||||
class Project;
|
||||
@@ -29,11 +29,11 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
|
||||
/** \brief Change the text.
|
||||
*/
|
||||
inline void SetText(const gd::String& str) { text = str; };
|
||||
inline void SetString(const gd::String& str) { text = str; };
|
||||
|
||||
/** \brief Get the text.
|
||||
*/
|
||||
inline const gd::String& GetText() const { return text; };
|
||||
inline const gd::String& GetString() const { return text; };
|
||||
|
||||
/** \brief Change the character size.
|
||||
*/
|
||||
@@ -66,63 +66,31 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
void SetSmooth(bool smooth) { smoothed = smooth; };
|
||||
bool IsSmoothed() const { return smoothed; };
|
||||
|
||||
void SetColor(const gd::String& color_) {
|
||||
color = color_;
|
||||
void SetColor(unsigned int r, unsigned int g, unsigned int b) {
|
||||
colorR = r;
|
||||
colorG = g;
|
||||
colorB = b;
|
||||
};
|
||||
inline const gd::String& GetColor() const { return color; };
|
||||
|
||||
void SetOutlineEnabled(bool smooth) { isOutlineEnabled = smooth; };
|
||||
bool IsOutlineEnabled() const { return isOutlineEnabled; };
|
||||
|
||||
void SetOutlineThickness(double value) { outlineThickness = value; };
|
||||
double GetOutlineThickness() const { return outlineThickness; };
|
||||
|
||||
void SetOutlineColor(const gd::String& color) {
|
||||
outlineColor = color;
|
||||
};
|
||||
const gd::String& GetOutlineColor() const { return outlineColor; };
|
||||
|
||||
void SetShadowEnabled(bool smooth) { isShadowEnabled = smooth; };
|
||||
bool IsShadowEnabled() const { return isShadowEnabled; };
|
||||
|
||||
void SetShadowColor(const gd::String& color) {
|
||||
shadowColor = color;
|
||||
};
|
||||
const gd::String& GetShadowColor() const { return shadowColor; };
|
||||
|
||||
void SetShadowOpacity(double value) { shadowOpacity = value; };
|
||||
double GetShadowOpacity() const { return shadowOpacity; };
|
||||
|
||||
void SetShadowAngle(double value) { shadowAngle = value; };
|
||||
double GetShadowAngle() const { return shadowAngle; };
|
||||
|
||||
void SetShadowDistance(double value) { shadowDistance = value; };
|
||||
double GetShadowDistance() const { return shadowDistance; };
|
||||
|
||||
void SetShadowBlurRadius(double value) { shadowBlurRadius = value; };
|
||||
double GetShadowBlurRadius() const { return shadowBlurRadius; };
|
||||
unsigned int GetColorR() const { return colorR; };
|
||||
unsigned int GetColorG() const { return colorG; };
|
||||
unsigned int GetColorB() const { return colorB; };
|
||||
|
||||
private:
|
||||
virtual void DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual void DoSerializeTo(gd::SerializerElement& element) const;
|
||||
#endif
|
||||
|
||||
gd::String text;
|
||||
double characterSize;
|
||||
gd::String fontName;
|
||||
bool smoothed;
|
||||
bool bold, italic, underlined;
|
||||
gd::String color;
|
||||
unsigned int colorR;
|
||||
unsigned int colorG;
|
||||
unsigned int colorB;
|
||||
gd::String textAlignment;
|
||||
|
||||
bool isOutlineEnabled;
|
||||
double outlineThickness;
|
||||
gd::String outlineColor;
|
||||
|
||||
bool isShadowEnabled;
|
||||
gd::String shadowColor;
|
||||
double shadowOpacity;
|
||||
double shadowAngle;
|
||||
double shadowDistance;
|
||||
double shadowBlurRadius;
|
||||
};
|
||||
|
||||
#endif // TEXTOBJECT_H
|
||||
|
@@ -69,23 +69,17 @@ namespace gdjs {
|
||||
this._object._outlineColor[1],
|
||||
this._object._outlineColor[2]
|
||||
);
|
||||
style.strokeThickness = this._object._isOutlineEnabled
|
||||
? this._object._outlineThickness
|
||||
: 0;
|
||||
style.strokeThickness = this._object._outlineThickness;
|
||||
style.dropShadow = this._object._shadow;
|
||||
style.dropShadowColor = gdjs.rgbToHexNumber(
|
||||
this._object._shadowColor[0],
|
||||
this._object._shadowColor[1],
|
||||
this._object._shadowColor[2]
|
||||
);
|
||||
style.dropShadowAlpha = this._object._shadowOpacity / 255;
|
||||
style.dropShadowBlur = this._object._shadowBlur;
|
||||
style.dropShadowAngle = gdjs.toRad(this._object._shadowAngle);
|
||||
style.dropShadowAngle = this._object._shadowAngle;
|
||||
style.dropShadowDistance = this._object._shadowDistance;
|
||||
const extraPaddingForShadow = style.dropShadow
|
||||
? style.dropShadowDistance + style.dropShadowBlur
|
||||
: 0;
|
||||
style.padding = Math.ceil(this._object._padding + extraPaddingForShadow);
|
||||
style.padding = this._object._padding;
|
||||
|
||||
// Prevent spikey outlines by adding a miter limit
|
||||
style.miterLimit = 3;
|
||||
|
@@ -5,35 +5,28 @@
|
||||
namespace gdjs {
|
||||
/** Base parameters for gdjs.TextRuntimeObject */
|
||||
export type TextObjectDataType = {
|
||||
content: {
|
||||
/** The size of the characters */
|
||||
characterSize: number;
|
||||
/** The font name */
|
||||
font: string;
|
||||
/** Is Bold? */
|
||||
bold: boolean;
|
||||
/** Is Italic? */
|
||||
italic: boolean;
|
||||
/** Is Underlined? */
|
||||
underlined: boolean;
|
||||
/** The text color in an RGB representation */
|
||||
color: string;
|
||||
/** The text of the object */
|
||||
text: string;
|
||||
textAlignment: string;
|
||||
|
||||
isOutlineEnabled: boolean;
|
||||
outlineThickness: float;
|
||||
/** The outline color in an RGB representation */
|
||||
outlineColor: string;
|
||||
isShadowEnabled: boolean;
|
||||
/** The shadow color in an RGB representation */
|
||||
shadowColor: string;
|
||||
shadowOpacity: float;
|
||||
shadowDistance: float;
|
||||
shadowAngle: float;
|
||||
shadowBlurRadius: float;
|
||||
/** The size of the characters */
|
||||
characterSize: number;
|
||||
/** The font name */
|
||||
font: string;
|
||||
/** Is Bold? */
|
||||
bold: boolean;
|
||||
/** Is Italic? */
|
||||
italic: boolean;
|
||||
/** Is Underlined? */
|
||||
underlined: boolean;
|
||||
/** The text color in an RGB representation */
|
||||
color: {
|
||||
/** The Red level from 0 to 255 */
|
||||
r: number;
|
||||
/** The Green level from 0 to 255 */
|
||||
g: number;
|
||||
/** The Blue level from 0 to 255 */
|
||||
b: number;
|
||||
};
|
||||
/** The text of the object */
|
||||
string: string;
|
||||
textAlignment: string;
|
||||
};
|
||||
|
||||
export type TextObjectData = ObjectData & TextObjectDataType;
|
||||
@@ -56,20 +49,14 @@ namespace gdjs {
|
||||
opacity: float = 255;
|
||||
_textAlign: string = 'left';
|
||||
_wrapping: boolean = false;
|
||||
// A wrapping of 1 makes games crash on Firefox
|
||||
_wrappingWidth: float = 100;
|
||||
|
||||
_isOutlineEnabled: boolean;
|
||||
_outlineThickness: float;
|
||||
_outlineColor: integer[];
|
||||
|
||||
_shadow: boolean;
|
||||
_shadowColor: integer[];
|
||||
_shadowOpacity: float;
|
||||
_shadowDistance: float;
|
||||
_shadowAngle: float;
|
||||
_shadowBlur: float;
|
||||
|
||||
_wrappingWidth: float = 1;
|
||||
_outlineThickness: number = 0;
|
||||
_outlineColor: integer[] = [255, 255, 255];
|
||||
_shadow: boolean = false;
|
||||
_shadowColor: integer[] = [0, 0, 0];
|
||||
_shadowDistance: number = 1;
|
||||
_shadowBlur: integer = 1;
|
||||
_shadowAngle: float = 0;
|
||||
_padding: integer = 5;
|
||||
_str: string;
|
||||
_renderer: gdjs.TextRuntimeObjectRenderer;
|
||||
@@ -87,27 +74,18 @@ namespace gdjs {
|
||||
textObjectData: TextObjectData
|
||||
) {
|
||||
super(instanceContainer, textObjectData);
|
||||
const content = textObjectData.content;
|
||||
this._characterSize = Math.max(1, content.characterSize);
|
||||
this._fontName = content.font;
|
||||
this._bold = content.bold;
|
||||
this._italic = content.italic;
|
||||
this._underlined = content.underlined;
|
||||
this._color = gdjs.rgbOrHexToRGBColor(content.color);
|
||||
this._str = content.text;
|
||||
this._textAlign = content.textAlignment;
|
||||
|
||||
this._isOutlineEnabled = content.isOutlineEnabled;
|
||||
this._outlineThickness = content.outlineThickness;
|
||||
this._outlineColor = gdjs.rgbOrHexToRGBColor(content.outlineColor);
|
||||
|
||||
this._shadow = content.isShadowEnabled;
|
||||
this._shadowColor = gdjs.rgbOrHexToRGBColor(content.shadowColor);
|
||||
this._shadowOpacity = content.shadowOpacity;
|
||||
this._shadowDistance = content.shadowDistance;
|
||||
this._shadowBlur = content.shadowBlurRadius;
|
||||
this._shadowAngle = content.shadowAngle;
|
||||
|
||||
this._characterSize = Math.max(1, textObjectData.characterSize);
|
||||
this._fontName = textObjectData.font;
|
||||
this._bold = textObjectData.bold;
|
||||
this._italic = textObjectData.italic;
|
||||
this._underlined = textObjectData.underlined;
|
||||
this._color = [
|
||||
textObjectData.color.r,
|
||||
textObjectData.color.g,
|
||||
textObjectData.color.b,
|
||||
];
|
||||
this._str = textObjectData.string;
|
||||
this._textAlign = textObjectData.textAlignment;
|
||||
this._renderer = new gdjs.TextRuntimeObjectRenderer(
|
||||
this,
|
||||
instanceContainer
|
||||
@@ -121,58 +99,40 @@ namespace gdjs {
|
||||
oldObjectData: TextObjectData,
|
||||
newObjectData: TextObjectData
|
||||
): boolean {
|
||||
const oldContent = oldObjectData.content;
|
||||
const newContent = newObjectData.content;
|
||||
if (oldContent.characterSize !== newContent.characterSize) {
|
||||
this.setCharacterSize(newContent.characterSize);
|
||||
if (oldObjectData.characterSize !== newObjectData.characterSize) {
|
||||
this.setCharacterSize(newObjectData.characterSize);
|
||||
}
|
||||
if (oldContent.font !== newContent.font) {
|
||||
this.setFontName(newContent.font);
|
||||
if (oldObjectData.font !== newObjectData.font) {
|
||||
this.setFontName(newObjectData.font);
|
||||
}
|
||||
if (oldContent.bold !== newContent.bold) {
|
||||
this.setBold(newContent.bold);
|
||||
if (oldObjectData.bold !== newObjectData.bold) {
|
||||
this.setBold(newObjectData.bold);
|
||||
}
|
||||
if (oldContent.italic !== newContent.italic) {
|
||||
this.setItalic(newContent.italic);
|
||||
if (oldObjectData.italic !== newObjectData.italic) {
|
||||
this.setItalic(newObjectData.italic);
|
||||
}
|
||||
if (oldContent.color !== newContent.color) {
|
||||
this.setColor(newContent.color);
|
||||
if (
|
||||
oldObjectData.color.r !== newObjectData.color.r ||
|
||||
oldObjectData.color.g !== newObjectData.color.g ||
|
||||
oldObjectData.color.b !== newObjectData.color.b
|
||||
) {
|
||||
this.setColor(
|
||||
'' +
|
||||
newObjectData.color.r +
|
||||
';' +
|
||||
newObjectData.color.g +
|
||||
';' +
|
||||
newObjectData.color.b
|
||||
);
|
||||
}
|
||||
if (oldContent.text !== newContent.text) {
|
||||
this.setText(newContent.text);
|
||||
if (oldObjectData.string !== newObjectData.string) {
|
||||
this.setString(newObjectData.string);
|
||||
}
|
||||
if (oldContent.underlined !== newContent.underlined) {
|
||||
if (oldObjectData.underlined !== newObjectData.underlined) {
|
||||
return false;
|
||||
}
|
||||
if (oldContent.textAlignment !== newContent.textAlignment) {
|
||||
this.setTextAlignment(newContent.textAlignment);
|
||||
}
|
||||
if (oldContent.isOutlineEnabled !== newContent.isOutlineEnabled) {
|
||||
this.setOutlineEnabled(newContent.isOutlineEnabled);
|
||||
}
|
||||
if (oldContent.outlineThickness !== newContent.outlineThickness) {
|
||||
this.setOutlineThickness(newContent.outlineThickness);
|
||||
}
|
||||
if (oldContent.outlineColor !== newContent.outlineColor) {
|
||||
this.setOutlineColor(newContent.outlineColor);
|
||||
}
|
||||
if (oldContent.isShadowEnabled !== newContent.isShadowEnabled) {
|
||||
this.showShadow(newContent.isShadowEnabled);
|
||||
}
|
||||
if (oldContent.shadowColor !== newContent.shadowColor) {
|
||||
this.setShadowColor(newContent.shadowColor);
|
||||
}
|
||||
if (oldContent.shadowOpacity !== newContent.shadowOpacity) {
|
||||
this.setShadowOpacity(newContent.shadowOpacity);
|
||||
}
|
||||
if (oldContent.shadowDistance !== newContent.shadowDistance) {
|
||||
this.setShadowDistance(newContent.shadowDistance);
|
||||
}
|
||||
if (oldContent.shadowAngle !== newContent.shadowAngle) {
|
||||
this.setShadowAngle(newContent.shadowAngle);
|
||||
}
|
||||
if (oldContent.shadowBlurRadius !== newContent.shadowBlurRadius) {
|
||||
this.setShadowBlurRadius(newContent.shadowBlurRadius);
|
||||
if (oldObjectData.textAlignment !== newObjectData.textAlignment) {
|
||||
this.setTextAlignment(newObjectData.textAlignment);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -195,8 +155,8 @@ namespace gdjs {
|
||||
*/
|
||||
extraInitializationFromInitialInstance(initialInstanceData: InstanceData) {
|
||||
if (initialInstanceData.customSize) {
|
||||
this.setWrappingWidth(initialInstanceData.width);
|
||||
this.setWrapping(true);
|
||||
this.setWrappingWidth(initialInstanceData.width);
|
||||
} else {
|
||||
this.setWrapping(false);
|
||||
}
|
||||
@@ -213,7 +173,7 @@ namespace gdjs {
|
||||
/**
|
||||
* Set object position on X axis.
|
||||
*/
|
||||
setX(x: float): void {
|
||||
setX(x): void {
|
||||
super.setX(x);
|
||||
this._updateTextPosition();
|
||||
}
|
||||
@@ -221,7 +181,7 @@ namespace gdjs {
|
||||
/**
|
||||
* Set object position on Y axis.
|
||||
*/
|
||||
setY(y: float): void {
|
||||
setY(y): void {
|
||||
super.setY(y);
|
||||
this._updateTextPosition();
|
||||
}
|
||||
@@ -238,7 +198,7 @@ namespace gdjs {
|
||||
/**
|
||||
* Set object opacity.
|
||||
*/
|
||||
setOpacity(opacity: float): void {
|
||||
setOpacity(opacity): void {
|
||||
if (opacity < 0) {
|
||||
opacity = 0;
|
||||
}
|
||||
@@ -332,7 +292,7 @@ namespace gdjs {
|
||||
* Set bold for the object text.
|
||||
* @param enable {boolean} true to have a bold text, false otherwise.
|
||||
*/
|
||||
setBold(enable: boolean): void {
|
||||
setBold(enable): void {
|
||||
this._bold = enable;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
@@ -348,7 +308,7 @@ namespace gdjs {
|
||||
* Set italic for the object text.
|
||||
* @param enable {boolean} true to have an italic text, false otherwise.
|
||||
*/
|
||||
setItalic(enable: boolean): void {
|
||||
setItalic(enable): void {
|
||||
this._italic = enable;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
@@ -514,22 +474,17 @@ namespace gdjs {
|
||||
if (width <= 1) {
|
||||
width = 1;
|
||||
}
|
||||
if (this._wrappingWidth === width) {
|
||||
return;
|
||||
}
|
||||
this._wrappingWidth = width;
|
||||
if (this._wrappingWidth === width) return;
|
||||
|
||||
if (this._wrapping) {
|
||||
this._renderer.updateStyle();
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
this._wrappingWidth = width;
|
||||
this._renderer.updateStyle();
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the outline for the text object.
|
||||
* @param str color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param thickness thickness of the outline (0 = disabled)
|
||||
* @deprecated Prefer independent setters.
|
||||
*/
|
||||
setOutline(str: string, thickness: number): void {
|
||||
const color = str.split(';');
|
||||
@@ -543,48 +498,12 @@ namespace gdjs {
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
isOutlineEnabled(): boolean {
|
||||
return this._isOutlineEnabled;
|
||||
}
|
||||
|
||||
setOutlineEnabled(enable: boolean): void {
|
||||
this._isOutlineEnabled = enable;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the outline thickness of the text object.
|
||||
* @return the outline thickness
|
||||
*/
|
||||
getOutlineThickness(): number {
|
||||
return this._outlineThickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the outline thickness of the text object.
|
||||
* @param value the outline thickness
|
||||
*/
|
||||
setOutlineThickness(value: float): void {
|
||||
this._outlineThickness = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow color of the text object.
|
||||
* @param color the shadow color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
setOutlineColor(color: string): void {
|
||||
this._outlineColor = gdjs.rgbOrHexToRGBColor(color);
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow for the text object.
|
||||
* @param str color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param distance distance between the shadow and the text, in pixels.
|
||||
* @param blur amount of shadow blur, in pixels.
|
||||
* @param angle shadow offset direction, in degrees.
|
||||
* @deprecated Prefer independent setters.
|
||||
*/
|
||||
setShadow(
|
||||
str: string,
|
||||
@@ -606,96 +525,6 @@ namespace gdjs {
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
isShadowEnabled(): boolean {
|
||||
return this._shadow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the shadow of the text object.
|
||||
* @param enable true to show the shadow, false to hide it
|
||||
*/
|
||||
showShadow(enable: boolean): void {
|
||||
this._shadow = enable;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shadow opacity of the text object.
|
||||
* @return the opacity (0 - 255)
|
||||
*/
|
||||
getShadowOpacity(): number {
|
||||
return this._shadowOpacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow opacity of the text object.
|
||||
* @param value the opacity (0 - 255)
|
||||
*/
|
||||
setShadowOpacity(value: float): void {
|
||||
this._shadowOpacity = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shadow offset distance of the text object.
|
||||
* @return the shadow offset distance
|
||||
*/
|
||||
getShadowDistance(): number {
|
||||
return this._shadowDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow offset distance of the text object.
|
||||
* @param value the shadow offset distance
|
||||
*/
|
||||
setShadowDistance(value: float): void {
|
||||
this._shadowDistance = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shadow offset angle of the text object.
|
||||
* @return the shadow offset angle in degrees
|
||||
*/
|
||||
getShadowAngle(): number {
|
||||
return this._shadowAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow offset angle of the text object.
|
||||
* @param value the shadow offset angle in degrees
|
||||
*/
|
||||
setShadowAngle(value: float): void {
|
||||
this._shadowAngle = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shadow blur radius of the text object.
|
||||
* @return the shadow blur radius
|
||||
*/
|
||||
getShadowBlurRadius(): number {
|
||||
return this._shadowBlur;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow blur radius of the text object.
|
||||
* @param value the shadow blur radius
|
||||
*/
|
||||
setShadowBlurRadius(value: float): void {
|
||||
this._shadowBlur = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shadow color of the text object.
|
||||
* @param color the shadow color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
setShadowColor(color: string): void {
|
||||
this._shadowColor = gdjs.rgbOrHexToRGBColor(color);
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the gradient for the text object.
|
||||
* @param strFirstColor color as a "R;G;B" string, for example: "255;0;0"
|
||||
@@ -749,6 +578,15 @@ namespace gdjs {
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the shadow of the text object.
|
||||
* @param enable true to show the shadow, false to hide it
|
||||
*/
|
||||
showShadow(enable: boolean): void {
|
||||
this._shadow = enable;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get padding of the text object.
|
||||
* @return number of pixels around the text before it gets cropped
|
||||
|
@@ -1,5 +1,5 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
|
||||
/// <reference path="helper/TileMapHelper.d.ts" />
|
||||
|
||||
/**
|
||||
@@ -15,13 +15,20 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {gd.PlatformExtension} extension
|
||||
* @param {(translationSource: string) => string} _
|
||||
* @param {GDNamespace} gd
|
||||
*/
|
||||
const defineTileMap = function (extension, _, gd) {
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
const defineTileMap = function (
|
||||
extension,
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
var objectTileMap = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
objectTileMap.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -62,6 +69,7 @@ const defineTileMap = function (extension, _, gd) {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
objectTileMap.getProperties = function (objectContent) {
|
||||
var objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -160,6 +168,7 @@ const defineTileMap = function (extension, _, gd) {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
objectTileMap.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -170,6 +179,7 @@ const defineTileMap = function (extension, _, gd) {
|
||||
) {
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
objectTileMap.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -598,13 +608,13 @@ const defineTileMap = function (extension, _, gd) {
|
||||
.setFunctionName('setHeight');
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {gd.PlatformExtension} extension
|
||||
* @param {(translationSource: string) => string} _
|
||||
* @param {GDNamespace} gd
|
||||
*/
|
||||
const defineCollisionMask = function (extension, _, gd) {
|
||||
const defineCollisionMask = function (
|
||||
extension,
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
var collisionMaskObject = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
collisionMaskObject.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -649,6 +659,7 @@ const defineCollisionMask = function (extension, _, gd) {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
collisionMaskObject.getProperties = function (objectContent) {
|
||||
var objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -757,6 +768,7 @@ const defineCollisionMask = function (extension, _, gd) {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
collisionMaskObject.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -767,6 +779,7 @@ const defineCollisionMask = function (extension, _, gd) {
|
||||
) {
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
collisionMaskObject.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -1020,7 +1033,6 @@ const defineCollisionMask = function (extension, _, gd) {
|
||||
.setFunctionName('setHeight');
|
||||
};
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
module.exports = {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
@@ -1081,7 +1093,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
@@ -1089,7 +1104,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerEditorConfigurations: function (objectsEditorService) {
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {
|
||||
objectsEditorService.registerEditorConfiguration(
|
||||
'TileMap::TileMap',
|
||||
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
|
||||
@@ -1108,7 +1125,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
|
||||
@@ -1219,33 +1238,33 @@ module.exports = {
|
||||
updateTileMap() {
|
||||
// Get the tileset resource to use
|
||||
const tilemapAtlasImage = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('tilemapAtlasImage')
|
||||
.getValue();
|
||||
const tilemapJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('tilemapJsonFile')
|
||||
.getValue();
|
||||
const tilesetJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('tilesetJsonFile')
|
||||
.getValue();
|
||||
const layerIndex = parseInt(
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('layerIndex')
|
||||
.getValue(),
|
||||
10
|
||||
);
|
||||
const levelIndex = parseInt(
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('levelIndex')
|
||||
.getValue(),
|
||||
10
|
||||
);
|
||||
const displayMode = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('displayMode')
|
||||
.getValue();
|
||||
|
||||
@@ -1287,7 +1306,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
/** @type {TileMapHelper.TileTextureCache} */
|
||||
manager.getOrLoadTextureCache(
|
||||
const textureCache = manager.getOrLoadTextureCache(
|
||||
this._loadTileMapWithCallback.bind(this),
|
||||
(textureName) =>
|
||||
this._pixiResourcesLoader.getPIXITexture(
|
||||
@@ -1338,14 +1357,14 @@ module.exports = {
|
||||
|
||||
async _loadTileMap(tilemapJsonFile, tilesetJsonFile) {
|
||||
try {
|
||||
const tileMapJsonData = await this._pixiResourcesLoader.getResourceJsonData(
|
||||
this._project,
|
||||
tilemapJsonFile
|
||||
);
|
||||
const tileMapJsonData =
|
||||
await this._pixiResourcesLoader.getResourceJsonData(
|
||||
this._project,
|
||||
tilemapJsonFile
|
||||
);
|
||||
|
||||
const tileMap = TilemapHelper.TileMapManager.identify(
|
||||
tileMapJsonData
|
||||
);
|
||||
const tileMap =
|
||||
TilemapHelper.TileMapManager.identify(tileMapJsonData);
|
||||
|
||||
if (tileMap.kind === 'tiled') {
|
||||
const tilesetJsonData = tilesetJsonFile
|
||||
@@ -1502,45 +1521,43 @@ module.exports = {
|
||||
* This is used to reload the Tilemap
|
||||
*/
|
||||
updateTileMap() {
|
||||
// This might become useful in the future
|
||||
/*
|
||||
// Get the tileset resource to use
|
||||
const tilemapAtlasImage = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('tilemapAtlasImage')
|
||||
.getValue();
|
||||
*/
|
||||
const tilemapJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('tilemapJsonFile')
|
||||
.getValue();
|
||||
const tilesetJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('tilesetJsonFile')
|
||||
.getValue();
|
||||
const collisionMaskTag = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('collisionMaskTag')
|
||||
.getValue();
|
||||
const outlineColor = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('outlineColor')
|
||||
.getValue()
|
||||
);
|
||||
const fillColor = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.getProperties(this.project)
|
||||
.get('fillColor')
|
||||
.getValue()
|
||||
);
|
||||
const outlineOpacity =
|
||||
+this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('outlineOpacity')
|
||||
.getValue() / 255;
|
||||
const fillOpacity =
|
||||
+this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('fillOpacity')
|
||||
.getValue() / 255;
|
||||
const outlineSize = 1;
|
||||
@@ -1584,14 +1601,14 @@ module.exports = {
|
||||
|
||||
async _loadTileMap(tilemapJsonFile, tilesetJsonFile) {
|
||||
try {
|
||||
const tileMapJsonData = await this._pixiResourcesLoader.getResourceJsonData(
|
||||
this._project,
|
||||
tilemapJsonFile
|
||||
);
|
||||
const tileMapJsonData =
|
||||
await this._pixiResourcesLoader.getResourceJsonData(
|
||||
this._project,
|
||||
tilemapJsonFile
|
||||
);
|
||||
|
||||
const tileMap = TilemapHelper.TileMapManager.identify(
|
||||
tileMapJsonData
|
||||
);
|
||||
const tileMap =
|
||||
TilemapHelper.TileMapManager.identify(tileMapJsonData);
|
||||
|
||||
if (tileMap.kind === 'tiled') {
|
||||
const tilesetJsonData = tilesetJsonFile
|
||||
|
@@ -1,5 +1,5 @@
|
||||
declare namespace PIXI {
|
||||
export namespace tilemap {
|
||||
namespace tilemap {
|
||||
/**
|
||||
* The renderer plugin for canvas. It isn't registered by default.
|
||||
*
|
||||
|
@@ -96,7 +96,7 @@ TopDownMovementBehavior::GetProperties(
|
||||
.SetType("Boolean");
|
||||
|
||||
gd::String viewpoint = behaviorContent.GetStringAttribute("viewpoint");
|
||||
gd::String viewpointStr = _("Top-Down");
|
||||
gd::String viewpointStr = _("Viewpoint");
|
||||
if (viewpoint == "TopDown")
|
||||
viewpointStr = _("Top-Down");
|
||||
else if (viewpoint == "PixelIsometry")
|
||||
@@ -108,7 +108,6 @@ TopDownMovementBehavior::GetProperties(
|
||||
properties["Viewpoint"]
|
||||
.SetLabel(_("Viewpoint"))
|
||||
.SetGroup(_("Viewpoint"))
|
||||
.SetAdvanced()
|
||||
.SetValue(viewpointStr)
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("Top-Down"))
|
||||
@@ -118,7 +117,6 @@ TopDownMovementBehavior::GetProperties(
|
||||
properties["CustomIsometryAngle"]
|
||||
.SetLabel(_("Custom isometry angle (between 1deg and 44deg)"))
|
||||
.SetGroup(_("Viewpoint"))
|
||||
.SetAdvanced()
|
||||
.SetType("Number")
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetDegreeAngle())
|
||||
.SetValue(gd::String::From(
|
||||
@@ -128,7 +126,6 @@ TopDownMovementBehavior::GetProperties(
|
||||
properties["MovementAngleOffset"]
|
||||
.SetLabel(_("Movement angle offset"))
|
||||
.SetGroup(_("Viewpoint"))
|
||||
.SetAdvanced()
|
||||
.SetType("Number")
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetDegreeAngle())
|
||||
.SetValue(gd::String::From(
|
||||
|
@@ -1,5 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -13,6 +12,13 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
const easingChoices = JSON.stringify([
|
||||
'linear',
|
||||
'easeInQuad',
|
||||
@@ -51,9 +57,11 @@ const easingChoices = JSON.stringify([
|
||||
'easeTo',
|
||||
]);
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -379,61 +387,57 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/TweenBehavior/tweentools.js')
|
||||
.setFunctionName('gdjs.evtTools.tween.tweenCameraRotation2');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'TweenNumberEffectPropertyTween',
|
||||
_('Tween number effect property'),
|
||||
_(
|
||||
'Tweens a number effect property from its current value to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the property _PARAM5_ for effect _PARAM4_ of _PARAM3_ to _PARAM2_ with easing _PARAM6_ over _PARAM7_ seconds as _PARAM1_'
|
||||
),
|
||||
_('Scene Tweens'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'sceneTween')
|
||||
.addParameter('expression', _('To value'), '', false)
|
||||
.addParameter('layer', _('Layer'), '', true)
|
||||
.addParameter('layerEffectName', _('Effect name'))
|
||||
.addParameter('layerEffectParameterName', _('Property name'))
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/TweenBehavior/TweenManager.js')
|
||||
.addIncludeFile('Extensions/TweenBehavior/tweentools.js')
|
||||
.setFunctionName('gdjs.evtTools.tween.tweenNumberEffectPropertyTween');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'TweenColorEffectPropertyTween',
|
||||
_('Tween color effect property'),
|
||||
_(
|
||||
'Tweens a color effect property from its current value to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the color property _PARAM5_ for effect _PARAM4_ of _PARAM3_ to _PARAM2_ with easing _PARAM6_ over _PARAM7_ seconds as _PARAM1_'
|
||||
),
|
||||
_('Scene Tweens'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'sceneTween')
|
||||
.addParameter('color', _('To color'), '', false)
|
||||
.addParameter('layer', _('Layer'), '', true)
|
||||
.addParameter('layerEffectName', _('Effect name'))
|
||||
.addParameter('layerEffectParameterName', _('Property name'))
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/TweenBehavior/TweenManager.js')
|
||||
.addIncludeFile('Extensions/TweenBehavior/tweentools.js')
|
||||
.setFunctionName('gdjs.evtTools.tween.tweenColorEffectPropertyTween');
|
||||
extension
|
||||
.addAction(
|
||||
'TweenNumberEffectPropertyTween',
|
||||
_('Tween number effect property'),
|
||||
_('Tweens a number effect property from its current value to a new one.'),
|
||||
_(
|
||||
'Tween the property _PARAM5_ for effect _PARAM4_ of _PARAM3_ to _PARAM2_ with easing _PARAM6_ over _PARAM7_ seconds as _PARAM1_'
|
||||
),
|
||||
_('Scene Tweens'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'sceneTween')
|
||||
.addParameter('expression', _('To value'), '', false)
|
||||
.addParameter('layer', _('Layer'), '', true)
|
||||
.addParameter("layerEffectName", _("Effect name"))
|
||||
.addParameter("layerEffectParameterName", _("Property name"))
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/TweenBehavior/TweenManager.js')
|
||||
.addIncludeFile('Extensions/TweenBehavior/tweentools.js')
|
||||
.setFunctionName('gdjs.evtTools.tween.tweenNumberEffectPropertyTween');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'TweenColorEffectPropertyTween',
|
||||
_('Tween color effect property'),
|
||||
_('Tweens a color effect property from its current value to a new one.'),
|
||||
_(
|
||||
'Tween the color property _PARAM5_ for effect _PARAM4_ of _PARAM3_ to _PARAM2_ with easing _PARAM6_ over _PARAM7_ seconds as _PARAM1_'
|
||||
),
|
||||
_('Scene Tweens'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'sceneTween')
|
||||
.addParameter('color', _('To color'), '', false)
|
||||
.addParameter('layer', _('Layer'), '', true)
|
||||
.addParameter("layerEffectName", _("Effect name"))
|
||||
.addParameter("layerEffectParameterName", _("Property name"))
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/TweenBehavior/TweenManager.js')
|
||||
.addIncludeFile('Extensions/TweenBehavior/tweentools.js')
|
||||
.setFunctionName('gdjs.evtTools.tween.tweenColorEffectPropertyTween');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
@@ -563,7 +567,7 @@ module.exports = {
|
||||
'Progress',
|
||||
_('Tween progress'),
|
||||
_('the progress of a tween (between 0.0 and 1.0)'),
|
||||
_('the progress of the scene tween _PARAM1_'),
|
||||
_('the progress of a tween'),
|
||||
_('Scene Tweens'),
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
@@ -593,6 +597,7 @@ module.exports = {
|
||||
|
||||
const tweenBehavior = new gd.BehaviorJsImplementation();
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
tweenBehavior.updateProperty = function (
|
||||
behaviorContent,
|
||||
propertyName,
|
||||
@@ -601,11 +606,13 @@ module.exports = {
|
||||
return false;
|
||||
};
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
tweenBehavior.getProperties = function (behaviorContent) {
|
||||
var behaviorProperties = new gd.MapStringPropertyDescriptor();
|
||||
return behaviorProperties;
|
||||
};
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating a behavior
|
||||
tweenBehavior.initializeContent = function (behaviorContent) {};
|
||||
|
||||
const behavior = extension
|
||||
@@ -619,7 +626,6 @@ module.exports = {
|
||||
'',
|
||||
'JsPlatform/Extensions/tween_behavior32.png',
|
||||
'TweenBehavior',
|
||||
// @ts-ignore - TODO: Fix tweenBehavior being an BehaviorJsImplementation instead of an Behavior
|
||||
tweenBehavior,
|
||||
new gd.BehaviorsSharedData()
|
||||
)
|
||||
@@ -920,37 +926,37 @@ module.exports = {
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectPositionZTween');
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
'AddObjectPositionZTween2',
|
||||
_('Tween object Z position'),
|
||||
_(
|
||||
'Tweens an object Z position (3D objects only) from its current Z position to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the Z position of _PARAM0_ to _PARAM4_ with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Position'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter('behavior', _('3D capability'), 'Scene3D::Base3DBehavior')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To Z'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectPositionZTween2');
|
||||
behavior
|
||||
.addAction(
|
||||
'AddObjectPositionZTween2',
|
||||
_('Tween object Z position'),
|
||||
_(
|
||||
'Tweens an object Z position (3D objects only) from its current Z position to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the Z position of _PARAM0_ to _PARAM4_ with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Position'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter("behavior", _("3D capability"), "Scene3D::Base3DBehavior")
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To Z'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectPositionZTween2');
|
||||
|
||||
// deprecated
|
||||
behavior
|
||||
@@ -1105,37 +1111,37 @@ module.exports = {
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectDepthTween');
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
'AddObjectDepthTween2',
|
||||
_('Tween object depth'),
|
||||
_(
|
||||
'Tweens an object depth (suitable 3D objects only) from its current depth to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the depth of _PARAM0_ to _PARAM4_ with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Size'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter('behavior', _('3D capability'), 'Scene3D::Base3DBehavior')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To depth'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectDepthTween2');
|
||||
behavior
|
||||
.addAction(
|
||||
'AddObjectDepthTween2',
|
||||
_('Tween object depth'),
|
||||
_(
|
||||
'Tweens an object depth (suitable 3D objects only) from its current depth to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the depth of _PARAM0_ to _PARAM4_ with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Size'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter("behavior", _("3D capability"), "Scene3D::Base3DBehavior")
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To depth'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectDepthTween2');
|
||||
|
||||
// deprecated
|
||||
behavior
|
||||
@@ -1261,69 +1267,65 @@ module.exports = {
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectAngleTween2');
|
||||
|
||||
behavior
|
||||
.addScopedAction(
|
||||
'AddObjectRotationXTween',
|
||||
_('Tween object rotation on X axis'),
|
||||
_(
|
||||
'Tweens an object rotation on X axis from its current angle to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the rotation on X axis of _PARAM0_ to _PARAM4_° with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Angle'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter('behavior', _('3D capability'), 'Scene3D::Base3DBehavior')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To angle (in degrees)'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectRotationXTween');
|
||||
behavior
|
||||
.addScopedAction(
|
||||
'AddObjectRotationXTween',
|
||||
_('Tween object rotation on X axis'),
|
||||
_('Tweens an object rotation on X axis from its current angle to a new one.'),
|
||||
_(
|
||||
'Tween the rotation on X axis of _PARAM0_ to _PARAM4_° with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Angle'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter("behavior", _("3D capability"), "Scene3D::Base3DBehavior")
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To angle (in degrees)'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectRotationXTween');
|
||||
|
||||
behavior
|
||||
.addScopedAction(
|
||||
'AddObjectRotationYTween',
|
||||
_('Tween object rotation on Y axis'),
|
||||
_(
|
||||
'Tweens an object rotation on Y axis from its current angle to a new one.'
|
||||
),
|
||||
_(
|
||||
'Tween the rotation on Y axis of _PARAM0_ to _PARAM4_° with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Angle'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter('behavior', _('3D capability'), 'Scene3D::Base3DBehavior')
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To angle (in degrees)'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectRotationYTween');
|
||||
behavior
|
||||
.addScopedAction(
|
||||
'AddObjectRotationYTween',
|
||||
_('Tween object rotation on Y axis'),
|
||||
_('Tweens an object rotation on Y axis from its current angle to a new one.'),
|
||||
_(
|
||||
'Tween the rotation on Y axis of _PARAM0_ to _PARAM4_° with easing _PARAM5_ over _PARAM6_ seconds as _PARAM3_'
|
||||
),
|
||||
_('Angle'),
|
||||
'JsPlatform/Extensions/tween_behavior24.png',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter("behavior", _("3D capability"), "Scene3D::Base3DBehavior")
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To angle (in degrees)'), '', false)
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
_('Destroy this object when tween finishes'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addObjectRotationYTween');
|
||||
|
||||
// deprecated
|
||||
behavior
|
||||
@@ -1698,9 +1700,7 @@ module.exports = {
|
||||
.addScopedAction(
|
||||
'AddNumberEffectPropertyTween',
|
||||
_('Tween number effect property'),
|
||||
_(
|
||||
'Tweens a number effect property from its current value to a new one.'
|
||||
),
|
||||
_('Tweens a number effect property from its current value to a new one.'),
|
||||
_(
|
||||
'Tween the property _PARAM6_ for effect _PARAM5_ of _PARAM0_ to _PARAM4_ with easing _PARAM7_ over _PARAM8_ seconds as _PARAM3_'
|
||||
),
|
||||
@@ -1710,15 +1710,11 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter(
|
||||
'behavior',
|
||||
_('Effect capability'),
|
||||
'EffectCapability::EffectBehavior'
|
||||
)
|
||||
.addParameter("behavior", _("Effect capability"), "EffectCapability::EffectBehavior")
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('expression', _('To value'), '', false)
|
||||
.addParameter('objectEffectName', _('Effect name'))
|
||||
.addParameter('objectEffectParameterName', _('Property name'))
|
||||
.addParameter("objectEffectName", _("Effect name"))
|
||||
.addParameter("objectEffectParameterName", _("Property name"))
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
@@ -1736,9 +1732,7 @@ module.exports = {
|
||||
.addScopedAction(
|
||||
'AddColorEffectPropertyTween',
|
||||
_('Tween color effect property'),
|
||||
_(
|
||||
'Tweens a color effect property from its current value to a new one.'
|
||||
),
|
||||
_('Tweens a color effect property from its current value to a new one.'),
|
||||
_(
|
||||
'Tween the color property _PARAM6_ for effect _PARAM5_ of _PARAM0_ to _PARAM4_ with easing _PARAM7_ over _PARAM8_ seconds as _PARAM3_'
|
||||
),
|
||||
@@ -1748,15 +1742,11 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
|
||||
.addParameter(
|
||||
'behavior',
|
||||
_('Effect capability'),
|
||||
'EffectCapability::EffectBehavior'
|
||||
)
|
||||
.addParameter("behavior", _("Effect capability"), "EffectCapability::EffectBehavior")
|
||||
.addParameter('identifier', _('Tween Identifier'), 'objectTween')
|
||||
.addParameter('color', _('To color'), '', false)
|
||||
.addParameter('objectEffectName', _('Effect name'))
|
||||
.addParameter('objectEffectParameterName', _('Property name'))
|
||||
.addParameter("objectEffectName", _("Effect name"))
|
||||
.addParameter("objectEffectParameterName", _("Property name"))
|
||||
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
|
||||
.setDefaultValue('linear')
|
||||
.addParameter('expression', _('Duration (in seconds)'), '', false)
|
||||
@@ -1768,7 +1758,7 @@ module.exports = {
|
||||
)
|
||||
.setDefaultValue('no')
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('addColorEffectPropertyTween');
|
||||
.setFunctionName('addNumberEffectPropertyTween');
|
||||
|
||||
// deprecated
|
||||
behavior
|
||||
@@ -2069,7 +2059,7 @@ module.exports = {
|
||||
'Progress',
|
||||
_('Tween progress'),
|
||||
_('the progress of a tween (between 0.0 and 1.0)'),
|
||||
_('the progress of the tween _PARAM2_'),
|
||||
_('the progress of a tween'),
|
||||
'',
|
||||
'JsPlatform/Extensions/tween_behavior32.png'
|
||||
)
|
||||
@@ -2098,7 +2088,10 @@ module.exports = {
|
||||
return extension;
|
||||
},
|
||||
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -126,25 +126,18 @@ describe('gdjs.TweenRuntimeBehavior', () => {
|
||||
name: behaviorName,
|
||||
},
|
||||
],
|
||||
content: {
|
||||
characterSize: 20,
|
||||
font: '',
|
||||
bold: false,
|
||||
italic: false,
|
||||
underlined: false,
|
||||
color: '0;0;0',
|
||||
text: '',
|
||||
textAlignment: 'left',
|
||||
isOutlineEnabled: false,
|
||||
outlineThickness: 2,
|
||||
outlineColor: '255;255;255',
|
||||
isShadowEnabled: false,
|
||||
shadowColor: '0;0;0',
|
||||
shadowOpacity: 128,
|
||||
shadowDistance: 4,
|
||||
shadowAngle: 90,
|
||||
shadowBlurRadius: 2,
|
||||
characterSize: 20,
|
||||
font: '',
|
||||
bold: false,
|
||||
italic: false,
|
||||
underlined: false,
|
||||
color: {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
},
|
||||
string: '',
|
||||
textAlignment: 'left',
|
||||
});
|
||||
runtimeScene.addObject(object);
|
||||
return object;
|
||||
|
@@ -126,25 +126,18 @@ describe('gdjs.TweenRuntimeBehavior', () => {
|
||||
name: behaviorName,
|
||||
},
|
||||
],
|
||||
content: {
|
||||
characterSize: 20,
|
||||
font: '',
|
||||
bold: false,
|
||||
italic: false,
|
||||
underlined: false,
|
||||
color: '0;0;0',
|
||||
text: '',
|
||||
textAlignment: 'left',
|
||||
isOutlineEnabled: false,
|
||||
outlineThickness: 2,
|
||||
outlineColor: '255;255;255',
|
||||
isShadowEnabled: false,
|
||||
shadowColor: '0;0;0',
|
||||
shadowOpacity: 128,
|
||||
shadowDistance: 4,
|
||||
shadowAngle: 90,
|
||||
shadowBlurRadius: 2,
|
||||
characterSize: 20,
|
||||
font: '',
|
||||
bold: false,
|
||||
italic: false,
|
||||
underlined: false,
|
||||
color: {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
},
|
||||
string: '',
|
||||
textAlignment: 'left',
|
||||
});
|
||||
runtimeScene.addObject(object);
|
||||
return object;
|
||||
|
@@ -15,44 +15,27 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
function isScalable(
|
||||
object: gdjs.RuntimeObject
|
||||
): object is gdjs.RuntimeObject & gdjs.Scalable {
|
||||
return (
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
object.setScaleX &&
|
||||
//@ts-ignore
|
||||
object.setScaleY &&
|
||||
//@ts-ignore
|
||||
object.getScaleX &&
|
||||
//@ts-ignore
|
||||
object.getScaleY
|
||||
);
|
||||
o: gdjs.RuntimeObject
|
||||
): o is gdjs.RuntimeObject & gdjs.Scalable {
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
return o.setScaleX && o.setScaleY && o.getScaleX && o.getScaleY;
|
||||
}
|
||||
|
||||
function isOpaque(
|
||||
object: gdjs.RuntimeObject
|
||||
): object is gdjs.RuntimeObject & gdjs.OpacityHandler {
|
||||
o: gdjs.RuntimeObject
|
||||
): o is gdjs.RuntimeObject & gdjs.OpacityHandler {
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
return object.setOpacity && object.getOpacity;
|
||||
return o.setOpacity && o.getOpacity;
|
||||
}
|
||||
|
||||
function is3D(
|
||||
object: gdjs.RuntimeObject
|
||||
): object is gdjs.RuntimeObject & gdjs.Base3DHandler {
|
||||
function isColorable(o: gdjs.RuntimeObject): o is IColorable {
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
return object.getZ && object.setZ;
|
||||
return o.setColor && o.getColor;
|
||||
}
|
||||
|
||||
function isColorable(object: gdjs.RuntimeObject): object is IColorable {
|
||||
function isCharacterScalable(o: gdjs.RuntimeObject): o is ICharacterScalable {
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
return object.setColor && object.getColor;
|
||||
}
|
||||
|
||||
function isCharacterScalable(
|
||||
object: gdjs.RuntimeObject
|
||||
): object is ICharacterScalable {
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
return object.setCharacterSize && object.getCharacterSize;
|
||||
return o.setCharacterSize && o.getCharacterSize;
|
||||
}
|
||||
|
||||
const linearInterpolation = gdjs.evtTools.common.lerp;
|
||||
@@ -533,7 +516,7 @@ namespace gdjs {
|
||||
timeSource: gdjs.evtTools.tween.TimeSource
|
||||
) {
|
||||
const { owner } = this;
|
||||
if (!is3D(owner)) return;
|
||||
if (!(owner instanceof gdjs.RuntimeObject3D)) return;
|
||||
|
||||
this._tweens.addSimpleTween(
|
||||
identifier,
|
||||
@@ -638,7 +621,7 @@ namespace gdjs {
|
||||
destroyObjectWhenFinished: boolean
|
||||
) {
|
||||
const { owner } = this;
|
||||
if (!is3D(owner)) return;
|
||||
if (!(owner instanceof gdjs.RuntimeObject3D)) return;
|
||||
|
||||
this._tweens.addSimpleTween(
|
||||
identifier,
|
||||
@@ -671,7 +654,7 @@ namespace gdjs {
|
||||
destroyObjectWhenFinished: boolean
|
||||
) {
|
||||
const { owner } = this;
|
||||
if (!is3D(owner)) return;
|
||||
if (!(owner instanceof gdjs.RuntimeObject3D)) return;
|
||||
|
||||
this._tweens.addSimpleTween(
|
||||
identifier,
|
||||
@@ -825,10 +808,7 @@ namespace gdjs {
|
||||
const owner = this.owner;
|
||||
if (!isScalable(owner)) return;
|
||||
|
||||
// This action doesn't require 3D capabilities.
|
||||
// So, gdjs.RuntimeObject3D may not exist
|
||||
// when the 3D extension is not used.
|
||||
const owner3d = is3D(owner) ? owner : null;
|
||||
const owner3d = owner instanceof gdjs.RuntimeObject3D ? owner : null;
|
||||
|
||||
const setValue = scaleFromCenterOfObject
|
||||
? (scale: float) => {
|
||||
@@ -1770,7 +1750,7 @@ namespace gdjs {
|
||||
timeSource: gdjs.evtTools.tween.TimeSource
|
||||
) {
|
||||
const { owner } = this;
|
||||
if (!is3D(owner)) return;
|
||||
if (!(owner instanceof gdjs.RuntimeObject3D)) return;
|
||||
|
||||
this._tweens.addSimpleTween(
|
||||
identifier,
|
||||
|
@@ -1,6 +1,4 @@
|
||||
//@ts-check
|
||||
/// <reference path="../JsExtensionTypes.d.ts" />
|
||||
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
@@ -14,27 +12,34 @@
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
/** @type {ExtensionModule} */
|
||||
/*::
|
||||
// Import types to allow Flow to do static type checking on this file.
|
||||
// Extensions declaration are typed using Flow (like the editor), but the files
|
||||
// for the game engine are checked with TypeScript annotations.
|
||||
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (_, gd) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
'Video',
|
||||
_('Video'),
|
||||
_(
|
||||
'Provides an object to display a video on the scene. The recommended file format is MPEG4, with H264 video codec and AAC audio codec, to maximize the support of the video on different platform and browsers.'
|
||||
),
|
||||
_('Provides an object to display a video on the scene. The recommended file format is MPEG4, with H264 video codec and AAC audio codec, to maximize the support of the video on different platform and browsers.'),
|
||||
'Aurélien Vivet',
|
||||
'Open source (MIT License)'
|
||||
)
|
||||
.setCategory('User interface')
|
||||
.setExtensionHelpPath('/objects/video');
|
||||
extension
|
||||
.addInstructionOrExpressionGroupMetadata(_('Video'))
|
||||
.setIcon('JsPlatform/Extensions/videoicon16.png');
|
||||
extension.addInstructionOrExpressionGroupMetadata(_("Video"))
|
||||
.setIcon("JsPlatform/Extensions/videoicon16.png");
|
||||
|
||||
var videoObject = new gd.ObjectJsImplementation();
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
videoObject.updateProperty = function (
|
||||
objectContent,
|
||||
propertyName,
|
||||
@@ -59,6 +64,7 @@ module.exports = {
|
||||
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
videoObject.getProperties = function (objectContent) {
|
||||
var objectProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
@@ -98,6 +104,7 @@ module.exports = {
|
||||
})
|
||||
);
|
||||
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
videoObject.updateInitialInstanceProperty = function (
|
||||
objectContent,
|
||||
instance,
|
||||
@@ -108,6 +115,7 @@ module.exports = {
|
||||
) {
|
||||
return false;
|
||||
};
|
||||
// $FlowExpectedError - ignore Flow warning as we're creating an object
|
||||
videoObject.getInitialInstanceProperties = function (
|
||||
content,
|
||||
instance,
|
||||
@@ -124,14 +132,13 @@ module.exports = {
|
||||
_('Video'),
|
||||
_('Displays a video.'),
|
||||
'JsPlatform/Extensions/videoicon32.png',
|
||||
// @ts-ignore - TODO: Fix videoObject being an ObjectJsImplementation instead of an ObjectConfiguration
|
||||
videoObject
|
||||
)
|
||||
.setIncludeFile('Extensions/Video/videoruntimeobject.js')
|
||||
.addIncludeFile('Extensions/Video/videoruntimeobject-pixi-renderer.js')
|
||||
.setCategoryFullName(_('User interface'))
|
||||
.addDefaultBehavior('EffectCapability::EffectBehavior')
|
||||
.addDefaultBehavior('OpacityCapability::OpacityBehavior');
|
||||
.addDefaultBehavior("OpacityCapability::OpacityBehavior");
|
||||
|
||||
object
|
||||
.addAction(
|
||||
@@ -526,7 +533,10 @@ module.exports = {
|
||||
* But it is recommended to create tests for the behaviors/objects properties you created
|
||||
* to avoid mistakes.
|
||||
*/
|
||||
runExtensionSanityTests: function (gd, extension) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
/**
|
||||
@@ -535,7 +545,9 @@ module.exports = {
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
|
||||
registerEditorConfigurations: function (objectsEditorService) {
|
||||
registerEditorConfigurations: function (
|
||||
objectsEditorService /*: ObjectsEditorService */
|
||||
) {
|
||||
objectsEditorService.registerEditorConfiguration(
|
||||
'Video::VideoObject',
|
||||
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
|
||||
@@ -548,7 +560,9 @@ module.exports = {
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
|
||||
*/
|
||||
registerInstanceRenderers: function (objectsRenderingService) {
|
||||
registerInstanceRenderers: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const RenderedInstance = objectsRenderingService.RenderedInstance;
|
||||
const PIXI = objectsRenderingService.PIXI;
|
||||
|
||||
@@ -556,7 +570,7 @@ module.exports = {
|
||||
* Renderer for instances of VideoObject inside the IDE.
|
||||
*/
|
||||
class RenderedVideoObjectInstance extends RenderedInstance {
|
||||
constructor(
|
||||
constructor (
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
@@ -592,7 +606,11 @@ module.exports = {
|
||||
/**
|
||||
* Return the path to the thumbnail of the specified object.
|
||||
*/
|
||||
static getThumbnail(project, resourcesLoader, objectConfiguration) {
|
||||
static getThumbnail(
|
||||
project,
|
||||
resourcesLoader,
|
||||
objectConfiguration
|
||||
) {
|
||||
return 'JsPlatform/Extensions/videoicon24.png';
|
||||
}
|
||||
|
||||
@@ -629,13 +647,14 @@ module.exports = {
|
||||
that._pixiObject.texture.on('error', function () {
|
||||
that._pixiObject.texture.off('error', this);
|
||||
|
||||
that._pixiObject.texture = that._pixiResourcesLoader.getInvalidPIXITexture();
|
||||
that._pixiObject.texture =
|
||||
that._pixiResourcesLoader.getInvalidPIXITexture();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update opacity
|
||||
const opacity = +this._associatedObjectConfiguration
|
||||
const opacity = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.get('Opacity')
|
||||
.getValue();
|
||||
|
@@ -7,11 +7,7 @@
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/IDE/WholeProjectBrowser.h"
|
||||
#include "GDCore/Project/CustomBehavior.h"
|
||||
#include "GDCore/Project/CustomBehaviorsSharedData.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
@@ -129,21 +125,14 @@ gd::ObjectMetadata &MetadataDeclarationHelper::DeclareObjectMetadata(
|
||||
// Note: EventsFunctionsExtension should be used instead of
|
||||
// PlatformExtension but this line will be removed soon.
|
||||
.SetCategoryFullName(extension.GetCategory())
|
||||
// Update Project::CreateObject when default behavior are added.
|
||||
.AddDefaultBehavior("EffectCapability::EffectBehavior")
|
||||
.AddDefaultBehavior("ResizableCapability::ResizableBehavior")
|
||||
.AddDefaultBehavior("ScalableCapability::ScalableBehavior")
|
||||
.AddDefaultBehavior("FlippableCapability::FlippableBehavior");
|
||||
.AddDefaultBehavior("FlippableCapability::FlippableBehavior")
|
||||
.AddDefaultBehavior("OpacityCapability::OpacityBehavior");
|
||||
if (eventsBasedObject.IsRenderedIn3D()) {
|
||||
objectMetadata
|
||||
.MarkAsRenderedIn3D()
|
||||
.AddDefaultBehavior("Scene3D::Base3DBehavior");
|
||||
}
|
||||
else {
|
||||
objectMetadata.AddDefaultBehavior("EffectCapability::EffectBehavior");
|
||||
objectMetadata.AddDefaultBehavior("OpacityCapability::OpacityBehavior");
|
||||
}
|
||||
if (eventsBasedObject.IsTextContainer()) {
|
||||
objectMetadata
|
||||
.AddDefaultBehavior("TextContainerCapability::TextContainerBehavior");
|
||||
objectMetadata.MarkAsRenderedIn3D();
|
||||
}
|
||||
|
||||
// TODO EBO Use full type to identify object to avoid collision.
|
||||
@@ -944,15 +933,18 @@ MetadataDeclarationHelper::DeclareObjectInstructionMetadata(
|
||||
|
||||
gd::String MetadataDeclarationHelper::GetStringifiedExtraInfo(
|
||||
const gd::PropertyDescriptor &property) {
|
||||
if (property.GetType() != "Choice") {
|
||||
return "";
|
||||
gd::String stringifiedExtraInfo = "";
|
||||
if (property.GetType() == "Choice") {
|
||||
stringifiedExtraInfo += "[";
|
||||
for (size_t i = 0; i < property.GetExtraInfo().size(); i++) {
|
||||
stringifiedExtraInfo += property.GetExtraInfo().at(i);
|
||||
if (i < property.GetExtraInfo().size() - 1) {
|
||||
stringifiedExtraInfo += ",";
|
||||
}
|
||||
}
|
||||
stringifiedExtraInfo += "]";
|
||||
}
|
||||
SerializerElement element;
|
||||
element.ConsiderAsArray();
|
||||
for (auto&& value : property.GetExtraInfo()) {
|
||||
element.AddChild("").SetStringValue(value);
|
||||
}
|
||||
return Serializer::ToJSON(element);
|
||||
return stringifiedExtraInfo;
|
||||
}
|
||||
|
||||
gd::String
|
||||
@@ -976,9 +968,6 @@ void MetadataDeclarationHelper::DeclarePropertyInstructionAndExpression(
|
||||
addObjectAndBehaviorParameters) {
|
||||
auto &propertyType = property.GetType();
|
||||
|
||||
auto group = (eventsBasedEntity.GetFullName() || eventsBasedEntity.GetName())
|
||||
+ " " + property.GetGroup() + " properties";
|
||||
|
||||
auto uncapitalizedLabel =
|
||||
UncapitalizeFirstLetter(property.GetLabel()) || property.GetName();
|
||||
if (propertyType == "Boolean") {
|
||||
@@ -988,7 +977,7 @@ void MetadataDeclarationHelper::DeclarePropertyInstructionAndExpression(
|
||||
.FindAndReplace("<property_name>", uncapitalizedLabel),
|
||||
_("Property <property_name> of _PARAM0_ is true")
|
||||
.FindAndReplace("<property_name>", uncapitalizedLabel),
|
||||
group,
|
||||
eventsBasedEntity.GetFullName() || eventsBasedEntity.GetName(),
|
||||
GetExtensionIconUrl(extension), GetExtensionIconUrl(extension));
|
||||
addObjectAndBehaviorParameters(conditionMetadata);
|
||||
conditionMetadata.SetFunctionName(getterName);
|
||||
@@ -1003,7 +992,7 @@ void MetadataDeclarationHelper::DeclarePropertyInstructionAndExpression(
|
||||
.FindAndReplace("<property_value>",
|
||||
"_PARAM" + gd::String::From(valueParameterIndex) +
|
||||
"_"),
|
||||
group,
|
||||
eventsBasedEntity.GetFullName() || eventsBasedEntity.GetName(),
|
||||
GetExtensionIconUrl(extension), GetExtensionIconUrl(extension));
|
||||
addObjectAndBehaviorParameters(setterActionMetadata);
|
||||
setterActionMetadata
|
||||
@@ -1018,7 +1007,7 @@ void MetadataDeclarationHelper::DeclarePropertyInstructionAndExpression(
|
||||
.FindAndReplace("<property_name>", uncapitalizedLabel),
|
||||
_("Toggle property <property_name> of _PARAM0_")
|
||||
.FindAndReplace("<property_name>", uncapitalizedLabel),
|
||||
group,
|
||||
eventsBasedEntity.GetFullName() || eventsBasedEntity.GetName(),
|
||||
GetExtensionIconUrl(extension), GetExtensionIconUrl(extension));
|
||||
addObjectAndBehaviorParameters(toggleActionMetadata);
|
||||
toggleActionMetadata.SetFunctionName(toggleFunctionName);
|
||||
@@ -1029,14 +1018,13 @@ void MetadataDeclarationHelper::DeclarePropertyInstructionAndExpression(
|
||||
parameterOptions.SetTypeExtraInfo(typeExtraInfo);
|
||||
auto propertyInstructionMetadata =
|
||||
entityMetadata.AddExpressionAndConditionAndAction(
|
||||
gd::ValueTypeMetadata::GetPrimitiveValueType(
|
||||
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(propertyType)),
|
||||
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(propertyType),
|
||||
expressionName, propertyLabel,
|
||||
_("the property value for the <property_name>")
|
||||
.FindAndReplace("<property_name>", uncapitalizedLabel),
|
||||
_("the property value for the <property_name>")
|
||||
.FindAndReplace("<property_name>", uncapitalizedLabel),
|
||||
group,
|
||||
eventsBasedEntity.GetFullName() || eventsBasedEntity.GetName(),
|
||||
GetExtensionIconUrl(extension));
|
||||
addObjectAndBehaviorParameters(propertyInstructionMetadata);
|
||||
propertyInstructionMetadata
|
||||
@@ -1225,39 +1213,20 @@ void MetadataDeclarationHelper::DeclareObjectInternalInstructions(
|
||||
// Objects are identified by their name alone.
|
||||
auto &objectType = eventsBasedObject.GetName();
|
||||
|
||||
if (eventsBasedObject.IsRenderedIn3D()) {
|
||||
objectMetadata
|
||||
.AddScopedAction(
|
||||
"SetRotationCenter", _("Center of rotation"),
|
||||
_("Change the center of rotation of an object relatively to the "
|
||||
"object origin."),
|
||||
_("Change the center of rotation of _PARAM0_ to _PARAM1_ ; _PARAM2_ ; _PARAM3_"),
|
||||
_("Angle"), "res/actions/position24_black.png",
|
||||
"res/actions/position_black.png")
|
||||
.AddParameter("object", _("Object"), objectType)
|
||||
.AddParameter("number", _("X position"))
|
||||
.AddParameter("number", _("Y position"))
|
||||
.AddParameter("number", _("Z position"))
|
||||
.MarkAsAdvanced()
|
||||
.SetPrivate()
|
||||
.SetFunctionName("setRotationCenter3D");
|
||||
}
|
||||
else {
|
||||
objectMetadata
|
||||
.AddScopedAction(
|
||||
"SetRotationCenter", _("Center of rotation"),
|
||||
_("Change the center of rotation of an object relatively to the "
|
||||
"object origin."),
|
||||
_("Change the center of rotation of _PARAM0_ to _PARAM1_ ; _PARAM2_"),
|
||||
_("Angle"), "res/actions/position24_black.png",
|
||||
"res/actions/position_black.png")
|
||||
.AddParameter("object", _("Object"), objectType)
|
||||
.AddParameter("number", _("X position"))
|
||||
.AddParameter("number", _("Y position"))
|
||||
.MarkAsAdvanced()
|
||||
.SetPrivate()
|
||||
.SetFunctionName("setRotationCenter");
|
||||
}
|
||||
objectMetadata
|
||||
.AddScopedAction(
|
||||
"SetRotationCenter", _("Center of rotation"),
|
||||
_("Change the center of rotation of an object relatively to the "
|
||||
"object origin."),
|
||||
_("Change the center of rotation of _PARAM0_ to _PARAM1_, _PARAM2_"),
|
||||
_("Angle"), "res/actions/position24_black.png",
|
||||
"res/actions/position_black.png")
|
||||
.AddParameter("object", _("Object"), objectType)
|
||||
.AddParameter("number", _("X position"))
|
||||
.AddParameter("number", _("Y position"))
|
||||
.MarkAsAdvanced()
|
||||
.SetPrivate()
|
||||
.SetFunctionName("setRotationCenter");
|
||||
}
|
||||
|
||||
void MetadataDeclarationHelper::AddParameter(
|
||||
@@ -1517,7 +1486,7 @@ gd::BehaviorMetadata &MetadataDeclarationHelper::GenerateBehaviorMetadata(
|
||||
}
|
||||
|
||||
gd::ObjectMetadata &MetadataDeclarationHelper::GenerateObjectMetadata(
|
||||
gd::Project &project, gd::PlatformExtension &extension,
|
||||
const gd::Project &project, gd::PlatformExtension &extension,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
std::map<gd::String, gd::String> &objectMethodMangledNames) {
|
||||
@@ -1552,58 +1521,7 @@ gd::ObjectMetadata &MetadataDeclarationHelper::GenerateObjectMetadata(
|
||||
instructionOrExpression.SetPrivate();
|
||||
}
|
||||
|
||||
UpdateCustomObjectDefaultBehaviors(project, objectMetadata);
|
||||
|
||||
return objectMetadata;
|
||||
}
|
||||
|
||||
class DefaultBehaviorUpdater : public gd::ArbitraryObjectsWorker {
|
||||
|
||||
public:
|
||||
DefaultBehaviorUpdater(const gd::Project &project_,
|
||||
const gd::ObjectMetadata &objectMetadata_)
|
||||
: project(project_), objectMetadata(objectMetadata_){};
|
||||
virtual ~DefaultBehaviorUpdater(){};
|
||||
|
||||
private:
|
||||
void DoVisitObject(gd::Object &object) override {
|
||||
|
||||
if (object.GetType() != objectMetadata.GetName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &defaultBehaviorTypes = objectMetadata.GetDefaultBehaviors();
|
||||
for (const gd::String &behaviorName : object.GetAllBehaviorNames()) {
|
||||
const auto &behavior = object.GetBehavior(behaviorName);
|
||||
if (behavior.IsDefaultBehavior()) {
|
||||
object.RemoveBehavior(behaviorName);
|
||||
}
|
||||
}
|
||||
auto &platform = project.GetCurrentPlatform();
|
||||
for (const gd::String &behaviorType : defaultBehaviorTypes) {
|
||||
auto &behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
|
||||
if (MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
gd::LogWarning("Object: " + object.GetType() +
|
||||
" has an unknown default behavior: " + behaviorType);
|
||||
continue;
|
||||
}
|
||||
const gd::String &behaviorName = behaviorMetadata.GetDefaultName();
|
||||
auto *behavior =
|
||||
object.AddNewBehavior(project, behaviorType, behaviorName);
|
||||
behavior->SetDefaultBehavior(true);
|
||||
}
|
||||
}
|
||||
|
||||
const gd::Project &project;
|
||||
const gd::ObjectMetadata &objectMetadata;
|
||||
};
|
||||
|
||||
void MetadataDeclarationHelper::UpdateCustomObjectDefaultBehaviors(
|
||||
gd::Project &project, const gd::ObjectMetadata &objectMetadata) {
|
||||
gd::WholeProjectBrowser projectBrowser;
|
||||
auto defaultBehaviorUpdater = DefaultBehaviorUpdater(project, objectMetadata);
|
||||
projectBrowser.ExposeObjects(project, defaultBehaviorUpdater);
|
||||
}
|
||||
|
||||
} // namespace gdjs
|
@@ -61,7 +61,7 @@ public:
|
||||
std::map<gd::String, gd::String> &behaviorMethodMangledNames);
|
||||
|
||||
static gd::ObjectMetadata &GenerateObjectMetadata(
|
||||
gd::Project &project, gd::PlatformExtension &extension,
|
||||
const gd::Project &project, gd::PlatformExtension &extension,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
std::map<gd::String, gd::String> &objectMethodMangledNames);
|
||||
@@ -313,10 +313,6 @@ private:
|
||||
gd::MultipleInstructionMetadata &multipleInstructionMetadata,
|
||||
const int userDefinedFirstParameterIndex);
|
||||
|
||||
static void
|
||||
UpdateCustomObjectDefaultBehaviors(gd::Project &project,
|
||||
const gd::ObjectMetadata &objectMetadata);
|
||||
|
||||
static gd::String RemoveTrailingDot(const gd::String &description);
|
||||
|
||||
static gd::String
|
||||
|
@@ -109,19 +109,6 @@ gd::String ObjectCodeGenerator::GenerateRuntimeObjectCompleteCode(
|
||||
}
|
||||
|
||||
return updateFromObjectCode;
|
||||
},
|
||||
// generateTextContainerCode
|
||||
[&]() {
|
||||
return gd::String(R"jscode_template(
|
||||
// gdjs.TextContainer interface implementation
|
||||
_text = '';
|
||||
getText() {
|
||||
return this._text;
|
||||
}
|
||||
setText(text) {
|
||||
this._text = text;
|
||||
}
|
||||
)jscode_template");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -132,15 +119,14 @@ gd::String ObjectCodeGenerator::GenerateRuntimeObjectTemplateCode(
|
||||
std::function<gd::String()> generateInitializePropertiesCode,
|
||||
std::function<gd::String()> generatePropertiesCode,
|
||||
std::function<gd::String()> generateMethodsCode,
|
||||
std::function<gd::String()> generateUpdateFromObjectDataCode,
|
||||
std::function<gd::String()> generateTextContainerCode) {
|
||||
std::function<gd::String()> generateUpdateFromObjectDataCode) {
|
||||
return gd::String(R"jscode_template(
|
||||
CODE_NAMESPACE = CODE_NAMESPACE || {};
|
||||
|
||||
/**
|
||||
* Object generated from OBJECT_FULL_NAME
|
||||
*/
|
||||
CODE_NAMESPACE.RUNTIME_OBJECT_CLASSNAME = class RUNTIME_OBJECT_CLASSNAME extends RUNTIME_OBJECT_BASE_CLASS_NAME {
|
||||
CODE_NAMESPACE.RUNTIME_OBJECT_CLASSNAME = class RUNTIME_OBJECT_CLASSNAME extends gdjs.CustomRuntimeObject {
|
||||
constructor(parentInstanceContainer, objectData) {
|
||||
super(parentInstanceContainer, objectData);
|
||||
this._parentInstanceContainer = parentInstanceContainer;
|
||||
@@ -163,8 +149,6 @@ CODE_NAMESPACE.RUNTIME_OBJECT_CLASSNAME = class RUNTIME_OBJECT_CLASSNAME extends
|
||||
|
||||
// Properties:
|
||||
PROPERTIES_CODE
|
||||
|
||||
TEXT_CONTAINER_CODE
|
||||
}
|
||||
|
||||
// Methods:
|
||||
@@ -177,14 +161,11 @@ gdjs.registerObject("EXTENSION_NAME::OBJECT_NAME", CODE_NAMESPACE.RUNTIME_OBJECT
|
||||
.FindAndReplace("OBJECT_FULL_NAME", eventsBasedObject.GetFullName())
|
||||
.FindAndReplace("RUNTIME_OBJECT_CLASSNAME",
|
||||
eventsBasedObject.GetName())
|
||||
.FindAndReplace("RUNTIME_OBJECT_BASE_CLASS_NAME",
|
||||
eventsBasedObject.IsRenderedIn3D() ? "gdjs.CustomRuntimeObject3D" : "gdjs.CustomRuntimeObject2D")
|
||||
.FindAndReplace("CODE_NAMESPACE", codeNamespace)
|
||||
.FindAndReplace("INITIALIZE_PROPERTIES_CODE",
|
||||
generateInitializePropertiesCode())
|
||||
.FindAndReplace("UPDATE_FROM_OBJECT_DATA_CODE", generateUpdateFromObjectDataCode())
|
||||
.FindAndReplace("PROPERTIES_CODE", generatePropertiesCode())
|
||||
.FindAndReplace("TEXT_CONTAINER_CODE", eventsBasedObject.IsTextContainer() ? generateTextContainerCode() : "")
|
||||
.FindAndReplace("METHODS_CODE", generateMethodsCode());
|
||||
;
|
||||
}
|
||||
|
@@ -74,8 +74,7 @@ class ObjectCodeGenerator {
|
||||
std::function<gd::String()> generateInitializePropertiesCode,
|
||||
std::function<gd::String()> generateMethodsCode,
|
||||
std::function<gd::String()> generatePropertiesCode,
|
||||
std::function<gd::String()> generateUpdateFromObjectDataCode,
|
||||
std::function<gd::String()> generateTextContainerCode);
|
||||
std::function<gd::String()> generateUpdateFromObjectDataCode);
|
||||
|
||||
gd::String GenerateRuntimeObjectPropertyTemplateCode(
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
|
@@ -25,11 +25,6 @@ NetworkExtension::NetworkExtension() {
|
||||
"gdjs.evtTools.network.enableMetrics");
|
||||
GetAllActions()["LaunchFile"].SetFunctionName("gdjs.evtTools.window.openURL");
|
||||
|
||||
AddDependency()
|
||||
.SetName("InAppBrowser Cordova plugin")
|
||||
.SetDependencyType("cordova")
|
||||
.SetExportName("cordova-plugin-inappbrowser");
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions();
|
||||
}
|
||||
|
||||
|
@@ -152,6 +152,11 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
scenesUsedResources);
|
||||
includesFiles.push_back(codeOutputDir + "/data.js");
|
||||
|
||||
// Export a WebManifest with project metadata
|
||||
if (!fs.WriteToFile(exportDir + "/manifest.webmanifest",
|
||||
helper.GenerateWebManifest(exportedProject)))
|
||||
gd::LogError("Unable to export WebManifest.");
|
||||
|
||||
helper.ExportIncludesAndLibs(includesFiles, exportDir, false);
|
||||
helper.ExportIncludesAndLibs(resourcesFiles, exportDir, false);
|
||||
|
||||
@@ -199,9 +204,6 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
return false;
|
||||
} else {
|
||||
if (!exportProject(options.exportPath)) return false;
|
||||
|
||||
if (!helper.ExportHtml5Files(exportedProject, options.exportPath))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -194,7 +194,7 @@ bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
for (std::size_t layoutIndex = 0;
|
||||
layoutIndex < exportedProject.GetLayoutsCount(); layoutIndex++) {
|
||||
auto &layout = exportedProject.GetLayout(layoutIndex);
|
||||
scenesUsedResources[layout.GetName()] =
|
||||
scenesUsedResources[layout.GetName()] =
|
||||
gd::SceneResourcesFinder::FindSceneResources(exportedProject,
|
||||
layout);
|
||||
}
|
||||
@@ -415,28 +415,10 @@ bool ExporterHelper::ExportCordovaFiles(const gd::Project &project,
|
||||
return output;
|
||||
};
|
||||
|
||||
auto makeProjectNameXcodeSafe = [](const gd::String &projectName) {
|
||||
// Avoid App Store Connect STATE_ERROR.VALIDATION_ERROR.90121 error, when
|
||||
// "CFBundleExecutable Info.plist key contains [...] any of the following
|
||||
// unsupported characters: \ [ ] { } ( ) + *".
|
||||
|
||||
// Remove \ [ ] { } ( ) + * from the project name.
|
||||
return projectName.FindAndReplace("\\", "")
|
||||
.FindAndReplace("[", "")
|
||||
.FindAndReplace("]", "")
|
||||
.FindAndReplace("{", "")
|
||||
.FindAndReplace("}", "")
|
||||
.FindAndReplace("(", "")
|
||||
.FindAndReplace(")", "")
|
||||
.FindAndReplace("+", "")
|
||||
.FindAndReplace("*", "");
|
||||
};
|
||||
|
||||
gd::String str =
|
||||
fs.ReadFile(gdjsRoot + "/Runtime/Cordova/config.xml")
|
||||
.FindAndReplace("GDJS_PROJECTNAME",
|
||||
gd::Serializer::ToEscapedXMLString(
|
||||
makeProjectNameXcodeSafe(project.GetName())))
|
||||
gd::Serializer::ToEscapedXMLString(project.GetName()))
|
||||
.FindAndReplace(
|
||||
"GDJS_PACKAGENAME",
|
||||
gd::Serializer::ToEscapedXMLString(project.GetPackageName()))
|
||||
@@ -513,16 +495,6 @@ bool ExporterHelper::ExportCordovaFiles(const gd::Project &project,
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gd::String str =
|
||||
fs.ReadFile(gdjsRoot + "/Runtime/Cordova/www/LICENSE.GDevelop.txt");
|
||||
|
||||
if (!fs.WriteToFile(exportDir + "/www/LICENSE.GDevelop.txt", str)) {
|
||||
lastError = "Unable to write Cordova LICENSE.GDevelop.txt file.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -547,27 +519,6 @@ bool ExporterHelper::ExportFacebookInstantGamesFiles(const gd::Project &project,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExporterHelper::ExportHtml5Files(const gd::Project &project,
|
||||
gd::String exportDir) {
|
||||
if (!fs.WriteToFile(exportDir + "/manifest.webmanifest",
|
||||
GenerateWebManifest(project))) {
|
||||
lastError = "Unable to export WebManifest.";
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
gd::String str =
|
||||
fs.ReadFile(gdjsRoot + "/Runtime/Electron/LICENSE.GDevelop.txt");
|
||||
|
||||
if (!fs.WriteToFile(exportDir + "/LICENSE.GDevelop.txt", str)) {
|
||||
lastError = "Unable to write LICENSE.GDevelop.txt file.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExporterHelper::ExportElectronFiles(const gd::Project &project,
|
||||
gd::String exportDir,
|
||||
std::set<gd::String> usedExtensions) {
|
||||
@@ -646,16 +597,6 @@ bool ExporterHelper::ExportElectronFiles(const gd::Project &project,
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gd::String str =
|
||||
fs.ReadFile(gdjsRoot + "/Runtime/Electron/LICENSE.GDevelop.txt");
|
||||
|
||||
if (!fs.WriteToFile(exportDir + "/LICENSE.GDevelop.txt", str)) {
|
||||
lastError = "Unable to write Electron LICENSE.GDevelop.txt file.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto &platformSpecificAssets = project.GetPlatformSpecificAssets();
|
||||
auto &resourceManager = project.GetResourcesManager();
|
||||
|
||||
@@ -749,7 +690,6 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
InsertUnique(includesFiles, "affinetransformation.js");
|
||||
InsertUnique(includesFiles, "CustomRuntimeObjectInstanceContainer.js");
|
||||
InsertUnique(includesFiles, "CustomRuntimeObject.js");
|
||||
InsertUnique(includesFiles, "CustomRuntimeObject2D.js");
|
||||
|
||||
// Common includes for events only.
|
||||
InsertUnique(includesFiles, "events-tools/commontools.js");
|
||||
@@ -803,7 +743,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
InsertUnique(includesFiles, "pixi-renderers/pixi-bitmapfont-manager.js");
|
||||
InsertUnique(includesFiles,
|
||||
"pixi-renderers/spriteruntimeobject-pixi-renderer.js");
|
||||
InsertUnique(includesFiles, "pixi-renderers/CustomRuntimeObject2DPixiRenderer.js");
|
||||
InsertUnique(includesFiles, "pixi-renderers/CustomObjectPixiRenderer.js");
|
||||
InsertUnique(includesFiles, "pixi-renderers/DebuggerPixiRenderer.js");
|
||||
InsertUnique(includesFiles,
|
||||
"pixi-renderers/loadingscreen-pixi-renderer.js");
|
||||
@@ -816,12 +756,6 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
includesFiles,
|
||||
"fontfaceobserver-font-manager/fontfaceobserver-font-manager.js");
|
||||
}
|
||||
if (pixiInThreeRenderers) {
|
||||
InsertUnique(includesFiles, "Extensions/3D/A_RuntimeObject3D.js");
|
||||
InsertUnique(includesFiles, "Extensions/3D/A_RuntimeObject3DRenderer.js");
|
||||
InsertUnique(includesFiles, "Extensions/3D/CustomRuntimeObject3D.js");
|
||||
InsertUnique(includesFiles, "Extensions/3D/CustomRuntimeObject3DRenderer.js");
|
||||
}
|
||||
}
|
||||
|
||||
void ExporterHelper::RemoveIncludes(bool pixiRenderers,
|
||||
|
@@ -438,14 +438,6 @@ class ExporterHelper {
|
||||
bool ExportFacebookInstantGamesFiles(const gd::Project &project,
|
||||
gd::String exportDir);
|
||||
|
||||
/**
|
||||
* \brief Generate any HTML5 specific file.
|
||||
*
|
||||
* \param project The project to be used to generate the files.
|
||||
* \param exportDir The directory where the files must be created.
|
||||
*/
|
||||
bool ExportHtml5Files(const gd::Project &project, gd::String exportDir);
|
||||
|
||||
/**
|
||||
* \brief Create a preview for the specified options.
|
||||
* \note The preview is not launched, it is the caller responsibility to open
|
||||
|
@@ -1,2 +0,0 @@
|
||||
Part of this app is using the GDevelop game engine, which is licensed under the MIT license.
|
||||
Find more information on https://gdevelop.io/.
|
@@ -19,32 +19,29 @@ namespace gdjs {
|
||||
*
|
||||
* @see gdjs.CustomRuntimeObjectInstanceContainer
|
||||
*/
|
||||
export abstract class CustomRuntimeObject
|
||||
export class CustomRuntimeObject
|
||||
extends gdjs.RuntimeObject
|
||||
implements
|
||||
gdjs.Resizable,
|
||||
gdjs.Scalable,
|
||||
gdjs.Flippable,
|
||||
gdjs.OpacityHandler {
|
||||
_renderer:
|
||||
| gdjs.CustomRuntimeObject2DRenderer
|
||||
| gdjs.CustomRuntimeObject3DRenderer;
|
||||
/** It contains the children of this object. */
|
||||
_instanceContainer: gdjs.CustomRuntimeObjectInstanceContainer;
|
||||
_isUntransformedHitBoxesDirty: boolean = true;
|
||||
/** It contains shallow copies of the children hitboxes */
|
||||
private _untransformedHitBoxes: gdjs.Polygon[] = [];
|
||||
_untransformedHitBoxes: gdjs.Polygon[] = [];
|
||||
/** The dimension of this object is calculated from its children AABBs. */
|
||||
private _unrotatedAABB: AABB = { min: [0, 0], max: [0, 0] };
|
||||
private _scaleX: float = 1;
|
||||
private _scaleY: float = 1;
|
||||
private _flippedX: boolean = false;
|
||||
private _flippedY: boolean = false;
|
||||
private opacity: float = 255;
|
||||
private _customCenter: FloatPoint | null = null;
|
||||
private _localTransformation: gdjs.AffineTransformation = new gdjs.AffineTransformation();
|
||||
private _localInverseTransformation: gdjs.AffineTransformation = new gdjs.AffineTransformation();
|
||||
private _isLocalTransformationDirty: boolean = true;
|
||||
_unrotatedAABB: AABB = { min: [0, 0], max: [0, 0] };
|
||||
_scaleX: float = 1;
|
||||
_scaleY: float = 1;
|
||||
_flippedX: boolean = false;
|
||||
_flippedY: boolean = false;
|
||||
opacity: float = 255;
|
||||
_customCenter: FloatPoint | null = null;
|
||||
_localTransformation: gdjs.AffineTransformation = new gdjs.AffineTransformation();
|
||||
_localInverseTransformation: gdjs.AffineTransformation = new gdjs.AffineTransformation();
|
||||
_isLocalTransformationDirty: boolean = true;
|
||||
|
||||
/**
|
||||
* @param parent The container the object belongs to
|
||||
@@ -59,24 +56,19 @@ namespace gdjs {
|
||||
parent,
|
||||
this
|
||||
);
|
||||
this._renderer = this._createRender();
|
||||
|
||||
this._instanceContainer.loadFrom(objectData);
|
||||
this.getRenderer().reinitialize(this, parent);
|
||||
|
||||
// The generated code calls onCreated at the constructor end
|
||||
// and onCreated calls its super implementation at its end.
|
||||
}
|
||||
|
||||
protected abstract _createRender():
|
||||
| gdjs.CustomRuntimeObject2DRenderer
|
||||
| gdjs.CustomRuntimeObject3DRenderer;
|
||||
protected abstract _reinitializeRenderer(): void;
|
||||
|
||||
reinitialize(objectData: ObjectData & CustomObjectConfiguration) {
|
||||
super.reinitialize(objectData);
|
||||
|
||||
this._instanceContainer.loadFrom(objectData);
|
||||
this._reinitializeRenderer();
|
||||
this.getRenderer().reinitialize(this, this.getParent());
|
||||
|
||||
// The generated code calls the onCreated super implementation at the end.
|
||||
this.onCreated();
|
||||
@@ -108,14 +100,14 @@ namespace gdjs {
|
||||
update(parent: gdjs.RuntimeInstanceContainer): void {
|
||||
this._instanceContainer._updateObjectsPreEvents();
|
||||
|
||||
this.doStepPreEvents(this._instanceContainer);
|
||||
this.doStepPreEvents(parent);
|
||||
|
||||
const profiler = this.getRuntimeScene().getProfiler();
|
||||
if (profiler) {
|
||||
profiler.begin(this.type);
|
||||
}
|
||||
// This is a bit like the "scene" events for custom objects.
|
||||
this.doStepPostEvents(this._instanceContainer);
|
||||
this.doStepPostEvents(parent);
|
||||
if (profiler) {
|
||||
profiler.end(this.type);
|
||||
}
|
||||
@@ -148,10 +140,12 @@ namespace gdjs {
|
||||
this.getRenderer().ensureUpToDate();
|
||||
}
|
||||
|
||||
getRenderer():
|
||||
| gdjs.CustomRuntimeObject2DRenderer
|
||||
| gdjs.CustomRuntimeObject3DRenderer {
|
||||
return this._renderer;
|
||||
getRendererObject() {
|
||||
return this.getRenderer().getRendererObject();
|
||||
}
|
||||
|
||||
getRenderer() {
|
||||
return this._instanceContainer.getRenderer();
|
||||
}
|
||||
|
||||
onChildrenLocationChanged() {
|
||||
@@ -198,41 +192,40 @@ namespace gdjs {
|
||||
this._isUntransformedHitBoxesDirty = false;
|
||||
|
||||
this._untransformedHitBoxes.length = 0;
|
||||
let minX = Number.MAX_VALUE;
|
||||
let minY = Number.MAX_VALUE;
|
||||
let maxX = -Number.MAX_VALUE;
|
||||
let maxY = -Number.MAX_VALUE;
|
||||
for (const childInstance of this._instanceContainer.getAdhocListOfAllInstances()) {
|
||||
if (!childInstance.isIncludedInParentCollisionMask()) {
|
||||
continue;
|
||||
if (this._instanceContainer.getAdhocListOfAllInstances().length === 0) {
|
||||
this._unrotatedAABB.min[0] = 0;
|
||||
this._unrotatedAABB.min[1] = 0;
|
||||
this._unrotatedAABB.max[0] = 0;
|
||||
this._unrotatedAABB.max[1] = 0;
|
||||
} else {
|
||||
let minX = Number.MAX_VALUE;
|
||||
let minY = Number.MAX_VALUE;
|
||||
let maxX = -Number.MAX_VALUE;
|
||||
let maxY = -Number.MAX_VALUE;
|
||||
for (const childInstance of this._instanceContainer.getAdhocListOfAllInstances()) {
|
||||
if (!childInstance.isIncludedInParentCollisionMask()) {
|
||||
continue;
|
||||
}
|
||||
Array.prototype.push.apply(
|
||||
this._untransformedHitBoxes,
|
||||
childInstance.getHitBoxes()
|
||||
);
|
||||
const childAABB = childInstance.getAABB();
|
||||
minX = Math.min(minX, childAABB.min[0]);
|
||||
minY = Math.min(minY, childAABB.min[1]);
|
||||
maxX = Math.max(maxX, childAABB.max[0]);
|
||||
maxY = Math.max(maxY, childAABB.max[1]);
|
||||
}
|
||||
Array.prototype.push.apply(
|
||||
this._untransformedHitBoxes,
|
||||
childInstance.getHitBoxes()
|
||||
);
|
||||
const childAABB = childInstance.getAABB();
|
||||
minX = Math.min(minX, childAABB.min[0]);
|
||||
minY = Math.min(minY, childAABB.min[1]);
|
||||
maxX = Math.max(maxX, childAABB.max[0]);
|
||||
maxY = Math.max(maxY, childAABB.max[1]);
|
||||
}
|
||||
if (minX === Number.MAX_VALUE) {
|
||||
// The unscaled size can't be 0 because setWidth and setHeight wouldn't
|
||||
// have any effect.
|
||||
minX = 0;
|
||||
minY = 0;
|
||||
maxX = 1;
|
||||
maxY = 1;
|
||||
}
|
||||
this._unrotatedAABB.min[0] = minX;
|
||||
this._unrotatedAABB.min[1] = minY;
|
||||
this._unrotatedAABB.max[0] = maxX;
|
||||
this._unrotatedAABB.max[1] = maxY;
|
||||
this._unrotatedAABB.min[0] = minX;
|
||||
this._unrotatedAABB.min[1] = minY;
|
||||
this._unrotatedAABB.max[0] = maxX;
|
||||
this._unrotatedAABB.max[1] = maxY;
|
||||
|
||||
while (this.hitBoxes.length < this._untransformedHitBoxes.length) {
|
||||
this.hitBoxes.push(new gdjs.Polygon());
|
||||
while (this.hitBoxes.length < this._untransformedHitBoxes.length) {
|
||||
this.hitBoxes.push(new gdjs.Polygon());
|
||||
}
|
||||
this.hitBoxes.length = this._untransformedHitBoxes.length;
|
||||
}
|
||||
this.hitBoxes.length = this._untransformedHitBoxes.length;
|
||||
}
|
||||
|
||||
// Position:
|
||||
@@ -421,10 +414,6 @@ namespace gdjs {
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
|
||||
hasCustomRotationCenter(): boolean {
|
||||
return !!this._customCenter;
|
||||
}
|
||||
|
||||
getCenterX(): float {
|
||||
if (this._isUntransformedHitBoxesDirty) {
|
||||
this._updateUntransformedHitBoxes();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user