mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
33 Commits
v5.0.0-bet
...
v5.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e4fc065dc1 | ||
![]() |
d1f4d26e49 | ||
![]() |
a1b840a4fa | ||
![]() |
465629b688 | ||
![]() |
38758c62c6 | ||
![]() |
26f6e95e46 | ||
![]() |
34abf8290e | ||
![]() |
52677f5512 | ||
![]() |
df2b51bb1b | ||
![]() |
6b0ff984f2 | ||
![]() |
f4512242e4 | ||
![]() |
8beabbadef | ||
![]() |
9491a8ed45 | ||
![]() |
f945dfd987 | ||
![]() |
ff42591354 | ||
![]() |
21fb93c66a | ||
![]() |
068fbe653a | ||
![]() |
80891dcc59 | ||
![]() |
34155d65f1 | ||
![]() |
18f22470ca | ||
![]() |
92a8ebc58b | ||
![]() |
565384e270 | ||
![]() |
8335b2edf9 | ||
![]() |
12c77d0455 | ||
![]() |
13b62a06eb | ||
![]() |
d27119d8ea | ||
![]() |
dd3ff554d5 | ||
![]() |
287a17b634 | ||
![]() |
7dc477e29e | ||
![]() |
8174bca3b1 | ||
![]() |
7f6388c6f5 | ||
![]() |
da3a099ff2 | ||
![]() |
7b2c7b4a00 |
@@ -1,9 +1,75 @@
|
||||
# CircleCI 2.0 configuration file to build GDevelop app running
|
||||
# on the Electron runtime (newIDE/electron-app).
|
||||
# CircleCI configuration to build GDevelop app running
|
||||
# on the Electron runtime (newIDE/electron-app) for macOS and Linux.
|
||||
# For Windows, see the appveyor.yml file.
|
||||
|
||||
version: 2
|
||||
version: 2.1
|
||||
jobs:
|
||||
build:
|
||||
build-macos:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# System dependencies (for Emscripten and upload)
|
||||
- run:
|
||||
name: Install dependencies for Emscripten and AWS S3 upload
|
||||
command: brew install cmake && brew install awscli
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
|
||||
# GDevelop.js dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- gd-macos-nodejs-dependencies---
|
||||
|
||||
- run:
|
||||
name: Install GDevelop.js dependencies and build it
|
||||
command: cd GDevelop.js && npm install && cd ..
|
||||
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
- run:
|
||||
name: Build GDevelop.js
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
|
||||
|
||||
# GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version)
|
||||
- run:
|
||||
name: Install GDevelop IDE dependencies
|
||||
command: cd newIDE/app && npm install && cd ../electron-app && npm install
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- newIDE/electron-app/node_modules
|
||||
- newIDE/app/node_modules
|
||||
- GDevelop.js/node_modules
|
||||
key: gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
|
||||
|
||||
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
|
||||
# Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing).
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app"
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
path: newIDE/electron-app/dist
|
||||
|
||||
# Upload artifacts (AWS)
|
||||
- run:
|
||||
name: Deploy to S3 (specific commit)
|
||||
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/
|
||||
- run:
|
||||
name: Deploy to S3 (latest)
|
||||
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
build-linux:
|
||||
# CircleCI docker workers are failing if they don't have enough memory (no swap)
|
||||
resource_class: xlarge
|
||||
docker:
|
||||
@@ -23,10 +89,6 @@ jobs:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
|
||||
- run:
|
||||
name: Install Wine for Electron builder
|
||||
command: sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt install wine32
|
||||
|
||||
- run:
|
||||
name: Install system dependencies for Electron builder
|
||||
command: sudo apt install icnsutils && sudo apt install graphicsmagick && sudo apt install rsync
|
||||
@@ -34,15 +96,15 @@ jobs:
|
||||
# GDevelop.js dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
|
||||
- gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- gd-nodejs-dependencies---
|
||||
- gd-linux-nodejs-dependencies---
|
||||
|
||||
- run:
|
||||
name: Install GDevelop.js dependencies and build it
|
||||
command: cd GDevelop.js && sudo npm install -g grunt-cli && npm install && cd ..
|
||||
command: cd GDevelop.js && npm install && cd ..
|
||||
|
||||
# Build GDevelop.js
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
- run:
|
||||
name: Build GDevelop.js
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
|
||||
@@ -57,16 +119,16 @@ jobs:
|
||||
- newIDE/electron-app/node_modules
|
||||
- newIDE/app/node_modules
|
||||
- GDevelop.js/node_modules
|
||||
key: gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}
|
||||
key: gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
|
||||
|
||||
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux AppImage --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf newIDE/electron-app/dist/linux-unpacked && rm -rf newIDE/electron-app/dist/win-unpacked && rm -rf newIDE/electron-app/dist/mac
|
||||
command: rm -rf newIDE/electron-app/dist/linux-unpacked
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
@@ -79,3 +141,20 @@ jobs:
|
||||
- run:
|
||||
name: Deploy to S3 (latest)
|
||||
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
|
||||
workflows:
|
||||
builds:
|
||||
jobs:
|
||||
- build-macos:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /experimental-build.*/
|
||||
- build-linux:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /experimental-build.*/
|
||||
|
@@ -1,3 +1,12 @@
|
||||
# Travis CI configuration to build and run all tests
|
||||
# (and typing/formatting) for the Core, newIDE, GDJS (and even GDCpp).
|
||||
#
|
||||
# This builds GDevelop.js and store it on a S3 so it can be used to run
|
||||
# GDevelop without building it.
|
||||
#
|
||||
# See also Semaphore CI for quick tests (not building GDevelop.js, so
|
||||
# faster but not always reliable).
|
||||
|
||||
language: cpp
|
||||
sudo: false
|
||||
compiler:
|
||||
|
@@ -275,6 +275,76 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
|
||||
expression, condition, action);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName) {
|
||||
gd::String newNameWithNamespace = extensionNamespace + newActionName;
|
||||
gd::String copiedNameWithNamespace = extensionNamespace + copiedActionName;
|
||||
|
||||
auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
|
||||
if (copiedAction == actionsInfos.end()) {
|
||||
gd::LogWarning("Could not find an action with name " +
|
||||
copiedNameWithNamespace + " to copy.");
|
||||
} else {
|
||||
actionsInfos[newNameWithNamespace] = copiedAction->second;
|
||||
}
|
||||
|
||||
return actionsInfos[newNameWithNamespace];
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedCondition(
|
||||
const gd::String& newConditionName, const gd::String& copiedConditionName) {
|
||||
gd::String newNameWithNamespace = extensionNamespace + newConditionName;
|
||||
gd::String copiedNameWithNamespace = extensionNamespace + copiedConditionName;
|
||||
|
||||
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
|
||||
if (copiedCondition == conditionsInfos.end()) {
|
||||
gd::LogWarning("Could not find a condition with name " +
|
||||
copiedNameWithNamespace + " to copy.");
|
||||
} else {
|
||||
conditionsInfos[newNameWithNamespace] = copiedCondition->second;
|
||||
}
|
||||
|
||||
return conditionsInfos[newNameWithNamespace];
|
||||
}
|
||||
|
||||
gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedExpression(
|
||||
const gd::String& newExpressionName,
|
||||
const gd::String& copiedExpressionName) {
|
||||
gd::String newNameWithNamespace = extensionNamespace + newExpressionName;
|
||||
gd::String copiedNameWithNamespace =
|
||||
extensionNamespace + copiedExpressionName;
|
||||
|
||||
auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace);
|
||||
if (copiedExpression == expressionsInfos.end()) {
|
||||
gd::LogWarning("Could not find an expression with name " +
|
||||
copiedNameWithNamespace + " to copy.");
|
||||
} else {
|
||||
expressionsInfos[newNameWithNamespace] = copiedExpression->second;
|
||||
}
|
||||
|
||||
return expressionsInfos[newNameWithNamespace];
|
||||
}
|
||||
|
||||
gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedStrExpression(
|
||||
const gd::String& newExpressionName,
|
||||
const gd::String& copiedExpressionName) {
|
||||
gd::String newNameWithNamespace = extensionNamespace + newExpressionName;
|
||||
gd::String copiedNameWithNamespace =
|
||||
extensionNamespace + copiedExpressionName;
|
||||
|
||||
auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace);
|
||||
if (copiedExpression == strExpressionsInfos.end()) {
|
||||
gd::LogWarning("Could not find a string expression with name " +
|
||||
copiedNameWithNamespace + " to copy.");
|
||||
} else {
|
||||
strExpressionsInfos[newNameWithNamespace] = copiedExpression->second;
|
||||
}
|
||||
|
||||
return strExpressionsInfos[newNameWithNamespace];
|
||||
}
|
||||
#endif
|
||||
|
||||
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
fullname = fullname_;
|
||||
|
@@ -138,6 +138,46 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated action that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName);
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated condition that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedCondition(
|
||||
const gd::String& newConditionName,
|
||||
const gd::String& copiedConditionName);
|
||||
|
||||
/**
|
||||
* \brief Create a new expression which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated expression that is just a "copy" of the
|
||||
* new one.
|
||||
*/
|
||||
gd::ExpressionMetadata& AddDuplicatedExpression(
|
||||
const gd::String& newExpressionName,
|
||||
const gd::String& copiedExpressionName);
|
||||
|
||||
/**
|
||||
* \brief Create a new string expression which is the duplicate of the
|
||||
* specified one.
|
||||
*
|
||||
* Useful for handling a deprecated string expression that is just a "copy" of
|
||||
* the new one.
|
||||
*/
|
||||
gd::ExpressionMetadata& AddDuplicatedStrExpression(
|
||||
const gd::String& newExpressionName,
|
||||
const gd::String& copiedExpressionName);
|
||||
|
||||
BehaviorMetadata& SetFullName(const gd::String& fullname_);
|
||||
BehaviorMetadata& SetDefaultName(const gd::String& defaultName_);
|
||||
BehaviorMetadata& SetDescription(const gd::String& description_);
|
||||
|
@@ -187,6 +187,19 @@ class GD_CORE_API InstructionMetadata {
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set the additional information, used for some parameters
|
||||
* with special type (for example, it can contains the type of object accepted
|
||||
* by the parameter), for the last added parameter.
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetExtraInfo(extraInfo);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Add the default parameters for an instruction manipulating the
|
||||
* specified type ("string", "number") with the default operators.
|
||||
|
@@ -68,14 +68,14 @@ class GD_CORE_API ParameterMetadata {
|
||||
|
||||
/**
|
||||
* \brief Return an optional additional information, used for some parameters
|
||||
* with special type (For example, it can contains the type of object accepted
|
||||
* with special type (for example, it can contains the type of object accepted
|
||||
* by the parameter).
|
||||
*/
|
||||
const gd::String &GetExtraInfo() const { return supplementaryInformation; }
|
||||
|
||||
/**
|
||||
* \brief Set an optional additional information, used for some parameters
|
||||
* with special type (For example, it can contains the type of object accepted
|
||||
* with special type (for example, it can contains the type of object accepted
|
||||
* by the parameter).
|
||||
*/
|
||||
ParameterMetadata &SetExtraInfo(const gd::String &supplementaryInformation_) {
|
||||
|
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "EditorSettings.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
EditorSettings::EditorSettings() {}
|
||||
|
||||
void EditorSettings::SerializeTo(SerializerElement& element) const {
|
||||
element = content;
|
||||
}
|
||||
|
||||
void EditorSettings::UnserializeFrom(
|
||||
const SerializerElement& element) {
|
||||
content = element;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
#endif
|
46
Core/GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h
Normal file
46
Core/GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef SCENECANVASSETTINGS_H
|
||||
#define SCENECANVASSETTINGS_H
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Container for arbitrary serialized data to be used by the editor
|
||||
* to store settings.
|
||||
*
|
||||
* \see Scene
|
||||
*/
|
||||
class GD_CORE_API EditorSettings {
|
||||
public:
|
||||
EditorSettings();
|
||||
virtual ~EditorSettings(){};
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the settings.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the settings.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
gd::SerializerElement content; ///< Arbitrary content, depending on the editor.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // SCENECANVASSETTINGS_H
|
||||
#endif
|
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "LayoutEditorCanvasOptions.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
LayoutEditorCanvasOptions::LayoutEditorCanvasOptions()
|
||||
: grid(false),
|
||||
snap(true),
|
||||
gridWidth(32),
|
||||
gridHeight(32),
|
||||
gridOffsetX(0),
|
||||
gridOffsetY(0),
|
||||
gridType("rectangular"),
|
||||
gridR(158),
|
||||
gridG(180),
|
||||
gridB(255),
|
||||
zoomFactor(1),
|
||||
windowMask(false) {}
|
||||
|
||||
void LayoutEditorCanvasOptions::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("grid", grid);
|
||||
element.SetAttribute("snap", snap);
|
||||
element.SetAttribute("gridWidth", gridWidth);
|
||||
element.SetAttribute("gridHeight", gridHeight);
|
||||
element.SetAttribute("gridOffsetX", gridOffsetX);
|
||||
element.SetAttribute("gridOffsetY", gridOffsetY);
|
||||
element.SetAttribute("gridType", gridType);
|
||||
element.SetAttribute("gridR", gridR);
|
||||
element.SetAttribute("gridG", gridG);
|
||||
element.SetAttribute("gridB", gridB);
|
||||
element.SetAttribute("zoomFactor", zoomFactor);
|
||||
element.SetAttribute("windowMask", windowMask);
|
||||
}
|
||||
|
||||
void LayoutEditorCanvasOptions::UnserializeFrom(
|
||||
const SerializerElement& element) {
|
||||
grid = element.GetBoolAttribute("grid");
|
||||
snap = element.GetBoolAttribute("snap");
|
||||
windowMask = element.GetBoolAttribute("windowMask");
|
||||
gridWidth = element.GetDoubleAttribute("gridWidth", 32);
|
||||
gridHeight = element.GetDoubleAttribute("gridHeight", 32);
|
||||
gridOffsetX = element.GetDoubleAttribute("gridOffsetX", 0);
|
||||
gridOffsetY = element.GetDoubleAttribute("gridOffsetY", 0);
|
||||
gridType = element.GetStringAttribute("gridType", "rectangular");
|
||||
gridR = element.GetIntAttribute("gridR", 158);
|
||||
gridG = element.GetIntAttribute("gridG", 180);
|
||||
gridB = element.GetIntAttribute("gridB", 255);
|
||||
zoomFactor = element.GetDoubleAttribute("zoomFactor", 1.0);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
#endif
|
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef SCENECANVASSETTINGS_H
|
||||
#define SCENECANVASSETTINGS_H
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Tool class used to store settings of a LayoutEditorCanvas.
|
||||
*
|
||||
* \see Scene
|
||||
*/
|
||||
class GD_CORE_API LayoutEditorCanvasOptions {
|
||||
public:
|
||||
LayoutEditorCanvasOptions();
|
||||
virtual ~LayoutEditorCanvasOptions(){};
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* \brief Serialize instances container.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the instances container.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
bool grid; ///< True if grid activated in editor
|
||||
bool snap; ///< True if snap to grid activated in editor
|
||||
double gridWidth; ///< Grid width in editor
|
||||
double gridHeight; ///< Grid height in editor
|
||||
double gridOffsetX; ///< Grid X offset
|
||||
double gridOffsetY; ///< Grid Y offset
|
||||
gd::String gridType; ///< Grid type: rectangular or isometric
|
||||
int gridR; ///< Grid red color in editor
|
||||
int gridG; ///< Grid green color in editor
|
||||
int gridB; ///< Grid blue color in editor
|
||||
double zoomFactor; ///< Stores the zoom factor
|
||||
bool windowMask; ///< True if window mask displayed in editor
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // SCENECANVASSETTINGS_H
|
||||
#endif
|
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvasOptions.h"
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
@@ -16,7 +16,7 @@ void ExternalLayout::UnserializeFrom(const SerializerElement& element) {
|
||||
name = element.GetStringAttribute("name", "", "Name");
|
||||
instances.UnserializeFrom(element.GetChild("instances", 0, "Instances"));
|
||||
#if defined(GD_IDE_ONLY)
|
||||
editionSettings.UnserializeFrom(element.GetChild("editionSettings"));
|
||||
editorSettings.UnserializeFrom(element.GetChild("editionSettings"));
|
||||
#endif
|
||||
associatedLayout = element.GetStringAttribute("associatedLayout");
|
||||
}
|
||||
@@ -25,7 +25,7 @@ void ExternalLayout::UnserializeFrom(const SerializerElement& element) {
|
||||
void ExternalLayout::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("name", name);
|
||||
instances.SerializeTo(element.AddChild("instances"));
|
||||
editionSettings.SerializeTo(element.AddChild("editionSettings"));
|
||||
editorSettings.SerializeTo(element.AddChild("editionSettings"));
|
||||
element.SetAttribute("associatedLayout", associatedLayout);
|
||||
}
|
||||
#endif
|
||||
|
@@ -13,7 +13,7 @@ namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvasOptions.h"
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
@@ -58,15 +58,15 @@ class GD_CORE_API ExternalLayout {
|
||||
/**
|
||||
* \brief Get the user settings for the IDE.
|
||||
*/
|
||||
const gd::LayoutEditorCanvasOptions& GetAssociatedSettings() const {
|
||||
return editionSettings;
|
||||
const gd::EditorSettings& GetAssociatedEditorSettings() const {
|
||||
return editorSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the user settings for the IDE.
|
||||
*/
|
||||
gd::LayoutEditorCanvasOptions& GetAssociatedSettings() {
|
||||
return editionSettings;
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() {
|
||||
return editorSettings;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -100,7 +100,7 @@ class GD_CORE_API ExternalLayout {
|
||||
gd::String name;
|
||||
gd::InitialInstancesContainer instances;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::LayoutEditorCanvasOptions editionSettings;
|
||||
gd::EditorSettings editorSettings;
|
||||
#endif
|
||||
gd::String associatedLayout;
|
||||
};
|
||||
|
@@ -70,54 +70,35 @@ void Layer::UnserializeFrom(const SerializerElement& element) {
|
||||
element.GetIntAttribute("ambientLightColorG", 200),
|
||||
element.GetIntAttribute("ambientLightColorB", 200));
|
||||
|
||||
// Compatibility with GD <= 3.3
|
||||
if (element.HasChild("Camera")) {
|
||||
for (std::size_t i = 0; i < element.GetChildrenCount("Camera"); ++i) {
|
||||
const SerializerElement& cameraElement = element.GetChild("Camera", i);
|
||||
SetCameraCount(GetCameraCount() + 1);
|
||||
Camera& camera = GetCamera(GetCameraCount() - 1);
|
||||
cameras.clear();
|
||||
SerializerElement& camerasElement = element.GetChild("cameras");
|
||||
camerasElement.ConsiderAsArrayOf("camera");
|
||||
for (std::size_t i = 0; i < camerasElement.GetChildrenCount(); ++i) {
|
||||
const SerializerElement& cameraElement = camerasElement.GetChild(i);
|
||||
|
||||
camera.SetUseDefaultSize(
|
||||
cameraElement.GetBoolAttribute("DefaultSize", true));
|
||||
camera.SetSize(cameraElement.GetDoubleAttribute("Width"),
|
||||
cameraElement.GetDoubleAttribute("Height"));
|
||||
Camera camera;
|
||||
camera.SetUseDefaultSize(
|
||||
cameraElement.GetBoolAttribute("defaultSize", true));
|
||||
camera.SetSize(cameraElement.GetDoubleAttribute("width"),
|
||||
cameraElement.GetDoubleAttribute("height"));
|
||||
camera.SetUseDefaultViewport(
|
||||
cameraElement.GetBoolAttribute("defaultViewport", true));
|
||||
camera.SetViewport(
|
||||
cameraElement.GetDoubleAttribute("viewportLeft"),
|
||||
cameraElement.GetDoubleAttribute("viewportTop"),
|
||||
cameraElement.GetDoubleAttribute("viewportRight"),
|
||||
cameraElement.GetDoubleAttribute(
|
||||
"viewportBottom"));
|
||||
|
||||
camera.SetUseDefaultViewport(
|
||||
cameraElement.GetBoolAttribute("DefaultViewport", true));
|
||||
camera.SetViewport(
|
||||
cameraElement.GetDoubleAttribute("ViewportLeft"),
|
||||
cameraElement.GetDoubleAttribute("ViewportTop"),
|
||||
cameraElement.GetDoubleAttribute("ViewportRight"),
|
||||
cameraElement.GetDoubleAttribute(
|
||||
"ViewportBottom")); // (sf::Rect used Right and Bottom instead of
|
||||
// Width and Height before)
|
||||
}
|
||||
cameras.push_back(camera);
|
||||
}
|
||||
// End of compatibility code
|
||||
else {
|
||||
SerializerElement& camerasElement = element.GetChild("cameras");
|
||||
camerasElement.ConsiderAsArrayOf("camera");
|
||||
for (std::size_t i = 0; i < camerasElement.GetChildrenCount(); ++i) {
|
||||
const SerializerElement& cameraElement = camerasElement.GetChild(i);
|
||||
|
||||
SetCameraCount(GetCameraCount() + 1);
|
||||
Camera& camera = GetCamera(GetCameraCount() - 1);
|
||||
|
||||
camera.SetUseDefaultSize(
|
||||
cameraElement.GetBoolAttribute("defaultSize", true));
|
||||
camera.SetSize(cameraElement.GetDoubleAttribute("width"),
|
||||
cameraElement.GetDoubleAttribute("height"));
|
||||
|
||||
camera.SetUseDefaultViewport(
|
||||
cameraElement.GetBoolAttribute("defaultViewport", true));
|
||||
camera.SetViewport(
|
||||
cameraElement.GetDoubleAttribute("viewportLeft"),
|
||||
cameraElement.GetDoubleAttribute("viewportTop"),
|
||||
cameraElement.GetDoubleAttribute("viewportRight"),
|
||||
cameraElement.GetDoubleAttribute(
|
||||
"viewportBottom")); // (sf::Rect used Right and Bottom instead of
|
||||
// Width and Height before)
|
||||
}
|
||||
if (camerasElement.GetChildrenCount() > 50) {
|
||||
// Highly unlikely that we want as many cameras, as they were not even exposed in
|
||||
// the editor nor used in the game engine. Must be because of a bug in the editor that
|
||||
// duplicated cameras when cancelling changes on a layer.
|
||||
// Reset to one camera.
|
||||
SetCameraCount(1);
|
||||
}
|
||||
|
||||
const SerializerElement& effectsElement = element.GetChild("effects");
|
||||
|
@@ -272,7 +272,7 @@ void Layout::SerializeTo(SerializerElement& element) const {
|
||||
disableInputWhenNotFocused);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
GetAssociatedSettings().SerializeTo(element.AddChild("uiSettings"));
|
||||
editorSettings.SerializeTo(element.AddChild("uiSettings"));
|
||||
#endif
|
||||
|
||||
GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
|
||||
@@ -333,7 +333,7 @@ void Layout::UnserializeFrom(gd::Project& project,
|
||||
element.GetBoolAttribute("disableInputWhenNotFocused");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
associatedSettings.UnserializeFrom(
|
||||
editorSettings.UnserializeFrom(
|
||||
element.GetChild("uiSettings", 0, "UISettings"));
|
||||
|
||||
GetObjectGroups().UnserializeFrom(
|
||||
@@ -412,7 +412,7 @@ void Layout::Init(const Layout& other) {
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
events = other.events;
|
||||
associatedSettings = other.associatedSettings;
|
||||
editorSettings = other.editorSettings;
|
||||
objectGroups = other.objectGroups;
|
||||
|
||||
profiler = other.profiler;
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvasOptions.h"
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#endif
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
@@ -291,18 +291,18 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* Return the settings associated to the layout.
|
||||
* \see gd::LayoutEditorCanvasOptions
|
||||
* \see gd::EditorSettings
|
||||
*/
|
||||
const gd::LayoutEditorCanvasOptions& GetAssociatedSettings() const {
|
||||
return associatedSettings;
|
||||
const gd::EditorSettings& GetAssociatedEditorSettings() const {
|
||||
return editorSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the settings associated to the layout.
|
||||
* \see gd::LayoutEditorCanvasOptions
|
||||
* \see gd::EditorSettings
|
||||
*/
|
||||
gd::LayoutEditorCanvasOptions& GetAssociatedSettings() {
|
||||
return associatedSettings;
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() {
|
||||
return editorSettings;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -436,7 +436,7 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
///< specified behavior shared data.
|
||||
#if defined(GD_IDE_ONLY)
|
||||
EventsList events; ///< Scene events
|
||||
gd::LayoutEditorCanvasOptions associatedSettings;
|
||||
gd::EditorSettings editorSettings;
|
||||
#endif
|
||||
|
||||
// TODO: GD C++ Platform specific code below
|
||||
|
@@ -5,15 +5,63 @@
|
||||
*/
|
||||
|
||||
#include "LoadingScreen.h"
|
||||
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
LoadingScreen::LoadingScreen()
|
||||
: showGDevelopSplash(true),
|
||||
gdevelopLogoStyle("light"),
|
||||
backgroundImageResourceName(""),
|
||||
backgroundColor(0),
|
||||
backgroundFadeInDuration(0.2),
|
||||
minDuration(1.5),
|
||||
logoAndProgressFadeInDuration(0.2),
|
||||
logoAndProgressLogoFadeInDelay(0.2),
|
||||
showProgressBar(true),
|
||||
progressBarMinWidth(40),
|
||||
progressBarMaxWidth(200),
|
||||
progressBarWidthPercent(30),
|
||||
progressBarHeight(20),
|
||||
progressBarColor(0xFFFFFF){};
|
||||
|
||||
void LoadingScreen::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("showGDevelopSplash", showGDevelopSplash);
|
||||
element.SetAttribute("gdevelopLogoStyle",
|
||||
gdevelopLogoStyle);
|
||||
element.SetAttribute("backgroundImageResourceName",
|
||||
backgroundImageResourceName);
|
||||
element.SetAttribute("backgroundColor", backgroundColor);
|
||||
element.SetAttribute("backgroundFadeInDuration", backgroundFadeInDuration);
|
||||
element.SetAttribute("minDuration", minDuration);
|
||||
element.SetAttribute("logoAndProgressFadeInDuration", logoAndProgressFadeInDuration);
|
||||
element.SetAttribute("logoAndProgressLogoFadeInDelay", logoAndProgressLogoFadeInDelay);
|
||||
element.SetAttribute("showProgressBar", showProgressBar);
|
||||
element.SetAttribute("progressBarMinWidth", progressBarMinWidth);
|
||||
element.SetAttribute("progressBarMaxWidth", progressBarMaxWidth);
|
||||
element.SetAttribute("progressBarWidthPercent", progressBarWidthPercent);
|
||||
element.SetAttribute("progressBarHeight", progressBarHeight);
|
||||
element.SetAttribute("progressBarColor", progressBarColor);
|
||||
}
|
||||
|
||||
void LoadingScreen::UnserializeFrom(const SerializerElement& element) {
|
||||
showGDevelopSplash = element.GetBoolAttribute("showGDevelopSplash", true);
|
||||
gdevelopLogoStyle =
|
||||
element.GetStringAttribute("gdevelopLogoStyle", "light");
|
||||
backgroundImageResourceName =
|
||||
element.GetStringAttribute("backgroundImageResourceName");
|
||||
backgroundColor = element.GetIntAttribute("backgroundColor", 0);
|
||||
backgroundFadeInDuration =
|
||||
element.GetDoubleAttribute("backgroundFadeInDuration", 0.2);
|
||||
minDuration = element.GetDoubleAttribute("minDuration", 1.5);
|
||||
logoAndProgressFadeInDuration = element.GetDoubleAttribute("logoAndProgressFadeInDuration", 0.2);
|
||||
logoAndProgressLogoFadeInDelay = element.GetDoubleAttribute("logoAndProgressLogoFadeInDelay", 0.2);
|
||||
showProgressBar = element.GetBoolAttribute("showProgressBar", true);
|
||||
progressBarMinWidth = element.GetDoubleAttribute("progressBarMinWidth", 40);
|
||||
progressBarMaxWidth = element.GetDoubleAttribute("progressBarMaxWidth", 200);
|
||||
progressBarWidthPercent = element.GetDoubleAttribute("progressBarWidthPercent", 30);
|
||||
progressBarHeight = element.GetDoubleAttribute("progressBarHeight", 20);
|
||||
progressBarColor = element.GetIntAttribute("progressBarColor", 0xFFFFFF);
|
||||
}
|
||||
} // namespace gd
|
||||
|
@@ -22,36 +22,151 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API LoadingScreen {
|
||||
public:
|
||||
LoadingScreen(){};
|
||||
LoadingScreen();
|
||||
virtual ~LoadingScreen(){};
|
||||
|
||||
/**
|
||||
* \brief Set if the GDevelop splash should be shown while loading assets.
|
||||
*/
|
||||
void ShowGDevelopSplash(bool show) { showGDevelopSplash = show; };
|
||||
|
||||
/**
|
||||
* \brief Return true if the GDevelop splash should be shown while loading
|
||||
* \brief Return true if the GDevelop logo should be shown while loading
|
||||
* assets.
|
||||
*/
|
||||
bool IsGDevelopSplashShown() const { return showGDevelopSplash; };
|
||||
|
||||
/**
|
||||
* \brief Set if the GDevelop logo should be shown while loading assets.
|
||||
*/
|
||||
LoadingScreen& ShowGDevelopSplash(bool show) {
|
||||
showGDevelopSplash = show;
|
||||
return *this;
|
||||
};
|
||||
|
||||
const gd::String& GetGDevelopLogoStyle() const { return gdevelopLogoStyle; };
|
||||
|
||||
LoadingScreen& SetGDevelopLogoStyle(const gd::String& value) {
|
||||
gdevelopLogoStyle = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetBackgroundImageResourceName() const {
|
||||
return backgroundImageResourceName;
|
||||
};
|
||||
|
||||
LoadingScreen& SetBackgroundImageResourceName(const gd::String& value) {
|
||||
backgroundImageResourceName = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int GetBackgroundColor() const { return backgroundColor; };
|
||||
|
||||
LoadingScreen& SetBackgroundColor(int value) {
|
||||
backgroundColor = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetBackgroundFadeInDuration() const {
|
||||
return backgroundFadeInDuration;
|
||||
};
|
||||
|
||||
LoadingScreen& SetBackgroundFadeInDuration(double value) {
|
||||
backgroundFadeInDuration = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetMinDuration() const { return minDuration; };
|
||||
|
||||
LoadingScreen& SetMinDuration(double value) {
|
||||
minDuration = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetLogoAndProgressFadeInDuration() const {
|
||||
return logoAndProgressFadeInDuration;
|
||||
}
|
||||
|
||||
LoadingScreen& SetLogoAndProgressFadeInDuration(double value) {
|
||||
logoAndProgressFadeInDuration = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetLogoAndProgressLogoFadeInDelay() const {
|
||||
return logoAndProgressLogoFadeInDelay;
|
||||
}
|
||||
|
||||
LoadingScreen& SetLogoAndProgressLogoFadeInDelay(double value) {
|
||||
logoAndProgressLogoFadeInDelay = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool GetShowProgressBar() const { return showProgressBar; }
|
||||
|
||||
LoadingScreen& SetShowProgressBar(bool value) {
|
||||
showProgressBar = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetProgressBarMinWidth() const { return progressBarMinWidth; }
|
||||
|
||||
LoadingScreen& SetProgressBarMinWidth(double value) {
|
||||
progressBarMinWidth = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetProgressBarMaxWidth() const { return progressBarMaxWidth; }
|
||||
|
||||
LoadingScreen& SetProgressBarMaxWidth(double value) {
|
||||
progressBarMaxWidth = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetProgressBarWidthPercent() const { return progressBarWidthPercent; }
|
||||
|
||||
LoadingScreen& SetProgressBarWidthPercent(double value) {
|
||||
progressBarWidthPercent = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double GetProgressBarHeight() const { return progressBarHeight; }
|
||||
|
||||
LoadingScreen& SetProgressBarHeight(double value) {
|
||||
progressBarHeight = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int GetProgressBarColor() const { return progressBarColor; }
|
||||
|
||||
LoadingScreen& SetProgressBarColor(int value) {
|
||||
progressBarColor = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** \name Saving and loading
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize objects groups container.
|
||||
* \brief Serialize the loading screen setup.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the objects groups container.
|
||||
* \brief Unserialize the loading screen setup.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
bool showGDevelopSplash;
|
||||
gd::String gdevelopLogoStyle;
|
||||
gd::String backgroundImageResourceName;
|
||||
int backgroundColor;
|
||||
double backgroundFadeInDuration; // In seconds.
|
||||
double minDuration; // In seconds.
|
||||
double logoAndProgressFadeInDuration; // In seconds.
|
||||
double logoAndProgressLogoFadeInDelay; // In seconds.
|
||||
bool showProgressBar;
|
||||
double progressBarMinWidth; // In pixels.
|
||||
double progressBarMaxWidth; // In pixels.
|
||||
double progressBarWidthPercent;
|
||||
double progressBarHeight; // In pixels.
|
||||
int progressBarColor;
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
|
@@ -24,12 +24,14 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const isFocused = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFocused();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const show = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
@@ -39,12 +41,14 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const isVisible = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isVisible();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const maximize = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
@@ -54,12 +58,14 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const isMaximized = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const minimize = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
@@ -69,89 +75,105 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const isMinimized = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const enable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setEnabled(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isEnabled = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isEnabled();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setResizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setResizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isResizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isResizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMovable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMovable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMovable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMovable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMaximizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMaximizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMaximizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMinimizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMinimizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMinimizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setFullScreenable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFullScreenable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isFullScreenable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFullScreenable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setClosable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setClosable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isClosable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isClosable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setAlwaysOnTop = function (
|
||||
activate: boolean,
|
||||
level:
|
||||
@@ -168,73 +190,86 @@ namespace gdjs {
|
||||
electronBrowserWindow.setAlwaysOnTop(activate, level);
|
||||
}
|
||||
};
|
||||
|
||||
export const isAlwaysOnTop = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isAlwaysOnTop();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setPosition = function (x: float, y: float) {
|
||||
if (electronBrowserWindow) {
|
||||
// Convert x and y to (32 bit) integers to avoid Electron errors.
|
||||
electronBrowserWindow.setPosition(~~x, ~~y);
|
||||
}
|
||||
};
|
||||
|
||||
export const getPositionX = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[0];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const getPositionY = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[1];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const setKiosk = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setKiosk(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isKiosk = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isKiosk();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const flash = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.flashFrame(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const setHasShadow = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setHasShadow(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const hasShadow = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.hasShadow();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setOpacity = function (opacity: float) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setOpacity(opacity);
|
||||
}
|
||||
};
|
||||
|
||||
export const getOpacity = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getOpacity();
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
export const setContentProtection = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setContentProtection(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const setFocusable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFocusable(activate);
|
||||
|
@@ -11,6 +11,7 @@ namespace gdjs {
|
||||
export const myConditionFunction = function (number, text) {
|
||||
return number <= 10 && text.length < 5;
|
||||
};
|
||||
|
||||
export const getString = function () {
|
||||
return 'Hello World';
|
||||
};
|
||||
|
@@ -18,18 +18,21 @@ namespace gdjs {
|
||||
supportedAPIs.indexOf('getRewardedVideoAsync') !== -1
|
||||
);
|
||||
};
|
||||
|
||||
export const getPlayerId = function () {
|
||||
if (typeof FBInstant === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
return FBInstant.player.getID() || '';
|
||||
};
|
||||
|
||||
export const getPlayerName = function () {
|
||||
if (typeof FBInstant === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
return FBInstant.player.getName() || '';
|
||||
};
|
||||
|
||||
export const loadPlayerData = function (
|
||||
key,
|
||||
successVariable,
|
||||
@@ -49,6 +52,7 @@ namespace gdjs {
|
||||
errorVariable.setString(error.message || 'Unknown error');
|
||||
});
|
||||
};
|
||||
|
||||
export const setPlayerData = function (
|
||||
key,
|
||||
variable,
|
||||
@@ -71,6 +75,7 @@ namespace gdjs {
|
||||
errorVariable.setString(error.message || 'Unknown error');
|
||||
});
|
||||
};
|
||||
|
||||
export const setPlayerScore = function (
|
||||
leaderboardName,
|
||||
score,
|
||||
@@ -95,6 +100,7 @@ namespace gdjs {
|
||||
errorVariable.setString(error.message || 'Unknown error');
|
||||
});
|
||||
};
|
||||
|
||||
export const getPlayerEntry = function (
|
||||
leaderboardName,
|
||||
rankVariable,
|
||||
@@ -124,6 +130,7 @@ namespace gdjs {
|
||||
errorVariable.setString(error.message || 'Unknown error');
|
||||
});
|
||||
};
|
||||
|
||||
export const loadInterstitialAd = function (
|
||||
adPlacementId,
|
||||
errorVariable
|
||||
@@ -155,6 +162,7 @@ namespace gdjs {
|
||||
errorVariable.setString(err.message || 'Unknown error');
|
||||
});
|
||||
};
|
||||
|
||||
export const showInterstitialAd = function (errorVariable) {
|
||||
if (typeof FBInstant === 'undefined') {
|
||||
return;
|
||||
@@ -175,9 +183,11 @@ namespace gdjs {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = false;
|
||||
});
|
||||
};
|
||||
|
||||
export const isInterstitialAdReady = function () {
|
||||
return gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded;
|
||||
};
|
||||
|
||||
export const loadRewardedVideo = function (adPlacementId, errorVariable) {
|
||||
if (typeof FBInstant === 'undefined') {
|
||||
return;
|
||||
@@ -206,6 +216,7 @@ namespace gdjs {
|
||||
errorVariable.setString(err.message || 'Unknown error');
|
||||
});
|
||||
};
|
||||
|
||||
export const showRewardedVideo = function (errorVariable) {
|
||||
if (typeof FBInstant === 'undefined') {
|
||||
return;
|
||||
@@ -226,6 +237,7 @@ namespace gdjs {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = false;
|
||||
});
|
||||
};
|
||||
|
||||
export const isRewardedVideoReady = function () {
|
||||
return gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded;
|
||||
};
|
||||
|
@@ -24,6 +24,7 @@ namespace gdjs {
|
||||
}
|
||||
return gdjs.fileSystem._fs;
|
||||
};
|
||||
|
||||
export const getDirectoryName = function (fileOrFolderPath: string) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) {
|
||||
@@ -31,6 +32,7 @@ namespace gdjs {
|
||||
}
|
||||
return path.dirname(fileOrFolderPath);
|
||||
};
|
||||
|
||||
export const getFileName = function (filePath: string) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) {
|
||||
@@ -38,6 +40,7 @@ namespace gdjs {
|
||||
}
|
||||
return path.basename(filePath);
|
||||
};
|
||||
|
||||
export const getExtensionName = function (filePath: string) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) {
|
||||
|
@@ -18,15 +18,19 @@ namespace gdjs {
|
||||
export const add = function (runtimeScene, inventoryName, name) {
|
||||
return InventoryManager.get(runtimeScene, inventoryName).add(name);
|
||||
};
|
||||
|
||||
export const remove = function (runtimeScene, inventoryName, name) {
|
||||
return InventoryManager.get(runtimeScene, inventoryName).remove(name);
|
||||
};
|
||||
|
||||
export const count = function (runtimeScene, inventoryName, name) {
|
||||
return InventoryManager.get(runtimeScene, inventoryName).count(name);
|
||||
};
|
||||
|
||||
export const has = function (runtimeScene, inventoryName, name) {
|
||||
return InventoryManager.get(runtimeScene, inventoryName).has(name);
|
||||
};
|
||||
|
||||
export const setMaximum = function (
|
||||
runtimeScene,
|
||||
inventoryName,
|
||||
@@ -38,6 +42,7 @@ namespace gdjs {
|
||||
maxCount
|
||||
);
|
||||
};
|
||||
|
||||
export const setUnlimited = function (
|
||||
runtimeScene,
|
||||
inventoryName,
|
||||
@@ -49,20 +54,24 @@ namespace gdjs {
|
||||
enable
|
||||
);
|
||||
};
|
||||
|
||||
export const isFull = function (runtimeScene, inventoryName, name) {
|
||||
return InventoryManager.get(runtimeScene, inventoryName).isFull(name);
|
||||
};
|
||||
|
||||
export const equip = function (runtimeScene, inventoryName, name, equip) {
|
||||
return InventoryManager.get(runtimeScene, inventoryName).equip(
|
||||
name,
|
||||
equip
|
||||
);
|
||||
};
|
||||
|
||||
export const isEquipped = function (runtimeScene, inventoryName, name) {
|
||||
return InventoryManager.get(runtimeScene, inventoryName).isEquipped(
|
||||
name
|
||||
);
|
||||
};
|
||||
|
||||
export const serializeToVariable = function (
|
||||
runtimeScene,
|
||||
inventoryName: string,
|
||||
@@ -81,6 +90,7 @@ namespace gdjs {
|
||||
serializedItem.getChild('equipped').setBoolean(item.equipped);
|
||||
}
|
||||
};
|
||||
|
||||
export const unserializeFromVariable = function (
|
||||
runtimeScene,
|
||||
inventoryName: string,
|
||||
|
@@ -221,7 +221,7 @@ module.exports = {
|
||||
'res/actions/color.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), 'LightObject', false)
|
||||
.addParameter('string', _('Color'), '', false)
|
||||
.addParameter('color', _('Color'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('setColor');
|
||||
|
||||
|
@@ -90,6 +90,7 @@ namespace gdjs {
|
||||
}
|
||||
LinksManager.getManager(runtimeScene).linkObjects(objA, objB);
|
||||
};
|
||||
|
||||
export const removeLinkBetween = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
objA: gdjs.RuntimeObject,
|
||||
@@ -100,6 +101,7 @@ namespace gdjs {
|
||||
}
|
||||
LinksManager.getManager(runtimeScene).removeLinkBetween(objA, objB);
|
||||
};
|
||||
|
||||
export const removeAllLinksOf = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
objA: gdjs.RuntimeObject
|
||||
@@ -109,12 +111,14 @@ namespace gdjs {
|
||||
}
|
||||
LinksManager.getManager(runtimeScene).removeAllLinksOf(objA);
|
||||
};
|
||||
|
||||
export const _objectIsInList = function (
|
||||
obj: gdjs.RuntimeObject,
|
||||
linkedObjects: gdjs.RuntimeObject[]
|
||||
) {
|
||||
return linkedObjects.indexOf(obj) !== -1;
|
||||
};
|
||||
|
||||
export const pickObjectsLinkedTo = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
objectsLists: Hashtable<gdjs.RuntimeObject[]>,
|
||||
|
@@ -2,10 +2,18 @@ namespace gdjs {
|
||||
import PIXI = GlobalPIXIModule.PIXI;
|
||||
class PanelSpriteRuntimeObjectPixiRenderer {
|
||||
_object: gdjs.PanelSpriteRuntimeObject;
|
||||
_spritesContainer: any;
|
||||
_centerSprite: any;
|
||||
_borderSprites: any;
|
||||
_alpha: float;
|
||||
/**
|
||||
* The _wrapperContainer must be considered as the main container of this object
|
||||
* All transformations are applied on this container
|
||||
* See updateOpacity for more info why.
|
||||
*/
|
||||
_wrapperContainer: PIXI.Container;
|
||||
/**
|
||||
* The _spritesContainer is used to create the sprites and apply cacheAsBitmap only.
|
||||
*/
|
||||
_spritesContainer: PIXI.Container;
|
||||
_centerSprite: PIXI.Sprite | PIXI.TilingSprite;
|
||||
_borderSprites: Array<PIXI.Sprite | PIXI.TilingSprite>;
|
||||
_wasRendered: boolean = false;
|
||||
_textureWidth = 0;
|
||||
_textureHeight = 0;
|
||||
@@ -17,38 +25,37 @@ namespace gdjs {
|
||||
tiled: boolean
|
||||
) {
|
||||
this._object = runtimeObject;
|
||||
if (this._spritesContainer === undefined) {
|
||||
const texture = (runtimeScene
|
||||
.getGame()
|
||||
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
|
||||
textureName
|
||||
);
|
||||
const StretchedSprite = !tiled ? PIXI.Sprite : PIXI.TilingSprite;
|
||||
this._spritesContainer = new PIXI.Container();
|
||||
const texture = (runtimeScene
|
||||
.getGame()
|
||||
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
|
||||
textureName
|
||||
);
|
||||
const StretchedSprite = !tiled ? PIXI.Sprite : PIXI.TilingSprite;
|
||||
this._spritesContainer = new PIXI.Container();
|
||||
this._wrapperContainer = new PIXI.Container();
|
||||
// @ts-ignore
|
||||
this._centerSprite = new StretchedSprite(new PIXI.Texture(texture));
|
||||
this._borderSprites = [
|
||||
// @ts-ignore
|
||||
this._centerSprite = new StretchedSprite(new PIXI.Texture(texture));
|
||||
this._borderSprites = [
|
||||
// @ts-ignore
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Right
|
||||
new PIXI.Sprite(texture),
|
||||
//Top-Right
|
||||
// @ts-ignore
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Top
|
||||
new PIXI.Sprite(texture),
|
||||
//Top-Left
|
||||
// @ts-ignore
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Left
|
||||
new PIXI.Sprite(texture),
|
||||
//Bottom-Left
|
||||
// @ts-ignore
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Bottom
|
||||
new PIXI.Sprite(texture),
|
||||
];
|
||||
}
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Right
|
||||
new PIXI.Sprite(texture),
|
||||
//Top-Right
|
||||
// @ts-ignore
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Top
|
||||
new PIXI.Sprite(texture),
|
||||
//Top-Left
|
||||
// @ts-ignore
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Left
|
||||
new PIXI.Sprite(texture),
|
||||
//Bottom-Left
|
||||
// @ts-ignore
|
||||
new StretchedSprite(new PIXI.Texture(texture)),
|
||||
//Bottom
|
||||
new PIXI.Sprite(texture),
|
||||
];
|
||||
|
||||
//Bottom-Right
|
||||
this.setTexture(textureName, runtimeScene);
|
||||
@@ -57,44 +64,43 @@ namespace gdjs {
|
||||
for (let i = 0; i < this._borderSprites.length; ++i) {
|
||||
this._spritesContainer.addChild(this._borderSprites[i]);
|
||||
}
|
||||
this._alpha = this._spritesContainer.alpha;
|
||||
this._wrapperContainer.addChild(this._spritesContainer);
|
||||
runtimeScene
|
||||
.getLayer('')
|
||||
.getRenderer()
|
||||
.addRendererObject(this._spritesContainer, runtimeObject.getZOrder());
|
||||
.addRendererObject(this._wrapperContainer, runtimeObject.getZOrder());
|
||||
}
|
||||
|
||||
getRendererObject() {
|
||||
return this._spritesContainer;
|
||||
return this._wrapperContainer;
|
||||
}
|
||||
|
||||
ensureUpToDate() {
|
||||
if (this._spritesContainer.visible && this._wasRendered) {
|
||||
// Update the alpha of the container to make sure that it's applied.
|
||||
// If not done, the alpha will be back to full opaque when changing the color
|
||||
// of the object.
|
||||
this._spritesContainer.alpha = this._alpha;
|
||||
// Cache the rendered sprites as a bitmap to speed up rendering when
|
||||
// lots of panel sprites are on the scene.
|
||||
// Sadly, because of this, we need a wrapper container to workaround
|
||||
// a PixiJS issue with alpha (see updateOpacity).
|
||||
this._spritesContainer.cacheAsBitmap = true;
|
||||
}
|
||||
this._wasRendered = true;
|
||||
}
|
||||
|
||||
updateOpacity(): void {
|
||||
//TODO: Workaround a not working property in PIXI.js:
|
||||
this._spritesContainer.alpha = this._spritesContainer.visible
|
||||
? this._object.opacity / 255
|
||||
: 0;
|
||||
this._alpha = this._spritesContainer.alpha;
|
||||
// The alpha is updated on a wrapper around the sprite because a known bug
|
||||
// in Pixi will create a flicker when cacheAsBitmap is set to true.
|
||||
// (see https://github.com/pixijs/pixijs/issues/4610)
|
||||
this._wrapperContainer.alpha = this._object.opacity / 255;
|
||||
}
|
||||
|
||||
updateAngle(): void {
|
||||
this._spritesContainer.rotation = gdjs.toRad(this._object.angle);
|
||||
this._wrapperContainer.rotation = gdjs.toRad(this._object.angle);
|
||||
}
|
||||
|
||||
updatePosition(): void {
|
||||
this._spritesContainer.position.x =
|
||||
this._wrapperContainer.position.x =
|
||||
this._object.x + this._object._width / 2;
|
||||
this._spritesContainer.position.y =
|
||||
this._wrapperContainer.position.y =
|
||||
this._object.y + this._object._height / 2;
|
||||
}
|
||||
|
||||
@@ -316,19 +322,19 @@ namespace gdjs {
|
||||
this._updateSpritesAndTexturesSize();
|
||||
this._updateLocalPositions();
|
||||
this.updatePosition();
|
||||
this._spritesContainer.pivot.x = this._object._width / 2;
|
||||
this._spritesContainer.pivot.y = this._object._height / 2;
|
||||
this._wrapperContainer.pivot.x = this._object._width / 2;
|
||||
this._wrapperContainer.pivot.y = this._object._height / 2;
|
||||
}
|
||||
|
||||
updateWidth(): void {
|
||||
this._spritesContainer.pivot.x = this._object._width / 2;
|
||||
this._wrapperContainer.pivot.x = this._object._width / 2;
|
||||
this._updateSpritesAndTexturesSize();
|
||||
this._updateLocalPositions();
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updateHeight(): void {
|
||||
this._spritesContainer.pivot.y = this._object._height / 2;
|
||||
this._wrapperContainer.pivot.y = this._object._height / 2;
|
||||
this._updateSpritesAndTexturesSize();
|
||||
this._updateLocalPositions();
|
||||
this.updatePosition();
|
||||
@@ -339,25 +345,21 @@ namespace gdjs {
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._centerSprite.tint =
|
||||
'0x' +
|
||||
gdjs.rgbToHex(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
this._centerSprite.tint = gdjs.rgbToHexNumber(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
for (
|
||||
let borderCounter = 0;
|
||||
borderCounter < this._borderSprites.length;
|
||||
borderCounter++
|
||||
) {
|
||||
this._borderSprites[borderCounter].tint =
|
||||
'0x' +
|
||||
gdjs.rgbToHex(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
this._borderSprites[borderCounter].tint = gdjs.rgbToHexNumber(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
}
|
||||
this._spritesContainer.cacheAsBitmap = false;
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ namespace gdjs {
|
||||
behavior
|
||||
);
|
||||
};
|
||||
|
||||
export const setTimeScale = function (objectsLists, behavior, timeScale) {
|
||||
const lists = gdjs.staticArray(gdjs.physics2.setTimeScale);
|
||||
objectsLists.values(lists);
|
||||
|
@@ -5,8 +5,9 @@ Copyright (c) 2014-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "GDCpp/Extensions/ExtensionBase.h"
|
||||
#include "PlatformBehavior.h"
|
||||
|
||||
#include "GDCpp/Extensions/ExtensionBase.h"
|
||||
#include "PlatformRuntimeBehavior.h"
|
||||
#include "PlatformerObjectBehavior.h"
|
||||
#include "PlatformerObjectRuntimeBehavior.h"
|
||||
@@ -381,6 +382,19 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
.SetFunctionName("SetCanJump")
|
||||
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
|
||||
|
||||
aut.AddScopedAction(
|
||||
"SetCanNotAirJump",
|
||||
_("Forbid jumping again in the air"),
|
||||
_("This revokes the effect of \"Allow jumping again\". The object "
|
||||
"is made unable to jump while in mid air. This has no effect if "
|
||||
"the object is not in the air."),
|
||||
_("Forbid _PARAM0_ to air jump"),
|
||||
_("Options"),
|
||||
"CppPlatform/Extensions/platformerobjecticon24.png",
|
||||
"CppPlatform/Extensions/platformerobjecticon16.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior");
|
||||
|
||||
aut.AddCondition("CanJump",
|
||||
_("Can jump"),
|
||||
_("Check if the object can jump."),
|
||||
@@ -461,6 +475,18 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
.SetFunctionName("SimulateLadderKey")
|
||||
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
|
||||
|
||||
aut.AddAction(
|
||||
"SimulateReleaseLadderKey",
|
||||
_("Simulate release ladder key press"),
|
||||
_("Simulate a press of the Release Ladder key (used to get off a ladder)."),
|
||||
_("Simulate pressing Release Ladder key for _PARAM0_"),
|
||||
_("Controls"),
|
||||
"res/conditions/keyboard24.png",
|
||||
"res/conditions/keyboard.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddAction("SimulateJumpKey",
|
||||
_("Simulate jump key press"),
|
||||
_("Simulate a press of the jump key."),
|
||||
@@ -473,30 +499,35 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
.SetFunctionName("SimulateJumpKey")
|
||||
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
|
||||
|
||||
aut.AddAction("SimulateReleaseKey",
|
||||
_("Simulate release key press"),
|
||||
_("Simulate a press of the release key (used when grabbing a "
|
||||
aut.AddAction("SimulateReleasePlatformKey",
|
||||
_("Simulate release platform key press"),
|
||||
_("Simulate a press of the release platform key (used when grabbing a "
|
||||
"platform ledge)."),
|
||||
_("Simulate pressing Release key for _PARAM0_"),
|
||||
_("Simulate pressing Release Platform key for _PARAM0_"),
|
||||
_("Controls"),
|
||||
"res/conditions/keyboard24.png",
|
||||
"res/conditions/keyboard.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
|
||||
.SetFunctionName("SimulateReleaseKey")
|
||||
.SetFunctionName("SimulateReleasePlatformKey")
|
||||
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
|
||||
|
||||
// Support for deprecated names:
|
||||
aut.AddDuplicatedAction("SimulateReleaseKey", "SimulateReleasePlatformKey").SetHidden();
|
||||
|
||||
aut.AddAction("SimulateControl",
|
||||
_("Simulate control"),
|
||||
_("Simulate a press of a key.\nValid keys are Left, Right, "
|
||||
"Jump, Ladder, Up, Down."),
|
||||
"Jump, Ladder, Release Ladder, Up, Down."),
|
||||
_("Simulate pressing _PARAM2_ key for _PARAM0_"),
|
||||
_("Controls"),
|
||||
"res/conditions/keyboard24.png",
|
||||
"res/conditions/keyboard.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
|
||||
.AddParameter("string", _("Key"))
|
||||
.AddParameter("stringWithSelector",
|
||||
_("Key"),
|
||||
"[\"Left\", \"Right\", \"Jump\", \"Ladder\", \"Release Ladder\", \"Up\", \"Down\"]")
|
||||
.MarkAsAdvanced()
|
||||
.SetFunctionName("SimulateControl")
|
||||
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
|
||||
|
@@ -119,6 +119,7 @@ class PlatformBehaviorJsExtension : public gd::PlatformExtension {
|
||||
"getCurrentJumpSpeed");
|
||||
autExpressions["CurrentJumpSpeed"].SetFunctionName("getCurrentJumpSpeed");
|
||||
autActions["PlatformBehavior::SetCanJump"].SetFunctionName("setCanJump");
|
||||
autActions["PlatformBehavior::PlatformerObjectBehavior::SetCanNotAirJump"].SetFunctionName("setCanNotAirJump");
|
||||
autConditions["PlatformBehavior::CanJump"].SetFunctionName(
|
||||
"canJump");
|
||||
autActions["PlatformBehavior::SimulateLeftKey"].SetFunctionName(
|
||||
@@ -131,10 +132,15 @@ class PlatformBehaviorJsExtension : public gd::PlatformExtension {
|
||||
"simulateDownKey");
|
||||
autActions["PlatformBehavior::SimulateLadderKey"].SetFunctionName(
|
||||
"simulateLadderKey");
|
||||
autActions["PlatformBehavior::SimulateReleaseLadderKey"].SetFunctionName(
|
||||
"simulateReleaseLadderKey");
|
||||
autActions["PlatformBehavior::SimulateJumpKey"].SetFunctionName(
|
||||
"simulateJumpKey");
|
||||
// deprecated release platform key.
|
||||
autActions["PlatformBehavior::SimulateReleaseKey"].SetFunctionName(
|
||||
"simulateReleaseKey");
|
||||
"simulateReleasePlatformKey");
|
||||
autActions["PlatformBehavior::SimulateReleasePlatformKey"].SetFunctionName(
|
||||
"simulateReleasePlatformKey");
|
||||
autActions["PlatformBehavior::SimulateControl"].SetFunctionName(
|
||||
"simulateControl");
|
||||
autActions["PlatformBehavior::IgnoreDefaultControls"].SetFunctionName(
|
||||
|
@@ -40,7 +40,8 @@ namespace gdjs {
|
||||
_upKey: boolean = false;
|
||||
_downKey: boolean = false;
|
||||
_jumpKey: boolean = false;
|
||||
_releaseKey: boolean = false;
|
||||
_releasePlatformKey: boolean = false;
|
||||
_releaseLadderKey: boolean = false;
|
||||
|
||||
private _state: State;
|
||||
_falling: Falling;
|
||||
@@ -181,8 +182,8 @@ namespace gdjs {
|
||||
(this._downKey =
|
||||
!this._ignoreDefaultControls && inputManager.isKeyPressed(DOWNKEY));
|
||||
|
||||
this._releaseKey ||
|
||||
(this._releaseKey =
|
||||
this._releasePlatformKey ||
|
||||
(this._releasePlatformKey =
|
||||
!this._ignoreDefaultControls && inputManager.isKeyPressed(DOWNKEY));
|
||||
|
||||
this._requestedDeltaX += this._updateSpeed(timeDelta);
|
||||
@@ -230,13 +231,16 @@ namespace gdjs {
|
||||
this._leftKey = false;
|
||||
this._rightKey = false;
|
||||
this._ladderKey = false;
|
||||
this._releaseLadderKey = false;
|
||||
this._upKey = false;
|
||||
this._downKey = false;
|
||||
this._releaseKey = false;
|
||||
this._releasePlatformKey = false;
|
||||
this._jumpKey = false;
|
||||
|
||||
//5) Track the movement
|
||||
this._hasReallyMoved = Math.abs(object.getX() - oldX) >= 1;
|
||||
this._hasReallyMoved =
|
||||
Math.abs(object.getX() - oldX) >= 1 ||
|
||||
Math.abs(object.getY() - oldY) >= 1;
|
||||
this._lastDeltaY = object.getY() - oldY;
|
||||
}
|
||||
|
||||
@@ -546,7 +550,7 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the platformer object has not being grabbing any platform.
|
||||
* Mark the platformer object as not grabbing any platform.
|
||||
*/
|
||||
_releaseGrabbedPlatform() {
|
||||
if (this._state === this._grabbingPlatform) {
|
||||
@@ -554,6 +558,15 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the platformer object as falling if on a ladder.
|
||||
*/
|
||||
_releaseLadder() {
|
||||
if (this._state === this._onLadder) {
|
||||
this._setFalling();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Separate the object from all platforms passed in parameter.
|
||||
* @param candidates The platform to be tested for collision
|
||||
@@ -784,7 +797,7 @@ namespace gdjs {
|
||||
|
||||
/**
|
||||
* Simulate a control action in the Platformer Object by specifying an input.
|
||||
* @param input The string expression of the control action [Left,Right,Up,Down,Ladder,Jump,Release].
|
||||
* @param input The string expression of the control action [Left,Right,Up,Down,Ladder,Jump,Release,Release Ladder].
|
||||
*/
|
||||
simulateControl(input: string) {
|
||||
if (input === 'Left') {
|
||||
@@ -800,7 +813,9 @@ namespace gdjs {
|
||||
} else if (input === 'Jump') {
|
||||
this._jumpKey = true;
|
||||
} else if (input === 'Release') {
|
||||
this._releaseKey = true;
|
||||
this._releasePlatformKey = true;
|
||||
} else if (input === 'Release Ladder') {
|
||||
this._releaseLadderKey = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,6 +1014,15 @@ namespace gdjs {
|
||||
this._canJump = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forbid the Platformer Object to air jump.
|
||||
*/
|
||||
setCanNotAirJump(): void {
|
||||
if (this._state === this._jumping || this._state === this._falling) {
|
||||
this._canJump = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the Platformer Object can grab platforms.
|
||||
* @param enable Enable / Disable grabbing of platforms.
|
||||
@@ -1039,6 +1063,13 @@ namespace gdjs {
|
||||
this._ladderKey = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate the "Release Ladder" control of the Platformer Object.
|
||||
*/
|
||||
simulateReleaseLadderKey() {
|
||||
this._releaseLadderKey = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate the "Up" control of the Platformer Object.
|
||||
*/
|
||||
@@ -1063,8 +1094,8 @@ namespace gdjs {
|
||||
/**
|
||||
* Simulate the "Release" control of the Platformer Object.
|
||||
*/
|
||||
simulateReleaseKey() {
|
||||
this._releaseKey = true;
|
||||
simulateReleasePlatformKey() {
|
||||
this._releasePlatformKey = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1135,7 +1166,8 @@ namespace gdjs {
|
||||
*/
|
||||
isMoving(): boolean {
|
||||
return (
|
||||
(this._hasReallyMoved && this._currentSpeed !== 0) ||
|
||||
(this._hasReallyMoved &&
|
||||
(this._currentSpeed !== 0 || this._state === this._onLadder)) ||
|
||||
this._jumping.getCurrentJumpSpeed() !== 0 ||
|
||||
this._currentFallSpeed !== 0
|
||||
);
|
||||
@@ -1560,7 +1592,8 @@ namespace gdjs {
|
||||
//Go on a ladder
|
||||
behavior._checkTransitionOnLadder();
|
||||
|
||||
if (behavior._releaseKey) {
|
||||
//Release the platform
|
||||
if (behavior._releasePlatformKey) {
|
||||
behavior._releaseGrabbedPlatform();
|
||||
}
|
||||
|
||||
@@ -1569,7 +1602,6 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
beforeMovingY(timeDelta: float, oldX: float) {
|
||||
const behavior = this._behavior;
|
||||
this._grabbedPlatformLastX = this._grabbedPlatform.owner.getX();
|
||||
this._grabbedPlatformLastY = this._grabbedPlatform.owner.getY();
|
||||
}
|
||||
@@ -1611,11 +1643,17 @@ namespace gdjs {
|
||||
|
||||
//Jumping
|
||||
behavior._checkTransitionJumping();
|
||||
|
||||
//Release the ladder
|
||||
if (behavior._releaseLadderKey) {
|
||||
behavior._releaseLadder();
|
||||
}
|
||||
}
|
||||
|
||||
beforeMovingY(timeDelta: float, oldX: float) {
|
||||
const behavior = this._behavior;
|
||||
|
||||
// TODO: we could consider supporting acceleration for ladder climbing in the future.
|
||||
if (behavior._upKey) {
|
||||
behavior._requestedDeltaY -= behavior._ladderClimbingSpeed * timeDelta;
|
||||
}
|
||||
|
@@ -332,7 +332,7 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
);
|
||||
expect(object.getY()).to.be(platform.getY());
|
||||
|
||||
object.getBehavior('auto1').simulateReleaseKey();
|
||||
object.getBehavior('auto1').simulateReleasePlatformKey();
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(true);
|
||||
@@ -389,7 +389,7 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
expect(object.getBehavior('auto1').isGrabbingPlatform()).to.be(true);
|
||||
|
||||
// Release upper platform
|
||||
object.getBehavior('auto1').simulateReleaseKey();
|
||||
object.getBehavior('auto1').simulateReleasePlatformKey();
|
||||
for (let i = 0; i < 35; ++i) {
|
||||
object.getBehavior('auto1').simulateLeftKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
@@ -550,6 +550,11 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
);
|
||||
expect(object.getBehavior('auto1').isMoving()).to.be(false);
|
||||
|
||||
// Forbid to jump
|
||||
object.getBehavior('auto1').setCanNotAirJump();
|
||||
// It has no impact as the object is on a platform.
|
||||
expect(object.getBehavior('auto1').canJump()).to.be(true);
|
||||
|
||||
// Jump with sustaining as much as possible, and
|
||||
// even more (18 frames at 60fps is greater than 0.2s)
|
||||
for (let i = 0; i < 18; ++i) {
|
||||
@@ -649,7 +654,7 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
);
|
||||
expect(object.getBehavior('auto1').isMoving()).to.be(false);
|
||||
|
||||
// Fell from the platform
|
||||
// Fall from the platform
|
||||
for (let i = 0; i < 35; ++i) {
|
||||
object.getBehavior('auto1').simulateLeftKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
@@ -663,6 +668,96 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(true);
|
||||
});
|
||||
|
||||
it('can be allowed to jump in mid air', function () {
|
||||
// Ensure the object falls on the platform
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
}
|
||||
|
||||
// Check the object is on the platform
|
||||
expect(object.getY()).to.be(-30); // -30 = -10 (platform y) + -20 (object height)
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(false);
|
||||
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(
|
||||
false
|
||||
);
|
||||
expect(object.getBehavior('auto1').isMoving()).to.be(false);
|
||||
|
||||
// Fall from the platform
|
||||
for (let i = 0; i < 20; ++i) {
|
||||
object.getBehavior('auto1').simulateLeftKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
}
|
||||
// Allow to jump in mid air
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(true);
|
||||
object.getBehavior('auto1').setCanJump();
|
||||
expect(object.getBehavior('auto1').canJump()).to.be(true);
|
||||
|
||||
// Can jump in the air
|
||||
object.getBehavior('auto1').simulateJumpKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getBehavior('auto1').isJumping()).to.be(true);
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(false);
|
||||
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(
|
||||
false
|
||||
);
|
||||
|
||||
for (let i = 0; i < 40; ++i) {
|
||||
object.getBehavior('auto1').simulateLeftKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
}
|
||||
expect(object.getBehavior('auto1').isJumping()).to.be(false);
|
||||
|
||||
// Can no longer to jump
|
||||
object.getBehavior('auto1').simulateJumpKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getBehavior('auto1').isJumping()).to.be(false);
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(true);
|
||||
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(true);
|
||||
});
|
||||
|
||||
it('can allow coyote time', function () {
|
||||
// Ensure the object falls on the platform
|
||||
for (let i = 0; i < 10; ++i) {
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
}
|
||||
|
||||
// Check the object is on the platform
|
||||
expect(object.getY()).to.be(-30); // -30 = -10 (platform y) + -20 (object height)
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(false);
|
||||
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(
|
||||
false
|
||||
);
|
||||
expect(object.getBehavior('auto1').isMoving()).to.be(false);
|
||||
|
||||
// Fall from the platform
|
||||
for (let i = 0; i < 20; ++i) {
|
||||
object.getBehavior('auto1').simulateLeftKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
}
|
||||
// Allow to jump
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(true);
|
||||
object.getBehavior('auto1').setCanJump();
|
||||
expect(object.getBehavior('auto1').canJump()).to.be(true);
|
||||
|
||||
// Still falling from the platform
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
object.getBehavior('auto1').simulateLeftKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
}
|
||||
|
||||
// Suppose that we miss an eventual time frame or some condition.
|
||||
// So we forbid to jump again:
|
||||
object.getBehavior('auto1').setCanNotAirJump();
|
||||
expect(object.getBehavior('auto1').canJump()).to.be(false);
|
||||
|
||||
// Can no longer to jump in mid air
|
||||
object.getBehavior('auto1').simulateJumpKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getBehavior('auto1').isJumping()).to.be(false);
|
||||
expect(object.getBehavior('auto1').isFalling()).to.be(true);
|
||||
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(true);
|
||||
});
|
||||
|
||||
it('should not grab a platform while in the ascending phase of a jump', function () {
|
||||
const topPlatform = addPlatformObject(runtimeScene);
|
||||
topPlatform.setPosition(12, -80);
|
||||
@@ -1532,12 +1627,22 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
object.getBehavior('auto1').simulateUpKey();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getBehavior('auto1').isOnLadder()).to.be(true);
|
||||
//TODO Probably a bug, uncomment it after it's fixed
|
||||
//expect(object.getBehavior('auto1').isMoving()).to.be(true);
|
||||
expect(object.getBehavior('auto1').isMoving()).to.be(true);
|
||||
expect(object.getY()).to.be.below(lastY);
|
||||
}
|
||||
};
|
||||
|
||||
const releaseLadder = (frameCount) => {
|
||||
object.getBehavior('auto1').simulateReleaseLadderKey();
|
||||
for (let i = 0; i < frameCount; ++i) {
|
||||
const lastY = object.getY();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getBehavior('auto1').isOnLadder()).to.be(false);
|
||||
expect(object.getBehavior('auto1').isMoving()).to.be(true);
|
||||
expect(object.getY()).to.be.above(lastY);
|
||||
}
|
||||
};
|
||||
|
||||
const stayOnLadder = (frameCount) => {
|
||||
for (let i = 0; i < frameCount; ++i) {
|
||||
const lastY = object.getY();
|
||||
@@ -1586,7 +1691,7 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
expect(object.getBehavior('auto1').isMoving()).to.be(false);
|
||||
};
|
||||
|
||||
it('can climb a ladder', function () {
|
||||
it('can climb and release a ladder', function () {
|
||||
object.setPosition(30, -32);
|
||||
// Ensure the object falls on the platform
|
||||
fallOnPlatform(10);
|
||||
@@ -1595,7 +1700,15 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
||||
object.getBehavior('auto1').simulateLadderKey();
|
||||
climbLadder(10);
|
||||
stayOnLadder(10);
|
||||
climbLadder(14);
|
||||
const objectPositionAfterFirstClimb = object.getY();
|
||||
releaseLadder(10);
|
||||
object.getBehavior('auto1').simulateLadderKey();
|
||||
expect(object.getY()).to.be.within(
|
||||
// gravity is 1500, 10 frames falling ~ 23px
|
||||
objectPositionAfterFirstClimb + 22,
|
||||
objectPositionAfterFirstClimb + 24
|
||||
);
|
||||
climbLadder(24);
|
||||
// Check that we reached the maximum height
|
||||
const playerAtLadderTop = ladder.getY() - object.getHeight();
|
||||
expect(object.getY()).to.be.within(
|
||||
|
@@ -375,6 +375,16 @@ void DeclarePrimitiveDrawingExtension(gd::PlatformExtension& extension) {
|
||||
.SetFunctionName("closePath")
|
||||
.SetIncludeFile("PrimitiveDrawing/ShapePainterObject.h");
|
||||
|
||||
obj.AddScopedAction(
|
||||
"ClearShapes",
|
||||
_("Clear shapes"),
|
||||
_("Clear the rendered shape(s). Useful if not set to be done automatically."),
|
||||
_("Clear the rendered image of _PARAM0_"),
|
||||
_("Advanced"),
|
||||
"res/actions/visibilite24.png",
|
||||
"res/actions/visibilite.png")
|
||||
.AddParameter("object", _("Shape Painter object"), "Drawer");
|
||||
|
||||
obj.AddAction(
|
||||
"ClearBetweenFrames",
|
||||
_("Clear between frames"),
|
||||
|
@@ -106,6 +106,9 @@ class PrimitiveDrawingJsExtension : public gd::PlatformExtension {
|
||||
GetAllActionsForObject(
|
||||
"PrimitiveDrawing::Drawer")["PrimitiveDrawing::ArcTo"]
|
||||
.SetFunctionName("drawArcTo");*/
|
||||
GetAllActionsForObject(
|
||||
"PrimitiveDrawing::Drawer")["PrimitiveDrawing::Drawer::ClearShapes"]
|
||||
.SetFunctionName("clear");
|
||||
GetAllActionsForObject(
|
||||
"PrimitiveDrawing::Drawer")["PrimitiveDrawing::ClearBetweenFrames"]
|
||||
.SetFunctionName("setClearBetweenFrames");
|
||||
|
@@ -2,14 +2,15 @@ namespace gdjs {
|
||||
import PIXI = GlobalPIXIModule.PIXI;
|
||||
|
||||
class ShapePainterRuntimeObjectPixiRenderer {
|
||||
_object: any;
|
||||
_graphics: any;
|
||||
_object: gdjs.ShapePainterRuntimeObject;
|
||||
_graphics: PIXI.Graphics;
|
||||
|
||||
constructor(runtimeObject, runtimeScene) {
|
||||
constructor(
|
||||
runtimeObject: gdjs.ShapePainterRuntimeObject,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
this._object = runtimeObject;
|
||||
if (this._graphics === undefined) {
|
||||
this._graphics = new PIXI.Graphics();
|
||||
}
|
||||
this._graphics = new PIXI.Graphics();
|
||||
runtimeScene
|
||||
.getLayer('')
|
||||
.getRenderer()
|
||||
@@ -24,7 +25,7 @@ namespace gdjs {
|
||||
this._graphics.clear();
|
||||
}
|
||||
|
||||
drawRectangle(x1, y1, x2, y2) {
|
||||
drawRectangle(x1: float, y1: float, x2: float, y2: float) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
@@ -34,7 +35,7 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawCircle(x, y, radius) {
|
||||
drawCircle(x: float, y: float, radius: float) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
@@ -44,7 +45,7 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawLine(x1, y1, x2, y2, thickness) {
|
||||
drawLine(x1: float, y1: float, x2: float, y2: float, thickness: float) {
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
this._object._fillOpacity / 255
|
||||
@@ -69,7 +70,7 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawLineV2(x1, y1, x2, y2, thickness) {
|
||||
drawLineV2(x1: float, y1: float, x2: float, y2: float, thickness: float) {
|
||||
this._graphics.lineStyle(
|
||||
thickness,
|
||||
this._object._outlineColor,
|
||||
@@ -80,7 +81,7 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawEllipse(x1, y1, width, height) {
|
||||
drawEllipse(x1: float, y1: float, width: float, height: float) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
@@ -90,7 +91,13 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawRoundedRectangle(x1, y1, x2, y2, radius) {
|
||||
drawRoundedRectangle(
|
||||
x1: float,
|
||||
y1: float,
|
||||
x2: float,
|
||||
y2: float,
|
||||
radius: float
|
||||
) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
@@ -101,12 +108,20 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawStar(x1, y1, points, radius, innerRadius, rotation) {
|
||||
drawStar(
|
||||
x1: float,
|
||||
y1: float,
|
||||
points: float,
|
||||
radius: float,
|
||||
innerRadius: float,
|
||||
rotation: float
|
||||
) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
this._object._fillOpacity / 255
|
||||
);
|
||||
//@ts-ignore from @pixi/graphics-extras
|
||||
this._graphics.drawStar(
|
||||
x1,
|
||||
y1,
|
||||
@@ -119,7 +134,15 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawArc(x1, y1, radius, startAngle, endAngle, anticlockwise, closePath) {
|
||||
drawArc(
|
||||
x1: float,
|
||||
y1: float,
|
||||
radius: float,
|
||||
startAngle: float,
|
||||
endAngle: float,
|
||||
anticlockwise: boolean,
|
||||
closePath: boolean
|
||||
) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
@@ -143,7 +166,16 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawBezierCurve(x1, y1, cpX, cpY, cpX2, cpY2, x2, y2) {
|
||||
drawBezierCurve(
|
||||
x1: float,
|
||||
y1: float,
|
||||
cpX: float,
|
||||
cpY: float,
|
||||
cpX2: float,
|
||||
cpY2: float,
|
||||
x2: float,
|
||||
y2: float
|
||||
) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
@@ -154,7 +186,14 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawQuadraticCurve(x1, y1, cpX, cpY, x2, y2) {
|
||||
drawQuadraticCurve(
|
||||
x1: float,
|
||||
y1: float,
|
||||
cpX: float,
|
||||
cpY: float,
|
||||
x2: float,
|
||||
y2: float
|
||||
) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(
|
||||
this._object._fillColor,
|
||||
@@ -176,19 +215,33 @@ namespace gdjs {
|
||||
this._graphics.endFill();
|
||||
}
|
||||
|
||||
drawPathMoveTo(x1, y1) {
|
||||
drawPathMoveTo(x1: float, y1: float) {
|
||||
this._graphics.moveTo(x1, y1);
|
||||
}
|
||||
|
||||
drawPathLineTo(x1, y1) {
|
||||
drawPathLineTo(x1: float, y1: float) {
|
||||
this._graphics.lineTo(x1, y1);
|
||||
}
|
||||
|
||||
drawPathBezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY) {
|
||||
drawPathBezierCurveTo(
|
||||
cpX: float,
|
||||
cpY: float,
|
||||
cpX2: float,
|
||||
cpY2: float,
|
||||
toX: float,
|
||||
toY: float
|
||||
) {
|
||||
this._graphics.bezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY);
|
||||
}
|
||||
|
||||
drawPathArc(x1, y1, radius, startAngle, endAngle, anticlockwise) {
|
||||
drawPathArc(
|
||||
x1: float,
|
||||
y1: float,
|
||||
radius: float,
|
||||
startAngle: float,
|
||||
endAngle: float,
|
||||
anticlockwise: boolean
|
||||
) {
|
||||
this._graphics.arc(
|
||||
x1,
|
||||
y1,
|
||||
@@ -199,7 +252,7 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
|
||||
drawPathQuadraticCurveTo(cpX, cpY, toX, toY) {
|
||||
drawPathQuadraticCurveTo(cpX: float, cpY: float, toX: float, toY: float) {
|
||||
this._graphics.quadraticCurveTo(cpX, cpY, toX, toY);
|
||||
}
|
||||
|
||||
|
@@ -6,11 +6,11 @@ namespace gdjs {
|
||||
/** Represents a color in RGB Format */
|
||||
export type RGBColor = {
|
||||
/** The Red component of the color, from 0 to 255. */
|
||||
r: number;
|
||||
r: integer;
|
||||
/** The Green component of the color, from 0 to 255. */
|
||||
g: number;
|
||||
g: integer;
|
||||
/** The Blue component of the color, from 0 to 255. */
|
||||
b: number;
|
||||
b: integer;
|
||||
};
|
||||
|
||||
/** Initial properties for a for {@link gdjs.ShapePainterRuntimeObject}. */
|
||||
@@ -19,12 +19,12 @@ namespace gdjs {
|
||||
fillColor: RGBColor;
|
||||
/** The color (in RGB format) of the outline of the painted shape */
|
||||
outlineColor: RGBColor;
|
||||
/** The opacity of the inner part of the painted shape */
|
||||
fillOpacity: number;
|
||||
/** The opacity of the outline of the painted shape */
|
||||
outlineOpacity: number;
|
||||
/** The opacity of the inner part of the painted shape, from 0 to 255 */
|
||||
fillOpacity: float;
|
||||
/** The opacity of the outline of the painted shape, from 0 to 255 */
|
||||
outlineOpacity: float;
|
||||
/** The size of the outline of the painted shape, in pixels. */
|
||||
outlineSize: number;
|
||||
outlineSize: float;
|
||||
/** Use absolute coordinates? */
|
||||
absoluteCoordinates: boolean;
|
||||
/** Clear the previous render before the next draw? */
|
||||
@@ -41,7 +41,7 @@ namespace gdjs {
|
||||
_outlineColor: integer;
|
||||
_fillOpacity: float;
|
||||
_outlineOpacity: float;
|
||||
_outlineSize: number;
|
||||
_outlineSize: float;
|
||||
_absoluteCoordinates: boolean;
|
||||
_clearBetweenFrames: boolean;
|
||||
_renderer: gdjs.ShapePainterRuntimeObjectRenderer;
|
||||
@@ -145,39 +145,52 @@ namespace gdjs {
|
||||
return true;
|
||||
}
|
||||
|
||||
stepBehaviorsPreEvents(runtimeScene) {
|
||||
stepBehaviorsPreEvents(runtimeScene: gdjs.RuntimeScene) {
|
||||
//We redefine stepBehaviorsPreEvents just to clear the graphics before running events.
|
||||
if (this._clearBetweenFrames) {
|
||||
this._renderer.clear();
|
||||
this.clear();
|
||||
}
|
||||
super.stepBehaviorsPreEvents(runtimeScene);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the graphics.
|
||||
*/
|
||||
clear() {
|
||||
this._renderer.clear();
|
||||
}
|
||||
|
||||
getVisibilityAABB() {
|
||||
return this._absoluteCoordinates ? null : this.getAABB();
|
||||
}
|
||||
|
||||
drawRectangle(x1, y1, x2, y2) {
|
||||
drawRectangle(x1: float, y1: float, x2: float, y2: float) {
|
||||
this._renderer.drawRectangle(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
drawCircle(x, y, radius) {
|
||||
drawCircle(x: float, y: float, radius: float) {
|
||||
this._renderer.drawCircle(x, y, radius);
|
||||
}
|
||||
|
||||
drawLine(x1, y1, x2, y2, thickness) {
|
||||
drawLine(x1: float, y1: float, x2: float, y2: float, thickness: float) {
|
||||
this._renderer.drawLine(x1, y1, x2, y2, thickness);
|
||||
}
|
||||
|
||||
drawLineV2(x1, y1, x2, y2, thickness) {
|
||||
drawLineV2(x1: float, y1: float, x2: float, y2: float, thickness: float) {
|
||||
this._renderer.drawLineV2(x1, y1, x2, y2, thickness);
|
||||
}
|
||||
|
||||
drawEllipse(centerX, centerY, width, height) {
|
||||
drawEllipse(centerX: float, centerY: float, width: float, height: float) {
|
||||
this._renderer.drawEllipse(centerX, centerY, width, height);
|
||||
}
|
||||
|
||||
drawRoundedRectangle(startX1, startY1, endX2, endY2, radius) {
|
||||
drawRoundedRectangle(
|
||||
startX1: float,
|
||||
startY1: float,
|
||||
endX2: float,
|
||||
endY2: float,
|
||||
radius: float
|
||||
) {
|
||||
this._renderer.drawRoundedRectangle(
|
||||
startX1,
|
||||
startY1,
|
||||
@@ -187,7 +200,14 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
|
||||
drawStar(centerX, centerY, points, radius, innerRadius, rotation) {
|
||||
drawStar(
|
||||
centerX: float,
|
||||
centerY: float,
|
||||
points: float,
|
||||
radius: float,
|
||||
innerRadius: float,
|
||||
rotation: float
|
||||
) {
|
||||
this._renderer.drawStar(
|
||||
centerX,
|
||||
centerY,
|
||||
@@ -199,13 +219,13 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
drawArc(
|
||||
centerX,
|
||||
centerY,
|
||||
radius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
anticlockwise,
|
||||
closePath
|
||||
centerX: float,
|
||||
centerY: float,
|
||||
radius: float,
|
||||
startAngle: float,
|
||||
endAngle: float,
|
||||
anticlockwise: boolean,
|
||||
closePath: boolean
|
||||
) {
|
||||
this._renderer.drawArc(
|
||||
centerX,
|
||||
@@ -218,15 +238,31 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
|
||||
drawBezierCurve(x1, y1, cpX, cpY, cpX2, cpY2, x2, y2) {
|
||||
drawBezierCurve(
|
||||
x1: float,
|
||||
y1: float,
|
||||
cpX: float,
|
||||
cpY: float,
|
||||
cpX2: float,
|
||||
cpY2: float,
|
||||
x2: float,
|
||||
y2: float
|
||||
) {
|
||||
this._renderer.drawBezierCurve(x1, y1, cpX, cpY, cpX2, cpY2, x2, y2);
|
||||
}
|
||||
|
||||
drawQuadraticCurve(x1, y1, cpX, cpY, x2, y2) {
|
||||
drawQuadraticCurve(
|
||||
x1: float,
|
||||
y1: float,
|
||||
cpX: float,
|
||||
cpY: float,
|
||||
x2: float,
|
||||
y2: float
|
||||
) {
|
||||
this._renderer.drawQuadraticCurve(x1, y1, cpX, cpY, x2, y2);
|
||||
}
|
||||
|
||||
beginFillPath(x1, y1) {
|
||||
beginFillPath(x1: float, y1: float) {
|
||||
this._renderer.beginFillPath();
|
||||
this._renderer.drawPathMoveTo(x1, y1);
|
||||
}
|
||||
@@ -235,19 +271,33 @@ namespace gdjs {
|
||||
this._renderer.endFillPath();
|
||||
}
|
||||
|
||||
drawPathMoveTo(x1, y1) {
|
||||
drawPathMoveTo(x1: float, y1: float) {
|
||||
this._renderer.drawPathMoveTo(x1, y1);
|
||||
}
|
||||
|
||||
drawPathLineTo(x1, y1) {
|
||||
drawPathLineTo(x1: float, y1: float) {
|
||||
this._renderer.drawPathLineTo(x1, y1);
|
||||
}
|
||||
|
||||
drawPathBezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY) {
|
||||
drawPathBezierCurveTo(
|
||||
cpX: float,
|
||||
cpY: float,
|
||||
cpX2: float,
|
||||
cpY2: float,
|
||||
toX: float,
|
||||
toY: float
|
||||
) {
|
||||
this._renderer.drawPathBezierCurveTo(cpX, cpY, cpX2, cpY2, toX, toY);
|
||||
}
|
||||
|
||||
drawPathArc(cx, cy, radius, startAngle, endAngle, anticlockwise) {
|
||||
drawPathArc(
|
||||
cx: float,
|
||||
cy: float,
|
||||
radius: float,
|
||||
startAngle: float,
|
||||
endAngle: float,
|
||||
anticlockwise: boolean
|
||||
) {
|
||||
this._renderer.drawPathArc(
|
||||
cx,
|
||||
cy,
|
||||
@@ -258,7 +308,7 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
|
||||
drawPathQuadraticCurveTo(cpX, cpY, toX, toY) {
|
||||
drawPathQuadraticCurveTo(cpX: float, cpY: float, toX: float, toY: float) {
|
||||
this._renderer.drawPathQuadraticCurveTo(cpX, cpY, toX, toY);
|
||||
}
|
||||
|
||||
@@ -266,7 +316,7 @@ namespace gdjs {
|
||||
this._renderer.closePath();
|
||||
}
|
||||
|
||||
setClearBetweenFrames(value): void {
|
||||
setClearBetweenFrames(value: boolean): void {
|
||||
this._clearBetweenFrames = value;
|
||||
}
|
||||
|
||||
@@ -274,7 +324,7 @@ namespace gdjs {
|
||||
return this._clearBetweenFrames;
|
||||
}
|
||||
|
||||
setCoordinatesRelative(value): void {
|
||||
setCoordinatesRelative(value: boolean): void {
|
||||
this._absoluteCoordinates = !value;
|
||||
}
|
||||
|
||||
@@ -282,7 +332,11 @@ namespace gdjs {
|
||||
return !this._absoluteCoordinates;
|
||||
}
|
||||
|
||||
setFillColor(rgbColor): void {
|
||||
/**
|
||||
*
|
||||
* @param rgbColor semicolon separated decimal values
|
||||
*/
|
||||
setFillColor(rgbColor: string): void {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
@@ -307,7 +361,11 @@ namespace gdjs {
|
||||
return gdjs.hexNumberToRGB(this._fillColor).b;
|
||||
}
|
||||
|
||||
setOutlineColor(rgbColor): void {
|
||||
/**
|
||||
*
|
||||
* @param rgbColor semicolon separated decimal values
|
||||
*/
|
||||
setOutlineColor(rgbColor: string): void {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
@@ -333,7 +391,7 @@ namespace gdjs {
|
||||
return gdjs.hexNumberToRGB(this._outlineColor).b;
|
||||
}
|
||||
|
||||
setOutlineSize(size): void {
|
||||
setOutlineSize(size: float): void {
|
||||
this._outlineSize = size;
|
||||
this._renderer.updateOutline();
|
||||
}
|
||||
@@ -342,24 +400,40 @@ namespace gdjs {
|
||||
return this._outlineSize;
|
||||
}
|
||||
|
||||
setFillOpacity(opacity): void {
|
||||
/**
|
||||
*
|
||||
* @param opacity from 0 to 255
|
||||
*/
|
||||
setFillOpacity(opacity: float): void {
|
||||
this._fillOpacity = opacity;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns an opacity value from 0 to 255.
|
||||
*/
|
||||
getFillOpacity() {
|
||||
return this._fillOpacity;
|
||||
}
|
||||
|
||||
setOutlineOpacity(opacity): void {
|
||||
/**
|
||||
*
|
||||
* @param opacity from 0 to 255
|
||||
*/
|
||||
setOutlineOpacity(opacity: float): void {
|
||||
this._outlineOpacity = opacity;
|
||||
this._renderer.updateOutline();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns an opacity value from 0 to 255.
|
||||
*/
|
||||
getOutlineOpacity() {
|
||||
return this._outlineOpacity;
|
||||
}
|
||||
|
||||
setX(x): void {
|
||||
setX(x: float): void {
|
||||
if (x === this.x) {
|
||||
return;
|
||||
}
|
||||
@@ -367,7 +441,7 @@ namespace gdjs {
|
||||
this._renderer.updateXPosition();
|
||||
}
|
||||
|
||||
setY(y): void {
|
||||
setY(y: float): void {
|
||||
if (y === this.y) {
|
||||
return;
|
||||
}
|
||||
|
@@ -39,6 +39,7 @@ namespace gdjs {
|
||||
const shopifyClient = ShopifyBuy.buildClient(config);
|
||||
ShopifyClientsManager.set(runtimeScene, name, shopifyClient);
|
||||
};
|
||||
|
||||
export const getCheckoutUrlForProduct = function (
|
||||
runtimeScene,
|
||||
name,
|
||||
|
@@ -80,7 +80,12 @@ bool Exporter::ExportWholePixiProject(
|
||||
// end of compatibility code
|
||||
|
||||
// Export engine libraries
|
||||
helper.AddLibsInclude(true, false, false, includesFiles);
|
||||
helper.AddLibsInclude(
|
||||
/*pixiRenderers=*/true,
|
||||
/*cocosRenderers=*/false,
|
||||
/*websocketDebuggerClient=*/false,
|
||||
exportedProject.GetLoadingScreen().GetGDevelopLogoStyle(),
|
||||
includesFiles);
|
||||
|
||||
// Export files for object and behaviors
|
||||
helper.ExportObjectAndBehaviorsIncludes(exportedProject, includesFiles);
|
||||
@@ -191,7 +196,12 @@ bool Exporter::ExportWholeCocos2dProject(gd::Project &project,
|
||||
// end of compatibility code
|
||||
|
||||
// Export engine libraries
|
||||
helper.AddLibsInclude(false, true, false, includesFiles);
|
||||
helper.AddLibsInclude(
|
||||
/*pixiRenderers=*/false,
|
||||
/*cocosRenderers=*/true,
|
||||
/*websocketDebuggerClient=*/false,
|
||||
exportedProject.GetLoadingScreen().GetGDevelopLogoStyle(),
|
||||
includesFiles);
|
||||
|
||||
// Export files for object and behaviors
|
||||
helper.ExportObjectAndBehaviorsIncludes(exportedProject, includesFiles);
|
||||
|
@@ -79,8 +79,12 @@ bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
|
||||
gd::Project exportedProject = options.project;
|
||||
|
||||
// Always disable the splash for preview
|
||||
exportedProject.GetLoadingScreen().ShowGDevelopSplash(false);
|
||||
if (!options.fullLoadingScreen) {
|
||||
// Most of the time, we skip the logo and minimum duration so that
|
||||
// the preview start as soon as possible.
|
||||
exportedProject.GetLoadingScreen().ShowGDevelopSplash(false);
|
||||
exportedProject.GetLoadingScreen().SetMinDuration(0);
|
||||
}
|
||||
|
||||
// Export resources (*before* generating events as some resources filenames
|
||||
// may be updated)
|
||||
@@ -96,7 +100,11 @@ bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
// end of compatibility code
|
||||
|
||||
// Export engine libraries
|
||||
AddLibsInclude(true, false, true, includesFiles);
|
||||
AddLibsInclude(/*pixiRenderers=*/true,
|
||||
/*cocosRenderers=*/false,
|
||||
/*websocketDebuggerClient=*/true,
|
||||
exportedProject.GetLoadingScreen().GetGDevelopLogoStyle(),
|
||||
includesFiles);
|
||||
|
||||
// Export files for object and behaviors
|
||||
ExportObjectAndBehaviorsIncludes(exportedProject, includesFiles);
|
||||
@@ -598,12 +606,12 @@ bool ExporterHelper::CompleteIndexFile(
|
||||
void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
bool cocosRenderers,
|
||||
bool websocketDebuggerClient,
|
||||
gd::String gdevelopLogoStyle,
|
||||
std::vector<gd::String> &includesFiles) {
|
||||
// First, do not forget common includes (they must be included before events
|
||||
// generated code files).
|
||||
InsertUnique(includesFiles, "libs/jshashtable.js");
|
||||
InsertUnique(includesFiles, "gd.js");
|
||||
InsertUnique(includesFiles, "gd-splash-image.js");
|
||||
InsertUnique(includesFiles, "libs/rbush.js");
|
||||
InsertUnique(includesFiles, "inputmanager.js");
|
||||
InsertUnique(includesFiles, "jsonmanager.js");
|
||||
@@ -635,6 +643,16 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
InsertUnique(includesFiles, "events-tools/windowtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/networktools.js");
|
||||
|
||||
if (gdevelopLogoStyle == "dark") {
|
||||
InsertUnique(includesFiles, "splash/gd-logo-dark.js");
|
||||
} else if (gdevelopLogoStyle == "dark-colored") {
|
||||
InsertUnique(includesFiles, "splash/gd-logo-dark-colored.js");
|
||||
} else if (gdevelopLogoStyle == "light-colored") {
|
||||
InsertUnique(includesFiles, "splash/gd-logo-light-colored.js");
|
||||
} else {
|
||||
InsertUnique(includesFiles, "splash/gd-logo-light.js");
|
||||
}
|
||||
|
||||
if (websocketDebuggerClient) {
|
||||
InsertUnique(includesFiles, "websocket-debugger-client/hot-reloader.js");
|
||||
InsertUnique(includesFiles,
|
||||
|
@@ -35,6 +35,7 @@ struct PreviewExportOptions {
|
||||
: project(project_),
|
||||
exportPath(exportPath_),
|
||||
projectDataOnlyExport(false),
|
||||
fullLoadingScreen(false),
|
||||
nonRuntimeScriptsCacheBurst(0){};
|
||||
|
||||
/**
|
||||
@@ -85,6 +86,15 @@ struct PreviewExportOptions {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the export should show the full loading screen (false
|
||||
* by default, skipping the minimum duration and GDevelop logo).
|
||||
*/
|
||||
PreviewExportOptions &SetFullLoadingScreen(bool enable) {
|
||||
fullLoadingScreen = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief If set to a non zero value, the exported script URLs will have an
|
||||
* extra search parameter added (with the given value) to ensure browser cache
|
||||
@@ -103,6 +113,7 @@ struct PreviewExportOptions {
|
||||
gd::String externalLayoutName;
|
||||
std::map<gd::String, int> includeFileHashes;
|
||||
bool projectDataOnlyExport;
|
||||
bool fullLoadingScreen;
|
||||
unsigned int nonRuntimeScriptsCacheBurst;
|
||||
};
|
||||
|
||||
@@ -158,6 +169,7 @@ class ExporterHelper {
|
||||
void AddLibsInclude(bool pixiRenderers,
|
||||
bool cocosRenderers,
|
||||
bool websocketDebuggerClient,
|
||||
gd::String gdevelopLogoStyle,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
|
||||
/**
|
||||
|
@@ -5,11 +5,13 @@
|
||||
*/
|
||||
namespace gdjs {
|
||||
export class LoadingScreenCocosRenderer {
|
||||
render(percent) {
|
||||
setPercent(percent) {
|
||||
console.log('Loading ' + percent + '%');
|
||||
}
|
||||
|
||||
unload() {}
|
||||
unload() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do
|
||||
|
@@ -17,6 +17,7 @@ namespace gdjs {
|
||||
}
|
||||
runtimeScene.getLayer(layer).setCameraX(x, cameraId);
|
||||
};
|
||||
|
||||
export const setCameraY = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
y: float,
|
||||
@@ -28,6 +29,7 @@ namespace gdjs {
|
||||
}
|
||||
runtimeScene.getLayer(layer).setCameraY(y, cameraId);
|
||||
};
|
||||
|
||||
export const getCameraX = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -38,6 +40,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraX();
|
||||
};
|
||||
|
||||
export const getCameraY = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -48,6 +51,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraY();
|
||||
};
|
||||
|
||||
export const getCameraWidth = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -58,6 +62,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraWidth();
|
||||
};
|
||||
|
||||
export const getCameraHeight = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -68,6 +73,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraHeight();
|
||||
};
|
||||
|
||||
export const showLayer = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string
|
||||
@@ -77,6 +83,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).show(true);
|
||||
};
|
||||
|
||||
export const hideLayer = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string
|
||||
@@ -86,6 +93,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).show(false);
|
||||
};
|
||||
|
||||
export const layerIsVisible = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string
|
||||
@@ -95,6 +103,7 @@ namespace gdjs {
|
||||
runtimeScene.getLayer(layer).isVisible()
|
||||
);
|
||||
};
|
||||
|
||||
export const setCameraRotation = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
rotation: float,
|
||||
@@ -108,6 +117,7 @@ namespace gdjs {
|
||||
.getLayer(layer)
|
||||
.setCameraRotation(rotation, cameraId);
|
||||
};
|
||||
|
||||
export const getCameraRotation = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -118,6 +128,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraRotation(cameraId);
|
||||
};
|
||||
|
||||
export const getCameraZoom = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -128,6 +139,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getCameraZoom(cameraId);
|
||||
};
|
||||
|
||||
export const setCameraZoom = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
newZoom: float,
|
||||
@@ -139,6 +151,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).setCameraZoom(newZoom, cameraId);
|
||||
};
|
||||
|
||||
export const centerCamera = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
object: gdjs.RuntimeObject | null,
|
||||
@@ -162,6 +175,7 @@ namespace gdjs {
|
||||
layer.setCameraX(object.getDrawableX() + object.getCenterX(), cameraId);
|
||||
layer.setCameraY(object.getDrawableY() + object.getCenterY(), cameraId);
|
||||
};
|
||||
|
||||
export const centerCameraWithinLimits = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
object: gdjs.RuntimeObject | null,
|
||||
@@ -309,6 +323,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).isEffectEnabled(effect);
|
||||
};
|
||||
|
||||
export const setLayerTimeScale = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -319,6 +334,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).setTimeScale(timeScale);
|
||||
};
|
||||
|
||||
export const getLayerTimeScale = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string
|
||||
@@ -328,6 +344,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).getTimeScale();
|
||||
};
|
||||
|
||||
export const setLayerDefaultZOrder = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string,
|
||||
@@ -338,6 +355,7 @@ namespace gdjs {
|
||||
}
|
||||
return runtimeScene.getLayer(layer).setDefaultZOrder(defaultZOrder);
|
||||
};
|
||||
|
||||
export const getLayerDefaultZOrder = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
layer: string
|
||||
|
@@ -179,9 +179,11 @@ namespace gdjs {
|
||||
export const anyKeyPressed = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getInputManager().anyKeyPressed();
|
||||
};
|
||||
|
||||
export const anyKeyReleased = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getInputManager().anyKeyReleased();
|
||||
};
|
||||
|
||||
export const isMouseButtonPressed = function (runtimeScene, button) {
|
||||
if (button === 'Left') {
|
||||
return runtimeScene
|
||||
@@ -203,6 +205,7 @@ namespace gdjs {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const isMouseButtonReleased = function (runtimeScene, button) {
|
||||
if (button === 'Left') {
|
||||
return runtimeScene
|
||||
@@ -224,21 +227,27 @@ namespace gdjs {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const hideCursor = function (runtimeScene) {
|
||||
runtimeScene.getRenderer().hideCursor();
|
||||
};
|
||||
|
||||
export const showCursor = function (runtimeScene) {
|
||||
runtimeScene.getRenderer().showCursor();
|
||||
};
|
||||
|
||||
export const getMouseWheelDelta = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getInputManager().getMouseWheelDelta();
|
||||
};
|
||||
|
||||
export const isScrollingUp = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getInputManager().isScrollingUp();
|
||||
};
|
||||
|
||||
export const isScrollingDown = function (runtimeScene) {
|
||||
return runtimeScene.getGame().getInputManager().isScrollingDown();
|
||||
};
|
||||
|
||||
export const getMouseX = function (runtimeScene, layer, camera) {
|
||||
return runtimeScene
|
||||
.getLayer(layer)
|
||||
@@ -247,6 +256,7 @@ namespace gdjs {
|
||||
runtimeScene.getGame().getInputManager().getMouseY()
|
||||
)[0];
|
||||
};
|
||||
|
||||
export const getMouseY = function (runtimeScene, layer, camera) {
|
||||
return runtimeScene
|
||||
.getLayer(layer)
|
||||
@@ -255,9 +265,11 @@ namespace gdjs {
|
||||
runtimeScene.getGame().getInputManager().getMouseY()
|
||||
)[1];
|
||||
};
|
||||
|
||||
export const _cursorIsOnObject = function (obj, runtimeScene) {
|
||||
return obj.cursorOnObject(runtimeScene);
|
||||
};
|
||||
|
||||
export const cursorOnObject = function (
|
||||
objectsLists,
|
||||
runtimeScene,
|
||||
@@ -271,6 +283,7 @@ namespace gdjs {
|
||||
runtimeScene
|
||||
);
|
||||
};
|
||||
|
||||
export const getTouchX = function (
|
||||
runtimeScene,
|
||||
identifier,
|
||||
@@ -284,6 +297,7 @@ namespace gdjs {
|
||||
runtimeScene.getGame().getInputManager().getTouchY(identifier)
|
||||
)[0];
|
||||
};
|
||||
|
||||
export const getTouchY = function (
|
||||
runtimeScene,
|
||||
identifier,
|
||||
@@ -297,12 +311,15 @@ namespace gdjs {
|
||||
runtimeScene.getGame().getInputManager().getTouchY(identifier)
|
||||
)[1];
|
||||
};
|
||||
|
||||
export const getLastTouchId = function () {
|
||||
return gdjs.evtTools.input.lastTouchId || 0;
|
||||
};
|
||||
|
||||
export const getLastEndedTouchId = function () {
|
||||
return gdjs.evtTools.input.lastEndedTouchId || 0;
|
||||
};
|
||||
|
||||
export const popStartedTouch = function (runtimeScene) {
|
||||
const startedTouchId = runtimeScene
|
||||
.getGame()
|
||||
@@ -314,6 +331,7 @@ namespace gdjs {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const popEndedTouch = function (runtimeScene) {
|
||||
const endedTouchId = runtimeScene
|
||||
.getGame()
|
||||
@@ -325,6 +343,7 @@ namespace gdjs {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const touchSimulateMouse = function (runtimeScene, enable) {
|
||||
runtimeScene.getGame().getInputManager().touchSimulateMouse(enable);
|
||||
};
|
||||
|
@@ -217,6 +217,7 @@ namespace gdjs {
|
||||
}
|
||||
arr.length = finalSize;
|
||||
};
|
||||
|
||||
export const hitBoxesCollisionTest = function (
|
||||
objectsLists1,
|
||||
objectsLists2,
|
||||
@@ -232,9 +233,11 @@ namespace gdjs {
|
||||
ignoreTouchingEdges
|
||||
);
|
||||
};
|
||||
|
||||
export const _distanceBetweenObjects = function (obj1, obj2, distance) {
|
||||
return obj1.getSqDistanceToObject(obj2) <= distance;
|
||||
};
|
||||
|
||||
export const distanceTest = function (
|
||||
objectsLists1,
|
||||
objectsLists2,
|
||||
@@ -249,6 +252,7 @@ namespace gdjs {
|
||||
distance * distance
|
||||
);
|
||||
};
|
||||
|
||||
export const _movesToward = function (obj1, obj2, tolerance) {
|
||||
if (obj1.hasNoForces()) {
|
||||
return false;
|
||||
@@ -272,6 +276,7 @@ namespace gdjs {
|
||||
tolerance / 2
|
||||
);
|
||||
};
|
||||
|
||||
export const movesTowardTest = function (
|
||||
objectsLists1,
|
||||
objectsLists2,
|
||||
@@ -286,6 +291,7 @@ namespace gdjs {
|
||||
tolerance
|
||||
);
|
||||
};
|
||||
|
||||
export const _turnedToward = function (obj1, obj2, tolerance) {
|
||||
let objAngle = Math.atan2(
|
||||
obj2.getDrawableY() +
|
||||
@@ -303,6 +309,7 @@ namespace gdjs {
|
||||
tolerance / 2
|
||||
);
|
||||
};
|
||||
|
||||
export const turnedTowardTest = function (
|
||||
objectsLists1,
|
||||
objectsLists2,
|
||||
@@ -317,6 +324,7 @@ namespace gdjs {
|
||||
tolerance
|
||||
);
|
||||
};
|
||||
|
||||
export const pickAllObjects = function (objectsContext, objectsLists) {
|
||||
for (const name in objectsLists.items) {
|
||||
if (objectsLists.items.hasOwnProperty(name)) {
|
||||
@@ -328,6 +336,7 @@ namespace gdjs {
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
export const pickRandomObject = function (runtimeScene, objectsLists) {
|
||||
// Compute one many objects we have
|
||||
let objectsCount = 0;
|
||||
@@ -366,6 +375,7 @@ namespace gdjs {
|
||||
gdjs.evtTools.object.pickOnly(objectsLists, theChosenOne);
|
||||
return true;
|
||||
};
|
||||
|
||||
export const pickNearestObject = function (objectsLists, x, y, inverted) {
|
||||
let bestObject = null;
|
||||
let best = 0;
|
||||
@@ -391,6 +401,7 @@ namespace gdjs {
|
||||
gdjs.evtTools.object.pickOnly(objectsLists, bestObject);
|
||||
return true;
|
||||
};
|
||||
|
||||
export const raycastObject = function (
|
||||
objectsLists,
|
||||
x,
|
||||
@@ -412,6 +423,7 @@ namespace gdjs {
|
||||
inverted
|
||||
);
|
||||
};
|
||||
|
||||
export const raycastObjectToPosition = function (
|
||||
objectsLists,
|
||||
x,
|
||||
|
@@ -9,12 +9,15 @@ namespace gdjs {
|
||||
export const sceneJustBegins = function (runtimeScene) {
|
||||
return runtimeScene.getTimeManager().isFirstFrame();
|
||||
};
|
||||
|
||||
export const sceneJustResumed = function (runtimeScene) {
|
||||
return runtimeScene.sceneJustResumed();
|
||||
};
|
||||
|
||||
export const getSceneName = function (runtimeScene) {
|
||||
return runtimeScene.getName();
|
||||
};
|
||||
|
||||
export const setBackgroundColor = function (runtimeScene, rgbColor) {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
@@ -26,15 +29,19 @@ namespace gdjs {
|
||||
parseInt(colors[2])
|
||||
);
|
||||
};
|
||||
|
||||
export const getElapsedTimeInSeconds = function (runtimeScene) {
|
||||
return runtimeScene.getTimeManager().getElapsedTime() / 1000;
|
||||
};
|
||||
|
||||
export const setTimeScale = function (runtimeScene, timeScale) {
|
||||
return runtimeScene.getTimeManager().setTimeScale(timeScale);
|
||||
};
|
||||
|
||||
export const getTimeScale = function (runtimeScene) {
|
||||
return runtimeScene.getTimeManager().getTimeScale();
|
||||
};
|
||||
|
||||
export const timerElapsedTime = function (
|
||||
runtimeScene,
|
||||
timeInSeconds,
|
||||
@@ -49,6 +56,7 @@ namespace gdjs {
|
||||
timeManager.getTimer(timerName).getTime() / 1000 >= timeInSeconds
|
||||
);
|
||||
};
|
||||
|
||||
export const timerPaused = function (runtimeScene, timerName) {
|
||||
const timeManager = runtimeScene.getTimeManager();
|
||||
if (!timeManager.hasTimer(timerName)) {
|
||||
@@ -56,6 +64,7 @@ namespace gdjs {
|
||||
}
|
||||
return timeManager.getTimer(timerName).isPaused();
|
||||
};
|
||||
|
||||
export const resetTimer = function (runtimeScene, timerName) {
|
||||
const timeManager = runtimeScene.getTimeManager();
|
||||
if (!timeManager.hasTimer(timerName)) {
|
||||
@@ -64,6 +73,7 @@ namespace gdjs {
|
||||
timeManager.getTimer(timerName).reset();
|
||||
}
|
||||
};
|
||||
|
||||
export const pauseTimer = function (runtimeScene, timerName) {
|
||||
const timeManager = runtimeScene.getTimeManager();
|
||||
if (!timeManager.hasTimer(timerName)) {
|
||||
@@ -71,6 +81,7 @@ namespace gdjs {
|
||||
}
|
||||
timeManager.getTimer(timerName).setPaused(true);
|
||||
};
|
||||
|
||||
export const unpauseTimer = function (runtimeScene, timerName) {
|
||||
const timeManager = runtimeScene.getTimeManager();
|
||||
if (!timeManager.hasTimer(timerName)) {
|
||||
@@ -78,10 +89,12 @@ namespace gdjs {
|
||||
}
|
||||
return timeManager.getTimer(timerName).setPaused(false);
|
||||
};
|
||||
|
||||
export const removeTimer = function (runtimeScene, timerName) {
|
||||
const timeManager = runtimeScene.getTimeManager();
|
||||
timeManager.removeTimer(timerName);
|
||||
};
|
||||
|
||||
export const getTimerElapsedTimeInSeconds = function (
|
||||
runtimeScene,
|
||||
timerName
|
||||
@@ -92,9 +105,11 @@ namespace gdjs {
|
||||
}
|
||||
return timeManager.getTimer(timerName).getTime() / 1000;
|
||||
};
|
||||
|
||||
export const getTimeFromStartInSeconds = function (runtimeScene) {
|
||||
return runtimeScene.getTimeManager().getTimeFromStart() / 1000;
|
||||
};
|
||||
|
||||
export const getTime = function (runtimeScene, what) {
|
||||
if (what === 'timestamp') {
|
||||
return Date.now();
|
||||
@@ -123,6 +138,7 @@ namespace gdjs {
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const replaceScene = function (
|
||||
runtimeScene,
|
||||
newSceneName,
|
||||
@@ -138,6 +154,7 @@ namespace gdjs {
|
||||
newSceneName
|
||||
);
|
||||
};
|
||||
|
||||
export const pushScene = function (runtimeScene, newSceneName) {
|
||||
if (!runtimeScene.getGame().getSceneData(newSceneName)) {
|
||||
return;
|
||||
@@ -147,12 +164,15 @@ namespace gdjs {
|
||||
newSceneName
|
||||
);
|
||||
};
|
||||
|
||||
export const popScene = function (runtimeScene) {
|
||||
runtimeScene.requestChange(gdjs.SceneChangeRequest.POP_SCENE);
|
||||
};
|
||||
|
||||
export const stopGame = function (runtimeScene) {
|
||||
runtimeScene.requestChange(gdjs.SceneChangeRequest.STOP_GAME);
|
||||
};
|
||||
|
||||
export const createObjectsFromExternalLayout = function (
|
||||
scene,
|
||||
externalLayout,
|
||||
|
@@ -11,6 +11,7 @@ namespace gdjs {
|
||||
) {
|
||||
return runtimeScene.getSoundManager().getGlobalVolume();
|
||||
};
|
||||
|
||||
export const setGlobalVolume = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
globalVolume: float
|
||||
@@ -34,6 +35,7 @@ namespace gdjs {
|
||||
.getSoundManager()
|
||||
.playSound(soundFile, loop, volume, pitch);
|
||||
};
|
||||
|
||||
export const playSoundOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
soundFile: string,
|
||||
@@ -46,6 +48,7 @@ namespace gdjs {
|
||||
.getSoundManager()
|
||||
.playSoundOnChannel(soundFile, channel, loop, volume, pitch);
|
||||
};
|
||||
|
||||
export const stopSoundOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -53,6 +56,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
sound && sound.stop();
|
||||
};
|
||||
|
||||
export const pauseSoundOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -60,6 +64,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
sound && sound.pause();
|
||||
};
|
||||
|
||||
export const continueSoundOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -69,6 +74,7 @@ namespace gdjs {
|
||||
sound.play();
|
||||
}
|
||||
};
|
||||
|
||||
export const isSoundOnChannelPlaying = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -76,6 +82,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
return sound ? sound.playing() : false;
|
||||
};
|
||||
|
||||
export const isSoundOnChannelPaused = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -83,6 +90,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
return sound ? sound.paused() : false;
|
||||
};
|
||||
|
||||
export const isSoundOnChannelStopped = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -90,6 +98,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
return sound ? sound.stopped() : true;
|
||||
};
|
||||
|
||||
export const getSoundOnChannelVolume = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -97,6 +106,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
return sound ? sound.getVolume() * 100 : 100;
|
||||
};
|
||||
|
||||
export const setSoundOnChannelVolume = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer,
|
||||
@@ -105,6 +115,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
sound && sound.setVolume(volume / 100);
|
||||
};
|
||||
|
||||
export const getSoundOnChannelPlayingOffset = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -112,6 +123,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
return sound ? sound.getSeek() : 0;
|
||||
};
|
||||
|
||||
export const setSoundOnChannelPlayingOffset = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer,
|
||||
@@ -120,6 +132,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
sound && sound.setSeek(playingOffset);
|
||||
};
|
||||
|
||||
export const getSoundOnChannelPitch = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -127,6 +140,7 @@ namespace gdjs {
|
||||
const sound = runtimeScene.getSoundManager().getSoundOnChannel(channel);
|
||||
return sound ? sound.getRate() : 1;
|
||||
};
|
||||
|
||||
export const setSoundOnChannelPitch = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer,
|
||||
@@ -164,6 +178,7 @@ namespace gdjs {
|
||||
.getSoundManager()
|
||||
.playMusic(soundFile, loop, volume, pitch);
|
||||
};
|
||||
|
||||
export const playMusicOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
soundFile: string,
|
||||
@@ -176,6 +191,7 @@ namespace gdjs {
|
||||
.getSoundManager()
|
||||
.playMusicOnChannel(soundFile, channel, loop, volume, pitch);
|
||||
};
|
||||
|
||||
export const stopMusicOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -183,6 +199,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
music && music.stop();
|
||||
};
|
||||
|
||||
export const pauseMusicOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -190,6 +207,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
music && music.pause();
|
||||
};
|
||||
|
||||
export const continueMusicOnChannel = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -199,6 +217,7 @@ namespace gdjs {
|
||||
music.play();
|
||||
}
|
||||
};
|
||||
|
||||
export const isMusicOnChannelPlaying = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -206,6 +225,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
return music ? music.playing() : false;
|
||||
};
|
||||
|
||||
export const isMusicOnChannelPaused = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -213,6 +233,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
return music ? music.paused() : false;
|
||||
};
|
||||
|
||||
export const isMusicOnChannelStopped = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -220,6 +241,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
return music ? music.stopped() : true;
|
||||
};
|
||||
|
||||
export const getMusicOnChannelVolume = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -227,6 +249,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
return music ? music.getVolume() * 100 : 100;
|
||||
};
|
||||
|
||||
export const setMusicOnChannelVolume = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer,
|
||||
@@ -235,6 +258,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
music && music.setVolume(volume / 100);
|
||||
};
|
||||
|
||||
export const getMusicOnChannelPlayingOffset = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -242,6 +266,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
return music ? music.getSeek() : 0;
|
||||
};
|
||||
|
||||
export const setMusicOnChannelPlayingOffset = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer,
|
||||
@@ -250,6 +275,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
music && music.setSeek(playingOffset);
|
||||
};
|
||||
|
||||
export const getMusicOnChannelPitch = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer
|
||||
@@ -257,6 +283,7 @@ namespace gdjs {
|
||||
const music = runtimeScene.getSoundManager().getMusicOnChannel(channel);
|
||||
return music ? music.getRate() : 1;
|
||||
};
|
||||
|
||||
export const setMusicOnChannelPitch = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
channel: integer,
|
||||
|
@@ -126,6 +126,7 @@ namespace gdjs {
|
||||
}
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
export const clearJSONFile = (name: string) => {
|
||||
return loadObject(name, (jsObject) => {
|
||||
for (const p in jsObject) {
|
||||
@@ -136,6 +137,7 @@ namespace gdjs {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const elementExistsInJSONFile = (
|
||||
name: string,
|
||||
elementPath: string
|
||||
@@ -152,6 +154,7 @@ namespace gdjs {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteElementFromJSONFile = (
|
||||
name: string,
|
||||
elementPath: string
|
||||
@@ -172,6 +175,7 @@ namespace gdjs {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const writeNumberInJSONFile = (
|
||||
name: string,
|
||||
elementPath: string,
|
||||
@@ -193,6 +197,7 @@ namespace gdjs {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const writeStringInJSONFile = (
|
||||
name: string,
|
||||
elementPath: string,
|
||||
@@ -214,6 +219,7 @@ namespace gdjs {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const readNumberFromJSONFile = (
|
||||
name: string,
|
||||
elementPath: string,
|
||||
@@ -239,6 +245,7 @@ namespace gdjs {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const readStringFromJSONFile = (
|
||||
name: string,
|
||||
elementPath: string,
|
||||
|
@@ -21,6 +21,7 @@ namespace gdjs {
|
||||
.getRenderer()
|
||||
.setMargins(top, right, bottom, left);
|
||||
};
|
||||
|
||||
export const setFullScreen = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
enable: boolean,
|
||||
@@ -29,11 +30,13 @@ namespace gdjs {
|
||||
runtimeScene.getGame().getRenderer().keepAspectRatio(keepAspectRatio);
|
||||
runtimeScene.getGame().getRenderer().setFullScreen(enable);
|
||||
};
|
||||
|
||||
export const isFullScreen = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
return runtimeScene.getGame().getRenderer().isFullScreen();
|
||||
};
|
||||
|
||||
export const setWindowSize = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
width: float,
|
||||
@@ -45,9 +48,11 @@ namespace gdjs {
|
||||
runtimeScene.getGame().setGameResolutionSize(width, height);
|
||||
}
|
||||
};
|
||||
|
||||
export const centerWindow = function (runtimeScene: gdjs.RuntimeScene) {
|
||||
runtimeScene.getGame().getRenderer().centerWindow();
|
||||
};
|
||||
|
||||
export const setGameResolutionSize = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
width: float,
|
||||
@@ -55,29 +60,34 @@ namespace gdjs {
|
||||
) {
|
||||
runtimeScene.getGame().setGameResolutionSize(width, height);
|
||||
};
|
||||
|
||||
export const setGameResolutionResizeMode = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
resizeMode: string
|
||||
) {
|
||||
runtimeScene.getGame().setGameResolutionResizeMode(resizeMode);
|
||||
};
|
||||
|
||||
export const setAdaptGameResolutionAtRuntime = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
enable: boolean
|
||||
) {
|
||||
runtimeScene.getGame().setAdaptGameResolutionAtRuntime(enable);
|
||||
};
|
||||
|
||||
export const setWindowTitle = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
title: string
|
||||
) {
|
||||
runtimeScene.getGame().getRenderer().setWindowTitle(title);
|
||||
};
|
||||
|
||||
export const getWindowTitle = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
return runtimeScene.getGame().getRenderer().getWindowTitle();
|
||||
};
|
||||
|
||||
export const getWindowInnerWidth = function (): number {
|
||||
if (
|
||||
gdjs.RuntimeGameRenderer &&
|
||||
@@ -88,6 +98,7 @@ namespace gdjs {
|
||||
// @ts-ignore
|
||||
return typeof window !== 'undefined' ? window.innerWidth : 800;
|
||||
};
|
||||
|
||||
export const getWindowInnerHeight = function (): number {
|
||||
if (
|
||||
gdjs.RuntimeGameRenderer &&
|
||||
@@ -98,16 +109,19 @@ namespace gdjs {
|
||||
// @ts-ignore
|
||||
return typeof window !== 'undefined' ? window.innerHeight : 800;
|
||||
};
|
||||
|
||||
export const getGameResolutionWidth = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
return runtimeScene.getGame().getGameResolutionWidth();
|
||||
};
|
||||
|
||||
export const getGameResolutionHeight = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
return runtimeScene.getGame().getGameResolutionHeight();
|
||||
};
|
||||
|
||||
export const openURL = function (
|
||||
url: string,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
|
File diff suppressed because one or more lines are too long
@@ -38,6 +38,9 @@ namespace gdjs {
|
||||
export const callbacksRuntimeSceneUnloaded: Array<RuntimeSceneCallback> = [];
|
||||
export const callbacksObjectDeletedFromScene: Array<RuntimeSceneRuntimeObjectCallback> = [];
|
||||
|
||||
/** Base64 encoded logo of GDevelop for the splash screen. */
|
||||
export let gdevelopLogo: string = '';
|
||||
|
||||
/**
|
||||
* Convert a rgb color value to a hex string.
|
||||
*
|
||||
|
@@ -1,89 +1,255 @@
|
||||
namespace gdjs {
|
||||
import PIXI = GlobalPIXIModule.PIXI;
|
||||
|
||||
class LoadingScreenPixiRenderer {
|
||||
_pixiRenderer: any;
|
||||
_loadingScreen: any;
|
||||
_progressText: any;
|
||||
_madeWithText: any;
|
||||
_websiteText: any;
|
||||
_splashImage: any;
|
||||
enum LoadingScreenState {
|
||||
NOT_STARTED,
|
||||
STARTED,
|
||||
FINISHED,
|
||||
}
|
||||
|
||||
constructor(runtimeGamePixiRenderer, loadingScreenSetup) {
|
||||
const fadeIn = (
|
||||
object: PIXI.DisplayObject | null,
|
||||
duration: float,
|
||||
deltaTimeInMs: float
|
||||
) => {
|
||||
if (!object) return;
|
||||
if (duration > 0) {
|
||||
object.alpha += ((1 / duration) * deltaTimeInMs) / 1000;
|
||||
if (object.alpha > 1) object.alpha = 1;
|
||||
} else {
|
||||
object.alpha = 1;
|
||||
}
|
||||
};
|
||||
const hasFadedIn = (object: PIXI.DisplayObject | null) => {
|
||||
return !object || object.alpha >= 1;
|
||||
};
|
||||
|
||||
class LoadingScreenPixiRenderer {
|
||||
_pixiRenderer: PIXI.Renderer | null;
|
||||
_loadingScreenData: LoadingScreenData;
|
||||
|
||||
_loadingScreenContainer: PIXI.Container;
|
||||
_backgroundSprite: PIXI.Sprite | null = null;
|
||||
_gdevelopLogoSprite: PIXI.Sprite | null = null;
|
||||
_progressBarGraphics: PIXI.Graphics | null = null;
|
||||
|
||||
_state: LoadingScreenState = LoadingScreenState.NOT_STARTED;
|
||||
_startTimeInMs: float = 0;
|
||||
_backgroundReadyTimeInMs: float = 0;
|
||||
_lastFrameTimeInMs: float = 0;
|
||||
_progressPercent: float = 0;
|
||||
|
||||
constructor(
|
||||
runtimeGamePixiRenderer: gdjs.RuntimeGamePixiRenderer,
|
||||
imageManager: gdjs.PixiImageManager,
|
||||
loadingScreenData: LoadingScreenData
|
||||
) {
|
||||
this._loadingScreenData = loadingScreenData;
|
||||
this._loadingScreenContainer = new PIXI.Container();
|
||||
this._pixiRenderer = runtimeGamePixiRenderer.getPIXIRenderer();
|
||||
if (!this._pixiRenderer) {
|
||||
// A PIXI Renderer can be missing during tests, when creating a runtime game
|
||||
// without a canvas.
|
||||
return;
|
||||
}
|
||||
this._loadingScreen = new PIXI.Container();
|
||||
this._progressText = new PIXI.Text(' ', {
|
||||
fontSize: '30px',
|
||||
fontFamily: 'Arial',
|
||||
fill: '#FFFFFF',
|
||||
align: 'center',
|
||||
});
|
||||
this._loadingScreen.addChild(this._progressText);
|
||||
if (loadingScreenSetup && loadingScreenSetup.showGDevelopSplash) {
|
||||
this._madeWithText = new PIXI.Text('Made with', {
|
||||
fontSize: '30px',
|
||||
fontFamily: 'Arial',
|
||||
fill: '#FFFFFF',
|
||||
align: 'center',
|
||||
});
|
||||
this._madeWithText.position.y = this._pixiRenderer.height / 2 - 130;
|
||||
this._websiteText = new PIXI.Text('gdevelop-app.com', {
|
||||
fontSize: '30px',
|
||||
fontFamily: 'Arial',
|
||||
fill: '#FFFFFF',
|
||||
align: 'center',
|
||||
});
|
||||
this._websiteText.position.y = this._pixiRenderer.height / 2 + 100;
|
||||
this._splashImage = PIXI.Sprite.from(gdjs.splashImage);
|
||||
this._splashImage.position.x = this._pixiRenderer.width / 2;
|
||||
this._splashImage.position.y = this._pixiRenderer.height / 2;
|
||||
this._splashImage.anchor.x = 0.5;
|
||||
this._splashImage.anchor.y = 0.5;
|
||||
this._splashImage.scale.x = this._pixiRenderer.width / 800;
|
||||
this._splashImage.scale.y = this._pixiRenderer.width / 800;
|
||||
this._loadingScreen.addChild(this._splashImage);
|
||||
this._loadingScreen.addChild(this._madeWithText);
|
||||
this._loadingScreen.addChild(this._websiteText);
|
||||
this._pixiRenderer.backgroundColor = this._loadingScreenData.backgroundColor;
|
||||
|
||||
const backgroundTexture = imageManager.getPIXITexture(
|
||||
loadingScreenData.backgroundImageResourceName
|
||||
);
|
||||
if (backgroundTexture !== imageManager.getInvalidPIXITexture()) {
|
||||
this._backgroundSprite = PIXI.Sprite.from(backgroundTexture);
|
||||
this._backgroundSprite.alpha = 0;
|
||||
this._backgroundSprite.anchor.x = 0.5;
|
||||
this._backgroundSprite.anchor.y = 0.5;
|
||||
this._loadingScreenContainer.addChild(this._backgroundSprite);
|
||||
}
|
||||
|
||||
if (loadingScreenData.showGDevelopSplash) {
|
||||
this._gdevelopLogoSprite = PIXI.Sprite.from(gdjs.gdevelopLogo);
|
||||
this._gdevelopLogoSprite.alpha = 0;
|
||||
this._gdevelopLogoSprite.anchor.x = 0.5;
|
||||
this._gdevelopLogoSprite.anchor.y = 0.5;
|
||||
this._loadingScreenContainer.addChild(this._gdevelopLogoSprite);
|
||||
}
|
||||
if (loadingScreenData.showProgressBar) {
|
||||
this._progressBarGraphics = new PIXI.Graphics();
|
||||
this._progressBarGraphics.alpha = 0;
|
||||
this._loadingScreenContainer.addChild(this._progressBarGraphics);
|
||||
}
|
||||
|
||||
this._render(performance.now());
|
||||
}
|
||||
|
||||
setPercent(percent: number) {
|
||||
this._progressPercent = percent;
|
||||
}
|
||||
|
||||
private _startLoadingScreen() {
|
||||
if (!this._pixiRenderer) return;
|
||||
this._state = LoadingScreenState.STARTED;
|
||||
this._startTimeInMs = performance.now();
|
||||
}
|
||||
|
||||
private _updatePositions() {
|
||||
if (!this._pixiRenderer) return;
|
||||
|
||||
if (this._backgroundSprite && this._backgroundSprite.texture.valid) {
|
||||
this._backgroundSprite.position.x = this._pixiRenderer.width / 2;
|
||||
this._backgroundSprite.position.y = this._pixiRenderer.height / 2;
|
||||
const scale = Math.max(
|
||||
this._pixiRenderer.width / this._backgroundSprite.texture.width,
|
||||
this._pixiRenderer.height / this._backgroundSprite.texture.height
|
||||
);
|
||||
this._backgroundSprite.scale.x = scale;
|
||||
this._backgroundSprite.scale.y = scale;
|
||||
}
|
||||
|
||||
if (this._gdevelopLogoSprite) {
|
||||
this._gdevelopLogoSprite.position.x = this._pixiRenderer.width / 2;
|
||||
this._gdevelopLogoSprite.position.y = this._pixiRenderer.height / 2;
|
||||
const logoWidth = 680;
|
||||
const border =
|
||||
this._pixiRenderer.width > this._pixiRenderer.height &&
|
||||
this._pixiRenderer.width > 500
|
||||
? 150
|
||||
: 35;
|
||||
const desiredWidth = Math.min(
|
||||
logoWidth,
|
||||
Math.max(1, this._pixiRenderer.width - border * 2)
|
||||
);
|
||||
const scale = desiredWidth / logoWidth;
|
||||
this._gdevelopLogoSprite.scale.x = scale;
|
||||
this._gdevelopLogoSprite.scale.y = scale;
|
||||
|
||||
// Give up trying to show the logo if the resolution is really too small.
|
||||
// TODO: use a low resolution logo instead.
|
||||
this._gdevelopLogoSprite.visible =
|
||||
this._pixiRenderer.width > 200 && this._pixiRenderer.height > 200;
|
||||
}
|
||||
}
|
||||
|
||||
render(percent) {
|
||||
private _render(timeInMs: float) {
|
||||
if (!this._pixiRenderer) {
|
||||
return;
|
||||
}
|
||||
const screenBorder = 10;
|
||||
if (this._madeWithText) {
|
||||
this._madeWithText.position.x =
|
||||
this._pixiRenderer.width / 2 - this._madeWithText.width / 2;
|
||||
this._madeWithText.position.y =
|
||||
this._pixiRenderer.height / 2 -
|
||||
this._splashImage.height / 2 -
|
||||
this._madeWithText.height -
|
||||
20;
|
||||
|
||||
// Continue the rendering loop as long as the loading screen is not finished.
|
||||
if (this._state !== LoadingScreenState.FINISHED) {
|
||||
requestAnimationFrame(() => this._render(performance.now()));
|
||||
}
|
||||
if (this._websiteText) {
|
||||
this._websiteText.position.x =
|
||||
this._pixiRenderer.width - this._websiteText.width - screenBorder;
|
||||
this._websiteText.position.y =
|
||||
this._pixiRenderer.height - this._websiteText.height - screenBorder;
|
||||
|
||||
const deltaTimeInMs = this._lastFrameTimeInMs
|
||||
? timeInMs - this._lastFrameTimeInMs
|
||||
: 0;
|
||||
this._lastFrameTimeInMs = timeInMs;
|
||||
|
||||
this._updatePositions();
|
||||
|
||||
if (this._state == LoadingScreenState.NOT_STARTED) {
|
||||
if (!this._backgroundSprite || this._backgroundSprite.texture.valid) {
|
||||
this._startLoadingScreen();
|
||||
}
|
||||
} else if (this._state == LoadingScreenState.STARTED) {
|
||||
const backgroundFadeInDuration = this._loadingScreenData
|
||||
.backgroundFadeInDuration;
|
||||
fadeIn(this._backgroundSprite, backgroundFadeInDuration, deltaTimeInMs);
|
||||
|
||||
if (hasFadedIn(this._backgroundSprite)) {
|
||||
if (!this._backgroundReadyTimeInMs)
|
||||
this._backgroundReadyTimeInMs = timeInMs;
|
||||
|
||||
const logoAndProgressFadeInDuration = this._loadingScreenData
|
||||
.logoAndProgressFadeInDuration;
|
||||
const logoAndProgressLogoFadeInDelay = this._loadingScreenData
|
||||
.logoAndProgressLogoFadeInDelay;
|
||||
|
||||
if (
|
||||
timeInMs - this._backgroundReadyTimeInMs >
|
||||
logoAndProgressLogoFadeInDelay * 1000
|
||||
) {
|
||||
fadeIn(
|
||||
this._gdevelopLogoSprite,
|
||||
logoAndProgressFadeInDuration,
|
||||
deltaTimeInMs
|
||||
);
|
||||
fadeIn(
|
||||
this._progressBarGraphics,
|
||||
logoAndProgressFadeInDuration,
|
||||
deltaTimeInMs
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._progressBarGraphics) {
|
||||
const color = this._loadingScreenData.progressBarColor;
|
||||
let progressBarWidth =
|
||||
(this._loadingScreenData.progressBarWidthPercent / 100) *
|
||||
this._pixiRenderer.width;
|
||||
if (this._loadingScreenData.progressBarMaxWidth > 0) {
|
||||
if (progressBarWidth > this._loadingScreenData.progressBarMaxWidth)
|
||||
progressBarWidth = this._loadingScreenData.progressBarMaxWidth;
|
||||
}
|
||||
if (this._loadingScreenData.progressBarMinWidth > 0) {
|
||||
if (progressBarWidth < this._loadingScreenData.progressBarMinWidth)
|
||||
progressBarWidth = this._loadingScreenData.progressBarMinWidth;
|
||||
}
|
||||
|
||||
const progressBarHeight = this._loadingScreenData.progressBarHeight;
|
||||
const progressBarX = Math.floor(
|
||||
this._pixiRenderer.width / 2 - progressBarWidth / 2
|
||||
);
|
||||
const progressBarY =
|
||||
this._pixiRenderer.height < 350
|
||||
? Math.floor(this._pixiRenderer.height - 10 - progressBarHeight)
|
||||
: Math.floor(this._pixiRenderer.height - 90 - progressBarHeight);
|
||||
const lineWidth = 1;
|
||||
// Display bar with an additional 1% to ensure it's filled at the end.
|
||||
const progress = Math.min(1, (this._progressPercent + 1) / 100);
|
||||
this._progressBarGraphics.clear();
|
||||
this._progressBarGraphics.lineStyle(lineWidth, color, 1, 0);
|
||||
this._progressBarGraphics.drawRect(
|
||||
progressBarX,
|
||||
progressBarY,
|
||||
progressBarWidth,
|
||||
progressBarHeight
|
||||
);
|
||||
|
||||
this._progressBarGraphics.beginFill(color, 1);
|
||||
this._progressBarGraphics.lineStyle(0, color, 1);
|
||||
this._progressBarGraphics.drawRect(
|
||||
progressBarX + lineWidth,
|
||||
progressBarY + lineWidth,
|
||||
progressBarWidth * progress - lineWidth * 2,
|
||||
progressBarHeight - lineWidth * 2
|
||||
);
|
||||
this._progressBarGraphics.endFill();
|
||||
}
|
||||
}
|
||||
this._progressText.text = percent + '%';
|
||||
this._progressText.position.x = screenBorder;
|
||||
this._progressText.position.y =
|
||||
this._pixiRenderer.height - this._progressText.height - screenBorder;
|
||||
this._pixiRenderer.render(this._loadingScreen);
|
||||
|
||||
this._pixiRenderer.render(this._loadingScreenContainer);
|
||||
}
|
||||
|
||||
unload() {}
|
||||
unload(): Promise<void> {
|
||||
const totalElapsedTime = (performance.now() - this._startTimeInMs) / 1000;
|
||||
const remainingTime =
|
||||
this._loadingScreenData.minDuration - totalElapsedTime;
|
||||
this.setPercent(100);
|
||||
|
||||
// Ensure we have shown the loading screen for at least minDuration.
|
||||
if (remainingTime <= 0) {
|
||||
this._state = LoadingScreenState.FINISHED;
|
||||
return Promise.resolve();
|
||||
}
|
||||
return new Promise((resolve) =>
|
||||
setTimeout(() => {
|
||||
this._state = LoadingScreenState.FINISHED;
|
||||
resolve();
|
||||
}, remainingTime * 1000)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do
|
||||
export const LoadingScreenRenderer = LoadingScreenPixiRenderer;
|
||||
|
||||
//Register the class to let the engine use it.
|
||||
export const LoadingScreenRenderer = LoadingScreenPixiRenderer;
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ namespace gdjs {
|
||||
export const clampValue = function (value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
};
|
||||
|
||||
export const clampKernelSize = function (value, min, max) {
|
||||
const len = Math.round((max - min) / 2 + 1);
|
||||
const arr = new Array(len);
|
||||
|
@@ -65,6 +65,9 @@ namespace gdjs {
|
||||
const res = this._resources[i];
|
||||
if (res.name === resourceName && res.kind === 'image') {
|
||||
texture = PIXI.Texture.from(res.file);
|
||||
if (!res.smoothed) {
|
||||
texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -26,12 +26,12 @@ namespace gdjs {
|
||||
//Used to track if the window is displayed as fullscreen (see setFullscreen method).
|
||||
_forceFullscreen: any;
|
||||
_pixiRenderer: PIXI.Renderer | null = null;
|
||||
_canvasWidth: float = 0;
|
||||
|
||||
// Current width of the canvas (might be scaled down/up compared to renderer)
|
||||
_canvasWidth: float = 0;
|
||||
// Current height of the canvas (might be scaled down/up compared to renderer)
|
||||
_canvasHeight: float = 0;
|
||||
|
||||
// Current height of the canvas (might be scaled down/up compared to renderer)
|
||||
_keepRatio: boolean = true;
|
||||
_marginLeft: any;
|
||||
_marginTop: any;
|
||||
@@ -72,9 +72,9 @@ namespace gdjs {
|
||||
this._pixiRenderer.view
|
||||
);
|
||||
this._pixiRenderer.view.style['position'] = 'absolute';
|
||||
//Ensure that the canvas has the focus.
|
||||
this._pixiRenderer.view.tabIndex = 1;
|
||||
|
||||
//Ensure that the canvas has the focus.
|
||||
this._resizeCanvas();
|
||||
|
||||
// Handle scale mode
|
||||
|
@@ -431,6 +431,7 @@ namespace gdjs {
|
||||
loadAllAssets(callback: () => void, progressCallback?: (float) => void) {
|
||||
const loadingScreen = new gdjs.LoadingScreenRenderer(
|
||||
this.getRenderer(),
|
||||
this._imageManager,
|
||||
this._data.properties.loadingScreen
|
||||
);
|
||||
const allAssetsTotal = this._data.resources.resources.length;
|
||||
@@ -442,7 +443,7 @@ namespace gdjs {
|
||||
this._imageManager.loadTextures(
|
||||
function (count, total) {
|
||||
const percent = Math.floor((count / allAssetsTotal) * 100);
|
||||
loadingScreen.render(percent);
|
||||
loadingScreen.setPercent(percent);
|
||||
if (progressCallback) {
|
||||
progressCallback(percent);
|
||||
}
|
||||
@@ -453,7 +454,7 @@ namespace gdjs {
|
||||
const percent = Math.floor(
|
||||
((texturesTotalCount + count) / allAssetsTotal) * 100
|
||||
);
|
||||
loadingScreen.render(percent);
|
||||
loadingScreen.setPercent(percent);
|
||||
if (progressCallback) {
|
||||
progressCallback(percent);
|
||||
}
|
||||
@@ -466,7 +467,7 @@ namespace gdjs {
|
||||
allAssetsTotal) *
|
||||
100
|
||||
);
|
||||
loadingScreen.render(percent);
|
||||
loadingScreen.setPercent(percent);
|
||||
if (progressCallback) {
|
||||
progressCallback(percent);
|
||||
}
|
||||
@@ -482,7 +483,7 @@ namespace gdjs {
|
||||
allAssetsTotal) *
|
||||
100
|
||||
);
|
||||
loadingScreen.render(percent);
|
||||
loadingScreen.setPercent(percent);
|
||||
if (progressCallback) {
|
||||
progressCallback(percent);
|
||||
}
|
||||
@@ -499,11 +500,11 @@ namespace gdjs {
|
||||
allAssetsTotal) *
|
||||
100
|
||||
);
|
||||
loadingScreen.render(percent);
|
||||
loadingScreen.setPercent(percent);
|
||||
if (progressCallback) progressCallback(percent);
|
||||
})
|
||||
.then(() => loadingScreen.unload())
|
||||
.then(() => {
|
||||
loadingScreen.unload();
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
4
GDJS/Runtime/splash/gd-logo-dark-colored.ts
Normal file
4
GDJS/Runtime/splash/gd-logo-dark-colored.ts
Normal file
File diff suppressed because one or more lines are too long
4
GDJS/Runtime/splash/gd-logo-dark.ts
Normal file
4
GDJS/Runtime/splash/gd-logo-dark.ts
Normal file
File diff suppressed because one or more lines are too long
4
GDJS/Runtime/splash/gd-logo-light-colored.ts
Normal file
4
GDJS/Runtime/splash/gd-logo-light-colored.ts
Normal file
File diff suppressed because one or more lines are too long
4
GDJS/Runtime/splash/gd-logo-light.ts
Normal file
4
GDJS/Runtime/splash/gd-logo-light.ts
Normal file
File diff suppressed because one or more lines are too long
12
GDJS/Runtime/types/project-data.d.ts
vendored
12
GDJS/Runtime/types/project-data.d.ts
vendored
@@ -190,6 +190,18 @@ declare interface ExtensionProperty {
|
||||
|
||||
declare interface LoadingScreenData {
|
||||
showGDevelopSplash: boolean;
|
||||
backgroundImageResourceName: string;
|
||||
backgroundColor: integer;
|
||||
backgroundFadeInDuration: float;
|
||||
minDuration: float;
|
||||
logoAndProgressFadeInDuration: float;
|
||||
logoAndProgressLogoFadeInDelay: float;
|
||||
showProgressBar: boolean;
|
||||
progressBarMinWidth: float;
|
||||
progressBarMaxWidth: float;
|
||||
progressBarWidthPercent: float;
|
||||
progressBarHeight: float;
|
||||
progressBarColor: integer;
|
||||
}
|
||||
|
||||
declare interface ResourcesData {
|
||||
|
BIN
GDJS/tests/games/sprites/assets/green.png
Normal file
BIN
GDJS/tests/games/sprites/assets/green.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 189 B |
BIN
GDJS/tests/games/sprites/assets/red.png
Normal file
BIN
GDJS/tests/games/sprites/assets/red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 108 B |
10510
GDJS/tests/games/sprites/game.json
Normal file
10510
GDJS/tests/games/sprites/game.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@ module.exports = function (config) {
|
||||
client: {
|
||||
mocha: {
|
||||
reporter: 'html',
|
||||
timeout: 5000, // Give a bit more time for CIs (the default 2s can be too low sometimes)
|
||||
timeout: 10000, // Give a bit more time for CIs (the default 2s can be too low sometimes, as a real browser is involved).
|
||||
},
|
||||
},
|
||||
files: [
|
||||
|
@@ -32,6 +32,18 @@ gdjs.getPixiRuntimeGameWithAssets = () => {
|
||||
verticalSync: true,
|
||||
loadingScreen: {
|
||||
showGDevelopSplash: true,
|
||||
backgroundImageResourceName: '',
|
||||
backgroundColor: 0,
|
||||
backgroundFadeInDuration: 0.2,
|
||||
minDuration: 0,
|
||||
logoAndProgressFadeInDuration: 0.2,
|
||||
logoAndProgressLogoFadeInDelay: 0.2,
|
||||
showProgressBar: true,
|
||||
progressBarMinWidth: 40,
|
||||
progressBarMaxWidth: 300,
|
||||
progressBarWidthPercent: 40,
|
||||
progressBarHeight: 20,
|
||||
progressBarColor: 0xFFFFFF,
|
||||
},
|
||||
currentPlatform: '',
|
||||
extensionProperties: [],
|
||||
|
@@ -293,8 +293,35 @@ interface PlatformSpecificAssets {
|
||||
interface LoadingScreen {
|
||||
void LoadingScreen();
|
||||
|
||||
void ShowGDevelopSplash(boolean show);
|
||||
boolean IsGDevelopSplashShown();
|
||||
void ShowGDevelopSplash(boolean show);
|
||||
[Const, Ref] DOMString GetGDevelopLogoStyle();
|
||||
[Ref] LoadingScreen SetGDevelopLogoStyle([Const] DOMString value);
|
||||
[Const, Ref] DOMString GetBackgroundImageResourceName();
|
||||
[Ref] LoadingScreen SetBackgroundImageResourceName([Const] DOMString value);
|
||||
long GetBackgroundColor();
|
||||
[Ref] LoadingScreen SetBackgroundColor(long value);
|
||||
double GetBackgroundFadeInDuration();
|
||||
[Ref] LoadingScreen SetBackgroundFadeInDuration(double value);
|
||||
double GetMinDuration();
|
||||
[Ref] LoadingScreen SetMinDuration(double value);
|
||||
double GetLogoAndProgressFadeInDuration();
|
||||
[Ref] LoadingScreen SetLogoAndProgressFadeInDuration(double value);
|
||||
double GetLogoAndProgressLogoFadeInDelay();
|
||||
[Ref] LoadingScreen SetLogoAndProgressLogoFadeInDelay(double value);
|
||||
boolean GetShowProgressBar();
|
||||
[Ref] LoadingScreen SetShowProgressBar(boolean value);
|
||||
double GetProgressBarMaxWidth();
|
||||
[Ref] LoadingScreen SetProgressBarMaxWidth(double value);
|
||||
double GetProgressBarMinWidth();
|
||||
[Ref] LoadingScreen SetProgressBarMinWidth(double value);
|
||||
double GetProgressBarWidthPercent();
|
||||
[Ref] LoadingScreen SetProgressBarWidthPercent(double value);
|
||||
double GetProgressBarHeight();
|
||||
[Ref] LoadingScreen SetProgressBarHeight(double value);
|
||||
long GetProgressBarColor();
|
||||
[Ref] LoadingScreen SetProgressBarColor(long value);
|
||||
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
@@ -580,7 +607,7 @@ interface Layout {
|
||||
void SerializeLayersTo([Ref] SerializerElement element);
|
||||
void UnserializeLayersFrom([Const, Ref] SerializerElement element);
|
||||
|
||||
[Ref] LayoutEditorCanvasOptions GetAssociatedSettings();
|
||||
[Ref] EditorSettings GetAssociatedEditorSettings();
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
@@ -629,7 +656,7 @@ interface ExternalLayout {
|
||||
[Const, Ref] DOMString GetAssociatedLayout();
|
||||
|
||||
[Ref] InitialInstancesContainer GetInitialInstances();
|
||||
[Ref] LayoutEditorCanvasOptions GetAssociatedSettings();
|
||||
[Ref] EditorSettings GetAssociatedEditorSettings();
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
@@ -694,6 +721,11 @@ interface Layer {
|
||||
|
||||
[Ref] EffectsContainer GetEffects();
|
||||
|
||||
// Note that for now, cameras are not used in the editor (and not supported in the game engine).
|
||||
// Just exposing the count to ensure we can test it.
|
||||
unsigned long GetCameraCount();
|
||||
void SetCameraCount(unsigned long cameraCount);
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
};
|
||||
@@ -1078,6 +1110,7 @@ interface InstructionMetadata {
|
||||
[Const] DOMString type, [Const] DOMString supplementaryInformation);
|
||||
[Ref] InstructionMetadata SetDefaultValue([Const] DOMString defaultValue);
|
||||
[Ref] InstructionMetadata SetParameterLongDescription([Const] DOMString longDescription);
|
||||
[Ref] InstructionMetadata SetParameterExtraInfo([Const] DOMString extraInfo);
|
||||
|
||||
[Ref] InstructionMetadata UseStandardOperatorParameters([Const] DOMString type);
|
||||
[Ref] InstructionMetadata UseStandardRelationalOperatorParameters([Const] DOMString type);
|
||||
@@ -1365,6 +1398,19 @@ interface BehaviorMetadata {
|
||||
[Const] DOMString group,
|
||||
[Const] DOMString icon);
|
||||
|
||||
[Ref] InstructionMetadata AddDuplicatedAction(
|
||||
[Const] DOMString newActionName,
|
||||
[Const] DOMString copiedActionName);
|
||||
[Ref] InstructionMetadata AddDuplicatedCondition(
|
||||
[Const] DOMString newConditionName,
|
||||
[Const] DOMString copiedConditionName);
|
||||
[Ref] ExpressionMetadata AddDuplicatedExpression(
|
||||
[Const] DOMString newExpressionName,
|
||||
[Const] DOMString copiedExpressionName);
|
||||
[Ref] ExpressionMetadata AddDuplicatedStrExpression(
|
||||
[Const] DOMString newExpressionName,
|
||||
[Const] DOMString copiedExpressionName);
|
||||
|
||||
[Ref] BehaviorMetadata SetIncludeFile([Const] DOMString includeFile);
|
||||
[Ref] BehaviorMetadata AddIncludeFile([Const] DOMString includeFile);
|
||||
|
||||
@@ -2268,8 +2314,8 @@ interface ResourcesInUseHelper {
|
||||
};
|
||||
ResourcesInUseHelper implements ArbitraryResourceWorker;
|
||||
|
||||
interface LayoutEditorCanvasOptions {
|
||||
void LayoutEditorCanvasOptions();
|
||||
interface EditorSettings {
|
||||
void EditorSettings();
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
@@ -2646,6 +2692,7 @@ interface PreviewExportOptions {
|
||||
[Ref] PreviewExportOptions SetExternalLayoutName([Const] DOMString externalLayoutName);
|
||||
[Ref] PreviewExportOptions SetIncludeFileHash([Const] DOMString includeFile, long hash);
|
||||
[Ref] PreviewExportOptions SetProjectDataOnlyExport(boolean enable);
|
||||
[Ref] PreviewExportOptions SetFullLoadingScreen(boolean enable);
|
||||
[Ref] PreviewExportOptions SetNonRuntimeScriptsCacheBurst(unsigned long value);
|
||||
};
|
||||
|
||||
|
@@ -20,7 +20,7 @@
|
||||
#include <GDCore/Extensions/Metadata/ParameterMetadataTools.h>
|
||||
#include <GDCore/Extensions/Platform.h>
|
||||
#include <GDCore/IDE/AbstractFileSystem.h>
|
||||
#include <GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvasOptions.h>
|
||||
#include <GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h>
|
||||
#include <GDCore/IDE/Events/ArbitraryEventsWorker.h>
|
||||
#include <GDCore/IDE/Events/EventsContextAnalyzer.h>
|
||||
#include <GDCore/IDE/Events/EventsListUnfolder.h>
|
||||
|
@@ -235,15 +235,21 @@ describe('libGD.js', function () {
|
||||
layer.setName('GUI');
|
||||
layer.setVisibility(false);
|
||||
layer.getEffects().insertNewEffect('MyEffect', 0);
|
||||
layer.setCameraCount(1);
|
||||
|
||||
const element = new gd.SerializerElement();
|
||||
layer.serializeTo(element);
|
||||
layer2.unserializeFrom(element);
|
||||
|
||||
expect(layer2.getName()).toBe('GUI');
|
||||
expect(layer2.getVisibility()).toBe(false);
|
||||
expect(layer2.getEffects().getEffectsCount()).toBe(1);
|
||||
expect(layer2.getEffects().getEffectAt(0).getName()).toBe('MyEffect');
|
||||
for (let i = 0; i < 5; ++i) {
|
||||
// Repeat multiple time to check idempotency.
|
||||
layer2.unserializeFrom(element);
|
||||
|
||||
expect(layer2.getName()).toBe('GUI');
|
||||
expect(layer2.getVisibility()).toBe(false);
|
||||
expect(layer2.getEffects().getEffectsCount()).toBe(1);
|
||||
expect(layer2.getEffects().getEffectAt(0).getName()).toBe('MyEffect');
|
||||
expect(layer2.getCameraCount()).toBe(1);
|
||||
}
|
||||
|
||||
layer.delete();
|
||||
layer2.delete();
|
||||
@@ -951,8 +957,8 @@ describe('libGD.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('gd.BitmapFontResource', function() {
|
||||
it('should have name and file', function() {
|
||||
describe('gd.BitmapFontResource', function () {
|
||||
it('should have name and file', function () {
|
||||
const resource = new gd.BitmapFontResource();
|
||||
resource.setName('MyBitmapFontResource');
|
||||
resource.setFile('MyBitmapFontFile');
|
||||
@@ -960,7 +966,7 @@ describe('libGD.js', function () {
|
||||
expect(resource.getFile()).toBe('MyBitmapFontFile');
|
||||
resource.delete();
|
||||
});
|
||||
it('can have metadata', function() {
|
||||
it('can have metadata', function () {
|
||||
const resource = new gd.BitmapFontResource();
|
||||
expect(resource.getMetadata()).toBe('');
|
||||
resource.setMetadata(JSON.stringify({ hello: 'world' }));
|
||||
@@ -969,8 +975,8 @@ describe('libGD.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('gd.VideoResource', function() {
|
||||
it('should have name and file', function() {
|
||||
describe('gd.VideoResource', function () {
|
||||
it('should have name and file', function () {
|
||||
const resource = new gd.VideoResource();
|
||||
resource.setName('MyVideoResource');
|
||||
resource.setFile('MyVideoFile');
|
||||
@@ -1936,10 +1942,11 @@ describe('libGD.js', function () {
|
||||
action.setParametersCount(2);
|
||||
action.setParameter(0, 'MyCharacter');
|
||||
|
||||
var formattedTexts = gd.InstructionSentenceFormatter.get().getAsFormattedText(
|
||||
action,
|
||||
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), 'Delete')
|
||||
);
|
||||
var formattedTexts =
|
||||
gd.InstructionSentenceFormatter.get().getAsFormattedText(
|
||||
action,
|
||||
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), 'Delete')
|
||||
);
|
||||
|
||||
expect(formattedTexts.size()).toBe(2);
|
||||
expect(formattedTexts.getString(0)).toBe('Delete ');
|
||||
@@ -2414,7 +2421,8 @@ describe('libGD.js', function () {
|
||||
resourcesMergingHelper.setBaseDirectory('/my/project/');
|
||||
project.exposeResources(resourcesMergingHelper);
|
||||
|
||||
const oldAndNewFilenames = resourcesMergingHelper.getAllResourcesOldAndNewFilename();
|
||||
const oldAndNewFilenames =
|
||||
resourcesMergingHelper.getAllResourcesOldAndNewFilename();
|
||||
expect(oldAndNewFilenames.get('/my/project/MyResource.png')).toBe(
|
||||
'MyResource.png'
|
||||
);
|
||||
@@ -2900,11 +2908,12 @@ describe('libGD.js', function () {
|
||||
layout
|
||||
);
|
||||
const expressionNode = parser.parseExpression(type, expression).get();
|
||||
const completionDescriptions = gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
expressionNode,
|
||||
// We're looking for completion for the character just before the caret.
|
||||
Math.max(0, caretPosition - 1)
|
||||
);
|
||||
const completionDescriptions =
|
||||
gd.ExpressionCompletionFinder.getCompletionDescriptionsFor(
|
||||
expressionNode,
|
||||
// We're looking for completion for the character just before the caret.
|
||||
Math.max(0, caretPosition - 1)
|
||||
);
|
||||
|
||||
for (let i = 0; i < completionDescriptions.size(); i++) {
|
||||
const completionDescription = completionDescriptions.at(i);
|
||||
@@ -3549,13 +3558,24 @@ describe('libGD.js', function () {
|
||||
const instructionMetadata = new gd.InstructionMetadata();
|
||||
|
||||
expect(instructionMetadata.getParametersCount()).toBe(0);
|
||||
instructionMetadata.addParameter('type', 'label', '', false);
|
||||
instructionMetadata.addParameter(
|
||||
'type',
|
||||
'label',
|
||||
'AdditionalStuffThatWillBeReplaced',
|
||||
false
|
||||
);
|
||||
instructionMetadata.setParameterLongDescription('Blabla');
|
||||
instructionMetadata.setParameterExtraInfo(
|
||||
'AdditionalStuffLikeTypicallyAnObjectOrBehaviorType'
|
||||
);
|
||||
expect(instructionMetadata.getParametersCount()).toBe(1);
|
||||
expect(instructionMetadata.getParameter(0).getType()).toBe('type');
|
||||
expect(instructionMetadata.getParameter(0).getDescription()).toBe(
|
||||
'label'
|
||||
);
|
||||
expect(instructionMetadata.getParameter(0).getExtraInfo()).toBe(
|
||||
'AdditionalStuffLikeTypicallyAnObjectOrBehaviorType'
|
||||
);
|
||||
expect(instructionMetadata.getParameter(0).getLongDescription()).toBe(
|
||||
'Blabla'
|
||||
);
|
||||
@@ -3592,4 +3612,26 @@ describe('libGD.js', function () {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gd.EditorSettings', () => {
|
||||
it('can store anything', () => {
|
||||
const element = gd.Serializer.fromJSObject({
|
||||
test: 1,
|
||||
anything: {
|
||||
canBeStored: true,
|
||||
},
|
||||
});
|
||||
|
||||
const editorSettings = new gd.EditorSettings();
|
||||
editorSettings.unserializeFrom(element);
|
||||
|
||||
const element2 = new gd.SerializerElement();
|
||||
editorSettings.serializeTo(element2);
|
||||
|
||||
expect(element2.getChild('test').getIntValue()).toBe(1);
|
||||
expect(
|
||||
element2.getChild('anything').getChild('canBeStored').getBoolValue()
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -15,6 +15,10 @@ declare class gdBehaviorMetadata {
|
||||
addStrExpression(name: string, fullname: string, description: string, group: string, smallicon: string): gdExpressionMetadata;
|
||||
addExpressionAndCondition(type: string, name: string, fullname: string, description: string, sentenceName: string, group: string, icon: string): gdMultipleInstructionMetadata;
|
||||
addExpressionAndConditionAndAction(type: string, name: string, fullname: string, description: string, sentenceName: string, group: string, icon: string): gdMultipleInstructionMetadata;
|
||||
addDuplicatedAction(newActionName: string, copiedActionName: string): gdInstructionMetadata;
|
||||
addDuplicatedCondition(newConditionName: string, copiedConditionName: string): gdInstructionMetadata;
|
||||
addDuplicatedExpression(newExpressionName: string, copiedExpressionName: string): gdExpressionMetadata;
|
||||
addDuplicatedStrExpression(newExpressionName: string, copiedExpressionName: string): gdExpressionMetadata;
|
||||
setIncludeFile(includeFile: string): gdBehaviorMetadata;
|
||||
addIncludeFile(includeFile: string): gdBehaviorMetadata;
|
||||
setObjectType(objectType: string): gdBehaviorMetadata;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdLayoutEditorCanvasOptions {
|
||||
declare class gdEditorSettings {
|
||||
constructor(): void;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
@@ -6,7 +6,7 @@ declare class gdExternalLayout {
|
||||
setAssociatedLayout(name: string): void;
|
||||
getAssociatedLayout(): string;
|
||||
getInitialInstances(): gdInitialInstancesContainer;
|
||||
getAssociatedSettings(): gdLayoutEditorCanvasOptions;
|
||||
getAssociatedEditorSettings(): gdEditorSettings;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
|
@@ -23,6 +23,7 @@ declare class gdInstructionMetadata {
|
||||
addCodeOnlyParameter(type: string, supplementaryInformation: string): gdInstructionMetadata;
|
||||
setDefaultValue(defaultValue: string): gdInstructionMetadata;
|
||||
setParameterLongDescription(longDescription: string): gdInstructionMetadata;
|
||||
setParameterExtraInfo(extraInfo: string): gdInstructionMetadata;
|
||||
useStandardOperatorParameters(type: string): gdInstructionMetadata;
|
||||
useStandardRelationalOperatorParameters(type: string): gdInstructionMetadata;
|
||||
markAsSimple(): gdInstructionMetadata;
|
||||
|
@@ -14,6 +14,8 @@ declare class gdLayer {
|
||||
getAmbientLightColorGreen(): number;
|
||||
getAmbientLightColorBlue(): number;
|
||||
getEffects(): gdEffectsContainer;
|
||||
getCameraCount(): number;
|
||||
setCameraCount(cameraCount: number): void;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
|
@@ -27,7 +27,7 @@ declare class gdLayout extends gdObjectsContainer {
|
||||
moveLayer(oldIndex: number, newIndex: number): void;
|
||||
serializeLayersTo(element: gdSerializerElement): void;
|
||||
unserializeLayersFrom(element: gdSerializerElement): void;
|
||||
getAssociatedSettings(): gdLayoutEditorCanvasOptions;
|
||||
getAssociatedEditorSettings(): gdEditorSettings;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
setStopSoundsOnStartup(enable: boolean): void;
|
||||
|
@@ -1,8 +1,34 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdLoadingScreen {
|
||||
constructor(): void;
|
||||
showGDevelopSplash(show: boolean): void;
|
||||
isGDevelopSplashShown(): boolean;
|
||||
showGDevelopSplash(show: boolean): void;
|
||||
getGDevelopLogoStyle(): string;
|
||||
setGDevelopLogoStyle(value: string): gdLoadingScreen;
|
||||
getBackgroundImageResourceName(): string;
|
||||
setBackgroundImageResourceName(value: string): gdLoadingScreen;
|
||||
getBackgroundColor(): number;
|
||||
setBackgroundColor(value: number): gdLoadingScreen;
|
||||
getBackgroundFadeInDuration(): number;
|
||||
setBackgroundFadeInDuration(value: number): gdLoadingScreen;
|
||||
getMinDuration(): number;
|
||||
setMinDuration(value: number): gdLoadingScreen;
|
||||
getLogoAndProgressFadeInDuration(): number;
|
||||
setLogoAndProgressFadeInDuration(value: number): gdLoadingScreen;
|
||||
getLogoAndProgressLogoFadeInDelay(): number;
|
||||
setLogoAndProgressLogoFadeInDelay(value: number): gdLoadingScreen;
|
||||
getShowProgressBar(): boolean;
|
||||
setShowProgressBar(value: boolean): gdLoadingScreen;
|
||||
getProgressBarMaxWidth(): number;
|
||||
setProgressBarMaxWidth(value: number): gdLoadingScreen;
|
||||
getProgressBarMinWidth(): number;
|
||||
setProgressBarMinWidth(value: number): gdLoadingScreen;
|
||||
getProgressBarWidthPercent(): number;
|
||||
setProgressBarWidthPercent(value: number): gdLoadingScreen;
|
||||
getProgressBarHeight(): number;
|
||||
setProgressBarHeight(value: number): gdLoadingScreen;
|
||||
getProgressBarColor(): number;
|
||||
setProgressBarColor(value: number): gdLoadingScreen;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
|
@@ -6,6 +6,7 @@ declare class gdPreviewExportOptions {
|
||||
setExternalLayoutName(externalLayoutName: string): gdPreviewExportOptions;
|
||||
setIncludeFileHash(includeFile: string, hash: number): gdPreviewExportOptions;
|
||||
setProjectDataOnlyExport(enable: boolean): gdPreviewExportOptions;
|
||||
setFullLoadingScreen(enable: boolean): gdPreviewExportOptions;
|
||||
setNonRuntimeScriptsCacheBurst(value: number): gdPreviewExportOptions;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
|
@@ -176,7 +176,7 @@ declare class libGDevelop {
|
||||
ResourcesRenamer: Class<gdResourcesRenamer>;
|
||||
ProjectResourcesCopier: Class<gdProjectResourcesCopier>;
|
||||
ResourcesInUseHelper: Class<gdResourcesInUseHelper>;
|
||||
LayoutEditorCanvasOptions: Class<gdLayoutEditorCanvasOptions>;
|
||||
EditorSettings: Class<gdEditorSettings>;
|
||||
Point: Class<gdPoint>;
|
||||
VectorPoint: Class<gdVectorPoint>;
|
||||
Polygon2d: Class<gdPolygon2d>;
|
||||
|
@@ -13,7 +13,7 @@ GDevelop is a full-featured, open-source game development software, allowing to
|
||||
| Create/improve an extension | Download [Node.js] and follow this [README](newIDE/README-extensions.md). |
|
||||
| Help to translate GDevelop | Go on the [GDevelop project on Crowdin](https://crowdin.com/project/gdevelop). |
|
||||
|
||||
> Are you interested in contributing to GDevelop for the first time? Or want to participate in [Google Summer of Code 2021](https://summerofcode.withgoogle.com/organizations/5586892420022272/)? Take a look at the list of **[good first issues](https://github.com/4ian/GDevelop/issues?q=is%3Aissue+is%3Aopen+label%3A%22%F0%9F%91%8Cgood+first+issue%22)**, **[good first contributions](https://github.com/4ian/GDevelop/discussions/categories/good-first-contribution)** or the **["🏐 not too hard" cards](https://trello.com/b/qf0lM7k8/gdevelop-roadmap?menu=filter&filter=label:Not%20too%20hard%20%E2%9A%BD%EF%B8%8F)** on the Roadmap.
|
||||
> Are you interested in contributing to GDevelop for the first time? Take a look at the list of **[good first issues](https://github.com/4ian/GDevelop/issues?q=is%3Aissue+is%3Aopen+label%3A%22%F0%9F%91%8Cgood+first+issue%22)**, **[good first contributions](https://github.com/4ian/GDevelop/discussions/categories/good-first-contribution)** or the **["🏐 not too hard" cards](https://trello.com/b/qf0lM7k8/gdevelop-roadmap?menu=filter&filter=label:Not%20too%20hard%20%E2%9A%BD%EF%B8%8F)** on the Roadmap.
|
||||
|
||||
## Overview of the architecture
|
||||
|
||||
@@ -30,7 +30,7 @@ To learn more about GDevelop Architecture, read the [architecture overview here]
|
||||
|
||||
Pre-generated documentation of the Core library, C++ and TypeScript game engines is [available here](https://docs.gdevelop-app.com).
|
||||
|
||||
Status of the tests and builds: [](https://app.circleci.com/pipelines/github/4ian/GDevelop) [](https://semaphoreci.com/4ian/gd) [](https://www.travis-ci.com/github/4ian/GDevelop) [](https://ci.appveyor.com/project/4ian/gdevelop/branch/master) [](https://good-labs.github.io/greater-good-affirmation)
|
||||
Status of the tests and builds: [](https://app.circleci.com/pipelines/github/4ian/GDevelop) [](https://semaphoreci.com/4ian/gd) [](https://www.travis-ci.com/github/4ian/GDevelop) [](https://ci.appveyor.com/project/4ian/gdevelop/branch/master) [](https://good-labs.github.io/greater-good-affirmation)
|
||||
|
||||
## Links
|
||||
|
||||
@@ -63,5 +63,3 @@ Status of the tests and builds: [: these engines are distributed under the MIT license so that you can **distribute, sell or do anything** with the games you created with GDevelop. In particular, you are not forced to make your game open source.
|
||||
|
||||
[node.js]: https://nodejs.org
|
||||
[cmake]: http://www.cmake.org/
|
||||
[ninja]: http://martine.github.io/ninja/
|
||||
|
53
appveyor.yml
53
appveyor.yml
@@ -1,13 +1,22 @@
|
||||
# AppVeyor configuration to build GDevelop app running
|
||||
# on the Electron runtime (newIDE/electron-app) for Windows.
|
||||
# For macOS and Linux, see the config.yml file.
|
||||
|
||||
version: 1.0.{build}
|
||||
pull_requests:
|
||||
do_not_increment_build_number: true
|
||||
image: Visual Studio 2019
|
||||
clone_depth: 5
|
||||
# Only build
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /experimental-build.*/
|
||||
init:
|
||||
- ps: ''
|
||||
install:
|
||||
- ps: Install-Product node 10
|
||||
build_script:
|
||||
- ps: Install-Product node 14
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
- cmd: >-
|
||||
cd GDevelop.js
|
||||
|
||||
@@ -29,21 +38,34 @@ build_script:
|
||||
|
||||
cd ..
|
||||
|
||||
# Build GDevelop IDE
|
||||
- cmd: >-
|
||||
cd newIDE\app
|
||||
|
||||
npm install
|
||||
|
||||
cd ..\..
|
||||
|
||||
cd GDJS
|
||||
|
||||
npm install
|
||||
|
||||
cd tests
|
||||
cd ..\electron-app
|
||||
|
||||
npm install
|
||||
|
||||
cd ..\..
|
||||
|
||||
# Package the app for Windows.
|
||||
build_script:
|
||||
- cmd: >-
|
||||
cd newIDE\electron-app
|
||||
|
||||
node --max-old-space-size=3072 scripts/build.js --win appx --publish=never
|
||||
|
||||
node scripts/build.js --skip-app-build --win nsis --publish=never
|
||||
|
||||
cd ..\..
|
||||
|
||||
# Clean dist folder to keep only installers/binaries.
|
||||
- cmd: >-
|
||||
DEL /F/Q/S newIDE\electron-app\dist\win-unpacked
|
||||
|
||||
# Run a few tests on Windows.
|
||||
test_script:
|
||||
- cmd: >-
|
||||
cd GDevelop.js
|
||||
@@ -57,5 +79,14 @@ test_script:
|
||||
npm test
|
||||
|
||||
cd ..\..
|
||||
on_finish:
|
||||
- ps: ''
|
||||
|
||||
artifacts:
|
||||
- path: newIDE\electron-app\dist
|
||||
name: GDevelopWindows
|
||||
|
||||
# Upload artifacts (AWS) - configuration is stored on AppVeyor itself.
|
||||
deploy:
|
||||
- provider: Environment
|
||||
name: Amazon S3 releases
|
||||
- provider: Environment
|
||||
name: Amazon S3 latest releases
|
||||
|
@@ -134,7 +134,7 @@ cd newIDE/web-app
|
||||
yarn deploy # or npm run deploy
|
||||
```
|
||||
|
||||
> Note: this will also upload the game engine (GDJS) and extension sources, needed by the IDE and purge the CloudFlare cache. If examples have been added/changed, be also sure to run `newIDE/web-app/scripts/deploy-examples-resources.js`.
|
||||
> Note: this will also upload the game engine (GDJS) and extension sources, needed by the IDE and purge the CloudFlare cache.
|
||||
|
||||
### (Optional) Updating translations
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
<head>
|
||||
<title>GDevelop Jfxr Editor</title>
|
||||
<link rel="stylesheet" type="text/css" href="gdide://external/utils/path-editor.css">
|
||||
<link rel="stylesheet" type="text/css" href="jfxr-style.css">
|
||||
</head>
|
||||
|
||||
@@ -11,4 +12,4 @@
|
||||
<script type="module" src="gdide://external/jfxr/jfxr-main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
51
newIDE/app/public/external/jfxr/jfxr-style.css
vendored
51
newIDE/app/public/external/jfxr/jfxr-style.css
vendored
@@ -17,54 +17,3 @@ body {
|
||||
border: none;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#path-editor-header .leftSide {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#path-editor-header > span > * {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > label {
|
||||
height: 27px;
|
||||
color: aqua;
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons {
|
||||
display: flex;
|
||||
padding-bottom: 4px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons > button {
|
||||
right: 0;
|
||||
margin-right: 4px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > button,
|
||||
#path-editor-header > span > button {
|
||||
background-color: whitesmoke;
|
||||
border: 2px solid lightblue;
|
||||
border-radius: 3px;
|
||||
max-height: 30px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > input {
|
||||
font-family: 'Courier New';
|
||||
height: 27px;
|
||||
width: 90px;
|
||||
float: left;
|
||||
padding: 4px;
|
||||
margin-top: 4px;
|
||||
font-size: 15px;
|
||||
border: 2px solid #e5cd50;
|
||||
border-radius: 3px;
|
||||
background-color: black;
|
||||
color: #e5cd50;
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
<head>
|
||||
<title>GDevelop Piskel Editor</title>
|
||||
<link rel="stylesheet" type="text/css" href="gdide://external/utils/path-editor.css">
|
||||
<link rel="stylesheet" type="text/css" href="piskel-style.css">
|
||||
</head>
|
||||
|
||||
@@ -11,4 +12,4 @@
|
||||
<script type="module" src="gdide://external/piskel/piskel-main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
@@ -16,54 +16,3 @@ body {
|
||||
border: none;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#path-editor-header .leftSide {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#path-editor-header > span > * {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > label {
|
||||
height: 27px;
|
||||
color: aqua;
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons {
|
||||
display: flex;
|
||||
padding-bottom: 4px;
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons > button {
|
||||
right: 0;
|
||||
margin-right: 4px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > button,
|
||||
#path-editor-header > span > button {
|
||||
background-color: whitesmoke;
|
||||
border: 2px solid lightblue;
|
||||
border-radius: 3px;
|
||||
max-height: 30px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > input {
|
||||
font-family: 'Courier New';
|
||||
height: 27px;
|
||||
width: 90px;
|
||||
float: left;
|
||||
padding: 4px;
|
||||
margin-top: 4px;
|
||||
font-size: 15px;
|
||||
border: 2px solid #e5cd50;
|
||||
border-radius: 3px;
|
||||
background-color: black;
|
||||
color: #e5cd50;
|
||||
}
|
||||
|
54
newIDE/app/public/external/utils/path-editor.css
vendored
Normal file
54
newIDE/app/public/external/utils/path-editor.css
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Shared PathEditor styles
|
||||
*/
|
||||
|
||||
#path-editor-header .leftSide {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#path-editor-header > span > * {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > label {
|
||||
height: 27px;
|
||||
color: aqua;
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons {
|
||||
display: flex;
|
||||
padding-bottom: 4px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons > button {
|
||||
right: 0;
|
||||
margin-right: 4px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > button,
|
||||
#path-editor-header > span > button {
|
||||
background-color: whitesmoke;
|
||||
border: 2px solid lightblue;
|
||||
border-radius: 3px;
|
||||
max-height: 30px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > input {
|
||||
font-family: 'Courier New';
|
||||
height: 27px;
|
||||
width: 90px;
|
||||
float: left;
|
||||
padding: 4px;
|
||||
margin-top: 4px;
|
||||
font-size: 15px;
|
||||
border: 2px solid #e5cd50;
|
||||
border-radius: 3px;
|
||||
background-color: black;
|
||||
color: #e5cd50;
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>GDevelop Dialogue Tree Editor (Yarn)</title>
|
||||
<link rel="stylesheet" type="text/css" href="gdide://external/utils/path-editor.css">
|
||||
<link rel="stylesheet" type="text/css" href="yarn-style.css" />
|
||||
</head>
|
||||
|
||||
|
29
newIDE/app/public/external/yarn/yarn-style.css
vendored
29
newIDE/app/public/external/yarn/yarn-style.css
vendored
@@ -17,31 +17,6 @@ body {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#path-editor-header .leftSide {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons {
|
||||
display: flex;
|
||||
padding-bottom: 4px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#path-editor-header .rightButtons > button {
|
||||
right: 0;
|
||||
margin-right: 4px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > button,
|
||||
#path-editor-header > span > button {
|
||||
background-color: white;
|
||||
border: 2px solid lightblue;
|
||||
border-radius: 3px;
|
||||
max-height: 30px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > input {
|
||||
font-family: 'Courier New';
|
||||
height: 27px;
|
||||
@@ -63,7 +38,3 @@ body {
|
||||
margin-top: 10px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#path-editor-header > span > * {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
@@ -1,6 +1,10 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { type AssetShortHeader } from '../Utils/GDevelopServices/Asset';
|
||||
import {
|
||||
type AssetShortHeader,
|
||||
isPixelArt,
|
||||
} from '../Utils/GDevelopServices/Asset';
|
||||
import { getPixelatedImageRendering } from '../Utils/CssHelpers';
|
||||
import ButtonBase from '@material-ui/core/ButtonBase';
|
||||
import Text from '../UI/Text';
|
||||
import { CorsAwareImage } from '../UI/CorsAwareImage';
|
||||
@@ -19,6 +23,11 @@ const styles = {
|
||||
verticalAlign: 'middle',
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
previewImagePixelated: {
|
||||
width: '100%',
|
||||
imageRendering: getPixelatedImageRendering(),
|
||||
padding: 15,
|
||||
},
|
||||
icon: {
|
||||
color: '#fff',
|
||||
},
|
||||
@@ -60,9 +69,12 @@ export const AssetCard = ({ assetShortHeader, onOpenDetails, size }: Props) => {
|
||||
<CorsAwareImage
|
||||
key={assetShortHeader.previewImageUrls[0]}
|
||||
style={{
|
||||
...styles.previewImage,
|
||||
maxWidth: 128 - 2 * paddingSize,
|
||||
maxHeight: 128 - 2 * paddingSize,
|
||||
...styles.previewImage,
|
||||
...(isPixelArt(assetShortHeader)
|
||||
? styles.previewImagePixelated
|
||||
: undefined),
|
||||
}}
|
||||
src={assetShortHeader.previewImageUrls[0]}
|
||||
alt={assetShortHeader.name}
|
||||
|
@@ -10,7 +10,9 @@ import {
|
||||
type Asset,
|
||||
type Author,
|
||||
getAsset,
|
||||
isPixelArt,
|
||||
} from '../Utils/GDevelopServices/Asset';
|
||||
import { getPixelatedImageRendering } from '../Utils/CssHelpers';
|
||||
import LeftLoader from '../UI/LeftLoader';
|
||||
import PlaceholderLoader from '../UI/PlaceholderLoader';
|
||||
import PlaceholderError from '../UI/PlaceholderError';
|
||||
@@ -31,6 +33,11 @@ import Window from '../Utils/Window';
|
||||
import CheckeredBackground from '../ResourcesList/CheckeredBackground';
|
||||
|
||||
const styles = {
|
||||
previewImagePixelated: {
|
||||
width: '100%',
|
||||
imageRendering: getPixelatedImageRendering(),
|
||||
padding: 15,
|
||||
},
|
||||
previewBackground: {
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
@@ -159,7 +166,12 @@ export const AssetDetails = ({
|
||||
>
|
||||
<CheckeredBackground />
|
||||
<CorsAwareImage
|
||||
style={styles.previewImage}
|
||||
style={{
|
||||
...styles.previewImage,
|
||||
...(isPixelArt(assetShortHeader)
|
||||
? styles.previewImagePixelated
|
||||
: undefined),
|
||||
}}
|
||||
src={assetShortHeader.previewImageUrls[0]}
|
||||
alt={assetShortHeader.name}
|
||||
/>
|
||||
|
@@ -106,6 +106,7 @@ export const ExtensionStore = ({
|
||||
getSearchItemUniqueId={getExtensionName}
|
||||
renderSearchItem={(extensionShortHeader, onHeightComputed) => (
|
||||
<ExtensionListItem
|
||||
key={extensionShortHeader.name}
|
||||
project={project}
|
||||
onHeightComputed={onHeightComputed}
|
||||
extensionShortHeader={extensionShortHeader}
|
||||
|
@@ -19,6 +19,7 @@ export type CommandName =
|
||||
| 'OPEN_RECENT_PROJECT'
|
||||
| 'OPEN_COMMAND_PALETTE'
|
||||
| 'OPEN_PROJECT_PROPERTIES'
|
||||
| 'OPEN_PROJECT_LOADING_SCREEN'
|
||||
| 'OPEN_PROJECT_VARIABLES'
|
||||
| 'OPEN_PLATFORM_SPECIFIC_ASSETS_DIALOG'
|
||||
| 'OPEN_PROJECT_RESOURCES'
|
||||
@@ -154,6 +155,10 @@ const commandsList: { [CommandName]: CommandMetadata } = {
|
||||
area: 'PROJECT',
|
||||
displayText: t`Open project properties`,
|
||||
},
|
||||
OPEN_PROJECT_LOADING_SCREEN: {
|
||||
area: 'PROJECT',
|
||||
displayText: t`Edit loading screen`,
|
||||
},
|
||||
OPEN_PROJECT_VARIABLES: {
|
||||
area: 'PROJECT',
|
||||
displayText: t`Edit global variables`,
|
||||
|
@@ -81,7 +81,6 @@ type Props = {|
|
||||
|};
|
||||
|
||||
const iconSize = 24;
|
||||
const minHeight = 400; // Avoid a super small list in empty scenes. 400 is enough to be displayed on an iPhone SE.
|
||||
|
||||
export default class InstructionOrObjectSelector extends React.PureComponent<
|
||||
Props,
|
||||
@@ -232,7 +231,7 @@ export default class InstructionOrObjectSelector extends React.PureComponent<
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: muiTheme.list.itemsBackgroundColor,
|
||||
minHeight,
|
||||
minHeight: 0,
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
@@ -277,12 +276,7 @@ export default class InstructionOrObjectSelector extends React.PureComponent<
|
||||
/>
|
||||
</Tabs>
|
||||
)}
|
||||
<ScrollView
|
||||
ref={
|
||||
// $FlowFixMe - improper typing of ScrollView?
|
||||
this._scrollView
|
||||
}
|
||||
>
|
||||
<ScrollView ref={this._scrollView}>
|
||||
{!isSearching && currentTab === 'objects' && (
|
||||
<TagChips
|
||||
tags={selectedObjectTags}
|
||||
|
@@ -15,7 +15,7 @@ import {
|
||||
type ChooseResourceFunction,
|
||||
} from '../../ResourcesList/ResourceSource.flow';
|
||||
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
|
||||
import { Line, Spacer } from '../../UI/Grid';
|
||||
import { Column, Line, Spacer } from '../../UI/Grid';
|
||||
import AlertMessage from '../../UI/AlertMessage';
|
||||
import DismissableAlertMessage from '../../UI/DismissableAlertMessage';
|
||||
import Window from '../../Utils/Window';
|
||||
@@ -33,15 +33,10 @@ import Text from '../../UI/Text';
|
||||
import { getInstructionMetadata } from './NewInstructionEditor';
|
||||
import { ColumnStackLayout } from '../../UI/Layout';
|
||||
import { setupInstructionParameters } from '../../InstructionOrExpression/SetupInstructionParameters';
|
||||
import ScrollView from '../../UI/ScrollView';
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
const styles = {
|
||||
// When displaying parameters, take all the height:
|
||||
container: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
},
|
||||
// When displaying the empty message, center the message:
|
||||
emptyContainer: {
|
||||
display: 'flex',
|
||||
@@ -50,7 +45,6 @@ const styles = {
|
||||
},
|
||||
parametersContainer: {
|
||||
flex: 1,
|
||||
overflowY: 'auto',
|
||||
},
|
||||
icon: {
|
||||
width: 24,
|
||||
@@ -245,150 +239,154 @@ export default class InstructionParametersEditor extends React.Component<
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<div style={styles.container}>
|
||||
<Line alignItems="flex-start">
|
||||
<img
|
||||
src={instructionMetadata.getIconFilename()}
|
||||
alt=""
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text style={styles.description}>
|
||||
{instructionMetadata.getDescription()}
|
||||
</Text>
|
||||
{isAnEventFunctionMetadata(instructionMetadata) && (
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
this._openExtension(i18n);
|
||||
}}
|
||||
>
|
||||
<OpenInNew />
|
||||
</IconButton>
|
||||
)}
|
||||
</Line>
|
||||
{instructionExtraInformation && (
|
||||
<Line>
|
||||
{instructionExtraInformation.identifier === undefined ? (
|
||||
<AlertMessage kind={instructionExtraInformation.kind}>
|
||||
{i18n._(instructionExtraInformation.message)}
|
||||
</AlertMessage>
|
||||
) : (
|
||||
<DismissableAlertMessage
|
||||
kind={instructionExtraInformation.kind}
|
||||
identifier={instructionExtraInformation.identifier}
|
||||
<ScrollView autoHideScrollbar>
|
||||
<Column expand>
|
||||
<Line alignItems="flex-start">
|
||||
<img
|
||||
src={instructionMetadata.getIconFilename()}
|
||||
alt=""
|
||||
style={styles.icon}
|
||||
/>
|
||||
<Text style={styles.description}>
|
||||
{instructionMetadata.getDescription()}
|
||||
</Text>
|
||||
{isAnEventFunctionMetadata(instructionMetadata) && (
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
this._openExtension(i18n);
|
||||
}}
|
||||
>
|
||||
{i18n._(instructionExtraInformation.message)}
|
||||
</DismissableAlertMessage>
|
||||
<OpenInNew />
|
||||
</IconButton>
|
||||
)}
|
||||
</Line>
|
||||
)}
|
||||
{tutorialHints.length ? (
|
||||
<Line>
|
||||
<ColumnStackLayout expand>
|
||||
{tutorialHints.map(tutorialHint => (
|
||||
<DismissableTutorialMessage
|
||||
key={tutorialHint.identifier}
|
||||
tutorialHint={tutorialHint}
|
||||
/>
|
||||
))}
|
||||
{instructionExtraInformation && (
|
||||
<Line>
|
||||
{instructionExtraInformation.identifier === undefined ? (
|
||||
<AlertMessage kind={instructionExtraInformation.kind}>
|
||||
{i18n._(instructionExtraInformation.message)}
|
||||
</AlertMessage>
|
||||
) : (
|
||||
<DismissableAlertMessage
|
||||
kind={instructionExtraInformation.kind}
|
||||
identifier={instructionExtraInformation.identifier}
|
||||
>
|
||||
{i18n._(instructionExtraInformation.message)}
|
||||
</DismissableAlertMessage>
|
||||
)}
|
||||
</Line>
|
||||
)}
|
||||
{tutorialHints.length ? (
|
||||
<Line>
|
||||
<ColumnStackLayout expand>
|
||||
{tutorialHints.map(tutorialHint => (
|
||||
<DismissableTutorialMessage
|
||||
key={tutorialHint.identifier}
|
||||
tutorialHint={tutorialHint}
|
||||
/>
|
||||
))}
|
||||
</ColumnStackLayout>
|
||||
</Line>
|
||||
) : null}
|
||||
<Spacer />
|
||||
<div key={instructionType} style={styles.parametersContainer}>
|
||||
<ColumnStackLayout noMargin>
|
||||
{mapFor(0, instructionMetadata.getParametersCount(), i => {
|
||||
const parameterMetadata = instructionMetadata.getParameter(
|
||||
i
|
||||
);
|
||||
if (
|
||||
!isParameterVisible(
|
||||
parameterMetadata,
|
||||
i,
|
||||
objectParameterIndex
|
||||
)
|
||||
)
|
||||
return null;
|
||||
|
||||
const parameterMetadataType = parameterMetadata.getType();
|
||||
const ParameterComponent = ParameterRenderingService.getParameterComponent(
|
||||
parameterMetadataType
|
||||
);
|
||||
|
||||
// Track the field count on screen, to affect the ref to the
|
||||
// first visible field.
|
||||
const isFirstVisibleParameterField =
|
||||
parameterFieldIndex === 0;
|
||||
parameterFieldIndex++;
|
||||
|
||||
return (
|
||||
<ParameterComponent
|
||||
instructionMetadata={instructionMetadata}
|
||||
instruction={instruction}
|
||||
parameterMetadata={parameterMetadata}
|
||||
parameterIndex={i}
|
||||
value={instruction.getParameter(i)}
|
||||
onChange={value => {
|
||||
if (instruction.getParameter(i) !== value) {
|
||||
instruction.setParameter(i, value);
|
||||
this.setState({
|
||||
isDirty: true,
|
||||
});
|
||||
}
|
||||
}}
|
||||
project={project}
|
||||
scope={scope}
|
||||
globalObjectsContainer={globalObjectsContainer}
|
||||
objectsContainer={objectsContainer}
|
||||
key={i}
|
||||
parameterRenderingService={ParameterRenderingService}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
resourceExternalEditors={
|
||||
this.props.resourceExternalEditors
|
||||
}
|
||||
ref={field => {
|
||||
if (isFirstVisibleParameterField) {
|
||||
this._firstVisibleField = field;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ColumnStackLayout>
|
||||
{this._getVisibleParametersCount(
|
||||
instructionMetadata,
|
||||
objectName
|
||||
) === 0 && (
|
||||
<EmptyMessage>
|
||||
<Trans>There is nothing to configure.</Trans>
|
||||
</EmptyMessage>
|
||||
)}
|
||||
{this.props.isCondition && (
|
||||
<Toggle
|
||||
label={<Trans>Invert condition</Trans>}
|
||||
labelPosition="right"
|
||||
toggled={instruction.isInverted()}
|
||||
style={styles.invertToggle}
|
||||
onToggle={(e, enabled) => {
|
||||
instruction.setInverted(enabled);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<Line>
|
||||
{!noHelpButton && helpPage && (
|
||||
<HelpButton
|
||||
helpPagePath={instructionMetadata.getHelpPath()}
|
||||
label={
|
||||
this.props.isCondition ? (
|
||||
<Trans>Help for this condition</Trans>
|
||||
) : (
|
||||
<Trans>Help for this action</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Line>
|
||||
) : null}
|
||||
<Spacer />
|
||||
<div key={instructionType} style={styles.parametersContainer}>
|
||||
<ColumnStackLayout noMargin>
|
||||
{mapFor(0, instructionMetadata.getParametersCount(), i => {
|
||||
const parameterMetadata = instructionMetadata.getParameter(i);
|
||||
if (
|
||||
!isParameterVisible(
|
||||
parameterMetadata,
|
||||
i,
|
||||
objectParameterIndex
|
||||
)
|
||||
)
|
||||
return null;
|
||||
|
||||
const parameterMetadataType = parameterMetadata.getType();
|
||||
const ParameterComponent = ParameterRenderingService.getParameterComponent(
|
||||
parameterMetadataType
|
||||
);
|
||||
|
||||
// Track the field count on screen, to affect the ref to the
|
||||
// first visible field.
|
||||
const isFirstVisibleParameterField =
|
||||
parameterFieldIndex === 0;
|
||||
parameterFieldIndex++;
|
||||
|
||||
return (
|
||||
<ParameterComponent
|
||||
instructionMetadata={instructionMetadata}
|
||||
instruction={instruction}
|
||||
parameterMetadata={parameterMetadata}
|
||||
parameterIndex={i}
|
||||
value={instruction.getParameter(i)}
|
||||
onChange={value => {
|
||||
if (instruction.getParameter(i) !== value) {
|
||||
instruction.setParameter(i, value);
|
||||
this.setState({
|
||||
isDirty: true,
|
||||
});
|
||||
}
|
||||
}}
|
||||
project={project}
|
||||
scope={scope}
|
||||
globalObjectsContainer={globalObjectsContainer}
|
||||
objectsContainer={objectsContainer}
|
||||
key={i}
|
||||
parameterRenderingService={ParameterRenderingService}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
resourceExternalEditors={
|
||||
this.props.resourceExternalEditors
|
||||
}
|
||||
ref={field => {
|
||||
if (isFirstVisibleParameterField) {
|
||||
this._firstVisibleField = field;
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ColumnStackLayout>
|
||||
{this._getVisibleParametersCount(
|
||||
instructionMetadata,
|
||||
objectName
|
||||
) === 0 && (
|
||||
<EmptyMessage>
|
||||
<Trans>There is nothing to configure.</Trans>
|
||||
</EmptyMessage>
|
||||
)}
|
||||
{this.props.isCondition && (
|
||||
<Toggle
|
||||
label={<Trans>Invert condition</Trans>}
|
||||
labelPosition="right"
|
||||
toggled={instruction.isInverted()}
|
||||
style={styles.invertToggle}
|
||||
onToggle={(e, enabled) => {
|
||||
instruction.setInverted(enabled);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<Line>
|
||||
{!noHelpButton && helpPage && (
|
||||
<HelpButton
|
||||
helpPagePath={instructionMetadata.getHelpPath()}
|
||||
label={
|
||||
this.props.isCondition ? (
|
||||
<Trans>Help for this condition</Trans>
|
||||
) : (
|
||||
<Trans>Help for this action</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Line>
|
||||
</div>
|
||||
</Column>
|
||||
</ScrollView>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
|
@@ -13,10 +13,8 @@ import InstructionParametersEditor from './InstructionParametersEditor';
|
||||
import InstructionOrObjectSelector, {
|
||||
type TabName,
|
||||
} from './InstructionOrObjectSelector';
|
||||
import { Column } from '../../UI/Grid';
|
||||
import InstructionOrExpressionSelector from './InstructionOrExpressionSelector';
|
||||
import HelpButton from '../../UI/HelpButton';
|
||||
import Background from '../../UI/Background';
|
||||
import { type EventsScope } from '../../InstructionOrExpression/EventsScope.flow';
|
||||
import { SelectColumns } from '../../UI/Reponsive/SelectColumns';
|
||||
import {
|
||||
@@ -172,51 +170,49 @@ export default function NewInstructionEditorDialog({
|
||||
: undefined;
|
||||
|
||||
const renderInstructionOrObjectSelector = () => (
|
||||
<Background noFullHeight key="instruction-or-object-selector">
|
||||
<InstructionOrObjectSelector
|
||||
style={styles.fullHeightSelector}
|
||||
project={project}
|
||||
scope={scope}
|
||||
currentTab={currentInstructionOrObjectSelectorTab}
|
||||
onChangeTab={setCurrentInstructionOrObjectSelectorTab}
|
||||
globalObjectsContainer={globalObjectsContainer}
|
||||
objectsContainer={objectsContainer}
|
||||
isCondition={isCondition}
|
||||
chosenInstructionType={!chosenObjectName ? instructionType : undefined}
|
||||
onChooseInstruction={(instructionType: string) => {
|
||||
chooseInstruction(instructionType);
|
||||
setStep('parameters');
|
||||
}}
|
||||
chosenObjectName={chosenObjectName}
|
||||
onChooseObject={(chosenObjectName: string) => {
|
||||
chooseObject(chosenObjectName);
|
||||
setStep('object-instructions');
|
||||
}}
|
||||
focusOnMount={!instructionType}
|
||||
onSearchStartOrReset={forceUpdate}
|
||||
/>
|
||||
</Background>
|
||||
<InstructionOrObjectSelector
|
||||
key="instruction-or-object-selector"
|
||||
style={styles.fullHeightSelector}
|
||||
project={project}
|
||||
scope={scope}
|
||||
currentTab={currentInstructionOrObjectSelectorTab}
|
||||
onChangeTab={setCurrentInstructionOrObjectSelectorTab}
|
||||
globalObjectsContainer={globalObjectsContainer}
|
||||
objectsContainer={objectsContainer}
|
||||
isCondition={isCondition}
|
||||
chosenInstructionType={!chosenObjectName ? instructionType : undefined}
|
||||
onChooseInstruction={(instructionType: string) => {
|
||||
chooseInstruction(instructionType);
|
||||
setStep('parameters');
|
||||
}}
|
||||
chosenObjectName={chosenObjectName}
|
||||
onChooseObject={(chosenObjectName: string) => {
|
||||
chooseObject(chosenObjectName);
|
||||
setStep('object-instructions');
|
||||
}}
|
||||
focusOnMount={!instructionType}
|
||||
onSearchStartOrReset={forceUpdate}
|
||||
/>
|
||||
);
|
||||
|
||||
const renderParameters = () => (
|
||||
<Column expand justifyContent="center" key="parameters">
|
||||
<InstructionParametersEditor
|
||||
project={project}
|
||||
scope={scope}
|
||||
globalObjectsContainer={globalObjectsContainer}
|
||||
objectsContainer={objectsContainer}
|
||||
objectName={chosenObjectName}
|
||||
isCondition={isCondition}
|
||||
instruction={instruction}
|
||||
resourceSources={resourceSources}
|
||||
onChooseResource={onChooseResource}
|
||||
resourceExternalEditors={resourceExternalEditors}
|
||||
openInstructionOrExpression={openInstructionOrExpression}
|
||||
ref={instructionParametersEditor}
|
||||
focusOnMount={!!instructionType}
|
||||
noHelpButton
|
||||
/>
|
||||
</Column>
|
||||
<InstructionParametersEditor
|
||||
key="parameters"
|
||||
project={project}
|
||||
scope={scope}
|
||||
globalObjectsContainer={globalObjectsContainer}
|
||||
objectsContainer={objectsContainer}
|
||||
objectName={chosenObjectName}
|
||||
isCondition={isCondition}
|
||||
instruction={instruction}
|
||||
resourceSources={resourceSources}
|
||||
onChooseResource={onChooseResource}
|
||||
resourceExternalEditors={resourceExternalEditors}
|
||||
openInstructionOrExpression={openInstructionOrExpression}
|
||||
ref={instructionParametersEditor}
|
||||
focusOnMount={!!instructionType}
|
||||
noHelpButton
|
||||
/>
|
||||
);
|
||||
|
||||
const renderObjectInstructionSelector = () =>
|
||||
@@ -292,6 +288,9 @@ export default function NewInstructionEditorDialog({
|
||||
maxWidth={false}
|
||||
noMargin
|
||||
flexRowBody
|
||||
fullHeight={
|
||||
true /* Always use full height to avoid a very small dialog when there are not a lot of objects. */
|
||||
}
|
||||
>
|
||||
<SelectColumns
|
||||
columnsRenderer={{
|
||||
|
@@ -18,8 +18,6 @@ const styles = {
|
||||
parametersEditor: {
|
||||
flex: 2,
|
||||
display: 'flex',
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
zIndex: 1, // Put the Paper shadow on the type selector
|
||||
},
|
||||
};
|
||||
|
@@ -57,7 +57,11 @@ export const browserOnlineCordovaExportPipeline: ExportPipeline<
|
||||
onlineBuildType: 'cordova-build',
|
||||
packageNameWarningType: 'mobile',
|
||||
|
||||
getInitialExportState: () => ({ targets: ['androidApk'] }),
|
||||
getInitialExportState: () => ({
|
||||
targets: ['androidApk'],
|
||||
keystore: 'new',
|
||||
signingDialogOpen: false,
|
||||
}),
|
||||
|
||||
canLaunchBuild: () => true,
|
||||
|
||||
@@ -157,7 +161,8 @@ export const browserOnlineCordovaExportPipeline: ExportPipeline<
|
||||
getAuthorizationHeader,
|
||||
profile.uid,
|
||||
uploadBucketKey,
|
||||
exportState.targets
|
||||
exportState.targets,
|
||||
exportState.keystore
|
||||
);
|
||||
},
|
||||
};
|
||||
|
@@ -7,9 +7,14 @@ import { type TargetName } from '../../Utils/GDevelopServices/Build';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import Radio from '@material-ui/core/Radio';
|
||||
import RadioGroup from '@material-ui/core/RadioGroup';
|
||||
import Dialog from '../../UI/Dialog';
|
||||
import FlatButton from '../../UI/FlatButton';
|
||||
import HelpButton from '../../UI/HelpButton';
|
||||
|
||||
export type ExportState = {|
|
||||
targets: Array<TargetName>,
|
||||
keystore: 'old' | 'new',
|
||||
signingDialogOpen: boolean,
|
||||
|};
|
||||
|
||||
type HeaderProps = {|
|
||||
@@ -40,6 +45,7 @@ export const SetupExportHeader = ({
|
||||
onChange={event => {
|
||||
const targetName = event.target.value;
|
||||
updateExportState(prevExportState => ({
|
||||
...prevExportState,
|
||||
targets: [targetName],
|
||||
}));
|
||||
}}
|
||||
@@ -61,6 +67,93 @@ export const SetupExportHeader = ({
|
||||
}
|
||||
/>
|
||||
</RadioGroup>
|
||||
<Line noMargin justifyContent="flex-end">
|
||||
<FlatButton
|
||||
label={<Trans>Signing options</Trans>}
|
||||
onClick={() => {
|
||||
updateExportState(prevExportState => ({
|
||||
...prevExportState,
|
||||
signingDialogOpen: true,
|
||||
}));
|
||||
}}
|
||||
disabled={exportState.targets[0] !== 'androidAppBundle'}
|
||||
/>
|
||||
</Line>
|
||||
{exportState.signingDialogOpen && (
|
||||
<Dialog
|
||||
actions={[
|
||||
<FlatButton
|
||||
key="close"
|
||||
label={<Trans>Close</Trans>}
|
||||
primary
|
||||
keyboardFocused
|
||||
onClick={() => {
|
||||
updateExportState(prevExportState => ({
|
||||
...prevExportState,
|
||||
signingDialogOpen: false,
|
||||
}));
|
||||
}}
|
||||
/>,
|
||||
]}
|
||||
secondaryActions={[
|
||||
<HelpButton
|
||||
helpPagePath="/publishing/android_and_ios/play-store/upgrading-from-apk-to-aab"
|
||||
key="help"
|
||||
/>,
|
||||
]}
|
||||
open
|
||||
title={<Trans>Signing options</Trans>}
|
||||
onRequestClose={() => {
|
||||
updateExportState(prevExportState => ({
|
||||
...prevExportState,
|
||||
signingDialogOpen: false,
|
||||
}));
|
||||
}}
|
||||
maxWidth="sm"
|
||||
>
|
||||
<Text>
|
||||
<Trans>
|
||||
Choose the upload key to use to identify your Android App Bundle.
|
||||
In most cases you don't need to change this. Use the "Old upload
|
||||
key" if you used to publish your game as an APK and you activated
|
||||
Play App Signing before switching to Android App Bundle.
|
||||
</Trans>
|
||||
</Text>
|
||||
<RadioGroup
|
||||
name="signing-keystore"
|
||||
value={exportState.keystore}
|
||||
onChange={event => {
|
||||
const keystore = event.target.value;
|
||||
updateExportState(prevExportState => ({
|
||||
...prevExportState,
|
||||
keystore,
|
||||
}));
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
value={'new'}
|
||||
control={<Radio color="primary" />}
|
||||
label={<Trans>New upload key (recommended)</Trans>}
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={'old'}
|
||||
control={<Radio color="primary" />}
|
||||
label={
|
||||
<Trans>
|
||||
Old upload key (only if you used to publish your game as an
|
||||
APK and already activated Play App Signing)
|
||||
</Trans>
|
||||
}
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={'custom'}
|
||||
control={<Radio color="primary" />}
|
||||
label={<Trans>Custom upload key (not available yet)</Trans>}
|
||||
disabled
|
||||
/>
|
||||
</RadioGroup>
|
||||
</Dialog>
|
||||
)}
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
|
@@ -51,7 +51,11 @@ export const localOnlineCordovaExportPipeline: ExportPipeline<
|
||||
onlineBuildType: 'cordova-build',
|
||||
packageNameWarningType: 'mobile',
|
||||
|
||||
getInitialExportState: () => ({ targets: ['androidApk'] }),
|
||||
getInitialExportState: () => ({
|
||||
targets: ['androidApk'],
|
||||
keystore: 'new',
|
||||
signingDialogOpen: false,
|
||||
}),
|
||||
|
||||
canLaunchBuild: () => true,
|
||||
|
||||
@@ -144,7 +148,8 @@ export const localOnlineCordovaExportPipeline: ExportPipeline<
|
||||
getAuthorizationHeader,
|
||||
profile.uid,
|
||||
uploadBucketKey,
|
||||
exportState.targets
|
||||
exportState.targets,
|
||||
exportState.keystore
|
||||
);
|
||||
},
|
||||
};
|
||||
|
@@ -217,6 +217,10 @@ export default class LocalPreviewLauncher extends React.Component<
|
||||
shouldHotReload && previewOptions.projectDataOnlyExport
|
||||
);
|
||||
|
||||
previewExportOptions.setFullLoadingScreen(
|
||||
previewOptions.fullLoadingScreen
|
||||
);
|
||||
|
||||
exporter.exportProjectForPixiPreview(previewExportOptions);
|
||||
previewExportOptions.delete();
|
||||
exporter.delete();
|
||||
|
@@ -8,6 +8,7 @@ export type PreviewOptions = {|
|
||||
networkPreview: boolean,
|
||||
hotReload: boolean,
|
||||
projectDataOnlyExport: boolean,
|
||||
fullLoadingScreen: boolean,
|
||||
getIsMenuBarHiddenInPreview: () => boolean,
|
||||
getIsAlwaysOnTopInPreview: () => boolean,
|
||||
|};
|
||||
|
@@ -8,7 +8,7 @@ import RaisedButton from '../UI/RaisedButton';
|
||||
import { ColumnStackLayout } from '../UI/Layout';
|
||||
import Text from '../UI/Text';
|
||||
import { type HotReloaderLog } from '../Export/PreviewLauncher.flow';
|
||||
import PlayCircleFilledIcon from '@material-ui/icons/PlayCircleFilled';
|
||||
import { NewPreviewIcon } from './HotReloadPreviewButton';
|
||||
|
||||
type Props = {|
|
||||
logs: Array<HotReloaderLog>,
|
||||
@@ -40,7 +40,7 @@ export default function HotReloadLogsDialog({
|
||||
onClick={onClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
icon={<PlayCircleFilledIcon />}
|
||||
icon={<NewPreviewIcon />}
|
||||
label={<Trans>Close and launch a new preview</Trans>}
|
||||
key="new-preview"
|
||||
primary
|
||||
|
@@ -8,15 +8,19 @@ import OfflineBoltIcon from '@material-ui/icons/OfflineBolt';
|
||||
export type HotReloadPreviewButtonProps = {|
|
||||
hasPreviewsRunning: boolean,
|
||||
launchProjectDataOnlyPreview: () => void,
|
||||
launchProjectWithLoadingScreenPreview: () => void,
|
||||
|};
|
||||
|
||||
export const NewPreviewIcon = PlayCircleFilledIcon;
|
||||
export const HotReloadPreviewIcon = OfflineBoltIcon;
|
||||
|
||||
export default function HotReloadPreviewButton({
|
||||
launchProjectDataOnlyPreview,
|
||||
hasPreviewsRunning,
|
||||
}: HotReloadPreviewButtonProps) {
|
||||
return (
|
||||
<FlatButton
|
||||
icon={hasPreviewsRunning ? <OfflineBoltIcon /> : <PlayCircleFilledIcon />}
|
||||
icon={hasPreviewsRunning ? <HotReloadPreviewIcon /> : <NewPreviewIcon />}
|
||||
label={
|
||||
hasPreviewsRunning ? (
|
||||
<Trans>Apply changes to preview</Trans>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user