Compare commits
130 Commits
v5.0.0-bet
...
4.0.97
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fcfb71132c | ||
![]() |
2017d34197 | ||
![]() |
662c7bd397 | ||
![]() |
cf5011c149 | ||
![]() |
954520ae3b | ||
![]() |
6ffcd6dfb0 | ||
![]() |
80e7a6010a | ||
![]() |
0dc023ba89 | ||
![]() |
e70021d0dd | ||
![]() |
eb63bda7d2 | ||
![]() |
10833aa45d | ||
![]() |
eed844357e | ||
![]() |
6d91676dab | ||
![]() |
69410d62ea | ||
![]() |
977425e700 | ||
![]() |
49d409260a | ||
![]() |
a50b62a2d8 | ||
![]() |
6b21ebcc9b | ||
![]() |
3c8aa4a249 | ||
![]() |
a8e9fa5895 | ||
![]() |
c9f8b4a8ed | ||
![]() |
6b38479166 | ||
![]() |
4ccbc1b958 | ||
![]() |
54d7d284c8 | ||
![]() |
58ed74e020 | ||
![]() |
e8ce83b162 | ||
![]() |
9b91f06011 | ||
![]() |
17247cbbf1 | ||
![]() |
10b81dd232 | ||
![]() |
3f3a5dbd3b | ||
![]() |
6ff8ee749d | ||
![]() |
db5f146818 | ||
![]() |
b7467afd1b | ||
![]() |
ee993f0cdb | ||
![]() |
bc6d3ce16f | ||
![]() |
1fae899497 | ||
![]() |
8319f60c95 | ||
![]() |
f6fe1a3205 | ||
![]() |
01e2b53a3f | ||
![]() |
da9eb3cea7 | ||
![]() |
c044b32c04 | ||
![]() |
4936b014ae | ||
![]() |
c1cd0d8780 | ||
![]() |
e79a328748 | ||
![]() |
2083ee1029 | ||
![]() |
3e982cdd87 | ||
![]() |
883527b289 | ||
![]() |
a4d84efdd5 | ||
![]() |
e46c8493bc | ||
![]() |
4c443b09cf | ||
![]() |
98bc2236f4 | ||
![]() |
5199299639 | ||
![]() |
3268d1db25 | ||
![]() |
741770924b | ||
![]() |
49aa9469bb | ||
![]() |
7cbe34436c | ||
![]() |
122f7ecf3e | ||
![]() |
d79bdd9554 | ||
![]() |
3e331cb2e8 | ||
![]() |
361fb6aeab | ||
![]() |
b4a76895ee | ||
![]() |
b2251e1a12 | ||
![]() |
1c1860370a | ||
![]() |
1a190b2a44 | ||
![]() |
b1e0f72416 | ||
![]() |
2c4ae7573e | ||
![]() |
04ff1f2726 | ||
![]() |
eaa5200f95 | ||
![]() |
53c749b79e | ||
![]() |
eb96ee8497 | ||
![]() |
458444ee7b | ||
![]() |
c8eb13f18f | ||
![]() |
a224b93edc | ||
![]() |
f077ca6723 | ||
![]() |
6bbfa1d4a1 | ||
![]() |
3c3dc6ef6e | ||
![]() |
5c101dbcda | ||
![]() |
701b78361a | ||
![]() |
07f26027f6 | ||
![]() |
09cf13d6e2 | ||
![]() |
42f91565fa | ||
![]() |
ac6c146808 | ||
![]() |
59ad23f8ac | ||
![]() |
769c6fe3d5 | ||
![]() |
07b92911ab | ||
![]() |
eb57bcfc87 | ||
![]() |
7addeba73a | ||
![]() |
263902b45a | ||
![]() |
d283f759fe | ||
![]() |
fabd028a63 | ||
![]() |
2b18272c41 | ||
![]() |
a1fb39da3d | ||
![]() |
09602fdf9e | ||
![]() |
d574ef17ba | ||
![]() |
0e3f70627b | ||
![]() |
a814a07105 | ||
![]() |
c49af90a9c | ||
![]() |
24afa155c8 | ||
![]() |
9e5a431516 | ||
![]() |
182a94285c | ||
![]() |
442c2c8dd9 | ||
![]() |
f8fd0dd353 | ||
![]() |
faad9e23ac | ||
![]() |
d2af0da1b1 | ||
![]() |
c65e5c3e49 | ||
![]() |
24a8dfc5f0 | ||
![]() |
9c6790ac37 | ||
![]() |
18ef7460ba | ||
![]() |
63cd0e76c3 | ||
![]() |
bdbf7fd9fc | ||
![]() |
6bbedbd8f9 | ||
![]() |
648bd1ff2e | ||
![]() |
d4288caedb | ||
![]() |
0a35bc3272 | ||
![]() |
d8b737a31f | ||
![]() |
cfd2655f6c | ||
![]() |
1896241b9d | ||
![]() |
0ed22a6ee1 | ||
![]() |
2bfcb99c3e | ||
![]() |
815f8a520a | ||
![]() |
f115b6607f | ||
![]() |
c876f67502 | ||
![]() |
27674f272c | ||
![]() |
02879507e3 | ||
![]() |
0a7629878f | ||
![]() |
b0368232d0 | ||
![]() |
a32bf3db98 | ||
![]() |
64cbbb20d3 | ||
![]() |
dd4fbecc98 | ||
![]() |
807a75a265 |
70
.vscode/c_cpp_properties.json
vendored
@@ -10,28 +10,31 @@
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"/usr/local/lib/wx/include/osx_cocoa-unicode-3.0",
|
||||
"/usr/local/include/wx-3.0",
|
||||
"/usr/include/machine",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
|
||||
"/usr/local/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
|
||||
"/usr/include"
|
||||
"/usr/include",
|
||||
"/usr/local/lib/wx/include/osx_cocoa-unicode-3.0",
|
||||
"/usr/local/include/wx-3.0",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"GD_IDE_ONLY",
|
||||
"__WXMAC__",
|
||||
"__WXOSX__",
|
||||
"__WXOSX_COCOA__",
|
||||
"GD_CORE_API=\" \"",
|
||||
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"WXUSINGDLL"
|
||||
],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
|
||||
"/usr/local/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
|
||||
"/usr/include",
|
||||
"${workspaceRoot}"
|
||||
@@ -39,20 +42,39 @@
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"macFrameworkPath": [
|
||||
"/System/Library/Frameworks",
|
||||
"/Library/Frameworks"
|
||||
]
|
||||
],
|
||||
"compilerPath": "/usr/bin/clang",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
},
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/IDE",
|
||||
"${workspaceRoot}/GDCpp",
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"/usr/include",
|
||||
"/usr/local/include"
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [],
|
||||
"defines": [
|
||||
"GD_IDE_ONLY",
|
||||
"__WXMAC__",
|
||||
"__WXOSX__",
|
||||
"__WXOSX_COCOA__",
|
||||
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"WXUSINGDLL"
|
||||
],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
@@ -61,19 +83,34 @@
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"intelliSenseMode": "clang-x64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceRoot}",
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include"
|
||||
"${workspaceRoot}/IDE",
|
||||
"${workspaceRoot}/GDCpp",
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
"UNICODE",
|
||||
"GD_IDE_ONLY",
|
||||
"__WXMAC__",
|
||||
"__WXOSX__",
|
||||
"__WXOSX_COCOA__",
|
||||
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"WXUSINGDLL"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
|
||||
@@ -81,8 +118,7 @@
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"intelliSenseMode": "msvc-x64"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": 3
|
||||
|
9
.vscode/settings.json
vendored
@@ -67,7 +67,11 @@
|
||||
"__functional_base": "cpp",
|
||||
"__functional_base_03": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp"
|
||||
"ratio": "cpp",
|
||||
"atomic": "cpp",
|
||||
"locale": "cpp",
|
||||
"string_view": "cpp",
|
||||
"__string": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
@@ -85,5 +89,6 @@
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype:
|
||||
"javascript.validate.enable": false
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true
|
||||
}
|
||||
|
BIN
Binaries/Output/Release_Windows/res/conditions/raycast.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
Binaries/Output/Release_Windows/res/conditions/raycast24.png
Normal file
After Width: | Height: | Size: 378 B |
After Width: | Height: | Size: 1.6 KiB |
BIN
Binaries/Output/Release_Windows/res/ribbon_default/networkpreview64.png
Executable file
After Width: | Height: | Size: 3.6 KiB |
@@ -11,7 +11,7 @@ IF NOT EXIST "%INNOSETUP_EXE%" set INNOSETUP_EXE=C:\Program Files\Inno Setup 5\I
|
||||
IF EXIST "%INNOSETUP_EXE%" (
|
||||
echo "Note: InnoSetup found at %INNOSETUP_EXE%"
|
||||
) ELSE (
|
||||
echo Warning: InnoSetup not found! Skipping installer creation.
|
||||
echo Warning: InnoSetup Unicode not found! Skipping installer creation.
|
||||
SET SKIPINSTALLER=1
|
||||
)
|
||||
|
||||
|
@@ -2,7 +2,9 @@
|
||||
Version=1.0
|
||||
Name=GDevelop
|
||||
GenericName=Game creator IDE
|
||||
GenericName[de]=Entwicklungsumgebung für Spiele
|
||||
Comment=HTML5 and native game development software
|
||||
Comment[de]=Entwicklungsumgebung für native und HTML5-Spiele
|
||||
Exec=sh -c "gdevelop %F"
|
||||
MimeType=application/x-gdevelop-project;
|
||||
Icon=GDevelop
|
||||
|
@@ -13,17 +13,17 @@ AllowNoIcons=yes
|
||||
LicenseFile=..\Output\Release_Windows\License-en.rtf
|
||||
InfoBeforeFile=..\Output\Release_Windows\Informations-en.rtf
|
||||
OutputDir=.\
|
||||
OutputBaseFilename=gd4096
|
||||
OutputBaseFilename=gd4097
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
SetupIconFile=..\Output\Release_Windows\res\icon.ico
|
||||
VersionInfoVersion=4.0
|
||||
WizardImageFile=Setup bitmap\wizbmp.bmp
|
||||
WizardSmallImageFile=Setup bitmap/smallicon.bmp
|
||||
AppCopyright=2008-2017 Florian Rival
|
||||
AppCopyright=2008-2018 Florian Rival
|
||||
VersionInfoCompany=Florian Rival
|
||||
VersionInfoDescription=GDevelop setup
|
||||
VersionInfoCopyright=2008-2016 Florian Rival
|
||||
VersionInfoCopyright=2008-2018 Florian Rival
|
||||
VersionInfoProductName=GDevelop
|
||||
VersionInfoProductVersion=4.0
|
||||
|
||||
|
@@ -78,6 +78,7 @@
|
||||
* The installation is fairly simple :<br>
|
||||
* <br>
|
||||
* - Launch the installer.<br>
|
||||
* - Uncheck "Check for updated files on the TDM-GCC server" (otherwise you won't get TDM-GCC 4.9.2 but a more recent version that won't be compatible with wxWidgets pre-compiled binaries)
|
||||
* - Choose Create.<br>
|
||||
|
||||
\image html compilerInstall1.png
|
||||
|
@@ -337,7 +337,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(gd::Plat
|
||||
extension.AddCondition("GlobalVolume",
|
||||
_("Global volume"),
|
||||
_("Test the global sound level. The volume is between 0 and 100."),
|
||||
_("The global game volume is _PARAM2_ to _PARAM1_"),
|
||||
_("The global game volume is _PARAM1__PARAM2_"),
|
||||
_("Audio"),
|
||||
"res/conditions/volume24.png",
|
||||
"res/conditions/volume.png")
|
||||
|
@@ -860,6 +860,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(gd:
|
||||
.AddCodeOnlyParameter("conditionInverted", "")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension.AddCondition("Raycast",
|
||||
_("Raycast"),
|
||||
_("Sends a ray from the given source position and angle, intersecting the closest object.\nThe instersected object will become the only one taken into account.\nIf the condition is inverted, the object to be intersected will be the farthest one within the ray radius."),
|
||||
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the result in _PARAM5_, _PARAM6_"),
|
||||
_("Collision"),
|
||||
"res/conditions/raycast24.png",
|
||||
"res/conditions/raycast.png")
|
||||
.AddParameter("objectList", _("Objects to test against the ray"))
|
||||
.AddParameter("expression", _("Ray source X position"))
|
||||
.AddParameter("expression", _("Ray source Y position"))
|
||||
.AddParameter("expression", _("Ray angle (in degrees)"))
|
||||
.AddParameter("expression", _("Ray maximum distance (in pixels)"))
|
||||
.AddParameter("scenevar", _("Variable where to store the X position of the intersection"))
|
||||
.AddParameter("scenevar", _("Variable where to store the Y position of the intersection"))
|
||||
.AddCodeOnlyParameter("conditionInverted", "")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension.AddExpression("Count", _("Number of objects"), _("Count the number of the specified objects currently picked"), _("Objects"), "res/conditions/nbObjet.png")
|
||||
.AddParameter("objectList", _("Object"));
|
||||
#endif
|
||||
|
@@ -26,14 +26,24 @@ public:
|
||||
mutable std::vector<sf::Vector2f> edges; ///< Edges. Can be computed from vertices using ComputeEdges()
|
||||
|
||||
/**
|
||||
* Moves each vertices from the given amount.
|
||||
* \brief Get the vertices composing the polygon.
|
||||
*/
|
||||
std::vector<sf::Vector2f> & GetVertices() { return vertices; }
|
||||
|
||||
/**
|
||||
* \brief Get the vertices composing the polygon.
|
||||
*/
|
||||
const std::vector<sf::Vector2f> & GetVertices() const { return vertices; }
|
||||
|
||||
/**
|
||||
* \brief Moves each vertices from the given amount.
|
||||
*
|
||||
* \note Edges are updated, there is no need to call ComputeEdges after calling Move.
|
||||
*/
|
||||
void Move(float x, float y);
|
||||
|
||||
/**
|
||||
* Rotate the polygon.
|
||||
* \brief Rotate the polygon.
|
||||
* \param angle Angle in radians
|
||||
*
|
||||
* \warning Rotation is made clockwise
|
||||
@@ -42,18 +52,18 @@ public:
|
||||
void Rotate(float angle);
|
||||
|
||||
/**
|
||||
* Automatically fill edges vector using vertices.
|
||||
* \brief Automatically fill edges vector using vertices.
|
||||
*/
|
||||
void ComputeEdges() const;
|
||||
|
||||
/**
|
||||
* Check if the polygon is convex.
|
||||
* \brief Check if the polygon is convex.
|
||||
* \return true if the polygon is convex
|
||||
*/
|
||||
bool IsConvex() const;
|
||||
|
||||
/**
|
||||
* Return the position of the center of the polygon
|
||||
* \brief Return the position of the center of the polygon
|
||||
*/
|
||||
sf::Vector2f ComputeCenter() const;
|
||||
|
||||
@@ -62,7 +72,7 @@ public:
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* Create a rectangle
|
||||
* \brief Create a rectangle
|
||||
*/
|
||||
static Polygon2d CreateRectangle(float width, float height);
|
||||
///@}
|
||||
|
@@ -103,6 +103,7 @@ bool Sprite::SetDefaultCenterPoint(bool enabled)
|
||||
|
||||
std::vector<Polygon2d> Sprite::GetCollisionMask() const
|
||||
{
|
||||
//TODO(perf): Cache to avoid re-creating a mask at every call
|
||||
#if !defined(EMSCRIPTEN)
|
||||
if ( automaticCollisionMask )
|
||||
{
|
||||
|
@@ -56,6 +56,16 @@ public:
|
||||
*/
|
||||
std::vector<Polygon2d> GetCollisionMask() const;
|
||||
|
||||
/**
|
||||
* \brief Get the custom collision mask.
|
||||
*/
|
||||
std::vector<Polygon2d> & GetCustomCollisionMask() { return customCollisionMask; };
|
||||
|
||||
/**
|
||||
* \brief Get the custom collision mask.
|
||||
*/
|
||||
const std::vector<Polygon2d> & GetCustomCollisionMask() const { return customCollisionMask; };
|
||||
|
||||
/**
|
||||
* \brief Set the custom collision mask.
|
||||
* Call then `SetCollisionMaskAutomatic(false)` to use it.
|
||||
|
@@ -225,13 +225,13 @@ void ChooseVariableDialog::RefreshVariable(wxTreeListItem item, const gd::String
|
||||
variablesList->SetItemText(item, 1, "(Structure)");
|
||||
|
||||
//Add/update children
|
||||
const std::map<gd::String, gd::Variable> & children = variable.GetAllChildren();
|
||||
const auto & children = variable.GetAllChildren();
|
||||
wxTreeListItem currentChildItem = variablesList->GetFirstChild(item);
|
||||
wxTreeListItem lastChildItem;
|
||||
for(std::map<gd::String, gd::Variable>::const_iterator it = children.begin();it != children.end();++it)
|
||||
for(auto it = children.begin();it != children.end();++it)
|
||||
{
|
||||
if ( !currentChildItem.IsOk() ) currentChildItem = variablesList->AppendItem(item, it->first);
|
||||
RefreshVariable(currentChildItem, it->first, it->second);
|
||||
RefreshVariable(currentChildItem, it->first, *it->second);
|
||||
lastChildItem = currentChildItem;
|
||||
|
||||
currentChildItem = variablesList->GetNextSibling(currentChildItem);
|
||||
@@ -255,10 +255,11 @@ void ChooseVariableDialog::RefreshAll()
|
||||
|
||||
for (std::size_t i = 0;i<temporaryContainer->Count();++i)
|
||||
{
|
||||
const std::pair<gd::String, gd::Variable> & variable = temporaryContainer->Get(i);
|
||||
const gd::String & name = temporaryContainer->GetNameAt(i);
|
||||
const auto & variable = temporaryContainer->Get(i);
|
||||
|
||||
wxTreeListItem item = variablesList->AppendItem(variablesList->GetRootItem(), variable.first);
|
||||
RefreshVariable(item, variable.first, variable.second);
|
||||
wxTreeListItem item = variablesList->AppendItem(variablesList->GetRootItem(), name);
|
||||
RefreshVariable(item, name, variable);
|
||||
variablesList->Expand(item);
|
||||
}
|
||||
|
||||
@@ -330,20 +331,11 @@ void ChooseVariableDialog::OnAddVarSelected(wxCommandEvent& event)
|
||||
void ChooseVariableDialog::OnMoveUpVarSelected(wxCommandEvent& event)
|
||||
{
|
||||
UpdateSelectedAndParentVariable();
|
||||
for (std::size_t i = 1;i<temporaryContainer->Count();++i)
|
||||
{
|
||||
const std::pair<gd::String, gd::Variable> & currentVar = temporaryContainer->Get(i);
|
||||
if ( currentVar.first == selectedVariableName)
|
||||
{
|
||||
const std::pair<gd::String, gd::Variable> & prevVar = temporaryContainer->Get(i-1);
|
||||
temporaryContainer->Swap(i, i-1);
|
||||
RefreshAll();
|
||||
|
||||
modificationCount++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto position = temporaryContainer->GetPosition(selectedVariableName);
|
||||
temporaryContainer->Move(position, position-1);
|
||||
RefreshAll();
|
||||
|
||||
modificationCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,21 +344,11 @@ void ChooseVariableDialog::OnMoveUpVarSelected(wxCommandEvent& event)
|
||||
void ChooseVariableDialog::OnMoveDownVarSelected(wxCommandEvent& event)
|
||||
{
|
||||
UpdateSelectedAndParentVariable();
|
||||
for (std::size_t i = 0;i<temporaryContainer->Count()-1;++i)
|
||||
{
|
||||
const std::pair<gd::String, gd::Variable> & currentVar = temporaryContainer->Get(i);
|
||||
if ( currentVar.first == selectedVariableName)
|
||||
{
|
||||
const std::pair<gd::String, gd::Variable> & nextVar = temporaryContainer->Get(i+1);
|
||||
|
||||
temporaryContainer->Swap(i, i+1);
|
||||
RefreshAll();
|
||||
|
||||
modificationCount++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto position = temporaryContainer->GetPosition(selectedVariableName);
|
||||
temporaryContainer->Move(position, position+1);
|
||||
RefreshAll();
|
||||
|
||||
modificationCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -52,6 +52,7 @@
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/IDE/Dialogs/DndResourcesEditor.h"
|
||||
#include "GDCore/IDE/wxTools/TreeItemStringData.h"
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include <gtk/gtk.h>
|
||||
@@ -635,7 +636,7 @@ void ResourcesEditor::OnresourcesTreeSelectionChanged( wxTreeEvent& event )
|
||||
|
||||
void ResourcesEditor::UpdatePropertyGrid()
|
||||
{
|
||||
std::vector<gd::String> commonProperties; ///< The name of the properties to be displayed
|
||||
std::map<gd::String, gd::PropertyDescriptor> commonProperties; ///< The name of the properties to be displayed
|
||||
bool aFolderIsSelected = false;
|
||||
|
||||
//First construct the list of common properties
|
||||
@@ -646,18 +647,29 @@ void ResourcesEditor::UpdatePropertyGrid()
|
||||
gd::TreeItemStringData * data = dynamic_cast<gd::TreeItemStringData*>(resourcesTree->GetItemData(selection[i]));
|
||||
if ( data && data->GetString() == "Image")
|
||||
{
|
||||
std::vector<gd::String> properties = project.GetResourcesManager().GetResource(data->GetSecondString()).GetAllProperties(project);
|
||||
const std::map<gd::String, gd::PropertyDescriptor> & properties =
|
||||
project.GetResourcesManager().GetResource(data->GetSecondString()).GetProperties(project);
|
||||
if ( i == 0 )
|
||||
commonProperties = properties;
|
||||
else
|
||||
{
|
||||
//Keep only properties that are common to all the selected resources
|
||||
for (std::size_t j = 0;j<commonProperties.size();)
|
||||
// TODO: This could be factored with helpers like ObjectsPropgridHelper
|
||||
|
||||
//Merge custom properties
|
||||
for(std::map<gd::String, gd::PropertyDescriptor>::const_iterator it = properties.begin();
|
||||
it != properties.end();++it)
|
||||
{
|
||||
if ( find(properties.begin(), properties.end(), commonProperties[j]) == properties.end() )
|
||||
commonProperties.erase(commonProperties.begin()+j);
|
||||
else
|
||||
++j;
|
||||
if ( commonProperties.find(it->first) == commonProperties.end() ) continue;
|
||||
if ( commonProperties[it->first].GetValue() != it->second.GetValue() )
|
||||
commonProperties[it->first].SetValue(_("(Multiples values)"));
|
||||
}
|
||||
//Also erase properties which are not in common.
|
||||
for(std::map<gd::String, gd::PropertyDescriptor>::iterator it = commonProperties.begin();
|
||||
it != commonProperties.end();)
|
||||
{
|
||||
if ( properties.find(it->first) == properties.end() )
|
||||
commonProperties.erase(it++);
|
||||
else ++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -721,32 +733,11 @@ void ResourcesEditor::UpdatePropertyGrid()
|
||||
|
||||
//Other properties
|
||||
if ( !commonProperties.empty() ) propertyGrid->Append( new wxPropertyCategory(_("Other properties")) );
|
||||
for (std::size_t j = 0;j<commonProperties.size();++j)
|
||||
for(auto & propertyIterator: commonProperties)
|
||||
{
|
||||
wxPGProperty * property = propertyGrid->Append( new wxStringProperty("", commonProperties[j], "") );
|
||||
wxString commonValue;
|
||||
|
||||
for (std::size_t i = 0;i<selection.size();++i)
|
||||
{
|
||||
gd::TreeItemStringData * data = dynamic_cast<gd::TreeItemStringData*>(resourcesTree->GetItemData(selection[i]));
|
||||
if ( data && data->GetString() == "Image")
|
||||
{
|
||||
//It is assumed that the description and the user friendly name
|
||||
//are the same for all the properties with the same name.
|
||||
gd::String propertyUserFriendlyName;
|
||||
gd::String propertyDescription;
|
||||
project.GetResourcesManager().GetResource(data->GetSecondString()).GetPropertyInformation(project, commonProperties[j], propertyUserFriendlyName, propertyDescription);
|
||||
propertyGrid->SetPropertyLabel(property, propertyUserFriendlyName);
|
||||
propertyGrid->SetPropertyHelpString(property, propertyDescription);
|
||||
|
||||
//Values can be different though
|
||||
gd::String propertyValue = project.GetResourcesManager().GetResource(data->GetSecondString()).GetProperty(project, commonProperties[j]);
|
||||
if ( i == 0 ) commonValue = propertyValue;
|
||||
else if ( commonValue != propertyValue ) commonValue = _("(Multiple values)");
|
||||
}
|
||||
}
|
||||
|
||||
propertyGrid->SetPropertyValue(property, commonValue);
|
||||
// TODO: For now, all other properties are assumed to be booleans.
|
||||
auto & propertyName = propertyIterator.first;
|
||||
propertyGrid->Append(new wxBoolProperty(propertyName, propertyName, propertyIterator.second.GetValue() == "true"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -782,7 +773,7 @@ void ResourcesEditor::OnPropertyChanged(wxPropertyGridEvent& event)
|
||||
RenameInTree(resourcesTree->GetRootItem(), renamedItemOldName, propertyNewValue, "Image");
|
||||
}
|
||||
else
|
||||
project.GetResourcesManager().GetResource(data->GetSecondString()).ChangeProperty(project, propertyName, propertyNewValue);
|
||||
project.GetResourcesManager().GetResource(data->GetSecondString()).UpdateProperty(propertyName, propertyNewValue, project);
|
||||
|
||||
for ( std::size_t j = 0; j < project.GetUsedPlatforms().size();++j)
|
||||
project.GetUsedPlatforms()[j]->GetChangesNotifier().OnResourceModified(project, data->GetSecondString());
|
||||
@@ -945,7 +936,7 @@ void ResourcesEditor::Refresh()
|
||||
gd::ResourceFolder & folder = project.GetResourcesManager().GetFolder(folders[i]);
|
||||
wxTreeItemId folderItem = resourcesTree->AppendItem( resourcesTree->GetRootItem(), folders[i], -1, -1, new gd::TreeItemStringData("Folder", folders[i] ));
|
||||
|
||||
std::vector<gd::String> resources = folder.GetAllResourcesList();
|
||||
std::vector<gd::String> resources = folder.GetAllResourceNames();
|
||||
for (std::size_t j=0;j<resources.size();++j)
|
||||
{
|
||||
gd::Resource & resource = folder.GetResource(resources[j]);
|
||||
@@ -959,7 +950,7 @@ void ResourcesEditor::Refresh()
|
||||
|
||||
//All images
|
||||
allImagesItem = resourcesTree->AppendItem( resourcesTree->GetRootItem(), _("All images"), -1,-1, new gd::TreeItemStringData("BaseFolder", "" ));
|
||||
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourcesList();
|
||||
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourceNames();
|
||||
for ( std::size_t i = 0;i <resources.size();i++ )
|
||||
{
|
||||
gd::Resource & resource = project.GetResourcesManager().GetResource(resources[i]);
|
||||
|
@@ -51,7 +51,7 @@ void ArbitraryResourceWorker::ExposeResources(gd::ResourcesManager * resourcesMa
|
||||
|
||||
resourcesManagers.push_back(resourcesManager);
|
||||
|
||||
std::vector<gd::String> resources = resourcesManager->GetAllResourcesList();
|
||||
std::vector<gd::String> resources = resourcesManager->GetAllResourceNames();
|
||||
for ( std::size_t i = 0;i < resources.size() ;i++ )
|
||||
{
|
||||
if ( resourcesManager->GetResource(resources[i]).UseFile() )
|
||||
|
@@ -45,7 +45,7 @@ std::vector<gd::String> ProjectResourcesAdder::GetAllUselessImages(gd::Project &
|
||||
std::set<gd::String> & usedImages = inventorizer.GetAllUsedImages();
|
||||
|
||||
//Search all images resources not used
|
||||
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourcesList();
|
||||
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourceNames();
|
||||
for (std::size_t i = 0;i < resources.size();i++)
|
||||
{
|
||||
if (project.GetResourcesManager().GetResource(resources[i]).GetKind() != "image")
|
||||
|
@@ -45,7 +45,7 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(gd::Project & originalProject, A
|
||||
#endif
|
||||
|
||||
auto projectDirectory = fs.DirNameFrom(originalProject.GetProjectFile());
|
||||
std::cout << "Copying all ressources from " << projectDirectory << " to " << destinationDirectory;
|
||||
std::cout << "Copying all ressources from " << projectDirectory << " to " << destinationDirectory << "..." << std::endl;
|
||||
|
||||
//Get the resources to be copied
|
||||
gd::ResourcesMergingHelper resourcesMergingHelper(fs);
|
||||
|
@@ -68,7 +68,7 @@ public:
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[ToString(_("Initial speed"))].SetValue("5");
|
||||
properties[_("Initial speed")].SetValue(gd::String::From(initialSpeed));
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
|
@@ -5,6 +5,10 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <map>
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
#endif
|
||||
|
||||
namespace gd
|
||||
{
|
||||
@@ -13,4 +17,12 @@ BehaviorsSharedData::~BehaviorsSharedData()
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorsSharedData::GetProperties(gd::Project & project) const
|
||||
{
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@@ -8,9 +8,13 @@
|
||||
#define BEHAVIORSSHAREDDATA_H
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include "GDCore/String.h"
|
||||
class BehaviorsRuntimeSharedData;
|
||||
namespace gd { class SerializerElement; }
|
||||
namespace gd { class PropertyDescriptor; }
|
||||
namespace gd { class Project; }
|
||||
namespace gd { class Layout; }
|
||||
|
||||
namespace gd
|
||||
{
|
||||
@@ -52,6 +56,31 @@ public:
|
||||
virtual void SetTypeName(const gd::String & type_) { type = type_; };
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the properties of the shared data.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Initial speed")].SetValue(gd::String::From(initialSpeed));
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a property of the shared data
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project) {return false;};
|
||||
|
||||
/**
|
||||
* \brief Serialize behaviors shared data.
|
||||
*/
|
||||
|
@@ -141,7 +141,7 @@ void ImageManager::LoadPermanentImages()
|
||||
//so as not to unload images that could be still present.
|
||||
std::map < gd::String, std::shared_ptr<SFMLTextureWrapper> > newPermanentlyLoadedImages;
|
||||
|
||||
std::vector<gd::String> resources = resourcesManager->GetAllResourcesList();
|
||||
std::vector<gd::String> resources = resourcesManager->GetAllResourceNames();
|
||||
for ( std::size_t i = 0;i <resources.size();i++ )
|
||||
{
|
||||
try
|
||||
|
@@ -29,6 +29,7 @@ namespace gd
|
||||
{
|
||||
|
||||
gd::Layer Layout::badLayer;
|
||||
gd::BehaviorsSharedData Layout::badBehaviorSharedData;
|
||||
|
||||
Layout::Layout(const Layout & other)
|
||||
{
|
||||
@@ -74,6 +75,53 @@ void Layout::SetName(const gd::String & name_)
|
||||
mangledName = gd::SceneNameMangler::GetMangledSceneName(name);
|
||||
};
|
||||
|
||||
bool Layout::HasBehaviorSharedData(const gd::String & behaviorName)
|
||||
{
|
||||
return behaviorsInitialSharedDatas.find(behaviorName) != behaviorsInitialSharedDatas.end();
|
||||
}
|
||||
|
||||
std::vector <gd::String> Layout::GetAllBehaviorSharedDataNames() const
|
||||
{
|
||||
std::vector < gd::String > allNames;
|
||||
|
||||
for (auto & it : behaviorsInitialSharedDatas)
|
||||
allNames.push_back(it.first);
|
||||
|
||||
return allNames;
|
||||
}
|
||||
|
||||
const gd::BehaviorsSharedData & Layout::GetBehaviorSharedData(const gd::String & behaviorName) const
|
||||
{
|
||||
auto it = behaviorsInitialSharedDatas.find(behaviorName);
|
||||
if (it != behaviorsInitialSharedDatas.end())
|
||||
return *it->second;
|
||||
|
||||
return badBehaviorSharedData;
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData & Layout::GetBehaviorSharedData(const gd::String & behaviorName)
|
||||
{
|
||||
auto it = behaviorsInitialSharedDatas.find(behaviorName);
|
||||
if (it != behaviorsInitialSharedDatas.end())
|
||||
return *it->second;
|
||||
|
||||
return badBehaviorSharedData;
|
||||
}
|
||||
|
||||
std::shared_ptr<gd::BehaviorsSharedData> Layout::GetBehaviorSharedDataSmartPtr(const gd::String & behaviorName)
|
||||
{
|
||||
auto it = behaviorsInitialSharedDatas.find(behaviorName);
|
||||
if (it != behaviorsInitialSharedDatas.end())
|
||||
return it->second;
|
||||
|
||||
return std::shared_ptr<gd::BehaviorsSharedData>();
|
||||
}
|
||||
|
||||
const std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > & Layout::GetAllBehaviorSharedData() const
|
||||
{
|
||||
return behaviorsInitialSharedDatas;
|
||||
}
|
||||
|
||||
gd::Layer & Layout::GetLayer(const gd::String & name)
|
||||
{
|
||||
std::vector<gd::Layer>::iterator layer = find_if(initialLayers.begin(), initialLayers.end(), bind2nd(gd::LayerHasName(), name));
|
||||
@@ -83,6 +131,7 @@ gd::Layer & Layout::GetLayer(const gd::String & name)
|
||||
|
||||
return badLayer;
|
||||
}
|
||||
|
||||
const gd::Layer & Layout::GetLayer(const gd::String & name) const
|
||||
{
|
||||
std::vector<gd::Layer>::const_iterator layer = find_if(initialLayers.begin(), initialLayers.end(), bind2nd(gd::LayerHasName(), name));
|
||||
@@ -92,14 +141,17 @@ const gd::Layer & Layout::GetLayer(const gd::String & name) const
|
||||
|
||||
return badLayer;
|
||||
}
|
||||
|
||||
gd::Layer & Layout::GetLayer(std::size_t index)
|
||||
{
|
||||
return initialLayers[index];
|
||||
}
|
||||
|
||||
const gd::Layer & Layout::GetLayer (std::size_t index) const
|
||||
{
|
||||
return initialLayers[index];
|
||||
}
|
||||
|
||||
std::size_t Layout::GetLayersCount() const
|
||||
{
|
||||
return initialLayers.size();
|
||||
|
@@ -172,37 +172,37 @@ public:
|
||||
|
||||
/** \name Layout layers management
|
||||
* Members functions related to layout layers management.
|
||||
* TODO: This should be moved to a separate class
|
||||
* TODO: This could be moved to a separate class
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* Must return true if the layer called "name" exists.
|
||||
* \brief Return true if the layer called "name" exists.
|
||||
*/
|
||||
bool HasLayerNamed(const gd::String & name) const;
|
||||
|
||||
/**
|
||||
* Must return a reference to the layer called "name".
|
||||
* \brief Return a reference to the layer called "name".
|
||||
*/
|
||||
Layer & GetLayer(const gd::String & name);
|
||||
|
||||
/**
|
||||
* Must return a reference to the layer called "name".
|
||||
* \brief Return a reference to the layer called "name".
|
||||
*/
|
||||
const Layer & GetLayer(const gd::String & name) const;
|
||||
|
||||
/**
|
||||
* Must return a reference to the layer at position "index" in the layers list
|
||||
* \brief Return a reference to the layer at position "index" in the layers list
|
||||
*/
|
||||
Layer & GetLayer(std::size_t index);
|
||||
|
||||
/**
|
||||
* Must return a reference to the layer at position "index" in the layers list
|
||||
* \brief Return a reference to the layer at position "index" in the layers list
|
||||
*/
|
||||
const Layer & GetLayer (std::size_t index) const;
|
||||
const Layer & GetLayer(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Must return the position of the layer called "name" in the layers list
|
||||
* \brief Return the position of the layer called "name" in the layers list
|
||||
*/
|
||||
std::size_t GetLayerPosition(const gd::String & name) const;
|
||||
|
||||
@@ -253,15 +253,45 @@ public:
|
||||
///@}
|
||||
|
||||
/**
|
||||
* Make sure that the scene had an instance of shared data for
|
||||
* This ensures that the scene had an instance of shared data for
|
||||
* every behavior of every object that can be used on the scene
|
||||
* ( i.e. the objects of the scene and the global objects )
|
||||
* (i.e. the objects of the scene and the global objects)
|
||||
*
|
||||
* Must be called when a behavior have been added/deleted
|
||||
* or when a scene have been added to a project.
|
||||
*/
|
||||
void UpdateBehaviorsSharedData(gd::Project & project);
|
||||
|
||||
/**
|
||||
* \brief Get the names of all shared data stored for behaviors
|
||||
*/
|
||||
std::vector <gd::String> GetAllBehaviorSharedDataNames() const;
|
||||
|
||||
/**
|
||||
* \brief Check if shared data are stored for a behavior
|
||||
*/
|
||||
bool HasBehaviorSharedData(const gd::String & behaviorName);
|
||||
|
||||
/**
|
||||
* \brief Get the shared data stored for a behavior
|
||||
*/
|
||||
const gd::BehaviorsSharedData & GetBehaviorSharedData(const gd::String & behaviorName) const;
|
||||
|
||||
/**
|
||||
* \brief Get the shared data stored for a behavior
|
||||
*/
|
||||
gd::BehaviorsSharedData & GetBehaviorSharedData(const gd::String & behaviorName);
|
||||
|
||||
/**
|
||||
* \brief Get a map of all shared data stored for behaviors
|
||||
*/
|
||||
const std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > & GetAllBehaviorSharedData() const;
|
||||
|
||||
/**
|
||||
* \brief Get the (smart pointer to the) shared data stored for a behavior.
|
||||
*/
|
||||
std::shared_ptr<gd::BehaviorsSharedData> GetBehaviorSharedDataSmartPtr(const gd::String & behaviorName);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* Return the settings associated to the layout.
|
||||
@@ -357,9 +387,6 @@ public:
|
||||
void UnserializeFrom(gd::Project & project, const SerializerElement & element);
|
||||
///@}
|
||||
|
||||
//TODO: Send this to private part.
|
||||
std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > behaviorsInitialSharedDatas; ///< Initial shared datas of behaviors
|
||||
|
||||
//TODO: GD C++ Platform specific code below
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/** \name Events compilation and bitcode management
|
||||
@@ -442,6 +469,7 @@ private:
|
||||
gd::InitialInstancesContainer initialInstances; ///< Initial instances
|
||||
std::vector < gd::Layer > initialLayers; ///< Initial layers
|
||||
ObjectGroupsContainer objectGroups; ///< Objects groups
|
||||
std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > behaviorsInitialSharedDatas; ///< Initial shared datas of behaviors
|
||||
bool stopSoundsOnStartup; ///< True to make the scene stop all sounds at startup.
|
||||
bool standardSortMethod; ///< True to sort objects using standard sort.
|
||||
float oglFOV; ///< OpenGL Field Of View value
|
||||
@@ -449,6 +477,7 @@ private:
|
||||
float oglZFar; ///< OpenGL Far Z position
|
||||
bool disableInputWhenNotFocused; /// If set to true, the input must be disabled when the window do not have the focus.
|
||||
static gd::Layer badLayer; ///< Null object, returned when GetLayer can not find an appropriate layer.
|
||||
static gd::BehaviorsSharedData badBehaviorSharedData; ///< Null object, returned when GetBehaviorSharedData can not find the specified behavior shared data.
|
||||
#if defined(GD_IDE_ONLY)
|
||||
EventsList events; ///< Scene events
|
||||
gd::LayoutEditorCanvasOptions associatedSettings;
|
||||
|
21
Core/GDCore/Project/LoadingScreen.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "LoadingScreen.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void LoadingScreen::SerializeTo(SerializerElement& element) const
|
||||
{
|
||||
element.SetAttribute("showGDevelopSplash", showGDevelopSplash);
|
||||
}
|
||||
|
||||
void LoadingScreen::UnserializeFrom(const SerializerElement& element)
|
||||
{
|
||||
showGDevelopSplash = element.GetBoolAttribute("showGDevelopSplash", true);
|
||||
}
|
||||
}
|
57
Core/GDCore/Project/LoadingScreen.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_LOADINGSCREEN_H
|
||||
#define GDCORE_LOADINGSCREEN_H
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Describe the content and set up of the loading screen
|
||||
*
|
||||
* \see gd::LoadingScreen
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API LoadingScreen {
|
||||
public:
|
||||
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 assets.
|
||||
*/
|
||||
bool IsGDevelopSplashShown() const { return showGDevelopSplash; };
|
||||
|
||||
/** \name Saving and loading
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize objects groups container.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the objects groups container.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
bool showGDevelopSplash;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // GDCORE_LOADINGSCREEN_H
|
58
Core/GDCore/Project/PlatformSpecificAssets.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "PlatformSpecificAssets.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
gd::String PlatformSpecificAssets::badStr;
|
||||
|
||||
bool PlatformSpecificAssets::Has(const gd::String& platform, const gd::String& name) const
|
||||
{
|
||||
return assets.find(platform + "-" + name) != assets.end();
|
||||
}
|
||||
|
||||
const gd::String& PlatformSpecificAssets::Get(const gd::String& platform, const gd::String& name) const
|
||||
{
|
||||
const auto & it = assets.find(platform + "-" + name);
|
||||
return it != assets.end() ? it->second : badStr;
|
||||
}
|
||||
|
||||
void PlatformSpecificAssets::Remove(const gd::String& platform, const gd::String& name)
|
||||
{
|
||||
assets.erase(platform + "-" + name);
|
||||
}
|
||||
|
||||
void PlatformSpecificAssets::Set(const gd::String& platform, const gd::String& name, const gd::String& resourceName)
|
||||
{
|
||||
assets[platform + "-" + name] = resourceName;
|
||||
}
|
||||
|
||||
void PlatformSpecificAssets::SerializeTo(SerializerElement& element) const
|
||||
{
|
||||
for (auto& it : assets) {
|
||||
element.AddChild(it.first).SetValue(it.second);
|
||||
}
|
||||
}
|
||||
|
||||
void PlatformSpecificAssets::UnserializeFrom(const SerializerElement& element)
|
||||
{
|
||||
assets.clear();
|
||||
|
||||
for (auto& child : element.GetAllChildren()) {
|
||||
assets[child.first] = child.second->GetValue().GetString();
|
||||
}
|
||||
}
|
||||
|
||||
void PlatformSpecificAssets::ExposeResources(gd::ArbitraryResourceWorker & worker)
|
||||
{
|
||||
for (auto& it : assets) {
|
||||
worker.ExposeImage(it.second);
|
||||
}
|
||||
}
|
||||
}
|
76
Core/GDCore/Project/PlatformSpecificAssets.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_PLATFORMASSETS_H
|
||||
#define GDCORE_PLATFORMASSETS_H
|
||||
#include "GDCore/String.h"
|
||||
#include <map>
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
namespace gd {
|
||||
class ArbitraryResourceWorker;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Store the icons, splashscreens or reference to any other asset
|
||||
* that can be needed when exporting the game.
|
||||
*
|
||||
* \see gd::Project
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API PlatformSpecificAssets {
|
||||
public:
|
||||
PlatformSpecificAssets(){};
|
||||
virtual ~PlatformSpecificAssets(){};
|
||||
|
||||
/**
|
||||
* \brief Return true if the specified asset exists.
|
||||
*/
|
||||
bool Has(const gd::String& platform, const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Get the specified asset resource name.
|
||||
*/
|
||||
const gd::String& Get(const gd::String& platform, const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Remove the specified asset.
|
||||
*/
|
||||
void Remove(const gd::String& platform, const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Remove the specified asset.
|
||||
*/
|
||||
void Set(const gd::String& platform, const gd::String& name, const gd::String& resourceName);
|
||||
|
||||
void ExposeResources(gd::ArbitraryResourceWorker & worker);
|
||||
|
||||
/** \name Saving and loading
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize objects groups container.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the objects groups container.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
std::map<gd::String, gd::String> assets;
|
||||
|
||||
static gd::String badStr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // GDCORE_PLATFORMASSETS_H
|
@@ -61,6 +61,7 @@ Project::Project() :
|
||||
#if defined(GD_IDE_ONLY)
|
||||
name(_("Project")),
|
||||
packageName("com.example.gamename"),
|
||||
orientation("landscape"),
|
||||
folderProject(false),
|
||||
#endif
|
||||
windowWidth(800),
|
||||
@@ -531,9 +532,12 @@ void Project::UnserializeFrom(const SerializerElement & element)
|
||||
#if defined(GD_IDE_ONLY)
|
||||
SetAuthor(propElement.GetChild("author", 0, "Auteur").GetValue().GetString());
|
||||
SetPackageName(propElement.GetStringAttribute("packageName"));
|
||||
SetOrientation(propElement.GetStringAttribute("orientation", "default"));
|
||||
SetFolderProject(propElement.GetBoolAttribute("folderProject"));
|
||||
SetProjectFile(propElement.GetStringAttribute("projectFile"));
|
||||
SetLastCompilationDirectory(propElement.GetChild("latestCompilationDirectory", 0, "LatestCompilationDirectory").GetValue().GetString());
|
||||
platformSpecificAssets.UnserializeFrom(propElement.GetChild("platformSpecificAssets"));
|
||||
loadingScreen.UnserializeFrom(propElement.GetChild("loadingScreen"));
|
||||
winExecutableFilename = propElement.GetStringAttribute("winExecutableFilename");
|
||||
winExecutableIconFile = propElement.GetStringAttribute("winExecutableIconFile");
|
||||
linuxExecutableFilename = propElement.GetStringAttribute("linuxExecutableFilename");
|
||||
@@ -743,6 +747,9 @@ void Project::SerializeTo(SerializerElement & element) const
|
||||
propElement.SetAttribute("projectFile", gameFile);
|
||||
propElement.SetAttribute("folderProject", folderProject);
|
||||
propElement.SetAttribute("packageName", packageName);
|
||||
propElement.SetAttribute("orientation", orientation);
|
||||
platformSpecificAssets.SerializeTo(propElement.AddChild("platformSpecificAssets"));
|
||||
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
|
||||
propElement.SetAttribute("winExecutableFilename", winExecutableFilename);
|
||||
propElement.SetAttribute("winExecutableIconFile", winExecutableIconFile);
|
||||
propElement.SetAttribute("linuxExecutableFilename", linuxExecutableFilename);
|
||||
@@ -815,6 +822,7 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker & worker)
|
||||
{
|
||||
//Add project resources
|
||||
worker.ExposeResources(&GetResourcesManager());
|
||||
platformSpecificAssets.ExposeResources(worker);
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
gd::SafeYield::Do();
|
||||
#endif
|
||||
@@ -1019,8 +1027,11 @@ void Project::Init(const gd::Project & game)
|
||||
#if defined(GD_IDE_ONLY)
|
||||
author = game.author;
|
||||
packageName = game.packageName;
|
||||
orientation = game.orientation;
|
||||
folderProject = game.folderProject;
|
||||
latestCompilationDirectory = game.latestCompilationDirectory;
|
||||
platformSpecificAssets = game.platformSpecificAssets;
|
||||
loadingScreen = game.loadingScreen;
|
||||
objectGroups = game.objectGroups;
|
||||
|
||||
GDMajorVersion = game.GDMajorVersion;
|
||||
|
@@ -16,6 +16,8 @@ class TiXmlElement;
|
||||
#include "GDCore/Project/ChangesNotifier.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
#include "GDCore/Project/PlatformSpecificAssets.h"
|
||||
#include "GDCore/Project/LoadingScreen.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
namespace gd { class Platform; }
|
||||
namespace gd { class Layout; }
|
||||
@@ -85,6 +87,18 @@ public:
|
||||
*/
|
||||
const gd::String & GetPackageName() const { return packageName; }
|
||||
|
||||
/**
|
||||
* \brief Change the project orientation (in particular when exported with Cordova).
|
||||
* This has no effect on desktop and web browsers.
|
||||
* \param orientation The orientation to use ("default", "landscape", "portrait").
|
||||
*/
|
||||
void SetOrientation(const gd::String & orientation_) { orientation = orientation_; };
|
||||
|
||||
/**
|
||||
* \brief Get project orientation ("default", "landscape", "portrait").
|
||||
*/
|
||||
const gd::String & GetOrientation() const { return orientation; }
|
||||
|
||||
/**
|
||||
* Called when project file has changed.
|
||||
*/
|
||||
@@ -118,6 +132,26 @@ public:
|
||||
* \see gd::Project::SetLastCompilationDirectory
|
||||
*/
|
||||
const gd::String & GetLastCompilationDirectory() const {return latestCompilationDirectory;}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to platform assets of the project (icons, splashscreen...).
|
||||
*/
|
||||
gd::PlatformSpecificAssets & GetPlatformSpecificAssets() { return platformSpecificAssets; }
|
||||
|
||||
/**
|
||||
* \brief Return a reference to platform assets of the project (icons, splashscreen...).
|
||||
*/
|
||||
const gd::PlatformSpecificAssets & GetPlatformSpecificAssets() const { return platformSpecificAssets; }
|
||||
|
||||
/**
|
||||
* \brief Return a reference to loading screen setup for the project
|
||||
*/
|
||||
gd::LoadingScreen & GetLoadingScreen() { return loadingScreen; }
|
||||
|
||||
/**
|
||||
* \brief Return a reference to loading screen setup for the project
|
||||
*/
|
||||
const gd::LoadingScreen & GetLoadingScreen() const { return loadingScreen; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -737,10 +771,13 @@ private:
|
||||
gd::ObjectGroupsContainer objectGroups; ///< Global objects groups
|
||||
gd::String author; ///< Game author name
|
||||
gd::String packageName; ///< Game package name
|
||||
gd::String orientation; ///< Lock game orientation (on mobile devices). "default", "landscape" or "portrait".
|
||||
bool folderProject; ///< True if folder project, false if single file project.
|
||||
gd::String gameFile; ///< File of the game
|
||||
gd::String latestCompilationDirectory; ///< File of the game
|
||||
gd::Platform* currentPlatform; ///< The platform being used to edit the project.
|
||||
gd::PlatformSpecificAssets platformSpecificAssets;
|
||||
gd::LoadingScreen loadingScreen;
|
||||
std::vector < std::unique_ptr<gd::ExternalEvents> > externalEvents; ///< List of all externals events
|
||||
mutable unsigned int GDMajorVersion; ///< The GD major version used the last time the project was saved.
|
||||
mutable unsigned int GDMinorVersion; ///< The GD minor version used the last time the project was saved.
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI)
|
||||
#include "GDCore/IDE/wxTools/CommonBitmapProvider.h"
|
||||
#include <wx/filedlg.h>
|
||||
@@ -20,6 +21,7 @@
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
|
||||
namespace gd
|
||||
{
|
||||
@@ -105,7 +107,7 @@ bool ResourcesManager::HasResource(const gd::String & name) const
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<gd::String> ResourcesManager::GetAllResourcesList()
|
||||
std::vector<gd::String> ResourcesManager::GetAllResourceNames()
|
||||
{
|
||||
std::vector<gd::String> allResources;
|
||||
for (std::size_t i = 0;i<resources.size();++i)
|
||||
@@ -114,8 +116,30 @@ std::vector<gd::String> ResourcesManager::GetAllResourcesList()
|
||||
return allResources;
|
||||
}
|
||||
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::PropertyDescriptor> Resource::GetProperties(gd::Project & project) const
|
||||
{
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> ImageResource::GetProperties(gd::Project & project) const
|
||||
{
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Smooth the image")].SetValue(smooth ? "true" : "false").SetType("Boolean");
|
||||
properties[_("Always loaded in memory")].SetValue(alwaysLoaded ? "true" : "false").SetType("Boolean");
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool ImageResource::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
|
||||
{
|
||||
if (name == _("Smooth the image")) smooth = value == "1";
|
||||
else if (name == _("Always loaded in memory")) alwaysLoaded = value == "1";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourcesManager::AddResource(const gd::Resource & resource)
|
||||
{
|
||||
if ( HasResource(resource.GetName()) ) return false;
|
||||
@@ -146,7 +170,7 @@ bool ResourcesManager::AddResource(const gd::String & name, const gd::String & f
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<gd::String> ResourceFolder::GetAllResourcesList()
|
||||
std::vector<gd::String> ResourceFolder::GetAllResourceNames()
|
||||
{
|
||||
std::vector<gd::String> allResources;
|
||||
for (std::size_t i = 0;i<resources.size();++i)
|
||||
@@ -155,61 +179,6 @@ std::vector<gd::String> ResourceFolder::GetAllResourcesList()
|
||||
return allResources;
|
||||
}
|
||||
|
||||
bool ImageResource::EditProperty(gd::Project & project, const gd::String & property)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImageResource::ChangeProperty(gd::Project & project, const gd::String & property, const gd::String & newValue)
|
||||
{
|
||||
if ( property == "smooth" )
|
||||
smooth = (newValue == _("Yes"));
|
||||
else if ( property == "alwaysLoaded" )
|
||||
alwaysLoaded = (newValue == _("Yes"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImageResource::GetPropertyInformation(gd::Project & project, const gd::String & property, gd::String & userFriendlyName, gd::String & description) const
|
||||
{
|
||||
if ( property == "smooth" )
|
||||
{
|
||||
userFriendlyName = _("Smooth the image");
|
||||
description = _("Set this to \"Yes\" to set a smooth filter on the image");
|
||||
}
|
||||
else if ( property == "alwaysLoaded" )
|
||||
{
|
||||
userFriendlyName = _("Always loaded in memory");
|
||||
description = _("Set this to \"Yes\" to let the image always loaded in memory.\nUseful when the image is used by actions.");
|
||||
}
|
||||
}
|
||||
|
||||
gd::String ImageResource::GetProperty(gd::Project & project, const gd::String & property)
|
||||
{
|
||||
if ( property == "smooth" )
|
||||
{
|
||||
return smooth ? _("Yes") : _("No");
|
||||
}
|
||||
else if ( property == "alwaysLoaded" )
|
||||
{
|
||||
return alwaysLoaded ? _("Yes") : _("No");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a vector containing the name of all the properties of the resource
|
||||
*/
|
||||
std::vector<gd::String> ImageResource::GetAllProperties(gd::Project & project) const
|
||||
{
|
||||
std::vector<gd::String> allProperties;
|
||||
allProperties.push_back("smooth");
|
||||
allProperties.push_back("alwaysLoaded");
|
||||
|
||||
return allProperties;
|
||||
}
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
void ImageResource::RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & project)
|
||||
{
|
||||
@@ -351,6 +320,25 @@ bool ResourcesManager::MoveResourceDownInList(const gd::String & name)
|
||||
return gd::MoveResourceDownInList(resources, name);
|
||||
}
|
||||
|
||||
std::size_t ResourcesManager::GetResourcePosition(const gd::String & name) const
|
||||
{
|
||||
for (std::size_t i = 0;i<resources.size();++i)
|
||||
{
|
||||
if (resources[i]->GetName() == name) return i;
|
||||
}
|
||||
return gd::String::npos;
|
||||
}
|
||||
|
||||
void ResourcesManager::MoveResource(std::size_t oldIndex, std::size_t newIndex)
|
||||
{
|
||||
if ( oldIndex >= resources.size() || newIndex >= resources.size() )
|
||||
return;
|
||||
|
||||
auto resource = resources[oldIndex];
|
||||
resources.erase(resources.begin() + oldIndex);
|
||||
resources.insert(resources.begin() + newIndex, resource);
|
||||
}
|
||||
|
||||
bool ResourcesManager::MoveFolderUpInList(const gd::String & name)
|
||||
{
|
||||
for (std::size_t i =1;i<folders.size();++i)
|
||||
|
@@ -6,11 +6,12 @@
|
||||
#ifndef GDCORE_RESOURCESMANAGER_H
|
||||
#define GDCORE_RESOURCESMANAGER_H
|
||||
#include <memory>
|
||||
#include "GDCore/String.h"
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd { class Project; }
|
||||
namespace gd { class ResourceFolder; }
|
||||
namespace gd { class SerializerElement; }
|
||||
namespace gd { class PropertyDescriptor; }
|
||||
class wxPaintDC;
|
||||
class wxPanel;
|
||||
|
||||
@@ -83,37 +84,6 @@ public:
|
||||
*/
|
||||
gd::String GetAbsoluteFile(const gd::Project & game) const;
|
||||
|
||||
/**
|
||||
* \brief Called when a property must be edited (i.e: it was double clicked in a property grid)
|
||||
*
|
||||
* \return true if the resource was changed
|
||||
*/
|
||||
virtual bool EditProperty(gd::Project & project, const gd::String & property) { return true; };
|
||||
|
||||
/**
|
||||
* \brief Called when a property must be changed (i.e: its value was changed in a property grid)
|
||||
*
|
||||
* \return true if the resource was changed
|
||||
*/
|
||||
virtual bool ChangeProperty(gd::Project & project, const gd::String & property, const gd::String & newValue) { return true; };
|
||||
|
||||
/**
|
||||
* \brief Must return a description of the main property provided by the resource (example : "Image file")
|
||||
*/
|
||||
virtual void GetPropertyInformation(gd::Project & project, const gd::String & property, gd::String & userFriendlyName, gd::String & description) const { return; };
|
||||
|
||||
/**
|
||||
* \brief Called when a property must be changed ( i.e: its value was changed in the property grid )
|
||||
*
|
||||
* \return the value of the property
|
||||
*/
|
||||
virtual gd::String GetProperty(gd::Project & project, const gd::String & property) { return ""; };
|
||||
|
||||
/**
|
||||
* \brief Return a description of the main property provided by the resource ( Example : "Image file" )
|
||||
*/
|
||||
virtual std::vector<gd::String> GetAllProperties(gd::Project & project) const { std::vector<gd::String> noProperties; return noProperties; };
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
/**
|
||||
* \brief Called when the resource must be rendered in a preview panel.
|
||||
@@ -121,6 +91,36 @@ public:
|
||||
virtual void RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & game) {};
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/** \name Resources properties
|
||||
* Reading and updating resources properties
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the resource.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[ToString(_("Text"))].SetValue("Hello world!");
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the resource
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
*/
|
||||
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project) {return false;};
|
||||
///@}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Serialize the object
|
||||
*/
|
||||
@@ -150,69 +150,41 @@ class GD_CORE_API ImageResource : public Resource
|
||||
public:
|
||||
ImageResource() : Resource(), smooth(true), alwaysLoaded(false) { SetKind("image"); };
|
||||
virtual ~ImageResource() {};
|
||||
virtual ImageResource* Clone() const { return new ImageResource(*this);}
|
||||
virtual ImageResource* Clone() const override { return new ImageResource(*this);}
|
||||
|
||||
/**
|
||||
* Return the file used by the resource.
|
||||
*/
|
||||
virtual const gd::String & GetFile() const {return file;};
|
||||
virtual const gd::String & GetFile() const override {return file;};
|
||||
|
||||
/**
|
||||
* Change the file of the resource.
|
||||
*/
|
||||
virtual void SetFile(const gd::String & newFile);
|
||||
virtual void SetFile(const gd::String & newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() { return true; }
|
||||
virtual bool UseFile() override { return true; }
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
/**
|
||||
* Called when the resource must be rendered in a preview panel.
|
||||
*/
|
||||
virtual void RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & game);
|
||||
virtual void RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & game) override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Called when a property must be edited ( i.e: it was double clicked )
|
||||
*
|
||||
* \return true if the resource was changed
|
||||
*/
|
||||
virtual bool EditProperty(gd::Project & project, const gd::String & property);
|
||||
|
||||
/**
|
||||
* Called when a property must be changed ( i.e: its value was changed in the property grid )
|
||||
*
|
||||
* \return true if the resource was changed
|
||||
*/
|
||||
virtual bool ChangeProperty(gd::Project & project, const gd::String & property, const gd::String & newValue);
|
||||
|
||||
/**
|
||||
* Called when a property must be changed ( i.e: its value was changed in the property grid )
|
||||
*
|
||||
* \return the value of the property
|
||||
*/
|
||||
virtual gd::String GetProperty(gd::Project & project, const gd::String & property);
|
||||
|
||||
/**
|
||||
* Return a description of the main property provided by the resource ( Example : "Image file" )
|
||||
*/
|
||||
virtual void GetPropertyInformation(gd::Project & project, const gd::String & property, gd::String & userFriendlyName, gd::String & description) const;
|
||||
|
||||
/**
|
||||
* Return a vector containing the name of all the properties of the resource
|
||||
*/
|
||||
virtual std::vector<gd::String> GetAllProperties(gd::Project & project) const;
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const override;
|
||||
bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project) override;
|
||||
|
||||
/**
|
||||
* \brief Serialize the object
|
||||
*/
|
||||
void SerializeTo(SerializerElement & element) const;
|
||||
void SerializeTo(SerializerElement & element) const override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unserialize the objectt.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement & element);
|
||||
void UnserializeFrom(const SerializerElement & element) override;
|
||||
|
||||
/**
|
||||
* \brief Return true if the image should be smoothed.
|
||||
@@ -242,17 +214,17 @@ class GD_CORE_API AudioResource : public Resource
|
||||
public:
|
||||
AudioResource() : Resource() { SetKind("audio"); };
|
||||
virtual ~AudioResource() {};
|
||||
virtual AudioResource* Clone() const { return new AudioResource(*this);}
|
||||
virtual AudioResource* Clone() const override { return new AudioResource(*this);}
|
||||
|
||||
virtual const gd::String & GetFile() const {return file;};
|
||||
virtual void SetFile(const gd::String & newFile);
|
||||
virtual const gd::String & GetFile() const override {return file;};
|
||||
virtual void SetFile(const gd::String & newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() { return true; }
|
||||
void SerializeTo(SerializerElement & element) const;
|
||||
virtual bool UseFile() override { return true; }
|
||||
void SerializeTo(SerializerElement & element) const override;
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const SerializerElement & element);
|
||||
void UnserializeFrom(const SerializerElement & element) override;
|
||||
|
||||
private:
|
||||
gd::String file;
|
||||
@@ -293,9 +265,9 @@ public:
|
||||
std::shared_ptr<Resource> CreateResource(const gd::String & kind);
|
||||
|
||||
/**
|
||||
* \brief Get a list containing the name of all of the resources.
|
||||
* \brief Get a list containing the names of all resources.
|
||||
*/
|
||||
std::vector<gd::String> GetAllResourcesList();
|
||||
std::vector<gd::String> GetAllResourceNames();
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
@@ -324,6 +296,11 @@ public:
|
||||
*/
|
||||
void RenameResource(const gd::String & oldName, const gd::String & newName);
|
||||
|
||||
/**
|
||||
* \brief Return the position of the layer called "name" in the layers list
|
||||
*/
|
||||
std::size_t GetResourcePosition(const gd::String & name) const;
|
||||
|
||||
/**
|
||||
* \brief Move a resource up in the list
|
||||
*/
|
||||
@@ -334,6 +311,11 @@ public:
|
||||
*/
|
||||
bool MoveResourceDownInList(const gd::String & name);
|
||||
|
||||
/**
|
||||
* Change the position of the specified resource.
|
||||
*/
|
||||
void MoveResource(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Return true if the folder exists.
|
||||
*/
|
||||
@@ -445,7 +427,7 @@ public:
|
||||
/**
|
||||
* Get a list containing the name of all of the resources.
|
||||
*/
|
||||
virtual std::vector<gd::String> GetAllResourcesList();
|
||||
virtual std::vector<gd::String> GetAllResourceNames();
|
||||
|
||||
/**
|
||||
* Move a resource up in the list
|
||||
|
@@ -5,24 +5,23 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/String.h"
|
||||
#include <sstream>
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd
|
||||
{
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* Get value as a double
|
||||
*/
|
||||
double Variable::GetValue() const
|
||||
{
|
||||
if (!isNumber)
|
||||
{
|
||||
stringstream ss; ss << str;
|
||||
if (!isNumber) {
|
||||
stringstream ss;
|
||||
ss << str;
|
||||
ss >> value;
|
||||
isNumber = true;
|
||||
}
|
||||
@@ -30,11 +29,11 @@ double Variable::GetValue() const
|
||||
return value;
|
||||
}
|
||||
|
||||
const gd::String & Variable::GetString() const
|
||||
const gd::String& Variable::GetString() const
|
||||
{
|
||||
if (isNumber)
|
||||
{
|
||||
stringstream s; s << (value);
|
||||
if (isNumber) {
|
||||
stringstream s;
|
||||
s << (value);
|
||||
str = s.str();
|
||||
isNumber = false;
|
||||
}
|
||||
@@ -42,7 +41,7 @@ const gd::String & Variable::GetString() const
|
||||
return str;
|
||||
}
|
||||
|
||||
bool Variable::HasChild(const gd::String & name) const
|
||||
bool Variable::HasChild(const gd::String& name) const
|
||||
{
|
||||
return isStructure && children.find(name) != children.end();
|
||||
}
|
||||
@@ -53,15 +52,15 @@ bool Variable::HasChild(const gd::String & name) const
|
||||
* If the variable is not a structure or has not
|
||||
* the specified child, an empty variable is returned.
|
||||
*/
|
||||
Variable & Variable::GetChild(const gd::String & name)
|
||||
Variable& Variable::GetChild(const gd::String& name)
|
||||
{
|
||||
std::map<gd::String, Variable>::iterator it = children.find(name);
|
||||
if ( it != children.end() ) return it->second;
|
||||
auto it = children.find(name);
|
||||
if (it != children.end())
|
||||
return *it->second;
|
||||
|
||||
isStructure = true;
|
||||
Variable newEmptyVariable;
|
||||
children[name] = newEmptyVariable;
|
||||
return children[name];
|
||||
children[name] = std::make_shared<gd::Variable>();
|
||||
return *children[name];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,26 +69,28 @@ Variable & Variable::GetChild(const gd::String & name)
|
||||
* If the variable is not a structure or has not
|
||||
* the specified child, an empty variable is returned.
|
||||
*/
|
||||
const Variable & Variable::GetChild(const gd::String & name) const
|
||||
const Variable& Variable::GetChild(const gd::String& name) const
|
||||
{
|
||||
std::map<gd::String, Variable>::iterator it = children.find(name);
|
||||
if ( it != children.end() ) return it->second;
|
||||
auto it = children.find(name);
|
||||
if (it != children.end())
|
||||
return *it->second;
|
||||
|
||||
isStructure = true;
|
||||
Variable newEmptyVariable;
|
||||
children[name] = newEmptyVariable;
|
||||
return children[name];
|
||||
children[name] = std::make_shared<gd::Variable>();
|
||||
return *children[name];
|
||||
}
|
||||
|
||||
void Variable::RemoveChild(const gd::String & name)
|
||||
void Variable::RemoveChild(const gd::String& name)
|
||||
{
|
||||
if ( !isStructure ) return;
|
||||
if (!isStructure)
|
||||
return;
|
||||
children.erase(name);
|
||||
}
|
||||
|
||||
bool Variable::RenameChild(const gd::String & oldName, const gd::String & newName)
|
||||
bool Variable::RenameChild(const gd::String& oldName, const gd::String& newName)
|
||||
{
|
||||
if ( !isStructure || !HasChild(oldName)|| HasChild(newName) ) return false;
|
||||
if (!isStructure || !HasChild(oldName) || HasChild(newName))
|
||||
return false;
|
||||
|
||||
children[newName] = children[oldName];
|
||||
children.erase(oldName);
|
||||
@@ -99,91 +100,114 @@ bool Variable::RenameChild(const gd::String & oldName, const gd::String & newNam
|
||||
|
||||
void Variable::ClearChildren()
|
||||
{
|
||||
if ( !isStructure ) return;
|
||||
if (!isStructure)
|
||||
return;
|
||||
children.clear();
|
||||
}
|
||||
|
||||
void Variable::SerializeTo(SerializerElement & element) const
|
||||
void Variable::SerializeTo(SerializerElement& element) const
|
||||
{
|
||||
if (!isStructure)
|
||||
element.SetAttribute("value", GetString());
|
||||
else
|
||||
{
|
||||
SerializerElement & childrenElement = element.AddChild("children");
|
||||
else {
|
||||
SerializerElement& childrenElement = element.AddChild("children");
|
||||
childrenElement.ConsiderAsArrayOf("variable");
|
||||
for (std::map<gd::String, gd::Variable>::iterator i = children.begin(); i != children.end(); ++i)
|
||||
{
|
||||
SerializerElement & variableElement = childrenElement.AddChild("variable");
|
||||
for (auto i = children.begin(); i != children.end(); ++i) {
|
||||
SerializerElement& variableElement = childrenElement.AddChild("variable");
|
||||
variableElement.SetAttribute("name", i->first);
|
||||
i->second.SerializeTo(variableElement);
|
||||
i->second->SerializeTo(variableElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Variable::UnserializeFrom(const SerializerElement & element)
|
||||
void Variable::UnserializeFrom(const SerializerElement& element)
|
||||
{
|
||||
isStructure = element.HasChild("children", "Children");
|
||||
|
||||
if (isStructure)
|
||||
{
|
||||
const SerializerElement & childrenElement = element.GetChild("children", 0, "Children");
|
||||
if (isStructure) {
|
||||
const SerializerElement& childrenElement = element.GetChild("children", 0, "Children");
|
||||
childrenElement.ConsiderAsArrayOf("variable", "Variable");
|
||||
for (int i = 0; i < childrenElement.GetChildrenCount(); ++i)
|
||||
{
|
||||
const SerializerElement & childElement = childrenElement.GetChild(i);
|
||||
for (int i = 0; i < childrenElement.GetChildrenCount(); ++i) {
|
||||
const SerializerElement& childElement = childrenElement.GetChild(i);
|
||||
gd::String name = childElement.GetStringAttribute("name", "", "Name");
|
||||
|
||||
gd::Variable childVariable;
|
||||
childVariable.UnserializeFrom(childElement);
|
||||
children[name] = childVariable;
|
||||
children[name] = std::make_shared<gd::Variable>();
|
||||
children[name]->UnserializeFrom(childElement);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
SetString(element.GetStringAttribute("value", "", "Value"));
|
||||
}
|
||||
|
||||
void Variable::SaveToXml(TiXmlElement * element) const
|
||||
void Variable::SaveToXml(TiXmlElement* element) const
|
||||
{
|
||||
if (!element) return;
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
if ( !isStructure )
|
||||
if (!isStructure)
|
||||
element->SetAttribute("Value", GetString().c_str());
|
||||
else
|
||||
{
|
||||
TiXmlElement * childrenElem = new TiXmlElement( "Children" );
|
||||
element->LinkEndChild( childrenElem );
|
||||
for (std::map<gd::String, gd::Variable>::iterator i = children.begin(); i != children.end(); ++i)
|
||||
{
|
||||
TiXmlElement * variable = new TiXmlElement( "Variable" );
|
||||
childrenElem->LinkEndChild( variable );
|
||||
else {
|
||||
TiXmlElement* childrenElem = new TiXmlElement("Children");
|
||||
element->LinkEndChild(childrenElem);
|
||||
for (auto i = children.begin(); i != children.end(); ++i) {
|
||||
TiXmlElement* variable = new TiXmlElement("Variable");
|
||||
childrenElem->LinkEndChild(variable);
|
||||
|
||||
variable->SetAttribute("Name", i->first.c_str());
|
||||
i->second.SaveToXml(variable);
|
||||
i->second->SaveToXml(variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Variable::LoadFromXml(const TiXmlElement * element)
|
||||
void Variable::LoadFromXml(const TiXmlElement* element)
|
||||
{
|
||||
if (!element) return;
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
isStructure = element->FirstChildElement("Children") != NULL;
|
||||
|
||||
if ( isStructure )
|
||||
{
|
||||
const TiXmlElement * child = element->FirstChildElement("Children")->FirstChildElement();
|
||||
while ( child )
|
||||
{
|
||||
if (isStructure) {
|
||||
const TiXmlElement* child = element->FirstChildElement("Children")->FirstChildElement();
|
||||
while (child) {
|
||||
gd::String name = child->Attribute("Name") ? child->Attribute("Name") : "";
|
||||
gd::Variable childVariable;
|
||||
childVariable.LoadFromXml(child);
|
||||
children[name] = childVariable;
|
||||
children[name] = std::make_shared<gd::Variable>();
|
||||
children[name]->LoadFromXml(child);
|
||||
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
else if (element->Attribute("Value"))
|
||||
} else if (element->Attribute("Value"))
|
||||
SetString(element->Attribute("Value"));
|
||||
}
|
||||
|
||||
std::vector<gd::String> Variable::GetAllChildrenNames() const
|
||||
{
|
||||
std::vector<gd::String> names;
|
||||
for (auto& it : children) {
|
||||
names.push_back(it.first);
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
bool Variable::Contains(const gd::Variable& variableToSearch, bool recursive) const
|
||||
{
|
||||
for (auto& it : children) {
|
||||
if (it.second.get() == &variableToSearch)
|
||||
return true;
|
||||
if (recursive && it.second->Contains(variableToSearch, true))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Variable::RemoveRecursively(const gd::Variable& variableToRemove)
|
||||
{
|
||||
for (auto it = children.begin(); it != children.end();) {
|
||||
if (it->second.get() == &variableToRemove) {
|
||||
it = children.erase(it);
|
||||
} else {
|
||||
it->second->RemoveRecursively(variableToRemove);
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#define GDCORE_VARIABLE_H
|
||||
#include "GDCore/String.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
namespace gd { class SerializerElement; }
|
||||
class TiXmlElement;
|
||||
|
||||
@@ -148,11 +149,30 @@ public:
|
||||
*/
|
||||
void ClearChildren();
|
||||
|
||||
/**
|
||||
* \brief Get the count of children that the variable has.
|
||||
*/
|
||||
size_t GetChildrenCount() const { return children.size(); };
|
||||
|
||||
/**
|
||||
* \brief Get the names of all children
|
||||
*/
|
||||
std::vector<gd::String> GetAllChildrenNames() const;
|
||||
|
||||
/**
|
||||
* \brief Get the map containing all the children.
|
||||
*/
|
||||
const std::map<gd::String, Variable> & GetAllChildren() const { return children; }
|
||||
const std::map<gd::String, std::shared_ptr<Variable>> & GetAllChildren() const { return children; }
|
||||
|
||||
/**
|
||||
* \brief Search if a variable is part of the children, optionally recursively
|
||||
*/
|
||||
bool Contains(const gd::Variable & variableToSearch, bool recursive) const;
|
||||
|
||||
/**
|
||||
* \brief Remove the specified variable if it can be found in the children
|
||||
*/
|
||||
void RemoveRecursively(const gd::Variable & variableToRemove);
|
||||
///@}
|
||||
|
||||
/** \name Serialization
|
||||
@@ -186,7 +206,7 @@ private:
|
||||
mutable gd::String str;
|
||||
mutable bool isNumber; ///< True if the type of the variable is a number.
|
||||
mutable bool isStructure; ///< False when the variable is a primitive ( i.e: Number or String ), true when it is a structure and has may have children.
|
||||
mutable std::map<gd::String, Variable> children; ///<Children, when the variable is considered as a structure.
|
||||
mutable std::map<gd::String, std::shared_ptr<Variable>> children; ///<Children, when the variable is considered as a structure.
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -3,177 +3,192 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "GDCore/String.h"
|
||||
#include <algorithm>
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
namespace gd
|
||||
{
|
||||
namespace gd {
|
||||
|
||||
std::pair<gd::String, Variable> VariablesContainer::badVariable;
|
||||
gd::Variable VariablesContainer::badVariable;
|
||||
gd::String VariablesContainer::badName;
|
||||
|
||||
namespace {
|
||||
|
||||
//Tool functor used below
|
||||
class VariableHasName
|
||||
{
|
||||
public:
|
||||
VariableHasName(gd::String const& name_) : name(name_) { }
|
||||
//Tool functor used below
|
||||
class VariableHasName {
|
||||
public:
|
||||
VariableHasName(gd::String const& name_)
|
||||
: name(name_)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator () (const std::pair<gd::String, gd::Variable> & p)
|
||||
{
|
||||
return (p.first == name);
|
||||
}
|
||||
|
||||
gd::String name;
|
||||
};
|
||||
bool operator()(const std::pair<gd::String, std::shared_ptr<gd::Variable>>& p)
|
||||
{
|
||||
return (p.first == name);
|
||||
}
|
||||
|
||||
gd::String name;
|
||||
};
|
||||
}
|
||||
|
||||
VariablesContainer::VariablesContainer()
|
||||
{
|
||||
}
|
||||
|
||||
bool VariablesContainer::Has(const gd::String & name) const
|
||||
bool VariablesContainer::Has(const gd::String& name) const
|
||||
{
|
||||
std::vector < std::pair<gd::String, gd::Variable> >::const_iterator i =
|
||||
std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
||||
auto i = std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
||||
return (i != variables.end());
|
||||
}
|
||||
|
||||
std::pair<gd::String, gd::Variable> & VariablesContainer::Get(std::size_t index)
|
||||
Variable& VariablesContainer::Get(const gd::String& name)
|
||||
{
|
||||
if ( index < variables.size() )
|
||||
return variables[index];
|
||||
auto i = std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
||||
if (i != variables.end())
|
||||
return *i->second;
|
||||
|
||||
return badVariable;
|
||||
}
|
||||
|
||||
const std::pair<gd::String, gd::Variable> & VariablesContainer::Get(std::size_t index) const
|
||||
const Variable& VariablesContainer::Get(const gd::String& name) const
|
||||
{
|
||||
if ( index < variables.size() )
|
||||
return variables[index];
|
||||
auto i = std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
||||
if (i != variables.end())
|
||||
return *i->second;
|
||||
|
||||
return badVariable;
|
||||
}
|
||||
|
||||
Variable & VariablesContainer::Get(const gd::String & name)
|
||||
Variable & VariablesContainer::Get(std::size_t index)
|
||||
{
|
||||
std::vector < std::pair<gd::String, gd::Variable> >::iterator i =
|
||||
std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
||||
if (i != variables.end())
|
||||
return i->second;
|
||||
if (index < variables.size())
|
||||
return *variables[index].second;
|
||||
|
||||
return badVariable.second;
|
||||
return badVariable;
|
||||
}
|
||||
|
||||
const Variable & VariablesContainer::Get(const gd::String & name) const
|
||||
const Variable & VariablesContainer::Get(std::size_t index) const
|
||||
{
|
||||
std::vector < std::pair<gd::String, gd::Variable> >::const_iterator i =
|
||||
std::find_if(variables.begin(), variables.end(), VariableHasName(name));
|
||||
if (i != variables.end())
|
||||
return i->second;
|
||||
if (index < variables.size())
|
||||
return *variables[index].second;
|
||||
|
||||
return badVariable.second;
|
||||
return badVariable;
|
||||
}
|
||||
|
||||
Variable & VariablesContainer::Insert(const gd::String & name, const gd::Variable & variable, std::size_t position)
|
||||
const gd::String & VariablesContainer::GetNameAt(std::size_t index) const
|
||||
{
|
||||
if (position<variables.size())
|
||||
{
|
||||
variables.insert(variables.begin()+position, std::make_pair(name, variable));
|
||||
return variables[position].second;
|
||||
}
|
||||
else
|
||||
{
|
||||
variables.push_back(std::make_pair(name, variable));
|
||||
return variables.back().second;
|
||||
if (index < variables.size())
|
||||
return variables[index].first;
|
||||
|
||||
return badName;
|
||||
}
|
||||
|
||||
Variable& VariablesContainer::Insert(const gd::String& name, const gd::Variable& variable, std::size_t position)
|
||||
{
|
||||
auto newVariable = std::make_shared<gd::Variable>(variable);
|
||||
if (position < variables.size()) {
|
||||
variables.insert(variables.begin() + position, std::make_pair(name, newVariable));
|
||||
return *variables[position].second;
|
||||
} else {
|
||||
variables.push_back(std::make_pair(name, newVariable));
|
||||
return *variables.back().second;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void VariablesContainer::Remove(const gd::String & varName)
|
||||
void VariablesContainer::Remove(const gd::String& varName)
|
||||
{
|
||||
variables.erase(std::remove_if(variables.begin(), variables.end(),
|
||||
VariableHasName(varName)), variables.end() );
|
||||
VariableHasName(varName)),
|
||||
variables.end());
|
||||
}
|
||||
|
||||
std::size_t VariablesContainer::GetPosition(const gd::String & name) const
|
||||
void VariablesContainer::RemoveRecursively(const gd::Variable& variableToRemove)
|
||||
{
|
||||
for(std::size_t i = 0;i<variables.size();++i)
|
||||
{
|
||||
if ( variables[i].first == name )
|
||||
variables.erase(std::remove_if(variables.begin(), variables.end(),
|
||||
[&variableToRemove](const std::pair<gd::String, std::shared_ptr<gd::Variable>>& nameAndVariable) {
|
||||
return &variableToRemove == nameAndVariable.second.get();
|
||||
}),
|
||||
variables.end());
|
||||
|
||||
for (auto& it : variables) {
|
||||
it.second->RemoveRecursively(variableToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t VariablesContainer::GetPosition(const gd::String& name) const
|
||||
{
|
||||
for (std::size_t i = 0; i < variables.size(); ++i) {
|
||||
if (variables[i].first == name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return gd::String::npos;
|
||||
}
|
||||
|
||||
Variable & VariablesContainer::InsertNew(const gd::String & name, std::size_t position)
|
||||
Variable& VariablesContainer::InsertNew(const gd::String& name, std::size_t position)
|
||||
{
|
||||
Variable newVariable;
|
||||
return Insert(name, newVariable, position);
|
||||
}
|
||||
|
||||
bool VariablesContainer::Rename(const gd::String & oldName, const gd::String & newName)
|
||||
bool VariablesContainer::Rename(const gd::String& oldName, const gd::String& newName)
|
||||
{
|
||||
if (Has(newName)) return false;
|
||||
if (Has(newName))
|
||||
return false;
|
||||
|
||||
std::vector < std::pair<gd::String, gd::Variable> >::iterator i =
|
||||
std::find_if(variables.begin(), variables.end(), VariableHasName(oldName));
|
||||
if (i != variables.end()) i->first = newName;
|
||||
auto i = std::find_if(variables.begin(), variables.end(), VariableHasName(oldName));
|
||||
if (i != variables.end())
|
||||
i->first = newName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VariablesContainer::Swap(std::size_t firstVariableIndex, std::size_t secondVariableIndex)
|
||||
{
|
||||
if ( firstVariableIndex >= variables.size() || secondVariableIndex >= variables.size() )
|
||||
if (firstVariableIndex >= variables.size() || secondVariableIndex >= variables.size())
|
||||
return;
|
||||
|
||||
std::pair<gd::String, gd::Variable> temp = variables[firstVariableIndex];
|
||||
auto temp = variables[firstVariableIndex];
|
||||
variables[firstVariableIndex] = variables[secondVariableIndex];
|
||||
variables[secondVariableIndex] = temp;
|
||||
}
|
||||
|
||||
void VariablesContainer::Move(std::size_t oldIndex, std::size_t newIndex)
|
||||
{
|
||||
if ( oldIndex >= variables.size() || newIndex >= variables.size() )
|
||||
if (oldIndex >= variables.size() || newIndex >= variables.size())
|
||||
return;
|
||||
|
||||
auto nameAndVariable = variables[oldIndex];
|
||||
variables.erase(variables.begin() + oldIndex);
|
||||
Insert(nameAndVariable.first, nameAndVariable.second, newIndex);
|
||||
variables.insert(variables.begin() + newIndex, nameAndVariable);
|
||||
}
|
||||
#endif
|
||||
|
||||
void VariablesContainer::SerializeTo(SerializerElement & element) const
|
||||
void VariablesContainer::SerializeTo(SerializerElement& element) const
|
||||
{
|
||||
element.ConsiderAsArrayOf("variable");
|
||||
for ( std::size_t j = 0;j < variables.size();j++ )
|
||||
{
|
||||
SerializerElement & variableElement = element.AddChild("variable");
|
||||
for (std::size_t j = 0; j < variables.size(); j++) {
|
||||
SerializerElement& variableElement = element.AddChild("variable");
|
||||
variableElement.SetAttribute("name", variables[j].first);
|
||||
variables[j].second.SerializeTo(variableElement);
|
||||
variables[j].second->SerializeTo(variableElement);
|
||||
}
|
||||
}
|
||||
|
||||
void VariablesContainer::UnserializeFrom(const SerializerElement & element)
|
||||
void VariablesContainer::UnserializeFrom(const SerializerElement& element)
|
||||
{
|
||||
Clear();
|
||||
element.ConsiderAsArrayOf("variable", "Variable");
|
||||
for ( std::size_t j = 0;j < element.GetChildrenCount();j++ )
|
||||
{
|
||||
const SerializerElement & variableElement = element.GetChild(j);
|
||||
for (std::size_t j = 0; j < element.GetChildrenCount(); j++) {
|
||||
const SerializerElement& variableElement = element.GetChild(j);
|
||||
|
||||
Variable variable;
|
||||
variable.UnserializeFrom(variableElement);
|
||||
Insert(variableElement.GetStringAttribute("name", "", "Name" ), variable, -1);
|
||||
Insert(variableElement.GetStringAttribute("name", "", "Name"), variable, -1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#define GDCORE_VARIABLESCONTAINER_H
|
||||
#include "GDCore/String.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "GDCore/Project/Variable.h"
|
||||
namespace gd { class SerializerElement; }
|
||||
class TiXmlElement;
|
||||
@@ -52,18 +53,14 @@ public:
|
||||
const Variable & Get(const gd::String & name) const;
|
||||
|
||||
/**
|
||||
* \brief Return a pair containing the name and the variable at position \index in the container.
|
||||
*
|
||||
* \note If index is invalid, an empty variable is returned.
|
||||
* \brief Return a reference to the variable at the specified position in the list.
|
||||
*/
|
||||
std::pair<gd::String, gd::Variable> & Get(std::size_t index);
|
||||
Variable & Get(std::size_t index);
|
||||
|
||||
/**
|
||||
* \brief Return a pair containing the name and the variable at position \index in the container.
|
||||
*
|
||||
* \note If index is invalid, an empty variable is returned.
|
||||
* \brief Return a reference to the variable at the specified position in the list.
|
||||
*/
|
||||
const std::pair<gd::String, gd::Variable> & Get(std::size_t index) const;
|
||||
const Variable & Get(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Must add a new variable constructed from the variable passed as parameter.
|
||||
@@ -79,6 +76,11 @@ public:
|
||||
*/
|
||||
std::size_t Count() const { return variables.size(); };
|
||||
|
||||
/**
|
||||
* \brief Return the name of the variable at a position
|
||||
*/
|
||||
const gd::String & GetNameAt(std::size_t index) const;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief return the position of the variable called "name" in the variable list
|
||||
@@ -94,10 +96,16 @@ public:
|
||||
Variable & InsertNew(const gd::String & name, std::size_t position = -1);
|
||||
|
||||
/**
|
||||
* \brief Remove the specified variable from the container.
|
||||
* \brief Remove the variable with the specified name from the container.
|
||||
* \note This operation is not recursive on variable children
|
||||
*/
|
||||
void Remove(const gd::String & name);
|
||||
|
||||
/**
|
||||
* \brief Remove the specified variable from the container.
|
||||
*/
|
||||
void RemoveRecursively(const gd::Variable & variable);
|
||||
|
||||
/**
|
||||
* \brief Rename a variable.
|
||||
* \return true if the variable was renamed, false otherwise.
|
||||
@@ -138,8 +146,9 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
std::vector < std::pair<gd::String, gd::Variable> > variables;
|
||||
static std::pair<gd::String, Variable> badVariable;
|
||||
std::vector < std::pair<gd::String, std::shared_ptr<gd::Variable>> > variables;
|
||||
static gd::Variable badVariable;
|
||||
static gd::String badName;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -84,7 +84,7 @@ TEST_CASE( "Resources", "[common][resources]" ) {
|
||||
|
||||
gd::ProjectResourcesAdder::RemoveAllUselessImages(project);
|
||||
std::vector<gd::String> remainingResources =
|
||||
project.GetResourcesManager().GetAllResourcesList();
|
||||
project.GetResourcesManager().GetAllResourceNames();
|
||||
REQUIRE(remainingResources.size() == 2);
|
||||
REQUIRE(remainingResources[0] == "res1");
|
||||
REQUIRE(remainingResources[1] == "res4");
|
||||
|
@@ -21,7 +21,7 @@ class GD_EXTENSION_API AdMobObject : public gd::Object
|
||||
public:
|
||||
AdMobObject(gd::String name_);
|
||||
virtual ~AdMobObject() {};
|
||||
virtual std::unique_ptr<gd::Object> Clone() const { return gd::make_unique<AdMobObject>(*this); }
|
||||
virtual std::unique_ptr<gd::Object> Clone() const override { return gd::make_unique<AdMobObject>(*this); }
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
void DrawInitialInstance(gd::InitialInstance & instance, sf::RenderTarget & renderTarget, gd::Project & project, gd::Layout & layout) override;
|
||||
|
@@ -10,7 +10,7 @@ include(CMakeUtils.txt) #Functions to factor common tasks done in CMakeLists.txt
|
||||
#Add all the CMakeLists:
|
||||
ADD_SUBDIRECTORY(AdMobObject)
|
||||
ADD_SUBDIRECTORY(AnchorBehavior)
|
||||
IF (NOT EMSCRIPTEN) #Only add some extensions when compiling with emscripten.
|
||||
IF (NOT EMSCRIPTEN)
|
||||
ADD_SUBDIRECTORY(AdvancedXML)
|
||||
ADD_SUBDIRECTORY(AES)
|
||||
ADD_SUBDIRECTORY(Box3DObject)
|
||||
@@ -35,9 +35,9 @@ ENDIF()
|
||||
ADD_SUBDIRECTORY(PanelSpriteObject)
|
||||
IF (NOT EMSCRIPTEN)
|
||||
ADD_SUBDIRECTORY(PathBehavior)
|
||||
ADD_SUBDIRECTORY(PathfindingBehavior)
|
||||
ADD_SUBDIRECTORY(PhysicsBehavior)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(PathfindingBehavior)
|
||||
ADD_SUBDIRECTORY(PhysicsBehavior)
|
||||
ADD_SUBDIRECTORY(PlatformBehavior)
|
||||
ADD_SUBDIRECTORY(PrimitiveDrawing)
|
||||
ADD_SUBDIRECTORY(Shopify)
|
||||
|
@@ -66,11 +66,11 @@ public:
|
||||
for(auto & child : variable.GetAllChildren())
|
||||
{
|
||||
const gd::String & name = child.first;
|
||||
const gd::Variable & serializedItem = child.second;
|
||||
inventory.SetMaximum(name, serializedItem.GetChild("maxCount").GetValue());
|
||||
inventory.SetUnlimited(name, serializedItem.GetChild("unlimited").GetString() == "true");
|
||||
inventory.SetCount(name, serializedItem.GetChild("count").GetValue());
|
||||
inventory.Equip(name, serializedItem.GetChild("equipped").GetString() == "true");
|
||||
const auto & serializedItem = child.second;
|
||||
inventory.SetMaximum(name, serializedItem->GetChild("maxCount").GetValue());
|
||||
inventory.SetUnlimited(name, serializedItem->GetChild("unlimited").GetString() == "true");
|
||||
inventory.SetCount(name, serializedItem->GetChild("count").GetValue());
|
||||
inventory.Equip(name, serializedItem->GetChild("equipped").GetString() == "true");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,11 +4,11 @@
|
||||
Light_Manager::Light_Manager() :
|
||||
commonBlurEffectLoaded(false)
|
||||
{
|
||||
std::cout << "Creating Light Manager";
|
||||
std::cout << "Creating Light Manager" << std::endl;
|
||||
}
|
||||
Light_Manager::~Light_Manager()
|
||||
{
|
||||
std::cout << "Destroying Light Manager";
|
||||
std::cout << "Destroying Light Manager" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -7,8 +7,6 @@ This project is released under the MIT License.
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void DeclarePanelSpriteObjectExtension(gd::PlatformExtension & extension);
|
||||
|
@@ -322,13 +322,13 @@ PathBehaviorEditor::PathBehaviorEditor(wxWindow* parent, gd::Project & game_, gd
|
||||
followAngleCheck->SetValue(behavior.FollowAngle());
|
||||
|
||||
//Setup shared datas
|
||||
if ( !scene || scene->behaviorsInitialSharedDatas.find(behavior.GetName()) == scene->behaviorsInitialSharedDatas.end())
|
||||
if (!scene || !scene->HasBehaviorSharedData(behavior.GetName()))
|
||||
{
|
||||
gd::LogError(_("Unable to access to shared datas."));
|
||||
return;
|
||||
}
|
||||
|
||||
sharedDatas = std::dynamic_pointer_cast<ScenePathDatas>(scene->behaviorsInitialSharedDatas[behavior.GetName()]);
|
||||
sharedDatas = std::dynamic_pointer_cast<ScenePathDatas>(scene->GetBehaviorSharedDataSmartPtr(behavior.GetName()));
|
||||
|
||||
if ( sharedDatas == std::shared_ptr<ScenePathDatas>() )
|
||||
{
|
||||
|
@@ -8,26 +8,21 @@ This project is released under the MIT License.
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
#include <iostream>
|
||||
void DeclarePathfindingBehaviorExtension(gd::PlatformExtension & extension);
|
||||
|
||||
/**
|
||||
* \brief This class declares information about the JS extension.
|
||||
*/
|
||||
class JsExtension : public gd::PlatformExtension
|
||||
class PathfindingBehaviorJsExtension : public gd::PlatformExtension
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
JsExtension()
|
||||
PathfindingBehaviorJsExtension()
|
||||
{
|
||||
SetExtensionInformation("PathfindingBehavior",
|
||||
_("Pathfinding behavior"),
|
||||
_("Compute paths for objects avoiding obstacles."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)");
|
||||
CloneExtension("GDevelop C++ platform", "PathfindingBehavior");
|
||||
DeclarePathfindingBehaviorExtension(*this);
|
||||
|
||||
GetBehaviorMetadata("PathfindingBehavior::PathfindingBehavior")
|
||||
.SetIncludeFile("Extensions/PathfindingBehavior/pathfindingruntimebehavior.js")
|
||||
@@ -103,14 +98,21 @@ public:
|
||||
}
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions();
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(EMSCRIPTEN)
|
||||
extern "C" gd::PlatformExtension * CreateGDJSPathfindingBehaviorExtension() {
|
||||
return new PathfindingBehaviorJsExtension;
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Used by GDevelop to create the extension class
|
||||
* -- Do not need to be modified. --
|
||||
*/
|
||||
extern "C" gd::PlatformExtension * GD_EXTENSION_API CreateGDJSExtension() {
|
||||
return new JsExtension;
|
||||
return new PathfindingBehaviorJsExtension;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -6,29 +6,23 @@ This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
void DeclarePhysicsBehaviorExtension(gd::PlatformExtension & extension);
|
||||
|
||||
/**
|
||||
* \brief This class declares information about the JS extension.
|
||||
*/
|
||||
class JsExtension : public gd::PlatformExtension
|
||||
class PhysicsBehaviorJsExtension : public gd::PlatformExtension
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
JsExtension()
|
||||
PhysicsBehaviorJsExtension()
|
||||
{
|
||||
SetExtensionInformation("PhysicsBehavior",
|
||||
_("Physics behavior"),
|
||||
_("Behavior allowing to move objects as if they were subject to the laws of physics."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)");
|
||||
CloneExtension("GDevelop C++ platform", "PhysicsBehavior");
|
||||
DeclarePhysicsBehaviorExtension(*this);
|
||||
|
||||
GetBehaviorMetadata("PhysicsBehavior::PhysicsBehavior")
|
||||
.SetIncludeFile("Extensions/PhysicsBehavior/box2djs/box2d.js")
|
||||
@@ -145,14 +139,21 @@ public:
|
||||
*/
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions();
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(EMSCRIPTEN)
|
||||
extern "C" gd::PlatformExtension * CreateGDJSPhysicsBehaviorExtension() {
|
||||
return new PhysicsBehaviorJsExtension;
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Used by GDevelop to create the extension class
|
||||
* -- Do not need to be modified. --
|
||||
*/
|
||||
extern "C" gd::PlatformExtension * GD_EXTENSION_API CreateGDJSExtension() {
|
||||
return new JsExtension;
|
||||
return new PhysicsBehaviorJsExtension;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -7,6 +7,7 @@ This project is released under the MIT License.
|
||||
|
||||
#include "PhysicsBehavior.h"
|
||||
#include <string>
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "Box2D/Box2D.h"
|
||||
#include "Triangulation/triangulate.h"
|
||||
#include "GDCpp/Runtime/RuntimeScene.h"
|
||||
@@ -17,6 +18,10 @@ This project is released under the MIT License.
|
||||
#include "GDCpp/Runtime/Project/Project.h"
|
||||
#include "GDCpp/Runtime/Project/Layout.h"
|
||||
#include "RuntimeScenePhysicsDatas.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <map>
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
#endif
|
||||
|
||||
#undef GetObject
|
||||
|
||||
@@ -100,10 +105,6 @@ void PhysicsBehavior::DoStepPostEvents(RuntimeScene & scene)
|
||||
float newHeight = object->GetHeight();
|
||||
if ( (int)objectOldWidth != (int)newWidth || (int)objectOldHeight != (int)newHeight )
|
||||
{
|
||||
/*std::cout << "Changed:" << (int)objectOldWidth << "!=" << (int)newWidth << std::endl;
|
||||
std::cout << "Changed:" << (int)objectOldHeight << "!=" << (int)newHeight << std::endl;
|
||||
std::cout << "( Object name:" << object->GetName() << std::endl;*/
|
||||
|
||||
double oldAngularVelocity = body->GetAngularVelocity();
|
||||
b2Vec2 oldVelocity = body->GetLinearVelocity();
|
||||
|
||||
@@ -700,6 +701,76 @@ void PhysicsBehavior::UnserializeFrom(const gd::SerializerElement & element)
|
||||
SetPolygonCoords(PhysicsBehavior::GetCoordsVectorFromString(coordsStr, '/', ';'));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::PropertyDescriptor> PhysicsBehavior::GetProperties(gd::Project & project) const
|
||||
{
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
|
||||
gd::String shapeTypeStr = _("Box (rectangle)");
|
||||
if (shapeType == Box) shapeTypeStr = _("Box (rectangle)");
|
||||
else if (shapeType == Circle) shapeTypeStr = _("Circle");
|
||||
else if (shapeType == CustomPolygon) shapeTypeStr = _("Custom polygon");
|
||||
|
||||
properties[_("Shape")]
|
||||
.SetValue(shapeTypeStr)
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("Box (rectangle)"))
|
||||
.AddExtraInfo(_("Circle"));
|
||||
|
||||
properties[_("Dynamic object")].SetValue(dynamic ? "true" : "false").SetType("Boolean");
|
||||
properties[_("Fixed rotation")].SetValue(fixedRotation ? "true" : "false").SetType("Boolean");
|
||||
properties[_("Consider as bullet (better collision handling)")].SetValue(isBullet ? "true" : "false").SetType("Boolean");
|
||||
properties[_("Mass density")].SetValue(gd::String::From(massDensity));
|
||||
properties[_("Friction")].SetValue(gd::String::From(averageFriction));
|
||||
properties[_("Restitution (elasticity)")].SetValue(gd::String::From(averageRestitution));
|
||||
properties[_("Linear Damping")].SetValue(gd::String::From(linearDamping));
|
||||
properties[_("Angular Damping")].SetValue(gd::String::From(angularDamping));
|
||||
properties[_("PLEASE_ALSO_SHOW_EDIT_BUTTON_THANKS")].SetValue("");
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool PhysicsBehavior::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
|
||||
{
|
||||
if (name == _("Shape"))
|
||||
{
|
||||
if (value == _("Box (rectangle)"))
|
||||
shapeType = Box;
|
||||
else if (value == _("Circle"))
|
||||
shapeType = Circle;
|
||||
else if (value == _("Custom polygon"))
|
||||
shapeType = CustomPolygon;
|
||||
}
|
||||
if ( name == _("Dynamic object") ) {
|
||||
dynamic = (value != "0");
|
||||
}
|
||||
if ( name == _("Fixed rotation") ) {
|
||||
fixedRotation = (value != "0");
|
||||
}
|
||||
if ( name == _("Consider as bullet (better collision handling)") ) {
|
||||
isBullet = (value != "0");
|
||||
}
|
||||
if ( name == _("Mass density") ) {
|
||||
massDensity = value.To<float>();
|
||||
}
|
||||
if ( name == _("Friction") ) {
|
||||
averageFriction = value.To<float>();
|
||||
}
|
||||
if ( name == _("Restitution (elasticity)") ) {
|
||||
averageRestitution = value.To<float>();
|
||||
}
|
||||
if ( name == _("Linear Damping") ) {
|
||||
if ( value.To<float>() < 0 ) return false;
|
||||
linearDamping = value.To<float>();
|
||||
}
|
||||
if ( name == _("Angular Damping") ) {
|
||||
if ( value.To<float>() < 0 ) return false;
|
||||
angularDamping = value.To<float>();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
gd::String PhysicsBehavior::GetStringFromCoordsVector(const std::vector<sf::Vector2f> &vec, char32_t coordsSep, char32_t composantSep)
|
||||
{
|
||||
|
@@ -56,6 +56,9 @@ public:
|
||||
* Called when user wants to edit the behavior.
|
||||
*/
|
||||
virtual void EditBehavior( wxWindow* parent, gd::Project & project_, gd::Layout * layout_, gd::MainFrameWrapper & mainFrameWrapper_ );
|
||||
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
|
||||
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@@ -241,13 +241,13 @@ scene(scene_)
|
||||
}
|
||||
|
||||
//Setup shared datas
|
||||
if ( !scene || scene->behaviorsInitialSharedDatas.find(behavior.GetName()) == scene->behaviorsInitialSharedDatas.end())
|
||||
if (!scene || !scene->HasBehaviorSharedData(behavior.GetName()))
|
||||
{
|
||||
gd::LogError(_("Unable to access to shared datas."));
|
||||
return;
|
||||
}
|
||||
|
||||
sharedDatas = std::dynamic_pointer_cast<ScenePhysicsDatas>(scene->behaviorsInitialSharedDatas[behavior.GetName()]);
|
||||
sharedDatas = std::dynamic_pointer_cast<ScenePhysicsDatas>(scene->GetBehaviorSharedDataSmartPtr(behavior.GetName()));
|
||||
|
||||
if ( sharedDatas == std::shared_ptr<ScenePhysicsDatas>() )
|
||||
{
|
||||
|
@@ -6,9 +6,46 @@ This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "ScenePhysicsDatas.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <map>
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::PropertyDescriptor> ScenePhysicsDatas::GetProperties(gd::Project & project) const
|
||||
{
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Gravity on X axis (in m/s²)")].SetValue(gd::String::From(gravityX));
|
||||
properties[_("Gravity on Y axis (in m/s²)")].SetValue(gd::String::From(gravityY));
|
||||
properties[_("X Scale: number of pixels for 1 meter")].SetValue(gd::String::From(scaleX));
|
||||
properties[_("Y Scale: number of pixels for 1 meter")].SetValue(gd::String::From(scaleY));
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool ScenePhysicsDatas::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
|
||||
{
|
||||
if (name == _("Gravity on X axis (in m/s²)")) {
|
||||
gravityX = value.To<float>();
|
||||
}
|
||||
if (name == _("Gravity on Y axis (in m/s²)")) {
|
||||
gravityY = value.To<float>();
|
||||
}
|
||||
if (name == _("X scale: number of pixels for 1 meter")) {
|
||||
scaleX = value.To<float>();
|
||||
}
|
||||
if (name == _("Y scale: number of pixels for 1 meter")) {
|
||||
scaleY = value.To<float>();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScenePhysicsDatas::SerializeTo(gd::SerializerElement & element) const
|
||||
{
|
||||
element.SetAttribute("gravityX", gravityX);
|
||||
|
@@ -17,7 +17,7 @@ This project is released under the MIT License.
|
||||
class ScenePhysicsDatas : public gd::BehaviorsSharedData
|
||||
{
|
||||
public:
|
||||
ScenePhysicsDatas() : BehaviorsSharedData(), gravityX(0), gravityY(0), scaleX(100), scaleY(100)
|
||||
ScenePhysicsDatas() : BehaviorsSharedData(), gravityX(0), gravityY(9), scaleX(100), scaleY(100)
|
||||
{
|
||||
};
|
||||
virtual ~ScenePhysicsDatas() {};
|
||||
@@ -34,6 +34,8 @@ public:
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
|
||||
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project);
|
||||
virtual void SerializeTo(gd::SerializerElement & element) const;
|
||||
#endif
|
||||
|
||||
|
@@ -106,6 +106,7 @@ BaseObjectExtension::BaseObjectExtension()
|
||||
GetAllConditions()["NbObjet"].SetFunctionName("PickedObjectsCount").SetManipulatedType("number").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
|
||||
GetAllConditions()["CollisionNP"].SetFunctionName("HitBoxesCollision").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
|
||||
GetAllConditions()["EstTourne"].SetFunctionName("ObjectsTurnedToward").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
|
||||
GetAllConditions()["Raycast"].SetFunctionName("RaycastObject").SetIncludeFile("GDCpp/Extensions/Builtin/RuntimeSceneTools.h");
|
||||
|
||||
GetAllExpressions()["Count"].SetFunctionName("PickedObjectsCount").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
|
||||
#endif
|
||||
|
@@ -245,11 +245,10 @@ gd::String GD_API VariableStructureToJSON(const gd::Variable & variable)
|
||||
|
||||
gd::String str = "{";
|
||||
bool firstChild = true;
|
||||
for(std::map<gd::String, gd::Variable>::const_iterator i = variable.GetAllChildren().begin();
|
||||
i != variable.GetAllChildren().end();++i)
|
||||
for(auto i = variable.GetAllChildren().begin(); i != variable.GetAllChildren().end();++i)
|
||||
{
|
||||
if ( !firstChild ) str += ",";
|
||||
str += gd::String::FromUTF8(StringToQuotedJSONString(i->first.c_str()))+": "+VariableStructureToJSON(i->second);
|
||||
str += gd::String::FromUTF8(StringToQuotedJSONString(i->first.c_str()))+": "+VariableStructureToJSON(*i->second);
|
||||
|
||||
firstChild = false;
|
||||
}
|
||||
|
@@ -22,6 +22,9 @@
|
||||
#include "GDCpp/Runtime/CommonTools.h"
|
||||
#include "GDCpp/Runtime/Project/Variable.h"
|
||||
#include "GDCpp/Extensions/CppPlatform.h"
|
||||
#include "GDCpp/Runtime/PolygonCollision.h"
|
||||
#include "GDCpp/Runtime/Polygon2d.h"
|
||||
#include <iostream>
|
||||
|
||||
gd::String GD_API GetSceneName(RuntimeScene & scene)
|
||||
{
|
||||
@@ -208,6 +211,48 @@ bool GD_API PickNearestObject(std::map <gd::String, std::vector<RuntimeObject*>
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GD_API RaycastObject(std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists, float x, float y, float angle, float dist, gd::Variable & varX, gd::Variable & varY, bool inverted)
|
||||
{
|
||||
RuntimeObject * matchObject = NULL;
|
||||
float testSqDist = inverted ? 0 : dist*dist;
|
||||
float resultX = 0.0f;
|
||||
float resultY = 0.0f;
|
||||
for (auto it = pickedObjectLists.begin(); it != pickedObjectLists.end(); ++it)
|
||||
{
|
||||
if ( it->second == NULL ) continue;
|
||||
auto list = *it->second;
|
||||
|
||||
for (std::size_t i = 0; i < list.size(); ++i)
|
||||
{
|
||||
|
||||
RaycastResult result = list[i]->RaycastTest(x, y, angle, dist, !inverted);
|
||||
|
||||
if( result.collision ) {
|
||||
if ( !inverted && (result.closeSqDist <= testSqDist) ) {
|
||||
testSqDist = result.closeSqDist;
|
||||
matchObject = list[i];
|
||||
resultX = result.closePoint.x;
|
||||
resultY = result.closePoint.y;
|
||||
}
|
||||
else if ( inverted && (result.farSqDist >= testSqDist) ) {
|
||||
testSqDist = result.farSqDist;
|
||||
matchObject = list[i];
|
||||
resultX = result.farPoint.x;
|
||||
resultY = result.farPoint.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !matchObject )
|
||||
return false;
|
||||
|
||||
PickOnly(pickedObjectLists, matchObject);
|
||||
varX.SetValue(resultX);
|
||||
varY.SetValue(resultY);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GD_API SceneVariableExists(RuntimeScene & scene, const gd::String & variable)
|
||||
{
|
||||
return scene.GetVariables().Has(variable);
|
||||
@@ -242,7 +287,7 @@ unsigned int GD_API GetVariableChildCount(gd::Variable & variable)
|
||||
{
|
||||
if (variable.IsStructure() == false) return 0;
|
||||
|
||||
return variable.GetAllChildren().size();
|
||||
return variable.GetChildrenCount();
|
||||
}
|
||||
|
||||
double GD_API GetVariableValue(const gd::Variable & variable)
|
||||
|
@@ -94,6 +94,11 @@ bool GD_API PickRandomObject(RuntimeScene & scene, std::map <gd::String, std::ve
|
||||
*/
|
||||
bool GD_API PickNearestObject(std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists, double x, double y, bool inverted);
|
||||
|
||||
/**
|
||||
* Only used internally by GD events generated code.
|
||||
*/
|
||||
bool GD_API RaycastObject(std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists, float x, float y, float angle, float dist, gd::Variable & varX, gd::Variable & varY, bool inverted);
|
||||
|
||||
/**
|
||||
* Only used internally by GD events generated code.
|
||||
*/
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include "GDCpp/Runtime/Polygon2d.h"
|
||||
#include <cmath>
|
||||
#include <cfloat>
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -30,6 +31,13 @@ float dotProduct(const sf::Vector2f a, const sf::Vector2f b)
|
||||
return dp;
|
||||
}
|
||||
|
||||
float crossProduct(const sf::Vector2f a, const sf::Vector2f b)
|
||||
{
|
||||
float cp = a.x*b.y - a.y*b.x;
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
void project(const sf::Vector2f axis, const Polygon2d & p, float& min, float& max)
|
||||
{
|
||||
float dp = dotProduct(axis, p.vertices[0]);
|
||||
@@ -129,6 +137,96 @@ CollisionResult GD_API PolygonCollisionTest(Polygon2d & p1, Polygon2d & p2)
|
||||
return result;
|
||||
}
|
||||
|
||||
RaycastResult GD_API PolygonRaycastTest(Polygon2d & poly, float startX, float startY, float endX, float endY)
|
||||
{
|
||||
RaycastResult result;
|
||||
result.collision = false;
|
||||
|
||||
if ( poly.vertices.size() < 2 )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
poly.ComputeEdges();
|
||||
sf::Vector2f p, q, r, s;
|
||||
float minSqDist = FLT_MAX;
|
||||
|
||||
// Ray segment: p + t*r, with p = start and r = end - start
|
||||
p.x = startX;
|
||||
p.y = startY;
|
||||
r.x = endX - startX;
|
||||
r.y = endY - startY;
|
||||
|
||||
for( int i=0; i<poly.edges.size(); i++ )
|
||||
{
|
||||
// Edge segment: q + u*s
|
||||
q = poly.vertices[i];
|
||||
s = poly.edges[i];
|
||||
sf::Vector2f deltaQP = q - p;
|
||||
float crossRS = crossProduct(r, s);
|
||||
float t = crossProduct(deltaQP, s) / crossRS;
|
||||
float u = crossProduct(deltaQP, r) / crossRS;
|
||||
|
||||
// Collinear
|
||||
if ( abs(crossRS) <= 0.0001 && abs(crossProduct(deltaQP, r)) <= 0.0001 )
|
||||
{
|
||||
// Project the ray and the edge to work on floats, keeping linearity through t
|
||||
sf::Vector2f axis(r.x, r.y);
|
||||
normalise(axis);
|
||||
float rayA = 0.0f;
|
||||
float rayB = dotProduct(axis, r);
|
||||
float edgeA = dotProduct(axis, deltaQP);
|
||||
float edgeB = dotProduct(axis, deltaQP + s);
|
||||
// Get overlapping range
|
||||
float minOverlap = std::max(std::min(rayA, rayB), std::min(edgeA, edgeB));
|
||||
float maxOverlap = std::min(std::max(rayA, rayB), std::max(edgeA, edgeB));
|
||||
if( minOverlap > maxOverlap ){
|
||||
return result;
|
||||
}
|
||||
result.collision = true;
|
||||
// Zero distance ray
|
||||
if( rayB == 0.0f ){
|
||||
result.closePoint = p;
|
||||
result.closeSqDist = 0.0f;
|
||||
result.farPoint = p;
|
||||
result.farSqDist = 0.0f;
|
||||
}
|
||||
float t1 = minOverlap / abs(rayB);
|
||||
float t2 = maxOverlap / abs(rayB);
|
||||
result.closePoint = p + t1*r;
|
||||
result.closeSqDist = t1*t1*(r.x*r.x + r.y*r.y);
|
||||
result.farPoint = p + t2*r;
|
||||
result.farSqDist = t2*t2*(r.x*r.x + r.y*r.y);
|
||||
|
||||
return result;
|
||||
}
|
||||
else if ( crossRS != 0 && 0<=t && t<=1 && 0<=u && u<=1 )
|
||||
{
|
||||
sf::Vector2f point = p + t*r;
|
||||
|
||||
float sqDist = (point.x-startX)*(point.x-startX) + (point.y-startY)*(point.y-startY);
|
||||
if ( sqDist < minSqDist )
|
||||
{
|
||||
if ( !result.collision ){
|
||||
result.farPoint = point;
|
||||
result.farSqDist = sqDist;
|
||||
}
|
||||
minSqDist = sqDist;
|
||||
result.closePoint = point;
|
||||
result.closeSqDist = sqDist;
|
||||
result.collision = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.farPoint = point;
|
||||
result.farSqDist = sqDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GD_API IsPointInsidePolygon(Polygon2d & poly, float x, float y)
|
||||
{
|
||||
bool inside = false;
|
||||
|
@@ -19,6 +19,15 @@ struct CollisionResult
|
||||
sf::Vector2f move_axis;
|
||||
};
|
||||
|
||||
struct RaycastResult
|
||||
{
|
||||
bool collision;
|
||||
sf::Vector2f closePoint;
|
||||
float closeSqDist;
|
||||
sf::Vector2f farPoint;
|
||||
float farSqDist;
|
||||
};
|
||||
|
||||
/**
|
||||
* Do a collision test between the two polygons.
|
||||
* \warning Polygons must convexes.
|
||||
@@ -33,6 +42,17 @@ struct CollisionResult
|
||||
*/
|
||||
CollisionResult GD_API PolygonCollisionTest(Polygon2d & p1, Polygon2d & p2);
|
||||
|
||||
/**
|
||||
* Do a raycast test.
|
||||
* \warning Polygon must be convex.
|
||||
* For some theory check "Find the Intersection Point of Two Line Segments" (https://www.codeproject.com/Tips/862988/Find-the-Intersection-Point-of-Two-Line-Segments)
|
||||
*
|
||||
* \return A raycast result with the contact points and distances
|
||||
*
|
||||
* \ingroup GameEngine
|
||||
*/
|
||||
RaycastResult GD_API PolygonRaycastTest(Polygon2d & poly, float startX, float startY, float endX, float endY);
|
||||
|
||||
/**
|
||||
* Check if a point is inside a polygon.
|
||||
*
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCpp/Extensions/Builtin/MathematicalTools.h"
|
||||
#include "GDCpp/Runtime/RuntimeObject.h"
|
||||
@@ -390,6 +391,43 @@ bool RuntimeObject::IsCollidingWithPoint(float pointX, float pointY){
|
||||
return false;
|
||||
}
|
||||
|
||||
RaycastResult RuntimeObject::RaycastTest(float x, float y, float angle, float dist, bool closest){
|
||||
float objW = GetWidth();
|
||||
float objH = GetHeight();
|
||||
float diffX = GetDrawableX()+GetCenterX() - x;
|
||||
float diffY = GetDrawableY()+GetCenterY() - y;
|
||||
float boundingRadius = sqrt(objW*objW + objH*objH)/2.0;
|
||||
|
||||
RaycastResult result;
|
||||
result.collision = false;
|
||||
|
||||
if ( sqrt(diffX*diffX + diffY*diffY) > boundingRadius + dist )
|
||||
return result;
|
||||
|
||||
float endX = x + dist*cos(angle*3.14159/180.0);
|
||||
float endY = y + dist*sin(angle*3.14159/180.0);
|
||||
float testSqDist = closest ? dist*dist : 0.0f;
|
||||
|
||||
vector<Polygon2d> hitboxes = GetHitBoxes();
|
||||
for (std::size_t i = 0; i < hitboxes.size(); ++i)
|
||||
{
|
||||
RaycastResult res = PolygonRaycastTest(hitboxes[i], x, y, endX, endY);
|
||||
|
||||
if ( res.collision ) {
|
||||
if ( closest && (res.closeSqDist < testSqDist) ) {
|
||||
testSqDist = res.closeSqDist;
|
||||
result = res;
|
||||
}
|
||||
else if ( !closest && (res.farSqDist > testSqDist) && (res.farSqDist <= dist*dist) ) {
|
||||
testSqDist = res.farSqDist;
|
||||
result = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void RuntimeObject::SeparateObjectsWithoutForces( std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists)
|
||||
{
|
||||
vector<RuntimeObject*> objects2;
|
||||
@@ -714,5 +752,5 @@ void RuntimeObject::VariableClearChildren(gd::Variable & variable)
|
||||
unsigned int RuntimeObject::GetVariableChildCount(gd::Variable & variable)
|
||||
{
|
||||
if (variable.IsStructure() == false) return 0;
|
||||
return variable.GetAllChildren().size();
|
||||
return variable.GetChildrenCount();
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ namespace gd { class InitialInstance; }
|
||||
namespace gd { class Object; }
|
||||
namespace sf { class RenderTarget; }
|
||||
class Polygon2d;
|
||||
class RaycastResult;
|
||||
class RuntimeScene;
|
||||
|
||||
/**
|
||||
@@ -231,6 +232,17 @@ public:
|
||||
*/
|
||||
bool IsCollidingWithPoint(float pointX, float pointY);
|
||||
|
||||
/**
|
||||
* \brief Check if a ray intersect any object hitbox.
|
||||
* \param x The raycast source X
|
||||
* \param y The raycast source Y
|
||||
* \param angle The raycast angle
|
||||
* \param dist The raycast max distance
|
||||
* \param closest Get the closest or farthest collision mask result?
|
||||
* \return A raycast result with the contact points and distances
|
||||
*/
|
||||
RaycastResult RaycastTest(float x, float y, float angle, float dist, bool closest);
|
||||
|
||||
/**
|
||||
* \brief Check collision with each object of the list using their hitboxes, and move the object
|
||||
* according to the sum of the move vector returned by each collision test.
|
||||
|
@@ -450,7 +450,7 @@ bool RuntimeScene::LoadFromSceneAndCustomInstances( const gd::Layout & scene, co
|
||||
|
||||
//Behaviors shared data
|
||||
std::cout << ".";
|
||||
behaviorsSharedDatas.LoadFrom(scene.behaviorsInitialSharedDatas);
|
||||
behaviorsSharedDatas.LoadFrom(scene.GetAllBehaviorSharedData());
|
||||
|
||||
std::cout << ".";
|
||||
//Extensions specific initialization
|
||||
|
@@ -38,15 +38,16 @@ void RuntimeVariablesContainer::Merge(const gd::VariablesContainer & container)
|
||||
{
|
||||
for ( std::size_t i = 0; i<container.Count();++i)
|
||||
{
|
||||
const std::pair<gd::String, gd::Variable> & variable = container.Get(i);
|
||||
const gd::String & name = container.GetNameAt(i);
|
||||
const gd::Variable & variable = container.Get(i);
|
||||
|
||||
if ( Has(variable.first) )
|
||||
Get(variable.first) = variable.second;
|
||||
if ( Has(name) )
|
||||
Get(name) = variable;
|
||||
else
|
||||
{
|
||||
gd::Variable * newVariable = new gd::Variable(variable.second);
|
||||
gd::Variable * newVariable = new gd::Variable(variable);
|
||||
variablesArray.push_back(newVariable);
|
||||
variables[variable.first] = newVariable;
|
||||
variables[name] = newVariable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -101,6 +101,7 @@ BaseObjectExtension::BaseObjectExtension()
|
||||
GetAllConditions()["CollisionNP"]
|
||||
.AddCodeOnlyParameter("currentScene", "") //We need an extra parameter pointing to the scene.
|
||||
.SetFunctionName("gdjs.evtTools.object.hitBoxesCollisionTest");
|
||||
GetAllConditions()["Raycast"].SetFunctionName("gdjs.evtTools.object.raycastObject");
|
||||
GetAllConditions()["Distance"].SetFunctionName("gdjs.evtTools.object.distanceTest");
|
||||
GetAllConditions()["SeDirige"].SetFunctionName("gdjs.evtTools.object.movesTowardTest");
|
||||
GetAllConditions()["EstTourne"].SetFunctionName("gdjs.evtTools.object.turnedTowardTest");
|
||||
|
@@ -137,6 +137,8 @@ gd::PlatformExtension * CreateGDJSInventoryExtension();
|
||||
gd::PlatformExtension * CreateGDJSLinkedObjectsExtension();
|
||||
gd::PlatformExtension * CreateGDJSSystemInfoExtension();
|
||||
gd::PlatformExtension * CreateGDJSShopifyExtension();
|
||||
gd::PlatformExtension * CreateGDJSPathfindingBehaviorExtension();
|
||||
gd::PlatformExtension * CreateGDJSPhysicsBehaviorExtension();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -183,6 +185,8 @@ JsPlatform::JsPlatform() :
|
||||
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSLinkedObjectsExtension())); std::cout.flush();
|
||||
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSSystemInfoExtension())); std::cout.flush();
|
||||
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSShopifyExtension())); std::cout.flush();
|
||||
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSPathfindingBehaviorExtension())); std::cout.flush();
|
||||
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSPhysicsBehaviorExtension())); std::cout.flush();
|
||||
#endif
|
||||
std::cout << "done." << std::endl;
|
||||
};
|
||||
|
@@ -97,8 +97,9 @@ bool Exporter::ExportWholePixiProject(gd::Project & project, gd::String exportDi
|
||||
bool minify, bool exportForCordova)
|
||||
{
|
||||
ExporterHelper helper(fs, gdjsRoot, codeOutputDir);
|
||||
gd::Project exportedProject = project;
|
||||
|
||||
auto exportProject = [this, &project, &minify,
|
||||
auto exportProject = [this, &exportedProject, &minify,
|
||||
&exportForCordova, &helper](gd::String exportDir)
|
||||
{
|
||||
wxProgressDialog * progressDialogPtr = NULL;
|
||||
@@ -111,8 +112,6 @@ bool Exporter::ExportWholePixiProject(gd::Project & project, gd::String exportDi
|
||||
fs.MkDir(exportDir);
|
||||
std::vector<gd::String> includesFiles;
|
||||
|
||||
gd::Project exportedProject = project;
|
||||
|
||||
//Export the resources (before generating events as some resources filenames may be updated)
|
||||
helper.ExportResources(fs, exportedProject, exportDir, progressDialogPtr);
|
||||
|
||||
@@ -168,11 +167,12 @@ bool Exporter::ExportWholePixiProject(gd::Project & project, gd::String exportDi
|
||||
{
|
||||
//Prepare the export directory
|
||||
fs.MkDir(exportDir);
|
||||
if (!helper.ExportCordovaConfigFile(project, exportDir))
|
||||
return false;
|
||||
|
||||
if (!exportProject(exportDir + "/www"))
|
||||
return false;
|
||||
|
||||
if (!helper.ExportCordovaConfigFile(exportedProject, exportDir))
|
||||
return false;
|
||||
} else {
|
||||
if (!exportProject(exportDir))
|
||||
return false;
|
||||
|
@@ -58,9 +58,10 @@ static void GenerateFontsDeclaration(gd::AbstractFileSystem & fs, const gd::Stri
|
||||
css += urlPrefix + relativeFile;
|
||||
css +="') format('truetype'); }";
|
||||
|
||||
// Use the font for a dummy text to trigger immediate load of the font at game startup
|
||||
html += "<div style=\"font-family: 'gdjs_font_";
|
||||
html += relativeFile;
|
||||
html += "';\">.</div>";
|
||||
html += "'; color: black;\">.</div>";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +80,9 @@ bool ExporterHelper::ExportLayoutForPixiPreview(gd::Project & project, gd::Layou
|
||||
|
||||
gd::Project exportedProject = project;
|
||||
|
||||
// Always disable the splash for preview
|
||||
exportedProject.GetLoadingScreen().ShowGDevelopSplash(false);
|
||||
|
||||
//Export resources (*before* generating events as some resources filenames may be updated)
|
||||
ExportResources(fs, exportedProject, exportDir);
|
||||
//Generate events code
|
||||
@@ -156,10 +160,42 @@ bool ExporterHelper::ExportPixiIndexFile(gd::String source, gd::String exportDir
|
||||
|
||||
bool ExporterHelper::ExportCordovaConfigFile(const gd::Project & project, gd::String exportDir)
|
||||
{
|
||||
auto & platformSpecificAssets = project.GetPlatformSpecificAssets();
|
||||
auto & resourceManager = project.GetResourcesManager();
|
||||
auto getIconFilename = [&resourceManager, &platformSpecificAssets](const gd::String & platform, const gd::String & name) {
|
||||
const gd::String & file = resourceManager.GetResource(platformSpecificAssets.Get(platform, name)).GetFile();
|
||||
return file.empty() ? "" : "www/" + file;
|
||||
};
|
||||
|
||||
gd::String str = fs.ReadFile(gdjsRoot + "/Runtime/Cordova/config.xml")
|
||||
.FindAndReplace("GDJS_PROJECTNAME", project.GetName())
|
||||
.FindAndReplace("GDJS_PACKAGENAME", project.GetPackageName())
|
||||
.FindAndReplace("GDJS_ORIENTATION", "default");
|
||||
.FindAndReplace("GDJS_ORIENTATION", project.GetOrientation())
|
||||
// Android icons
|
||||
.FindAndReplace("GDJS_ICON_ANDROID_36", getIconFilename("android", "icon-36"))
|
||||
.FindAndReplace("GDJS_ICON_ANDROID_48", getIconFilename("android", "icon-48"))
|
||||
.FindAndReplace("GDJS_ICON_ANDROID_72", getIconFilename("android", "icon-72"))
|
||||
.FindAndReplace("GDJS_ICON_ANDROID_96", getIconFilename("android", "icon-96"))
|
||||
.FindAndReplace("GDJS_ICON_ANDROID_144", getIconFilename("android", "icon-144"))
|
||||
.FindAndReplace("GDJS_ICON_ANDROID_192", getIconFilename("android", "icon-192"))
|
||||
// iOS icons
|
||||
.FindAndReplace("GDJS_ICON_IOS_180", getIconFilename("ios", "icon-180"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_60", getIconFilename("ios", "icon-60"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_120", getIconFilename("ios", "icon-120"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_76", getIconFilename("ios", "icon-76"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_152", getIconFilename("ios", "icon-152"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_40", getIconFilename("ios", "icon-40"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_80", getIconFilename("ios", "icon-80"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_57", getIconFilename("ios", "icon-57"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_114", getIconFilename("ios", "icon-114"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_72", getIconFilename("ios", "icon-72"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_144", getIconFilename("ios", "icon-144"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_167", getIconFilename("ios", "icon-167"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_29", getIconFilename("ios", "icon-29"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_58", getIconFilename("ios", "icon-58"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_50", getIconFilename("ios", "icon-50"))
|
||||
.FindAndReplace("GDJS_ICON_IOS_100", getIconFilename("ios", "icon-100"))
|
||||
;
|
||||
|
||||
if (!fs.WriteToFile(exportDir + "/config.xml", str))
|
||||
{
|
||||
@@ -196,14 +232,14 @@ bool ExporterHelper::ExportCocos2dFiles(const gd::Project & project, gd::String
|
||||
std::vector<gd::String> noIncludesInThisFile;
|
||||
if (!CompleteIndexFile(str, customCss, customHtml, exportDir, noIncludesInThisFile, ""))
|
||||
{
|
||||
lastError = "Unable to complete Cocos2d index.html file.";
|
||||
lastError = "Unable to complete Cocos2d-JS index.html file.";
|
||||
return false;
|
||||
}
|
||||
|
||||
//Write the index.html file
|
||||
if (!fs.WriteToFile(exportDir + "/index.html", str))
|
||||
{
|
||||
lastError = "Unable to write Cocos2d index.html file.";
|
||||
lastError = "Unable to write Cocos2d-JS index.html file.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +265,7 @@ bool ExporterHelper::ExportCocos2dFiles(const gd::Project & project, gd::String
|
||||
|
||||
if (!fs.WriteToFile(exportDir + "/project.json", str))
|
||||
{
|
||||
lastError = "Unable to write Cocos2d project.json file.";
|
||||
lastError = "Unable to write Cocos2d-JS project.json file.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -337,6 +373,7 @@ bool ExporterHelper::ExportEventsCode(gd::Project & project, gd::String outputDi
|
||||
//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/hshg.js");
|
||||
InsertUnique(includesFiles, "libs/rbush.js");
|
||||
InsertUnique(includesFiles, "inputmanager.js");
|
||||
|
@@ -12,10 +12,47 @@
|
||||
<allow-intent href="geo:*" />
|
||||
<platform name="android">
|
||||
<allow-intent href="market:*" />
|
||||
<icon src="GDJS_ICON_ANDROID_36" density="ldpi" />
|
||||
<icon src="GDJS_ICON_ANDROID_48" density="mdpi" />
|
||||
<icon src="GDJS_ICON_ANDROID_72" density="hdpi" />
|
||||
<icon src="GDJS_ICON_ANDROID_96" density="xhdpi" />
|
||||
<icon src="GDJS_ICON_ANDROID_144" density="xxhdpi" />
|
||||
<icon src="GDJS_ICON_ANDROID_192" density="xxxhdpi" />
|
||||
</platform>
|
||||
<platform name="ios">
|
||||
<allow-intent href="itms:*" />
|
||||
<allow-intent href="itms-apps:*" />
|
||||
<!-- iOS 8.0+ -->
|
||||
<!-- iPhone 6 Plus -->
|
||||
<icon src="GDJS_ICON_IOS_180" width="180" height="180" />
|
||||
<!-- iOS 7.0+ -->
|
||||
<!-- iPhone / iPod Touch -->
|
||||
<icon src="GDJS_ICON_IOS_60" width="60" height="60" />
|
||||
<icon src="GDJS_ICON_IOS_120" width="120" height="120" />
|
||||
<!-- iPad -->
|
||||
<icon src="GDJS_ICON_IOS_76" width="76" height="76" />
|
||||
<icon src="GDJS_ICON_IOS_152" width="152" height="152" />
|
||||
<!-- Spotlight Icon -->
|
||||
<icon src="GDJS_ICON_IOS_40" width="40" height="40" />
|
||||
<icon src="GDJS_ICON_IOS_80" width="80" height="80" />
|
||||
<!-- iOS 6.1 -->
|
||||
<!-- iPhone / iPod Touch -->
|
||||
<icon src="GDJS_ICON_IOS_57" width="57" height="57" />
|
||||
<icon src="GDJS_ICON_IOS_114" width="114" height="114" />
|
||||
<!-- iPad -->
|
||||
<icon src="GDJS_ICON_IOS_72" width="72" height="72" />
|
||||
<icon src="GDJS_ICON_IOS_144" width="144" height="144" />
|
||||
<!-- iPad Pro -->
|
||||
<icon src="GDJS_ICON_IOS_167" width="167" height="167" />
|
||||
<!-- iPhone Spotlight and Settings Icon -->
|
||||
<icon src="GDJS_ICON_IOS_29" width="29" height="29" />
|
||||
<icon src="GDJS_ICON_IOS_58" width="58" height="58" />
|
||||
<!-- iPad Spotlight and Settings Icon -->
|
||||
<icon src="GDJS_ICON_IOS_50" width="50" height="50" />
|
||||
<icon src="GDJS_ICON_IOS_100" width="100" height="100" />
|
||||
<!-- iPad Pro -->
|
||||
<icon src="GDJS_ICON_IOS_167" width="167" height="167" />
|
||||
</platform>
|
||||
<preference name="orientation" value="GDJS_ORIENTATION" />
|
||||
<preference name="BackgroundColor" value="0xff000000"/>
|
||||
</widget>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
gdjs.LoadingScreenCocosRenderer = function(runtimeGamePixiRenderer)
|
||||
gdjs.LoadingScreenCocosRenderer = function(runtimeGamePixiRenderer, loadingScreenSetup)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -13,3 +13,7 @@ gdjs.LoadingScreenRenderer = gdjs.LoadingScreenCocosRenderer; //Register the cla
|
||||
gdjs.LoadingScreenCocosRenderer.prototype.render = function(percent) {
|
||||
console.log("Loading " + percent + "%");
|
||||
};
|
||||
|
||||
gdjs.LoadingScreenCocosRenderer.prototype.unload = function() {
|
||||
// Nothing to do
|
||||
};
|
||||
|
@@ -316,6 +316,47 @@ gdjs.evtTools.object.pickNearestObject = function(objectsLists, x, y, inverted)
|
||||
return true;
|
||||
};
|
||||
|
||||
gdjs.evtTools.object.raycastObject = function(objectsLists, x, y, angle, dist, varX, varY, inverted) {
|
||||
var matchObject = null;
|
||||
var testSqDist = inverted ? 0 : dist*dist;
|
||||
var resultX = 0;
|
||||
var resultY = 0;
|
||||
|
||||
var lists = gdjs.staticArray(gdjs.evtTools.object.raycastObject);
|
||||
objectsLists.values(lists);
|
||||
for (var i = 0; i < lists.length; i++) {
|
||||
var list = lists[i];
|
||||
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
var object = list[j];
|
||||
var result = object.raycastTest(x, y, angle, dist, !inverted);
|
||||
|
||||
if( result.collision ) {
|
||||
if ( !inverted && (result.closeSqDist <= testSqDist) ) {
|
||||
testSqDist = result.closeSqDist;
|
||||
matchObject = object;
|
||||
resultX = result.closeX;
|
||||
resultY = result.closeY;
|
||||
}
|
||||
else if ( inverted && (result.farSqDist >= testSqDist) ) {
|
||||
testSqDist = result.farSqDist;
|
||||
matchObject = object;
|
||||
resultX = result.farX;
|
||||
resultY = result.farY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !matchObject )
|
||||
return false;
|
||||
|
||||
gdjs.evtTools.object.pickOnly(objectsLists, matchObject);
|
||||
varX.setNumber(resultX);
|
||||
varY.setNumber(resultY);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Do the work of creating a new object
|
||||
* @private
|
||||
|
@@ -108,13 +108,13 @@ gdjs.evtTools.runtimeScene.getTime = function(runtimeScene, what) {
|
||||
else if ( what === "sec" )
|
||||
return now.getSeconds();
|
||||
else if ( what === "mday" )
|
||||
return now.getdate();
|
||||
return now.getDate();
|
||||
else if ( what === "mon" )
|
||||
return now.getMonth();
|
||||
else if ( what === "year" )
|
||||
return now.getFullYear() - 1900; //Conform to the C way of returning years.
|
||||
else if ( what === "wday" )
|
||||
return now.getday();
|
||||
return now.getDay();
|
||||
else if ( what === "yday" ) {
|
||||
var start = new Date(now.getFullYear(), 0, 0);
|
||||
var diff = now - start;
|
||||
|
1
GDJS/Runtime/gd-splash-image.js
Normal file
@@ -2,6 +2,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
gdjs.LayerPixiRenderer = function(layer, runtimeSceneRenderer)
|
||||
{
|
||||
this._pixiContainer = new PIXI.Container();
|
||||
this._filters = {};
|
||||
this._layer = layer;
|
||||
runtimeSceneRenderer.getPIXIContainer().addChild(this._pixiContainer);
|
||||
|
||||
|
@@ -1,16 +1,70 @@
|
||||
gdjs.LoadingScreenPixiRenderer = function(runtimeGamePixiRenderer)
|
||||
{
|
||||
this._pixiRenderer = runtimeGamePixiRenderer.getPIXIRenderer();
|
||||
this._loadingScreen = new PIXI.Container();
|
||||
this._text = new PIXI.Text(" ", {font: "bold 60px Arial", fill: "#FFFFFF", align: "center"});
|
||||
this._loadingScreen.addChild(this._text);
|
||||
this._text.position.y = this._pixiRenderer.height/2;
|
||||
}
|
||||
gdjs.LoadingScreenPixiRenderer = function(runtimeGamePixiRenderer, loadingScreenSetup) {
|
||||
this._pixiRenderer = runtimeGamePixiRenderer.getPIXIRenderer();
|
||||
this._loadingScreen = new PIXI.Container();
|
||||
|
||||
this._progressText = new PIXI.Text(' ', {
|
||||
font: '30px Arial',
|
||||
fill: '#FFFFFF',
|
||||
align: 'center',
|
||||
});
|
||||
this._loadingScreen.addChild(this._progressText);
|
||||
|
||||
if (loadingScreenSetup && loadingScreenSetup.showGDevelopSplash) {
|
||||
this._madeWithText = new PIXI.Text('Made with', {
|
||||
font: '30px Arial',
|
||||
fill: '#FFFFFF',
|
||||
align: 'center',
|
||||
});
|
||||
this._madeWithText.position.y = this._pixiRenderer.height / 2 - 130;
|
||||
this._websiteText = new PIXI.Text('gdevelop-app.com', {
|
||||
font: '30px Arial',
|
||||
fill: '#FFFFFF',
|
||||
align: 'center',
|
||||
});
|
||||
this._websiteText.position.y = this._pixiRenderer.height / 2 + 100;
|
||||
|
||||
this._splashImage = new PIXI.Sprite.fromImage(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);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.LoadingScreenRenderer = gdjs.LoadingScreenPixiRenderer; //Register the class to let the engine use it.
|
||||
|
||||
gdjs.LoadingScreenPixiRenderer.prototype.render = function(percent) {
|
||||
this._text.text = percent + "%";
|
||||
this._text.position.x = this._pixiRenderer.width/2 - this._text.width/2;
|
||||
this._pixiRenderer.render(this._loadingScreen);
|
||||
var 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
gdjs.LoadingScreenPixiRenderer.prototype.unload = function() {
|
||||
// Nothing to do
|
||||
};
|
||||
|
@@ -86,12 +86,14 @@ gdjs.PixiFiltersTools._filters = {
|
||||
},
|
||||
Sepia: {
|
||||
makeFilter: function() {
|
||||
return new PIXI.filters.SepiaFilter();
|
||||
var colorMatrix = new PIXI.filters.ColorMatrixFilter();
|
||||
colorMatrix.sepia();
|
||||
return colorMatrix;
|
||||
},
|
||||
updateParameter: function(filter, parameterName, value) {
|
||||
if (parameterName !== 'opacity') return;
|
||||
|
||||
filter.sepia = value;
|
||||
filter.alpha = value;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@@ -219,6 +219,146 @@ gdjs.Polygon.collisionTest._statics = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Do a raycast test.<br>
|
||||
* Please note that the polygon must be <b>convex</b>!
|
||||
* For some theory, check <a href="https://www.codeproject.com/Tips/862988/Find-the-Intersection-Point-of-Two-Line-Segments">Find the Intersection Point of Two Line Segments</a>
|
||||
*
|
||||
* @method raycastTest
|
||||
* @static
|
||||
* @param poly {Polygon} The polygon to test
|
||||
* @param startX {Number} The raycast start point X
|
||||
* @param startY {Number} The raycast start point Y
|
||||
* @param endX {Number} The raycast end point X
|
||||
* @param endY {Number} The raycast end point Y
|
||||
* @return A raycast result with the contact points and distances
|
||||
*/
|
||||
gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
|
||||
{
|
||||
var result = gdjs.Polygon.raycastTest._statics.result;
|
||||
result.collision = false;
|
||||
|
||||
if ( poly.vertices.length < 2 )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
poly.computeEdges();
|
||||
var p = gdjs.Polygon.raycastTest._statics.p;
|
||||
var q = gdjs.Polygon.raycastTest._statics.q;
|
||||
var r = gdjs.Polygon.raycastTest._statics.r;
|
||||
var s = gdjs.Polygon.raycastTest._statics.s;
|
||||
var minSqDist = Number.MAX_VALUE;
|
||||
|
||||
// Ray segment: p + t*r, with p = start and r = end - start
|
||||
p[0] = startX;
|
||||
p[1] = startY;
|
||||
r[0] = endX - startX;
|
||||
r[1] = endY - startY;
|
||||
|
||||
for(var i=0; i<poly.edges.length; i++)
|
||||
{
|
||||
// Edge segment: q + u*s
|
||||
q[0] = poly.vertices[i][0];
|
||||
q[1] = poly.vertices[i][1];
|
||||
s[0] = poly.edges[i][0];
|
||||
s[1] = poly.edges[i][1];
|
||||
var deltaQP = gdjs.Polygon.raycastTest._statics.deltaQP;
|
||||
deltaQP[0] = q[0] - p[0];
|
||||
deltaQP[1] = q[1] - p[1];
|
||||
var crossRS = gdjs.Polygon.crossProduct(r, s);
|
||||
var t = gdjs.Polygon.crossProduct(deltaQP, s) / crossRS;
|
||||
var u = gdjs.Polygon.crossProduct(deltaQP, r) / crossRS;
|
||||
|
||||
// Collinear
|
||||
if ( Math.abs(crossRS) <= 0.0001 && Math.abs(gdjs.Polygon.crossProduct(deltaQP, r)) <= 0.0001 )
|
||||
{
|
||||
// Project the ray and the edge to work on floats, keeping linearity through t
|
||||
var axis = gdjs.Polygon.raycastTest._statics.axis;
|
||||
axis[0] = r[0];
|
||||
axis[1] = r[1];
|
||||
gdjs.Polygon.normalise(axis);
|
||||
var rayA = 0;
|
||||
var rayB = gdjs.Polygon.dotProduct(axis, r);
|
||||
var edgeA = gdjs.Polygon.dotProduct(axis, deltaQP);
|
||||
var edgeB = gdjs.Polygon.dotProduct(axis, [deltaQP[0] + s[0], deltaQP[1] + s[1]]);
|
||||
// Get overlapping range
|
||||
var minOverlap = Math.max(Math.min(rayA, rayB), Math.min(edgeA, edgeB));
|
||||
var maxOverlap = Math.min(Math.max(rayA, rayB), Math.max(edgeA, edgeB));
|
||||
if( minOverlap > maxOverlap ){
|
||||
return result;
|
||||
}
|
||||
result.collision = true;
|
||||
// Zero distance ray
|
||||
if( rayB === 0 ){
|
||||
result.closeX = startX;
|
||||
result.closeY = startY;
|
||||
result.closeSqDist = 0;
|
||||
result.farX = startX;
|
||||
result.farY = startY;
|
||||
result.farSqDist = 0;
|
||||
}
|
||||
var t1 = minOverlap / Math.abs(rayB);
|
||||
var t2 = maxOverlap / Math.abs(rayB);
|
||||
result.closeX = startX + t1*r[0];
|
||||
result.closeY = startY + t1*r[1];
|
||||
result.closeSqDist = t1*t1*(r[0]*r[0] + r[1]*r[1]);
|
||||
result.farX = startX + t2*r[0];
|
||||
result.farY = startY + t2*r[1];
|
||||
result.farSqDist = t2*t2*(r[0]*r[0] + r[1]*r[1]);
|
||||
|
||||
return result;
|
||||
}
|
||||
// One point intersection
|
||||
else if ( crossRS !== 0 && 0<=t && t<=1 && 0<=u && u<=1 )
|
||||
{
|
||||
var x = p[0] + t*r[0];
|
||||
var y = p[1] + t*r[1];
|
||||
|
||||
var sqDist = (x-startX)*(x-startX) + (y-startY)*(y-startY);
|
||||
if ( sqDist < minSqDist )
|
||||
{
|
||||
if ( !result.collision ){
|
||||
result.farX = x;
|
||||
result.farY = y;
|
||||
result.farSqDist = sqDist;
|
||||
}
|
||||
minSqDist = sqDist;
|
||||
result.closeX = x;
|
||||
result.closeY = y;
|
||||
result.closeSqDist = sqDist;
|
||||
result.collision = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.farX = x;
|
||||
result.farY = y;
|
||||
result.farSqDist = sqDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
gdjs.Polygon.raycastTest._statics = {
|
||||
p: [0,0],
|
||||
q: [0,0],
|
||||
r: [0,0],
|
||||
s: [0,0],
|
||||
deltaQP: [0,0],
|
||||
axis: [0,0],
|
||||
result: {
|
||||
collision: false,
|
||||
closeX: 0,
|
||||
closeY: 0,
|
||||
closeSqDist: 0,
|
||||
farX: 0,
|
||||
farY: 0,
|
||||
farSqDist: 0
|
||||
}
|
||||
}
|
||||
|
||||
//Tools functions :
|
||||
gdjs.Polygon.normalise = function(v)
|
||||
{
|
||||
@@ -237,6 +377,13 @@ gdjs.Polygon.dotProduct = function(a, b)
|
||||
return dp;
|
||||
}
|
||||
|
||||
gdjs.Polygon.crossProduct = function(a, b)
|
||||
{
|
||||
var cp = a[0]*b[1] - a[1]*b[0];
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
gdjs.Polygon.project = function(axis, p, result)
|
||||
{
|
||||
var dp = gdjs.Polygon.dotProduct(axis, p.vertices[0]);
|
||||
|
@@ -13,38 +13,44 @@
|
||||
* @param data The object (usually stored in data.json) containing the full project data
|
||||
* @param spec Optional object for specifiying additional options: {forceFullscreen: ...}
|
||||
*/
|
||||
gdjs.RuntimeGame = function(data, spec)
|
||||
{
|
||||
spec = spec || {};
|
||||
gdjs.RuntimeGame = function(data, spec) {
|
||||
spec = spec || {};
|
||||
|
||||
this._variables = new gdjs.VariablesContainer(data.variables);
|
||||
this._data = data;
|
||||
this._imageManager = new gdjs.ImageManager(data.resources ? data.resources.resources : undefined);
|
||||
this._soundManager = new gdjs.SoundManager(data.resources ? data.resources.resources : undefined);
|
||||
this._minFPS = data ? parseInt(data.properties.minFPS, 10) : 15;
|
||||
this._variables = new gdjs.VariablesContainer(data.variables);
|
||||
this._data = data;
|
||||
this._imageManager = new gdjs.ImageManager(
|
||||
data.resources ? data.resources.resources : undefined
|
||||
);
|
||||
this._soundManager = new gdjs.SoundManager(
|
||||
data.resources ? data.resources.resources : undefined
|
||||
);
|
||||
this._minFPS = data ? parseInt(data.properties.minFPS, 10) : 15;
|
||||
|
||||
this._defaultWidth = data.properties.windowWidth; //Default size for scenes cameras
|
||||
this._defaultHeight = data.properties.windowHeight;
|
||||
this._originalWidth = data.properties.windowWidth; //Original size of the game, won't be changed.
|
||||
this._originalHeight = data.properties.windowHeight;
|
||||
this._renderer = new gdjs.RuntimeGameRenderer(this,
|
||||
this._defaultWidth, this._defaultHeight,
|
||||
spec.forceFullscreen || false);
|
||||
this._defaultWidth = data.properties.windowWidth; //Default size for scenes cameras
|
||||
this._defaultHeight = data.properties.windowHeight;
|
||||
this._originalWidth = data.properties.windowWidth; //Original size of the game, won't be changed.
|
||||
this._originalHeight = data.properties.windowHeight;
|
||||
this._renderer = new gdjs.RuntimeGameRenderer(
|
||||
this,
|
||||
this._defaultWidth,
|
||||
this._defaultHeight,
|
||||
spec.forceFullscreen || false
|
||||
);
|
||||
|
||||
//Game loop management (see startGameLoop method)
|
||||
this._sceneStack = new gdjs.SceneStack(this);
|
||||
this._notifySceneForResize = false; //When set to true, the current scene is notified that canvas size changed.
|
||||
//Game loop management (see startGameLoop method)
|
||||
this._sceneStack = new gdjs.SceneStack(this);
|
||||
this._notifySceneForResize = false; //When set to true, the current scene is notified that canvas size changed.
|
||||
|
||||
//Inputs :
|
||||
this._inputManager = new gdjs.InputManager();
|
||||
//Inputs :
|
||||
this._inputManager = new gdjs.InputManager();
|
||||
|
||||
//Allow to specify an external layout to insert in the first scene:
|
||||
this._injectExternalLayout = spec.injectExternalLayout || "";
|
||||
//Allow to specify an external layout to insert in the first scene:
|
||||
this._injectExternalLayout = spec.injectExternalLayout || '';
|
||||
};
|
||||
|
||||
gdjs.RuntimeGame.prototype.getRenderer = function() {
|
||||
return this._renderer;
|
||||
}
|
||||
return this._renderer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the variables of the RuntimeGame.
|
||||
@@ -52,7 +58,7 @@ gdjs.RuntimeGame.prototype.getRenderer = function() {
|
||||
* @return a variablesContainer object.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getVariables = function() {
|
||||
return this._variables;
|
||||
return this._variables;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -61,7 +67,7 @@ gdjs.RuntimeGame.prototype.getVariables = function() {
|
||||
* @return {gdjs.SoundManager} The sound manager.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getSoundManager = function() {
|
||||
return this._soundManager;
|
||||
return this._soundManager;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -70,7 +76,7 @@ gdjs.RuntimeGame.prototype.getSoundManager = function() {
|
||||
* @return {gdjs.ImageManager} The image manager.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getImageManager = function() {
|
||||
return this._imageManager;
|
||||
return this._imageManager;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -79,7 +85,7 @@ gdjs.RuntimeGame.prototype.getImageManager = function() {
|
||||
* @return The input manager owned by the game
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getInputManager = function() {
|
||||
return this._inputManager;
|
||||
return this._inputManager;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -88,7 +94,7 @@ gdjs.RuntimeGame.prototype.getInputManager = function() {
|
||||
* @return The object associated to the game.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getGameData = function() {
|
||||
return this._data;
|
||||
return this._data;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -99,20 +105,20 @@ gdjs.RuntimeGame.prototype.getGameData = function() {
|
||||
* @return The data associated to the scene.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getSceneData = function(sceneName) {
|
||||
var scene = undefined;
|
||||
for(var i = 0, len = this._data.layouts.length;i<len;++i) {
|
||||
var sceneData = this._data.layouts[i];
|
||||
var scene = undefined;
|
||||
for (var i = 0, len = this._data.layouts.length; i < len; ++i) {
|
||||
var sceneData = this._data.layouts[i];
|
||||
|
||||
if ( sceneName === undefined || sceneData.name === sceneName ) {
|
||||
scene = sceneData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sceneName === undefined || sceneData.name === sceneName) {
|
||||
scene = sceneData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( scene === undefined )
|
||||
console.warn("The game has no scene called \""+sceneName+"\"");
|
||||
if (scene === undefined)
|
||||
console.warn('The game has no scene called "' + sceneName + '"');
|
||||
|
||||
return scene;
|
||||
return scene;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -123,17 +129,17 @@ gdjs.RuntimeGame.prototype.getSceneData = function(sceneName) {
|
||||
* @return true if the scene exists. If sceneName is undefined, true if the game has a scene.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.hasScene = function(sceneName) {
|
||||
var isTrue = false;
|
||||
for(var i = 0, len = this._data.layouts.length;i<len;++i) {
|
||||
var sceneData = this._data.layouts[i];
|
||||
var isTrue = false;
|
||||
for (var i = 0, len = this._data.layouts.length; i < len; ++i) {
|
||||
var sceneData = this._data.layouts[i];
|
||||
|
||||
if ( sceneName === undefined || sceneData.name == sceneName ) {
|
||||
isTrue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sceneName === undefined || sceneData.name == sceneName) {
|
||||
isTrue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isTrue;
|
||||
return isTrue;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -144,17 +150,17 @@ gdjs.RuntimeGame.prototype.hasScene = function(sceneName) {
|
||||
* @return The data associated to the external layout or null if not found.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getExternalLayoutData = function(name) {
|
||||
var externalLayout = null;
|
||||
for(var i = 0, len = this._data.externalLayouts.length;i<len;++i) {
|
||||
var layoutData = this._data.externalLayouts[i];
|
||||
var externalLayout = null;
|
||||
for (var i = 0, len = this._data.externalLayouts.length; i < len; ++i) {
|
||||
var layoutData = this._data.externalLayouts[i];
|
||||
|
||||
if ( layoutData.name === name ) {
|
||||
externalLayout = layoutData;
|
||||
break;
|
||||
}
|
||||
if (layoutData.name === name) {
|
||||
externalLayout = layoutData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return externalLayout;
|
||||
return externalLayout;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -163,7 +169,7 @@ gdjs.RuntimeGame.prototype.getExternalLayoutData = function(name) {
|
||||
* @return The data associated to the global objects.
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getInitialObjectsData = function() {
|
||||
return this._data.objects || [];
|
||||
return this._data.objects || [];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -173,7 +179,7 @@ gdjs.RuntimeGame.prototype.getInitialObjectsData = function() {
|
||||
* @method getOriginalWidth
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getOriginalWidth = function() {
|
||||
return this._originalWidth;
|
||||
return this._originalWidth;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -183,7 +189,7 @@ gdjs.RuntimeGame.prototype.getOriginalWidth = function() {
|
||||
* @method getOriginalHeight
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getOriginalHeight = function() {
|
||||
return this._originalHeight;
|
||||
return this._originalHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -192,7 +198,7 @@ gdjs.RuntimeGame.prototype.getOriginalHeight = function() {
|
||||
* @method getDefaultWidth
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getDefaultWidth = function() {
|
||||
return this._defaultWidth;
|
||||
return this._defaultWidth;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -201,7 +207,7 @@ gdjs.RuntimeGame.prototype.getDefaultWidth = function() {
|
||||
* @method getDefaultHeight
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getDefaultHeight = function() {
|
||||
return this._defaultHeight;
|
||||
return this._defaultHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -211,7 +217,7 @@ gdjs.RuntimeGame.prototype.getDefaultHeight = function() {
|
||||
* @param width {Number} The new default width
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.setDefaultWidth = function(width) {
|
||||
this._defaultWidth = width;
|
||||
this._defaultWidth = width;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -221,7 +227,7 @@ gdjs.RuntimeGame.prototype.setDefaultWidth = function(width) {
|
||||
* @param height {Number} The new default height
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.setDefaultHeight = function(height) {
|
||||
this._defaultHeight = height;
|
||||
this._defaultHeight = height;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -230,7 +236,7 @@ gdjs.RuntimeGame.prototype.setDefaultHeight = function(height) {
|
||||
* @method getMinimalFramerate
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.getMinimalFramerate = function() {
|
||||
return this._minFPS;
|
||||
return this._minFPS;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -238,60 +244,73 @@ gdjs.RuntimeGame.prototype.getMinimalFramerate = function() {
|
||||
* @method loadAllAssets
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.loadAllAssets = function(callback) {
|
||||
var loadingScreen = new gdjs.LoadingScreenRenderer(this.getRenderer());
|
||||
var allAssetsTotal = this._data.resources.resources.length;
|
||||
var loadingScreen = new gdjs.LoadingScreenRenderer(
|
||||
this.getRenderer(),
|
||||
this._data.properties.loadingScreen
|
||||
);
|
||||
var allAssetsTotal = this._data.resources.resources.length;
|
||||
|
||||
var that = this;
|
||||
this._imageManager.loadTextures(function (count, total) {
|
||||
loadingScreen.render(Math.floor(count / allAssetsTotal * 100));
|
||||
}, function() {
|
||||
that._soundManager.preloadAudio(function (count, total) {
|
||||
loadingScreen.render(Math.floor((allAssetsTotal - total + count)
|
||||
/ allAssetsTotal * 100));
|
||||
}, function() {
|
||||
callback();
|
||||
});
|
||||
});
|
||||
var that = this;
|
||||
this._imageManager.loadTextures(
|
||||
function(count, total) {
|
||||
loadingScreen.render(Math.floor(count / allAssetsTotal * 100));
|
||||
},
|
||||
function() {
|
||||
that._soundManager.preloadAudio(
|
||||
function(count, total) {
|
||||
loadingScreen.render(
|
||||
Math.floor((allAssetsTotal - total + count) / allAssetsTotal * 100)
|
||||
);
|
||||
},
|
||||
function() {
|
||||
loadingScreen.unload();
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
gdjs.RuntimeGame.prototype.startGameLoop = function() {
|
||||
if ( !this.hasScene() ) {
|
||||
console.log("The game has no scene.");
|
||||
return;
|
||||
if (!this.hasScene()) {
|
||||
console.log('The game has no scene.');
|
||||
return;
|
||||
}
|
||||
|
||||
//Load the first scene
|
||||
var firstSceneName = gdjs.projectData.firstLayout;
|
||||
this._sceneStack.push(
|
||||
this.hasScene(firstSceneName) ? firstSceneName : this.getSceneData().name,
|
||||
this._injectExternalLayout
|
||||
);
|
||||
|
||||
//Uncomment to profile the first x frames of the game.
|
||||
// var x = 500;
|
||||
// var startTime = Date.now();
|
||||
// console.profile("Stepping for " + x + " frames")
|
||||
// for(var i = 0; i < x; ++i) {
|
||||
// this._sceneStack.step(16);
|
||||
// }
|
||||
// console.profileEnd();
|
||||
// var time = Date.now() - startTime;
|
||||
// console.log("Took", time, "ms");
|
||||
// return;
|
||||
|
||||
//The standard game loop
|
||||
var that = this;
|
||||
this._renderer.startGameLoop(function(elapsedTime) {
|
||||
//Manage resize events.
|
||||
if (that._notifySceneForResize) {
|
||||
that._sceneStack.onRendererResized();
|
||||
that._notifySceneForResize = false;
|
||||
}
|
||||
|
||||
//Load the first scene
|
||||
var firstSceneName = gdjs.projectData.firstLayout;
|
||||
this._sceneStack.push(this.hasScene(firstSceneName) ? firstSceneName : this.getSceneData().name,
|
||||
this._injectExternalLayout);
|
||||
//Render and step the scene.
|
||||
if (that._sceneStack.step(elapsedTime)) {
|
||||
that.getInputManager().onFrameEnded();
|
||||
return true;
|
||||
}
|
||||
|
||||
//Uncomment to profile the first x frames of the game.
|
||||
// var x = 500;
|
||||
// var startTime = Date.now();
|
||||
// console.profile("Stepping for " + x + " frames")
|
||||
// for(var i = 0; i < x; ++i) {
|
||||
// this._sceneStack.step(16);
|
||||
// }
|
||||
// console.profileEnd();
|
||||
// var time = Date.now() - startTime;
|
||||
// console.log("Took", time, "ms");
|
||||
// return;
|
||||
|
||||
//The standard game loop
|
||||
var that = this;
|
||||
this._renderer.startGameLoop(function(elapsedTime) {
|
||||
//Manage resize events.
|
||||
if (that._notifySceneForResize) {
|
||||
that._sceneStack.onRendererResized();
|
||||
that._notifySceneForResize = false;
|
||||
}
|
||||
|
||||
//Render and step the scene.
|
||||
if (that._sceneStack.step(elapsedTime)) {
|
||||
that.getInputManager().onFrameEnded();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
@@ -1151,12 +1151,47 @@ gdjs.RuntimeObject.collisionTest = function(obj1, obj2) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the distance between two objects.
|
||||
* @method distanceTest
|
||||
* @static
|
||||
* @method raycastTest
|
||||
* @param x {Number} The raycast source X
|
||||
* @param y {Number} The raycast source Y
|
||||
* @param angle {Number} The raycast angle
|
||||
* @param dist {Number} The raycast max distance
|
||||
* @param closest {Boolean} Get the closest or farthest collision mask result?
|
||||
* @return A raycast result with the contact points and distances
|
||||
*/
|
||||
gdjs.RuntimeObject.distanceTest = function(obj1, obj2, distance) {
|
||||
return obj1.getSqDistanceToObject(obj2) <= distance;
|
||||
gdjs.RuntimeObject.prototype.raycastTest = function(x, y, angle, dist, closest) {
|
||||
var objW = this.getWidth();
|
||||
var objH = this.getHeight();
|
||||
var diffX = this.getDrawableX()+this.getCenterX() - x;
|
||||
var diffY = this.getDrawableY()+this.getCenterY() - y;
|
||||
var boundingRadius = Math.sqrt(objW*objW + objH*objH)/2.0;
|
||||
|
||||
var result = gdjs.Polygon.raycastTest._statics.result;
|
||||
result.collision = false;
|
||||
|
||||
if ( Math.sqrt(diffX*diffX + diffY*diffY) > boundingRadius + dist )
|
||||
return result;
|
||||
|
||||
var endX = x + dist*Math.cos(angle*Math.PI/180.0);
|
||||
var endY = y + dist*Math.sin(angle*Math.PI/180.0);
|
||||
var testSqDist = closest ? dist*dist : 0;
|
||||
|
||||
var hitBoxes = this.getHitBoxes();
|
||||
for (var i=0; i<hitBoxes.length; i++) {
|
||||
var res = gdjs.Polygon.raycastTest(hitBoxes[i], x, y, endX, endY);
|
||||
if ( res.collision ) {
|
||||
if ( closest && (res.closeSqDist < testSqDist) ) {
|
||||
testSqDist = res.closeSqDist;
|
||||
result = res;
|
||||
}
|
||||
else if ( !closest && (res.farSqDist > testSqDist) && (res.farSqDist <= dist*dist) ) {
|
||||
testSqDist = res.farSqDist;
|
||||
result = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1174,6 +1209,15 @@ gdjs.RuntimeObject.prototype.insideObject = function(x, y) {
|
||||
&& this.getDrawableY() + this.getHeight() >= y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the distance between two objects.
|
||||
* @method distanceTest
|
||||
* @static
|
||||
*/
|
||||
gdjs.RuntimeObject.distanceTest = function(obj1, obj2, distance) {
|
||||
return obj1.getSqDistanceToObject(obj2) <= distance;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if the cursor, or any touch, is on the object.
|
||||
*
|
||||
|
@@ -161,7 +161,6 @@ gdjs.RuntimeScene.prototype.unloadScene = function() {
|
||||
this._allInstancesList = [];
|
||||
this._instancesRemoved = [];
|
||||
|
||||
this._renderer = new gdjs.RuntimeSceneRenderer(this, this._runtimeGame ? this._runtimeGame.getRenderer() : null);
|
||||
this._lastId = 0;
|
||||
this._eventsContext = null;
|
||||
|
||||
|
606
GDJS/tests/games/Raycast.gdg
Normal file
@@ -0,0 +1,606 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<project firstLayout="">
|
||||
<gdVersion build="96" major="4" minor="0" revision="140" />
|
||||
<properties folderProject="false" linuxExecutableFilename="" macExecutableFilename="" packageName="com.example.gamename" projectFile="C:\Users\Maciel\Programacion\gits\GD\GDJS\tests\games\Raycast.gdg" useExternalSourceFiles="false" winExecutableFilename="" winExecutableIconFile="">
|
||||
<name>Project</name>
|
||||
<author></author>
|
||||
<windowWidth>800</windowWidth>
|
||||
<windowHeight>600</windowHeight>
|
||||
<latestCompilationDirectory></latestCompilationDirectory>
|
||||
<maxFPS>60</maxFPS>
|
||||
<minFPS>10</minFPS>
|
||||
<verticalSync>false</verticalSync>
|
||||
<extensions>
|
||||
<extension name="BuiltinObject" />
|
||||
<extension name="BuiltinAudio" />
|
||||
<extension name="BuiltinVariables" />
|
||||
<extension name="BuiltinTime" />
|
||||
<extension name="BuiltinMouse" />
|
||||
<extension name="BuiltinKeyboard" />
|
||||
<extension name="BuiltinJoystick" />
|
||||
<extension name="BuiltinCamera" />
|
||||
<extension name="BuiltinWindow" />
|
||||
<extension name="BuiltinFile" />
|
||||
<extension name="BuiltinNetwork" />
|
||||
<extension name="BuiltinScene" />
|
||||
<extension name="BuiltinAdvanced" />
|
||||
<extension name="Sprite" />
|
||||
<extension name="BuiltinCommonInstructions" />
|
||||
<extension name="BuiltinCommonConversions" />
|
||||
<extension name="BuiltinStringInstructions" />
|
||||
<extension name="BuiltinMathematicalTools" />
|
||||
<extension name="BuiltinExternalLayouts" />
|
||||
<extension name="PrimitiveDrawing" />
|
||||
</extensions>
|
||||
<platforms>
|
||||
<platform name="GDevelop JS platform" />
|
||||
<platform name="GDevelop C++ platform" />
|
||||
</platforms>
|
||||
<currentPlatform>GDevelop JS platform</currentPlatform>
|
||||
</properties>
|
||||
<resources>
|
||||
<resources>
|
||||
<resource alwaysLoaded="false" file="Grass.png" kind="image" name="Grass.png" smoothed="true" userAdded="true" />
|
||||
<resource alwaysLoaded="false" file="spship2.png" kind="image" name="spship2.png" smoothed="true" userAdded="false" />
|
||||
<resource alwaysLoaded="false" file="Shape1.png" kind="image" name="Shape1.png" smoothed="true" userAdded="false" />
|
||||
<resource alwaysLoaded="false" file="Pea-Happy.png" kind="image" name="Pea-Happy.png" smoothed="true" userAdded="false" />
|
||||
</resources>
|
||||
<resourceFolders />
|
||||
</resources>
|
||||
<objects />
|
||||
<objectsGroups />
|
||||
<variables />
|
||||
<layouts>
|
||||
<layout b="30" disableInputWhenNotFocused="true" mangledName="Scene" name="Scene" oglFOV="90.000000" oglZFar="500.000000" oglZNear="1.000000" r="30" standardSortMethod="false" stopSoundsOnStartup="true" title="" v="30">
|
||||
<uiSettings grid="false" gridB="80" gridG="80" gridHeight="70" gridOffsetX="0" gridOffsetY="20" gridR="80" gridWidth="70" snap="true" windowMask="false" zoomFactor="0.754867" />
|
||||
<objectsGroups>
|
||||
<group name="Colliders">
|
||||
<objects>
|
||||
<object name="Quad" />
|
||||
<object name="Line" />
|
||||
<object name="Triangle" />
|
||||
<object name="Polygon" />
|
||||
</objects>
|
||||
</group>
|
||||
</objectsGroups>
|
||||
<variables />
|
||||
<instances>
|
||||
<instance angle="0.000000" customSize="true" height="64.000000" layer="" locked="false" name="Player" width="64.000000" x="400.000000" y="300.000000" zOrder="2">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="160.000000" layer="" locked="false" name="Quad" width="160.000000" x="511.653046" y="426.899933" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="642.864868" y="20.479473" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="340.216797" y="524.969666" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="52.560143" y="106.766174" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="202.182587" y="29.507092" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="550.417358" y="268.102661" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="259.622040" y="466.785736" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="640.945984" y="188.205658" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="80.000000" layer="" locked="false" name="Quad" width="80.000000" x="330.563049" y="69.781281" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="13.854311" y="547.935608" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="4.000000" layer="" locked="false" name="Line" width="200.000000" x="42.436562" y="348.760468" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="22.880741" y="14.281113" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="694.834351" y="81.030281" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="321.407257" y="436.969086" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="false" height="0.000000" layer="" locked="false" name="Drawer" width="0.000000" x="467.504181" y="221.897949" zOrder="5">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="687.335632" y="495.352386" zOrder="1">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="231.507050" y="134.513855" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="432.457794" y="17.137005" zOrder="3">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="119.492599" y="63.272141" zOrder="3">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="625.232666" y="333.912476" zOrder="3">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="476.822723" y="355.556915" zOrder="3">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="404.859680" y="522.776550" zOrder="3">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="80.000000" layer="" locked="false" name="Polygon" width="100.000000" x="19.355259" y="383.442963" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="50.000000" layer="" locked="false" name="Polygon" width="100.000000" x="723.214783" y="536.209045" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
<instance angle="0.000000" customSize="true" height="140.000000" layer="" locked="false" name="Polygon" width="60.000000" x="517.953369" y="37.765617" zOrder="4">
|
||||
<numberProperties />
|
||||
<stringProperties />
|
||||
<initialVariables />
|
||||
</instance>
|
||||
</instances>
|
||||
<objects>
|
||||
<object name="Player" type="Sprite" updateIfNotVisible="true">
|
||||
<variables />
|
||||
<behaviors />
|
||||
<animations>
|
||||
<animation name="" useMultipleDirections="false">
|
||||
<directions>
|
||||
<direction looping="false" timeBetweenFrames="1.000000">
|
||||
<sprites>
|
||||
<sprite hasCustomCollisionMask="false" image="Pea-Happy.png">
|
||||
<points />
|
||||
<originPoint name="origine" x="18.000000" y="18.000000" />
|
||||
<centerPoint automatic="true" name="centre" x="18.500000" y="18.500000" />
|
||||
<customCollisionMask>
|
||||
<polygon>
|
||||
<vertice x="0.000000" y="0.000000" />
|
||||
<vertice x="37.000000" y="0.000000" />
|
||||
<vertice x="37.000000" y="37.000000" />
|
||||
<vertice x="0.000000" y="37.000000" />
|
||||
</polygon>
|
||||
</customCollisionMask>
|
||||
</sprite>
|
||||
</sprites>
|
||||
</direction>
|
||||
</directions>
|
||||
</animation>
|
||||
</animations>
|
||||
</object>
|
||||
<object name="Quad" type="Sprite" updateIfNotVisible="true">
|
||||
<variables />
|
||||
<behaviors />
|
||||
<animations>
|
||||
<animation name="" useMultipleDirections="false">
|
||||
<directions>
|
||||
<direction looping="false" timeBetweenFrames="1.000000">
|
||||
<sprites>
|
||||
<sprite hasCustomCollisionMask="false" image="Grass.png">
|
||||
<points />
|
||||
<originPoint name="origine" x="0.000000" y="0.000000" />
|
||||
<centerPoint automatic="true" name="centre" x="35.000000" y="35.000000" />
|
||||
<customCollisionMask>
|
||||
<polygon>
|
||||
<vertice x="0.000000" y="0.000000" />
|
||||
<vertice x="70.000000" y="0.000000" />
|
||||
<vertice x="70.000000" y="70.000000" />
|
||||
<vertice x="0.000000" y="70.000000" />
|
||||
</polygon>
|
||||
</customCollisionMask>
|
||||
</sprite>
|
||||
</sprites>
|
||||
</direction>
|
||||
</directions>
|
||||
</animation>
|
||||
</animations>
|
||||
</object>
|
||||
<object name="Line" type="Sprite" updateIfNotVisible="false">
|
||||
<variables />
|
||||
<behaviors />
|
||||
<animations>
|
||||
<animation name="" useMultipleDirections="false">
|
||||
<directions>
|
||||
<direction looping="false" timeBetweenFrames="1.000000">
|
||||
<sprites>
|
||||
<sprite hasCustomCollisionMask="true" image="Pea-Happy.png">
|
||||
<points />
|
||||
<originPoint name="origine" x="0.000000" y="0.000000" />
|
||||
<centerPoint automatic="true" name="centre" x="18.500000" y="18.500000" />
|
||||
<customCollisionMask>
|
||||
<polygon>
|
||||
<vertice x="0.000000" y="18.000000" />
|
||||
<vertice x="36.000000" y="18.000000" />
|
||||
</polygon>
|
||||
</customCollisionMask>
|
||||
</sprite>
|
||||
</sprites>
|
||||
</direction>
|
||||
</directions>
|
||||
</animation>
|
||||
</animations>
|
||||
</object>
|
||||
<object name="Drawer" type="PrimitiveDrawing::Drawer">
|
||||
<variables />
|
||||
<behaviors />
|
||||
<fillOpacity>255</fillOpacity>
|
||||
<outlineSize>0</outlineSize>
|
||||
<outlineOpacity>0</outlineOpacity>
|
||||
<fillColor b="255" g="255" r="255" />
|
||||
<outlineColor b="255" g="34" r="250" />
|
||||
<absoluteCoordinates>true</absoluteCoordinates>
|
||||
</object>
|
||||
<object name="Triangle" type="Sprite" updateIfNotVisible="false">
|
||||
<variables />
|
||||
<behaviors />
|
||||
<animations>
|
||||
<animation name="" useMultipleDirections="false">
|
||||
<directions>
|
||||
<direction looping="false" timeBetweenFrames="1.000000">
|
||||
<sprites>
|
||||
<sprite hasCustomCollisionMask="true" image="spship2.png">
|
||||
<points />
|
||||
<originPoint name="origine" x="0.000000" y="0.000000" />
|
||||
<centerPoint automatic="true" name="centre" x="41.500000" y="41.500000" />
|
||||
<customCollisionMask>
|
||||
<polygon>
|
||||
<vertice x="0.000000" y="0.000000" />
|
||||
<vertice x="83.000000" y="42.000000" />
|
||||
<vertice x="0.000000" y="83.000000" />
|
||||
</polygon>
|
||||
</customCollisionMask>
|
||||
</sprite>
|
||||
</sprites>
|
||||
</direction>
|
||||
</directions>
|
||||
</animation>
|
||||
</animations>
|
||||
</object>
|
||||
<object name="Polygon" type="Sprite" updateIfNotVisible="false">
|
||||
<variables />
|
||||
<behaviors />
|
||||
<animations>
|
||||
<animation name="" useMultipleDirections="false">
|
||||
<directions>
|
||||
<direction looping="false" timeBetweenFrames="1.000000">
|
||||
<sprites>
|
||||
<sprite hasCustomCollisionMask="true" image="Shape1.png">
|
||||
<points />
|
||||
<originPoint name="origine" x="0.000000" y="0.000000" />
|
||||
<centerPoint automatic="true" name="centre" x="89.000000" y="64.500000" />
|
||||
<customCollisionMask>
|
||||
<polygon>
|
||||
<vertice x="0.000000" y="47.000000" />
|
||||
<vertice x="77.000000" y="0.000000" />
|
||||
<vertice x="175.000000" y="11.000000" />
|
||||
<vertice x="178.000000" y="56.000000" />
|
||||
<vertice x="160.000000" y="96.000000" />
|
||||
<vertice x="104.000000" y="129.000000" />
|
||||
<vertice x="7.000000" y="103.000000" />
|
||||
</polygon>
|
||||
</customCollisionMask>
|
||||
</sprite>
|
||||
</sprites>
|
||||
</direction>
|
||||
</directions>
|
||||
</animation>
|
||||
</animations>
|
||||
</object>
|
||||
</objects>
|
||||
<events>
|
||||
<event disabled="false" folded="false">
|
||||
<type>BuiltinCommonInstructions::Standard</type>
|
||||
<conditions>
|
||||
<instruction>
|
||||
<type inverted="false" value="DepartScene" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</conditions>
|
||||
<actions />
|
||||
<events>
|
||||
<event disabled="false" folded="false">
|
||||
<type>BuiltinCommonInstructions::Repeat</type>
|
||||
<repeatExpression>300</repeatExpression>
|
||||
<conditions />
|
||||
<actions>
|
||||
<instruction>
|
||||
<type inverted="false" value="Create" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
<parameter>Polygon</parameter>
|
||||
<parameter>Random(200)</parameter>
|
||||
<parameter>Random(200)</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="Create" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
<parameter>Line</parameter>
|
||||
<parameter>500 + Random(300)</parameter>
|
||||
<parameter>400 + Random(200)</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="ChangeScaleHeight" />
|
||||
<parameters>
|
||||
<parameter>Line</parameter>
|
||||
<parameter>=</parameter>
|
||||
<parameter>0.1</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</actions>
|
||||
<events />
|
||||
</event>
|
||||
</events>
|
||||
</event>
|
||||
<event disabled="false" folded="false">
|
||||
<type>BuiltinCommonInstructions::Standard</type>
|
||||
<conditions />
|
||||
<actions>
|
||||
<instruction>
|
||||
<type inverted="false" value="ChangeColor" />
|
||||
<parameters>
|
||||
<parameter>Colliders</parameter>
|
||||
<parameter>"255;255;255"</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::FillColor" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>"200;200;250"</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::FillOpacity" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>=</parameter>
|
||||
<parameter>50</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::Circle" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>Player.X()</parameter>
|
||||
<parameter>Player.Y()</parameter>
|
||||
<parameter>400</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</actions>
|
||||
<events />
|
||||
</event>
|
||||
<event disabled="false" folded="false">
|
||||
<type>BuiltinCommonInstructions::Standard</type>
|
||||
<conditions>
|
||||
<instruction>
|
||||
<type inverted="true" value="Raycast" />
|
||||
<parameters>
|
||||
<parameter>Colliders</parameter>
|
||||
<parameter>Player.X()</parameter>
|
||||
<parameter>Player.Y()</parameter>
|
||||
<parameter>ToDeg(atan2(MouseY("",0)-Player.Y(), MouseX("",0)-Player.X()))</parameter>
|
||||
<parameter>400</parameter>
|
||||
<parameter>x</parameter>
|
||||
<parameter>y</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</conditions>
|
||||
<actions>
|
||||
<instruction>
|
||||
<type inverted="false" value="SetAngle" />
|
||||
<parameters>
|
||||
<parameter>Colliders</parameter>
|
||||
<parameter>+</parameter>
|
||||
<parameter>10 * TimeDelta()</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::FillColor" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>"255;0;0"</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::FillOpacity" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>=</parameter>
|
||||
<parameter>100</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::Line" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>Player.X()</parameter>
|
||||
<parameter>Player.Y()</parameter>
|
||||
<parameter>Variable(x)</parameter>
|
||||
<parameter>Variable(y)</parameter>
|
||||
<parameter>1</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::Circle" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>Variable(x)</parameter>
|
||||
<parameter>Variable(y)</parameter>
|
||||
<parameter>3</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</actions>
|
||||
<events />
|
||||
</event>
|
||||
<event disabled="false" folded="false">
|
||||
<type>BuiltinCommonInstructions::Standard</type>
|
||||
<conditions>
|
||||
<instruction>
|
||||
<type inverted="false" value="Raycast" />
|
||||
<parameters>
|
||||
<parameter>Colliders</parameter>
|
||||
<parameter>Player.X()</parameter>
|
||||
<parameter>Player.Y()</parameter>
|
||||
<parameter>ToDeg(atan2(MouseY("",0)-Player.Y(), MouseX("",0)-Player.X()))</parameter>
|
||||
<parameter>400</parameter>
|
||||
<parameter>x</parameter>
|
||||
<parameter>y</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</conditions>
|
||||
<actions>
|
||||
<instruction>
|
||||
<type inverted="false" value="ChangeColor" />
|
||||
<parameters>
|
||||
<parameter>Colliders</parameter>
|
||||
<parameter>"50;100;50"</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::FillColor" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>"0;255;0"</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::FillOpacity" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>=</parameter>
|
||||
<parameter>100</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::Line" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>Player.X()</parameter>
|
||||
<parameter>Player.Y()</parameter>
|
||||
<parameter>Variable(x)</parameter>
|
||||
<parameter>Variable(y)</parameter>
|
||||
<parameter>1</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="PrimitiveDrawing::Circle" />
|
||||
<parameters>
|
||||
<parameter>Drawer</parameter>
|
||||
<parameter>Variable(x)</parameter>
|
||||
<parameter>Variable(y)</parameter>
|
||||
<parameter>2</parameter>
|
||||
</parameters>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</actions>
|
||||
<events />
|
||||
</event>
|
||||
</events>
|
||||
<layers>
|
||||
<layer name="" visibility="true">
|
||||
<cameras>
|
||||
<camera defaultSize="true" defaultViewport="true" height="0.000000" viewportBottom="1.000000" viewportLeft="0.000000" viewportRight="1.000000" viewportTop="0.000000" width="0.000000" />
|
||||
</cameras>
|
||||
<effects />
|
||||
</layer>
|
||||
<layer name="Debug" visibility="true">
|
||||
<cameras>
|
||||
<camera defaultSize="true" defaultViewport="true" height="0.000000" viewportBottom="1.000000" viewportLeft="0.000000" viewportRight="1.000000" viewportTop="0.000000" width="0.000000" />
|
||||
</cameras>
|
||||
<effects />
|
||||
</layer>
|
||||
</layers>
|
||||
<behaviorsSharedData />
|
||||
</layout>
|
||||
</layouts>
|
||||
<externalEvents />
|
||||
<externalLayouts />
|
||||
<externalSourceFiles>
|
||||
<sourceFile filename="C:\Users\Maciel\AppData\Local\Temp/GDTemporaries/GD0x67750b8SourceFile.cpp" gdManaged="true" language="C++" />
|
||||
<sourceFile filename="C:\Users\Maciel\AppData\Local\Temp/GDTemporaries/GD0x6830850SourceFile.cpp" gdManaged="true" language="C++" />
|
||||
</externalSourceFiles>
|
||||
</project>
|
BIN
GDJS/tests/games/Shape1.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
@@ -9,7 +9,7 @@ Getting started [ to download GD! |
|
||||
| Download GDevelop to make games | Go on [GDevelop website](https://gdevelop-app.com) to download GD! |
|
||||
| Contribute to the new editor | Download [Node.js] and follow this [README](newIDE/README.md). |
|
||||
| Contribute to the old C++ editor | Download and launch [CMake], choose this directory as the source, generate the Makefile and launch it. Be sure to have [required development libraries](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/setup_dev_env.html) installed. <br><br> Fully detailed instructions are [available here](http://4ian.github.io/GD-Documentation). |
|
||||
| Help to translate GDevelop | Go on the [GDevelop project on Crowdin](https://crowdin.com/project/gdevelop). |
|
||||
@@ -36,7 +36,7 @@ Links
|
||||
### Community
|
||||
|
||||
* [GDevelop forums](http://forum.compilgames.net)
|
||||
* [GDevelop homepage](http://www.compilgames.net) ([open source](https://github.com/4ian/GDevelop-website))
|
||||
* [GDevelop homepage](https://gdevelop-app.com) ([open-source](https://github.com/4ian/GDevelop-website))
|
||||
* [GDevelop wiki](http://wiki.compilgames.net)
|
||||
* Help translate GD in your language: [GDevelop project on Crowdin](https://crowdin.com/project/gdevelop).
|
||||
* [GDevelop Nightly Builds](http://nightlies.gd.victorlevasseur.com/) (powered by a [Buildbot](https://github.com/victorlevasseur/GD-Buildbot)) ([open source](https://github.com/victorlevasseur/GD-Nightlies-Website))
|
||||
|
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
|
||||
project(GDVersion)
|
||||
set(GD_VERSION_STR "4.0.96")
|
||||
set(GD_VERSION_STR "4.0.97-0-release")
|
||||
|
||||
if(FULL_VERSION_NUMBER)
|
||||
set(GENERATE_VERSION_SCRIPT ${PROJECT_SOURCE_DIR}/GenerateVersionFull.cmake)
|
||||
|
@@ -23,7 +23,8 @@ yarn start #or npm start
|
||||
|
||||
This will open the app in your web browser.
|
||||
|
||||
Images resources, GDJS Runtime, extensions will be copied in resources, and [libGD.js](https://github.com/4ian/GDevelop.js) will be downloaded automatically.
|
||||
Images resources, GDJS Runtime, extensions will be copied in resources, and [libGD.js](https://github.com/4ian/GDevelop.js) will be downloaded automatically. If you wish, you can
|
||||
[build libGD.js by yourself](https://github.com/4ian/GDevelop.js) (useful if you modified GDevelop native code like extensions).
|
||||
|
||||
### Development of the standalone app
|
||||
|
||||
@@ -97,7 +98,6 @@ yarn deploy #or npm run deploy
|
||||
This new editor is still in development and is missing some features:
|
||||
|
||||
- [ ] Support for translations (See an [example of a component that can be translated](https://github.com/4ian/GD/blob/master/newIDE/app/src/MainFrame/Toolbar.js#L44))
|
||||
- [ ] [Collision mask editor](https://trello.com/c/2Kzwj61r/47-collision-masks-editors-for-sprite-objects-in-the-new-ide)
|
||||
- [ ] Support for native games
|
||||
- [ ] More [documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) about how to package for iOS/Android with Cordova/PhoneGap Build or Cocos2d-JS.
|
||||
- [ ] Search in events
|
||||
@@ -108,6 +108,8 @@ This new editor is still in development and is missing some features:
|
||||
|
||||
You can contribute by picking anything here or anything that you think is missing or could be improved in GD5! If you don't know how to start, it's a good idea to play a bit with the editor and see if there is something that is unavailable and that you can add or fix.
|
||||
|
||||
See also [the roadmap for ideas and features planned](https://trello.com/b/qf0lM7k8/gdevelop-roadmap).
|
||||
|
||||
## Additional help
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app). Check out their documentation for common tasks or help about using it.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Rename this file as .env.local and complete the following values.
|
||||
# Copy this file as ".env.local" and complete the following values.
|
||||
# If values are not completed, some features will be unavailable.
|
||||
|
||||
REACT_APP_PREVIEW_S3_ACCESS_KEY_ID=
|
||||
|
14
newIDE/app/flow-typed/libGD.js
vendored
@@ -13,6 +13,20 @@ declare type gdExternalEvents = EmscriptenObject;
|
||||
declare type gdSerializerElement = EmscriptenObject;
|
||||
declare type gdInitialInstance = EmscriptenObject;
|
||||
declare type gdBaseEvent = EmscriptenObject;
|
||||
declare type gdResource = EmscriptenObject;
|
||||
declare type gdObject = EmscriptenObject;
|
||||
|
||||
declare type gdInstruction = EmscriptenObject;
|
||||
declare type gdInstructionMetadata = EmscriptenObject;
|
||||
declare type gdInstructionsList = EmscriptenObject;
|
||||
declare type gdParameterMetadata = EmscriptenObject;
|
||||
|
||||
declare type gdVariable = EmscriptenObject;
|
||||
declare type gdVariablesContainer = EmscriptenObject;
|
||||
|
||||
declare type gdVectorPolygon2d = EmscriptenObject;
|
||||
|
||||
declare type gdSpriteObject = EmscriptenObject;
|
||||
|
||||
//Represents all objects that have serializeTo and unserializeFrom methods.
|
||||
declare type gdSerializable = EmscriptenObject;
|
||||
|
@@ -18,6 +18,7 @@
|
||||
"axios": "^0.16.1",
|
||||
"blueimp-md5": "^2.10.0",
|
||||
"classnames": "2.2.5",
|
||||
"create-react-context": "^0.1.6",
|
||||
"date-fns": "^1.29.0",
|
||||
"element-closest": "2.0.2",
|
||||
"firebase": "^4.8.2",
|
||||
|
@@ -25,27 +25,8 @@
|
||||
<meta name="theme-color" content="#4ab0e4">
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
||||
<!-- Fullstory user analytics -->
|
||||
<script>
|
||||
window['_fs_debug'] = false;
|
||||
window['_fs_host'] = 'fullstory.com';
|
||||
window['_fs_org'] = '8DWZ1';
|
||||
window['_fs_namespace'] = 'FS';
|
||||
(function(m,n,e,t,l,o,g,y){
|
||||
if (e in m) {if(m.console && m.console.log) { m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].');} return;}
|
||||
g=m[e]=function(a,b){g.q?g.q.push([a,b]):g._api(a,b);};g.q=[];
|
||||
o=n.createElement(t);o.async=1;o.src='https://'+_fs_host+'/s/fs.js';
|
||||
y=n.getElementsByTagName(t)[0];y.parentNode.insertBefore(o,y);
|
||||
g.identify=function(i,v){g(l,{uid:i});if(v)g(l,v)};g.setUserVars=function(v){g(l,v)};
|
||||
g.identifyAccount=function(i,v){o='account';v=v||{};v.acctId=i;g(o,v)};
|
||||
g.clearUserCookie=function(c,d,i){if(!c || document.cookie.match('fs_uid=[`;`]*`[`;`]*`[`;`]*`')){
|
||||
d=n.domain;while(1){n.cookie='fs_uid=;domain='+d+
|
||||
';path=/;expires='+new Date(0).toUTCString();i=d.indexOf('.');if(i<0)break;d=d.slice(i+1)}}};
|
||||
})(window,document,window['_fs_namespace'],'script','user');
|
||||
</script>
|
||||
|
||||
<!-- Stripe.com Checkout -->
|
||||
<script src="https://checkout.stripe.com/checkout.js"></script>
|
||||
<!-- Stripe.com Checkout -->
|
||||
<script src="https://checkout.stripe.com/checkout.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
BIN
newIDE/app/resources/examples/parallax/Elisa_standing.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
newIDE/app/resources/examples/parallax/Ground_(front_layer).png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
newIDE/app/resources/examples/parallax/Sky_back_layer.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 15 KiB |
760
newIDE/app/resources/examples/parallax/parallax.json
Normal file
@@ -0,0 +1,760 @@
|
||||
{
|
||||
"firstLayout": "",
|
||||
"gdVersion": {
|
||||
"build": 96,
|
||||
"major": 4,
|
||||
"minor": 0,
|
||||
"revision": 0
|
||||
},
|
||||
"properties": {
|
||||
"folderProject": false,
|
||||
"linuxExecutableFilename": "",
|
||||
"macExecutableFilename": "",
|
||||
"packageName": "",
|
||||
"projectFile": "/Users/florian/Desktop/parallax/parallax.json",
|
||||
"useExternalSourceFiles": false,
|
||||
"winExecutableFilename": "",
|
||||
"winExecutableIconFile": "",
|
||||
"name": "Project",
|
||||
"author": "",
|
||||
"windowWidth": 600,
|
||||
"windowHeight": 400,
|
||||
"latestCompilationDirectory": "",
|
||||
"maxFPS": 60,
|
||||
"minFPS": 10,
|
||||
"verticalSync": false,
|
||||
"extensions": [
|
||||
{
|
||||
"name": "BuiltinObject"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinAudio"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinVariables"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinTime"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinMouse"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinKeyboard"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinJoystick"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinCamera"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinWindow"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinFile"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinNetwork"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinScene"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinAdvanced"
|
||||
},
|
||||
{
|
||||
"name": "Sprite"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinCommonInstructions"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinCommonConversions"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinStringInstructions"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinMathematicalTools"
|
||||
},
|
||||
{
|
||||
"name": "BuiltinExternalLayouts"
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
{
|
||||
"name": "GDevelop JS platform"
|
||||
}
|
||||
],
|
||||
"currentPlatform": "GDevelop JS platform"
|
||||
},
|
||||
"resources": {
|
||||
"resources": [
|
||||
{
|
||||
"alwaysLoaded": false,
|
||||
"file": "Vegetation_(middle_layer).png",
|
||||
"kind": "image",
|
||||
"name": "Vegetation_(middle_layer).png",
|
||||
"smoothed": true,
|
||||
"userAdded": true
|
||||
},
|
||||
{
|
||||
"alwaysLoaded": false,
|
||||
"file": "Ground_(front_layer).png",
|
||||
"kind": "image",
|
||||
"name": "Ground_(front_layer).png",
|
||||
"smoothed": true,
|
||||
"userAdded": true
|
||||
},
|
||||
{
|
||||
"alwaysLoaded": false,
|
||||
"file": "Sky_back_layer.png",
|
||||
"kind": "image",
|
||||
"name": "Sky_back_layer.png",
|
||||
"smoothed": true,
|
||||
"userAdded": true
|
||||
},
|
||||
{
|
||||
"alwaysLoaded": false,
|
||||
"file": "Elisa_standing.png",
|
||||
"kind": "image",
|
||||
"name": "Elisa_standing.png",
|
||||
"smoothed": true,
|
||||
"userAdded": true
|
||||
}
|
||||
],
|
||||
"resourceFolders": []
|
||||
},
|
||||
"objects": [],
|
||||
"objectsGroups": [],
|
||||
"variables": [],
|
||||
"layouts": [
|
||||
{
|
||||
"b": 209,
|
||||
"disableInputWhenNotFocused": true,
|
||||
"mangledName": "New_32scene",
|
||||
"name": "New scene",
|
||||
"oglFOV": 90,
|
||||
"oglZFar": 500,
|
||||
"oglZNear": 1,
|
||||
"r": 209,
|
||||
"standardSortMethod": true,
|
||||
"stopSoundsOnStartup": true,
|
||||
"title": "",
|
||||
"v": 209,
|
||||
"uiSettings": {
|
||||
"grid": true,
|
||||
"gridB": 255,
|
||||
"gridG": 180,
|
||||
"gridHeight": 32,
|
||||
"gridOffsetX": 0,
|
||||
"gridOffsetY": 0,
|
||||
"gridR": 158,
|
||||
"gridWidth": 32,
|
||||
"snap": true,
|
||||
"windowMask": false,
|
||||
"zoomFactor": 1
|
||||
},
|
||||
"objectsGroups": [],
|
||||
"variables": [],
|
||||
"instances": [
|
||||
{
|
||||
"angle": 0,
|
||||
"customSize": false,
|
||||
"height": 0,
|
||||
"layer": "",
|
||||
"locked": false,
|
||||
"name": "ObjectToFollow",
|
||||
"width": 0,
|
||||
"x": -128,
|
||||
"y": 320,
|
||||
"zOrder": 1,
|
||||
"numberProperties": [],
|
||||
"stringProperties": [],
|
||||
"initialVariables": []
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"customSize": false,
|
||||
"height": 0,
|
||||
"layer": "Layer4",
|
||||
"locked": false,
|
||||
"name": "Background",
|
||||
"width": 0,
|
||||
"x": -640,
|
||||
"y": -32,
|
||||
"zOrder": 1,
|
||||
"numberProperties": [],
|
||||
"stringProperties": [],
|
||||
"initialVariables": []
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"customSize": false,
|
||||
"height": 0,
|
||||
"layer": "Layer3",
|
||||
"locked": false,
|
||||
"name": "Background",
|
||||
"width": 0,
|
||||
"x": -640,
|
||||
"y": -32,
|
||||
"zOrder": 1,
|
||||
"numberProperties": [
|
||||
{
|
||||
"name": "animation",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"stringProperties": [],
|
||||
"initialVariables": []
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"customSize": false,
|
||||
"height": 0,
|
||||
"layer": "Layer2",
|
||||
"locked": false,
|
||||
"name": "Background",
|
||||
"width": 0,
|
||||
"x": -608,
|
||||
"y": -32,
|
||||
"zOrder": 1,
|
||||
"numberProperties": [
|
||||
{
|
||||
"name": "animation",
|
||||
"value": 2
|
||||
}
|
||||
],
|
||||
"stringProperties": [],
|
||||
"initialVariables": []
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"customSize": false,
|
||||
"height": 0,
|
||||
"layer": "Layer3",
|
||||
"locked": false,
|
||||
"name": "Background",
|
||||
"width": 0,
|
||||
"x": 0,
|
||||
"y": -32,
|
||||
"zOrder": 1,
|
||||
"numberProperties": [
|
||||
{
|
||||
"name": "animation",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"stringProperties": [],
|
||||
"initialVariables": []
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"customSize": false,
|
||||
"height": 0,
|
||||
"layer": "Layer2",
|
||||
"locked": false,
|
||||
"name": "Background",
|
||||
"width": 0,
|
||||
"x": 0,
|
||||
"y": -32,
|
||||
"zOrder": 1,
|
||||
"numberProperties": [
|
||||
{
|
||||
"name": "animation",
|
||||
"value": 2
|
||||
}
|
||||
],
|
||||
"stringProperties": [],
|
||||
"initialVariables": []
|
||||
},
|
||||
{
|
||||
"angle": 0,
|
||||
"customSize": false,
|
||||
"height": 0,
|
||||
"layer": "Layer4",
|
||||
"locked": false,
|
||||
"name": "Background",
|
||||
"width": 0,
|
||||
"x": 0,
|
||||
"y": -32,
|
||||
"zOrder": 1,
|
||||
"numberProperties": [],
|
||||
"stringProperties": [],
|
||||
"initialVariables": []
|
||||
}
|
||||
],
|
||||
"objects": [
|
||||
{
|
||||
"name": "Background",
|
||||
"type": "Sprite",
|
||||
"updateIfNotVisible": true,
|
||||
"variables": [],
|
||||
"behaviors": [],
|
||||
"animations": [
|
||||
{
|
||||
"name": "",
|
||||
"useMultipleDirections": false,
|
||||
"directions": [
|
||||
{
|
||||
"looping": false,
|
||||
"timeBetweenFrames": 1,
|
||||
"sprites": [
|
||||
{
|
||||
"hasCustomCollisionMask": false,
|
||||
"image": "Sky_back_layer.png",
|
||||
"points": [],
|
||||
"originPoint": {
|
||||
"name": "origine",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"centerPoint": {
|
||||
"automatic": true,
|
||||
"name": "centre",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"customCollisionMask": [
|
||||
[
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"useMultipleDirections": false,
|
||||
"directions": [
|
||||
{
|
||||
"looping": false,
|
||||
"timeBetweenFrames": 1,
|
||||
"sprites": [
|
||||
{
|
||||
"hasCustomCollisionMask": false,
|
||||
"image": "Vegetation_(middle_layer).png",
|
||||
"points": [],
|
||||
"originPoint": {
|
||||
"name": "origine",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"centerPoint": {
|
||||
"automatic": true,
|
||||
"name": "centre",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"customCollisionMask": [
|
||||
[
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"useMultipleDirections": false,
|
||||
"directions": [
|
||||
{
|
||||
"looping": false,
|
||||
"timeBetweenFrames": 1,
|
||||
"sprites": [
|
||||
{
|
||||
"hasCustomCollisionMask": false,
|
||||
"image": "Ground_(front_layer).png",
|
||||
"points": [],
|
||||
"originPoint": {
|
||||
"name": "origine",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"centerPoint": {
|
||||
"automatic": true,
|
||||
"name": "centre",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"customCollisionMask": [
|
||||
[
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ObjectToFollow",
|
||||
"type": "Sprite",
|
||||
"updateIfNotVisible": true,
|
||||
"variables": [],
|
||||
"behaviors": [],
|
||||
"animations": [
|
||||
{
|
||||
"name": "",
|
||||
"useMultipleDirections": false,
|
||||
"directions": [
|
||||
{
|
||||
"looping": false,
|
||||
"timeBetweenFrames": 1,
|
||||
"sprites": [
|
||||
{
|
||||
"hasCustomCollisionMask": false,
|
||||
"image": "Elisa_standing.png",
|
||||
"points": [],
|
||||
"originPoint": {
|
||||
"name": "origine",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"centerPoint": {
|
||||
"automatic": true,
|
||||
"name": "centre",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"customCollisionMask": [
|
||||
[
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"disabled": false,
|
||||
"folded": false,
|
||||
"type": "BuiltinCommonInstructions::Comment",
|
||||
"color": {
|
||||
"b": 109,
|
||||
"g": 230,
|
||||
"r": 255,
|
||||
"textB": 0,
|
||||
"textG": 0,
|
||||
"textR": 0
|
||||
},
|
||||
"comment": "The character can just be moved left and right - in a real game you can use the Platformer character behavior.",
|
||||
"comment2": ""
|
||||
},
|
||||
{
|
||||
"disabled": false,
|
||||
"folded": false,
|
||||
"type": "BuiltinCommonInstructions::Standard",
|
||||
"conditions": [
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "KeyPressed"
|
||||
},
|
||||
"parameters": [
|
||||
"",
|
||||
"Left"
|
||||
],
|
||||
"subInstructions": []
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "AddForceXY"
|
||||
},
|
||||
"parameters": [
|
||||
"ObjectToFollow",
|
||||
"-200",
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
"subInstructions": []
|
||||
}
|
||||
],
|
||||
"events": []
|
||||
},
|
||||
{
|
||||
"disabled": false,
|
||||
"folded": false,
|
||||
"type": "BuiltinCommonInstructions::Standard",
|
||||
"conditions": [
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "KeyPressed"
|
||||
},
|
||||
"parameters": [
|
||||
"",
|
||||
"Right"
|
||||
],
|
||||
"subInstructions": []
|
||||
}
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "AddForceXY"
|
||||
},
|
||||
"parameters": [
|
||||
"ObjectToFollow",
|
||||
"200",
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
"subInstructions": []
|
||||
}
|
||||
],
|
||||
"events": []
|
||||
},
|
||||
{
|
||||
"disabled": false,
|
||||
"folded": false,
|
||||
"type": "BuiltinCommonInstructions::Standard",
|
||||
"conditions": [],
|
||||
"actions": [
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "MoveObjects"
|
||||
},
|
||||
"parameters": [
|
||||
""
|
||||
],
|
||||
"subInstructions": []
|
||||
}
|
||||
],
|
||||
"events": []
|
||||
},
|
||||
{
|
||||
"disabled": false,
|
||||
"folded": false,
|
||||
"type": "BuiltinCommonInstructions::Comment",
|
||||
"color": {
|
||||
"b": 109,
|
||||
"g": 230,
|
||||
"r": 255,
|
||||
"textB": 0,
|
||||
"textG": 0,
|
||||
"textR": 0
|
||||
},
|
||||
"comment": "Parallax is achieved by setting the position of the camera to the position of the player, multiplied by a factor (between 0 and 1).\nA small factor makes the layer appears far.\nA factor close to 1 makes the layer appears like if it was near the player.",
|
||||
"comment2": ""
|
||||
},
|
||||
{
|
||||
"disabled": false,
|
||||
"folded": false,
|
||||
"type": "BuiltinCommonInstructions::Standard",
|
||||
"conditions": [],
|
||||
"actions": [
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "CameraX"
|
||||
},
|
||||
"parameters": [
|
||||
"",
|
||||
"=",
|
||||
"ObjectToFollow.X()",
|
||||
"",
|
||||
""
|
||||
],
|
||||
"subInstructions": []
|
||||
},
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "CameraX"
|
||||
},
|
||||
"parameters": [
|
||||
"",
|
||||
"=",
|
||||
"ObjectToFollow.X()*0.75",
|
||||
"\"Layer2\"",
|
||||
""
|
||||
],
|
||||
"subInstructions": []
|
||||
},
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "CameraX"
|
||||
},
|
||||
"parameters": [
|
||||
"",
|
||||
"=",
|
||||
"ObjectToFollow.X()*0.50",
|
||||
"\"Layer3\"",
|
||||
""
|
||||
],
|
||||
"subInstructions": []
|
||||
},
|
||||
{
|
||||
"type": {
|
||||
"inverted": false,
|
||||
"value": "CameraX"
|
||||
},
|
||||
"parameters": [
|
||||
"",
|
||||
"=",
|
||||
"ObjectToFollow.X()*0.25",
|
||||
"\"Layer4\"",
|
||||
""
|
||||
],
|
||||
"subInstructions": []
|
||||
}
|
||||
],
|
||||
"events": []
|
||||
}
|
||||
],
|
||||
"layers": [
|
||||
{
|
||||
"name": "Layer4",
|
||||
"visibility": true,
|
||||
"cameras": [
|
||||
{
|
||||
"defaultSize": true,
|
||||
"defaultViewport": true,
|
||||
"height": 0,
|
||||
"viewportBottom": 1,
|
||||
"viewportLeft": 0,
|
||||
"viewportRight": 1,
|
||||
"viewportTop": 0,
|
||||
"width": 0
|
||||
}
|
||||
],
|
||||
"effects": []
|
||||
},
|
||||
{
|
||||
"name": "Layer3",
|
||||
"visibility": true,
|
||||
"cameras": [
|
||||
{
|
||||
"defaultSize": true,
|
||||
"defaultViewport": true,
|
||||
"height": 0,
|
||||
"viewportBottom": 1,
|
||||
"viewportLeft": 0,
|
||||
"viewportRight": 1,
|
||||
"viewportTop": 0,
|
||||
"width": 0
|
||||
}
|
||||
],
|
||||
"effects": []
|
||||
},
|
||||
{
|
||||
"name": "Layer2",
|
||||
"visibility": true,
|
||||
"cameras": [
|
||||
{
|
||||
"defaultSize": true,
|
||||
"defaultViewport": true,
|
||||
"height": 0,
|
||||
"viewportBottom": 1,
|
||||
"viewportLeft": 0,
|
||||
"viewportRight": 1,
|
||||
"viewportTop": 0,
|
||||
"width": 0
|
||||
}
|
||||
],
|
||||
"effects": []
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"visibility": true,
|
||||
"cameras": [
|
||||
{
|
||||
"defaultSize": true,
|
||||
"defaultViewport": true,
|
||||
"height": 0,
|
||||
"viewportBottom": 1,
|
||||
"viewportLeft": 0,
|
||||
"viewportRight": 1,
|
||||
"viewportTop": 0,
|
||||
"width": 0
|
||||
}
|
||||
],
|
||||
"effects": []
|
||||
}
|
||||
],
|
||||
"behaviorsSharedData": []
|
||||
}
|
||||
],
|
||||
"externalEvents": [],
|
||||
"externalLayouts": [],
|
||||
"externalSourceFiles": []
|
||||
}
|
BIN
newIDE/app/resources/examples/pathfinding/3DWall.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
newIDE/app/resources/examples/pathfinding/DestroyedTank.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
newIDE/app/resources/examples/pathfinding/ExplosionTexture.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
newIDE/app/resources/examples/pathfinding/GrassDead.png
Normal file
After Width: | Height: | Size: 143 KiB |