Compare commits
89 Commits
v5.0.0-bet
...
v5.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5f916903ab | ||
![]() |
60fe29660d | ||
![]() |
596e0087e5 | ||
![]() |
8034247494 | ||
![]() |
73b60e6da8 | ||
![]() |
57e00a7ce0 | ||
![]() |
1a6aa3b7ab | ||
![]() |
e6eb05ce22 | ||
![]() |
ddf63637fe | ||
![]() |
c02aec0f6b | ||
![]() |
280eebbccd | ||
![]() |
48611c2c38 | ||
![]() |
5dbbc25b2b | ||
![]() |
23c85d8a75 | ||
![]() |
cdd0f72266 | ||
![]() |
68189bf720 | ||
![]() |
376c2cc5c5 | ||
![]() |
38b587cdd4 | ||
![]() |
dd65aaf086 | ||
![]() |
db7604ee88 | ||
![]() |
d94749177b | ||
![]() |
d061be627b | ||
![]() |
3dede19f1f | ||
![]() |
916d2eb99e | ||
![]() |
9fadc0faab | ||
![]() |
ba6c7ec78d | ||
![]() |
0b4fc055bf | ||
![]() |
8a841fa68f | ||
![]() |
f71983679c | ||
![]() |
be3cc48e32 | ||
![]() |
956656236b | ||
![]() |
a53de69c4e | ||
![]() |
a7abbda061 | ||
![]() |
c267d14348 | ||
![]() |
7db2709ff0 | ||
![]() |
86a3614f89 | ||
![]() |
b8e0b5d8e3 | ||
![]() |
c7a8df3d5a | ||
![]() |
3be8966132 | ||
![]() |
61cefa6cd7 | ||
![]() |
e1dd41bb32 | ||
![]() |
24466ca653 | ||
![]() |
1c9497dc92 | ||
![]() |
5dd3ed43cf | ||
![]() |
368cdebd78 | ||
![]() |
3d7279144b | ||
![]() |
18682eccfa | ||
![]() |
f70c565e7d | ||
![]() |
b9035efc9e | ||
![]() |
493fc7b6f9 | ||
![]() |
52db6e15ee | ||
![]() |
28de2b179b | ||
![]() |
4a6c37f502 | ||
![]() |
9ce734e204 | ||
![]() |
fb3a0edfac | ||
![]() |
e613c7d546 | ||
![]() |
6db6455bb6 | ||
![]() |
86e928724a | ||
![]() |
f31d8f88c2 | ||
![]() |
940eac6bc4 | ||
![]() |
6908f51b4a | ||
![]() |
a537f678fb | ||
![]() |
1019aaba5f | ||
![]() |
5770ac6396 | ||
![]() |
7171f691a3 | ||
![]() |
0ad7b71cf2 | ||
![]() |
006d7296a2 | ||
![]() |
443c49f83e | ||
![]() |
9884965595 | ||
![]() |
e0379466e0 | ||
![]() |
622cba4642 | ||
![]() |
50c7a582ef | ||
![]() |
e501fd4a09 | ||
![]() |
50746b3c75 | ||
![]() |
1c5364f917 | ||
![]() |
89d099ff7d | ||
![]() |
ca1721ef9a | ||
![]() |
ddcf51a2b7 | ||
![]() |
46279e7762 | ||
![]() |
557af32cc9 | ||
![]() |
729a85a9a9 | ||
![]() |
34146c2f18 | ||
![]() |
00146bb8f8 | ||
![]() |
6026d79ebb | ||
![]() |
fc28f272b3 | ||
![]() |
9702db06a5 | ||
![]() |
209f83d697 | ||
![]() |
0ef8eb32a5 | ||
![]() |
8115b8181e |
@@ -1,15 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<project firstLayout="">
|
||||
<gdVersion build="84" major="3" minor="6" revision="0" />
|
||||
<properties linuxExecutableFilename="" macExecutableFilename="" useExternalSourceFiles="false" winExecutableFilename="" winExecutableIconFile="">
|
||||
<gdVersion build="97" major="4" minor="0" revision="0" />
|
||||
<properties folderProject="false" linuxExecutableFilename="" macExecutableFilename="" orientation="default" packageName="" projectFile="C:\Users\Maciel\Programacion\gits\GD\Binaries\Output\Release_Windows\Examples\Particles - Explosions.gdg" useExternalSourceFiles="false" winExecutableFilename="" winExecutableIconFile="">
|
||||
<name>Explosions</name>
|
||||
<author></author>
|
||||
<windowWidth>800</windowWidth>
|
||||
<windowHeight>600</windowHeight>
|
||||
<latestCompilationDirectory></latestCompilationDirectory>
|
||||
<latestCompilationDirectory>C:\Users\Maciel\AppData\Local\Temp\GDTemporaries\JSCocosExportParticles</latestCompilationDirectory>
|
||||
<maxFPS>60</maxFPS>
|
||||
<minFPS>10</minFPS>
|
||||
<verticalSync>false</verticalSync>
|
||||
<platformSpecificAssets />
|
||||
<loadingScreen showGDevelopSplash="true" />
|
||||
<extensions>
|
||||
<extension name="BuiltinObject" />
|
||||
<extension name="BuiltinAudio" />
|
||||
@@ -34,6 +36,7 @@
|
||||
</extensions>
|
||||
<platforms>
|
||||
<platform name="GDevelop C++ platform" />
|
||||
<platform name="GDevelop JS platform" />
|
||||
</platforms>
|
||||
<currentPlatform>GDevelop C++ platform</currentPlatform>
|
||||
</properties>
|
||||
@@ -48,40 +51,40 @@
|
||||
<variables />
|
||||
<layouts>
|
||||
<layout b="0" disableInputWhenNotFocused="true" mangledName="New_32scene" name="New scene" oglFOV="90.000000" oglZFar="500.000000" oglZNear="1.000000" r="0" standardSortMethod="true" stopSoundsOnStartup="true" title="" v="0">
|
||||
<uiSettings associatedLayout="" grid="false" gridB="255" gridG="180" gridHeight="32" gridOffsetX="0" gridOffsetY="0" gridR="158" gridWidth="32" snap="true" windowMask="false" zoomFactor="1.000000" />
|
||||
<uiSettings grid="false" gridB="255" gridG="180" gridHeight="32" gridOffsetX="0" gridOffsetY="0" gridR="158" gridWidth="32" snap="true" windowMask="false" zoomFactor="1.000000" />
|
||||
<objectsGroups />
|
||||
<variables />
|
||||
<instances />
|
||||
<objects>
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Mutable" destroyWhenNoParticles="true" emissionEditionSimpleMode="false" emitterAngleA="180.000000" emitterAngleB="160.000000" emitterForceMax="40.000000" emitterForceMin="5.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="-1.000000" friction="2.000000" gravityEditionSimpleMode="false" greenParam="Mutable" maxParticleNb="5000" name="Explosion" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="25.000000" particleBlue2="50.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="20.000000" particleGreen1="128.000000" particleGreen2="50.000000" particleLifeTimeMax="1.500000" particleLifeTimeMin="0.700000" particleRed1="255.000000" particleRed2="50.000000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Mutable" rendererParam1="20.000000" rendererParam2="20.000000" rendererType="Quad" sizeParam="Random" tank="1000.000000" textureParticleName="ExplosionTexture.png" type="ParticleSystem::ParticleEmitter" zoneRadius="2.000000">
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Mutable" destroyWhenNoParticles="true" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="360.000000" emitterForceMax="70.000000" emitterForceMin="30.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="-1.000000" friction="2.000000" gravityEditionSimpleMode="false" greenParam="Mutable" maxParticleNb="100" name="Explosion" particleAlpha1="225.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="25.000000" particleBlue2="50.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="20.000000" particleGreen1="128.000000" particleGreen2="50.000000" particleLifeTimeMax="1.500000" particleLifeTimeMin="0.700000" particleRed1="255.000000" particleRed2="50.000000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Mutable" rendererParam1="20.000000" rendererParam2="20.000000" rendererType="Quad" sizeParam="Random" tank="100.000000" textureParticleName="ExplosionTexture.png" type="ParticleSystem::ParticleEmitter" zoneRadius="2.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Mutable" destroyWhenNoParticles="true" emissionEditionSimpleMode="false" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="130.000000" emitterForceMin="50.000000" emitterXDirection="1.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="-1.000000" friction="2.000000" gravityEditionSimpleMode="false" greenParam="Mutable" maxParticleNb="5000" name="Explosion2" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="25.000000" particleBlue2="75.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="30.000000" particleGreen1="76.000000" particleGreen2="180.000000" particleLifeTimeMax="1.500000" particleLifeTimeMin="0.700000" particleRed1="153.000000" particleRed2="1.000000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="0.050000" rendererParam2="1.000000" rendererType="Line" sizeParam="Random" tank="350.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="2.000000">
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Mutable" destroyWhenNoParticles="true" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="360.000000" emitterForceMax="130.000000" emitterForceMin="130.000000" emitterXDirection="1.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="-1.000000" friction="2.000000" gravityEditionSimpleMode="false" greenParam="Mutable" maxParticleNb="151" name="Explosion2" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="25.000000" particleBlue2="75.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="30.000000" particleGreen1="76.000000" particleGreen2="180.000000" particleLifeTimeMax="1.000000" particleLifeTimeMin="0.700000" particleRed1="153.000000" particleRed2="1.000000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="3.000000" rendererParam2="6.000000" rendererType="Line" sizeParam="Random" tank="40.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="2.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Enabled" destroyWhenNoParticles="true" emissionEditionSimpleMode="false" emitterAngleA="45.000000" emitterAngleB="180.000000" emitterForceMax="10.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="400.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Enabled" maxParticleNb="5000" name="ExplosionSmoke" particleAlpha1="153.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="25.000000" particleBlue2="0.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="30.000000" particleGreen1="25.000000" particleGreen2="0.800000" particleLifeTimeMax="1.200000" particleLifeTimeMin="0.700000" particleRed1="25.000000" particleRed2="0.100000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="20.000000" rendererParam2="20.000000" rendererType="Quad" sizeParam="Random" tank="500.000000" textureParticleName="ExplosionTexture.png" type="ParticleSystem::ParticleEmitter" zoneRadius="20.000000">
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Enabled" destroyWhenNoParticles="true" emissionEditionSimpleMode="false" emitterAngleA="45.000000" emitterAngleB="180.000000" emitterForceMax="10.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="400.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Enabled" maxParticleNb="50" name="ExplosionSmoke" particleAlpha1="153.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="25.000000" particleBlue2="0.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="30.000000" particleGreen1="25.000000" particleGreen2="0.800000" particleLifeTimeMax="2.000000" particleLifeTimeMin="0.700000" particleRed1="25.000000" particleRed2="0.100000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="20.000000" rendererParam2="20.000000" rendererType="Quad" sizeParam="Random" tank="50.000000" textureParticleName="ExplosionTexture.png" type="ParticleSystem::ParticleEmitter" zoneRadius="20.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
</objects>
|
||||
<events>
|
||||
<event disabled="false" folded="false">
|
||||
<type>BuiltinCommonInstructions::Standard</type>
|
||||
<conditions>
|
||||
<condition>
|
||||
<instruction>
|
||||
<type inverted="false" value="Timer" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
<parameter>Random(0.3)+0.2</parameter>
|
||||
<parameter>"Creating"</parameter>
|
||||
</parameters>
|
||||
<subConditions />
|
||||
</condition>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</conditions>
|
||||
<actions>
|
||||
<action>
|
||||
<instruction>
|
||||
<type inverted="false" value="Create" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
@@ -90,9 +93,9 @@
|
||||
<parameter>Random(600)</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subActions />
|
||||
</action>
|
||||
<action>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="Create" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
@@ -101,9 +104,9 @@
|
||||
<parameter>Explosion.Y()</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subActions />
|
||||
</action>
|
||||
<action>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="Create" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
@@ -112,16 +115,16 @@
|
||||
<parameter>Explosion.Y()</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subActions />
|
||||
</action>
|
||||
<action>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="ResetTimer" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
<parameter>"Creating"</parameter>
|
||||
</parameters>
|
||||
<subActions />
|
||||
</action>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</actions>
|
||||
<events />
|
||||
</event>
|
||||
@@ -131,9 +134,10 @@
|
||||
<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>
|
||||
<automatismsSharedData />
|
||||
<behaviorsSharedData />
|
||||
</layout>
|
||||
</layouts>
|
||||
<externalEvents />
|
||||
|
@@ -1,15 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<project firstLayout="">
|
||||
<gdVersion build="84" major="3" minor="6" revision="0" />
|
||||
<properties linuxExecutableFilename="" macExecutableFilename="" useExternalSourceFiles="false" winExecutableFilename="" winExecutableIconFile="">
|
||||
<gdVersion build="97" major="4" minor="0" revision="0" />
|
||||
<properties folderProject="false" linuxExecutableFilename="" macExecutableFilename="" orientation="default" packageName="" projectFile="C:\Users\Maciel\Programacion\gits\GD\Binaries\Output\Release_Windows\Examples\Particles - Various effects.gdg" useExternalSourceFiles="false" winExecutableFilename="" winExecutableIconFile="">
|
||||
<name>Project</name>
|
||||
<author></author>
|
||||
<windowWidth>800</windowWidth>
|
||||
<windowHeight>600</windowHeight>
|
||||
<latestCompilationDirectory></latestCompilationDirectory>
|
||||
<latestCompilationDirectory>C:\Users\Maciel\AppData\Local\Temp\GDTemporaries\JSCocosExportParticles</latestCompilationDirectory>
|
||||
<maxFPS>60</maxFPS>
|
||||
<minFPS>10</minFPS>
|
||||
<verticalSync>false</verticalSync>
|
||||
<platformSpecificAssets />
|
||||
<loadingScreen showGDevelopSplash="true" />
|
||||
<extensions>
|
||||
<extension name="BuiltinObject" />
|
||||
<extension name="BuiltinAudio" />
|
||||
@@ -34,6 +36,7 @@
|
||||
</extensions>
|
||||
<platforms>
|
||||
<platform name="GDevelop C++ platform" />
|
||||
<platform name="GDevelop JS platform" />
|
||||
</platforms>
|
||||
<currentPlatform>GDevelop C++ platform</currentPlatform>
|
||||
</properties>
|
||||
@@ -47,8 +50,8 @@
|
||||
<objectsGroups />
|
||||
<variables />
|
||||
<layouts>
|
||||
<layout b="0" disableInputWhenNotFocused="true" mangledName="Nouvelle_32sc_232ne" name="Nouvelle scène" oglFOV="90.000000" oglZFar="500.000000" oglZNear="1.000000" r="0" standardSortMethod="true" stopSoundsOnStartup="true" title="" v="0">
|
||||
<uiSettings associatedLayout="" grid="false" gridB="255" gridG="180" gridHeight="32" gridOffsetX="0" gridOffsetY="0" gridR="158" gridWidth="32" snap="true" windowMask="false" zoomFactor="1.000000" />
|
||||
<layout b="0" disableInputWhenNotFocused="true" mangledName="Scene" name="Scene" oglFOV="90.000000" oglZFar="500.000000" oglZNear="1.000000" r="0" standardSortMethod="true" stopSoundsOnStartup="true" title="" v="0">
|
||||
<uiSettings grid="false" gridB="255" gridG="180" gridHeight="32" gridOffsetX="0" gridOffsetY="0" gridR="158" gridWidth="32" snap="true" windowMask="false" zoomFactor="1.000000" />
|
||||
<objectsGroups />
|
||||
<variables />
|
||||
<instances>
|
||||
@@ -99,47 +102,47 @@
|
||||
</instance>
|
||||
</instances>
|
||||
<objects>
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Mutable" blueParam="Random" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="10.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="300.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Random" maxParticleNb="5000" name="Fire" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="30.000000" particleBlue1="50.000000" particleBlue2="0.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="-100.000000" particleGravityZ="0.000000" particleGreen1="50.000000" particleGreen2="204.000000" particleLifeTimeMax="2.500000" particleLifeTimeMin="0.500000" particleRed1="240.000000" particleRed2="1.000000" particleSize1="100.000000" particleSize2="0.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="10.000000" rendererParam2="20.000000" rendererType="Quad" sizeParam="Mutable" tank="-1.000000" textureParticleName="Fire" type="ParticleSystem::ParticleEmitter" zoneRadius="5.000000">
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Mutable" blueParam="Mutable" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="10.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="30.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Mutable" maxParticleNb="200" name="Fire" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="30.000000" particleBlue1="50.000000" particleBlue2="0.000000" particleEditionSimpleMode="true" particleGravityX="0.000000" particleGravityY="-100.000000" particleGravityZ="0.000000" particleGreen1="50.000000" particleGreen2="191.000000" particleLifeTimeMax="2.500000" particleLifeTimeMin="0.500000" particleRed1="240.000000" particleRed2="255.000000" particleSize1="100.000000" particleSize2="0.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Mutable" rendererParam1="10.000000" rendererParam2="20.000000" rendererType="Quad" sizeParam="Mutable" tank="-1.000000" textureParticleName="Fire" type="ParticleSystem::ParticleEmitter" zoneRadius="5.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
<object additive="false" alphaParam="Mutable" angleParam="Random" blueParam="Enabled" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="0.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="200.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Enabled" maxParticleNb="5000" name="Smoke" particleAlpha1="160.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="360.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="50.000000" particleBlue2="0.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="-100.000000" particleGravityZ="0.000000" particleGreen1="50.000000" particleGreen2="0.800000" particleLifeTimeMax="2.500000" particleLifeTimeMin="0.500000" particleRed1="50.000000" particleRed2="1.000000" particleSize1="20.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="30.000000" rendererParam2="30.000000" rendererType="Quad" sizeParam="Mutable" tank="-1.000000" textureParticleName="Fire" type="ParticleSystem::ParticleEmitter" zoneRadius="7.000000">
|
||||
<object additive="false" alphaParam="Mutable" angleParam="Random" blueParam="Mutable" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="360.000000" emitterForceMax="0.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="150.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Mutable" maxParticleNb="150" name="Smoke" particleAlpha1="160.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="360.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="255.000000" particleBlue2="149.000000" particleEditionSimpleMode="true" particleGravityX="0.000000" particleGravityY="-100.000000" particleGravityZ="0.000000" particleGreen1="250.000000" particleGreen2="144.000000" particleLifeTimeMax="2.500000" particleLifeTimeMin="0.500000" particleRed1="253.000000" particleRed2="135.000000" particleSize1="20.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Mutable" rendererParam1="30.000000" rendererParam2="30.000000" rendererType="Quad" sizeParam="Mutable" tank="-1.000000" textureParticleName="Fire" type="ParticleSystem::ParticleEmitter" zoneRadius="15.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="65.000000" emitterForceMin="25.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="200.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Random" maxParticleNb="5000" name="Particles" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="125.000000" particleBlue2="204.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="250.000000" particleGreen1="125.000000" particleGreen2="204.000000" particleLifeTimeMax="2.500000" particleLifeTimeMin="0.500000" particleRed1="204.000000" particleRed2="255.000000" particleSize1="0.000000" particleSize2="0.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Random" rendererParam1="8.000000" rendererParam2="1.000000" rendererType="Point" sizeParam="Random" tank="-1.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="2.000000">
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="65.000000" emitterForceMin="25.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="200.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Random" maxParticleNb="5000" name="Particles" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="125.000000" particleBlue2="204.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="250.000000" particleGreen1="125.000000" particleGreen2="204.000000" particleLifeTimeMax="2.500000" particleLifeTimeMin="0.500000" particleRed1="204.000000" particleRed2="255.000000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Random" rendererParam1="8.000000" rendererParam2="1.000000" rendererType="Point" sizeParam="Random" tank="-1.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="2.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
<object additive="false" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="0.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="100.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Random" maxParticleNb="5000" name="Beam" particleAlpha1="250.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="204.000000" particleBlue2="255.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="0.000000" particleGravityZ="500.000000" particleGreen1="127.000000" particleGreen2="230.000000" particleLifeTimeMax="2.000000" particleLifeTimeMin="0.500000" particleRed1="153.000000" particleRed2="180.000000" particleSize1="0.000000" particleSize2="0.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Random" rendererParam1="3.000000" rendererParam2="1.000000" rendererType="Line" sizeParam="Random" tank="-1.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="3.000000">
|
||||
<object additive="false" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="false" emissionEditionSimpleMode="false" emitterAngleA="-55.000000" emitterAngleB="-35.000000" emitterForceMax="5.000000" emitterForceMin="0.000000" emitterXDirection="0.000000" emitterYDirection="1.000000" emitterZDirection="0.000000" flow="100.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Random" maxParticleNb="151" name="Beam" particleAlpha1="250.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="204.000000" particleBlue2="255.000000" particleEditionSimpleMode="false" particleGravityX="100.000000" particleGravityY="0.000000" particleGravityZ="500.000000" particleGreen1="127.000000" particleGreen2="230.000000" particleLifeTimeMax="2.000000" particleLifeTimeMin="0.500000" particleRed1="153.000000" particleRed2="180.000000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Random" rendererParam1="100.000000" rendererParam2="3.000000" rendererType="Line" sizeParam="Random" tank="-1.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="20.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="0.000000" emitterForceMax="65.000000" emitterForceMin="25.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="0.000000" flow="300.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Random" maxParticleNb="5000" name="Beam2" particleAlpha1="125.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="255.000000" particleBlue2="204.000000" particleEditionSimpleMode="false" particleGravityX="-500.000000" particleGravityY="0.000000" particleGravityZ="0.000000" particleGreen1="204.000000" particleGreen2="125.000000" particleLifeTimeMax="5.000000" particleLifeTimeMin="0.500000" particleRed1="127.000000" particleRed2="0.500000" particleSize1="0.000000" particleSize2="0.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="0.500000" rendererParam2="2.000000" rendererType="Line" sizeParam="Random" tank="-1.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="3.000000">
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="false" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="0.000000" emitterForceMax="65.000000" emitterForceMin="25.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="0.000000" flow="50.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Random" maxParticleNb="5000" name="Beam2" particleAlpha1="125.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="255.000000" particleBlue2="204.000000" particleEditionSimpleMode="false" particleGravityX="-500.000000" particleGravityY="0.000000" particleGravityZ="0.000000" particleGreen1="204.000000" particleGreen2="125.000000" particleLifeTimeMax="5.000000" particleLifeTimeMin="0.500000" particleRed1="127.000000" particleRed2="0.500000" particleSize1="100.000000" particleSize2="100.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Enabled" rendererParam1="10.000000" rendererParam2="3.000000" rendererType="Line" sizeParam="Random" tank="-1.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="10.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="true" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="180.000000" emitterForceMax="100.000000" emitterForceMin="25.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="400.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Enabled" maxParticleNb="5000" name="Pyro" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="204.000000" particleBlue2="255.000000" particleEditionSimpleMode="false" particleGravityX="0.000000" particleGravityY="-100.000000" particleGravityZ="0.000000" particleGreen1="127.000000" particleGreen2="1.000000" particleLifeTimeMax="1.000000" particleLifeTimeMin="0.500000" particleRed1="127.000000" particleRed2="230.000000" particleSize1="100.000000" particleSize2="1.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Random" rendererParam1="0.060000" rendererParam2="3.000000" rendererType="Line" sizeParam="Mutable" tank="600.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="7.000000">
|
||||
<object additive="true" alphaParam="Mutable" angleParam="Random" blueParam="Random" destroyWhenNoParticles="true" emissionEditionSimpleMode="true" emitterAngleA="0.000000" emitterAngleB="360.000000" emitterForceMax="100.000000" emitterForceMin="25.000000" emitterXDirection="0.000000" emitterYDirection="0.000000" emitterZDirection="1.000000" flow="70.000000" friction="2.000000" gravityEditionSimpleMode="true" greenParam="Enabled" maxParticleNb="151" name="Pyro" particleAlpha1="204.000000" particleAlpha2="0.000000" particleAlphaRandomness1="0.000000" particleAlphaRandomness2="0.000000" particleAngle1="0.000000" particleAngle2="0.000000" particleAngleRandomness1="0.000000" particleAngleRandomness2="0.000000" particleBlue1="204.000000" particleBlue2="255.000000" particleEditionSimpleMode="false" particleGravityX="-0.000080" particleGravityY="-200.000000" particleGravityZ="0.000000" particleGreen1="127.000000" particleGreen2="1.000000" particleLifeTimeMax="1.000000" particleLifeTimeMin="0.500000" particleRed1="127.000000" particleRed2="230.000000" particleSize1="100.000000" particleSize2="1.000000" particleSizeRandomness1="0.000000" particleSizeRandomness2="0.000000" redParam="Random" rendererParam1="8.000000" rendererParam2="8.000000" rendererType="Line" sizeParam="Mutable" tank="80.000000" textureParticleName="" type="ParticleSystem::ParticleEmitter" zoneRadius="25.000000">
|
||||
<variables />
|
||||
<automatisms />
|
||||
<behaviors />
|
||||
</object>
|
||||
</objects>
|
||||
<events>
|
||||
<event disabled="false" folded="false">
|
||||
<type>BuiltinCommonInstructions::Standard</type>
|
||||
<conditions>
|
||||
<condition>
|
||||
<instruction>
|
||||
<type inverted="false" value="Timer" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
<parameter>Random(0.3)+1</parameter>
|
||||
<parameter>1</parameter>
|
||||
<parameter>"Creating"</parameter>
|
||||
</parameters>
|
||||
<subConditions />
|
||||
</condition>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</conditions>
|
||||
<actions>
|
||||
<action>
|
||||
<instruction>
|
||||
<type inverted="false" value="Create" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
@@ -148,16 +151,16 @@
|
||||
<parameter>100+Random(300)</parameter>
|
||||
<parameter></parameter>
|
||||
</parameters>
|
||||
<subActions />
|
||||
</action>
|
||||
<action>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
<instruction>
|
||||
<type inverted="false" value="ResetTimer" />
|
||||
<parameters>
|
||||
<parameter></parameter>
|
||||
<parameter>"Creating"</parameter>
|
||||
</parameters>
|
||||
<subActions />
|
||||
</action>
|
||||
<subInstructions />
|
||||
</instruction>
|
||||
</actions>
|
||||
<events />
|
||||
</event>
|
||||
@@ -167,9 +170,10 @@
|
||||
<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>
|
||||
<automatismsSharedData />
|
||||
<behaviorsSharedData />
|
||||
</layout>
|
||||
</layouts>
|
||||
<externalEvents />
|
||||
|
1864
Binaries/Output/Release_Windows/Examples/SkeletonTest.gdg
Normal file
1
Binaries/Output/Release_Windows/Examples/skeleton.json
Normal file
@@ -0,0 +1 @@
|
||||
{"SubTexture":[{"frameY":0,"y":234,"frameWidth":112,"frameX":0,"frameHeight":210,"width":111,"height":209,"name":"parts/tailTip","x":456},{"width":112,"y":234,"height":86,"name":"parts/armUpperL","x":340},{"width":48,"y":859,"height":80,"name":"parts/armL","x":373},{"width":96,"y":922,"height":78,"name":"parts/handL","x":1},{"frameY":0,"y":677,"frameWidth":204,"frameX":0,"frameHeight":180,"width":203,"height":180,"name":"parts/legL","x":238},{"frameY":0,"y":397,"frameWidth":236,"frameX":0,"frameHeight":348,"width":235,"height":347,"name":"parts/body","x":1},{"width":216,"y":397,"height":278,"name":"parts/tail","x":238},{"width":208,"y":746,"height":174,"name":"parts/clothes1","x":1},{"width":124,"y":677,"height":282,"name":"parts/hair","x":443},{"frameY":0,"y":1,"frameWidth":338,"frameX":0,"frameHeight":394,"width":337,"height":394,"name":"parts/head","x":1},{"width":28,"y":961,"height":46,"name":"parts/eyeL","x":459},{"frameY":0,"y":961,"frameWidth":38,"frameX":0,"frameHeight":58,"width":37,"height":58,"name":"parts/eyeR","x":420},{"frameY":0,"y":1,"frameWidth":180,"frameX":0,"frameHeight":232,"width":180,"height":231,"name":"parts/legR","x":340},{"width":160,"y":859,"height":94,"name":"parts/armUpperR","x":211},{"frameY":0,"y":941,"frameWidth":46,"frameX":0,"frameHeight":78,"width":45,"height":77,"name":"parts/armR","x":373},{"width":98,"y":322,"height":58,"name":"parts/handR","x":340},{"frameY":0,"y":955,"frameWidth":120,"frameX":0,"frameHeight":36,"width":119,"height":36,"name":"parts/beardL","x":237},{"width":136,"y":955,"height":36,"name":"parts/beardR","x":99}],"width":1024,"height":1024,"name":"dragon","imagePath":"dragon_tex.png"}
|
BIN
Binaries/Output/Release_Windows/Examples/skeleton_texture.png
Normal file
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 354 B |
After Width: | Height: | Size: 486 B |
After Width: | Height: | Size: 464 B |
After Width: | Height: | Size: 638 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 550 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 469 B |
After Width: | Height: | Size: 600 B |
BIN
Binaries/Output/Release_Windows/res/centerPoint.png
Normal file
After Width: | Height: | Size: 1005 B |
BIN
Binaries/Output/Release_Windows/res/originPoint.png
Normal file
After Width: | Height: | Size: 1006 B |
@@ -167,7 +167,7 @@ private:
|
||||
|
||||
/**
|
||||
* Initialize from another list of events, copying events. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed !
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const gd::EventsList & other);
|
||||
};
|
||||
|
@@ -879,6 +879,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(gd:
|
||||
|
||||
extension.AddExpression("Count", _("Number of objects"), _("Count the number of the specified objects currently picked"), _("Objects"), "res/conditions/nbObjet.png")
|
||||
.AddParameter("objectList", _("Object"));
|
||||
|
||||
obj.AddStrExpression("ObjectName", _("Object name"), _("Return the name of the object"), _("Objects"), "res/conditions/text.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -102,7 +102,7 @@ private:
|
||||
|
||||
/**
|
||||
* Initialize from another ExternalEvents. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed !
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const ExternalEvents & externalEvents);
|
||||
};
|
||||
|
@@ -493,7 +493,7 @@ private:
|
||||
|
||||
/**
|
||||
* Initialize from another layout. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed !
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const gd::Layout & other);
|
||||
};
|
||||
|
@@ -321,7 +321,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Initialize object using another object. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed !
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const gd::Object & object);
|
||||
};
|
||||
|
@@ -742,7 +742,7 @@ private:
|
||||
|
||||
/**
|
||||
* Initialize from another game. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed !
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const gd::Project & project);
|
||||
|
||||
|
@@ -210,4 +210,34 @@ void Variable::RemoveRecursively(const gd::Variable& variableToRemove)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Variable::Variable(const Variable& other) :
|
||||
value(other.value),
|
||||
str(other.str),
|
||||
isNumber(other.isNumber),
|
||||
isStructure(other.isStructure)
|
||||
{
|
||||
CopyChildren(other);
|
||||
}
|
||||
|
||||
Variable& Variable::operator=(const Variable& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
value = other.value;
|
||||
str = other.str;
|
||||
isNumber = other.isNumber;
|
||||
isStructure = other.isStructure;
|
||||
CopyChildren(other);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Variable::CopyChildren(const gd::Variable& other)
|
||||
{
|
||||
children.clear();
|
||||
for (auto& it : other.children) {
|
||||
children[it.first] = std::make_shared<gd::Variable>(*it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -30,8 +30,11 @@ public:
|
||||
* \brief Default constructor creating a variable with 0 as value.
|
||||
*/
|
||||
Variable() : value(0), isNumber(true), isStructure(false) {};
|
||||
Variable(const Variable&);
|
||||
virtual ~Variable() {};
|
||||
|
||||
Variable& operator=(const Variable & rhs);
|
||||
|
||||
/** \name Number or string
|
||||
* Methods and operators used when the variable is considered as a number or a string.
|
||||
*/
|
||||
@@ -207,6 +210,11 @@ private:
|
||||
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, std::shared_ptr<Variable>> children; ///<Children, when the variable is considered as a structure.
|
||||
|
||||
/**
|
||||
* Initialize children by copying them from another variable. Used by copy-ctor and assign-op.
|
||||
*/
|
||||
void CopyChildren(const Variable & other);
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@ const Variable& VariablesContainer::Get(const gd::String& name) const
|
||||
return badVariable;
|
||||
}
|
||||
|
||||
Variable & VariablesContainer::Get(std::size_t index)
|
||||
Variable& VariablesContainer::Get(std::size_t index)
|
||||
{
|
||||
if (index < variables.size())
|
||||
return *variables[index].second;
|
||||
@@ -71,7 +71,7 @@ Variable & VariablesContainer::Get(std::size_t index)
|
||||
return badVariable;
|
||||
}
|
||||
|
||||
const Variable & VariablesContainer::Get(std::size_t index) const
|
||||
const Variable& VariablesContainer::Get(std::size_t index) const
|
||||
{
|
||||
if (index < variables.size())
|
||||
return *variables[index].second;
|
||||
@@ -79,7 +79,7 @@ const Variable & VariablesContainer::Get(std::size_t index) const
|
||||
return badVariable;
|
||||
}
|
||||
|
||||
const gd::String & VariablesContainer::GetNameAt(std::size_t index) const
|
||||
const gd::String& VariablesContainer::GetNameAt(std::size_t index) const
|
||||
{
|
||||
if (index < variables.size())
|
||||
return variables[index].first;
|
||||
@@ -191,4 +191,27 @@ void VariablesContainer::UnserializeFrom(const SerializerElement& element)
|
||||
Insert(variableElement.GetStringAttribute("name", "", "Name"), variable, -1);
|
||||
}
|
||||
}
|
||||
|
||||
VariablesContainer::VariablesContainer(const VariablesContainer& other)
|
||||
{
|
||||
Init(other);
|
||||
}
|
||||
|
||||
VariablesContainer& VariablesContainer::operator=(const VariablesContainer& other)
|
||||
{
|
||||
if (this != &other)
|
||||
Init(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void VariablesContainer::Init(const gd::VariablesContainer& other)
|
||||
{
|
||||
variables.clear();
|
||||
for (auto& it : other.variables) {
|
||||
variables.push_back(std::make_pair(
|
||||
it.first,
|
||||
std::make_shared<gd::Variable>(*it.second)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -30,8 +30,11 @@ class GD_CORE_API VariablesContainer
|
||||
{
|
||||
public:
|
||||
VariablesContainer();
|
||||
VariablesContainer(const VariablesContainer&);
|
||||
virtual ~VariablesContainer() {};
|
||||
|
||||
VariablesContainer& operator=(const VariablesContainer & rhs);
|
||||
|
||||
/** \name Variables management
|
||||
* Members functions related to variables management.
|
||||
*/
|
||||
@@ -149,6 +152,12 @@ private:
|
||||
std::vector < std::pair<gd::String, std::shared_ptr<gd::Variable>> > variables;
|
||||
static gd::Variable badVariable;
|
||||
static gd::String badName;
|
||||
|
||||
/**
|
||||
* Initialize from another variables container, copying elements. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const VariablesContainer & other);
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -143,7 +143,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Initialize from another list of elements, copying elements. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed !
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const SPtrList<T> & other);
|
||||
};
|
||||
|
@@ -26,48 +26,6 @@ TEST_CASE( "Project", "[common]" ) {
|
||||
REQUIRE( project.GetName() == "myname" );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "Variable", "[common]" ) {
|
||||
SECTION("Basics") {
|
||||
gd::Variable variable;
|
||||
variable.SetValue(50);
|
||||
REQUIRE( variable.GetValue() == 50 );
|
||||
REQUIRE( variable == 50 );
|
||||
REQUIRE( variable.IsNumber() == true );
|
||||
REQUIRE( variable.IsStructure() == false );
|
||||
|
||||
variable.SetString("MyString");
|
||||
REQUIRE( variable.GetString() == "MyString" );
|
||||
REQUIRE( variable == "MyString" );
|
||||
REQUIRE( variable.IsNumber() == false );
|
||||
REQUIRE( variable.IsStructure() == false );
|
||||
}
|
||||
SECTION("Conversions") {
|
||||
gd::Variable variable;
|
||||
variable.SetValue(50);
|
||||
REQUIRE( variable.GetString() == "50" ); //Used as a string...
|
||||
REQUIRE( variable.IsNumber() == false ); //...so consider as a string
|
||||
|
||||
variable.SetString("MyString");
|
||||
REQUIRE( variable.GetValue() == 0 ); //Used as a number...
|
||||
REQUIRE( variable.IsNumber() == true ); //...so consider as a number
|
||||
}
|
||||
SECTION("Use with int and string like semantics") {
|
||||
gd::Variable variable;
|
||||
variable = 50;
|
||||
REQUIRE( variable.GetValue() == 50 );
|
||||
REQUIRE( variable.IsNumber() == true );
|
||||
|
||||
variable = "MyString";
|
||||
REQUIRE( variable.GetString() == "MyString" );
|
||||
REQUIRE( variable.IsNumber() == false );
|
||||
|
||||
variable = "MyRealStdString";
|
||||
REQUIRE( variable.GetString() == "MyRealStdString" );
|
||||
REQUIRE( variable.IsNumber() == false );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "EventsList", "[common][events]" ) {
|
||||
SECTION("Basics") {
|
||||
gd::EventsList list;
|
||||
|
89
Core/tests/Variable.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering events of GDevelop Core.
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
|
||||
TEST_CASE( "Variable", "[common][variables]" ) {
|
||||
SECTION("Basics") {
|
||||
gd::Variable variable;
|
||||
variable.SetValue(50);
|
||||
REQUIRE( variable.GetValue() == 50 );
|
||||
REQUIRE( variable == 50 );
|
||||
REQUIRE( variable.IsNumber() == true );
|
||||
REQUIRE( variable.IsStructure() == false );
|
||||
|
||||
variable.SetString("MyString");
|
||||
REQUIRE( variable.GetString() == "MyString" );
|
||||
REQUIRE( variable == "MyString" );
|
||||
REQUIRE( variable.IsNumber() == false );
|
||||
REQUIRE( variable.IsStructure() == false );
|
||||
}
|
||||
SECTION("Conversions") {
|
||||
gd::Variable variable;
|
||||
variable.SetValue(50);
|
||||
REQUIRE( variable.GetString() == "50" ); //Used as a string...
|
||||
REQUIRE( variable.IsNumber() == false ); //...so consider as a string
|
||||
|
||||
variable.SetString("MyString");
|
||||
REQUIRE( variable.GetValue() == 0 ); //Used as a number...
|
||||
REQUIRE( variable.IsNumber() == true ); //...so consider as a number
|
||||
}
|
||||
SECTION("Use with int and string like semantics") {
|
||||
gd::Variable variable;
|
||||
variable = 50;
|
||||
REQUIRE( variable.GetValue() == 50 );
|
||||
REQUIRE( variable.IsNumber() == true );
|
||||
|
||||
variable = "MyString";
|
||||
REQUIRE( variable.GetString() == "MyString" );
|
||||
REQUIRE( variable.IsNumber() == false );
|
||||
|
||||
variable = "MyRealStdString";
|
||||
REQUIRE( variable.GetString() == "MyRealStdString" );
|
||||
REQUIRE( variable.IsNumber() == false );
|
||||
}
|
||||
SECTION("Copy and assignment") {
|
||||
gd::Variable variable1;
|
||||
gd::Variable variable2;
|
||||
|
||||
variable1.GetChild("Child1").SetString("Hello World");
|
||||
variable1.GetChild("Child2").SetValue(42);
|
||||
|
||||
gd::Variable variable3(variable1);
|
||||
variable2 = variable1;
|
||||
|
||||
REQUIRE( variable2.HasChild("Child1") == true );
|
||||
REQUIRE( variable2.HasChild("Child2") == true );
|
||||
REQUIRE( variable3.HasChild("Child1") == true );
|
||||
REQUIRE( variable3.HasChild("Child2") == true );
|
||||
REQUIRE( variable1.GetChild("Child1").GetString() == "Hello World" );
|
||||
REQUIRE( variable1.GetChild("Child2").GetValue() == 42 );
|
||||
REQUIRE( variable2.GetChild("Child1").GetString() == "Hello World" );
|
||||
REQUIRE( variable2.GetChild("Child2").GetValue() == 42 );
|
||||
REQUIRE( variable3.GetChild("Child1").GetString() == "Hello World" );
|
||||
REQUIRE( variable3.GetChild("Child2").GetValue() == 42 );
|
||||
|
||||
variable2.GetChild("Child1").SetString("Hello copied World");
|
||||
variable2.GetChild("Child2").SetValue(43);
|
||||
variable3.GetChild("Child1").SetString("Hello second copied World");
|
||||
variable3.GetChild("Child2").SetValue(44);
|
||||
REQUIRE( variable1.GetChild("Child1").GetString() == "Hello World" );
|
||||
REQUIRE( variable1.GetChild("Child2").GetValue() == 42 );
|
||||
REQUIRE( variable2.GetChild("Child1").GetString() == "Hello copied World" );
|
||||
REQUIRE( variable2.GetChild("Child2").GetValue() == 43 );
|
||||
REQUIRE( variable3.GetChild("Child1").GetString() == "Hello second copied World" );
|
||||
REQUIRE( variable3.GetChild("Child2").GetValue() == 44 );
|
||||
}
|
||||
}
|
52
Core/tests/VariablesContainer.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
||||
* This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering events of GDevelop Core.
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
|
||||
TEST_CASE( "VariablesContainer", "[common][variables]" ) {
|
||||
|
||||
SECTION("Copy and assignment") {
|
||||
gd::VariablesContainer container1;
|
||||
gd::VariablesContainer container2;
|
||||
|
||||
container1.InsertNew("Variable1", 0).SetString("Hello World");
|
||||
container1.InsertNew("Variable2", 0).SetValue(42);
|
||||
|
||||
gd::VariablesContainer container3(container1);
|
||||
container2 = container1;
|
||||
|
||||
REQUIRE( container2.Has("Variable1") == true );
|
||||
REQUIRE( container2.Has("Variable2") == true );
|
||||
REQUIRE( container3.Has("Variable1") == true );
|
||||
REQUIRE( container3.Has("Variable2") == true );
|
||||
REQUIRE( container1.Get("Variable1").GetString() == "Hello World" );
|
||||
REQUIRE( container1.Get("Variable2").GetValue() == 42 );
|
||||
REQUIRE( container2.Get("Variable1").GetString() == "Hello World" );
|
||||
REQUIRE( container2.Get("Variable2").GetValue() == 42 );
|
||||
REQUIRE( container3.Get("Variable1").GetString() == "Hello World" );
|
||||
REQUIRE( container3.Get("Variable2").GetValue() == 42 );
|
||||
|
||||
container2.Get("Variable1").SetString("Hello copied World");
|
||||
container2.Get("Variable2").SetValue(43);
|
||||
container3.Get("Variable1").SetString("Hello second copied World");
|
||||
container3.Get("Variable2").SetValue(44);
|
||||
REQUIRE( container1.Get("Variable1").GetString() == "Hello World" );
|
||||
REQUIRE( container1.Get("Variable2").GetValue() == 42 );
|
||||
REQUIRE( container2.Get("Variable1").GetString() == "Hello copied World" );
|
||||
REQUIRE( container2.Get("Variable2").GetValue() == 43 );
|
||||
REQUIRE( container3.Get("Variable1").GetString() == "Hello second copied World" );
|
||||
REQUIRE( container3.Get("Variable2").GetValue() == 44 );
|
||||
}
|
||||
}
|
@@ -41,6 +41,7 @@ ADD_SUBDIRECTORY(PhysicsBehavior)
|
||||
ADD_SUBDIRECTORY(PlatformBehavior)
|
||||
ADD_SUBDIRECTORY(PrimitiveDrawing)
|
||||
ADD_SUBDIRECTORY(Shopify)
|
||||
ADD_SUBDIRECTORY(SkeletonObject)
|
||||
IF (NOT EMSCRIPTEN)
|
||||
ADD_SUBDIRECTORY(SoundObject)
|
||||
ENDIF()
|
||||
|
@@ -15,37 +15,162 @@ This project is released under the MIT License.
|
||||
#include "Extension.h"
|
||||
|
||||
|
||||
/**
|
||||
* Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
Extension::Extension()
|
||||
void DeclareParticleSystemExtension(gd::PlatformExtension & extension)
|
||||
{
|
||||
SetExtensionInformation("ParticleSystem",
|
||||
_("Particle system"),
|
||||
_("This Extension can display a large number of small particles."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)");
|
||||
extension.SetExtensionInformation("ParticleSystem",
|
||||
_("Particle system"),
|
||||
_("This Extension can display a large number of small particles."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)");
|
||||
|
||||
//Declaration of all objects available
|
||||
{
|
||||
gd::ObjectMetadata & obj = AddObject<ParticleEmitterObject>(
|
||||
"ParticleEmitter",
|
||||
_("Particles emitter"),
|
||||
_("Displays a large number of small particles to create visual effects."),
|
||||
"CppPlatform/Extensions/particleSystemicon.png");
|
||||
gd::ObjectMetadata & obj = extension.AddObject<ParticleEmitterObject>(
|
||||
"ParticleEmitter",
|
||||
_("Particles emitter"),
|
||||
_("Displays a large number of small particles to create visual effects."),
|
||||
"CppPlatform/Extensions/particleSystemicon.png");
|
||||
|
||||
AddRuntimeObject<ParticleEmitterObject, RuntimeParticleEmitterObject>(
|
||||
obj, "RuntimeParticleEmitterObject");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#if defined(GD_IDE_ONLY)
|
||||
obj.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
|
||||
//Declaration is too big to be compiled by GCC in one file, unless you have 4GB+ ram. :/
|
||||
ExtensionSubDeclaration1(obj);
|
||||
ExtensionSubDeclaration2(obj);
|
||||
ExtensionSubDeclaration3(obj);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
ParticleSystemCppExtension::ParticleSystemCppExtension()
|
||||
{
|
||||
DeclareParticleSystemExtension(*this);
|
||||
AddRuntimeObject<ParticleEmitterObject, RuntimeParticleEmitterObject>(
|
||||
GetObjectMetadata("ParticleSystem::ParticleEmitter"),
|
||||
"RuntimeParticleEmitterObject");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
auto & actions = GetAllActionsForObject("ParticleSystem::ParticleEmitter");
|
||||
auto & conditions = GetAllConditionsForObject("ParticleSystem::ParticleEmitter");
|
||||
auto & expressions = GetAllExpressionsForObject("ParticleSystem::ParticleEmitter");
|
||||
auto & strExpressions = GetAllStrExpressionsForObject("ParticleSystem::ParticleEmitter");
|
||||
|
||||
actions["ParticleSystem::EmitterForceMin"].SetFunctionName("SetEmitterForceMin").SetGetter("GetEmitterForceMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::EmitterForceMax"].SetFunctionName("SetEmitterForceMax").SetGetter("GetEmitterForceMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::EmitterXDirection"].SetFunctionName("SetEmitterXDirection").SetGetter("GetEmitterXDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::EmitterXDirection"].SetFunctionName("GetEmitterXDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::EmitterYDirection"].SetFunctionName("SetEmitterYDirection").SetGetter("GetEmitterYDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::EmitterYDirection"].SetFunctionName("GetEmitterYDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::EmitterZDirection"].SetFunctionName("SetEmitterZDirection").SetGetter("GetEmitterZDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::EmitterZDirection"].SetFunctionName("GetEmitterZDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::EmitterAngle"].SetFunctionName("SetAngle").SetGetter("GetAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::EmitterAngle"].SetFunctionName("GetAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::EmitterAngleA"].SetFunctionName("SetEmitterAngleA").SetGetter("GetEmitterAngleA").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::EmitterAngleA"].SetFunctionName("GetEmitterAngleA").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::EmitterAngleB"].SetFunctionName("SetEmitterAngleB").SetGetter("GetEmitterAngleB").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::EmitterAngleB"].SetFunctionName("GetEmitterAngleB").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ConeSprayAngle"].SetFunctionName("SetConeSprayAngle").SetGetter("GetConeSprayAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ConeSprayAngle"].SetFunctionName("GetConeSprayAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::Friction"].SetFunctionName("SetFriction").SetGetter("GetFriction").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::Friction"].SetFunctionName("GetFriction").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ZoneRadius"].SetFunctionName("SetZoneRadius").SetGetter("GetZoneRadius").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ZoneRadius"].SetFunctionName("GetZoneRadius").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleLifeTimeMin"].SetFunctionName("SetParticleLifeTimeMin").SetGetter("GetParticleLifeTimeMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleLifeTimeMin"].SetFunctionName("GetParticleLifeTimeMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleLifeTimeMax"].SetFunctionName("SetParticleLifeTimeMax").SetGetter("GetParticleLifeTimeMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleLifeTimeMax"].SetFunctionName("GetParticleLifeTimeMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleGravityX"].SetFunctionName("SetParticleGravityX").SetGetter("GetParticleGravityX").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleGravityX"].SetFunctionName("GetParticleGravityX").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleGravityY"].SetFunctionName("SetParticleGravityY").SetGetter("GetParticleGravityY").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleGravityY"].SetFunctionName("GetParticleGravityY").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleGravityZ"].SetFunctionName("SetParticleGravityZ").SetGetter("GetParticleGravityZ").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleGravityZ"].SetFunctionName("GetParticleGravityZ").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleGravityAngle"].SetFunctionName("SetParticleGravityAngle").SetGetter("GetParticleGravityAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleGravityAngle"].SetFunctionName("GetParticleGravityAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleGravityLength"].SetFunctionName("SetParticleGravityLength").SetGetter("GetParticleGravityLength").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleGravityLength"].SetFunctionName("GetParticleGravityLength").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
|
||||
actions["ParticleSystem::ParticleColor1"].SetFunctionName("SetParticleColor1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleColor2"].SetFunctionName("SetParticleColor2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleRed1"].SetFunctionName("SetParticleRed1").SetGetter("GetParticleRed1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleRed1"].SetFunctionName("GetParticleRed1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleRed2"].SetFunctionName("SetParticleRed2").SetGetter("GetParticleRed2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleRed2"].SetFunctionName("GetParticleRed2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleBlue1"].SetFunctionName("SetParticleBlue1").SetGetter("GetParticleBlue1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleBlue1"].SetFunctionName("GetParticleBlue1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleBlue2"].SetFunctionName("SetParticleBlue2").SetGetter("GetParticleBlue2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleBlue2"].SetFunctionName("GetParticleBlue2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleGreen1"].SetFunctionName("SetParticleGreen1").SetGetter("GetParticleGreen1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleGreen1"].SetFunctionName("GetParticleGreen1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleGreen2"].SetFunctionName("SetParticleGreen2").SetGetter("GetParticleGreen2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleGreen2"].SetFunctionName("GetParticleGreen2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleSize1"].SetFunctionName("SetParticleSize1").SetGetter("GetParticleSize1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleSize1"].SetFunctionName("GetParticleSize1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleSize2"].SetFunctionName("SetParticleSize2").SetGetter("GetParticleSize2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleSize2"].SetFunctionName("GetParticleSize2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleAngle1"].SetFunctionName("SetParticleAngle1").SetGetter("GetParticleAngle1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleAngle1"].SetFunctionName("GetParticleAngle1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleAngle2"].SetFunctionName("SetParticleAngle2").SetGetter("GetParticleAngle2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleAngle2"].SetFunctionName("GetParticleAngle2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleAlpha1"].SetFunctionName("SetParticleAlpha1").SetGetter("GetParticleAlpha1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleAlpha1"].SetFunctionName("GetParticleAlpha1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::ParticleAlpha2"].SetFunctionName("SetParticleAlpha2").SetGetter("GetParticleAlpha2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::ParticleAlpha2"].SetFunctionName("GetParticleAlpha2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::NoMoreParticles"].SetFunctionName("NoMoreParticles").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
|
||||
actions["ParticleSystem::RecreateParticleSystem"].SetFunctionName("RecreateParticleSystem").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::RendererParam1"].SetFunctionName("SetRendererParam1").SetGetter("GetRendererParam1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::RendererParam1"].SetFunctionName("GetRendererParam1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::RendererParam2"].SetFunctionName("SetRendererParam2").SetGetter("GetRendererParam2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::RendererParam2"].SetFunctionName("GetRendererParam2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::Tank"].SetFunctionName("SetTank").SetGetter("GetTank").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::Tank"].SetFunctionName("GetTank").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::Flow"].SetFunctionName("SetFlow").SetGetter("GetFlow").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::Flow"].SetFunctionName("GetFlow").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
actions["ParticleSystem::Texture"].SetFunctionName("SetTexture").SetGetter("GetTexture").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
conditions["ParticleSystem::Texture"].SetFunctionName("GetTexture").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
|
||||
strExpressions["Texture"].SetFunctionName("GetTexture").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["NbParticles"].SetFunctionName("GetNbParticles").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["RendererParam1"].SetFunctionName("GetRendererParam1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["RendererParam2"].SetFunctionName("GetRendererParam2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["Tank"].SetFunctionName("GetTank").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["Flow"].SetFunctionName("GetFlow").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterForceMin"].SetFunctionName("GetEmitterForceMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterForceMax"].SetFunctionName("GetEmitterForceMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterXDirection"].SetFunctionName("GetEmitterXDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterYDirection"].SetFunctionName("GetEmitterYDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterZDirection"].SetFunctionName("GetEmitterZDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterAngle"].SetFunctionName("GetAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterAngleA"].SetFunctionName("GetEmitterAngleA").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["EmitterAngleB"].SetFunctionName("GetEmitterAngleB").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ZoneRadius"].SetFunctionName("GetZoneRadius").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleGravityX"].SetFunctionName("GetParticleGravityX").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleGravityY"].SetFunctionName("GetParticleGravityY").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleGravityZ"].SetFunctionName("GetParticleGravityZ").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleGravityAngle"].SetFunctionName("GetParticleGravityAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleGravityLength"].SetFunctionName("GetParticleGravityLength").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["Friction"].SetFunctionName("GetFriction").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleLifeTimeMin"].SetFunctionName("GetParticleLifeTimeMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleLifeTimeMax"].SetFunctionName("GetParticleLifeTimeMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleRed1"].SetFunctionName("GetParticleRed1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleRed2"].SetFunctionName("GetParticleRed2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleBlue1"].SetFunctionName("GetParticleBlue1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleBlue2"].SetFunctionName("GetParticleBlue2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleGreen1"].SetFunctionName("GetParticleGreen1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleGreen2"].SetFunctionName("GetParticleGreen2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleAlpha1"].SetFunctionName("GetParticleAlpha1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleAlpha2"].SetFunctionName("GetParticleAlpha2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleSize1"].SetFunctionName("GetParticleSize1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleSize2"].SetFunctionName("GetParticleSize2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleAngle1"].SetFunctionName("GetParticleAngle1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
expressions["ParticleAngle2"].SetFunctionName("GetParticleAngle2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions();
|
||||
#endif
|
||||
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
};
|
||||
@@ -55,5 +180,5 @@ Extension::Extension()
|
||||
* -- Do not need to be modified. --
|
||||
*/
|
||||
extern "C" ExtensionBase * GD_EXTENSION_API CreateGDExtension() {
|
||||
return new Extension;
|
||||
return new ParticleSystemCppExtension;
|
||||
}
|
||||
|
@@ -8,20 +8,18 @@ This project is released under the MIT License.
|
||||
#ifndef EXTENSION_H_INCLUDED
|
||||
#define EXTENSION_H_INCLUDED
|
||||
namespace gd { class ObjectMetadata; }
|
||||
namespace gd { class PlatformExtension; }
|
||||
|
||||
void DeclareParticleSystemExtension(gd::PlatformExtension & extension);
|
||||
|
||||
/**
|
||||
* \brief This class declares information about the extension.
|
||||
*/
|
||||
class Extension : public ExtensionBase
|
||||
class ParticleSystemCppExtension : public ExtensionBase
|
||||
{
|
||||
public:
|
||||
Extension();
|
||||
virtual ~Extension() {};
|
||||
|
||||
private:
|
||||
void ExtensionSubDeclaration1(gd::ObjectMetadata & objInfos);
|
||||
void ExtensionSubDeclaration2(gd::ObjectMetadata & objInfos);
|
||||
void ExtensionSubDeclaration3(gd::ObjectMetadata & objInfos);
|
||||
ParticleSystemCppExtension();
|
||||
virtual ~ParticleSystemCppExtension() {};
|
||||
};
|
||||
|
||||
#endif // EXTENSION_H_INCLUDED
|
||||
|
@@ -9,12 +9,11 @@ This project is released under the MIT License.
|
||||
|
||||
#include "Extension.h"
|
||||
#include "ParticleEmitterObject.h"
|
||||
#include "ParticleEmitterObject.h"
|
||||
|
||||
/**
|
||||
* Declare some actions and conditions of the particle emitter
|
||||
*/
|
||||
void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
void ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
obj.AddAction("EmitterForceMin",
|
||||
@@ -27,8 +26,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetEmitterForceMin").SetManipulatedType("number").SetGetter("GetEmitterForceMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("EmitterForceMax",
|
||||
_("Emission maximal force"),
|
||||
@@ -40,8 +38,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetEmitterForceMax").SetManipulatedType("number").SetGetter("GetEmitterForceMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("EmitterXDirection",
|
||||
_("Emission X direction"),
|
||||
@@ -53,8 +50,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetEmitterXDirection").SetManipulatedType("number").SetGetter("GetEmitterXDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("EmitterXDirection",
|
||||
_("Emission X direction"),
|
||||
@@ -66,8 +62,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetEmitterXDirection").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("EmitterYDirection",
|
||||
@@ -80,8 +75,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetEmitterYDirection").SetManipulatedType("number").SetGetter("GetEmitterYDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("EmitterYDirection",
|
||||
_("Emission Y direction"),
|
||||
@@ -93,8 +87,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetEmitterYDirection").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("EmitterZDirection",
|
||||
@@ -107,8 +100,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetEmitterZDirection").SetManipulatedType("number").SetGetter("GetEmitterZDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("EmitterZDirection",
|
||||
@@ -121,8 +113,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetEmitterZDirection").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("EmitterAngle",
|
||||
@@ -135,7 +126,6 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetAngle").SetManipulatedType("number").SetGetter("GetAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
|
||||
|
||||
@@ -149,8 +139,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetAngle").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("EmitterAngleA",
|
||||
_("Emission angle 1"),
|
||||
@@ -162,8 +151,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetEmitterAngleA").SetManipulatedType("number").SetGetter("GetEmitterAngleA").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("EmitterAngleA",
|
||||
@@ -176,8 +164,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetEmitterAngleA").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("EmitterAngleB",
|
||||
@@ -190,8 +177,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetEmitterAngleB").SetManipulatedType("number").SetGetter("GetEmitterAngleB").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("EmitterAngleB",
|
||||
@@ -204,8 +190,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetEmitterAngleB").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ConeSprayAngle",
|
||||
@@ -218,8 +203,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetConeSprayAngle").SetManipulatedType("number").SetGetter("GetConeSprayAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ConeSprayAngle",
|
||||
_("Angle of the spray cone"),
|
||||
@@ -231,8 +215,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetConeSprayAngle").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("Friction",
|
||||
_("Friction"),
|
||||
@@ -244,8 +227,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetFriction").SetManipulatedType("number").SetGetter("GetFriction").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number").SetGetter("GetFriction");
|
||||
|
||||
|
||||
obj.AddCondition("Friction",
|
||||
@@ -259,8 +241,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetFriction").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ZoneRadius",
|
||||
@@ -273,8 +254,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetZoneRadius").SetManipulatedType("number").SetGetter("GetZoneRadius").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("ZoneRadius",
|
||||
@@ -287,8 +267,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetZoneRadius").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ParticleLifeTimeMin",
|
||||
@@ -301,8 +280,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleLifeTimeMin").SetManipulatedType("number").SetGetter("GetParticleLifeTimeMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleLifeTimeMin",
|
||||
_("Minimum lifetime"),
|
||||
@@ -314,8 +292,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleLifeTimeMin").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleLifeTimeMax",
|
||||
_("Maximum lifetime"),
|
||||
@@ -327,8 +304,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleLifeTimeMax").SetManipulatedType("number").SetGetter("GetParticleLifeTimeMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("ParticleLifeTimeMax",
|
||||
@@ -341,8 +317,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleLifeTimeMax").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ParticleGravityX",
|
||||
@@ -355,8 +330,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleGravityX").SetManipulatedType("number").SetGetter("GetParticleGravityX").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("ParticleGravityX",
|
||||
@@ -369,8 +343,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleGravityX").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ParticleGravityY",
|
||||
@@ -383,8 +356,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleGravityY").SetManipulatedType("number").SetGetter("GetParticleGravityY").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("ParticleGravityY",
|
||||
@@ -397,8 +369,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleGravityY").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ParticleGravityZ",
|
||||
@@ -411,8 +382,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleGravityZ").SetManipulatedType("number").SetGetter("GetParticleGravityZ").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("ParticleGravityZ",
|
||||
@@ -425,8 +395,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleGravityZ").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleGravityAngle",
|
||||
_("Gravity angle"),
|
||||
@@ -438,8 +407,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleGravityAngle").SetManipulatedType("number").SetGetter("GetParticleGravityAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleGravityAngle",
|
||||
_("Gravity angle"),
|
||||
@@ -451,8 +419,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleGravityAngle").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleGravityLength",
|
||||
_("Gravity"),
|
||||
@@ -464,8 +431,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleGravityLength").SetManipulatedType("number").SetGetter("GetParticleGravityLength").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleGravityLength",
|
||||
_("Gravity"),
|
||||
@@ -477,8 +443,7 @@ void Extension::ExtensionSubDeclaration1(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleGravityLength").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#ifndef EXTENSIONSUBDECLARATION1_H
|
||||
#define EXTENSIONSUBDECLARATION1_H
|
||||
|
||||
class ExtensionObjectInfos;
|
||||
void ExtensionSubDeclaration1(ExtensionObjectInfos & objInfos);
|
||||
namespace gd { class ObjectMetadata; }
|
||||
void ExtensionSubDeclaration1(gd::ObjectMetadata & objInfos);
|
||||
|
||||
#endif // EXTENSIONSUBDECLARATION1_H
|
||||
|
||||
|
@@ -13,7 +13,7 @@ This project is released under the MIT License.
|
||||
/**
|
||||
* Declare some actions and conditions of the particle emitter
|
||||
*/
|
||||
void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
void ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
obj.AddAction("ParticleColor1",
|
||||
@@ -24,9 +24,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("color", _("Initial color"))
|
||||
|
||||
.SetFunctionName("SetParticleColor1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("color", _("Initial color"));
|
||||
|
||||
obj.AddAction("ParticleColor2",
|
||||
_("Final color"),
|
||||
@@ -36,9 +34,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("color", _("Final color"))
|
||||
|
||||
.SetFunctionName("SetParticleColor2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("color", _("Final color"));
|
||||
|
||||
obj.AddAction("ParticleRed1",
|
||||
_("Red color, parameter 1"),
|
||||
@@ -50,8 +46,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleRed1").SetManipulatedType("number").SetGetter("GetParticleRed1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleRed1",
|
||||
_("Red color, parameter 1"),
|
||||
@@ -63,8 +58,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleRed1").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleRed2",
|
||||
_("Red color, parameter 2"),
|
||||
@@ -76,8 +70,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleRed2").SetManipulatedType("number").SetGetter("GetParticleRed2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleRed2",
|
||||
_("Red color, parameter 2"),
|
||||
@@ -89,8 +82,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleRed2").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleBlue1",
|
||||
_("Blue color, parameter 1"),
|
||||
@@ -102,8 +94,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleBlue1").SetManipulatedType("number").SetGetter("GetParticleBlue1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleBlue1",
|
||||
_("Blue color, parameter 1"),
|
||||
@@ -115,8 +106,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleBlue1").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleBlue2",
|
||||
_("Blue color, parameter 2"),
|
||||
@@ -128,8 +118,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleBlue2").SetManipulatedType("number").SetGetter("GetParticleBlue2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleBlue2",
|
||||
_("Blue color, parameter 2"),
|
||||
@@ -141,8 +130,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleBlue2").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleGreen1",
|
||||
_("Green color, parameter 1"),
|
||||
@@ -154,8 +142,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleGreen1").SetManipulatedType("number").SetGetter("GetParticleGreen1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleGreen1",
|
||||
_("Green color, parameter 1"),
|
||||
@@ -167,8 +154,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleGreen1").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ParticleGreen2",
|
||||
@@ -181,8 +167,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleGreen2").SetManipulatedType("number").SetGetter("GetParticleGreen2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleGreen2",
|
||||
_("Green color, parameter 2"),
|
||||
@@ -194,8 +179,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleGreen2").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("ParticleSize1",
|
||||
@@ -208,8 +192,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleSize1").SetManipulatedType("number").SetGetter("GetParticleSize1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleSize1",
|
||||
_("SIze, parameter 1"),
|
||||
@@ -221,8 +204,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleSize1").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleSize2",
|
||||
_("Size, parameter 2"),
|
||||
@@ -234,8 +216,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleSize2").SetManipulatedType("number").SetGetter("GetParticleSize2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleSize2",
|
||||
_("Size, parameter 2"),
|
||||
@@ -247,8 +228,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleSize2").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleAngle1",
|
||||
_("Angle, parameter 1"),
|
||||
@@ -260,8 +240,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleAngle1").SetManipulatedType("number").SetGetter("GetParticleAngle1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleAngle1",
|
||||
_("Angle, parameter 1"),
|
||||
@@ -273,8 +252,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleAngle1").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleAngle2",
|
||||
_("Angle, parameter 2"),
|
||||
@@ -286,8 +264,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleAngle2").SetManipulatedType("number").SetGetter("GetParticleAngle2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleAngle2",
|
||||
_("Angle, parameter 2"),
|
||||
@@ -299,8 +276,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleAngle2").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleAlpha1",
|
||||
_("Transparency, parameter 1"),
|
||||
@@ -312,8 +288,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleAlpha1").SetManipulatedType("number").SetGetter("GetParticleAlpha1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ParticleAlpha1",
|
||||
_("Transparency, parameter 1"),
|
||||
@@ -325,8 +300,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleAlpha1").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ParticleAlpha2",
|
||||
_("Transparency, parameter 2"),
|
||||
@@ -338,8 +312,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetParticleAlpha2").SetManipulatedType("number").SetGetter("GetParticleAlpha2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("ParticleAlpha2",
|
||||
@@ -352,8 +325,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetParticleAlpha2").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("NoMoreParticles",
|
||||
@@ -363,9 +335,7 @@ void Extension::ExtensionSubDeclaration2(gd::ObjectMetadata & obj)
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
|
||||
.SetFunctionName("NoMoreParticles").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#ifndef EXTENSIONSUBDECLARATION1_H
|
||||
#define EXTENSIONSUBDECLARATION1_H
|
||||
#ifndef EXTENSIONSUBDECLARATION2_H
|
||||
#define EXTENSIONSUBDECLARATION2_H
|
||||
|
||||
class ExtensionObjectInfos;
|
||||
void ExtensionSubDeclaration2(ExtensionObjectInfos & objInfos);
|
||||
namespace gd { class ObjectMetadata; }
|
||||
void ExtensionSubDeclaration2(gd::ObjectMetadata & objInfos);
|
||||
|
||||
#endif // EXTENSIONSUBDECLARATION1_H
|
||||
#endif // EXTENSIONSUBDECLARATION2_H
|
||||
|
||||
|
||||
|
||||
|
@@ -13,7 +13,7 @@ This project is released under the MIT License.
|
||||
/**
|
||||
* Declare some actions, conditions and expressions of the particle emitter
|
||||
*/
|
||||
void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
void ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
obj.AddAction("RecreateParticleSystem",
|
||||
@@ -23,9 +23,7 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
|
||||
.SetFunctionName("RecreateParticleSystem").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter");
|
||||
|
||||
obj.AddAction("RendererParam1",
|
||||
_("Rendering first parameter"),
|
||||
@@ -37,11 +35,10 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetRendererParam1").SetManipulatedType("number").SetGetter("GetRendererParam1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("RendererParam1",
|
||||
_("Direction of gravity on Z axis"),
|
||||
_("Rendering first parameter"),
|
||||
_("Test the first parameter of rendering ( Size/Length )."),
|
||||
_("The 1nd rendering parameter of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Setup"),
|
||||
@@ -51,8 +48,7 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetRendererParam1").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("RendererParam2",
|
||||
_("Rendering second parameter"),
|
||||
@@ -64,8 +60,7 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetRendererParam2").SetManipulatedType("number").SetGetter("GetRendererParam2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("RendererParam2",
|
||||
_("Rendering second parameter"),
|
||||
@@ -77,8 +72,7 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetRendererParam2").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("Tank",
|
||||
@@ -91,8 +85,7 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetTank").SetManipulatedType("number").SetGetter("GetTank").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("Tank",
|
||||
_("Capacity"),
|
||||
@@ -104,22 +97,20 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetTank").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("Flow",
|
||||
_("Flow"),
|
||||
_("Change the flow of the emitter."),
|
||||
_("Do _PARAM1__PARAM2_ to flow of _PARAM0_"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
_("Flow"),
|
||||
_("Change the flow of the emitter."),
|
||||
_("Do _PARAM1__PARAM2_ to flow of _PARAM0_"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
|
||||
.SetFunctionName("SetFlow").SetManipulatedType("number").SetGetter("GetFlow").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddCondition("Flow",
|
||||
@@ -132,21 +123,18 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
|
||||
.SetFunctionName("GetFlow").SetManipulatedType("number").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("number");
|
||||
|
||||
|
||||
obj.AddAction("Texture",
|
||||
_("Image"),
|
||||
_("Change the image of particles ( if displayed )."),
|
||||
_("Change the image of particles of _PARAM0_ to _PARAM1_"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
_("Image"),
|
||||
_("Change the image of particles ( if displayed )."),
|
||||
_("Change the image of particles of _PARAM0_ to _PARAM1_"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("string", _("New image"))
|
||||
|
||||
.SetFunctionName("SetTexture").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("string", _("New image"));
|
||||
|
||||
obj.AddCondition("Texture",
|
||||
_("Image"),
|
||||
@@ -158,123 +146,87 @@ void Extension::ExtensionSubDeclaration3(gd::ObjectMetadata & obj)
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("string", _("Text to test"))
|
||||
|
||||
.SetFunctionName("GetTexture").SetManipulatedType("string").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.SetManipulatedType("string");
|
||||
|
||||
|
||||
obj.AddStrExpression("Texture", _("Particles image"), _("Name of the image displayed by particles"), _("Particles"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetTexture").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("NbParticles", _("Particles number"), _("Particles number"), _("Particles"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetNbParticles").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("RendererParam1", _("Rendering first parameter"), _("Rendering first parameter"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetRendererParam1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("RendererParam2", _("Rendering second parameter"), _("Rendering second parameter"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetRendererParam2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("Tank", _("Capacity"), _("Capacity"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetTank").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("Flow", _("Flow"), _("Flow"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetFlow").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("EmitterForceMin", _("Emission minimal force"), _("Emission minimal force"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetEmitterForceMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("EmitterForceMax", _("Emission maximal force"), _("Emission maximal force"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetEmitterForceMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("EmitterXDirection", _("Emission X direction"), _("Emission X direction"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetEmitterXDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("EmitterYDirection", _("Emission Y direction"), _("Emission Y direction"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetEmitterYDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("EmitterZDirection", _("Emission Z direction"), _("Emission Z direction"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetEmitterZDirection").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("EmitterAngle", _("Emission angle"), _("Emission angle"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("EmitterAngleA", _("Emission angle A"), _("Emission angle A"), _("Advanced"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetEmitterAngleA").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("EmitterAngleB", _("Emission angle B"), _("Emission angle B"), _("Advanced"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetEmitterAngleB").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ZoneRadius", _("Radius of the emission zone"), _("Radius of the emission zone"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetZoneRadius").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityX", _("X Gravity of particles"), _("X Gravity of particles"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleGravityX").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityY", _("Y Gravity of particles"), _("Y Gravity of particles"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleGravityY").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityZ", _("Z Gravity of particles"), _("Z Gravity of particles"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleGravityZ").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityAngle", _("Gravity angle"), _("Gravity angle"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleGravityAngle").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityLength", _("Gravity"), _("Gravity value"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleGravityLength").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("Friction", _("Particles friction"), _("Particles friction"), _("Common"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetFriction").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleLifeTimeMin", _("Minimum lifetime of particles"), _("Minimum lifetime of particles"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleLifeTimeMin").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleLifeTimeMax", _("Maximum lifetime of particles"), _("Maximum lifetime of particles"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleLifeTimeMax").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleRed1", _("Parameter 1 of red color"), _("Parameter 1 of red color"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleRed1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleRed2", _("Parameter 2 of red color"), _("Parameter 2 of red color"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleRed2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleBlue1", _("Parameter 1 of blue color"), _("Parameter 1 of blue color"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleBlue1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleBlue2", _("Parameter 2 of blue color"), _("Parameter 2 of blue color"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleBlue2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGreen1", _("Parameter 1 of green color"), _("Parameter 1 of green color"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleGreen1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGreen2", _("Parameter 2 of green color"), _("Parameter 2 of green color"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleGreen2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleAlpha1", _("Parameter 1 of transparency"), _("Parameter 1 of transparency"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleAlpha1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleAlpha2", _("Parameter 2 of transparency"), _("Parameter 2 of transparency"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleAlpha2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleSize1", _("Parameter 1 of size"), _("Parameter 1 of size"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleSize1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleSize2", _("Parameter 2 of size"), _("Parameter 2 of size"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleSize2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleAngle1", _("Parameter 1 of angle"), _("Parameter 1 of angle"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleAngle1").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleAngle2", _("Parameter 2 of angle"), _("Parameter 2 of angle"), _("Setup"), "CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false)
|
||||
.SetFunctionName("GetParticleAngle2").SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#ifndef EXTENSIONSUBDECLARATION1_H
|
||||
#define EXTENSIONSUBDECLARATION1_H
|
||||
#ifndef EXTENSIONSUBDECLARATION3_H
|
||||
#define EXTENSIONSUBDECLARATION3_H
|
||||
|
||||
class ExtensionObjectInfos;
|
||||
void ExtensionSubDeclaration3(ExtensionObjectInfos & objInfos);
|
||||
namespace gd { class ObjectMetadata; }
|
||||
void ExtensionSubDeclaration3(gd::ObjectMetadata & objInfos);
|
||||
|
||||
#endif // EXTENSIONSUBDECLARATION1_H
|
||||
#endif // EXTENSIONSUBDECLARATION3_H
|
||||
|
||||
|
||||
|
||||
|
138
Extensions/ParticleSystem/JsExtension.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
|
||||
GDevelop - Particle System Extension
|
||||
Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "ParticleEmitterObject.h"
|
||||
|
||||
void DeclareParticleSystemExtension(gd::PlatformExtension & extension);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
class ParticleSystemJsExtension : public gd::PlatformExtension
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
ParticleSystemJsExtension()
|
||||
{
|
||||
DeclareParticleSystemExtension(*this);
|
||||
|
||||
GetObjectMetadata("ParticleSystem::ParticleEmitter")
|
||||
.SetIncludeFile("Extensions/ParticleSystem/particleemitterobject.js")
|
||||
.AddIncludeFile("Extensions/ParticleSystem/particleemitterobject-pixi-renderer.js")
|
||||
.AddIncludeFile("Extensions/ParticleSystem/pixi-particles-pixi-renderer.min.js")
|
||||
.AddIncludeFile("Extensions/ParticleSystem/particleemitterobject-cocos-renderer.js");
|
||||
|
||||
auto & actions = GetAllActionsForObject("ParticleSystem::ParticleEmitter");
|
||||
auto & conditions = GetAllConditionsForObject("ParticleSystem::ParticleEmitter");
|
||||
auto & expressions = GetAllExpressionsForObject("ParticleSystem::ParticleEmitter");
|
||||
auto & strExpressions = GetAllStrExpressionsForObject("ParticleSystem::ParticleEmitter");
|
||||
|
||||
actions["ParticleSystem::EmitterForceMin"].SetFunctionName("setEmitterForceMin").SetGetter("getEmitterForceMin");
|
||||
actions["ParticleSystem::EmitterForceMax"].SetFunctionName("setEmitterForceMax").SetGetter("getEmitterForceMax");
|
||||
actions["ParticleSystem::EmitterAngle"].SetFunctionName("setAngle").SetGetter("getAngle");
|
||||
conditions["ParticleSystem::EmitterAngle"].SetFunctionName("getAngle");
|
||||
actions["ParticleSystem::EmitterAngleA"].SetFunctionName("setEmitterAngleA").SetGetter("getEmitterAngleA");
|
||||
conditions["ParticleSystem::EmitterAngleA"].SetFunctionName("getEmitterAngleA");
|
||||
actions["ParticleSystem::EmitterAngleB"].SetFunctionName("setEmitterAngleB").SetGetter("getEmitterAngleB");
|
||||
conditions["ParticleSystem::EmitterAngleB"].SetFunctionName("getEmitterAngleB");
|
||||
actions["ParticleSystem::ConeSprayAngle"].SetFunctionName("setConeSprayAngle").SetGetter("getConeSprayAngle");
|
||||
conditions["ParticleSystem::ConeSprayAngle"].SetFunctionName("getConeSprayAngle");
|
||||
actions["ParticleSystem::ZoneRadius"].SetFunctionName("setZoneRadius").SetGetter("getZoneRadius");
|
||||
conditions["ParticleSystem::ZoneRadius"].SetFunctionName("getZoneRadius");
|
||||
actions["ParticleSystem::ParticleLifeTimeMin"].SetFunctionName("setParticleLifeTimeMin").SetGetter("getParticleLifeTimeMin");
|
||||
conditions["ParticleSystem::ParticleLifeTimeMin"].SetFunctionName("getParticleLifeTimeMin");
|
||||
actions["ParticleSystem::ParticleLifeTimeMax"].SetFunctionName("setParticleLifeTimeMax").SetGetter("getParticleLifeTimeMax");
|
||||
conditions["ParticleSystem::ParticleLifeTimeMax"].SetFunctionName("getParticleLifeTimeMax");
|
||||
actions["ParticleSystem::ParticleGravityX"].SetFunctionName("setParticleGravityX").SetGetter("getParticleGravityX");
|
||||
conditions["ParticleSystem::ParticleGravityX"].SetFunctionName("getParticleGravityX");
|
||||
actions["ParticleSystem::ParticleGravityY"].SetFunctionName("setParticleGravityY").SetGetter("getParticleGravityY");
|
||||
conditions["ParticleSystem::ParticleGravityY"].SetFunctionName("getParticleGravityY");
|
||||
actions["ParticleSystem::ParticleGravityAngle"].SetFunctionName("setParticleGravityAngle").SetGetter("getParticleGravityAngle");
|
||||
conditions["ParticleSystem::ParticleGravityAngle"].SetFunctionName("getParticleGravityAngle");
|
||||
actions["ParticleSystem::ParticleGravityLength"].SetFunctionName("setParticleGravityLength").SetGetter("getParticleGravityLength");
|
||||
conditions["ParticleSystem::ParticleGravityLength"].SetFunctionName("getParticleGravityLength");
|
||||
|
||||
actions["ParticleSystem::ParticleColor1"].SetFunctionName("setParticleColor1");
|
||||
actions["ParticleSystem::ParticleColor2"].SetFunctionName("setParticleColor2");
|
||||
actions["ParticleSystem::ParticleRed1"].SetFunctionName("setParticleRed1").SetGetter("getParticleRed1");
|
||||
conditions["ParticleSystem::ParticleRed1"].SetFunctionName("getParticleRed1");
|
||||
actions["ParticleSystem::ParticleRed2"].SetFunctionName("setParticleRed2").SetGetter("getParticleRed2");
|
||||
conditions["ParticleSystem::ParticleRed2"].SetFunctionName("getParticleRed2");
|
||||
actions["ParticleSystem::ParticleBlue1"].SetFunctionName("setParticleBlue1").SetGetter("getParticleBlue1");
|
||||
conditions["ParticleSystem::ParticleBlue1"].SetFunctionName("getParticleBlue1");
|
||||
actions["ParticleSystem::ParticleBlue2"].SetFunctionName("setParticleBlue2").SetGetter("getParticleBlue2");
|
||||
conditions["ParticleSystem::ParticleBlue2"].SetFunctionName("getParticleBlue2");
|
||||
actions["ParticleSystem::ParticleGreen1"].SetFunctionName("setParticleGreen1").SetGetter("getParticleGreen1");
|
||||
conditions["ParticleSystem::ParticleGreen1"].SetFunctionName("getParticleGreen1");
|
||||
actions["ParticleSystem::ParticleGreen2"].SetFunctionName("setParticleGreen2").SetGetter("getParticleGreen2");
|
||||
conditions["ParticleSystem::ParticleGreen2"].SetFunctionName("getParticleGreen2");
|
||||
actions["ParticleSystem::ParticleSize1"].SetFunctionName("setParticleSize1").SetGetter("getParticleSize1");
|
||||
conditions["ParticleSystem::ParticleSize1"].SetFunctionName("getParticleSize1");
|
||||
actions["ParticleSystem::ParticleSize2"].SetFunctionName("setParticleSize2").SetGetter("getParticleSize2");
|
||||
conditions["ParticleSystem::ParticleSize2"].SetFunctionName("getParticleSize2");
|
||||
actions["ParticleSystem::ParticleAlpha1"].SetFunctionName("setParticleAlpha1").SetGetter("getParticleAlpha1");
|
||||
conditions["ParticleSystem::ParticleAlpha1"].SetFunctionName("getParticleAlpha1");
|
||||
actions["ParticleSystem::ParticleAlpha2"].SetFunctionName("setParticleAlpha2").SetGetter("getParticleAlpha2");
|
||||
conditions["ParticleSystem::ParticleAlpha2"].SetFunctionName("getParticleAlpha2");
|
||||
conditions["ParticleSystem::NoMoreParticles"].SetFunctionName("noMoreParticles");
|
||||
|
||||
actions["ParticleSystem::RecreateParticleSystem"].SetFunctionName("recreateParticleSystem");
|
||||
actions["ParticleSystem::Tank"].SetFunctionName("setTank").SetGetter("getTank");
|
||||
conditions["ParticleSystem::Tank"].SetFunctionName("getTank");
|
||||
actions["ParticleSystem::Flow"].SetFunctionName("setFlow").SetGetter("getFlow");
|
||||
conditions["ParticleSystem::Flow"].SetFunctionName("getFlow");
|
||||
actions["ParticleSystem::Texture"].AddCodeOnlyParameter("currentScene", "").SetFunctionName("setTexture").SetGetter("getTexture");
|
||||
conditions["ParticleSystem::Texture"].SetFunctionName("getTexture");
|
||||
|
||||
strExpressions["Texture"].SetFunctionName("getTexture");
|
||||
expressions["NbParticles"].SetFunctionName("getNbParticles");
|
||||
expressions["RendererParam1"].SetFunctionName("getRendererParam1");
|
||||
expressions["RendererParam2"].SetFunctionName("getRendererParam2");
|
||||
expressions["Tank"].SetFunctionName("getTank");
|
||||
expressions["Flow"].SetFunctionName("getFlow");
|
||||
expressions["EmitterForceMin"].SetFunctionName("getEmitterForceMin");
|
||||
expressions["EmitterForceMax"].SetFunctionName("getEmitterForceMax");
|
||||
expressions["EmitterAngle"].SetFunctionName("getAngle");
|
||||
expressions["EmitterAngleA"].SetFunctionName("getEmitterAngleA");
|
||||
expressions["EmitterAngleB"].SetFunctionName("getEmitterAngleB");
|
||||
expressions["ZoneRadius"].SetFunctionName("getZoneRadius");
|
||||
expressions["ParticleGravityX"].SetFunctionName("getParticleGravityX");
|
||||
expressions["ParticleGravityY"].SetFunctionName("getParticleGravityY");
|
||||
expressions["ParticleGravityAngle"].SetFunctionName("getParticleGravityAngle");
|
||||
expressions["ParticleGravityLength"].SetFunctionName("getParticleGravityLength");
|
||||
expressions["ParticleLifeTimeMin"].SetFunctionName("getParticleLifeTimeMin");
|
||||
expressions["ParticleLifeTimeMax"].SetFunctionName("getParticleLifeTimeMax");
|
||||
expressions["ParticleRed1"].SetFunctionName("getParticleRed1");
|
||||
expressions["ParticleRed2"].SetFunctionName("getParticleRed2");
|
||||
expressions["ParticleBlue1"].SetFunctionName("getParticleBlue1");
|
||||
expressions["ParticleBlue2"].SetFunctionName("getParticleBlue2");
|
||||
expressions["ParticleGreen1"].SetFunctionName("getParticleGreen1");
|
||||
expressions["ParticleGreen2"].SetFunctionName("getParticleGreen2");
|
||||
expressions["ParticleAlpha1"].SetFunctionName("getParticleAlpha1");
|
||||
expressions["ParticleAlpha2"].SetFunctionName("getParticleAlpha2");
|
||||
expressions["ParticleSize1"].SetFunctionName("getParticleSize1");
|
||||
expressions["ParticleSize2"].SetFunctionName("getParticleSize2");
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions();
|
||||
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Used by GDevelop to create the extension class
|
||||
* -- Do not need to be modified. --
|
||||
*/
|
||||
extern "C" gd::PlatformExtension * GD_EXTENSION_API CreateGDJSExtension() {
|
||||
return new ParticleSystemJsExtension;
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,301 @@
|
||||
/**
|
||||
|
||||
GDevelop - Particle System Extension
|
||||
Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer = function(runtimeScene, runtimeObject, objectData){
|
||||
var drawer = new cc.DrawNode();
|
||||
var renderTexture = null;
|
||||
this.originalSize = Math.max(objectData.rendererParam1, objectData.rendererParam2);
|
||||
if(objectData.rendererType === "Point"){
|
||||
drawer.drawDot(cc.p(objectData.rendererParam1, objectData.rendererParam1),
|
||||
objectData.rendererParam1, cc.color(255,255,255,255));
|
||||
this.originalSize = 2 * objectData.rendererParam1;
|
||||
renderTexture = new cc.RenderTexture(this.originalSize, this.originalSize);
|
||||
}
|
||||
else if(objectData.rendererType === "Line"){
|
||||
this.originalSize = Math.max(2*objectData.rendererParam1, objectData.rendererParam2);
|
||||
drawer.drawRect(cc.p(this.originalSize/2.0,
|
||||
(this.originalSize - objectData.rendererParam2)/2.0),
|
||||
cc.p(this.originalSize/2.0 + objectData.rendererParam1,
|
||||
(this.originalSize + objectData.rendererParam2)/2.0),
|
||||
cc.color(255,255,255,255), 0.01 , cc.color(255,255,255,0));
|
||||
renderTexture = new cc.RenderTexture(this.originalSize, this.originalSize);
|
||||
}
|
||||
else{
|
||||
if(objectData.textureParticleName){
|
||||
var imageManager = runtimeScene.getGame().getImageManager();
|
||||
var sprite = new cc.Sprite(imageManager.getTexture(objectData.textureParticleName));
|
||||
this.originalSize = Math.max(sprite.width, sprite.height);
|
||||
sprite.setPosition( this.originalSize/2.0, this.originalSize/2.0);
|
||||
drawer.addChild(sprite);
|
||||
renderTexture = new cc.RenderTexture( this.originalSize, this.originalSize);
|
||||
}
|
||||
else{
|
||||
drawer.drawRect(cc.p((this.originalSize - objectData.rendererParam1)/2.0,
|
||||
(this.originalSize - objectData.rendererParam2)/2.0),
|
||||
cc.p((this.originalSize + objectData.rendererParam1)/2.0,
|
||||
(this.originalSize + objectData.rendererParam2)/2.0),
|
||||
cc.color(255,255,255,255), 0.01 , cc.color(255,255,255,255));
|
||||
renderTexture = new cc.RenderTexture(this.originalSize, this.originalSize);
|
||||
}
|
||||
}
|
||||
renderTexture.begin();
|
||||
drawer.visit();
|
||||
renderTexture.end();
|
||||
var texture = renderTexture.getSprite().getTexture();
|
||||
|
||||
var plist = {
|
||||
duration: -1,
|
||||
emitterType: 0,
|
||||
|
||||
gravityx: objectData.particleGravityX,
|
||||
gravityy:-objectData.particleGravityY,
|
||||
|
||||
particleLifespan: (objectData.particleLifeTimeMin + objectData.particleLifeTimeMax)/2.0,
|
||||
particleLifespanVariance: Math.abs(objectData.particleLifeTimeMax - objectData.particleLifeTimeMin)/2.0,
|
||||
|
||||
sourcePositionVariancex: objectData.zoneRadius,
|
||||
sourcePositionVariancey: objectData.zoneRadius,
|
||||
|
||||
speed: (objectData.emitterForceMin + objectData.emitterForceMax)/2.0,
|
||||
speedVariance: Math.abs(objectData.emitterForceMax - objectData.emitterForceMin)/2.0,
|
||||
|
||||
tangentialAccelVariance: 0.0,
|
||||
tangentialAcceleration: 1,
|
||||
|
||||
rotationIsDir: "true",
|
||||
|
||||
// We are forced to use a texture name / base64 string, it's a one-pixel base64 image
|
||||
textureImageData: "H4sIAAAAAAAAA+sM8HPn5ZLiYmBg4PX0cAkC0owgzMEEJCeUB98DUpwFHpHFDAzcwiDMyDBrjgRQkL3E09eV/RELu4CFwaX8heVAIdnMkIgS5/zc3NS8EgYQcC5KTSxJTVEozyzJUHD39A1I0UtlB4rzeLo4hnBcT/7x/789A+s/pn93zkQ+B2nwdPVzWeeU0AQAwMwOBZYAAAA="
|
||||
};
|
||||
|
||||
if(objectData.emissionEditionSimpleMode){
|
||||
plist.angle = 0;
|
||||
plist.angleVariance = objectData.emitterAngleB/2.0;
|
||||
}
|
||||
else{
|
||||
plist.angle = -(objectData.emitterAngleA + objectData.emitterAngleB)/2.0;
|
||||
plist.angleVariance = Math.abs(plist.angle + objectData.emitterAngleB);
|
||||
}
|
||||
|
||||
if(objectData.redParam === "Mutable"){
|
||||
plist.startColorVarianceRed = plist.finishColorVarianceRed = 0.0;
|
||||
plist.startColorRed = objectData.particleRed1/255.0;
|
||||
plist.finishColorRed = objectData.particleRed2/255.0;
|
||||
}
|
||||
else if(objectData.redParam === "Random"){
|
||||
plist.startColorRed = plist.finishColorRed = (objectData.particleRed1 + objectData.particleRed2)/(2.0*255.0);
|
||||
plist.startColorVarianceRed = Math.abs(plist.startColorRed - objectData.particleRed2/255.0);
|
||||
plist.finishColorVarianceRed = plist.startColorVarianceRed;
|
||||
}
|
||||
else{
|
||||
plist.startColorVarianceRed = plist.finishColorVarianceRed = 0.0;
|
||||
plist.startColorRed = objectData.particleRed1/255.0;
|
||||
plist.finishColorRed = plist.startColorRed;
|
||||
}
|
||||
|
||||
if(objectData.greenParam === "Mutable"){
|
||||
plist.startColorVarianceGreen = plist.finishColorVarianceGreen = 0.0;
|
||||
plist.startColorGreen = objectData.particleGreen1/255.0;
|
||||
plist.finishColorGreen = objectData.particleGreen2/255.0;
|
||||
}
|
||||
else if(objectData.greenParam === "Random"){
|
||||
plist.startColorGreen = plist.finishColorGreen = (objectData.particleGreen1 + objectData.particleGreen2)/(2.0*255.0);
|
||||
plist.startColorVarianceGreen = Math.abs(plist.startColorGreen - objectData.particleGreen2/255.0);
|
||||
plist.finishColorVarianceGreen = plist.startColorVarianceGreen;
|
||||
}
|
||||
else{
|
||||
plist.startColorVarianceGreen = plist.finishColorVarianceGreen = 0.0;
|
||||
plist.startColorGreen = objectData.particleGreen1/255.0;
|
||||
plist.finishColorGreen = plist.startColorGreen;
|
||||
}
|
||||
|
||||
if(objectData.blueParam === "Mutable"){
|
||||
plist.startColorVarianceBlue = plist.finishColorVarianceBlue = 0.0;
|
||||
plist.startColorBlue = objectData.particleBlue1/255.0;
|
||||
plist.finishColorBlue = objectData.particleBlue2/255.0;
|
||||
}
|
||||
else if(objectData.blueParam === "Random"){
|
||||
plist.startColorBlue = plist.finishColorBlue = (objectData.particleBlue1 + objectData.particleBlue2)/(2.0*255.0);
|
||||
plist.startColorVarianceBlue = Math.abs(plist.startColorBlue - objectData.particleBlue2/255.0);
|
||||
plist.finishColorVarianceBlue = plist.startColorVarianceBlue;
|
||||
}
|
||||
else{
|
||||
plist.startColorVarianceBlue = plist.finishColorVarianceBlue = 0.0;
|
||||
plist.startColorBlue = objectData.particleBlue1/255.0;
|
||||
plist.finishColorBlue = plist.startColorBlue;
|
||||
}
|
||||
|
||||
if(objectData.alphaParam === "Mutable"){
|
||||
var alphaInit = (objectData.particleAlpha1 + objectData.particleAlphaRandomness1)/255.0;
|
||||
var alphaEnd = (objectData.particleAlpha1 + objectData.particleAlphaRandomness2)/255.0;
|
||||
plist.startColorAlpha = (alphaInit + alphaEnd)/2.0;
|
||||
plist.startColorVarianceAlpha = alphaEnd - plist.startColorAlpha;
|
||||
alphaInit = (objectData.particleAlpha2 + objectData.particleAlphaRandomness1)/255.0;
|
||||
alphaEnd = (objectData.particleAlpha2 + objectData.particleAlphaRandomness2)/255.0;
|
||||
plist.finishColorAlpha = (alphaInit + alphaEnd)/2.0;
|
||||
plist.finishColorVarianceAlpha = alphaEnd - plist.finishColorAlpha;
|
||||
}
|
||||
else{
|
||||
var alphaMid = (objectData.particleAlphaRandomness1 + objectData.particleAlphaRandomness2)/(2.0*255.0);
|
||||
plist.startColorAlpha = plist.endColorAlpha = alphaMid;
|
||||
plist.startColorVarianceAlpha = Math.abs(alphaMid - objectData.particleAlphaRandomness1);
|
||||
plist.startColorVarianceAlpha = plist.finishColorVarianceAlpha;
|
||||
}
|
||||
|
||||
if(objectData.sizeParam === "Mutable"){
|
||||
var minSizeVariance = Math.min(objectData.particleSizeRandomness1, objectData.particleSizeRandomness2)/100.0;
|
||||
var maxSizeVariance = Math.max(objectData.particleSizeRandomness1, objectData.particleSizeRandomness2)/100.0;
|
||||
var midSizeVariance = (maxSizeVariance + minSizeVariance)/2.0;
|
||||
plist.startParticleSizeVariance = this.originalSize*objectData.particleSize1/100.0*(maxSizeVariance - minSizeVariance)/2.0;
|
||||
plist.finishParticleSizeVariance = this.originalSize*objectData.particleSize2/100.0*(maxSizeVariance - minSizeVariance)/2.0;
|
||||
plist.startParticleSize = this.originalSize*objectData.particleSize1/100.0 - plist.startParticleSizeVariance;
|
||||
plist.finishParticleSize = this.originalSize*objectData.particleSize2/100.0 - plist.finishParticleSizeVariance;
|
||||
}
|
||||
else{
|
||||
var sizeMid = (objectData.particleSize1 + objectData.particleSize2)/(2.0*100.0);
|
||||
plist.startParticleSize = plist.finishParticleSize = this.originalSize*sizeMid;
|
||||
plist.startParticleSizeVariance = this.originalSize*Math.abs(sizeMid - objectData.particleSizeRandomness1/100.0);
|
||||
plist.finishParticleSizeVariance = plist.startParticleSizeVariance;
|
||||
}
|
||||
|
||||
if(objectData.angleParam === "Mutable"){
|
||||
plist.rotationStart = objectData.particleAngle1 + (objectData.particleAngleRandomness1 + objectData.particleAngleRandomness2)/2.0;
|
||||
plist.rotationEnd = objectData.particleAngle2 + (objectData.particleAngleRandomness1 + objectData.particleAngleRandomness2)/2.0;
|
||||
plist.rotationStartVariance = Math.abs(objectData.particleAngleRandomness2 - objectData.particleAngleRandomness1)/2.0;
|
||||
plist.rotationEndVariance = plist.rotationStartVariance;
|
||||
}
|
||||
else{
|
||||
plist.rotationStart = plist.rotationEnd = (objectData.particleAngleRandomness1 + objectData.particleAngleRandomness2)/2.0;
|
||||
plist.rotationStartVariance = Math.abs(objectData.particleAngleRandomness2 - objectData.particleAngleRandomness1)/2.0;
|
||||
plist.rotationEndVariance = plist.rotationStartVariance;
|
||||
}
|
||||
|
||||
this.renderer = new cc.ParticleSystem(plist);
|
||||
this.renderer.setTexture(texture);
|
||||
this.renderer.setPosition(0, 0);
|
||||
this.renderer.init();
|
||||
|
||||
this.renderer.setBlendFunc(cc.SRC_ALPHA, cc.ONE_MINUS_SRC_ALPHA);
|
||||
if(objectData.additive) this.renderer.setBlendAdditive(true);
|
||||
|
||||
this.renderer.setTotalParticles(objectData.maxParticleNb); // Some particle systems don't work for max particles <= 150
|
||||
this.renderer.setEmissionRate(objectData.flow);
|
||||
this.renderer.setDuration(objectData.tank < 0 ? -1 :
|
||||
(objectData.flow < 0 ? 0.001 : objectData.tank / objectData.flow));
|
||||
|
||||
this.totalParticles = 0;
|
||||
var that = this;
|
||||
this.renderer.addParticle = function(){
|
||||
cc.ParticleSystem.prototype.addParticle.call(that.renderer);
|
||||
++that.totalParticles;
|
||||
};
|
||||
|
||||
this.started = false;
|
||||
|
||||
var renderer = runtimeScene.getLayer("").getRenderer();
|
||||
renderer.addRendererObject(this.renderer, runtimeObject.getZOrder());
|
||||
this._convertYPosition = renderer.convertYPosition;
|
||||
};
|
||||
gdjs.ParticleEmitterObjectRenderer = gdjs.ParticleEmitterObjectCocosRenderer;
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.getRendererObject = function(){
|
||||
return this.renderer;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.update = function(delta){
|
||||
this.renderer.update(delta);
|
||||
if(!this.started && this.getParticleCount() > 0){
|
||||
this.started = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setPosition = function(x, y){
|
||||
this.renderer.setPosition(cc.p(x, this._convertYPosition(y)));
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setAngle = function(angle1, angle2){
|
||||
this.renderer.setAngle(-(angle1 + angle2)/2.0);
|
||||
this.renderer.setAngleVar(Math.abs(angle2 - angle1)/2.0);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setForce = function(min, max){
|
||||
this.renderer.setSpeed((min + max)/2.0);
|
||||
this.renderer.setSpeedVar(Math.abs(max - min)/2.0);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setZoneRadius = function(radius){
|
||||
this.renderer.setPosVar(cc.p(radius, radius));
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setLifeTime = function(min, max){
|
||||
this.renderer.setLife((min + max)/2.0);
|
||||
this.renderer.setLifeVar(Math.abs(max - min)/2.0);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setGravity = function(x, y){
|
||||
this.renderer.setGravity(cc.p(x, -y));
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setColor = function(r1, g1, b1, r2, g2, b2){
|
||||
var a = this.renderer.getStartColor().a;
|
||||
this.renderer.setStartColor(cc.color(r1, g1, b1, a));
|
||||
a = this.renderer.getEndColor().a;
|
||||
this.renderer.setEndColor(cc.color(r2, g2, b2, a));
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setAlpha = function(alpha1, alpha2){
|
||||
var color = this.renderer.getStartColor();
|
||||
color.a = alpha1;
|
||||
this.renderer.setStartColor(color);
|
||||
color = this.renderer.getEndColor();
|
||||
color.a = alpha2;
|
||||
this.renderer.setEndColor(color);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setSize = function(size1, size2){
|
||||
this.renderer.setStartSize(this.originalSize*size1/100.0);
|
||||
this.renderer.setEndSize(this.originalSize*size2/100.0);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setFlow = function(flow){
|
||||
this.renderer.setEmissionRate(flow);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.isTextureValid = function(texture, runtimeScene){
|
||||
return runtimeScene.getGame().getImageManager().getTexture(texture)._textureLoaded;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setTexture = function(texture, runtimeScene){
|
||||
var texture = runtimeScene.getGame().getImageManager().getTexture(texture);
|
||||
if(texture._textureLoaded){
|
||||
this.renderer.setTexture(texture);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.getTotalParticleCount = function(){
|
||||
return this.totalParticles;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.getParticleCount = function(){
|
||||
return this.renderer.getParticleCount();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.stop = function(){
|
||||
this.renderer.stopSystem();
|
||||
};
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.recreate = function(){
|
||||
this.renderer.resetSystem();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.destroy = function(){
|
||||
this.renderer.destroyParticleSystem();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.hasStarted = function(){
|
||||
return this.started;
|
||||
};
|
260
Extensions/ParticleSystem/particleemitterobject-pixi-renderer.js
Normal file
@@ -0,0 +1,260 @@
|
||||
/**
|
||||
|
||||
GDevelop - Particle System Extension
|
||||
Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer = function(runtimeScene, runtimeObject, objectData){
|
||||
var texture = null;
|
||||
var graphics = new PIXI.Graphics();
|
||||
graphics.lineStyle(0, 0, 0);
|
||||
graphics.beginFill(gdjs.rgbToHexNumber(255,255,255), 1);
|
||||
if(objectData.rendererType === "Point")
|
||||
graphics.drawCircle(0, 0, objectData.rendererParam1);
|
||||
else if(objectData.rendererType === "Line"){
|
||||
graphics.drawRect(objectData.rendererParam1, 0, objectData.rendererParam1, objectData.rendererParam2);
|
||||
// Draw an almost-invisible rectangle in the left hand to force PIXI to take a full texture with our line at the right hand
|
||||
graphics.beginFill(gdjs.rgbToHexNumber(255,255,255), 0.001);
|
||||
graphics.drawRect(0, 0, objectData.rendererParam1, objectData.rendererParam2);
|
||||
}
|
||||
else{
|
||||
if(objectData.textureParticleName){
|
||||
var sprite = new PIXI.Sprite(runtimeScene.getGame().getImageManager().getPIXITexture(objectData.textureParticleName));
|
||||
sprite.width = objectData.rendererParam1;
|
||||
sprite.height = objectData.rendererParam2;
|
||||
graphics.addChild(sprite);
|
||||
}
|
||||
else{
|
||||
graphics.drawRect(0, 0, objectData.rendererParam1, objectData.rendererParam2);
|
||||
}
|
||||
}
|
||||
graphics.endFill();
|
||||
texture = graphics.generateTexture();
|
||||
|
||||
var config = {
|
||||
color: {
|
||||
list: [
|
||||
{
|
||||
value: gdjs.rgbToHexNumber(objectData.particleRed1,
|
||||
objectData.particleGreen1,
|
||||
objectData.particleBlue1).toString(16),
|
||||
time: 0
|
||||
},
|
||||
{
|
||||
value: gdjs.rgbToHexNumber(objectData.particleRed2,
|
||||
objectData.particleGreen2,
|
||||
objectData.particleBlue2).toString(16),
|
||||
time: 1
|
||||
}
|
||||
],
|
||||
isStepped: false
|
||||
},
|
||||
acceleration: {
|
||||
x: objectData.particleGravityX,
|
||||
y: objectData.particleGravityY
|
||||
},
|
||||
lifetime: {
|
||||
min: objectData.particleLifeTimeMin,
|
||||
max: objectData.particleLifeTimeMax
|
||||
},
|
||||
// A negative flow is "infinite flow" (all particles burst)
|
||||
frequency: objectData.flow < 0 ? 0.0001 : 1.0/objectData.flow,
|
||||
spawnChance: 1,
|
||||
particlesPerWave: objectData.flow < 0 ? objectData.maxParticleNb : 1,
|
||||
maxParticles: objectData.maxParticleNb,
|
||||
|
||||
// Lifetime can be computed from the tank (the number of particles available)
|
||||
// and the flow (number of particles emitted per seconds)
|
||||
emitterLifetime:
|
||||
objectData.tank < 0 ? -1 :
|
||||
(objectData.flow < 0 ? 0.001 : objectData.tank / objectData.flow),
|
||||
pos: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
addAtBack: false,
|
||||
spawnType: "circle",
|
||||
spawnCircle: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
r: objectData.zoneRadius
|
||||
}
|
||||
};
|
||||
|
||||
config.speed = { list: [{time: 0, value: objectData.emitterForceMax}],
|
||||
minimumSpeedMultiplier: objectData.emitterForceMax !== 0 ?
|
||||
objectData.emitterForceMin / objectData.emitterForceMax : 1,
|
||||
isStepped: false };
|
||||
|
||||
if(objectData.alphaParam === "Mutable"){
|
||||
config.alpha = { list: [{time: 0, value: objectData.particleAlpha1/255.0},
|
||||
{time: 1, value: objectData.particleAlpha2/255.0}],
|
||||
isStepped: false };
|
||||
}
|
||||
else{
|
||||
config.alpha = { list: [{time: 0, value: objectData.particleAlpha1/255.0}],
|
||||
isStepped: false };
|
||||
}
|
||||
|
||||
if(objectData.sizeParam === "Mutable"){
|
||||
var size1 = objectData.particleSize1/100;
|
||||
var size2 = objectData.particleSize2/100;
|
||||
var sizeRandom1 = objectData.particleSizeRandomness1/100;
|
||||
var sizeRandom2 = objectData.particleSizeRandomness2/100;
|
||||
var m = sizeRandom2 !== 0 ? (1 + sizeRandom1)/(1 + sizeRandom2) : 1;
|
||||
config.scale = { list: [{time: 0, value: size1*(1 + sizeRandom1)},
|
||||
{time: 1, value: size2*(1 + sizeRandom2)}],
|
||||
minimumScaleMultiplier: m,
|
||||
isStepped: false };
|
||||
}
|
||||
else{
|
||||
var size1 = objectData.particleSize1/100;
|
||||
var size2 = objectData.particleSize2/100;
|
||||
var mult = size2 !== 0 ? (1 + size1)/(1 + size2) : 1;
|
||||
if(size2 === 0 && size1 > size2){
|
||||
mult = (1 + size2)/(1 + size1);
|
||||
size2 = size1;
|
||||
}
|
||||
config.scale = { list: [{time: 0, value: size2}],
|
||||
minimumScaleMultiplier: mult,
|
||||
isStepped: false };
|
||||
}
|
||||
|
||||
|
||||
if(objectData.emissionEditionSimpleMode){
|
||||
config.startRotation = { min:-objectData.emitterAngleB/2.0,
|
||||
max: objectData.emitterAngleB/2.0 };
|
||||
}
|
||||
else{
|
||||
config.startRotation = { min: objectData.emitterAngleA,
|
||||
max: objectData.emitterAngleB };
|
||||
}
|
||||
|
||||
if(objectData.angleParam === "Mutable"){
|
||||
var mediumLifetime = (objectData.particleLifeTimeMin + objectData.particleLifeTimeMax)/2;
|
||||
config.rotationSpeed = { min: objectData.particleAngle1/mediumLifetime,
|
||||
max: objectData.particleAngle2/mediumLifetime };
|
||||
}
|
||||
else{
|
||||
config.startRotation = { min: objectData.particleAngle1,
|
||||
max: objectData.particleAngle2 };
|
||||
config.rotationSpeed = { min: 0, max: 0 };
|
||||
}
|
||||
|
||||
config.blendMode = objectData.additive ? "ADD" : "NORMAL";
|
||||
|
||||
this.renderer = new PIXI.Container();
|
||||
this.emitter = new PIXI.particles.Emitter(this.renderer, texture, config);
|
||||
this.emitter.emit = true;
|
||||
this.started = false;
|
||||
|
||||
var layer = runtimeScene.getLayer("");
|
||||
if (layer) layer.getRenderer().addRendererObject(this.renderer, runtimeObject.getZOrder());
|
||||
};
|
||||
gdjs.ParticleEmitterObjectRenderer = gdjs.ParticleEmitterObjectPixiRenderer;
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.getRendererObject = function(){
|
||||
return this.renderer;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.update = function(delta){
|
||||
this.emitter.update(delta);
|
||||
if(!this.started && this.getParticleCount() > 0){
|
||||
this.started = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setPosition = function(x, y){
|
||||
this.emitter.spawnPos.x = x;
|
||||
this.emitter.spawnPos.y = y;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setAngle = function(angle1, angle2){
|
||||
this.emitter.minStartRotation = angle1;
|
||||
this.emitter.maxStartRotation = angle2;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setForce = function(min, max){
|
||||
this.emitter.startSpeed.value = max;
|
||||
this.emitter.minimumSpeedMultiplier = max !== 0 ? min/max : 1;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setZoneRadius = function(radius){
|
||||
this.emitter.spawnCircle.radius = radius;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setLifeTime = function(min, max){
|
||||
this.emitter.minLifetime = min;
|
||||
this.emitter.maxLifetime = max;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setGravity = function(x, y){
|
||||
this.emitter.acceleration.x = x;
|
||||
this.emitter.acceleration.y = y;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setColor = function(r1, g1, b1, r2, g2, b2){
|
||||
this.emitter.startColor.value.r = r1;
|
||||
this.emitter.startColor.value.g = g1;
|
||||
this.emitter.startColor.value.b = b1;
|
||||
this.emitter.startColor.next.value.r = r2;
|
||||
this.emitter.startColor.next.value.g = g2;
|
||||
this.emitter.startColor.next.value.b = b2;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setSize = function(size1, size2){
|
||||
this.emitter.startScale.value = size1/100.0;
|
||||
if(this.emitter.startScale.next){
|
||||
this.emitter.startScale.next.value = size2/100.0;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setAlpha = function(alpha1, alpha2){
|
||||
this.emitter.startAlpha.value = alpha1/255.0;
|
||||
if(this.emitter.startAlpha.next){
|
||||
this.emitter.startAlpha.next.value = alpha2/255.0;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setFlow = function(flow, tank){
|
||||
this.emitter.frequency = flow < 0 ? 0.0001 : 1.0/flow;
|
||||
this.emitterLifetime = tank < 0 ? -1 :
|
||||
(flow < 0 ? 0.001 : (tank - this.emitter.totalParticleCount) / flow);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.isTextureValid = function(texture, runtimeScene){
|
||||
return runtimeScene.getGame().getImageManager().getPIXITexture(texture).valid;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.setTexture = function(texture, runtimeScene){
|
||||
var pixiTexture = runtimeScene.getGame().getImageManager().getPIXITexture(texture);
|
||||
if(pixiTexture.valid){
|
||||
this.emitter.particleImages[0] = pixiTexture;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.getTotalParticleCount = function(){
|
||||
return this.emitter.totalParticleCount;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.getParticleCount = function(){
|
||||
return this.emitter.particleCount;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.stop = function(){
|
||||
this.emitter.emit = false;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.recreate = function(){
|
||||
this.emitter.cleanup();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.destroy = function(){
|
||||
this.emitter.destroy();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObjectPixiRenderer.prototype.hasStarted = function(){
|
||||
return this.started;
|
||||
};
|
468
Extensions/ParticleSystem/particleemitterobject.js
Normal file
@@ -0,0 +1,468 @@
|
||||
/**
|
||||
|
||||
GDevelop - Particle System Extension
|
||||
Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
gdjs.ParticleEmitterObject = function(runtimeScene, objectData){
|
||||
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
|
||||
|
||||
this.renderer = new gdjs.ParticleEmitterObjectRenderer(runtimeScene, this, objectData);
|
||||
|
||||
this.singleAngle = objectData.emissionEditionSimpleMode;
|
||||
this.angleA = objectData.emitterAngleA;
|
||||
this.angleB = objectData.emitterAngleB;
|
||||
this.forceMin = objectData.emitterForceMin;
|
||||
this.forceMax = objectData.emitterForceMax;
|
||||
this.zoneRadius = objectData.zoneRadius;
|
||||
this.lifeTimeMin = objectData.particleLifeTimeMin;
|
||||
this.lifeTimeMax = objectData.particleLifeTimeMax;
|
||||
this.gravityX = objectData.particleGravityX;
|
||||
this.gravityY = objectData.particleGravityY;
|
||||
this.colorR1 = objectData.particleRed1;
|
||||
this.colorR2 = objectData.particleRed2;
|
||||
this.colorG1 = objectData.particleGreen1;
|
||||
this.colorG2 = objectData.particleGreen2;
|
||||
this.colorB1 = objectData.particleBlue1;
|
||||
this.colorB2 = objectData.particleBlue2;
|
||||
this.size1 = objectData.particleSize1;
|
||||
this.size2 = objectData.particleSize2;
|
||||
this.sizeParam = objectData.sizeParam;
|
||||
this.alpha1 = objectData.particleAlpha1;
|
||||
this.alpha2 = objectData.particleAlpha2;
|
||||
this.rendererType = objectData.rendererType;
|
||||
this.rendererParam1 = objectData.rendererParam1;
|
||||
this.rendererParam2 = objectData.rendererParam2;
|
||||
this.texture = objectData.textureParticleName;
|
||||
this.flow = objectData.flow;
|
||||
this.tank = objectData.tank;
|
||||
this.destroyWhenNoParticles = objectData.destroyWhenNoParticles;
|
||||
|
||||
this._posDirty = true;
|
||||
this._angleDirty = true;
|
||||
this._forceDirty = true;
|
||||
this._zoneRadiusDirty = true;
|
||||
this._lifeTimeDirty = true;
|
||||
this._gravityDirty = true;
|
||||
this._colorDirty = true;
|
||||
this._sizeDirty = true;
|
||||
this._alphaDirty = true;
|
||||
this._textureDirty = true;
|
||||
this._flowDirty = true;
|
||||
};
|
||||
gdjs.ParticleEmitterObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
|
||||
gdjs.ParticleEmitterObject.thisIsARuntimeObjectConstructor = "ParticleSystem::ParticleEmitter";
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setX = function(x){
|
||||
if(this.x !== x) this._posDirty = true;
|
||||
gdjs.RuntimeObject.prototype.setX.call(this, x);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setY = function(y){
|
||||
if(this.y !== y) this._posDirty = true;
|
||||
gdjs.RuntimeObject.prototype.setY.call(this, y);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setAngle = function(angle){
|
||||
if(this.angle !== angle) this._angleDirty = true;
|
||||
gdjs.RuntimeObject.prototype.setAngle.call(this, angle);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getRendererObject = function(){
|
||||
return this.renderer.getRendererObject();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.update = function(runtimeScene){
|
||||
if(this._posDirty){
|
||||
this.renderer.setPosition(this.getX(), this.getY());
|
||||
}
|
||||
if(this._angleDirty){
|
||||
var angle = this.getAngle();
|
||||
if(this.singleAngle) this.renderer.setAngle(this.angle - this.angleB/2.0, this.angle + this.angleB/2.0);
|
||||
else this.renderer.setAngle(this.angle + this.angleA, this.angle + this.angleB);
|
||||
}
|
||||
if(this._forceDirty){
|
||||
this.renderer.setForce(this.forceMin, this.forceMax);
|
||||
}
|
||||
if(this._zoneRadiusDirty){
|
||||
this.renderer.setZoneRadius(this.zoneRadius);
|
||||
}
|
||||
if(this._lifeTimeDirty){
|
||||
this.renderer.setLifeTime(this.lifeTimeMin, this.lifeTimeMax);
|
||||
}
|
||||
if(this._gravityDirty){
|
||||
this.renderer.setGravity(this.gravityX, this.gravityY);
|
||||
}
|
||||
if(this._colorDirty){
|
||||
this.renderer.setColor(this.colorR1, this.colorG1, this.colorB1,
|
||||
this.colorR2, this.colorG2, this.colorB2);
|
||||
}
|
||||
if(this._sizeDirty && this.sizeParam === "Mutable"){
|
||||
this.renderer.setSize(this.size1, this.size2);
|
||||
}
|
||||
if(this._alphaDirty){
|
||||
this.renderer.setAlpha(this.alpha1, this.alpha2);
|
||||
}
|
||||
if(this._flowDirty){
|
||||
this.renderer.setFlow(this.flow, this.tank);
|
||||
}
|
||||
if(this._textureDirty){
|
||||
this.renderer.setTexture(this.texture, runtimeScene);
|
||||
}
|
||||
|
||||
this._posDirty = this._angleDirty = this._forceDirty = this._zoneRadiusDirty = false;
|
||||
this._lifeTimeDirty = this._gravityDirty = this._colorDirty = this._sizeDirty = false;
|
||||
this._alphaDirty = this._flowDirty = this._textureDirty = false;
|
||||
|
||||
this.renderer.update(this.getElapsedTime(runtimeScene)/1000.0);
|
||||
|
||||
if(this.tank > 0 && this.renderer.getTotalParticleCount() > this.tank){
|
||||
this.renderer.stop();
|
||||
}
|
||||
|
||||
if(this.renderer.hasStarted() && this.renderer.getParticleCount() === 0 && this.destroyWhenNoParticles){
|
||||
this.deleteFromScene(runtimeScene);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.onDeletedFromScene = function(runtimeScene){
|
||||
this.renderer.destroy();
|
||||
gdjs.RuntimeObject.prototype.onDeletedFromScene.call(this, runtimeScene);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getEmitterForceMin = function(){
|
||||
return this.forceMin;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setEmitterForceMin = function(force){
|
||||
if(force < 0) force = 0;
|
||||
|
||||
if(this.forceMin !== force){
|
||||
this._forceDirty = true;
|
||||
this.forceMin = force;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getEmitterForceMax = function(){
|
||||
return this.forceMax;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setEmitterForceMax = function(force){
|
||||
if(force < 0) force = 0;
|
||||
|
||||
if(this.forceMax !== force){
|
||||
this._forceDirty = true;
|
||||
this.forceMax = force;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getEmitterAngle = function(){
|
||||
return (this.angleA + this.angleB)/2.0;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setEmitterAngle = function(angle){
|
||||
var oldAngle = this.getEmitterAngle();
|
||||
if(angle !== oldAngle){
|
||||
this._angleDirty = true;
|
||||
this.angleA += angle - oldAngle;
|
||||
this.angleB += angle - oldAngle;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getEmitterAngleA = function(){
|
||||
return this.angleA;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setEmitterAngleA = function(angle){
|
||||
if(this.angleA !== angle){
|
||||
this._angleDirty = true;
|
||||
this.angleA = angle;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getEmitterAngleB = function(){
|
||||
return this.angleB;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setEmitterAngleB = function(angle){
|
||||
if(this.angleB !== angle){
|
||||
this._angleDirty = true;
|
||||
this.angleB = angle;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getConeSprayAngle = function(){
|
||||
return Math.abs(this.angleB - this.angleA);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setConeSprayAngle = function(angle){
|
||||
var oldCone = this.getConeSprayAngle();
|
||||
if(oldCone !== angle){
|
||||
this._angleDirty = true;
|
||||
var midAngle = this.getEmitterAngle();
|
||||
this.angleA = midAngle - angle/2.0;
|
||||
this.angleB = midAngle + angle/2.0;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getZoneRadius = function(){
|
||||
return this.zoneRadius;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setZoneRadius = function(radius){
|
||||
if(radius < 0) radius = 0;
|
||||
|
||||
if(this.zoneRadius !== radius && radius > 0){
|
||||
this._zoneRadiusDirty = true;
|
||||
this.zoneRadius = radius;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleLifeTimeMin = function(){
|
||||
return this.lifeTimeMin;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleLifeTimeMin = function(lifeTime){
|
||||
if(lifeTime < 0) lifeTime = 0;
|
||||
|
||||
if(this.lifeTimeMin !== lifeTime){
|
||||
this._lifeTimeDirty = true;
|
||||
this.lifeTimeMin = lifeTime;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleLifeTimeMax = function(){
|
||||
return this.lifeTimeMax;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleLifeTimeMax = function(lifeTime){
|
||||
if(lifeTime < 0) lifeTime = 0;
|
||||
|
||||
if(this.lifeTimeMax !== lifeTime){
|
||||
this._lifeTimeDirty = true;
|
||||
this.lifeTimeMax = lifeTime;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleGravityX = function(){
|
||||
return this.gravityX;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleGravityX = function(x){
|
||||
if(this.gravityX !== x){
|
||||
this._gravityDirty = true;
|
||||
this.gravityX = x;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleGravityY = function(){
|
||||
return this.gravityY;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleGravityY = function(y){
|
||||
if(this.gravityY !== y){
|
||||
this._gravityDirty = true;
|
||||
this.gravityY = y;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleGravityAngle = function(){
|
||||
return Math.atan2(this.gravityY, this.gravityX)*180.0/Math.PI;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleGravityAngle = function(angle){
|
||||
var oldAngle = this.getParticleGravityAngle();
|
||||
if(oldAngle !== angle){
|
||||
this._gravityDirty = true;
|
||||
var length = this.getParticleGravityLength();
|
||||
this.gravityX = length*Math.cos(angle*Math.PI/180.0);
|
||||
this.gravityY = length*Math.sin(angle*Math.PI/180.0);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleGravityLength = function(){
|
||||
return Math.sqrt(this.gravityX*this.gravityX + this.gravityY*this.gravityY);
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleGravityLength = function(length){
|
||||
if(length < 0) length = 0;
|
||||
|
||||
var oldLength = this.getParticleGravityLength();
|
||||
if(oldLength !== length){
|
||||
this._gravityDirty = true;
|
||||
this.gravityX *= length/oldLength;
|
||||
this.gravityY *= length/oldLength;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleRed1 = function(){
|
||||
return this.colorR1;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleRed1 = function(red){
|
||||
if(red < 0) red = 0;
|
||||
if(red > 255) red = 255;
|
||||
|
||||
if(this.colorR1 !== red){
|
||||
this._colorDirty = true;
|
||||
this.colorR1 = red;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleRed2 = function(){
|
||||
return this.colorR2;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleRed2 = function(red){
|
||||
if(red < 0) red = 0;
|
||||
if(red > 255) red = 255;
|
||||
|
||||
if(this.colorR2 !== red){
|
||||
this._colorDirty = true;
|
||||
this.colorR2 = red;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleGreen1 = function(){
|
||||
return this.colorG1;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleGreen1 = function(green){
|
||||
if(green < 0) green = 0;
|
||||
if(green > 255) green = 255;
|
||||
|
||||
if(this.colorG1 !== green){
|
||||
this._colorDirty = true;
|
||||
this.colorG1 = green;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleGreen2 = function(){
|
||||
return this.colorG2;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleGreen2 = function(green){
|
||||
if(green < 0) green = 0;
|
||||
if(green > 255) green = 255;
|
||||
|
||||
if(this.colorG2 !== green){
|
||||
this._colorDirty = true;
|
||||
this.colorG2 = green;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleBlue1 = function(){
|
||||
return this.colorB1;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleBlue1 = function(blue){
|
||||
if(blue < 0) blue = 0;
|
||||
if(blue > 255) blue = 255;
|
||||
|
||||
if(this.colorB1 !== blue){
|
||||
this._colorDirty = true;
|
||||
this.colorB1 = blue;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleBlue2 = function(){
|
||||
return this.colorB2;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleBlue2 = function(blue){
|
||||
if(blue < 0) blue = 0;
|
||||
if(blue > 255) blue = 255;
|
||||
|
||||
if(this.colorB2 !== blue){
|
||||
this._colorDirty = true;
|
||||
this.colorB2 = blue;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleSize1 = function(){
|
||||
return this.size1;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleSize1 = function(size){
|
||||
if(size < 0) size = 0;
|
||||
|
||||
if(this.size1 !== size){
|
||||
this._sizeDirty = true;
|
||||
this.size1 = size;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleSize2 = function(){
|
||||
return this.size2;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleSize2 = function(size){
|
||||
if(this.size2 !== size){
|
||||
this._sizeDirty = true;
|
||||
this.size2 = size;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleAlpha1 = function(){
|
||||
return this.alpha1;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleAlpha1 = function(alpha){
|
||||
if(this.alpha1 !== alpha){
|
||||
this._alphaDirty = true;
|
||||
this.alpha1 = alpha;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getParticleAlpha2 = function(){
|
||||
return this.alpha2;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setParticleAlpha2 = function(alpha){
|
||||
if(this.alpha2 !== alpha){
|
||||
this._alphaDirty = true;
|
||||
this.alpha2 = alpha;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.noMoreParticles = function(){
|
||||
this.renderer.stop();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.recreateParticleSystem = function(){
|
||||
this.renderer.recreate();
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getFlow = function(){
|
||||
return this.flow;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setFlow = function(flow){
|
||||
if(this.flow !== flow){
|
||||
this.flow = flow;
|
||||
this._flowDirty = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getTank = function(){
|
||||
return this.tank;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setTank = function(tank){
|
||||
this.tank = tank;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.getTexture = function(){
|
||||
return this.texture;
|
||||
};
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setTexture = function(texture, runtimeScene){
|
||||
if(this.texture !== texture){
|
||||
if(this.renderer.isTextureValid(texture, runtimeScene)){
|
||||
this.texture = texture;
|
||||
this._textureDirty = true;
|
||||
}
|
||||
}
|
||||
};
|
1
Extensions/ParticleSystem/pixi-particles-pixi-renderer.min.js
vendored
Normal file
398
Extensions/SkeletonObject/Ask.js
Normal file
@@ -0,0 +1,398 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @namespace gdjs.sk
|
||||
*/
|
||||
gdjs.sk = gdjs.sk || {
|
||||
// Some useful constants
|
||||
SLOT_UNDEFINED: -1,
|
||||
SLOT_IMAGE: 0,
|
||||
SLOT_MESH: 1,
|
||||
SLOT_POLYGON: 2,
|
||||
SLOT_ARMATURE: 3,
|
||||
EASING_CONST: 0,
|
||||
EASING_LINEAR: 1,
|
||||
EASING_CURVE: 2,
|
||||
EVENT_STOP: 0,
|
||||
EVENT_PLAY: 1,
|
||||
EVENT_PLAYSINGLE: 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Matrix holds the basic transformation data in a matrix form.
|
||||
*
|
||||
* @namespace gdjs.sk
|
||||
* @class Matrix
|
||||
*/
|
||||
gdjs.sk.Matrix = function(a=1, b=0, tx=0, c=0, d=1, ty=0){
|
||||
this.a = a; this.b = b; this.tx = tx;
|
||||
this.c = c; this.d = d; this.ty = ty;
|
||||
this.u = 0; this.v = 0; this.w = 1;
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.translation = function(x, y){
|
||||
this.tx = x;
|
||||
this.ty = y;
|
||||
return this;
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.rotation = function(angle){
|
||||
this.a = Math.cos(angle); this.b = -Math.sin(angle);
|
||||
this.c = Math.sin(angle); this.d = Math.cos(angle);
|
||||
return this;
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.scale = function(sx, sy){
|
||||
this.a = sx;
|
||||
this.d = sy;
|
||||
return this;
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.clone = function(){
|
||||
return new gdjs.sk.Matrix(this.a, this.b, this.tx,
|
||||
this.c, this.d, this.ty,
|
||||
this.u, this.v, this.w );
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.mul = function(m){
|
||||
return new gdjs.sk.Matrix(this.a*m.a + this.b*m.c,
|
||||
this.a*m.b + this.b*m.d,
|
||||
this.a*m.tx + this.b*m.ty + this.tx,
|
||||
this.c*m.a + this.d*m.c,
|
||||
this.c*m.b + this.d*m.d,
|
||||
this.c*m.tx + this.d*m.ty + this.ty);
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.mulVec = function(v){
|
||||
return [this.a*v[0] + this.b*v[1] + this.tx,
|
||||
this.c*v[0] + this.d*v[1] + this.ty];
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.invert = function(){
|
||||
var det_inv = 1.0 / (this.a*this.d - this.b*this.c);
|
||||
var a = this.a;
|
||||
var tx = this.tx;
|
||||
|
||||
this.tx = (this.b*this.ty - this.d*tx)*det_inv;
|
||||
this.ty = (this.c*tx - this.a*this.ty)*det_inv;
|
||||
this.a = this.d*det_inv;
|
||||
this.b =-this.b*det_inv;
|
||||
this.c =-this.c*det_inv;
|
||||
this.d = a*det_inv;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.inverse = function(){
|
||||
var det_inv = 1.0 / (this.a*this.d - this.b*this.c);
|
||||
return new gdjs.sk.Matrix( this.d*det_inv,
|
||||
-this.b*det_inv,
|
||||
(this.b*this.ty - this.d*this.tx)*det_inv,
|
||||
-this.c*det_inv,
|
||||
this.a*det_inv,
|
||||
(this.c*this.tx - this.a*this.ty)*det_inv);
|
||||
};
|
||||
|
||||
gdjs.sk.Matrix.prototype.str = function(){
|
||||
return "|" + this.a.toFixed(2) + ", " + this.b.toFixed(2) + ", " + this.tx.toFixed(2) + "|\n" +
|
||||
"|" + this.c.toFixed(2) + ", " + this.d.toFixed(2) + ", " + this.ty.toFixed(2) + "|\n" +
|
||||
"|" + this.u.toFixed(2) + ", " + this.v.toFixed(2) + ", " + this.w.toFixed(2) + "|\n";
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The Transform is the basic class for transformable objects as bones, slots and armatures.
|
||||
*
|
||||
* @namespace gdjs.sk
|
||||
* @class Transform
|
||||
*/
|
||||
gdjs.sk.Transform = function(x=0, y=0, rot=0, sx=1, sy=1){
|
||||
this.parent = null;
|
||||
this.children = [];
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rot = rot * Math.PI / 180.0;
|
||||
this.sx = sx;
|
||||
this.sy = sy;
|
||||
this.matrix = new gdjs.sk.Matrix();
|
||||
this.worldMatrix = new gdjs.sk.Matrix();
|
||||
this._updateMatrix = true;
|
||||
this._updateWorldMatrix = false;
|
||||
this.inheritTranslation = true;
|
||||
this.inheritRotation = true;
|
||||
this.inheritScale = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.addChild = function(child){
|
||||
this.children.push(child);
|
||||
child.reparent(this);
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.reparent = function(parent){
|
||||
if(this.parent){
|
||||
this.parent.removeChild(this);
|
||||
}
|
||||
this.parent = parent;
|
||||
this._updateWorldMatrix = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.removeChild = function(child){
|
||||
var index = this.children.indexOf(child);
|
||||
if(index > -1){
|
||||
this.children.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getX = function(){
|
||||
return this.x;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setX = function(x){
|
||||
if(this.x !== x){
|
||||
this.x = x;
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getGlobalX = function(){
|
||||
this.updateParentsTransform();
|
||||
return this.worldMatrix.tx;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setGlobalX = function(x){
|
||||
var globalY = this.getGlobalY(); // Also updates parent transforms
|
||||
var localPos = this.parent.worldMatrix.inverse().mulVec([x, globalY, 1.0]);
|
||||
this.x = localPos[0];
|
||||
this.y = localPos[1];
|
||||
this._updateMatrix = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getY = function(){
|
||||
return this.y;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setY = function(y){
|
||||
if(this.y !== y){
|
||||
this.y = y;
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getGlobalY = function(){
|
||||
this.updateParentsTransform();
|
||||
return this.worldMatrix.ty;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setGlobalY = function(y){
|
||||
var globalX = this.getGlobalX(); // Also updates parent transforms
|
||||
var localPos = this.parent.worldMatrix.inverse().mulVec([globalX, y, 1.0]);
|
||||
this.x = localPos[0];
|
||||
this.y = localPos[1];
|
||||
this._updateMatrix = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setPos = function(x, y){
|
||||
if(this.x !== x || this.y !== y){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getRot = function(){
|
||||
return this.rot * 180.0 / Math.PI;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setRot = function(angle){
|
||||
angle *= Math.PI / 180.0;
|
||||
if(this.rot !== angle){
|
||||
this.rot = angle;
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getGlobalRot = function(){
|
||||
this.updateParentsTransform();
|
||||
var sx = Math.sqrt(this.worldMatrix.a * this.worldMatrix.a +
|
||||
this.worldMatrix.c * this.worldMatrix.c );
|
||||
var sy = Math.sqrt(this.worldMatrix.b * this.worldMatrix.b +
|
||||
this.worldMatrix.d * this.worldMatrix.d );
|
||||
return Math.atan2(-this.worldMatrix.b/sy, this.worldMatrix.a/sx) * 180.0 / Math.PI;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setGlobalRot = function(rot){
|
||||
var parentGlobalRot = this.parent ? this.parent.getGlobalRot() : 0;
|
||||
this.rot = (rot - parentGlobalRot)*Math.PI/180.0;
|
||||
this._updateMatrix = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getSx = function(){
|
||||
return this.sx;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.getSy = function(){
|
||||
return this.sy;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setSx = function(sx){
|
||||
if(this.sx !== sx){
|
||||
this.sx = sx;
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setSy = function(sy){
|
||||
if(this.sy !== sy){
|
||||
this.sy = sy;
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.setScale = function(sx, sy){
|
||||
if(this.sx !== sx || this.sy !== sy){
|
||||
this.sx = sx;
|
||||
this.sy = sy;
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.move = function(x, y){
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this._updateMatrix = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.rotate = function(angle){
|
||||
this.rot += angle * Math.PI / 180.0;
|
||||
this._updateMatrix = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.scale = function(sx, sy){
|
||||
this.sx *= sx;
|
||||
this.sy *= sy;
|
||||
this._updateMatrix = true;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.update = function(){
|
||||
this.updateTransform();
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this.children[i].update();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.updateTransform = function(){
|
||||
var sin_rot, cos_rot;
|
||||
if(this._updateMatrix || this._updateWorldMatrix){
|
||||
sin_rot = Math.sin(this.rot);
|
||||
cos_rot = Math.cos(this.rot);
|
||||
}
|
||||
|
||||
if(this._updateMatrix){
|
||||
this.matrix = new gdjs.sk.Matrix(this.sx*cos_rot,-this.sy*sin_rot, this.x,
|
||||
this.sx*sin_rot, this.sy*cos_rot, this.y,
|
||||
0, 0, 1);
|
||||
}
|
||||
if(this._updateMatrix || this._updateWorldMatrix){
|
||||
if(!this.parent){
|
||||
this.worldMatrix = this.matrix.clone();
|
||||
}
|
||||
else{
|
||||
this.worldMatrix = this.parent.worldMatrix.mul(this.matrix);
|
||||
|
||||
if(!this.inheritRotation || !this.inheritScale){
|
||||
if(this.inheritScale){ // Non iherited rotation
|
||||
var worldSx = Math.sqrt(this.worldMatrix.a*this.worldMatrix.a +
|
||||
this.worldMatrix.c*this.worldMatrix.c);
|
||||
var worldSy = Math.sqrt(this.worldMatrix.b*this.worldMatrix.b +
|
||||
this.worldMatrix.d*this.worldMatrix.d);
|
||||
this.worldMatrix.a = worldSx*cos_rot;
|
||||
this.worldMatrix.b = -worldSy*sin_rot;
|
||||
this.worldMatrix.c = worldSx*sin_rot;
|
||||
this.worldMatrix.d = worldSy*cos_rot;
|
||||
}
|
||||
else if(this.inheritRotation){ // Non inherited scale
|
||||
var worldSx = Math.sqrt(this.worldMatrix.a*this.worldMatrix.a +
|
||||
this.worldMatrix.c*this.worldMatrix.c);
|
||||
var worldSy = Math.sqrt(this.worldMatrix.b*this.worldMatrix.b +
|
||||
this.worldMatrix.d*this.worldMatrix.d);
|
||||
this.worldMatrix.a *= this.sx / worldSx;
|
||||
this.worldMatrix.b *= this.sy / worldSy;
|
||||
this.worldMatrix.c *= this.sx / worldSx;
|
||||
this.worldMatrix.d *= this.sy / worldSy;
|
||||
}
|
||||
else{ // Non inherited rotation nor scale
|
||||
this.worldMatrix.a = this.sx*cos_rot;
|
||||
this.worldMatrix.b = -this.sy*sin_rot;
|
||||
this.worldMatrix.c = this.sx*sin_rot;
|
||||
this.worldMatrix.d = this.sy*cos_rot;
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.inheritTranslation){
|
||||
this.worldMatrix.tx = this.x;
|
||||
this.worldMatrix.ty = this.y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(var i=0; i<this.children.length; i++){
|
||||
this.children[i]._updateWorldMatrix = true;
|
||||
}
|
||||
}
|
||||
|
||||
this._updateMatrix = false;
|
||||
this._updateWorldMatrix = false;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.updateParentsTransform = function(){
|
||||
if(this.parent){
|
||||
this.parent.updateParentsTransform();
|
||||
}
|
||||
this.updateTransform();
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.prototype.transformPolygon = function(vertices){
|
||||
this.updateParentsTransform();
|
||||
|
||||
var worldPoly = new gdjs.Polygon();
|
||||
for(var i=0; i<vertices.length; i++){
|
||||
worldPoly.vertices.push(this.worldMatrix.mulVec(vertices[i]));
|
||||
}
|
||||
return worldPoly;
|
||||
};
|
||||
|
||||
gdjs.sk.Transform._statics = {
|
||||
transform: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
sx: 1,
|
||||
sy: 1,
|
||||
skx: 0,
|
||||
sky: 0,
|
||||
rot: 0
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Transform.decomposeMatrix = function(matrix){
|
||||
var transform = gdjs.sk.Transform._statics.transform;
|
||||
|
||||
transform.x = matrix.tx
|
||||
transform.y = matrix.ty;
|
||||
var sx = Math.sqrt(matrix.a*matrix.a + matrix.c*matrix.c);
|
||||
var sy = Math.sqrt(matrix.b*matrix.b + matrix.d*matrix.d);
|
||||
transform.sx = sx;
|
||||
transform.sy = sy;
|
||||
transform.skx = -Math.atan2(matrix.d, matrix.b) + Math.PI/2.0;
|
||||
transform.sky = Math.atan2(matrix.c, matrix.a);
|
||||
transform.rot = Math.atan2(-matrix.b/sy, matrix.a/sx);
|
||||
|
||||
return transform;
|
||||
};
|
@@ -0,0 +1,174 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
gdjs.sk.CocosDataLoader = function()
|
||||
{
|
||||
this.textures = {};
|
||||
};
|
||||
gdjs.sk.DataLoader = gdjs.sk.CocosDataLoader;
|
||||
|
||||
gdjs.sk.CocosDataLoader.prototype.getData = function(dataName){
|
||||
return cc.loader.getRes("res/"+dataName);
|
||||
};
|
||||
|
||||
gdjs.sk.CocosDataLoader.prototype.loadDragonBones = function(runtimeScene, objectData){
|
||||
var textureData = this.getData(objectData.textureDataFilename);
|
||||
var texture = runtimeScene.getGame().getImageManager().getTexture(objectData.textureName);
|
||||
if(!textureData || !texture._textureLoaded) return;
|
||||
|
||||
for(var i=0; i<textureData.SubTexture.length; i++){
|
||||
var subTex = textureData.SubTexture[i];
|
||||
var frame = new cc.rect(subTex.x, subTex.y, subTex.width, subTex.height);
|
||||
if(subTex.hasOwnProperty("frameWidth")){
|
||||
frame.width = subTex.frameWidth;
|
||||
}
|
||||
if (subTex.hasOwnProperty("frameHeight")){
|
||||
frame.height = subTex.frameHeight;
|
||||
}
|
||||
|
||||
this.textures[subTex.name] = {"texture": texture, "frame": frame};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
gdjs.sk.ArmatureCocosRenderer = function()
|
||||
{
|
||||
this.layer = new cc.Layer();
|
||||
this.slotsRenderers = new cc.Layer();
|
||||
this.layer.addChild(this.slotsRenderers);
|
||||
this.debugRenderers = new cc.Layer();
|
||||
this.layer.addChild(this.debugRenderers);
|
||||
this._convertYPosition = function(y){ return y; };
|
||||
};
|
||||
gdjs.sk.ArmatureRenderer = gdjs.sk.ArmatureCocosRenderer;
|
||||
|
||||
gdjs.sk.ArmatureCocosRenderer.prototype.putInScene = function(runtimeObject, runtimeScene){
|
||||
var layerRenderer = runtimeScene.getLayer("").getRenderer();
|
||||
layerRenderer.addRendererObject(this.layer, runtimeObject.getZOrder());
|
||||
this._convertYPosition = layerRenderer.convertYPosition;
|
||||
};
|
||||
|
||||
gdjs.sk.ArmatureCocosRenderer.prototype.getRendererObject = function(){
|
||||
return this.layer;
|
||||
};
|
||||
|
||||
gdjs.sk.ArmatureCocosRenderer.prototype.addRenderer = function(renderer){
|
||||
this.slotsRenderers.addChild(renderer.getRendererObject());
|
||||
renderer._convertYPosition = this._convertYPosition;
|
||||
|
||||
};
|
||||
|
||||
gdjs.sk.ArmatureCocosRenderer.prototype.sortRenderers = function(){
|
||||
this.slotsRenderers.children.sort(function(a, b){ return a.z - b.z; });
|
||||
};
|
||||
|
||||
gdjs.sk.ArmatureCocosRenderer.prototype.addDebugRenderer = function(renderer){
|
||||
this.debugRenderers.addChild(renderer.getRendererObject());
|
||||
renderer._convertYPosition = this._convertYPosition;
|
||||
};
|
||||
|
||||
gdjs.sk.ArmatureCocosRenderer.prototype.extraInitialization = function(parentArmatureRenderer){
|
||||
this._convertYPosition = parentArmatureRenderer._convertYPosition;
|
||||
};
|
||||
|
||||
|
||||
|
||||
gdjs.sk.SlotCocosRenderer = function()
|
||||
{
|
||||
this.renderer = null;
|
||||
this._convertYPosition = function(y){ return y; };
|
||||
};
|
||||
gdjs.sk.SlotRenderer = gdjs.sk.SlotCocosRenderer;
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.getRendererObject = function(){
|
||||
return this.renderer;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.loadAsSprite = function(texture){
|
||||
if(!texture)
|
||||
this.renderer = new cc.Sprite();
|
||||
else
|
||||
this.renderer = new cc.Sprite.createWithTexture(texture.texture, texture.frame);
|
||||
this.renderer.z = 0;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.loadAsMesh = function(texture, vertices, uvs, triangles){
|
||||
// Meshes not supported, load as sprites
|
||||
this.loadAsSprite(texture);
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.getWidth = function(){
|
||||
return this.renderer.width;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.getHeight = function(){
|
||||
return this.renderer.height;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.setTransform = function(transform){
|
||||
this.renderer.setPositionX(transform.x);
|
||||
this.renderer.setPositionY(this._convertYPosition(transform.y));
|
||||
this.renderer.setScaleX(transform.sx);
|
||||
this.renderer.setScaleY(transform.sy);
|
||||
this.renderer.setRotationX(-transform.skx*180.0/Math.PI);
|
||||
this.renderer.setRotationY( transform.sky*180.0/Math.PI);
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.setZ = function(z){
|
||||
this.renderer.z = z;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.setColor = function(color){
|
||||
this.renderer.setColor(cc.color(color[0], color[1], color[2]));
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.setAlpha = function(alpha){
|
||||
this.renderer.setOpacity(255*alpha);
|
||||
};
|
||||
|
||||
gdjs.sk.SlotCocosRenderer.prototype.setVisible = function(visible){
|
||||
this.renderer.setVisible(visible);
|
||||
};
|
||||
|
||||
// Meshes not supported
|
||||
gdjs.sk.SlotCocosRenderer.prototype.setVertices = function(vertices, updateList){
|
||||
};
|
||||
|
||||
|
||||
gdjs.sk.DebugCocosRenderer = function()
|
||||
{
|
||||
this.renderer = new cc.DrawNode();
|
||||
this._convertYPosition = function(y){ return y; };
|
||||
};
|
||||
gdjs.sk.DebugRenderer = gdjs.sk.DebugCocosRenderer;
|
||||
|
||||
gdjs.sk.DebugCocosRenderer.prototype.getRendererObject = function(){
|
||||
return this.renderer;
|
||||
};
|
||||
|
||||
gdjs.sk.DebugCocosRenderer.prototype.loadVertices = function(verts, color, fill){
|
||||
var fillAlpha = fill ? 100 : 0;
|
||||
var fillColor = new cc.Color(color[0], color[1], color[2], fillAlpha);
|
||||
var lineColor = new cc.Color(color[0], color[1], color[2], 225);
|
||||
for(var i=0; i<verts.length; i++){
|
||||
var vertices = [];
|
||||
for(var i=0; i<verts.length; i++){
|
||||
vertices.push(cc.p(verts[i][0], -verts[i][1]));
|
||||
}
|
||||
this.renderer.drawPoly(vertices, fillColor, 3, lineColor);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.DebugCocosRenderer.prototype.setTransform = function(transform){
|
||||
this.renderer.setPositionX(transform.x);
|
||||
this.renderer.setPositionY(this._convertYPosition(transform.y));
|
||||
this.renderer.setScaleX(transform.sx);
|
||||
this.renderer.setScaleY(transform.sy);
|
||||
this.renderer.setRotationX(-transform.skx*180.0/Math.PI);
|
||||
this.renderer.setRotationY( transform.sky*180.0/Math.PI);
|
||||
};
|
@@ -0,0 +1,187 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
gdjs.sk.PixiDataLoader = function()
|
||||
{
|
||||
this.textures = {};
|
||||
};
|
||||
gdjs.sk.DataLoader = gdjs.sk.PixiDataLoader;
|
||||
|
||||
gdjs.sk.PixiDataLoader.prototype.getData = function(dataName){
|
||||
if(PIXI.loader.resources[dataName]){
|
||||
return PIXI.loader.resources[dataName].data;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
gdjs.sk.PixiDataLoader.prototype.loadDragonBones = function(runtimeScene, objectData){
|
||||
var textureData = this.getData(objectData.textureDataFilename);
|
||||
var texture = runtimeScene.getGame().getImageManager().getPIXITexture(objectData.textureName);
|
||||
if(!textureData || !texture.valid) return;
|
||||
|
||||
for(var i=0; i<textureData.SubTexture.length; i++){
|
||||
var subTex = textureData.SubTexture[i];
|
||||
var frame = new PIXI.Rectangle(subTex.x, subTex.y, subTex.width, subTex.height);
|
||||
if(subTex.hasOwnProperty("frameWidth")){
|
||||
frame.width = subTex.frameWidth;
|
||||
}
|
||||
if (subTex.hasOwnProperty("frameHeight")){
|
||||
frame.height = subTex.frameHeight;
|
||||
}
|
||||
// Fix the frame size, in case texture is not loaded
|
||||
if(frame.x > texture.width) frame.x = 0;
|
||||
if(frame.y > texture.height) frame.y = 0;
|
||||
if(frame.x + frame.width > texture.width) frame.width = texture.width - frame.x;
|
||||
if(frame.y + frame.height > texture.height) frame.height = texture.height - frame.y;
|
||||
|
||||
this.textures[subTex.name] = new PIXI.Texture(texture.baseTexture, frame=frame);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
gdjs.sk.ArmaturePixiRenderer = function()
|
||||
{
|
||||
this.container = new PIXI.Container();
|
||||
this.slotsRenderers = new PIXI.Container();
|
||||
this.container.addChild(this.slotsRenderers);
|
||||
this.debugRenderers = new PIXI.Container();
|
||||
this.container.addChild(this.debugRenderers);
|
||||
};
|
||||
gdjs.sk.ArmatureRenderer = gdjs.sk.ArmaturePixiRenderer;
|
||||
|
||||
gdjs.sk.ArmaturePixiRenderer.prototype.putInScene = function(runtimeObject, runtimeScene){
|
||||
runtimeScene.getLayer("").getRenderer().addRendererObject(this.container, runtimeObject.getZOrder());
|
||||
};
|
||||
|
||||
gdjs.sk.ArmaturePixiRenderer.prototype.getRendererObject = function(){
|
||||
return this.container;
|
||||
};
|
||||
|
||||
gdjs.sk.ArmaturePixiRenderer.prototype.addRenderer = function(renderer){
|
||||
this.slotsRenderers.addChild(renderer.getRendererObject());
|
||||
};
|
||||
|
||||
gdjs.sk.ArmaturePixiRenderer.prototype.sortRenderers = function(){
|
||||
this.slotsRenderers.children.sort(function(a, b){ return a.z - b.z; });
|
||||
};
|
||||
|
||||
gdjs.sk.ArmaturePixiRenderer.prototype.addDebugRenderer = function(renderer){
|
||||
this.debugRenderers.addChild(renderer.getRendererObject());
|
||||
};
|
||||
|
||||
gdjs.sk.ArmaturePixiRenderer.prototype.extraInitialization = function(parentArmatureRenderer){
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
gdjs.sk.SlotPixiRenderer = function()
|
||||
{
|
||||
this.renderer = null;
|
||||
};
|
||||
gdjs.sk.SlotRenderer = gdjs.sk.SlotPixiRenderer;
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.getRendererObject = function(){
|
||||
return this.renderer;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.loadAsSprite = function(texture){
|
||||
this.renderer = new PIXI.Sprite(texture);
|
||||
this.renderer.pivot = new PIXI.Point(this.renderer.width/2.0, this.renderer.height/2.0);
|
||||
this.renderer.z = 0;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.loadAsMesh = function(texture, vertices, uvs, triangles){
|
||||
this.renderer = new PIXI.mesh.Mesh(texture,
|
||||
new Float32Array(vertices),
|
||||
new Float32Array(uvs),
|
||||
new Uint16Array(triangles),
|
||||
PIXI.mesh.Mesh.DRAW_MODES.TRIANGLES);
|
||||
|
||||
this.renderer.uploadUvTransform = true;
|
||||
this.renderer.z = 0;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.getWidth = function(){
|
||||
return this.renderer.width;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.getHeight = function(){
|
||||
return this.renderer.height;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.setTransform = function(transform){
|
||||
this.renderer.x = transform.x;
|
||||
this.renderer.y = transform.y;
|
||||
this.renderer.scale.x = transform.sx;
|
||||
this.renderer.scale.y = transform.sy;
|
||||
this.renderer.skew.x = transform.skx;
|
||||
this.renderer.skew.y = transform.sky;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.setZ = function(z){
|
||||
this.renderer.z = z;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.setColor = function(color){
|
||||
this.renderer.tint = (color[0] << 16) + (color[1] << 8) + color[2];
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.setAlpha = function(alpha){
|
||||
this.renderer.alpha = alpha;
|
||||
};
|
||||
|
||||
gdjs.sk.SlotPixiRenderer.prototype.setVisible = function(visible){
|
||||
this.renderer.visible = visible;
|
||||
};
|
||||
|
||||
// Mesh only
|
||||
gdjs.sk.SlotPixiRenderer.prototype.setVertices = function(vertices, updateList){
|
||||
for(var i=0; i<updateList.length; i++){
|
||||
this.renderer.vertices[2*updateList[i]] = vertices[i][0];
|
||||
this.renderer.vertices[2*updateList[i] + 1] = vertices[i][1];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
gdjs.sk.DebugPixiRenderer = function()
|
||||
{
|
||||
this.renderer = new PIXI.Graphics();
|
||||
};
|
||||
gdjs.sk.DebugRenderer = gdjs.sk.DebugPixiRenderer;
|
||||
|
||||
gdjs.sk.DebugPixiRenderer.prototype.getRendererObject = function(){
|
||||
return this.renderer;
|
||||
};
|
||||
|
||||
gdjs.sk.DebugPixiRenderer.prototype.loadVertices = function(verts, color, fill){
|
||||
color = color[2] | (color[1] << 8) | (color[0] << 16);
|
||||
if(fill){
|
||||
this.renderer.beginFill(color, 0.1);
|
||||
}
|
||||
this.renderer.lineStyle(3, color, 0.8);
|
||||
for(var i=0; i<verts.length; i++){
|
||||
this.renderer.drawPolygon(verts.reduce(function(a, b){ return a.concat(b); }).concat(verts[0]));
|
||||
}
|
||||
if(fill){
|
||||
this.renderer.endFill();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.DebugPixiRenderer.prototype.setTransform = function(transform){
|
||||
this.renderer.x = transform.x;
|
||||
this.renderer.y = transform.y;
|
||||
this.renderer.scale.x = transform.sx;
|
||||
this.renderer.scale.y = transform.sy;
|
||||
this.renderer.skew.x = transform.skx;
|
||||
this.renderer.skew.y = transform.sky;
|
||||
};
|
||||
|
||||
gdjs.sk.DebugPixiRenderer.prototype.skewSupported = function(){
|
||||
return true;
|
||||
};
|
20
Extensions/SkeletonObject/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
|
||||
project(SkeletonObject)
|
||||
gd_add_extension_includes()
|
||||
|
||||
#Defines
|
||||
###
|
||||
gd_add_extension_definitions(SkeletonObject)
|
||||
|
||||
#The targets
|
||||
###
|
||||
include_directories(.)
|
||||
file(GLOB source_files *)
|
||||
|
||||
gd_add_extension_target(SkeletonObject "${source_files}" "JsPlatform")
|
||||
|
||||
#Linker files for the IDE extension
|
||||
###
|
||||
gd_extension_link_libraries(SkeletonObject)
|
131
Extensions/SkeletonObject/Cskbone.js
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @namespace gdjs.sk
|
||||
* @class SharedBone
|
||||
*/
|
||||
gdjs.sk.SharedBone = function(){
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.rot = 0;
|
||||
this.sx = 1;
|
||||
this.sy = 1;
|
||||
this.name = "";
|
||||
this.length = 0;
|
||||
this.parent = -1;
|
||||
this.childBones = [];
|
||||
this.childSlots = [];
|
||||
this.restX = 0;
|
||||
this.restY = 0;
|
||||
this.restRot = 0;
|
||||
this.restSx = 1;
|
||||
this.restSy = 1;
|
||||
};
|
||||
|
||||
gdjs.sk.SharedBone.prototype.loadDragonBones = function(boneData){
|
||||
this.name = boneData.name;
|
||||
this.length = boneData.hasOwnProperty("length") ? boneData.length : 0;
|
||||
|
||||
var transformData = boneData.transform;
|
||||
this.restX = transformData.hasOwnProperty("x") ? transformData.x : 0;
|
||||
this.restY = transformData.hasOwnProperty("y") ? transformData.y : 0;
|
||||
this.restRot = transformData.hasOwnProperty("skX") ? transformData.skX * Math.PI / 180.0 : 0;
|
||||
this.restSx = transformData.hasOwnProperty("scX") ? transformData.scX : 1;
|
||||
this.restSy = transformData.hasOwnProperty("scY") ? transformData.scY : 1;
|
||||
|
||||
this.inheritRotation = boneData.hasOwnProperty("inheritRotation") ? transformData.inheritRotation : true;
|
||||
this.inheritScale = boneData.hasOwnProperty("inheritScale") ? transformData.inheritScale : true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Bone holds basic transform data in a hierarchy tree.
|
||||
*
|
||||
* @namespace gdjs.sk
|
||||
* @class Bone
|
||||
* @extends gdjs.sk.Transform
|
||||
*/
|
||||
gdjs.sk.Bone = function(armature){
|
||||
gdjs.sk.Transform.call(this);
|
||||
|
||||
this.shared = null;
|
||||
this.armature = armature;
|
||||
};
|
||||
gdjs.sk.Bone.prototype = Object.create(gdjs.sk.Transform.prototype);
|
||||
|
||||
gdjs.sk.Bone.prototype.loadData = function(boneData){
|
||||
this.shared = boneData;
|
||||
this.resetState();
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.resetState = function(){
|
||||
this.setPos(0, 0);
|
||||
this.setRot(0);
|
||||
this.setScale(1, 1);
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.setX = function(x){
|
||||
var prevX = this.x;
|
||||
this.x = this.shared.restX + x;
|
||||
if(this.x !== prevX){
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.setY = function(y){
|
||||
var prevY = this.y;
|
||||
this.y = this.shared.restY + y;
|
||||
if(this.y !== prevY){
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.setPos = function(x, y){
|
||||
var prevX = this.x;
|
||||
var prevY = this.y;
|
||||
this.x = this.shared.restX + x;
|
||||
this.y = this.shared.restY + y;
|
||||
if(this.x !== prevX || this.y !== prevY){
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.setRot = function(angle){
|
||||
var prevRot = this.rot;
|
||||
this.rot = this.shared.restRot + angle*Math.PI/180.0;
|
||||
if(this.rot !== prevRot){
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.setSx = function(sx){
|
||||
var prevSx = this.sx;
|
||||
this.sx = this.shared.restSx * sx;
|
||||
if(this.sx !== prevSx){
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.setSy = function(sy){
|
||||
var prevSy = this.sy;
|
||||
this.sy = this.shared.restSy * sy;
|
||||
if(this.sy !== prevSy){
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Bone.prototype.setScale = function(sx, sy){
|
||||
var prevSx = this.sx;
|
||||
var prevSy = this.sy;
|
||||
this.sx = this.shared.restSx * sx;
|
||||
this.sy = this.shared.restSy * sy;
|
||||
if(this.sx !== prevSx || this.sy !== prevSy){
|
||||
this._updateMatrix = true;
|
||||
}
|
||||
};
|
456
Extensions/SkeletonObject/Dskslot.js
Normal file
@@ -0,0 +1,456 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @namespace gdjs.sk
|
||||
* @class SharedSlot
|
||||
*/
|
||||
gdjs.sk.SharedSlot = function(){
|
||||
// Transform
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.rot = 0;
|
||||
this.sx = 1;
|
||||
this.sy = 1;
|
||||
// Slot
|
||||
this.name = "";
|
||||
this.type = gdjs.sk.SLOT_UNDEFINED;
|
||||
this.path = "";
|
||||
this.parent = -1;
|
||||
this.defaultZ = 0;
|
||||
this.defaultR = 255;
|
||||
this.defaultG = 255;
|
||||
this.defaultB = 255;
|
||||
this.defaultAlpha = 1.0;
|
||||
this.defaultVisible = true;
|
||||
this.aabb = null;
|
||||
// Polygon
|
||||
this.polygons = [];
|
||||
// Mesh
|
||||
this.rawVertices = [];
|
||||
this.rawUVs = [];
|
||||
this.rawTriangles = [];
|
||||
this.defaultVertices = [];
|
||||
this.skinned = false;
|
||||
this.skinBones = [];
|
||||
this.skinBonesMatricesInverses = [];
|
||||
this.vertexBones = [];
|
||||
this.vertexWeights = [];
|
||||
// Armature
|
||||
this.armature = "";
|
||||
};
|
||||
|
||||
gdjs.sk.SharedSlot.prototype.loadDragonBonesSlotData = function(slotData){
|
||||
this.name = slotData.name;
|
||||
|
||||
this.defaultZ = slotData.hasOwnProperty("z") ? slotData.z : 0;
|
||||
this.defaultR = slotData.color.hasOwnProperty("rM") ? Math.ceil(slotData.color.rM * 255 / 100) : 255;
|
||||
this.defaultG = slotData.color.hasOwnProperty("gM") ? Math.ceil(slotData.color.gM * 255 / 100) : 255;
|
||||
this.defaultB = slotData.color.hasOwnProperty("bM") ? Math.ceil(slotData.color.bM * 255 / 100) : 255;
|
||||
this.defaultAlpha = slotData.color.hasOwnProperty("aM") ? slotData.color.aM / 100.0 : 1.0;
|
||||
this.defaultVisible = slotData.hasOwnProperty("displayIndex") ? (slotData.displayIndex + 1) / 2 : 1; // {-1, 1} -> {0, 1}
|
||||
};
|
||||
|
||||
gdjs.sk.SharedSlot.prototype.loadDragonBonesSkinData = function(skinDatas, index){
|
||||
var skinData = skinDatas[index];
|
||||
|
||||
var transformData = skinData.display[0].transform;
|
||||
this.x = transformData.hasOwnProperty("x") ? transformData.x : 0;
|
||||
this.y = transformData.hasOwnProperty("y") ? transformData.y : 0;
|
||||
this.rot = transformData.hasOwnProperty("skX") ? transformData.skX * Math.PI / 180.0 : 0;
|
||||
this.sx = transformData.hasOwnProperty("scX") ? transformData.scX : 1;
|
||||
this.sy = transformData.hasOwnProperty("scY") ? transformData.scY : 1;
|
||||
|
||||
// If another slot is already using the same image path we have to search for it
|
||||
if(!skinData.display[0].hasOwnProperty("path")){
|
||||
for(var i=0; i<skinDatas.length; i++){
|
||||
if(skinDatas[i].display[0].name === skinData.display[0].name && skinDatas[i].display[0].path){
|
||||
this.path = skinDatas[i].display[0].path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
this.path = skinData.display[0].path;
|
||||
}
|
||||
|
||||
if(skinData.display[0].type === "image"){
|
||||
this.type = gdjs.sk.SLOT_IMAGE;
|
||||
}
|
||||
|
||||
else if(skinData.display[0].type === "armature"){
|
||||
this.type = gdjs.sk.SLOT_ARMATURE;
|
||||
}
|
||||
|
||||
else if(skinData.display[0].type === "boundingBox"){
|
||||
this.type = gdjs.sk.SLOT_POLYGON;
|
||||
|
||||
var polygon = [];
|
||||
var verts = skinData.display[0].vertices;
|
||||
for(var i=0; i<verts.length; i+=2){
|
||||
polygon.push([verts[i], verts[i+1]]);
|
||||
}
|
||||
this.polygons.push(polygon);
|
||||
}
|
||||
|
||||
else if(skinData.display[0].type === "mesh"){
|
||||
this.type = gdjs.sk.SLOT_MESH;
|
||||
|
||||
for(var i=0; i<skinData.display[0].vertices.length; i+=2){
|
||||
this.defaultVertices.push([skinData.display[0].vertices[i],
|
||||
skinData.display[0].vertices[i+1]]);
|
||||
}
|
||||
|
||||
this.rawVertices = skinData.display[0].vertices;
|
||||
this.rawUVs = skinData.display[0].uvs;
|
||||
this.rawTriangles = skinData.display[0].triangles;
|
||||
|
||||
if(skinData.display[0].hasOwnProperty("weights")){
|
||||
this.skinned = true;
|
||||
|
||||
var slotPose = skinData.display[0].slotPose;
|
||||
var worldMatrixInverse = new gdjs.sk.Matrix( slotPose[0],-slotPose[1], slotPose[4],
|
||||
-slotPose[2], slotPose[3], slotPose[5]);
|
||||
worldMatrixInverse.invert();
|
||||
|
||||
// maps Armature.bones index -> skinBones index
|
||||
var boneMap = {};
|
||||
for(var i=0, j=0; i<skinData.display[0].bonePose.length; i+=7, j++){
|
||||
var bonePose = skinData.display[0].bonePose;
|
||||
var boneWorldMatrix = new gdjs.sk.Matrix( bonePose[i+1],-bonePose[i+2], bonePose[i+5],
|
||||
-bonePose[i+3], bonePose[i+4], bonePose[i+6]);
|
||||
boneMap[bonePose[i]] = j;
|
||||
this.skinBones.push(bonePose[i]);
|
||||
this.skinBonesMatricesInverses.push(worldMatrixInverse.mul(boneWorldMatrix).invert());
|
||||
|
||||
}
|
||||
|
||||
for(var i=0; i<skinData.display[0].weights.length;){
|
||||
var boneCount = skinData.display[0].weights[i];
|
||||
|
||||
var vertexWeights = [];
|
||||
var vertexBones = [];
|
||||
for(var k=0; k<boneCount; k++){
|
||||
|
||||
var boneId = skinData.display[0].weights[i + 2*k + 1];
|
||||
vertexBones.push(boneMap[boneId]);
|
||||
|
||||
var boneWeight = skinData.display[0].weights[i + 2*k + 2];
|
||||
vertexWeights.push(boneWeight);
|
||||
}
|
||||
this.vertexBones.push(vertexBones);
|
||||
this.vertexWeights.push(vertexWeights);
|
||||
|
||||
i += 2 * boneCount + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The Slot display images transformed by animations itself and bones.
|
||||
*
|
||||
* @namespace gdjs.sk
|
||||
* @class Slot
|
||||
* @extends gdjs.sk.Transform
|
||||
*/
|
||||
gdjs.sk.Slot = function(armature){
|
||||
gdjs.sk.Transform.call(this);
|
||||
|
||||
this.shared = null;
|
||||
this.armature = armature;
|
||||
this.z = 0;
|
||||
this.r = 0;
|
||||
this.g = 0;
|
||||
this.b = 0;
|
||||
this.alpha = 0;
|
||||
this.visible = false;
|
||||
this.renderer = new gdjs.sk.SlotRenderer();
|
||||
this._updateRender = false;
|
||||
// Mesh only
|
||||
this.vertices = []; // same as this.shared.defaultVertices, but modified on animations
|
||||
this.skinBones = [];
|
||||
// Armature only
|
||||
this.childArmature = null;
|
||||
// Debug only
|
||||
this.debugRenderer = null;
|
||||
}
|
||||
gdjs.sk.Slot.prototype = Object.create(gdjs.sk.Transform.prototype);
|
||||
|
||||
gdjs.sk.Slot.prototype.loadData = function(slotData, skeletalData, textures, debugPolygons){
|
||||
this.shared = slotData;
|
||||
|
||||
this.z = this.shared.defaultZ;
|
||||
this.r = this.shared.defaultR;
|
||||
this.g = this.shared.defaultG;
|
||||
this.b = this.shared.defaultB;
|
||||
this.alpha = this.shared.defaultAlpha;
|
||||
this.visible = this.shared.defaultVisible;
|
||||
this.x = this.shared.x;
|
||||
this.y = this.shared.y;
|
||||
this.rot = this.shared.rot;
|
||||
this.sx = this.shared.sx;
|
||||
this.sy = this.shared.sy;
|
||||
this._updateMatrix = true;
|
||||
this._updateWorldMatrix = true;
|
||||
|
||||
if(this.shared.type === gdjs.sk.SLOT_IMAGE){
|
||||
this.renderer.loadAsSprite(textures[this.shared.path]);
|
||||
|
||||
if(!this.shared.aabb){
|
||||
this.shared.aabb = [];
|
||||
this.shared.aabb.push([-this.renderer.getWidth()/2.0,-this.renderer.getHeight()/2.0]);
|
||||
this.shared.aabb.push([ this.renderer.getWidth()/2.0,-this.renderer.getHeight()/2.0]);
|
||||
this.shared.aabb.push([ this.renderer.getWidth()/2.0, this.renderer.getHeight()/2.0]);
|
||||
this.shared.aabb.push([-this.renderer.getWidth()/2.0, this.renderer.getHeight()/2.0]);
|
||||
}
|
||||
|
||||
if(debugPolygons){
|
||||
this.debugRenderer = new gdjs.sk.DebugRenderer();
|
||||
this.debugRenderer.loadVertices(this.shared.aabb, [255, 100, 100], false);
|
||||
}
|
||||
}
|
||||
else if(this.shared.type === gdjs.sk.SLOT_MESH){
|
||||
for(var i=0; i<this.shared.defaultVertices.length; i++){
|
||||
this.vertices.push([this.shared.defaultVertices[i][0], this.shared.defaultVertices[i][1]]);
|
||||
}
|
||||
|
||||
for(var i=0; i<this.shared.skinBones.length; i++){
|
||||
this.skinBones.push(this.armature.bones[this.shared.skinBones[i]]);
|
||||
}
|
||||
|
||||
this.renderer.loadAsMesh(textures[this.shared.path],
|
||||
this.shared.rawVertices,
|
||||
this.shared.rawUVs,
|
||||
this.shared.rawTriangles);
|
||||
|
||||
if(!this.shared.aabb){
|
||||
this.shared.aabb = [];
|
||||
this.shared.aabb.push([-this.renderer.getWidth()/2.0,-this.renderer.getHeight()/2.0]);
|
||||
this.shared.aabb.push([ this.renderer.getWidth()/2.0,-this.renderer.getHeight()/2.0]);
|
||||
this.shared.aabb.push([ this.renderer.getWidth()/2.0, this.renderer.getHeight()/2.0]);
|
||||
this.shared.aabb.push([-this.renderer.getWidth()/2.0, this.renderer.getHeight()/2.0]);
|
||||
}
|
||||
|
||||
if(debugPolygons){
|
||||
this.debugRenderer = new gdjs.sk.DebugRenderer();
|
||||
this.debugRenderer.loadVertices(this.shared.aabb, [255, 100, 100], false);
|
||||
}
|
||||
}
|
||||
else if(this.shared.type === gdjs.sk.SLOT_POLYGON){
|
||||
if(debugPolygons){
|
||||
this.debugRenderer = new gdjs.sk.DebugRenderer();
|
||||
this.debugRenderer.loadVertices(this.shared.polygons[0], [100, 255, 100], true);
|
||||
}
|
||||
}
|
||||
else if(this.shared.type === gdjs.sk.SLOT_ARMATURE){
|
||||
for(var i=0; i<skeletalData.armatures.length; i++){
|
||||
if(skeletalData.armatures[i].name === this.shared.path){
|
||||
|
||||
this.childArmature = new gdjs.sk.Armature(this.armature.skeleton, this.armature, this);
|
||||
this.childArmature.getRenderer().extraInitialization(this.armature.getRenderer());
|
||||
this.childArmature.loadData(skeletalData.armatures[i], skeletalData, debugPolygons);
|
||||
this.addChild(this.childArmature);
|
||||
|
||||
if(!this.shared.aabb){
|
||||
this.shared.aabb = [];
|
||||
var verts = this.childArmature.getAABB().vertices;
|
||||
for(var j=0; j<verts.length; j++){
|
||||
this.shared.aabb.push([verts[j][0], verts[j][1]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.updateRendererColor();
|
||||
this.updateRendererAlpha();
|
||||
this.updateRendererVisible();
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.resetState = function(){
|
||||
this.setZ(this.shared.defaultZ);
|
||||
this.setColor(this.shared.defaultR, this.shared.defaultG, this.shared.defaultB);
|
||||
this.setAlpha(this.shared.defaultAlpha);
|
||||
this.setVisible(this.shared.defaultVisible);
|
||||
if(this.shared.type === gdjs.sk.SLOT_MESH){
|
||||
var verts = [];
|
||||
var updateList = [];
|
||||
for(var i=0; i<this.shared.defaultVertices.length; i++){
|
||||
verts.push([0, 0]);
|
||||
updateList.push(i);
|
||||
}
|
||||
this.setVertices(verts, updateList);
|
||||
}
|
||||
if(this.shared.type === gdjs.sk.SLOT_ARMATURE){
|
||||
this.childArmature.resetState();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.getZ = function(){
|
||||
return this.z;
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.setZ = function(z){
|
||||
this.z = z;
|
||||
if(this.shared.type === gdjs.sk.SLOT_IMAGE || this.shared.type === gdjs.sk.SLOT_MESH){
|
||||
this.renderer.setZ(z);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.getColor = function(){
|
||||
if(!this.armature.parentSlot){
|
||||
return [this.r, this.g, this.b];
|
||||
}
|
||||
|
||||
var armatureColor = this.armature.parentSlot.getColor();
|
||||
return [this.r * armatureColor[0] / 255,
|
||||
this.g * armatureColor[1] / 255,
|
||||
this.b * armatureColor[2] / 255];
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.setColor = function(r, g, b){
|
||||
if(this.r !== r || this.g !== g || this.b !== b){
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.updateRendererColor();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.updateRendererColor = function(){
|
||||
if(this.shared.type === gdjs.sk.SLOT_IMAGE || this.shared.type === gdjs.sk.SLOT_MESH){
|
||||
this.renderer.setColor(this.getColor());
|
||||
}
|
||||
else if(this.shared.type === gdjs.sk.SLOT_ARMATURE && this.childArmature){
|
||||
for(var i=0; i<this.childArmature.slots.length; i++){
|
||||
this.childArmature.slots[i].updateRendererColor();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.getAlpha = function(){
|
||||
if(!this.armature.parentSlot){
|
||||
return this.alpha;
|
||||
}
|
||||
var armatureAlpha = this.armature.parentSlot.getAlpha();
|
||||
return (this.alpha * armatureAlpha);
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.setAlpha = function(alpha){
|
||||
if(this.alpha !== alpha){
|
||||
this.alpha = alpha;
|
||||
this.updateRendererAlpha();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.updateRendererAlpha = function(){
|
||||
if(this.shared.type === gdjs.sk.SLOT_IMAGE || this.shared.type === gdjs.sk.SLOT_MESH){
|
||||
this.renderer.setAlpha(this.getAlpha());
|
||||
}
|
||||
else if(this.shared.type === gdjs.sk.SLOT_ARMATURE && this.childArmature){
|
||||
for(var i=0; i<this.childArmature.slots.length; i++){
|
||||
this.childArmature.slots[i].updateRendererAlpha();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.getVisible = function(){
|
||||
if(!this.armature.parentSlot){
|
||||
return this.visible;
|
||||
}
|
||||
return (this.visible && this.armature.parentSlot.getVisible());
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.setVisible = function(visible){
|
||||
if(this.visible !== visible){
|
||||
this.visible = visible;
|
||||
this.updateRendererVisible();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.updateRendererVisible = function(){
|
||||
if(this.shared.type === gdjs.sk.SLOT_IMAGE || this.shared.type === gdjs.sk.SLOT_MESH){
|
||||
this.renderer.setVisible(this.getVisible());
|
||||
}
|
||||
else if(this.shared.type === gdjs.sk.SLOT_ARMATURE && this.childArmature){
|
||||
for(var i=0; i<this.childArmature.slots.length; i++){
|
||||
this.childArmature.slots[i].updateRendererVisible();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Mesh only
|
||||
gdjs.sk.Slot.prototype.setVertices = function(vertices, updateList){
|
||||
var verts = [];
|
||||
for(var i=0; i<updateList.length; i++){
|
||||
this.vertices[updateList[i]] = [vertices[i][0] + this.shared.defaultVertices[updateList[i]][0],
|
||||
vertices[i][1] + this.shared.defaultVertices[updateList[i]][1]];
|
||||
verts.push(this.vertices[updateList[i]]);
|
||||
}
|
||||
this.renderer.setVertices(verts, updateList);
|
||||
}
|
||||
// Mesh only
|
||||
gdjs.sk.Slot.prototype.updateSkinning = function(){
|
||||
var verts = [];
|
||||
var updateList = [];
|
||||
var boneMatrices = [];
|
||||
var inverseWorldMatrix = this.worldMatrix.inverse();
|
||||
for(var i=0; i<this.skinBones.length; i++){
|
||||
var localBoneMatrix = inverseWorldMatrix.mul(this.skinBones[i].worldMatrix);
|
||||
boneMatrices.push(localBoneMatrix.mul(this.shared.skinBonesMatricesInverses[i]));
|
||||
}
|
||||
for(var i=0; i<this.shared.vertexWeights.length; i++){
|
||||
var vx = 0.0;
|
||||
var vy = 0.0;
|
||||
for(var j=0; j<this.shared.vertexWeights[i].length; j++){
|
||||
var v = boneMatrices[this.shared.vertexBones[i][j]].mulVec(this.vertices[i]);
|
||||
vx += this.shared.vertexWeights[i][j] * v[0];
|
||||
vy += this.shared.vertexWeights[i][j] * v[1];
|
||||
}
|
||||
verts.push([vx, vy]);
|
||||
updateList.push(i);
|
||||
}
|
||||
this.renderer.setVertices(verts, updateList);
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.getPolygons = function(){
|
||||
if(this.shared.type === gdjs.sk.SLOT_POLYGON){
|
||||
var worldPolygons = [];
|
||||
for(var i=0; i<this.shared.polygons.length; i++){
|
||||
worldPolygons.push(this.transformPolygon(this.shared.polygons[i]));
|
||||
}
|
||||
return worldPolygons;
|
||||
}
|
||||
return [this.transformPolygon(this.shared.aabb)];
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.update = function(){
|
||||
gdjs.sk.Transform.prototype.update.call(this);
|
||||
|
||||
if(this._updateRender && (this.shared.type === gdjs.sk.SLOT_IMAGE || this.shared.type === gdjs.sk.SLOT_MESH)){
|
||||
var transform = gdjs.sk.Transform.decomposeMatrix(this.worldMatrix);
|
||||
this.renderer.setTransform(transform);
|
||||
}
|
||||
|
||||
if(this._updateRender && this.debugRenderer){
|
||||
var transform = gdjs.sk.Transform.decomposeMatrix(this.worldMatrix);
|
||||
this.debugRenderer.setTransform(transform);
|
||||
}
|
||||
|
||||
this._updateRender = false;
|
||||
};
|
||||
|
||||
gdjs.sk.Slot.prototype.updateTransform = function(){
|
||||
if(this._updateMatrix || this._updateWorldMatrix){
|
||||
this._updateRender = true;
|
||||
}
|
||||
gdjs.sk.Transform.prototype.updateTransform.call(this);
|
||||
};
|
317
Extensions/SkeletonObject/Eskarmature.js
Normal file
@@ -0,0 +1,317 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @namespace gdjs.sk
|
||||
* @class SharedArmature
|
||||
*/
|
||||
gdjs.sk.SharedArmature = function(){
|
||||
this.name = "";
|
||||
this.bones = [];
|
||||
this.bonesMap = {};
|
||||
this.rootBone = -1;
|
||||
this.slots = [];
|
||||
this.slotsMap = {};
|
||||
this.animations = [];
|
||||
this.animationsMap = {};
|
||||
this.aabb = [];
|
||||
};
|
||||
|
||||
gdjs.sk.SharedArmature.prototype.loadDragonBones = function(armatureData, textures){
|
||||
this.name = armatureData.name;
|
||||
|
||||
var aabb = armatureData.aabb;
|
||||
this.aabb.push([aabb.x, aabb.y ]);
|
||||
this.aabb.push([aabb.x + aabb.width, aabb.y ]);
|
||||
this.aabb.push([aabb.x + aabb.width, aabb.y + aabb.height]);
|
||||
this.aabb.push([aabb.x, aabb.y + aabb.height]);
|
||||
|
||||
// Get all the bones
|
||||
for(var i=0; i<armatureData.bone.length; i++){
|
||||
var bone = new gdjs.sk.SharedBone();
|
||||
bone.loadDragonBones(armatureData.bone[i]);
|
||||
this.bones.push(bone);
|
||||
this.bonesMap[armatureData.bone[i].name] = i;
|
||||
}
|
||||
// Set bone parents
|
||||
for(var i=0; i<armatureData.bone.length; i++){
|
||||
if(armatureData.bone[i].hasOwnProperty("parent")){ // Child bone
|
||||
this.bones[i].parent = this.bonesMap[armatureData.bone[i].parent];
|
||||
this.bones[this.bones[i].parent].childBones.push(i);
|
||||
}
|
||||
else{ // Root bone
|
||||
this.rootBone = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all the slots
|
||||
for(var i=0; i<armatureData.slot.length; i++){
|
||||
var slot = new gdjs.sk.SharedSlot()
|
||||
slot.loadDragonBonesSlotData(armatureData.slot[i]);
|
||||
this.slots.push(slot);
|
||||
this.slotsMap[armatureData.slot[i].name] = i;
|
||||
this.slots[i].parent = this.bonesMap[armatureData.slot[i].parent];
|
||||
this.bones[this.slots[i].parent].childSlots.push(i);
|
||||
}
|
||||
// Generate displayers
|
||||
for(var i=0; i<armatureData.skin[0].slot.length; i++){
|
||||
var skinData = armatureData.skin[0].slot[i];
|
||||
var slot = this.slots[this.slotsMap[skinData.name]];
|
||||
slot.loadDragonBonesSkinData(armatureData.skin[0].slot, i);
|
||||
}
|
||||
|
||||
// Get all the animations
|
||||
for(var i=0; i<armatureData.animation.length; i++){
|
||||
var animation = new gdjs.sk.SharedAnimation();
|
||||
animation.loadDragonBones(armatureData.animation[i], armatureData.frameRate, this.slots);
|
||||
this.animations.push(animation);
|
||||
this.animationsMap[animation.name] = i;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The Armature holds the bones and slots/attachments as well as its animations.
|
||||
*
|
||||
* @namespace gdjs.sk
|
||||
* @class Armature
|
||||
* @extends gdjs.sk.Transform
|
||||
*/
|
||||
gdjs.sk.Armature = function(skeleton, parentArmature=null, parentSlot=null){
|
||||
gdjs.sk.Transform.call(this);
|
||||
|
||||
this.shared = null;
|
||||
this.skeleton = skeleton;
|
||||
this.parentArmature = parentArmature;
|
||||
this.parentSlot = parentSlot;
|
||||
this.bones = [];
|
||||
this.bonesMap = {};
|
||||
this.slots = [];
|
||||
this.slotsMap = {};
|
||||
this.animations = [];
|
||||
this.animationsMap = {};
|
||||
this.currentAnimation = -1;
|
||||
this.renderer = new gdjs.sk.ArmatureRenderer();
|
||||
this.debugRenderer = null;
|
||||
this.isRoot = false;
|
||||
};
|
||||
gdjs.sk.Armature.prototype = Object.create(gdjs.sk.Transform.prototype);
|
||||
|
||||
gdjs.sk.Armature.prototype.loadData = function(armatureData, skeletalData, debugPolygons){
|
||||
this.shared = armatureData;
|
||||
|
||||
if(debugPolygons){
|
||||
this.debugRenderer = new gdjs.sk.DebugRenderer();
|
||||
this.debugRenderer.loadVertices(this.shared.aabb, [100, 100, 255], false);
|
||||
}
|
||||
|
||||
// Get all the bones
|
||||
for(var i=0; i<this.shared.bones.length; i++){
|
||||
var bone = new gdjs.sk.Bone(this);
|
||||
bone.loadData(this.shared.bones[i]);
|
||||
this.bones.push(bone);
|
||||
this.bonesMap[bone.shared.name] = bone;
|
||||
}
|
||||
// With all the bones loaded, set parents
|
||||
for(var i=0; i<this.shared.bones.length; i++){
|
||||
if(this.shared.bones[i].parent !== -1){ // Child bone
|
||||
this.bones[this.shared.bones[i].parent].addChild(this.bones[i]);
|
||||
}
|
||||
else{ // Root bone
|
||||
this.addChild(this.bones[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Get all the slots
|
||||
for(var i=0; i<this.shared.slots.length; i++){
|
||||
var slot = new gdjs.sk.Slot(this);
|
||||
this.bones[this.shared.slots[i].parent].addChild(slot);
|
||||
slot.loadData(this.shared.slots[i], skeletalData, skeletalData.loader.textures, debugPolygons);
|
||||
this.slots.push(slot);
|
||||
this.slotsMap[slot.shared.name] = slot;
|
||||
}
|
||||
|
||||
// Get all the animations
|
||||
for(var i=0; i<this.shared.animations.length; i++){
|
||||
var animation = new gdjs.sk.Animation(this);
|
||||
animation.loadData(this.shared.animations[i]);
|
||||
this.animations.push(animation);
|
||||
this.animationsMap[animation.shared.name] = animation;
|
||||
}
|
||||
|
||||
this.setRenderers();
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.setAsRoot = function(){
|
||||
this.isRoot = true;
|
||||
// Create an empty shared data, in case nothing is loaded
|
||||
this.shared = new gdjs.sk.SharedArmature();
|
||||
this.shared.aabb = [[0,0], [0,0], [0,0], [0,0]];
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getRenderer = function(){
|
||||
return this.renderer;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getRendererObject = function(){
|
||||
return this.renderer.getRendererObject();
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.setRenderers = function(){
|
||||
for(var i=0; i<this.slots.length; i++){
|
||||
if(this.slots[i].shared.type === gdjs.sk.SLOT_IMAGE || this.slots[i].shared.type === gdjs.sk.SLOT_MESH){
|
||||
this.renderer.addRenderer(this.slots[i].renderer);
|
||||
if(this.slots[i].debugRenderer){
|
||||
this.renderer.addDebugRenderer(this.slots[i].debugRenderer);
|
||||
}
|
||||
}
|
||||
else if(this.slots[i].shared.type === gdjs.sk.SLOT_ARMATURE){
|
||||
this.renderer.addRenderer(this.slots[i].childArmature.renderer);
|
||||
if(this.slots[i].childArmature.debugRenderer){
|
||||
this.renderer.addDebugRenderer(this.slots[i].childArmature.debugRenderer);
|
||||
}
|
||||
}
|
||||
else if(this.slots[i].shared.type === gdjs.sk.SLOT_POLYGON){
|
||||
if(this.slots[i].debugRenderer){
|
||||
this.renderer.addDebugRenderer(this.slots[i].debugRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this.isRoot){
|
||||
this.renderer.addDebugRenderer(this.debugRenderer);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getAABB = function(){
|
||||
return this.transformPolygon(this.shared.aabb);
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getDefaultWidth = function(){
|
||||
return this.shared.aabb[1][0] - this.shared.aabb[0][0];
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getDefaultHeight = function(){
|
||||
return this.shared.aabb[2][1] - this.shared.aabb[1][1];
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.resetState = function(){
|
||||
for(var i=0; i<this.bones.length; i++){
|
||||
this.bones[i].resetState();
|
||||
}
|
||||
for(var i=0; i<this.slots.length; i++){
|
||||
this.slots[i].resetState();
|
||||
}
|
||||
this.renderer.sortRenderers();
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.updateZOrder = function(){
|
||||
this.renderer.sortRenderers();
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.update = function(){
|
||||
gdjs.sk.Transform.prototype.update.call(this);
|
||||
|
||||
if(this.debugRenderer){
|
||||
var transform = gdjs.sk.Transform.decomposeMatrix(this.worldMatrix);
|
||||
this.debugRenderer.setTransform(transform);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getCurrentAnimation = function(){
|
||||
if(this.currentAnimation >= 0 && this.currentAnimation < this.animations.length){
|
||||
return this.animations[this.currentAnimation];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.updateAnimation = function(delta){
|
||||
var animation = this.getCurrentAnimation();
|
||||
if(animation){
|
||||
animation.update(delta);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.isAnimationFinished = function(){
|
||||
var animation = this.getCurrentAnimation();
|
||||
return animation ? animation.isFinished() : false;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getAnimationTime = function(){
|
||||
var animation = this.getCurrentAnimation();
|
||||
return animation ? animation.getTime() : 0;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.setAnimationTime = function(time){
|
||||
var animation = this.getCurrentAnimation();
|
||||
if(animation){
|
||||
animation.setTime(time);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getAnimationTimeLength = function(){
|
||||
var animation = this.getCurrentAnimation();
|
||||
return animation ? animation.getTimeLength() : 0;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getAnimationFrame = function(){
|
||||
var animation = this.getCurrentAnimation();
|
||||
return animation ? animation.getFrame() : 0;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.setAnimationFrame = function(frame){
|
||||
var animation = this.getCurrentAnimation();
|
||||
if(animation){
|
||||
animation.setFrame(frame);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getAnimationFrameLength = function(){
|
||||
var animation = this.getCurrentAnimation();
|
||||
return animation ? animation.getFrameLength() : 0;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getAnimationIndex = function(){
|
||||
return this.currentAnimation;
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.setAnimationIndex = function(newAnimation, blendTime, loops){
|
||||
if(newAnimation >= 0 && newAnimation < this.animations.length && newAnimation !== this.currentAnimation){
|
||||
this.resetState();
|
||||
var oldAnimation = this.currentAnimation;
|
||||
this.currentAnimation = newAnimation;
|
||||
this.animations[this.currentAnimation].reset(loops);
|
||||
if(blendTime > 0 && oldAnimation >= 0 && oldAnimation < this.animations.length){
|
||||
this.animations[this.currentAnimation].blendFrom(this.animations[oldAnimation], blendTime);
|
||||
}
|
||||
var armatureAnimators = this.animations[this.currentAnimation].armatureAnimators;
|
||||
for(var i=0; i<armatureAnimators.length; i++){
|
||||
armatureAnimators[i].setFirstFrameAnimation(blendTime);
|
||||
}
|
||||
|
||||
this.animations[this.currentAnimation].update(0);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.getAnimationName = function(){
|
||||
var animation = this.getCurrentAnimation();
|
||||
return animation ? animation.shared.name : "";
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.setAnimationName = function(newAnimation, blendTime, loops){
|
||||
if(newAnimation in this.animationsMap){
|
||||
this.setAnimationIndex(this.animations.indexOf(this.animationsMap[newAnimation]), blendTime, loops);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.sk.Armature.prototype.resetAnimation = function(){
|
||||
var animation = this.getCurrentAnimation();
|
||||
if(animation){
|
||||
animation.reset();
|
||||
}
|
||||
};
|
678
Extensions/SkeletonObject/Extension.cpp
Normal file
@@ -0,0 +1,678 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
#include "SkeletonObject.h"
|
||||
|
||||
void DeclareSkeletonObjectExtension(gd::PlatformExtension & extension)
|
||||
{
|
||||
extension.SetExtensionInformation("SkeletonObject",
|
||||
_("Skeleton"),
|
||||
_("Enables the use of animated skeleton objects.\nCurrently supported formats:\n *DragonBones"),
|
||||
"Franco Maciel",
|
||||
"Open source (MIT License)");
|
||||
|
||||
gd::ObjectMetadata & obj = extension.AddObject<SkeletonObject>(
|
||||
"Skeleton",
|
||||
_("Skeleton"),
|
||||
_("Object animated through bones"),
|
||||
"JsPlatform/Extensions/skeletonicon.png");
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
SkeletonObject::LoadEdittimeIcon();
|
||||
#endif
|
||||
|
||||
// Object instructions
|
||||
obj.AddCondition("ScaleX",
|
||||
_("Scale X"),
|
||||
_("Check the object scale X."),
|
||||
_("Current scale X of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetScaleX",
|
||||
_("Scale X"),
|
||||
_("Change the object scale X."),
|
||||
_("Set _PARAM0_ scale X _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("ScaleX", _("Scale X"), _("Object scale X"), _("Size"), "JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("ScaleY",
|
||||
_("Scale Y"),
|
||||
_("Check the object scale Y."),
|
||||
_("Current scale Y of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetScaleY",
|
||||
_("Scale Y"),
|
||||
_("Change the object scale Y."),
|
||||
_("Set _PARAM0_ scale Y _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("ScaleY", _("Scale Y"), _("Object scale Y"), _("Size"), "JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("Width",
|
||||
_("Width"),
|
||||
_("Check the object width."),
|
||||
_("Current width of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetWidth",
|
||||
_("Width"),
|
||||
_("Change the object width."),
|
||||
_("Set _PARAM0_ width _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("Width", _("Width"), _("Object width"), _("Size"), "JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("Height",
|
||||
_("Height"),
|
||||
_("Check the object height."),
|
||||
_("Current height of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetHeight",
|
||||
_("Height"),
|
||||
_("Change the object height."),
|
||||
_("Set _PARAM0_ height _PARAM1__PARAM2_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("Height", _("Height"), _("Object height"), _("Size"), "JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddAction("SetDefaultHitbox",
|
||||
_("Default hitbox"),
|
||||
_("Change the object default hitbox to be used by other conditions and behaviors."),
|
||||
_("Set _PARAM0_ default hitbox to _PARAM1_"),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/skeletonicon24.png",
|
||||
"JsPlatform/Extensions/skeletonicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Slot path")).SetDefaultValue("\"\"");
|
||||
|
||||
// Animation instructions
|
||||
obj.AddCondition("AnimationPaused",
|
||||
_("Paused"),
|
||||
_("Test if the animation for the skeleton is paused"),
|
||||
_("Animation of _PARAM0_ is paused"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddAction("PauseAnimation",
|
||||
_("Pause"),
|
||||
_("Pauses animation for the skeleton"),
|
||||
_("Pause animation for _PARAM0_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddCodeOnlyParameter("yesorno", "").SetDefaultValue("true");
|
||||
|
||||
obj.AddAction("UnpauseAnimation",
|
||||
_("Unpause"),
|
||||
_("Unpauses animation for the skeleton"),
|
||||
_("Unpause animation for _PARAM0_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddCodeOnlyParameter("yesorno", "").SetDefaultValue("false");
|
||||
|
||||
obj.AddCondition("AnimationFinished",
|
||||
_("Finished"),
|
||||
_("Test if the animation has finished on this frame"),
|
||||
_("Animation of _PARAM0_ has finished"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("AnimationTime",
|
||||
_("Current time"),
|
||||
_("Check the current animation elapsed time."),
|
||||
_("Current animation time of _PARAM0_ is _PARAM1_ _PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetAnimationTime",
|
||||
_("Current time"),
|
||||
_("Change the current animation elapsed time."),
|
||||
_("Set _PARAM0_ current animation time _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("AnimationTime", _("Current time"), _("Current animation elapsed time"), _("Animation"), "JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddExpression("AnimationTimeLength", _("Animation time length"), _("Current animation time length"), _("Animation"), "JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("AnimationFrame",
|
||||
_("Current frame"),
|
||||
_("Check the current animation frame.\nIf the animation is set as smooth, a float can be (and probably will be) returned."),
|
||||
_("Current animation frame of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetAnimationFrame",
|
||||
_("Current frame"),
|
||||
_("Change the current animation frame"),
|
||||
_("Set _PARAM0_ current animation frame _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("AnimationFrame", _("Current frame"), _("Current animation frame"), _("Animation"), "JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddExpression("AnimationFrameLength", _("Animation frame length"), _("Current animation frame length"), _("Animation"), "JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("AnimationIndex",
|
||||
_("Animation index"),
|
||||
_("Check the current animation index.\nIf not sure about the index, you can use the \"by name\" action"),
|
||||
_("Current animation of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetAnimationIndex",
|
||||
_("Animation index"),
|
||||
_("Change the current animation from the animation index.\nIf not sure about the index, you can use the \"by name\" action"),
|
||||
_("Set _PARAM0_ animation _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.AddParameter("expression", _("Blend time (0 for automatic blending)"), "", true).SetDefaultValue("0")
|
||||
.AddParameter("expression", _("Loops (0 for infinite loops)"), "", true).SetDefaultValue("-1")
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("AnimationIndex", _("Animation index"), _("Current animation index"), _("Animation"), "JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("AnimationName",
|
||||
_("Animation name"),
|
||||
_("Check the current animation name."),
|
||||
_("Current animation of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("string", _("Text"))
|
||||
.SetManipulatedType("string");
|
||||
|
||||
obj.AddAction("SetAnimationName",
|
||||
_("Animation name"),
|
||||
_("Change the current animation from the animation name."),
|
||||
_("Set _PARAM0_ animation to _PARAM1_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Text"))
|
||||
.AddParameter("expression", _("Blend time (0 for automatic blending)"), "", true).SetDefaultValue("0")
|
||||
.AddParameter("expression", _("Loops (0 for infinite loops)"), "", true).SetDefaultValue("-1");
|
||||
|
||||
obj.AddStrExpression("AnimationName", _("Animation name"), _("Current animation name"), _("Animation"), "JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddCondition("AnimationSmooth",
|
||||
_("Smooth"),
|
||||
_("Check if the object animation interpolator is smooth."),
|
||||
_("Animation mode of _PARAM0_ is smooth"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddAction("SetAnimationSmooth",
|
||||
_("Smooth"),
|
||||
_("Change the object animation interpolator."),
|
||||
_("Set animation mode of _PARAM0_ as smooth: _PARAM1_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("yesorno", _("Smooth"));
|
||||
|
||||
obj.AddCondition("AnimationTimeScale",
|
||||
_("Time scale"),
|
||||
_("Check the animation time scale."),
|
||||
_("Animation time scale of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetAnimationTimeScale",
|
||||
_("Time scale"),
|
||||
_("Change the animation time scale"),
|
||||
_("Set _PARAM0_ animation time scale _PARAM1__PARAM2_"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("AnimationTimeScale", _("Time scale"), _("Animation time scale"), _("Animation"), "JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
obj.AddAction("ResetAnimation",
|
||||
_("Reset"),
|
||||
_("Reset current animation"),
|
||||
_("Reset _PARAM0_ current animation"),
|
||||
_("Animation"),
|
||||
"JsPlatform/Extensions/skeletonanimationicon24.png",
|
||||
"JsPlatform/Extensions/skeletonanimationicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton");
|
||||
|
||||
// Bone instructions
|
||||
obj.AddCondition("BonePositionX",
|
||||
_("Position X"),
|
||||
_("Check the bone position X."),
|
||||
_("Current position X of _PARAM0_:_PARAM1_ is _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetBonePositionX",
|
||||
_("Position X"),
|
||||
_("Change the bone position X."),
|
||||
_("Set _PARAM0_:_PARAM1_ position X _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("BonePositionX", _("Position X"), _("Bone position X"), _("Bone"), "JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"");
|
||||
|
||||
obj.AddCondition("BonePositionY",
|
||||
_("Position Y"),
|
||||
_("Check the bone position Y."),
|
||||
_("Current position Y of _PARAM0_:_PARAM1_ is _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetBonePositionY",
|
||||
_("Position Y"),
|
||||
_("Change the bone position Y."),
|
||||
_("Set _PARAM0_:_PARAM1_ position Y _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("BonePositionY", _("Position Y"), _("Bone position Y"), _("Bone"), "JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"");
|
||||
|
||||
obj.AddAction("SetBonePosition",
|
||||
_("Position"),
|
||||
_("Change the bone position."),
|
||||
_("Set _PARAM0_:_PARAM1_ position X _PARAM2__PARAM3_; Y _PARAM4__PARAM5_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Position X"))
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Position Y"));
|
||||
|
||||
obj.AddCondition("BoneAngle",
|
||||
_("Angle"),
|
||||
_("Check the bone angle (in degrees)."),
|
||||
_("Current angle of _PARAM0_:_PARAM1_ is _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetBoneAngle",
|
||||
_("Angle"),
|
||||
_("Change the bone angle (in degrees)."),
|
||||
_("Set _PARAM0_:_PARAM1_ angle _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("BoneAngle", _("Angle"), _("Slot angle (in degrees)"), _("Bone"), "JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"");
|
||||
|
||||
obj.AddCondition("BoneScaleX",
|
||||
_("Scale X"),
|
||||
_("Check the bone scale X."),
|
||||
_("Current scale X of _PARAM0_:_PARAM1_ is _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetBoneScaleX",
|
||||
_("Scale X"),
|
||||
_("Change the bone scale X."),
|
||||
_("Set _PARAM0_:_PARAM1_ scale X _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("BoneScaleX", _("Scale X"), _("Slot scale X"), _("Bone"), "JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"");
|
||||
|
||||
obj.AddCondition("BoneScaleY",
|
||||
_("Scale Y"),
|
||||
_("Check the bone scale Y."),
|
||||
_("Current scale Y of _PARAM0_:_PARAM1_ is _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetBoneScaleY",
|
||||
_("Scale Y"),
|
||||
_("Change the bone scale Y."),
|
||||
_("Set _PARAM0_:_PARAM1_ scale Y _PARAM2__PARAM3_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("BoneScaleY", _("Scale Y"), _("Slot scale Y"), _("Bone"), "JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"");
|
||||
|
||||
obj.AddAction("SetBoneScale",
|
||||
_("Scale"),
|
||||
_("Change the bone scale."),
|
||||
_("Set _PARAM0_:_PARAM1_ scale X _PARAM2__PARAM3_; Y _PARAM4__PARAM5_"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Scale X"))
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Scale Y"));
|
||||
|
||||
obj.AddAction("ResetBone",
|
||||
_("Reset"),
|
||||
_("Reset the bone transformation."),
|
||||
_("Reset _PARAM0_:_PARAM1_ transformation"),
|
||||
_("Bone"),
|
||||
"JsPlatform/Extensions/skeletonboneicon24.png",
|
||||
"JsPlatform/Extensions/skeletonboneicon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Bone path")).SetDefaultValue("\"\"");
|
||||
|
||||
// Slot instructions
|
||||
obj.AddAction("SetSlotColor",
|
||||
_("Color"),
|
||||
_("Change the slot color."),
|
||||
_("Set _PARAM0_:_PARAM1_ color to _PARAM2_"),
|
||||
_("Slot"),
|
||||
"JsPlatform/Extensions/skeletonsloticon24.png",
|
||||
"JsPlatform/Extensions/skeletonsloticon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Sloth path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("color", _("Color"));
|
||||
|
||||
obj.AddCondition("SlotVisible",
|
||||
_("Visible"),
|
||||
_("Check the slot visibility."),
|
||||
_("_PARAM0_:_PARAM1_ is visible"),
|
||||
_("Slot"),
|
||||
"JsPlatform/Extensions/skeletonsloticon24.png",
|
||||
"JsPlatform/Extensions/skeletonsloticon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Slot path")).SetDefaultValue("\"\"");
|
||||
|
||||
obj.AddAction("ShowSlot",
|
||||
_("Show"),
|
||||
_("Show the slot, making it visible."),
|
||||
_("Show _PARAM0_:_PARAM1_"),
|
||||
_("Slot"),
|
||||
"JsPlatform/Extensions/skeletonsloticon24.png",
|
||||
"JsPlatform/Extensions/skeletonsloticon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Slot path")).SetDefaultValue("\"\"")
|
||||
.AddCodeOnlyParameter("yesorno", "").SetDefaultValue("true");
|
||||
|
||||
obj.AddAction("HideSlot",
|
||||
_("Hide"),
|
||||
_("Hide the slot, making it invisible."),
|
||||
_("Hide _PARAM0_:_PARAM1_"),
|
||||
_("Slot"),
|
||||
"JsPlatform/Extensions/skeletonsloticon24.png",
|
||||
"JsPlatform/Extensions/skeletonsloticon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Slot path")).SetDefaultValue("\"\"")
|
||||
.AddCodeOnlyParameter("yesorno", "").SetDefaultValue("false");
|
||||
|
||||
obj.AddCondition("SlotZOrder",
|
||||
_("Z-order"),
|
||||
_("Check the slot Z-order."),
|
||||
_("Z-order of _PARAM0_:_PARAM1_ is _PARAM2__PARAM3_"),
|
||||
_("Slot"),
|
||||
"JsPlatform/Extensions/skeletonsloticon24.png",
|
||||
"JsPlatform/Extensions/skeletonsloticon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Slot path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("SetSlotZOrder",
|
||||
_("Z-order"),
|
||||
_("Change the slot Z-order."),
|
||||
_("Set _PARAM0_:_PARAM1_ Z-order _PARAM2__PARAM3_"),
|
||||
_("Slot"),
|
||||
"JsPlatform/Extensions/skeletonsloticon24.png",
|
||||
"JsPlatform/Extensions/skeletonsloticon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Slot path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("SlotZOrder", _("Z-order"), _("Slot Z-order"), _("Slot"), "JsPlatform/Extensions/skeletonsloticon16.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Sloth path")).SetDefaultValue("\"\"");
|
||||
|
||||
obj.AddCondition("PointInsideSlot",
|
||||
_("Point inside slot"),
|
||||
_("Check if the point is inside the slot"),
|
||||
_("The point _PARAM2_;_PARAM3_ is inside _PARAM0_:_PARAM1_"),
|
||||
_("Collision"),
|
||||
"res/conditions/collisionPoint24.png",
|
||||
"res/conditions/collisionPoint.png")
|
||||
.AddParameter("object", _("Object"), "Skeleton")
|
||||
.AddParameter("string", _("Sloth path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Point X"))
|
||||
.AddParameter("expression", _("Point Y"));
|
||||
|
||||
// Extension instructions
|
||||
extension.AddCondition("SlotCollidesWithObject",
|
||||
_("Slot collides with object"),
|
||||
_("Check if the slot collides with an object"),
|
||||
_("_PARAM0_:_PARAM1_ collides with _PARAM2_"),
|
||||
_("Collision"),
|
||||
"res/conditions/collision24.png",
|
||||
"res/conditions/collision.png")
|
||||
.AddParameter("objectList", _("Skeleton"), "Skeleton")
|
||||
.AddParameter("string", _("Sloth path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.AddCodeOnlyParameter("conditionInverted", "");
|
||||
|
||||
extension.AddCondition("SlotCollidesWithSlot",
|
||||
_("Slot collides with slot"),
|
||||
_("Check if the slot collides with another skeleton slot"),
|
||||
_("_PARAM0_:_PARAM1_ collides with _PARAM2_:_PARAM3_"),
|
||||
_("Collision"),
|
||||
"res/conditions/collision24.png",
|
||||
"res/conditions/collision.png")
|
||||
.AddParameter("objectList", _("Skeleton"), "Skeleton")
|
||||
.AddParameter("string", _("Sloth path")).SetDefaultValue("\"\"")
|
||||
.AddParameter("objectList", _("Other skeleton"), "Skeleton")
|
||||
.AddParameter("string", _("Sloth path")).SetDefaultValue("\"\"")
|
||||
.AddCodeOnlyParameter("conditionInverted", "");
|
||||
|
||||
extension.AddCondition("RaycastSlot",
|
||||
_("Raycast slot"),
|
||||
_("Same as Raycast, but intersects specific slots instead."),
|
||||
_("Raycast _PARAM0_:_PARAM1_ from _PARAM2_;_PARAM3_"),
|
||||
_("Collision"),
|
||||
"res/conditions/collision24.png",
|
||||
"res/conditions/collision.png")
|
||||
.AddParameter("objectList", _("Skeleton to test against the ray"), "Skeleton")
|
||||
.AddParameter("string", _("Sloth path")).SetDefaultValue("\"\"")
|
||||
.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();
|
||||
}
|
1394
Extensions/SkeletonObject/Fskanimation.js
Normal file
451
Extensions/SkeletonObject/Gskeletonruntimeobject.js
Normal file
@@ -0,0 +1,451 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The SkeletonRuntimeObject imports and displays skeletal animations files.
|
||||
*
|
||||
* @namespace gdjs
|
||||
* @class SkeletonRuntimeObject
|
||||
* @extends RuntimeObject
|
||||
*/
|
||||
gdjs.SkeletonRuntimeObject = function(runtimeScene, objectData){
|
||||
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
|
||||
|
||||
this.rootArmature = new gdjs.sk.Armature(this);
|
||||
this.rootArmature.getRenderer().putInScene(this, runtimeScene);
|
||||
this.rootArmature.setAsRoot();
|
||||
this.animationPlaying = true;
|
||||
this.animationSmooth = true;
|
||||
this.timeScale = 1.0;
|
||||
this.scaleX = 1.0;
|
||||
this.scaleY = 1.0;
|
||||
this.hitboxSlot = null;
|
||||
|
||||
this.manager = gdjs.SkeletonObjectsManager.getManager(runtimeScene);
|
||||
this.getSkeletonData(runtimeScene, objectData);
|
||||
};
|
||||
gdjs.SkeletonRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
|
||||
gdjs.SkeletonRuntimeObject.thisIsARuntimeObjectConstructor = "SkeletonObject::Skeleton";
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.extraInitializationFromInitialInstance = function(initialInstanceData) {
|
||||
if(initialInstanceData.customSize){
|
||||
this.setWidth(initialInstanceData.width);
|
||||
this.setHeight(initialInstanceData.height);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getSkeletonData = function(runtimeScene, objectData){
|
||||
var skeletonData = this.manager.getSkeleton(runtimeScene, this.name, objectData);
|
||||
|
||||
if(skeletonData.armatures.length > 0){
|
||||
this.rootArmature.loadData(skeletonData.armatures[skeletonData.rootArmature],
|
||||
skeletonData,
|
||||
objectData.debugPolygons);
|
||||
|
||||
this.rootArmature.resetState();
|
||||
}
|
||||
};
|
||||
|
||||
// RuntimeObject overwrites
|
||||
gdjs.SkeletonRuntimeObject.prototype.setX = function(x){
|
||||
this.x = x;
|
||||
this.rootArmature.setX(x);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setY = function(y){
|
||||
this.y = y;
|
||||
this.rootArmature.setY(y);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAngle = function(angle){
|
||||
this.angle = angle;
|
||||
this.rootArmature.setRot(angle);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getRendererObject = function(){
|
||||
return this.rootArmature.getRendererObject();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getHitBoxes = function(){
|
||||
if(this.hitboxSlot){
|
||||
return this.hitboxSlot.getPolygons();
|
||||
}
|
||||
return [this.rootArmature.getAABB()];
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.stepBehaviorsPreEvents = function(runtimeScene){
|
||||
var delta = this.getElapsedTime(runtimeScene) / 1000.0;
|
||||
if(this.animationPlaying){
|
||||
this.rootArmature.updateAnimation(delta*this.timeScale);
|
||||
}
|
||||
|
||||
gdjs.RuntimeObject.prototype.stepBehaviorsPreEvents.call(this, runtimeScene);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.update = function(runtimeScene){
|
||||
this.rootArmature.update();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getDrawableX = function(){
|
||||
return this.getX() - this.rootArmature.shared.aabb[0][0] * Math.abs(this.scaleX);
|
||||
};
|
||||
gdjs.SkeletonRuntimeObject.prototype.getDrawableY = function(){
|
||||
return this.getY() - this.rootArmature.shared.aabb[0][1] * Math.abs(this.scaleY);
|
||||
};
|
||||
|
||||
// Object instructions
|
||||
gdjs.SkeletonRuntimeObject.prototype.getScaleX = function(){
|
||||
return this.scaleX;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setScaleX = function(scaleX){
|
||||
this.scaleX = scaleX;
|
||||
this.rootArmature.setSx(scaleX);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getScaleY = function(){
|
||||
return this.scaleY;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setScaleY = function(scaleY){
|
||||
this.scaleY = scaleY;
|
||||
this.rootArmature.setSy(scaleY);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getWidth = function(){
|
||||
return this.rootArmature.getDefaultWidth() * Math.abs(this.scaleX);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setWidth = function(width){
|
||||
if(width < 0) width = 0;
|
||||
this.setScaleX(width / this.rootArmature.getDefaultWidth());
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getHeight = function(){
|
||||
return this.rootArmature.getDefaultHeight() * Math.abs(this.scaleY);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setHeight = function(height){
|
||||
if(height < 0) height = 0;
|
||||
this.setScaleY(height / this.rootArmature.getDefaultHeight());
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setDefaultHitbox = function(slotPath){
|
||||
if(slotPath === ""){
|
||||
this.hitboxSlot = null;
|
||||
return;
|
||||
}
|
||||
var slot = this.getSlot(slotPath);
|
||||
if(slot){
|
||||
this.hitboxSlot = slot;
|
||||
}
|
||||
};
|
||||
|
||||
// Animation instructions
|
||||
gdjs.SkeletonRuntimeObject.prototype.isAnimationPaused = function(){
|
||||
return !this.animationPlaying;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAnimationPaused = function(paused){
|
||||
this.animationPlaying = !paused;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.isAnimationFinished = function(){
|
||||
return this.rootArmature.isAnimationFinished();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getAnimationTime = function(){
|
||||
return this.rootArmature.getAnimationTime();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAnimationTime = function(time){
|
||||
this.rootArmature.setAnimationTime(time);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getAnimationTimeLength = function(){
|
||||
return this.rootArmature.getAnimationTimeLength();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getAnimationFrame = function(){
|
||||
return this.rootArmature.getAnimationFrame();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAnimationFrame = function(frame){
|
||||
this.rootArmature.setAnimationFrame(frame);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getAnimationFrameLength = function(){
|
||||
return this.rootArmature.getAnimationFrameLength();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getAnimationIndex = function(){
|
||||
return this.rootArmature.getAnimationIndex();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAnimationIndex = function(newAnimation, blendTime=0, loops=-1){
|
||||
this.rootArmature.setAnimationIndex(newAnimation, blendTime, loops);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getAnimationName = function(){
|
||||
return this.rootArmature.getAnimationName();
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAnimationName = function(newAnimation, blendTime=0, loops=-1){
|
||||
this.rootArmature.setAnimationName(newAnimation, blendTime, loops);
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.isAnimationSmooth = function(){
|
||||
return this.animationSmooth;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAnimationSmooth = function(smooth){
|
||||
this.animationSmooth = smooth;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getAnimationTimeScale = function(){
|
||||
return this.timeScale;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setAnimationTimeScale = function(timeScale){
|
||||
if(timeScale < 0) timeScale = 0; // Support negative timeScale (backward animation) ?
|
||||
this.timeScale = timeScale;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.resetAnimation = function(){
|
||||
this.rootArmature.resetAnimation();
|
||||
};
|
||||
|
||||
// Bone instructions
|
||||
gdjs.SkeletonRuntimeObject.prototype.getBoneX = function(bonePath){
|
||||
var bone = this.getBone(bonePath);
|
||||
return bone ? bone.getGlobalX() : 0;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setBoneX = function(bonePath, x){
|
||||
var bone = this.getBone(bonePath);
|
||||
if(bone){
|
||||
bone.setGlobalX(x);
|
||||
bone.update();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getBoneY = function(bonePath){
|
||||
var bone = this.getBone(bonePath);
|
||||
return bone ? bone.getGlobalY() : 0;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setBoneY = function(bonePath, y){
|
||||
var bone = this.getBone(bonePath);
|
||||
if(bone){
|
||||
bone.setGlobalY(y);
|
||||
bone.update();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getBoneAngle = function(bonePath){
|
||||
var bone = this.getBone(bonePath);
|
||||
return bone ? bone.getGlobalRot() : 0;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setBoneAngle = function(bonePath, angle){
|
||||
var bone = this.getBone(bonePath);
|
||||
if(bone){
|
||||
bone.setGlobalRot(angle);
|
||||
bone.update();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getBoneScaleX = function(bonePath){
|
||||
var bone = this.getBone(bonePath);
|
||||
return bone ? bone.getSx() : 0;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setBoneScaleX = function(bonePath, scaleX){
|
||||
var bone = this.getBone(bonePath);
|
||||
if(bone){
|
||||
bone.setSx(scaleX);
|
||||
bone.update();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getBoneScaleY = function(bonePath){
|
||||
var bone = this.getBone(bonePath);
|
||||
return bone ? bone.getSy() : 0;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setBoneScaleY = function(bonePath, scaleY){
|
||||
var bone = this.getBone(bonePath);
|
||||
if(bone){
|
||||
bone.setSy(scaleY);
|
||||
bone.update();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.resetBone = function(bonePath){
|
||||
var bone = this.getBone(bonePath);
|
||||
if(bone){
|
||||
bone.resetState();
|
||||
}
|
||||
};
|
||||
|
||||
// Slot instructions
|
||||
gdjs.SkeletonRuntimeObject.prototype.setSlotColor = function(slotPath, color){
|
||||
var slot = this.getSlot(slotPath);
|
||||
if(slot){
|
||||
var rgb = color.split(";");
|
||||
if(rgb.length < 3) return;
|
||||
slot.setColor(...rgb);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.isSlotVisible = function(slotPath){
|
||||
var slot = this.getSlot(slotPath);
|
||||
return slot ? slot.getVisible() : false;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setSlotVisible = function(slotPath, visible){
|
||||
var slot = this.getSlot(slotPath);
|
||||
if(slot){
|
||||
slot.setVisible(visible);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getSlotZOrder = function(slotPath){
|
||||
var slot = this.getSlot(slotPath);
|
||||
return slot ? slot.getZ() : 0;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.setSlotZOrder = function(slotPath, z){
|
||||
var slot = this.getSlot(slotPath);
|
||||
if(slot){
|
||||
slot.setZ(z);
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.isPointInsideSlot = function(slotPath, x, y){
|
||||
var hitBoxes = this.getPolygons(slotPath);
|
||||
if(!hitBoxes) return false;
|
||||
|
||||
for(var i = 0; i < this.hitBoxes.length; ++i) {
|
||||
if ( gdjs.Polygon.isPointInside(hitBoxes[i], x, y) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Extension instructions
|
||||
gdjs.SkeletonRuntimeObject.prototype.raycastSlot = function(slotPath, x, y, angle, dist, closest){
|
||||
var result = gdjs.Polygon.raycastTest._statics.result;
|
||||
result.collision = false;
|
||||
|
||||
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.getPolygons(slotPath);
|
||||
if(!hitBoxes) return result;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
// Warning!, assuming gdjs.evtTools.object.twoListsTest calls the predicate
|
||||
// respecting the given objects lists paramenters order
|
||||
gdjs.SkeletonRuntimeObject.slotObjectCollisionTest = function(skl, obj, slotPath){
|
||||
var hitBoxes1 = skl.getPolygons(slotPath);
|
||||
if(!hitBoxes1) return false;
|
||||
|
||||
var hitBoxes2 = obj.getHitBoxes();
|
||||
for(var k=0, lenBoxes1=hitBoxes1.length; k<lenBoxes1; ++k){
|
||||
for(var l=0, lenBoxes2=hitBoxes2.length; l<lenBoxes2; ++l){
|
||||
if (gdjs.Polygon.collisionTest(hitBoxes1[k], hitBoxes2[l]).collision){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.slotSlotCollisionTest = function(skl1, skl2, slotPaths){
|
||||
var hitBoxes1 = skl1.getPolygons(slotPaths[0]);
|
||||
var hitBoxes2 = skl2.getPolygons(slotPaths[1]);
|
||||
if(!hitBoxes1 || !hitBoxes2) return false;
|
||||
|
||||
for(var k=0, lenBoxes1=hitBoxes1.length; k<lenBoxes1; ++k){
|
||||
for(var l=0, lenBoxes2=hitBoxes2.length; l<lenBoxes2; ++l){
|
||||
if (gdjs.Polygon.collisionTest(hitBoxes1[k], hitBoxes2[l]).collision){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Helpers
|
||||
gdjs.SkeletonRuntimeObject.prototype.getSlot = function(slotPath){
|
||||
var slotArray = slotPath.split("/");
|
||||
var currentSlot = null;
|
||||
if(slotArray[0] in this.rootArmature.slotsMap){
|
||||
currentSlot = this.rootArmature.slotsMap[slotArray[0]];
|
||||
for(var i=1; i<slotArray.length; i++){
|
||||
if(currentSlot.type === gdjs.sk.SLOT_ARMATURE &&
|
||||
slotArray[i] in currentSlot.childArmature.slotsMap){
|
||||
currentSlot = currentSlot.childArmature.slotsMap[slotArray[i]];
|
||||
}
|
||||
else{
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentSlot;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getBone = function(bonePath){
|
||||
var slotArray = bonePath.split("/");
|
||||
var boneName = slotArray.pop();
|
||||
|
||||
if(slotArray.length === 0 && boneName in this.rootArmature.bonesMap){
|
||||
return this.rootArmature.bonesMap[boneName];
|
||||
}
|
||||
|
||||
var slot = this.getSlot(slotArray.join("/"));
|
||||
if(slot && slot.type === gdjs.sk.SLOT_ARMATURE && boneName in slot.childArmature.bonesMap){
|
||||
return slot.childArmature.bonesMap[boneName];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.getPolygons = function(slotPath){
|
||||
if(slotPath === ""){
|
||||
return this.rootArmature.getHitBoxes();
|
||||
}
|
||||
|
||||
var slot = this.getSlot(slotPath);
|
||||
if(slot){
|
||||
return slot.getPolygons();
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
53
Extensions/SkeletonObject/Hskmanager.js
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
gdjs.SkeletonObjectsManager = function(){
|
||||
// List of loaded skeletons per object type
|
||||
this.loadedObjects = {};
|
||||
};
|
||||
|
||||
gdjs.SkeletonObjectsManager.getManager = function(runtimeScene){
|
||||
if( !runtimeScene.skeletonObjectsManager ){
|
||||
runtimeScene.skeletonObjectsManager = new gdjs.SkeletonObjectsManager();
|
||||
}
|
||||
|
||||
return runtimeScene.skeletonObjectsManager;
|
||||
};
|
||||
|
||||
gdjs.SkeletonObjectsManager.prototype.getSkeleton = function(runtimeScene, objectName, objectData){
|
||||
if( !(objectName in this.loadedObjects) ){
|
||||
this.loadedObjects[objectName] = this.loadSkeleton(runtimeScene, objectData);
|
||||
}
|
||||
|
||||
return this.loadedObjects[objectName];
|
||||
};
|
||||
|
||||
gdjs.SkeletonObjectsManager.prototype.loadSkeleton = function(runtimeScene, objectData){
|
||||
var loader = new gdjs.sk.DataLoader();
|
||||
var skeletalData = loader.getData(objectData.skeletalDataFilename);
|
||||
var skeleton = {"loader": loader,
|
||||
"armatures": [],
|
||||
"rootArmature": 0};
|
||||
|
||||
if(!skeletalData) return skeleton;
|
||||
|
||||
if(objectData.apiName === "DragonBones"){
|
||||
// Load sub-textures
|
||||
loader.loadDragonBones(runtimeScene, objectData);
|
||||
// Load the root armature with the given name
|
||||
for(var i=0; i<skeletalData.armature.length; i++){
|
||||
var armature = new gdjs.sk.SharedArmature();
|
||||
armature.loadDragonBones(skeletalData.armature[i]);
|
||||
skeleton.armatures.push(armature);
|
||||
if(armature.name === objectData.rootArmatureName){
|
||||
skeleton.rootArmature = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return skeleton;
|
||||
};
|
57
Extensions/SkeletonObject/Isk-tools.js
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
gdjs.sk.slotObjectCollision = function(objectsLists1, slotPath, objectsLists2, inverted){
|
||||
return gdjs.evtTools.object.twoListsTest(gdjs.SkeletonRuntimeObject.slotObjectCollisionTest,
|
||||
objectsLists1, objectsLists2, inverted, slotPath);
|
||||
};
|
||||
|
||||
gdjs.sk.slotSlotCollision = function(objectsLists1, slotPath1, objectsLists2, slotPath2, inverted){
|
||||
return gdjs.evtTools.object.twoListsTest(gdjs.SkeletonRuntimeObject.slotSlotCollisionTest,
|
||||
objectsLists1, objectsLists2, inverted, [slotPath1, slotPath2]);
|
||||
};
|
||||
|
||||
gdjs.sk.raycastSlot = function(objectsLists, slotPath, 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.sk.raycastSlot);
|
||||
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.raycastSlot(slotPath, 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;
|
||||
};
|
159
Extensions/SkeletonObject/JsExtension.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
|
||||
#include "SkeletonObject.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void DeclareSkeletonObjectExtension(gd::PlatformExtension & extension);
|
||||
|
||||
/**
|
||||
* \brief This class declares information about the JS extension.
|
||||
*/
|
||||
class SkeletonObjectJsExtension : public gd::PlatformExtension
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
||||
*/
|
||||
SkeletonObjectJsExtension()
|
||||
{
|
||||
DeclareSkeletonObjectExtension(*this);
|
||||
|
||||
GetObjectMetadata("SkeletonObject::Skeleton")
|
||||
.SetIncludeFile("Extensions/SkeletonObject/Isk-tools.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Hskmanager.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Gskeletonruntimeobject.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Fskanimation.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Eskarmature.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Dskslot.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Cskbone.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Bskeletonruntimeobject-cocos-renderer.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Bskeletonruntimeobject-pixi-renderer.js")
|
||||
.AddIncludeFile("Extensions/SkeletonObject/Ask.js");
|
||||
|
||||
auto & actions = GetAllActionsForObject("SkeletonObject::Skeleton");
|
||||
auto & conditions = GetAllConditionsForObject("SkeletonObject::Skeleton");
|
||||
auto & expressions = GetAllExpressionsForObject("SkeletonObject::Skeleton");
|
||||
auto & strExpressions = GetAllStrExpressionsForObject("SkeletonObject::Skeleton");
|
||||
|
||||
// Object instructions
|
||||
conditions["SkeletonObject::ScaleX"].SetFunctionName("getScaleX");
|
||||
actions["SkeletonObject::SetScaleX"].SetFunctionName("setScaleX").SetGetter("getScaleX");
|
||||
expressions["ScaleX"].SetFunctionName("getScaleX");
|
||||
|
||||
conditions["SkeletonObject::ScaleY"].SetFunctionName("getScaleY");
|
||||
actions["SkeletonObject::SetScaleY"].SetFunctionName("setScaleY").SetGetter("getScaleY");
|
||||
expressions["ScaleY"].SetFunctionName("getScaleY");
|
||||
|
||||
conditions["SkeletonObject::Width"].SetFunctionName("getWidth");
|
||||
actions["SkeletonObject::SetWidth"].SetFunctionName("setWidth").SetGetter("getWidth");
|
||||
expressions["Width"].SetFunctionName("getWidth");
|
||||
|
||||
conditions["SkeletonObject::Height"].SetFunctionName("getHeight");
|
||||
actions["SkeletonObject::SetHeight"].SetFunctionName("setHeight").SetGetter("getHeight");
|
||||
expressions["Height"].SetFunctionName("getHeight");
|
||||
|
||||
actions["SkeletonObject::SetDefaultHitbox"].SetFunctionName("setDefaultHitbox");
|
||||
|
||||
// Animation instructions
|
||||
conditions["SkeletonObject::AnimationPaused"].SetFunctionName("isAnimationPaused");
|
||||
actions["SkeletonObject::PauseAnimation"].SetFunctionName("setAnimationPaused");
|
||||
actions["SkeletonObject::UnpauseAnimation"].SetFunctionName("setAnimationPaused");
|
||||
|
||||
conditions["SkeletonObject::AnimationFinished"].SetFunctionName("isAnimationFinished");
|
||||
|
||||
conditions["SkeletonObject::AnimationTime"].SetFunctionName("getAnimationTime");
|
||||
actions["SkeletonObject::SetAnimationTime"].SetFunctionName("setAnimationTime").SetGetter("getAnimationTime");
|
||||
expressions["AnimationTime"].SetFunctionName("getAnimationTime");
|
||||
expressions["AnimationTimeLength"].SetFunctionName("getAnimationTimeLength");
|
||||
|
||||
conditions["SkeletonObject::AnimationFrame"].SetFunctionName("getAnimationFrame");
|
||||
actions["SkeletonObject::SetAnimationFrame"].SetFunctionName("setAnimationFrame").SetGetter("getAnimationFrame");
|
||||
expressions["AnimationFrame"].SetFunctionName("getAnimationFrame");
|
||||
expressions["AnimationFrameLength"].SetFunctionName("getAnimationFrameLength");
|
||||
|
||||
conditions["SkeletonObject::AnimationIndex"].SetFunctionName("getAnimationIndex");
|
||||
actions["SkeletonObject::SetAnimationIndex"].SetFunctionName("setAnimationIndex").SetGetter("getAnimationIndex");
|
||||
expressions["AnimationIndex"].SetFunctionName("getAnimationIndex");
|
||||
|
||||
conditions["SkeletonObject::AnimationName"].SetFunctionName("getAnimationName");
|
||||
actions["SkeletonObject::SetAnimationName"].SetFunctionName("setAnimationName").SetGetter("getAnimationName");
|
||||
strExpressions["AnimationName"].SetFunctionName("getAnimationName");
|
||||
|
||||
conditions["SkeletonObject::AnimationSmooth"].SetFunctionName("isAnimationSmooth");
|
||||
actions["SkeletonObject::SetAnimationSmooth"].SetFunctionName("setAnimationSmooth");
|
||||
|
||||
conditions["SkeletonObject::AnimationTimeScale"].SetFunctionName("getAnimationTimeScale");
|
||||
actions["SkeletonObject::SetAnimationTimeScale"].SetFunctionName("setAnimationTimeScale").SetGetter("getAnimationTimeScale");
|
||||
expressions["AnimationTimeScale"].SetFunctionName("getAnimationTimeScale");
|
||||
|
||||
actions["SkeletonObject::ResetAnimation"].SetFunctionName("resetAnimation");
|
||||
|
||||
// Bone instructions
|
||||
conditions["SkeletonObject::BonePositionX"].SetFunctionName("getBoneX");
|
||||
actions["SkeletonObject::SetBonePositionX"].SetFunctionName("setBoneX").SetGetter("getBoneX");
|
||||
expressions["BonePositionX"].SetFunctionName("getBoneX");
|
||||
|
||||
conditions["SkeletonObject::BonePositionY"].SetFunctionName("getBoneY");
|
||||
actions["SkeletonObject::SetBonePositionY"].SetFunctionName("setBoneY").SetGetter("getBoneY");
|
||||
expressions["BonePositionY"].SetFunctionName("getBoneY");
|
||||
|
||||
conditions["SkeletonObject::BoneAngle"].SetFunctionName("getBoneAngle");
|
||||
actions["SkeletonObject::SetBoneAngle"].SetFunctionName("setBoneAngle").SetGetter("getBoneAngle");
|
||||
expressions["BoneAngle"].SetFunctionName("getBoneAngle");
|
||||
|
||||
conditions["SkeletonObject::BoneScaleX"].SetFunctionName("getBoneScaleX");
|
||||
actions["SkeletonObject::SetBoneScaleX"].SetFunctionName("setBoneScaleX").SetGetter("getBoneScaleX");
|
||||
expressions["BoneScaleX"].SetFunctionName("getBoneScaleX");
|
||||
|
||||
conditions["SkeletonObject::BoneScaleY"].SetFunctionName("getBoneScaleY");
|
||||
actions["SkeletonObject::SetBoneScaleY"].SetFunctionName("setBoneScaleY").SetGetter("getBoneScaleY");
|
||||
expressions["BoneScaleY"].SetFunctionName("getBoneScaleY");
|
||||
|
||||
actions["SkeletonObject::ResetBone"].SetFunctionName("resetBone");
|
||||
|
||||
// Slot instructions
|
||||
actions["SkeletonObject::SetSlotColor"].SetFunctionName("setSlotColor");
|
||||
|
||||
conditions["SkeletonObject::SlotVisible"].SetFunctionName("isSlotVisible");
|
||||
actions["SkeletonObject::ShowSlot"].SetFunctionName("setSlotVisible");
|
||||
actions["SkeletonObject::HideSlot"].SetFunctionName("setSlotVisible");
|
||||
|
||||
conditions["SkeletonObject::SlotZOrder"].SetFunctionName("getSlotZOrder");
|
||||
actions["SkeletonObject::SetSlotZOrder"].SetFunctionName("setSlotZOrder").SetGetter("getSlotZOrder");
|
||||
expressions["SlotZOrder"].SetFunctionName("getSlotZOrder");
|
||||
|
||||
conditions["SkeletonObject::PointInsideSlot"].SetFunctionName("isPointInsideSlot");
|
||||
|
||||
// Extension instructions
|
||||
GetAllConditions()["SkeletonObject::SlotCollidesWithObject"].SetFunctionName("gdjs.sk.slotObjectCollision");
|
||||
GetAllConditions()["SkeletonObject::SlotCollidesWithSlot"].SetFunctionName("gdjs.sk.slotSlotCollision");
|
||||
GetAllConditions()["SkeletonObject::RaycastSlot"].SetFunctionName("gdjs.sk.raycastSlot");
|
||||
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(EMSCRIPTEN)
|
||||
extern "C" gd::PlatformExtension * CreateGDJSSkeletonObjectExtension() {
|
||||
return new SkeletonObjectJsExtension;
|
||||
}
|
||||
#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 SkeletonObjectJsExtension;
|
||||
}
|
||||
#endif
|
||||
#endif
|
151
Extensions/SkeletonObject/SkeletonObject.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "GDCpp/Runtime/Project/Project.h"
|
||||
#include "GDCpp/Runtime/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
#include "GDCpp/Runtime/ImageManager.h"
|
||||
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
|
||||
#include "GDCpp/Runtime/Serialization/Serializer.h"
|
||||
#include "GDCpp/Runtime/Project/InitialInstance.h"
|
||||
#include "GDCpp/Runtime/CommonTools.h"
|
||||
#include "SkeletonObject.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCpp/Runtime/ResourcesLoader.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/filename.h>
|
||||
#endif
|
||||
|
||||
sf::Texture SkeletonObject::edittimeIconImage;
|
||||
sf::Sprite SkeletonObject::edittimeIcon;
|
||||
#endif
|
||||
|
||||
SkeletonObject::SkeletonObject(gd::String name_) :
|
||||
Object(name_)
|
||||
{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
originalSize = sf::Vector2f(32.0f, 32.0f),
|
||||
originOffset = sf::Vector2f(16.0f, 16.0f),
|
||||
sizeDirty = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkeletonObject::DoUnserializeFrom(gd::Project & project, const gd::SerializerElement & element)
|
||||
{
|
||||
skeletalDataFilename = element.GetStringAttribute("skeletalDataFilename");
|
||||
rootArmatureName = element.GetStringAttribute("rootArmatureName");
|
||||
textureDataFilename = element.GetStringAttribute("textureDataFilename");
|
||||
textureName = element.GetStringAttribute("textureName");
|
||||
apiName = element.GetStringAttribute("apiName");
|
||||
debugPolygons = element.GetBoolAttribute("debugPolygons", false);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void SkeletonObject::DoSerializeTo(gd::SerializerElement & element) const
|
||||
{
|
||||
element.SetAttribute("skeletalDataFilename", skeletalDataFilename);
|
||||
element.SetAttribute("rootArmatureName", rootArmatureName);
|
||||
element.SetAttribute("textureDataFilename", textureDataFilename);
|
||||
element.SetAttribute("textureName", textureName);
|
||||
element.SetAttribute("apiName", apiName);
|
||||
element.SetAttribute("debugPolygons", debugPolygons);
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> SkeletonObject::GetProperties(gd::Project & project) const
|
||||
{
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Skeletal data filename")].SetValue(skeletalDataFilename);
|
||||
properties[_("Main armature name")].SetValue(rootArmatureName);
|
||||
properties[_("Texture data filename")].SetValue(textureDataFilename);
|
||||
properties[_("Texture")].SetValue(textureName);
|
||||
properties[_("API")]
|
||||
.SetValue(apiName)
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo("DragonBones");
|
||||
properties[_("Debug Polygons")].SetValue(debugPolygons ? "true" : "false").SetType("Boolean");
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool SkeletonObject::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
|
||||
{
|
||||
if (name == _("Skeletal data filename")) {
|
||||
skeletalDataFilename = value;
|
||||
sizeDirty = true;
|
||||
}
|
||||
if (name == _("Main armature name")) {
|
||||
rootArmatureName = value;
|
||||
sizeDirty = true;
|
||||
}
|
||||
if (name == _("Texture data filename")) textureDataFilename = value;
|
||||
if (name == _("Texture")) textureName = value;
|
||||
if (name == _("API")) apiName = value;
|
||||
if (name == _("Debug Polygons")) debugPolygons = value == "1";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkeletonObject::LoadEdittimeIcon()
|
||||
{
|
||||
edittimeIconImage.loadFromFile("JsPlatform/Extensions/skeletonicon.png");
|
||||
edittimeIcon.setTexture(edittimeIconImage);
|
||||
}
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
bool SkeletonObject::GenerateThumbnail(const gd::Project & project, wxBitmap & thumbnail) const
|
||||
{
|
||||
thumbnail = wxBitmap("JsPlatform/Extensions/skeletonicon24.png", wxBITMAP_TYPE_ANY);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SkeletonObject::DrawInitialInstance(gd::InitialInstance & instance, sf::RenderTarget & renderTarget, gd::Project & project, gd::Layout & layout)
|
||||
{
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
if(sizeDirty) UpdateSize(project);
|
||||
#endif
|
||||
|
||||
edittimeIcon.setPosition(instance.GetX() - originalSize.x/2.0f, instance.GetY() - originalSize.y/2.0f);
|
||||
renderTarget.draw(edittimeIcon);
|
||||
}
|
||||
|
||||
sf::Vector2f SkeletonObject::GetInitialInstanceOrigin(gd::InitialInstance & instance, gd::Project & project, gd::Layout & layout) const
|
||||
{
|
||||
return originOffset;
|
||||
}
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
void SkeletonObject::UpdateSize(gd::Project & project)
|
||||
{
|
||||
sizeDirty = false;
|
||||
|
||||
// Force the path as relative
|
||||
wxString projectDir = wxFileName::FileName(project.GetProjectFile()).GetPath();
|
||||
wxFileName fileName(skeletalDataFilename.ToWxString());
|
||||
fileName.SetPath(projectDir);
|
||||
|
||||
// Can't unserialize from JSON's with empty arrays/objects ?
|
||||
// gd::String fileContent = gd::ResourcesLoader::Get()->LoadPlainText(gd::String::FromWxString(fileName.GetFullPath()));
|
||||
// gd::SerializerElement element = gd::Serializer::FromJSON(fileContent);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
gd::Object * CreateSkeletonObject(gd::String name)
|
||||
{
|
||||
return new SkeletonObject(name);
|
||||
}
|
68
Extensions/SkeletonObject/SkeletonObject.h
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
/**
|
||||
GDevelop - Skeleton Object Extension
|
||||
Copyright (c) 2017-2018 Franco Maciel (francomaciel10@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef SKELETONOBJECT_H
|
||||
#define SKELETONOBJECT_H
|
||||
|
||||
#include "GDCpp/Runtime/Project/Object.h"
|
||||
#include "GDCpp/Runtime/String.h"
|
||||
namespace gd { class InitialInstance; }
|
||||
namespace gd { class Project; }
|
||||
namespace sf { class Texture; }
|
||||
namespace sf { class Sprite; }
|
||||
class wxBitmap;
|
||||
|
||||
class GD_EXTENSION_API SkeletonObject : public gd::Object
|
||||
{
|
||||
public:
|
||||
SkeletonObject(gd::String name_);
|
||||
virtual ~SkeletonObject() {};
|
||||
virtual std::unique_ptr<gd::Object> Clone() const { return gd::make_unique<SkeletonObject>(*this); }
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
static void LoadEdittimeIcon();
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
bool GenerateThumbnail(const gd::Project & project, wxBitmap & thumbnail) const override;
|
||||
#endif
|
||||
|
||||
void DrawInitialInstance(gd::InitialInstance & instance, sf::RenderTarget & renderTarget, gd::Project & project, gd::Layout & layout) override;
|
||||
sf::Vector2f GetInitialInstanceOrigin(gd::InitialInstance & instance, gd::Project & project, gd::Layout & layout) const override;
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
void UpdateSize(gd::Project & project);
|
||||
#endif
|
||||
|
||||
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;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void DoUnserializeFrom(gd::Project & project, const gd::SerializerElement & element) override;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void DoSerializeTo(gd::SerializerElement & element) const override;
|
||||
#endif
|
||||
|
||||
gd::String skeletalDataFilename;
|
||||
gd::String rootArmatureName;
|
||||
gd::String textureDataFilename;
|
||||
gd::String textureName;
|
||||
gd::String apiName;
|
||||
bool debugPolygons;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
static sf::Texture edittimeIconImage;
|
||||
static sf::Sprite edittimeIcon;
|
||||
sf::Vector2f originalSize;
|
||||
sf::Vector2f originOffset;
|
||||
bool sizeDirty;
|
||||
#endif
|
||||
};
|
||||
|
||||
gd::Object * CreateSkeletonObject(gd::String name);
|
||||
|
||||
#endif // SKELETONOBJECT_H
|
@@ -91,6 +91,7 @@ BaseObjectExtension::BaseObjectExtension()
|
||||
objectExpressions["Variable"].SetFunctionName("GetVariableValue").SetStatic();
|
||||
objectStrExpressions["VariableString"].SetFunctionName("GetVariableString").SetStatic();
|
||||
objectExpressions["VariableChildCount"].SetFunctionName("GetVariableChildCount");
|
||||
objectStrExpressions["ObjectName"].SetFunctionName("GetName");
|
||||
|
||||
GetAllActions()["Create"].SetFunctionName("CreateObjectOnScene").SetIncludeFile("GDCpp/Extensions/Builtin/RuntimeSceneTools.h");
|
||||
GetAllActions()["CreateByName"].SetFunctionName("CreateObjectFromGroupOnScene").SetIncludeFile("GDCpp/Extensions/Builtin/RuntimeSceneTools.h");
|
||||
|
@@ -92,6 +92,7 @@ BaseObjectExtension::BaseObjectExtension()
|
||||
objectExpressions["Longueur"].SetFunctionName("getAverageForce().getLength"); //Deprecated
|
||||
objectExpressions["Distance"].SetFunctionName("getDistanceToObject");
|
||||
objectExpressions["SqDistance"].SetFunctionName("getSqDistanceToObject");
|
||||
objectStrExpressions["ObjectName"].SetFunctionName("getName");
|
||||
|
||||
|
||||
GetAllActions()["Create"].SetFunctionName("gdjs.evtTools.object.createObjectOnScene");
|
||||
|
@@ -120,13 +120,15 @@ bool Exporter::ExportWholePixiProject(gd::Project & project, gd::String exportDi
|
||||
progressDialog.Update(50, _("Exporting events..."));
|
||||
#endif
|
||||
|
||||
//Export engine libraries
|
||||
helper.AddLibsInclude(true, false, false, includesFiles);
|
||||
|
||||
//Export events
|
||||
if ( !helper.ExportEventsCode(exportedProject, codeOutputDir, includesFiles) )
|
||||
{
|
||||
gd::LogError(_("Error during exporting! Unable to export events:\n")+lastError);
|
||||
return false;
|
||||
}
|
||||
helper.AddLibsInclude(true, false, includesFiles);
|
||||
|
||||
//Export source files
|
||||
if ( !helper.ExportExternalSourceFiles(exportedProject, codeOutputDir, includesFiles) )
|
||||
@@ -222,13 +224,15 @@ bool Exporter::ExportWholeCocos2dProject(gd::Project & project, bool debugMode,
|
||||
progressDialog.Update(50, _("Exporting events..."));
|
||||
#endif
|
||||
|
||||
//Export engine libraries
|
||||
helper.AddLibsInclude(false, true, false, includesFiles);
|
||||
|
||||
//Export events
|
||||
if ( !helper.ExportEventsCode(exportedProject, codeOutputDir, includesFiles) )
|
||||
{
|
||||
gd::LogError(_("Error during exporting! Unable to export events:\n")+lastError);
|
||||
return false;
|
||||
}
|
||||
helper.AddLibsInclude(false, true, includesFiles);
|
||||
|
||||
//Export source files
|
||||
if ( !helper.ExportExternalSourceFiles(exportedProject, codeOutputDir, includesFiles) )
|
||||
|
@@ -85,12 +85,14 @@ bool ExporterHelper::ExportLayoutForPixiPreview(gd::Project & project, gd::Layou
|
||||
|
||||
//Export resources (*before* generating events as some resources filenames may be updated)
|
||||
ExportResources(fs, exportedProject, exportDir);
|
||||
|
||||
//Export engine libraries
|
||||
AddLibsInclude(true, false, true, includesFiles);
|
||||
|
||||
//Generate events code
|
||||
if ( !ExportEventsCode(exportedProject, codeOutputDir, includesFiles) )
|
||||
return false;
|
||||
|
||||
AddLibsInclude(true, false, includesFiles);
|
||||
|
||||
//Export source files
|
||||
if ( !ExportExternalSourceFiles(exportedProject, codeOutputDir, includesFiles) )
|
||||
{
|
||||
@@ -312,8 +314,48 @@ bool ExporterHelper::CompleteIndexFile(gd::String & str, gd::String customCss, g
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExporterHelper::AddLibsInclude(bool pixiRenderers, bool cocosRenderers, std::vector<gd::String> & includesFiles)
|
||||
void ExporterHelper::AddLibsInclude(bool pixiRenderers, bool cocosRenderers, bool websocketDebuggerClient, std::vector<gd::String> & includesFiles)
|
||||
{
|
||||
//First, do not forget common includes (they must be included before events generated code files).
|
||||
InsertUnique(includesFiles, "libs/jshashtable.js");
|
||||
InsertUnique(includesFiles, "gd.js");
|
||||
InsertUnique(includesFiles, "gd-splash-image.js");
|
||||
InsertUnique(includesFiles, "libs/hshg.js");
|
||||
InsertUnique(includesFiles, "libs/rbush.js");
|
||||
InsertUnique(includesFiles, "inputmanager.js");
|
||||
InsertUnique(includesFiles, "timemanager.js");
|
||||
InsertUnique(includesFiles, "runtimeobject.js");
|
||||
InsertUnique(includesFiles, "profiler.js");
|
||||
InsertUnique(includesFiles, "runtimescene.js");
|
||||
InsertUnique(includesFiles, "scenestack.js");
|
||||
InsertUnique(includesFiles, "polygon.js");
|
||||
InsertUnique(includesFiles, "force.js");
|
||||
InsertUnique(includesFiles, "layer.js");
|
||||
InsertUnique(includesFiles, "timer.js");
|
||||
InsertUnique(includesFiles, "runtimegame.js");
|
||||
InsertUnique(includesFiles, "variable.js");
|
||||
InsertUnique(includesFiles, "variablescontainer.js");
|
||||
InsertUnique(includesFiles, "eventscontext.js");
|
||||
InsertUnique(includesFiles, "runtimebehavior.js");
|
||||
InsertUnique(includesFiles, "spriteruntimeobject.js");
|
||||
|
||||
//Common includes for events only.
|
||||
InsertUnique(includesFiles, "events-tools/commontools.js");
|
||||
InsertUnique(includesFiles, "events-tools/runtimescenetools.js");
|
||||
InsertUnique(includesFiles, "events-tools/inputtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/objecttools.js");
|
||||
InsertUnique(includesFiles, "events-tools/cameratools.js");
|
||||
InsertUnique(includesFiles, "events-tools/soundtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/storagetools.js");
|
||||
InsertUnique(includesFiles, "events-tools/stringtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/windowtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/networktools.js");
|
||||
|
||||
if (websocketDebuggerClient)
|
||||
{
|
||||
InsertUnique(includesFiles, "websocket-debugger-client/websocket-debugger-client.js");
|
||||
}
|
||||
|
||||
if (pixiRenderers)
|
||||
{
|
||||
InsertUnique(includesFiles, "pixi-renderers/pixi.js");
|
||||
@@ -370,41 +412,6 @@ bool ExporterHelper::ExportEventsCode(gd::Project & project, gd::String outputDi
|
||||
{
|
||||
fs.MkDir(outputDir);
|
||||
|
||||
//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");
|
||||
InsertUnique(includesFiles, "timemanager.js");
|
||||
InsertUnique(includesFiles, "runtimeobject.js");
|
||||
InsertUnique(includesFiles, "profiler.js");
|
||||
InsertUnique(includesFiles, "runtimescene.js");
|
||||
InsertUnique(includesFiles, "scenestack.js");
|
||||
InsertUnique(includesFiles, "polygon.js");
|
||||
InsertUnique(includesFiles, "force.js");
|
||||
InsertUnique(includesFiles, "layer.js");
|
||||
InsertUnique(includesFiles, "timer.js");
|
||||
InsertUnique(includesFiles, "runtimegame.js");
|
||||
InsertUnique(includesFiles, "variable.js");
|
||||
InsertUnique(includesFiles, "variablescontainer.js");
|
||||
InsertUnique(includesFiles, "eventscontext.js");
|
||||
InsertUnique(includesFiles, "runtimebehavior.js");
|
||||
InsertUnique(includesFiles, "spriteruntimeobject.js");
|
||||
|
||||
//Common includes for events only.
|
||||
InsertUnique(includesFiles, "events-tools/commontools.js");
|
||||
InsertUnique(includesFiles, "events-tools/runtimescenetools.js");
|
||||
InsertUnique(includesFiles, "events-tools/inputtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/objecttools.js");
|
||||
InsertUnique(includesFiles, "events-tools/cameratools.js");
|
||||
InsertUnique(includesFiles, "events-tools/soundtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/storagetools.js");
|
||||
InsertUnique(includesFiles, "events-tools/stringtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/windowtools.js");
|
||||
InsertUnique(includesFiles, "events-tools/networktools.js");
|
||||
|
||||
for (std::size_t i = 0;i<project.GetLayoutsCount();++i)
|
||||
{
|
||||
std::set<gd::String> eventsIncludes;
|
||||
|
@@ -64,11 +64,10 @@ public:
|
||||
static void ExportResources(gd::AbstractFileSystem & fs, gd::Project & project, gd::String exportDir,
|
||||
wxProgressDialog * progressDlg = NULL);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Add libraries files from Pixi.js or Cocos2d to the list of includes.
|
||||
*/
|
||||
void AddLibsInclude(bool pixiRenderers, bool cocosRenderers, std::vector<gd::String> & includesFiles);
|
||||
void AddLibsInclude(bool pixiRenderers, bool cocosRenderers, bool websocketDebuggerClient, std::vector<gd::String> & includesFiles);
|
||||
|
||||
/**
|
||||
* \brief Remove include files that are Pixi or Cocos2d renderers.
|
||||
|
@@ -40,12 +40,18 @@ gdjs.RuntimeGame = function(data, spec) {
|
||||
//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.
|
||||
this._paused = false;
|
||||
|
||||
//Inputs :
|
||||
this._inputManager = new gdjs.InputManager();
|
||||
|
||||
//Allow to specify an external layout to insert in the first scene:
|
||||
this._injectExternalLayout = spec.injectExternalLayout || '';
|
||||
|
||||
//Optional client to connect to a debugger:
|
||||
this._debuggerClient = gdjs.DebuggerClient
|
||||
? new gdjs.DebuggerClient(this)
|
||||
: null;
|
||||
};
|
||||
|
||||
gdjs.RuntimeGame.prototype.getRenderer = function() {
|
||||
@@ -239,6 +245,16 @@ gdjs.RuntimeGame.prototype.getMinimalFramerate = function() {
|
||||
return this._minFPS;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set or unset the game as paused.
|
||||
* When paused, the game won't step and will be freezed. Useful for debugging.
|
||||
* @method pause
|
||||
* @param enable {Boolean} true to pause the game, false to unpause
|
||||
*/
|
||||
gdjs.RuntimeGame.prototype.pause = function(enable) {
|
||||
this._paused = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all assets, displaying progress in renderer.
|
||||
* @method loadAllAssets
|
||||
@@ -299,6 +315,8 @@ gdjs.RuntimeGame.prototype.startGameLoop = function() {
|
||||
//The standard game loop
|
||||
var that = this;
|
||||
this._renderer.startGameLoop(function(elapsedTime) {
|
||||
if (that._paused) return true;
|
||||
|
||||
//Manage resize events.
|
||||
if (that._notifySceneForResize) {
|
||||
that._sceneStack.onRendererResized();
|
||||
|
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* This DebuggerClient connects to a websocket server and can dump
|
||||
* the data of the current game, and receive message to change a field or
|
||||
* call a function on an object of the specified runtimeGame.
|
||||
* @param {*} runtimegame
|
||||
*/
|
||||
gdjs.WebsocketDebuggerClient = function(runtimegame) {
|
||||
this._runtimegame = runtimegame;
|
||||
|
||||
if (typeof WebSocket !== 'undefined') {
|
||||
var that = this;
|
||||
var ws = (this._ws = new WebSocket('ws://127.0.0.1:3030/'));
|
||||
|
||||
ws.onopen = function open() {
|
||||
console.info('Debugger connection open');
|
||||
};
|
||||
|
||||
ws.onclose = function close() {
|
||||
console.info('Debugger connection closed');
|
||||
};
|
||||
|
||||
ws.onerror = function errored(error) {
|
||||
console.warn('Debugger client error:', error);
|
||||
};
|
||||
|
||||
ws.onmessage = function incoming(message) {
|
||||
var data = null;
|
||||
try {
|
||||
data = JSON.parse(message.data);
|
||||
} catch (e) {
|
||||
console.info('Debugger received a badly formatted message');
|
||||
}
|
||||
|
||||
if (data && data.command) {
|
||||
if (data.command === 'play') {
|
||||
runtimegame.pause(false);
|
||||
} else if (data.command === 'pause') {
|
||||
runtimegame.pause(true);
|
||||
that.sendRuntimeGameDump();
|
||||
} else if (data.command === 'refresh') {
|
||||
that.sendRuntimeGameDump();
|
||||
} else if (data.command === 'set') {
|
||||
that.set(data.path, data.newValue);
|
||||
} else if (data.command === 'call') {
|
||||
that.call(data.path, data.args);
|
||||
} else {
|
||||
console.info(
|
||||
'Unknown command "' + data.command + '" received by the debugger.'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.info('Debugger received a message with badly formatted data.');
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("WebSocket is not defined, debugger won't work");
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.DebuggerClient = gdjs.WebsocketDebuggerClient; //Register the class to let the engine use it.
|
||||
|
||||
gdjs.WebsocketDebuggerClient.prototype.set = function(path, newValue) {
|
||||
if (!path || !path.length) {
|
||||
console.warn('No path specified, set operation from debugger aborted');
|
||||
return false;
|
||||
}
|
||||
|
||||
var object = this._runtimegame;
|
||||
var currentIndex = 0;
|
||||
while (currentIndex < path.length - 1) {
|
||||
var key = path[currentIndex];
|
||||
if (!object || !object[key]) {
|
||||
console.error('Incorrect path specified. No ' + key + ' in ', object);
|
||||
return false;
|
||||
}
|
||||
|
||||
object = object[key];
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
// Ensure the newValue is properly typed to avoid breaking anything in
|
||||
// the game engine.
|
||||
var currentValue = object[path[currentIndex]];
|
||||
if (typeof currentValue === 'number') {
|
||||
newValue = parseFloat(newValue);
|
||||
} else if (typeof currentValue === 'string') {
|
||||
newValue = '' + newValue;
|
||||
}
|
||||
|
||||
console.log('Updating', path, 'to', newValue);
|
||||
object[path[currentIndex]] = newValue;
|
||||
return true;
|
||||
};
|
||||
|
||||
gdjs.WebsocketDebuggerClient.prototype.call = function(path, args) {
|
||||
if (!path || !path.length) {
|
||||
console.warn('No path specified, call operation from debugger aborted');
|
||||
return false;
|
||||
}
|
||||
|
||||
var object = this._runtimegame;
|
||||
var currentIndex = 0;
|
||||
while (currentIndex < path.length - 1) {
|
||||
var key = path[currentIndex];
|
||||
if (!object || !object[key]) {
|
||||
console.error('Incorrect path specified. No ' + key + ' in ', object);
|
||||
return false;
|
||||
}
|
||||
|
||||
object = object[key];
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
if (!object[path[currentIndex]]) {
|
||||
console.error('Unable to call', path);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('Calling', path, 'with', args);
|
||||
object[path[currentIndex]].apply(object, args);
|
||||
return true;
|
||||
};
|
||||
|
||||
gdjs.WebsocketDebuggerClient.prototype.sendRuntimeGameDump = function() {
|
||||
if (!this._ws) {
|
||||
console.warn('No connection to debugger opened to send RuntimeGame dump');
|
||||
return;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
var message = {
|
||||
command: 'dump',
|
||||
payload: this._runtimegame,
|
||||
};
|
||||
|
||||
var serializationStartTime = Date.now();
|
||||
|
||||
// This is an alternative to JSON.stringify that ensure that circular reference
|
||||
// are replaced by a placeholder.
|
||||
function circularSafeStringify(obj, replacer, spaces, cycleReplacer) {
|
||||
return JSON.stringify(
|
||||
obj,
|
||||
depthLimitedSerializer(replacer, cycleReplacer, 18),
|
||||
spaces
|
||||
);
|
||||
}
|
||||
|
||||
function depthLimitedSerializer(replacer, cycleReplacer, maxDepth) {
|
||||
var stack = [],
|
||||
keys = [];
|
||||
|
||||
if (cycleReplacer == null)
|
||||
cycleReplacer = function(key, value) {
|
||||
if (stack[0] === value) return '[Circular ~]';
|
||||
return (
|
||||
'[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'
|
||||
);
|
||||
};
|
||||
|
||||
return function(key, value) {
|
||||
if (stack.length > 0) {
|
||||
var thisPos = stack.indexOf(this);
|
||||
~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
|
||||
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
|
||||
|
||||
if (thisPos > maxDepth) {
|
||||
return '[Max depth reached]';
|
||||
} else if (~stack.indexOf(value))
|
||||
value = cycleReplacer.call(this, key, value);
|
||||
} else stack.push(value);
|
||||
|
||||
return replacer == null ? value : replacer.call(this, key, value);
|
||||
};
|
||||
}
|
||||
|
||||
// Stringify the message, excluding some known data that are big and/or not
|
||||
// useful for the debugger.
|
||||
var excludedValues = [that._runtimegame.getGameData()];
|
||||
var excludedKeys = [
|
||||
// Exclude some RuntimeScene fields:
|
||||
'_allInstancesList',
|
||||
'_initialObjectsData',
|
||||
|
||||
// Exclude circular references to parent runtimeGame or runtimeScene:
|
||||
'_runtimeGame',
|
||||
'_runtimeScene',
|
||||
|
||||
// Exclude some runtimeObject duplicated data:
|
||||
'_behaviorsTable',
|
||||
|
||||
// Exclude some objects data:
|
||||
'_animations',
|
||||
'_animationFrame',
|
||||
|
||||
// Exclude some behaviors data:
|
||||
'_platformRBush',
|
||||
|
||||
// Exclude rendering related objects:
|
||||
'_renderer',
|
||||
'_imageManager',
|
||||
|
||||
// Exclude PIXI textures:
|
||||
'baseTexture',
|
||||
'_baseTexture',
|
||||
'_invalidTexture',
|
||||
];
|
||||
var stringifiedMessage = circularSafeStringify(message, function(key, value) {
|
||||
if (
|
||||
excludedValues.indexOf(value) !== -1 ||
|
||||
excludedKeys.indexOf(key) !== -1
|
||||
)
|
||||
return '[Removed from the debugger]';
|
||||
|
||||
return value;
|
||||
});
|
||||
|
||||
var serializationDuration = Date.now() - serializationStartTime;
|
||||
console.log('RuntimeGame serialization took ' + serializationDuration + 'ms');
|
||||
if (serializationDuration > 500) {
|
||||
console.warn(
|
||||
'Serialization took a long time: please check if there is a need to remove some objects from serialization'
|
||||
);
|
||||
}
|
||||
|
||||
this._ws.send(stringifiedMessage);
|
||||
};
|
@@ -26,6 +26,9 @@ 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. 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).
|
||||
|
||||
Note for Linux: If you get an error message that looks like this:
|
||||
`Error: watch GD/newIDE/app/some/file ENOSPC` then follow the instructions [here](https://stackoverflow.com/questions/22475849/node-js-error-enospc) to fix.
|
||||
|
||||
### Development of the standalone app
|
||||
|
||||
You can run the app with Electron. **Make sure that you've run `yarn start` in `app` folder before** (see above).
|
||||
@@ -55,17 +58,24 @@ yarn storybook #or npm run storybook
|
||||
|
||||
### Tests
|
||||
|
||||
Unit tests can be launched with this command:
|
||||
Unit tests and type checking can be launched with this command:
|
||||
|
||||
```bash
|
||||
cd newIDE/app
|
||||
yarn test #or npm run test
|
||||
yarn flow #or npm run flow
|
||||
```
|
||||
|
||||
### Theming
|
||||
|
||||
It's possible to create new themes for the UI. See [this file](https://github.com/4ian/GD/blob/master/newIDE/app/src/UI/Theme/index.js) to declare a new theme. You can take a look at the [default theme](https://github.com/4ian/GD/blob/master/newIDE/app/src/UI/Theme/DefaultTheme/index.js), including the [styling of the Events Sheets](https://github.com/4ian/GD/blob/master/newIDE/app/src/UI/Theme/DefaultTheme/EventsSheet.css).
|
||||
|
||||
### Recommended tools for development
|
||||
|
||||
Any text editor is fine, but it's a good idea to have one with *Prettier* (code formatting), *ESLint* (code linting) and *Flow* (type checking) integration.
|
||||
|
||||
👉 You can use [Visual Studio Code](https://code.visualstudio.com) with these extensions: [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode), [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [Flow Language Support](https://github.com/flowtype/flow-for-vscode).
|
||||
|
||||
## Building and deploying the standalone app
|
||||
|
||||
### Desktop version
|
||||
|
@@ -1,2 +1,6 @@
|
||||
<!-- GDevelop.js core -->
|
||||
<script src="/libGD.js"></script
|
||||
<script src="/libGD.js"></script>
|
||||
|
||||
<!-- DocSearch support -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
|
||||
|
1
newIDE/app/flow-typed/libGD.js
vendored
@@ -15,6 +15,7 @@ declare type gdInitialInstance = EmscriptenObject;
|
||||
declare type gdBaseEvent = EmscriptenObject;
|
||||
declare type gdResource = EmscriptenObject;
|
||||
declare type gdObject = EmscriptenObject;
|
||||
declare type gdResourcesManager = EmscriptenObject;
|
||||
|
||||
declare type gdInstruction = EmscriptenObject;
|
||||
declare type gdInstructionMetadata = EmscriptenObject;
|
||||
|
@@ -40,6 +40,7 @@
|
||||
"react-dom": "^16.2.0",
|
||||
"react-error-boundary": "^1.2.0",
|
||||
"react-i18next": "6.2.0",
|
||||
"react-json-view": "^1.16.1",
|
||||
"react-measure": "1.4.7",
|
||||
"react-mosaic-component": "1.0.3",
|
||||
"react-sortable-hoc": "0.6.8",
|
||||
|
@@ -28,6 +28,8 @@
|
||||
<!-- Stripe.com Checkout -->
|
||||
<script src="https://checkout.stripe.com/checkout.js"></script>
|
||||
|
||||
<!-- DocSearch support -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- Root div used for React `App` component rendering-->
|
||||
@@ -48,5 +50,8 @@
|
||||
global.gd = require(name)();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- DocSearch support -->
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -5,7 +5,7 @@ var fs = require('fs');
|
||||
var sourceFile = '../../../Binaries/Output/libGD.js/Release/libGD.js';
|
||||
var destinationTestDirectory = '../node_modules/libGD.js-for-tests-only';
|
||||
|
||||
if (!shell.mkdir(destinationTestDirectory)) {
|
||||
if (!shell.mkdir('-p', destinationTestDirectory)) {
|
||||
shell.echo('❌ Error while creating node_modules folder for libGD.js');
|
||||
}
|
||||
|
||||
|
151
newIDE/app/src/Debugger/DebuggerContent.js
Normal file
@@ -0,0 +1,151 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import EditorMosaic, { MosaicWindow } from '../UI/EditorMosaic';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import get from 'lodash/get';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import { Column, Line } from '../UI/Grid';
|
||||
import InspectorsList from './InspectorsList';
|
||||
import {
|
||||
getInspectorDescriptions,
|
||||
type InspectorDescription,
|
||||
type EditFunction,
|
||||
type CallFunction,
|
||||
} from './GDJSInspectorDescriptions';
|
||||
import RawContentInspector from './Inspectors/RawContentInspector';
|
||||
import EmptyMessage from '../UI/EmptyMessage';
|
||||
import Checkbox from 'material-ui/Checkbox';
|
||||
import Flash from 'material-ui/svg-icons/image/flash-on';
|
||||
import FlashOff from 'material-ui/svg-icons/image/flash-off';
|
||||
import HelpButton from '../UI/HelpButton';
|
||||
type Props = {|
|
||||
gameData: ?any,
|
||||
onEdit: EditFunction,
|
||||
onCall: CallFunction,
|
||||
onPlay: () => void,
|
||||
onPause: () => void,
|
||||
onRefresh: () => void,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
selectedInspector: ?InspectorDescription,
|
||||
selectedInspectorFullPath: Array<string>,
|
||||
rawMode: boolean,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
container: { flex: 1, display: 'flex' },
|
||||
};
|
||||
|
||||
/**
|
||||
* The debugger interface: show the list of inspectors for a game, along with the
|
||||
* currently selected inspector.
|
||||
*/
|
||||
export default class DebuggerContent extends React.Component<Props, State> {
|
||||
state = {
|
||||
selectedInspector: null,
|
||||
selectedInspectorFullPath: [],
|
||||
rawMode: false,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { gameData, onRefresh, onCall, onEdit } = this.props;
|
||||
const {
|
||||
selectedInspector,
|
||||
selectedInspectorFullPath,
|
||||
rawMode,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<EditorMosaic
|
||||
editors={{
|
||||
inspectors: (
|
||||
<MosaicWindow
|
||||
title="Inspectors"
|
||||
toolbarControls={[]}
|
||||
gameData={gameData}
|
||||
>
|
||||
<Paper style={styles.container}>
|
||||
<Column expand noMargin>
|
||||
<Line justifyContent="center">
|
||||
<RaisedButton label="Refresh" onClick={onRefresh} primary />
|
||||
</Line>
|
||||
<Line expand noMargin>
|
||||
<InspectorsList
|
||||
gameData={gameData}
|
||||
getInspectorDescriptions={getInspectorDescriptions}
|
||||
onChooseInspector={(
|
||||
selectedInspector,
|
||||
selectedInspectorFullPath
|
||||
) =>
|
||||
this.setState({
|
||||
selectedInspector,
|
||||
selectedInspectorFullPath,
|
||||
})}
|
||||
/>
|
||||
</Line>
|
||||
</Column>
|
||||
</Paper>
|
||||
</MosaicWindow>
|
||||
),
|
||||
'selected-inspector': (
|
||||
<Column expand noMargin>
|
||||
{' '}
|
||||
{selectedInspector ? (
|
||||
rawMode ? (
|
||||
<RawContentInspector
|
||||
gameData={get(gameData, selectedInspectorFullPath, null)}
|
||||
onEdit={(path, newValue) =>
|
||||
onEdit(selectedInspectorFullPath.concat(path), newValue)}
|
||||
/>
|
||||
) : (
|
||||
selectedInspector.renderInspector(
|
||||
get(gameData, selectedInspectorFullPath, null),
|
||||
{
|
||||
onCall: (path, args) =>
|
||||
onCall(selectedInspectorFullPath.concat(path), args),
|
||||
onEdit: (path, newValue) =>
|
||||
onEdit(
|
||||
selectedInspectorFullPath.concat(path),
|
||||
newValue
|
||||
),
|
||||
}
|
||||
) || (
|
||||
<EmptyMessage>
|
||||
No inspector, choose another element in the list or toggle
|
||||
the raw data view.
|
||||
</EmptyMessage>
|
||||
)
|
||||
)
|
||||
) : (
|
||||
<EmptyMessage>
|
||||
{gameData
|
||||
? 'Choose an element to inspect in the list'
|
||||
: 'Pause the game (from the toolbar) or hit refresh (on the left) to inspect the game'}
|
||||
</EmptyMessage>
|
||||
)}
|
||||
<Column>
|
||||
<Line justifyContent="space-between" alignItems="center">
|
||||
<HelpButton helpPagePath="/interface/debugger" />
|
||||
<div>
|
||||
<Checkbox
|
||||
checkedIcon={<Flash />}
|
||||
uncheckedIcon={<FlashOff />}
|
||||
checked={rawMode}
|
||||
onCheck={(e, enabled) =>
|
||||
this.setState({
|
||||
rawMode: enabled,
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</Line>
|
||||
</Column>
|
||||
</Column>
|
||||
),
|
||||
}}
|
||||
initialEditorNames={['inspectors', 'selected-inspector']}
|
||||
initialSplitPercentage={32}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
40
newIDE/app/src/Debugger/DebuggerSelector.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import SelectField from 'material-ui/SelectField';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import { Column } from '../UI/Grid';
|
||||
import { type DebuggerId } from '.';
|
||||
|
||||
type Props = {|
|
||||
selectedId: DebuggerId,
|
||||
debuggerIds: Array<DebuggerId>,
|
||||
onChooseDebugger: DebuggerId => void,
|
||||
|};
|
||||
|
||||
export default class DebuggerSelector extends React.Component<Props, void> {
|
||||
render() {
|
||||
const hasDebuggers = !!this.props.debuggerIds.length;
|
||||
return (
|
||||
<Column>
|
||||
<SelectField
|
||||
fullWidth
|
||||
value={hasDebuggers ? this.props.selectedId : 0}
|
||||
onChange={(e, i, value) => this.props.onChooseDebugger(value)}
|
||||
disabled={!hasDebuggers}
|
||||
>
|
||||
{this.props.debuggerIds.map(id => (
|
||||
<MenuItem value={id} key={id} primaryText={'Game preview #' + id} />
|
||||
))}
|
||||
{!hasDebuggers && (
|
||||
<MenuItem
|
||||
value={0}
|
||||
primaryText={
|
||||
'No preview running. Run a preview and you will be able to inspect it with the debugger'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</SelectField>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
}
|
129
newIDE/app/src/Debugger/GDJSInspectorDescriptions.js
Normal file
@@ -0,0 +1,129 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import RuntimeObjectInspector from './Inspectors/RuntimeObjectInspector';
|
||||
import VariablesContainerInspector from './Inspectors/VariablesContainerInspector';
|
||||
import RuntimeSceneInspector from './Inspectors/RuntimeSceneInspector';
|
||||
|
||||
export type GameData = any;
|
||||
export type EditFunction = (path: Array<string>, newValue: any) => boolean;
|
||||
export type CallFunction = (path: Array<string>, args: Array<any>) => boolean;
|
||||
|
||||
export type InspectorDescriptionsGetter = (
|
||||
gameData: GameData
|
||||
) => Array<InspectorDescription>; //eslint-disable-line
|
||||
|
||||
export type InspectorDescription = {|
|
||||
label: string,
|
||||
key: string | Array<string>,
|
||||
renderInspector: (
|
||||
gameData: GameData,
|
||||
{
|
||||
onCall: CallFunction,
|
||||
onEdit: EditFunction,
|
||||
}
|
||||
) => React.Node,
|
||||
getSubInspectors?: InspectorDescriptionsGetter,
|
||||
initiallyOpen?: boolean,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Returns the list of inspectors, given the data coming from a GDJS RuntimeGame.
|
||||
* @param {*} gdjsRuntimeGame
|
||||
*/
|
||||
export const getInspectorDescriptions = (
|
||||
gdjsRuntimeGame: GameData
|
||||
): Array<InspectorDescription> => {
|
||||
return [
|
||||
{
|
||||
label: 'Global variables',
|
||||
key: '_variables',
|
||||
renderInspector: (gameData, { onCall, onEdit }) => (
|
||||
<VariablesContainerInspector
|
||||
variablesContainer={gameData}
|
||||
onCall={onCall}
|
||||
onEdit={onEdit}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Scenes',
|
||||
key: ['_sceneStack', '_stack'],
|
||||
renderInspector: () => null,
|
||||
initiallyOpen: true,
|
||||
getSubInspectors: gdjsStack => {
|
||||
if (!gdjsStack) return [];
|
||||
|
||||
return gdjsStack.map((runtimeScene, index) => ({
|
||||
label: runtimeScene._name,
|
||||
key: index,
|
||||
renderInspector: (gameData, { onCall, onEdit }) => (
|
||||
<RuntimeSceneInspector
|
||||
runtimeScene={gameData}
|
||||
onCall={onCall}
|
||||
onEdit={onEdit}
|
||||
/>
|
||||
),
|
||||
initiallyOpen: true,
|
||||
getSubInspectors: runtimeScene => [
|
||||
{
|
||||
label: 'Scene variables',
|
||||
key: `_variables`,
|
||||
renderInspector: (gameData, { onCall, onEdit }) => (
|
||||
<VariablesContainerInspector
|
||||
variablesContainer={gameData}
|
||||
onCall={onCall}
|
||||
onEdit={onEdit}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Instances',
|
||||
key: `_instances`,
|
||||
renderInspector: () => null,
|
||||
initiallyOpen: true,
|
||||
getSubInspectors: instances => {
|
||||
if (!instances || !instances.items) return [];
|
||||
|
||||
return Object.keys(instances.items).map(objectName => {
|
||||
if (
|
||||
!instances.items[objectName] ||
|
||||
typeof instances.items[objectName].length === undefined
|
||||
)
|
||||
return null;
|
||||
|
||||
return {
|
||||
label: `${objectName} (${instances.items[objectName]
|
||||
.length})`,
|
||||
key: ['items', objectName],
|
||||
renderInspector: () => null,
|
||||
getSubInspectors: instancesList =>
|
||||
instancesList
|
||||
? instancesList
|
||||
.filter(runtimeObject => !!runtimeObject)
|
||||
.map((runtimeObject, index) => {
|
||||
return {
|
||||
label: `#${runtimeObject.id}`,
|
||||
key: index,
|
||||
renderInspector: (
|
||||
gameData,
|
||||
{ onCall, onEdit }
|
||||
) => (
|
||||
<RuntimeObjectInspector
|
||||
runtimeObject={gameData}
|
||||
onCall={onCall}
|
||||
onEdit={onEdit}
|
||||
/>
|
||||
),
|
||||
};
|
||||
})
|
||||
: [],
|
||||
};
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
37
newIDE/app/src/Debugger/Inspectors/RawContentInspector.js
Normal file
@@ -0,0 +1,37 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import ReactJsonView from 'react-json-view';
|
||||
import { type GameData } from '../GDJSInspectorDescriptions';
|
||||
import EmptyMessage from '../../UI/EmptyMessage';
|
||||
|
||||
type Props = {|
|
||||
gameData: GameData,
|
||||
onEdit: (path: Array<string>, newValue: any) => boolean,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
overflowY: 'scroll',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* A very simple inspector that display the raw information given by the gameData
|
||||
* object.
|
||||
*/
|
||||
export default ({ gameData, onEdit }: Props) => (
|
||||
<div style={styles.container}>
|
||||
<EmptyMessage>You are in raw mode. You can edit the fields, but be aware that this can lead to unexpected results or even crash the debugged game!</EmptyMessage>
|
||||
<ReactJsonView
|
||||
collapsed={1}
|
||||
name={false}
|
||||
src={gameData}
|
||||
onEdit={edit => {
|
||||
return onEdit(edit.namespace.concat(edit.name), edit.new_value);
|
||||
}}
|
||||
groupArraysAfterLength={50}
|
||||
theme="monokai"
|
||||
/>
|
||||
</div>
|
||||
);
|
80
newIDE/app/src/Debugger/Inspectors/RuntimeObjectInspector.js
Normal file
@@ -0,0 +1,80 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import ReactJsonView from 'react-json-view';
|
||||
import {
|
||||
type GameData,
|
||||
type EditFunction,
|
||||
type CallFunction,
|
||||
} from '../GDJSInspectorDescriptions';
|
||||
import VariablesContainerInspector from './VariablesContainerInspector';
|
||||
|
||||
type Props = {|
|
||||
runtimeObject: GameData,
|
||||
onCall: CallFunction,
|
||||
onEdit: EditFunction,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
overflowY: 'scroll',
|
||||
},
|
||||
};
|
||||
|
||||
const transform = runtimeObject => {
|
||||
if (!runtimeObject) return null;
|
||||
return {
|
||||
'X position': runtimeObject.x,
|
||||
'Y position': runtimeObject.y,
|
||||
Angle: runtimeObject.angle,
|
||||
Layer: runtimeObject.layer,
|
||||
'Z order': runtimeObject.zOrder,
|
||||
'Is hidden?': runtimeObject.hidden,
|
||||
};
|
||||
};
|
||||
|
||||
const handleEdit = (edit, { onCall, onEdit }: Props) => {
|
||||
if (edit.name === 'X position') {
|
||||
onCall(['setX'], [parseFloat(edit.new_value)]);
|
||||
} else if (edit.name === 'Y position') {
|
||||
onCall(['setY'], [parseFloat(edit.new_value)]);
|
||||
} else if (edit.name === 'Angle') {
|
||||
onCall(['setAngle'], [parseFloat(edit.new_value)]);
|
||||
} else if (edit.name === 'Layer') {
|
||||
onCall(['setLayer'], [edit.new_value]);
|
||||
} else if (edit.name === 'Z order') {
|
||||
onCall(['setZOrder'], [parseFloat(edit.new_value)]);
|
||||
} else if (edit.name === 'Is hidden?') {
|
||||
onCall(['hide'], [!!edit.new_value]);
|
||||
} else return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export default (props: Props) => (
|
||||
<div style={styles.container}>
|
||||
<p>General:</p>
|
||||
<ReactJsonView
|
||||
collapsed={false}
|
||||
name={false}
|
||||
src={transform(props.runtimeObject)}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
displayObjectSize={false}
|
||||
onEdit={edit => handleEdit(edit, props)}
|
||||
groupArraysAfterLength={50}
|
||||
theme="monokai"
|
||||
/>
|
||||
<p>Instance variables:</p>
|
||||
<VariablesContainerInspector
|
||||
variablesContainer={
|
||||
props.runtimeObject ? props.runtimeObject._variables : null
|
||||
}
|
||||
// TODO: onEdit and onCall could benefit from a "forward" utility function
|
||||
// (can also be applied in DebuggerContent.js)
|
||||
onEdit={(path, newValue) =>
|
||||
props.onEdit(['_variables'].concat(path), newValue)}
|
||||
onCall={(path, args) => props.onCall(['_variables'].concat(path), args)}
|
||||
/>
|
||||
</div>
|
||||
);
|
172
newIDE/app/src/Debugger/Inspectors/RuntimeSceneInspector.js
Normal file
@@ -0,0 +1,172 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import ReactJsonView from 'react-json-view';
|
||||
import {
|
||||
type GameData,
|
||||
type EditFunction,
|
||||
type CallFunction,
|
||||
} from '../GDJSInspectorDescriptions';
|
||||
import { Line } from '../../UI/Grid';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import AutoComplete from 'material-ui/AutoComplete';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
|
||||
type Props = {|
|
||||
runtimeScene: GameData,
|
||||
onCall: CallFunction,
|
||||
onEdit: EditFunction,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
newObjectName: string,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
overflowY: 'scroll',
|
||||
},
|
||||
};
|
||||
|
||||
const transformLayer = layer => {
|
||||
if (!layer) return null;
|
||||
return {
|
||||
'Camera rotation (in deg)': layer._cameraRotation,
|
||||
'Camera zoom': layer._zoomFactor,
|
||||
'Layer is hidden': !!layer._hidden,
|
||||
'Camera X position': layer._cameraX,
|
||||
'Camera Y position': layer._cameraY,
|
||||
'Time scale': layer._timeScale,
|
||||
};
|
||||
};
|
||||
|
||||
const transform = runtimeScene => {
|
||||
if (!runtimeScene) return null;
|
||||
|
||||
return {
|
||||
'Time scale': runtimeScene._timeManager
|
||||
? runtimeScene._timeManager._timeScale
|
||||
: null,
|
||||
Layers:
|
||||
runtimeScene._layers && runtimeScene._layers.items
|
||||
? mapValues(runtimeScene._layers.items, transformLayer)
|
||||
: null,
|
||||
};
|
||||
};
|
||||
|
||||
const handleEdit = (edit, { onCall, onEdit }: Props) => {
|
||||
if (edit.namespace.length === 0 && edit.name === 'Time scale') {
|
||||
onCall(['_timeManager', 'setTimeScale'], [parseFloat(edit.new_value)]);
|
||||
} else if (edit.namespace.length >= 2) {
|
||||
if (edit.namespace[0] === 'Layers') {
|
||||
if (edit.name === 'Camera rotation (in deg)') {
|
||||
onCall(
|
||||
['_layers', 'items', edit.namespace[1], 'setCameraRotation'],
|
||||
[parseFloat(edit.new_value)]
|
||||
);
|
||||
} else if (edit.name === 'Camera zoom') {
|
||||
onCall(
|
||||
['_layers', 'items', edit.namespace[1], 'setCameraZoom'],
|
||||
[parseFloat(edit.new_value)]
|
||||
);
|
||||
} else if (edit.name === 'Layer is hidden') {
|
||||
onCall(
|
||||
['_layers', 'items', edit.namespace[1], 'show'],
|
||||
[!edit.new_value]
|
||||
);
|
||||
} else if (edit.name === 'Camera X position') {
|
||||
onCall(
|
||||
['_layers', 'items', edit.namespace[1], 'setCameraX'],
|
||||
[parseFloat(edit.new_value)]
|
||||
);
|
||||
} else if (edit.name === 'Camera Y position') {
|
||||
onCall(
|
||||
['_layers', 'items', edit.namespace[1], 'setCameraY'],
|
||||
[parseFloat(edit.new_value)]
|
||||
);
|
||||
} else if (edit.name === 'Time scale') {
|
||||
onCall(
|
||||
['_layers', 'items', edit.namespace[1], 'setTimeScale'],
|
||||
[parseFloat(edit.new_value)]
|
||||
);
|
||||
}
|
||||
}
|
||||
} else return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export default class RuntimeSceneInspector extends React.Component<
|
||||
Props,
|
||||
State
|
||||
> {
|
||||
state = {
|
||||
newObjectName: '',
|
||||
};
|
||||
|
||||
render() {
|
||||
const { runtimeScene, onCall } = this.props;
|
||||
if (!runtimeScene) return null;
|
||||
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
<p>Layers:</p>
|
||||
<ReactJsonView
|
||||
collapsed={false}
|
||||
name={false}
|
||||
src={transform(runtimeScene)}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
displayObjectSize={false}
|
||||
onEdit={edit => handleEdit(edit, this.props)}
|
||||
groupArraysAfterLength={50}
|
||||
theme="monokai"
|
||||
/>
|
||||
<p>Create a new instance on the scene (will be at position 0;0):</p>
|
||||
{runtimeScene._objects &&
|
||||
runtimeScene._objects.items && (
|
||||
<Line noMargin alignItems="baseline">
|
||||
<AutoComplete
|
||||
hintText="Enter the name of the object"
|
||||
fullWidth
|
||||
menuProps={{
|
||||
maxHeight: 250,
|
||||
}}
|
||||
searchText={this.state.newObjectName}
|
||||
onUpdateInput={value => {
|
||||
this.setState({
|
||||
newObjectName: value,
|
||||
});
|
||||
}}
|
||||
onNewRequest={data => {
|
||||
// Note that data may be a string or a {text, value} object.
|
||||
if (typeof data === 'string') {
|
||||
this.setState({
|
||||
newObjectName: data,
|
||||
});
|
||||
} else if (typeof data.value === 'string') {
|
||||
this.setState({
|
||||
newObjectName: data.value,
|
||||
});
|
||||
}
|
||||
}}
|
||||
dataSource={Object.keys(
|
||||
runtimeScene._objects.items
|
||||
).map(objectName => ({
|
||||
text: objectName,
|
||||
value: objectName,
|
||||
}))}
|
||||
filter={AutoComplete.fuzzyFilter}
|
||||
/>
|
||||
<RaisedButton
|
||||
label="Create"
|
||||
primary
|
||||
onClick={() =>
|
||||
onCall(['createObject'], [this.state.newObjectName])}
|
||||
/>
|
||||
</Line>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import ReactJsonView from 'react-json-view';
|
||||
import {
|
||||
type GameData,
|
||||
type EditFunction,
|
||||
type CallFunction,
|
||||
} from '../GDJSInspectorDescriptions';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
|
||||
type Props = {|
|
||||
variablesContainer: GameData,
|
||||
onCall: CallFunction,
|
||||
onEdit: EditFunction,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
overflowY: 'scroll',
|
||||
},
|
||||
};
|
||||
|
||||
const transformVariable = variable => {
|
||||
if (!variable) return null;
|
||||
|
||||
if (!variable._isStructure) {
|
||||
return variable._stringDirty ? variable._value : variable._str;
|
||||
} else {
|
||||
if (!variable._children) return null;
|
||||
|
||||
return mapValues(variable._children, transformVariable);
|
||||
}
|
||||
};
|
||||
|
||||
const transform = variablesContainer => {
|
||||
if (!variablesContainer || !variablesContainer._variables || !variablesContainer._variables.items)
|
||||
return null;
|
||||
|
||||
return mapValues(variablesContainer._variables.items, transformVariable);
|
||||
};
|
||||
|
||||
const handleEdit = (edit, { onCall, onEdit }: Props) => {
|
||||
// Reconstruct the path to the variable to edit
|
||||
const path = ['_variables', 'items'];
|
||||
edit.namespace.forEach(variableName => {
|
||||
path.push(variableName);
|
||||
path.push('_children');
|
||||
});
|
||||
path.push(edit.name);
|
||||
|
||||
// Guess the type of the new value (number or string)
|
||||
if (parseFloat(edit.new_value).toString() === edit.new_value) {
|
||||
path.push('setNumber');
|
||||
onCall(path, [parseFloat(edit.new_value)]);
|
||||
} else {
|
||||
path.push('setString');
|
||||
onCall(path, ['' + edit.new_value]);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export default (props: Props) => (
|
||||
<div style={styles.container}>
|
||||
<ReactJsonView
|
||||
collapsed={false}
|
||||
name={false}
|
||||
src={
|
||||
props.variablesContainer ? transform(props.variablesContainer) : null
|
||||
}
|
||||
enableClipboard={false}
|
||||
displayDataTypes={false}
|
||||
displayObjectSize={false}
|
||||
onEdit={edit => handleEdit(edit, props)}
|
||||
groupArraysAfterLength={50}
|
||||
theme="monokai"
|
||||
/>
|
||||
</div>
|
||||
);
|
81
newIDE/app/src/Debugger/InspectorsList.js
Normal file
@@ -0,0 +1,81 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { List, ListItem } from 'material-ui/List';
|
||||
import get from 'lodash/get';
|
||||
import {
|
||||
type InspectorDescription,
|
||||
type InspectorDescriptionsGetter,
|
||||
type GameData,
|
||||
} from './GDJSInspectorDescriptions';
|
||||
|
||||
type Props = {|
|
||||
gameData: GameData,
|
||||
getInspectorDescriptions: InspectorDescriptionsGetter,
|
||||
onChooseInspector: (
|
||||
InspectorDescription,
|
||||
fullInspectorPath: Array<string>
|
||||
) => void,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
},
|
||||
list: {
|
||||
overflowY: 'scroll',
|
||||
flex: 1,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a visual list of inspectors, using gameData and getInspectorDescriptions
|
||||
*/
|
||||
export default class InspectorsList extends React.Component<Props, void> {
|
||||
_renderInspectorList(
|
||||
gameData: GameData,
|
||||
getInspectorDescriptions: InspectorDescriptionsGetter,
|
||||
path: Array<string>
|
||||
) {
|
||||
return getInspectorDescriptions(gameData).map(inspectorDescription => {
|
||||
if (!inspectorDescription) return null;
|
||||
const fullInspectorPath = path.concat(inspectorDescription.key);
|
||||
|
||||
const getSubInspectors = inspectorDescription.getSubInspectors;
|
||||
const nestedItems = getSubInspectors
|
||||
? this._renderInspectorList(
|
||||
get(gameData, inspectorDescription.key, null),
|
||||
getSubInspectors,
|
||||
fullInspectorPath
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={fullInspectorPath.join('.')}
|
||||
primaryText={inspectorDescription.label}
|
||||
initiallyOpen={!!inspectorDescription.initiallyOpen}
|
||||
onClick={() =>
|
||||
this.props.onChooseInspector(
|
||||
inspectorDescription,
|
||||
fullInspectorPath
|
||||
)}
|
||||
nestedItems={nestedItems}
|
||||
primaryTogglesNestedList
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.gameData ? (
|
||||
<List style={styles.list}>
|
||||
{this._renderInspectorList(
|
||||
this.props.gameData,
|
||||
this.props.getInspectorDescriptions,
|
||||
[]
|
||||
)}
|
||||
</List>
|
||||
) : null;
|
||||
}
|
||||
}
|
41
newIDE/app/src/Debugger/Toolbar.js
Normal file
@@ -0,0 +1,41 @@
|
||||
// @flow
|
||||
import React, { PureComponent } from 'react';
|
||||
import { translate, type TranslatorProps } from 'react-i18next';
|
||||
import { ToolbarGroup } from 'material-ui/Toolbar';
|
||||
import ToolbarIcon from '../UI/ToolbarIcon';
|
||||
import ToolbarSeparator from '../UI/ToolbarSeparator';
|
||||
|
||||
type Props = {|
|
||||
onPlay: () => void,
|
||||
canPlay: boolean,
|
||||
onPause: () => void,
|
||||
canPause: boolean,
|
||||
|} & TranslatorProps;
|
||||
|
||||
type State = {||};
|
||||
|
||||
export class Toolbar extends PureComponent<Props, State> {
|
||||
render() {
|
||||
const { t, onPlay, onPause, canPlay, canPause } = this.props;
|
||||
|
||||
return (
|
||||
<ToolbarGroup lastChild>
|
||||
<ToolbarIcon
|
||||
onClick={onPlay}
|
||||
src="res/ribbon_default/preview32.png"
|
||||
disabled={!canPlay}
|
||||
tooltip={t('Play the game')}
|
||||
/>
|
||||
<ToolbarSeparator />
|
||||
<ToolbarIcon
|
||||
onClick={onPause}
|
||||
src="res/ribbon_default/pause32.png"
|
||||
disabled={!canPause}
|
||||
tooltip={t('Pause the game')}
|
||||
/>
|
||||
</ToolbarGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default translate()(Toolbar);
|
298
newIDE/app/src/Debugger/index.js
Normal file
@@ -0,0 +1,298 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import Toolbar from './Toolbar';
|
||||
import DebuggerContent from './DebuggerContent';
|
||||
import DebuggerSelector from './DebuggerSelector';
|
||||
import { Column } from '../UI/Grid';
|
||||
import PlaceholderLoader from '../UI/PlaceholderLoader';
|
||||
import PlaceholderMessage from '../UI/PlaceholderMessage';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import optionalRequire from '../Utils/OptionalRequire';
|
||||
import EmptyMessage from '../UI/EmptyMessage';
|
||||
const electron = optionalRequire('electron');
|
||||
const ipcRenderer = electron ? electron.ipcRenderer : null;
|
||||
|
||||
//Each game connected to the debugger server is identified by a unique number
|
||||
export type DebuggerId = number;
|
||||
|
||||
type Props = {|
|
||||
project: gdProject,
|
||||
setToolbar: React.Node => void,
|
||||
isActive: boolean,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
debuggerServerStarted: boolean,
|
||||
debuggerServerError: ?any,
|
||||
|
||||
debuggerIds: Array<DebuggerId>,
|
||||
debuggerGameData: { [number]: any },
|
||||
selectedId: DebuggerId,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
container: { flex: 1, display: 'flex' },
|
||||
};
|
||||
|
||||
/**
|
||||
* Start the debugger server, listen to commands received and issue commands to it.
|
||||
* This is only supported on Electron runtime for now.
|
||||
*/
|
||||
export default class Debugger extends React.Component<Props, State> {
|
||||
state = {
|
||||
debuggerServerStarted: false,
|
||||
debuggerServerError: null,
|
||||
debuggerIds: [],
|
||||
debuggerGameData: {},
|
||||
selectedId: 0,
|
||||
};
|
||||
|
||||
updateToolbar() {
|
||||
if (!this.props.isActive) return;
|
||||
|
||||
this.props.setToolbar(
|
||||
<Toolbar
|
||||
onPlay={() => this._play(this.state.selectedId)}
|
||||
onPause={() => this._pause(this.state.selectedId)}
|
||||
canPlay={this._hasSelectedDebugger()}
|
||||
canPause={this._hasSelectedDebugger()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.isActive) {
|
||||
this._startServer();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
if (nextProps.isActive && !this.props.isActive) {
|
||||
this._startServer();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._removeServerListeners();
|
||||
}
|
||||
|
||||
_removeServerListeners = () => {
|
||||
if (!ipcRenderer) return;
|
||||
|
||||
ipcRenderer.removeAllListeners('debugger-send-message-done');
|
||||
ipcRenderer.removeAllListeners('debugger-error-received');
|
||||
ipcRenderer.removeAllListeners('debugger-connection-closed');
|
||||
ipcRenderer.removeAllListeners('debugger-connection-opened');
|
||||
ipcRenderer.removeAllListeners('debugger-start-server-done');
|
||||
ipcRenderer.removeAllListeners('debugger-message-received');
|
||||
};
|
||||
|
||||
_startServer = () => {
|
||||
if (!ipcRenderer) return;
|
||||
|
||||
this.setState({
|
||||
debuggerServerStarted: false,
|
||||
});
|
||||
this._removeServerListeners();
|
||||
|
||||
ipcRenderer.on('debugger-error-received', (event, err) => {
|
||||
this.setState(
|
||||
{
|
||||
debuggerServerError: err,
|
||||
},
|
||||
() => this.updateToolbar()
|
||||
);
|
||||
});
|
||||
|
||||
ipcRenderer.on('debugger-connection-closed', (event, { id }) => {
|
||||
const { debuggerIds, selectedId } = this.state;
|
||||
const remainingDebuggerIds = debuggerIds.filter(
|
||||
debuggerId => debuggerId !== id
|
||||
);
|
||||
this.setState(
|
||||
{
|
||||
debuggerIds: remainingDebuggerIds,
|
||||
selectedId:
|
||||
selectedId !== id
|
||||
? selectedId
|
||||
: remainingDebuggerIds.length
|
||||
? remainingDebuggerIds[remainingDebuggerIds.length - 1]
|
||||
: selectedId,
|
||||
},
|
||||
() => this.updateToolbar()
|
||||
);
|
||||
});
|
||||
|
||||
ipcRenderer.on('debugger-connection-opened', (event, { id }) => {
|
||||
this.setState(
|
||||
{
|
||||
debuggerIds: [...this.state.debuggerIds, id],
|
||||
selectedId: id,
|
||||
},
|
||||
() => this.updateToolbar()
|
||||
);
|
||||
});
|
||||
|
||||
ipcRenderer.on('debugger-start-server-done', event => {
|
||||
this.setState(
|
||||
{
|
||||
debuggerServerStarted: true,
|
||||
},
|
||||
() => this.updateToolbar()
|
||||
);
|
||||
});
|
||||
|
||||
ipcRenderer.on('debugger-message-received', (event, { id, message }) => {
|
||||
console.log('Processing message received for debugger');
|
||||
try {
|
||||
const data = JSON.parse(message);
|
||||
this._handleMessage(id, data);
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
'Error while parsing message received from debugger client:',
|
||||
e
|
||||
);
|
||||
}
|
||||
});
|
||||
ipcRenderer.send('debugger-start-server');
|
||||
};
|
||||
|
||||
_handleMessage = (id: DebuggerId, data: any) => {
|
||||
if (data.command === 'dump') {
|
||||
this.setState({
|
||||
debuggerGameData: {
|
||||
...this.state.debuggerGameData,
|
||||
[id]: data.payload,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
console.warn(
|
||||
'Unknown command received from debugger client:',
|
||||
data.command
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
_play = (id: DebuggerId) => {
|
||||
if (!ipcRenderer) return;
|
||||
|
||||
ipcRenderer.send('debugger-send-message', {
|
||||
id,
|
||||
message: '{"command": "play"}',
|
||||
});
|
||||
};
|
||||
|
||||
_pause = (id: DebuggerId) => {
|
||||
if (!ipcRenderer) return;
|
||||
|
||||
ipcRenderer.send('debugger-send-message', {
|
||||
id,
|
||||
message: '{"command": "pause"}',
|
||||
});
|
||||
};
|
||||
|
||||
_refresh = (id: DebuggerId) => {
|
||||
if (!ipcRenderer) return;
|
||||
|
||||
ipcRenderer.send('debugger-send-message', {
|
||||
id,
|
||||
message: '{"command": "refresh"}',
|
||||
});
|
||||
};
|
||||
|
||||
_edit = (id: DebuggerId, path: Array<string>, newValue: any) => {
|
||||
if (!ipcRenderer) return false;
|
||||
|
||||
ipcRenderer.send('debugger-send-message', {
|
||||
id,
|
||||
message: JSON.stringify({
|
||||
command: 'set',
|
||||
path,
|
||||
newValue,
|
||||
}),
|
||||
});
|
||||
|
||||
setTimeout(() => this._refresh(id), 100);
|
||||
return true;
|
||||
};
|
||||
|
||||
_call = (id: DebuggerId, path: Array<string>, args: Array<any>) => {
|
||||
if (!ipcRenderer) return false;
|
||||
|
||||
ipcRenderer.send('debugger-send-message', {
|
||||
id,
|
||||
message: JSON.stringify({
|
||||
command: 'call',
|
||||
path,
|
||||
args,
|
||||
}),
|
||||
});
|
||||
|
||||
setTimeout(() => this._refresh(id), 100);
|
||||
return true;
|
||||
};
|
||||
|
||||
_hasSelectedDebugger = () => {
|
||||
const { selectedId, debuggerIds } = this.state;
|
||||
return debuggerIds.indexOf(selectedId) !== -1;
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
debuggerServerError,
|
||||
debuggerServerStarted,
|
||||
selectedId,
|
||||
debuggerIds,
|
||||
debuggerGameData,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<Paper style={styles.container}>
|
||||
{!debuggerServerStarted &&
|
||||
!debuggerServerError && (
|
||||
<PlaceholderMessage>
|
||||
<PlaceholderLoader />
|
||||
<p>Debugger is starting...</p>
|
||||
</PlaceholderMessage>
|
||||
)}
|
||||
{!debuggerServerStarted &&
|
||||
debuggerServerError && (
|
||||
<PlaceholderMessage>
|
||||
<p>
|
||||
Unable to start the debugger server! Make sure that you are
|
||||
authorized to run servers on this computer.
|
||||
</p>
|
||||
</PlaceholderMessage>
|
||||
)}
|
||||
{debuggerServerStarted && (
|
||||
<Column expand noMargin>
|
||||
<DebuggerSelector
|
||||
selectedId={selectedId}
|
||||
debuggerIds={debuggerIds}
|
||||
onChooseDebugger={id =>
|
||||
this.setState({
|
||||
selectedId: id,
|
||||
})}
|
||||
/>
|
||||
{this._hasSelectedDebugger() && (
|
||||
<DebuggerContent
|
||||
gameData={debuggerGameData[selectedId]}
|
||||
onPlay={() => this._play(selectedId)}
|
||||
onPause={() => this._pause(selectedId)}
|
||||
onRefresh={() => this._refresh(selectedId)}
|
||||
onEdit={(path, args) => this._edit(selectedId, path, args)}
|
||||
onCall={(path, args) => this._call(selectedId, path, args)}
|
||||
/>
|
||||
)}
|
||||
{!this._hasSelectedDebugger() && (
|
||||
<EmptyMessage>
|
||||
Run a preview and you will be able to inspect it with the
|
||||
debugger.
|
||||
</EmptyMessage>
|
||||
)}
|
||||
</Column>
|
||||
)}
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,15 +1,49 @@
|
||||
import React, { Component } from 'react';
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import InlinePopover from './InlinePopover';
|
||||
import ParameterRenderingService from './InstructionEditor/ParameterRenderingService';
|
||||
import {
|
||||
type ResourceSource,
|
||||
type ChooseResourceFunction,
|
||||
} from '../ResourcesList/ResourceSource.flow';
|
||||
const gd = global.gd;
|
||||
|
||||
export default class InlineParameterEditor extends Component {
|
||||
type Props = {|
|
||||
project: gdProject,
|
||||
layout: gdLayout,
|
||||
|
||||
open: boolean,
|
||||
onRequestClose: () => void,
|
||||
onChange: (string) => void,
|
||||
|
||||
instruction: gdInstruction,
|
||||
isCondition: boolean,
|
||||
parameterIndex: number,
|
||||
|
||||
anchorEl: ?any,
|
||||
|
||||
resourceSources: Array<ResourceSource>,
|
||||
onChooseResource: ChooseResourceFunction,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
isValid: boolean,
|
||||
parameterMetadata: ?gdParameterMetadata,
|
||||
instruction: ?gdInstruction,
|
||||
ParameterComponent: ?any,
|
||||
|};
|
||||
|
||||
export default class InlineParameterEditor extends React.Component<Props, State> {
|
||||
state = {
|
||||
isValid: false,
|
||||
parameterMetadata: null,
|
||||
ParameterComponent: null,
|
||||
instruction: null,
|
||||
};
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
_field: ?any;
|
||||
|
||||
componentWillReceiveProps(newProps: Props) {
|
||||
if (
|
||||
(newProps.open && !this.props.open) ||
|
||||
newProps.instruction !== this.props.instruction
|
||||
@@ -26,7 +60,7 @@ export default class InlineParameterEditor extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
_loadComponentFromInstruction(props) {
|
||||
_loadComponentFromInstruction(props: Props) {
|
||||
const { project, isCondition, instruction, parameterIndex } = props;
|
||||
if (!instruction) return this._unload();
|
||||
|
||||
@@ -81,6 +115,8 @@ export default class InlineParameterEditor extends Component {
|
||||
ref={field => (this._field = field)}
|
||||
parameterRenderingService={ParameterRenderingService}
|
||||
isInline
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
/>
|
||||
</InlinePopover>
|
||||
);
|
||||
|
@@ -114,6 +114,8 @@ export default class InstructionParametersEditor extends Component {
|
||||
this.forceUpdate();
|
||||
}}
|
||||
parameterRenderingService={ParameterRenderingService}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@@ -0,0 +1,35 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
import ResourceSelector from '../../../ResourcesList/ResourceSelector';
|
||||
import { type ParameterFieldProps } from './ParameterFieldProps.flow';
|
||||
|
||||
export default class AudioResourceField extends Component<
|
||||
ParameterFieldProps,
|
||||
void
|
||||
> {
|
||||
focus() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.resourceSources || !this.props.onChooseResource) {
|
||||
console.error(
|
||||
'Missing resourceSources or onChooseResource for AudioResourceField'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ResourceSelector
|
||||
project={this.props.project}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
resourceKind="audio"
|
||||
fullWidth
|
||||
initialResourceName={this.props.value}
|
||||
onChange={this.props.onChange}
|
||||
floatingLabelText="Choose the audio file to use"
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,4 +1,10 @@
|
||||
// @flow
|
||||
import {
|
||||
type ResourceSource,
|
||||
type ChooseResourceFunction,
|
||||
} from '../../../ResourcesList/ResourceSource.flow';
|
||||
|
||||
|
||||
export type ParameterFieldProps = {|
|
||||
parameterMetadata?: gdParameterMetadata,
|
||||
project: gdProject,
|
||||
@@ -10,4 +16,6 @@ export type ParameterFieldProps = {|
|
||||
components: any,
|
||||
getParameterComponent: (type: string) => any,
|
||||
},
|
||||
resourceSources?: Array<ResourceSource>,
|
||||
onChooseResource?: ChooseResourceFunction,
|
||||
|};
|
||||
|
@@ -14,6 +14,7 @@ import SceneVariableField from './ParameterFields/SceneVariableField';
|
||||
import GlobalVariableField from './ParameterFields/GlobalVariableField';
|
||||
import ObjectVariableField from './ParameterFields/ObjectVariableField';
|
||||
import LayerField from './ParameterFields/LayerField';
|
||||
import AudioResourceField from './ParameterFields/AudioResourceField';
|
||||
const gd = global.gd;
|
||||
|
||||
const components = {
|
||||
@@ -33,8 +34,8 @@ const components = {
|
||||
layer: LayerField,
|
||||
key: KeyField,
|
||||
file: DefaultField, //TODO
|
||||
musicfile: DefaultField, //TODO
|
||||
soundfile: DefaultField, //TODO
|
||||
musicfile: AudioResourceField,
|
||||
soundfile: AudioResourceField,
|
||||
color: DefaultField, //TODO
|
||||
police: DefaultField, //TODO
|
||||
joyaxis: DefaultField, //TODO
|
||||
|
@@ -42,6 +42,8 @@ export default class InstructionEditor extends Component {
|
||||
layout={layout}
|
||||
isCondition={isCondition}
|
||||
instruction={instruction}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
/>
|
||||
</Paper>
|
||||
</div>
|
||||
|
@@ -47,12 +47,26 @@ export class Toolbar extends PureComponent {
|
||||
/>
|
||||
)}
|
||||
{this.props.showNetworkPreviewButton && (
|
||||
<ToolbarIcon
|
||||
onClick={this.props.onNetworkPreview}
|
||||
src="res/ribbon_default/networkpreview32.png"
|
||||
tooltip={t('Preview the scene on a mobile or tablet connected to your wifi')}
|
||||
/>
|
||||
)}
|
||||
<IconMenu
|
||||
iconButtonElement={
|
||||
<ToolbarIcon
|
||||
src="res/ribbon_default/bug32.png"
|
||||
tooltip={t('Advanced preview options (debugger, network preview...)')}
|
||||
/>
|
||||
}
|
||||
buildMenuTemplate={() => [
|
||||
{
|
||||
label: 'Network preview (Preview over WiFi/LAN)',
|
||||
click: () => this.props.onNetworkPreview(),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Preview with debugger',
|
||||
click: () => this.props.onOpenDebugger(),
|
||||
},
|
||||
]}
|
||||
/>)
|
||||
}
|
||||
{this.props.showPreviewButton && <ToolbarSeparator />}
|
||||
<ToolbarIcon
|
||||
onClick={this.props.onAddStandardEvent}
|
||||
|
@@ -105,6 +105,10 @@ export default class EventsSheet extends Component {
|
||||
showNetworkPreviewButton={this.props.showNetworkPreviewButton}
|
||||
onPreview={() => this.props.onPreview({})}
|
||||
onNetworkPreview={() => this.props.onPreview({networkPreview: true})}
|
||||
onOpenDebugger={() => {
|
||||
this.props.onOpenDebugger();
|
||||
this.props.onPreview({});
|
||||
}}
|
||||
canUndo={canUndo(this.state.history)}
|
||||
canRedo={canRedo(this.state.history)}
|
||||
undo={this.undo}
|
||||
@@ -516,6 +520,8 @@ export default class EventsSheet extends Component {
|
||||
inlineEditingChangesMade: true,
|
||||
});
|
||||
}}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
/>
|
||||
<ContextMenu
|
||||
ref={eventContextMenu => (this.eventContextMenu = eventContextMenu)}
|
||||
@@ -654,6 +660,8 @@ export default class EventsSheet extends Component {
|
||||
this.closeInstructionEditor(true);
|
||||
this._eventsTree.forceEventsUpdate();
|
||||
}}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
90
newIDE/app/src/HelpFinder/DocSearchArea.js
Normal file
@@ -0,0 +1,90 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import TextField from 'material-ui/TextField';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import Window from '../Utils/Window';
|
||||
import './DocSearchOverrides.css';
|
||||
import { Column } from '../UI/Grid';
|
||||
|
||||
const styles = {
|
||||
dropdownMenuContainer: {
|
||||
maxHeight: 300,
|
||||
overflowY: 'scroll',
|
||||
},
|
||||
poweredByText: {
|
||||
textAlign: 'right',
|
||||
opacity: 0.8,
|
||||
},
|
||||
};
|
||||
|
||||
export default class DocSearchArea extends React.Component<*, *> {
|
||||
componentDidMount() {
|
||||
if (!global.docsearch) {
|
||||
console.warn("docsearch not found - DocSearchArea won't work");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
global.docsearch({
|
||||
apiKey: '69c73fc1a710bb79543d4b91f6b81c08',
|
||||
indexName: 'gdevelop',
|
||||
inputSelector: '#help-finder-search-bar',
|
||||
debug: true, // Set debug to true if you want to inspect the dropdown
|
||||
handleSelected: (input, event, suggestion) => {
|
||||
Window.openExternalURL(suggestion.url);
|
||||
this.props.onChange('');
|
||||
},
|
||||
autocompleteOptions: {
|
||||
appendTo: true,
|
||||
hint: false,
|
||||
dropdownMenuContainer: '#help-finder-dropdown-menu-container',
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Error while loading docsearch:', e);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<TextField
|
||||
id={'help-finder-search-bar'}
|
||||
fullWidth
|
||||
hintText={'Enter what you want to build.'}
|
||||
value={this.props.value}
|
||||
onChange={(e, text) => this.props.onChange(text)}
|
||||
/>
|
||||
<div
|
||||
id="help-finder-dropdown-menu-container"
|
||||
className="algolia-autocomplete"
|
||||
style={{
|
||||
...styles.dropdownMenuContainer,
|
||||
visibility: !this.props.value ? 'hidden' : undefined,
|
||||
}}
|
||||
/>
|
||||
{!this.props.value && (
|
||||
<React.Fragment>
|
||||
<p>Examples:</p>
|
||||
<Column expand>
|
||||
<p>
|
||||
Coins in platformer<br />
|
||||
Export on Android<br />
|
||||
Add a score<br />
|
||||
Move enemies<br />
|
||||
...<br />
|
||||
</p>
|
||||
</Column>
|
||||
<p style={styles.poweredByText}>
|
||||
This search is powered by{' '}
|
||||
<FlatButton
|
||||
onClick={() => Window.openExternalURL('http://algolia.com/')}
|
||||
label="Algolia"
|
||||
/>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
6
newIDE/app/src/HelpFinder/DocSearchOverrides.css
Normal file
@@ -0,0 +1,6 @@
|
||||
/* The dropdown is inserted into a container and should always take the width
|
||||
of this container. */
|
||||
.algolia-autocomplete .ds-dropdown-menu {
|
||||
min-width: 0 !important;
|
||||
max-width: initial !important;
|
||||
}
|
88
newIDE/app/src/HelpFinder/index.js
Normal file
@@ -0,0 +1,88 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import Dialog from '../UI/Dialog';
|
||||
import FlatButton from 'material-ui/FlatButton';
|
||||
import Window from '../Utils/Window';
|
||||
import DocSearchArea from './DocSearchArea';
|
||||
import debounce from 'lodash/debounce';
|
||||
import {
|
||||
sendHelpFinderOpened,
|
||||
sendHelpSearch,
|
||||
} from '../Utils/Analytics/EventSender';
|
||||
|
||||
type Props = {|
|
||||
open: boolean,
|
||||
onClose: () => void,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
searchText: string,
|
||||
|};
|
||||
|
||||
export default class HelpFinder extends React.Component<Props, State> {
|
||||
state = {
|
||||
searchText: '',
|
||||
};
|
||||
|
||||
componentWillReceiveProps(newProps: Props) {
|
||||
if (newProps.open && !this.props.open) {
|
||||
sendHelpFinderOpened();
|
||||
}
|
||||
}
|
||||
|
||||
_handleSearchTextChange = (searchText: string) => {
|
||||
this.setState({
|
||||
searchText,
|
||||
});
|
||||
this._sendHelpSearch();
|
||||
};
|
||||
|
||||
_sendHelpSearch = debounce(() => {
|
||||
if (this.state.searchText) sendHelpSearch(this.state.searchText.trim());
|
||||
}, 1300);
|
||||
|
||||
render() {
|
||||
const { open, onClose } = this.props;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title="Help!"
|
||||
onRequestClose={onClose}
|
||||
actions={[
|
||||
<FlatButton
|
||||
label="Close"
|
||||
key="close"
|
||||
primary={false}
|
||||
onClick={onClose}
|
||||
/>,
|
||||
]}
|
||||
secondaryActions={[
|
||||
<FlatButton
|
||||
key="forum"
|
||||
primary={false}
|
||||
onClick={() => {
|
||||
Window.openExternalURL('http://forum.compilgames.net');
|
||||
}}
|
||||
label="Community forum"
|
||||
/>,
|
||||
<FlatButton
|
||||
key="wiki"
|
||||
primary={false}
|
||||
onClick={() => {
|
||||
Window.openExternalURL(
|
||||
'http://wiki.compilgames.net/doku.php/gdevelop5/start'
|
||||
);
|
||||
}}
|
||||
label="Wiki"
|
||||
/>,
|
||||
]}
|
||||
open={open}
|
||||
>
|
||||
<DocSearchArea
|
||||
value={this.state.searchText}
|
||||
onChange={this._handleSearchTextChange}
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
@@ -52,9 +52,9 @@ export default class InstancesEditorContainer extends Component {
|
||||
if (this.keyboardShortcuts.shouldZoom()) {
|
||||
this.zoomBy(event.wheelDelta / 5000);
|
||||
} else if (this.keyboardShortcuts.shouldScrollHorizontally()) {
|
||||
this.viewPosition.scrollBy(-event.wheelDelta / 20, 0);
|
||||
this.viewPosition.scrollBy(-event.wheelDelta / 10, 0);
|
||||
} else {
|
||||
this.viewPosition.scrollBy(0, -event.wheelDelta / 20);
|
||||
this.viewPosition.scrollBy(event.deltaX / 10, event.deltaY / 10);
|
||||
}
|
||||
|
||||
if (this.props.onViewPositionChanged) {
|
||||
@@ -69,6 +69,12 @@ export default class InstancesEditorContainer extends Component {
|
||||
this.pixiRenderer.view.addEventListener('blur', e => {
|
||||
this.keyboardShortcuts.blur();
|
||||
});
|
||||
this.pixiRenderer.view.addEventListener('mouseover', e => {
|
||||
this.keyboardShortcuts.focus();
|
||||
});
|
||||
this.pixiRenderer.view.addEventListener('mouseout', e => {
|
||||
this.keyboardShortcuts.blur();
|
||||
});
|
||||
|
||||
this.pixiContainer = new PIXI.Container();
|
||||
|
||||
@@ -113,7 +119,6 @@ export default class InstancesEditorContainer extends Component {
|
||||
});
|
||||
this.pixiContainer.addChild(this.grid.getPixiObject());
|
||||
|
||||
// TODO: This should probably be moved up in the InstancesFullEditor component.
|
||||
this.keyboardShortcuts = new KeyboardShortcuts({
|
||||
onDelete: this.props.onDeleteSelection,
|
||||
onMove: this.moveSelection,
|
||||
@@ -506,12 +511,12 @@ export default class InstancesEditorContainer extends Component {
|
||||
pauseSceneRendering = () => {
|
||||
if (this.nextFrame) cancelAnimationFrame(this.nextFrame);
|
||||
this._renderingPaused = true;
|
||||
}
|
||||
};
|
||||
|
||||
restartSceneRendering = () => {
|
||||
this._renderingPaused = false;
|
||||
this._renderScene();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.props.project) return null;
|
||||
|
@@ -3,6 +3,7 @@ import * as React from 'react';
|
||||
import { serializeToJSObject } from '../../Utils/Serializer';
|
||||
import { rgbToHexNumber } from '../../Utils/ColorTransformer';
|
||||
|
||||
//TODO: try BaseEditor<Props,State>
|
||||
export default class BaseEditor extends React.Component<*,*> {
|
||||
static defaultProps = {
|
||||
setToolbar: () => {},
|
||||
|
56
newIDE/app/src/MainFrame/Editors/DebuggerEditor.js
Normal file
@@ -0,0 +1,56 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import Debugger from '../../Debugger';
|
||||
import BaseEditor from './BaseEditor';
|
||||
import SubscriptionChecker from '../../Profile/SubscriptionChecker';
|
||||
|
||||
export default class DebuggerEditor extends BaseEditor {
|
||||
editor: ?Debugger;
|
||||
_subscriptionChecker: ?SubscriptionChecker;
|
||||
state = {
|
||||
subscriptionChecked: false,
|
||||
};
|
||||
|
||||
updateToolbar() {
|
||||
if (this.editor) this.editor.updateToolbar();
|
||||
}
|
||||
|
||||
componentWillReceiveProps() {
|
||||
this._checkHasSubscription();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._checkHasSubscription();
|
||||
}
|
||||
|
||||
_checkHasSubscription() {
|
||||
if (
|
||||
this._subscriptionChecker &&
|
||||
this.props.isActive &&
|
||||
!this.state.subscriptionChecked
|
||||
) {
|
||||
this._subscriptionChecker.checkHasSubscription();
|
||||
this.setState({
|
||||
subscriptionChecked: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Debugger {...this.props} ref={editor => (this.editor = editor)} />
|
||||
<SubscriptionChecker
|
||||
ref={subscriptionChecker =>
|
||||
(this._subscriptionChecker = subscriptionChecker)}
|
||||
onChangeSubscription={() => {
|
||||
if (this.props.onChangeSubscription)
|
||||
this.props.onChangeSubscription();
|
||||
}}
|
||||
title="Debugger"
|
||||
mode="try"
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
@@ -5,7 +5,7 @@ import { serializeToJSObject } from '../../Utils/Serializer';
|
||||
import BaseEditor from './BaseEditor';
|
||||
|
||||
export default class EventsEditor extends BaseEditor {
|
||||
editor: ?typeof EventsSheet;
|
||||
editor: ?EventsSheet;
|
||||
|
||||
updateToolbar() {
|
||||
if (this.editor) this.editor.updateToolbar();
|
||||
@@ -45,6 +45,8 @@ export default class EventsEditor extends BaseEditor {
|
||||
events={layout.getEvents()}
|
||||
onPreview={(options) => this.props.onPreview(project, layout, options)}
|
||||
onOpenExternalEvents={this.props.onOpenExternalEvents}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@@ -98,6 +98,8 @@ export default class ExternalEventsEditor extends BaseEditor {
|
||||
onPreview={() => this.props.onPreview(project, layout)}
|
||||
onOpenSettings={this.openLayoutChooser}
|
||||
onOpenExternalEvents={this.props.onOpenExternalEvents}
|
||||
resourceSources={this.props.resourceSources}
|
||||
onChooseResource={this.props.onChooseResource}
|
||||
/>
|
||||
)}
|
||||
{!layout && (
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import RaisedButton from 'material-ui/RaisedButton';
|
||||
import InstancesFullEditor from '../../SceneEditor/InstancesFullEditor';
|
||||
import SceneEditor from '../../SceneEditor';
|
||||
import { serializeToJSObject } from '../../Utils/Serializer';
|
||||
import PlaceholderMessage from '../../UI/PlaceholderMessage';
|
||||
import BaseEditor from './BaseEditor';
|
||||
@@ -15,7 +15,7 @@ const styles = {
|
||||
};
|
||||
|
||||
export default class ExternalLayoutEditor extends BaseEditor {
|
||||
editor: ?typeof InstancesFullEditor;
|
||||
editor: ?typeof SceneEditor;
|
||||
state = {
|
||||
layoutChooserOpen: false,
|
||||
};
|
||||
@@ -89,7 +89,7 @@ export default class ExternalLayoutEditor extends BaseEditor {
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
{layout && (
|
||||
<InstancesFullEditor
|
||||
<SceneEditor
|
||||
{...this.props}
|
||||
ref={editor => (this.editor = editor)}
|
||||
project={project}
|
||||
@@ -100,6 +100,7 @@ export default class ExternalLayoutEditor extends BaseEditor {
|
||||
)}
|
||||
onPreview={options =>
|
||||
this.props.onPreview(project, layout, externalLayout, options)}
|
||||
onOpenDebugger={this.props.onOpenDebugger}
|
||||
onOpenMoreSettings={this.openLayoutChooser}
|
||||
isActive={isActive}
|
||||
/>
|
||||
|