From 64485468bee2bdd1f45fd378ac704a7b77539cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Thu, 3 Aug 2023 17:15:27 +0200 Subject: [PATCH 1/6] [3D car coin hunt] Add leaderboards. --- .../3d-car-coin-hunt/3d-car-coin-hunt.json | 6924 ++++++++++++++++- .../assets/Grey Button_Hovered.png | Bin 0 -> 2208 bytes .../assets/Grey Button_Idle.png | Bin 0 -> 2353 bytes .../assets/Grey Button_Pressed.png | Bin 0 -> 2118 bytes 4 files changed, 6908 insertions(+), 16 deletions(-) create mode 100644 examples/3d-car-coin-hunt/assets/Grey Button_Hovered.png create mode 100644 examples/3d-car-coin-hunt/assets/Grey Button_Idle.png create mode 100644 examples/3d-car-coin-hunt/assets/Grey Button_Pressed.png diff --git a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json index 721f2f706..f595c8504 100644 --- a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json +++ b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json @@ -476,6 +476,54 @@ "name": "ios-icon-20.png", "smoothed": true, "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/Grey Button_Hovered.png", + "kind": "image", + "metadata": "", + "name": "Grey Button_Hovered.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/b43e0035dca80ea2fad5c5d65de926dae0185038e5f9cb21d5f20234f30d1c76_Grey Button_Hovered.png", + "name": "Grey Button_Hovered.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Grey Button_Idle.png", + "kind": "image", + "metadata": "", + "name": "Grey Button_Idle.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/da7fc2efa0882eb5dfa0266315f2483c2f68d86a6751dc309ea9e9d0dd4759ba_Grey Button_Idle.png", + "name": "Grey Button_Idle.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Grey Button_Pressed.png", + "kind": "image", + "metadata": "", + "name": "Grey Button_Pressed.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/49c35e14af0e1f7aae407455cb944de96328955870e5f1500f63723ad879a42e_Grey Button_Pressed.png", + "name": "Grey Button_Pressed.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Grey Button_Idle.png", + "kind": "image", + "metadata": "", + "name": "assets\\Grey Button_Idle.png", + "smoothed": true, + "userAdded": true } ], "resourceFolders": [] @@ -487,8 +535,8 @@ { "b": 79, "disableInputWhenNotFocused": true, - "mangledName": "GameScene", - "name": "GameScene", + "mangledName": "Game", + "name": "Game", "r": 80, "standardSortMethod": true, "stopSoundsOnStartup": true, @@ -3007,6 +3055,7 @@ }, "childrenContent": { "Border": { + "adaptCollisionMaskAutomatically": false, "updateIfNotVisible": false, "animations": [ { @@ -3041,6 +3090,7 @@ ] }, "Thumb": { + "adaptCollisionMaskAutomatically": false, "updateIfNotVisible": false, "animations": [ { @@ -3100,6 +3150,7 @@ }, "childrenContent": { "Border": { + "adaptCollisionMaskAutomatically": false, "updateIfNotVisible": false, "animations": [ { @@ -3134,6 +3185,7 @@ ] }, "Thumb": { + "adaptCollisionMaskAutomatically": false, "updateIfNotVisible": false, "animations": [ { @@ -3433,6 +3485,7 @@ } }, { + "adaptCollisionMaskAutomatically": false, "assetStoreId": "", "name": "Arrow", "tags": "", @@ -3540,7 +3593,7 @@ "parameters": [ "BestTimeText", "=", - "\"Best: \" + ToString(ceilTo(Variable(HighScore), 2))" + "\"Best: \" + TimeFormatter::SecondsToHHMMSS000(GlobalVariable(HighScore))" ] }, { @@ -3717,7 +3770,7 @@ "parameters": [ "TimeText", "=", - "\"Time: \" + ToString(ceilTo(TimerElapsedTime(\"Time\"), 2))" + "\"Time: \" + TimeFormatter::SecondsToHHMMSS000(TimerElapsedTime(\"Time\"))" ] } ] @@ -4410,6 +4463,41 @@ } ], "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "HighScore", + ">=", + "TimerElapsedTime(\"Time\")" + ] + } + ], + "actions": [ + { + "type": { + "value": "Wait" + }, + "parameters": [ + "1.5" + ] + }, + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"Game\"", + "" + ] + } + ] + }, { "type": "BuiltinCommonInstructions::Standard", "conditions": [ @@ -4435,6 +4523,16 @@ "TimerElapsedTime(\"Time\")" ] }, + { + "type": { + "value": "ModVarGlobal" + }, + "parameters": [ + "Score", + "=", + "Variable(HighScore)" + ] + }, { "type": { "value": "EcrireFichierExp" @@ -4453,13 +4551,7 @@ "BestTimeText", "\"248;231;28\"" ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ + }, { "type": { "value": "Wait" @@ -4474,7 +4566,7 @@ }, "parameters": [ "", - "\"GameScene\"", + "\"Leaderboard\"", "" ] } @@ -4698,10 +4790,6808 @@ "scaleY": 100 } ] - } - ], - "externalEvents": [], - "eventsFunctionsExtensions": [ + }, + { + "b": 0, + "disableInputWhenNotFocused": true, + "mangledName": "Leaderboard", + "name": "Leaderboard", + "r": 0, + "standardSortMethod": true, + "stopSoundsOnStartup": true, + "title": "", + "v": 0, + "uiSettings": { + "grid": true, + "gridType": "rectangular", + "gridWidth": 16, + "gridHeight": 16, + "gridOffsetX": 0, + "gridOffsetY": 0, + "gridColor": 16777215, + "gridAlpha": 0.21, + "snap": true, + "zoomFactor": 0.6652993502634535, + "windowMask": false + }, + "objectsGroups": [ + { + "name": "PanelContent", + "objects": [ + { + "name": "ScoreText" + }, + { + "name": "PlayerNameInput" + }, + { + "name": "SubmitButton" + }, + { + "name": "RestartButton" + } + ] + } + ], + "variables": [ + { + "name": "LeaderboardScore", + "type": "string", + "value": "" + } + ], + "instances": [ + { + "angle": 0, + "customSize": true, + "height": 64, + "layer": "", + "name": "Platform", + "persistentUuid": "c2c6a11c-e8f8-4ee6-aedb-369f62303136", + "width": 1152, + "x": -96, + "y": 512, + "zOrder": 14, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "height": 896, + "layer": "3D", + "name": "Background", + "persistentUuid": "968c9c47-08c4-44eb-917a-906d2ecee36b", + "width": 1024, + "x": -32, + "y": -320, + "zOrder": 15, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 67, + "layer": "", + "name": "ScoreText", + "persistentUuid": "722f1233-75ba-4128-8905-4ac5dd26bc1e", + "width": 384, + "x": 386, + "y": 172, + "zOrder": 18, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "height": 96, + "layer": "", + "name": "PlayerNameInput", + "persistentUuid": "a681abd2-5235-4165-a003-4a9553d79cb5", + "width": 416, + "x": 344, + "y": 288, + "zOrder": 19, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": false, + "height": 0, + "layer": "", + "name": "RestartButton", + "persistentUuid": "9e303562-d182-4829-a5eb-148a1af72803", + "width": 0, + "x": 528, + "y": 448, + "zOrder": 35, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "height": 106, + "layer": "", + "name": "SubmitButton", + "persistentUuid": "3aa859c1-2135-4384-a300-bfb28b424a52", + "width": 128, + "x": 824, + "y": 278, + "zOrder": 37, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + }, + { + "angle": 0, + "customSize": true, + "depth": 0, + "height": 480, + "layer": "", + "name": "Panel", + "persistentUuid": "ef024407-8612-4ce2-99b1-0f3e932160eb", + "width": 688, + "x": 304, + "y": 128, + "zOrder": 1, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + } + ], + "objects": [ + { + "assetStoreId": "", + "bold": false, + "italic": false, + "name": "ScoreText", + "smoothed": true, + "tags": "", + "type": "TextObject::Text", + "underlined": false, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "Sticker", + "type": "Sticker::Sticker", + "OnlyFollowPosition": true + } + ], + "string": "Score", + "font": "", + "textAlignment": "", + "characterSize": 60, + "color": { + "b": 79, + "g": 72, + "r": 72 + } + }, + { + "assetStoreId": "", + "name": "PlayerNameInput", + "tags": "", + "type": "TextInput::TextInputObject", + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "Sticker", + "type": "Sticker::Sticker", + "OnlyFollowPosition": true + } + ], + "content": { + "initialValue": "", + "placeholder": "PlayerName", + "fontResourceName": "", + "fontSize": 60, + "inputType": "text", + "textColor": "72;72;79", + "fillColor": "231;232;243", + "fillOpacity": 255, + "borderColor": "255;255;255", + "borderOpacity": 255, + "borderWidth": 6, + "readOnly": false, + "disabled": false + } + }, + { + "assetStoreId": "bfab3a269992cf43081e2cb8053c28aaef11f2f9e0d0cbdc00207ea271f69c2c", + "name": "SubmitButton", + "tags": "", + "type": "PanelSpriteButton::PanelSpriteButton", + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "Sticker", + "type": "Sticker::Sticker", + "OnlyFollowPosition": true + } + ], + "content": { + "LeftPadding": 16, + "RightPadding": 16, + "PressedLabelOffsetY": 10, + "BottomPadding": 32, + "TopPadding": 16, + "HoveredFadeOutDuration": 0.25 + }, + "childrenContent": { + "Hovered": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Hovered.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Idle": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Idle.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Label": { + "bold": false, + "italic": false, + "smoothed": true, + "underlined": false, + "string": "🡲", + "font": "", + "textAlignment": "center", + "characterSize": 60, + "color": { + "b": 79, + "g": 72, + "r": 72 + } + }, + "Pressed": { + "bottomMargin": 16, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Pressed.png", + "tiled": true, + "topMargin": 32, + "width": 256 + } + } + }, + { + "assetStoreId": "bfab3a269992cf43081e2cb8053c28aaef11f2f9e0d0cbdc00207ea271f69c2c", + "name": "RestartButton", + "tags": "", + "type": "PanelSpriteButton::PanelSpriteButton", + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "Sticker", + "type": "Sticker::Sticker", + "OnlyFollowPosition": true + } + ], + "content": { + "LeftPadding": 16, + "RightPadding": 16, + "PressedLabelOffsetY": 10, + "BottomPadding": 32, + "TopPadding": 16, + "HoveredFadeOutDuration": 0.25 + }, + "childrenContent": { + "Hovered": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Hovered.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Idle": { + "bottomMargin": 32, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Idle.png", + "tiled": true, + "topMargin": 16, + "width": 256 + }, + "Label": { + "bold": false, + "italic": false, + "smoothed": true, + "underlined": false, + "string": "Restart", + "font": "", + "textAlignment": "center", + "characterSize": 60, + "color": { + "b": 79, + "g": 72, + "r": 72 + } + }, + "Pressed": { + "bottomMargin": 16, + "height": 106, + "leftMargin": 16, + "rightMargin": 16, + "texture": "Grey Button_Pressed.png", + "tiled": true, + "topMargin": 32, + "width": 256 + } + } + }, + { + "assetStoreId": "", + "bottomMargin": 32, + "height": 128, + "leftMargin": 16, + "name": "Panel", + "rightMargin": 16, + "tags": "", + "texture": "assets\\Grey Button_Idle.png", + "tiled": false, + "topMargin": 16, + "type": "PanelSpriteObject::PanelSprite", + "width": 128, + "variables": [], + "effects": [], + "behaviors": [] + }, + { + "assetStoreId": "b8200f0619b25c76e3d392f1d0d16d7547bf1c96097bc23af81b68cf11e57677", + "name": "Coin", + "tags": "", + "type": "Scene3D::Model3DObject", + "variables": [ + { + "folded": true, + "name": "Lane", + "type": "number", + "value": 0 + } + ], + "effects": [], + "behaviors": [ + { + "name": "ScreenWrap", + "type": "ScreenWrap::ScreenWrap", + "HorizontalWrapping": false, + "VerticalWrapping": true, + "BorderTop": 0, + "BorderLeft": 0, + "BorderRight": 0, + "BorderBottom": 0, + "TriggerOffset": 500 + } + ], + "content": { + "centerLocation": "ModelOrigin", + "depth": 64, + "height": 64, + "keepAspectRatio": true, + "materialType": "StandardWithoutMetalness", + "modelResourceName": "Coin.glb", + "originLocation": "ModelOrigin", + "rotationX": 0, + "rotationY": 0, + "rotationZ": 0, + "width": 64, + "animations": [] + } + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DepartScene" + }, + "parameters": [ + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "ScoreText", + "=", + "\"Time: \" + TimeFormatter::SecondsToHHMMSS000(GlobalVariable(Score))" + ] + }, + { + "type": { + "value": "Sticker::Sticker::Stick" + }, + "parameters": [ + "PanelContent", + "Sticker", + "Panel", + "" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::DisplayAuthenticationBanner" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "TextInput::TextInputObject::SetText" + }, + "parameters": [ + "PlayerNameInput", + "=", + "PlayerAuthentication::Username()" + ] + }, + { + "type": { + "value": "TextInput::TextInputObject::SetDisabled" + }, + "parameters": [ + "PlayerNameInput", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + }, + { + "type": { + "value": "VarGlobalTxt" + }, + "parameters": [ + "PlayerName", + "!=", + "\"0\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "TextInput::TextInputObject::SetText" + }, + "parameters": [ + "PlayerNameInput", + "=", + "GlobalVariableString(PlayerName)" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetCenterX" + }, + "parameters": [ + "Panel", + "=", + "SceneWindowWidth() / 2" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlayerAuthentication::HasPlayerLoggedIn" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "TextInput::TextInputObject::SetText" + }, + "parameters": [ + "PlayerNameInput", + "=", + "PlayerAuthentication::Username()" + ] + }, + { + "type": { + "value": "TextInput::TextInputObject::SetDisabled" + }, + "parameters": [ + "PlayerNameInput", + "yes" + ] + }, + { + "type": { + "value": "PlayerAuthentication::DisplayAuthenticationBanner" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Leaderboards::IsLeaderboardViewErrored" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::DisplayAuthenticationBanner" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsClicked" + }, + "parameters": [ + "RestartButton", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::HideAuthenticationBanner" + }, + "parameters": [ + "" + ] + }, + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"Game\"", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Handle leaderboards.\nTo create a leaderboard, make sure your game is registered in Home > Profile > Games Dashboard and then, click on \"Manage game\" > Leaderboards. When a leaderboard is created, it should be available in the actions." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsClicked" + }, + "parameters": [ + "SubmitButton", + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "Leaderboards::SaveConnectedPlayerScore" + }, + "parameters": [ + "", + "\"a41abfc9-2392-4fda-a2eb-abcf16b5c0d6\"", + "GlobalVariable(Score)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PlayerAuthentication::IsPlayerAuthenticated" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "Leaderboards::SavePlayerScore" + }, + "parameters": [ + "", + "\"a41abfc9-2392-4fda-a2eb-abcf16b5c0d6\"", + "GlobalVariable(Score)", + "PlayerNameInput.Text()" + ] + }, + { + "type": { + "value": "ModVarGlobalTxt" + }, + "parameters": [ + "PlayerName", + "=", + "PlayerNameInput.Text()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PlayerAuthentication::HideAuthenticationBanner" + }, + "parameters": [ + "" + ] + }, + { + "type": { + "value": "Leaderboards::DisplayLeaderboard" + }, + "parameters": [ + "", + "\"a41abfc9-2392-4fda-a2eb-abcf16b5c0d6\"", + "yes" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Allow to try and submit again in case of error." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Leaderboards::HasPlayerJustClosedLeaderboardView" + }, + "parameters": [] + }, + { + "type": { + "value": "Leaderboards::HasLastSaveSucceeded" + }, + "parameters": [ + "\"a41abfc9-2392-4fda-a2eb-abcf16b5c0d6\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "Scene" + }, + "parameters": [ + "", + "\"Game\"", + "" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Coins animation", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "DepartScene" + }, + "parameters": [ + "" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "100", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Coin", + "RandomInRange(CameraBorderLeft(), CameraBorderRight())", + "RandomInRange(-500 + CameraBorderTop(), CameraBorderBottom() + 500)", + "\"3D\"" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Coin", + "RotationX", + "=", + "RandomFloatInRange(20, 45)" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Coin", + "RotationY", + "=", + "RandomFloatInRange(20, 45)" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Coin", + "RotationZ", + "=", + "RandomFloatInRange(20, 45)" + ] + }, + { + "type": { + "value": "AddForceXY" + }, + "parameters": [ + "Coin", + "0", + "200", + "1" + ] + }, + { + "type": { + "value": "Scene3D::Model3DObject::SetZ" + }, + "parameters": [ + "Coin", + "=", + "RandomFloatInRange(-1000, -32)" + ] + }, + { + "type": { + "value": "Scene3D::Model3DObject::SetRotationX" + }, + "parameters": [ + "Coin", + "+", + "RandomFloat(360)" + ] + }, + { + "type": { + "value": "Scene3D::Model3DObject::SetRotationY" + }, + "parameters": [ + "Coin", + "+", + "RandomFloat(360)" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Scene3D::Model3DObject::SetRotationX" + }, + "parameters": [ + "Coin", + "+", + "Coin.Variable(RotationX) * TimeDelta()" + ] + }, + { + "type": { + "value": "Scene3D::Model3DObject::SetRotationY" + }, + "parameters": [ + "Coin", + "+", + "Coin.Variable(RotationY) * TimeDelta()" + ] + }, + { + "type": { + "value": "SetAngle" + }, + "parameters": [ + "Coin", + "+", + "Coin.Variable(RotationZ) * TimeDelta()" + ] + } + ] + } + ], + "parameters": [] + } + ], + "layers": [ + { + "ambientLightColorB": 167797870, + "ambientLightColorG": 6032144, + "ambientLightColorR": 8563600, + "camera3DFarPlaneDistance": 10000, + "camera3DFieldOfView": 45, + "camera3DNearPlaneDistance": 0.1, + "followBaseLayerCamera": false, + "isLightingLayer": false, + "isLocked": false, + "name": "3D", + "renderingType": "3d", + "visibility": true, + "cameras": [], + "effects": [ + { + "effectType": "Scene3D::HemisphereLight", + "name": "Light", + "doubleParameters": { + "elevation": 90, + "intensity": 0.5, + "rotation": 0 + }, + "stringParameters": { + "groundColor": "127;127;127", + "skyColor": "255;255;255", + "top": "Y-" + }, + "booleanParameters": {} + } + ] + }, + { + "ambientLightColorB": 3, + "ambientLightColorG": 134217728, + "ambientLightColorR": 1597197633, + "camera3DFarPlaneDistance": 10000, + "camera3DFieldOfView": 45, + "camera3DNearPlaneDistance": 0.1, + "followBaseLayerCamera": false, + "isLightingLayer": false, + "isLocked": false, + "name": "", + "renderingType": "2d", + "visibility": true, + "cameras": [ + { + "defaultSize": true, + "defaultViewport": true, + "height": 0, + "viewportBottom": 1, + "viewportLeft": 0, + "viewportRight": 1, + "viewportTop": 0, + "width": 0 + } + ], + "effects": [] + } + ], + "behaviorsSharedData": [ + { + "name": "ScreenWrap", + "type": "ScreenWrap::ScreenWrap" + }, + { + "name": "Sticker", + "type": "Sticker::Sticker" + } + ] + } + ], + "externalEvents": [], + "eventsFunctionsExtensions": [ + { + "author": "@Bouh", + "category": "User interface", + "extensionNamespace": "", + "fullName": "Time formatting", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWNsb2NrLWRpZ2l0YWwiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMiw2QTIsMiAwIDAsMCAwLDhWMTZBMiwyIDAgMCwwIDIsMThIMjJBMiwyIDAgMCwwIDI0LDE2VjhBMiwyIDAgMCwwIDIyLDZNMiw4SDIyVjE2SDJNMyw5VjEwLjVINi4yNUwzLDE1SDQuNzVMOCwxMC41VjlNOS4yNSw5VjEwLjVIMTAuNzVWOU0xMiw5VjEwLjVIMTMuNVYxNUgxNVY5TTE3LDlBMSwxIDAgMCwwIDE2LDEwVjE0QTEsMSAwIDAsMCAxNywxNUgyMEExLDEgMCAwLDAgMjEsMTRWMTBBMSwxIDAgMCwwIDIwLDlNMTcuNSwxMC41SDE5LjVWMTMuNUgxNy41TTkuMjUsMTMuNVYxNUgxMC43NVYxMy41IiAvPjwvc3ZnPg==", + "name": "TimeFormatter", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/clock-digital.svg", + "shortDescription": "Converts seconds into standard time formats, such as HH:MM:SS. ", + "version": "0.0.2", + "description": [ + "Ideal for displaying timers on screen.", + "", + "Formats included:", + "* HH:MM:SS", + "* HH:MM:SS.000 (displays milliseconds)" + ], + "origin": { + "identifier": "TimeFormatter", + "name": "gdevelop-extension-store" + }, + "tags": [ + "time", + "timer", + "format", + "hours", + "minutes", + "seconds", + "milliseconds" + ], + "authorIds": [ + "2OwwM8ToR9dx9RJ2sAKTcrLmCB92" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Format time in seconds to HH:MM:SS.", + "fullName": "Format time in seconds to HH:MM:SS", + "functionType": "StringExpression", + "name": "SecondsToHHMMSS", + "sentence": "Format time _PARAM1_ to HH:MM:SS in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "var format_time = function (time_second) {\r", + " date = new Date(null);\r", + " date.setSeconds(time_second);\r", + " if (time_second >= 3600) {\r", + " return date.toISOString().substr(11, 8); // MM:SS\r", + " } else {\r", + " return date.toISOString().substr(14, 5); // HH:MM:SS\r", + " }\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = format_time(eventsFunctionContext.getArgument(\"TimeInSeconds\"));" + ], + "parameterObjects": "", + "useStrict": false, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Time, in seconds", + "name": "TimeInSeconds", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Format time in seconds to HH:MM:SS.000, including milliseconds.", + "fullName": "Format time in seconds to HH:MM:SS.000", + "functionType": "StringExpression", + "name": "SecondsToHHMMSS000", + "sentence": "Format time _PARAM1_ to HH:MM:SS in _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "var format_time = function (time_second) {\r", + " date = new Date(null);\r", + " date.setMilliseconds(1000*time_second);\r", + " if (time_second >= 3600) {\r", + " return date.toISOString().substr(11, 12); // MM:SS.000\r", + " } else {\r", + " return date.toISOString().substr(14, 9); // HH:MM:SS.000\r", + " }\r", + "}\r", + "\r", + "eventsFunctionContext.returnValue = format_time(eventsFunctionContext.getArgument(\"TimeInSeconds\"));" + ], + "parameterObjects": "", + "useStrict": false, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Time, in seconds", + "name": "TimeInSeconds", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] + }, + { + "author": "", + "category": "User interface", + "extensionNamespace": "", + "fullName": "Panel sprite button", + "helpPath": "/objects/button", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI5LDIzSDNjLTEuMSwwLTItMC45LTItMlYxMWMwLTEuMSwwLjktMiwyLTJoMjZjMS4xLDAsMiwwLjksMiwydjEwQzMxLDIyLjEsMzAuMSwyMywyOSwyM3oiLz4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xMywxOUwxMywxOWMtMS4xLDAtMi0wLjktMi0ydi0yYzAtMS4xLDAuOS0yLDItMmgwYzEuMSwwLDIsMC45LDIsMnYyQzE1LDE4LjEsMTQuMSwxOSwxMywxOXoiLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIxOCIgeTE9IjEzIiB4Mj0iMTgiIHkyPSIxOSIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjIxIiB5MT0iMTMiIHgyPSIxOCIgeTI9IjE3Ii8+DQo8bGluZSBjbGFzcz0ic3QwIiB4MT0iMjEiIHkxPSIxOSIgeDI9IjE5IiB5Mj0iMTYiLz4NCjwvc3ZnPg0K", + "name": "PanelSpriteButton", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/Line Hero Pack/Master/SVG/Interface Elements/Interface Elements_interface_ui_button_ok_cta_clock_tap.svg", + "shortDescription": "A button that can be customized.", + "version": "1.4.4", + "description": [ + "The button can be customized with a background for each state and a label. It handles user interactions and a simple condition can be used to check if it is clicked.", + "", + "There are ready-to-use buttons in the asset-store [menu buttons pack](https://editor.gdevelop.io/?initial-dialog=asset-store&asset-pack=menu-buttons-menu-buttons)." + ], + "origin": { + "identifier": "PanelSpriteButton", + "name": "gdevelop-extension-store" + }, + "tags": [ + "button", + "ui" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "The finite state machine used internally by the button object.", + "fullName": "Button finite state machine", + "name": "ButtonFSM", + "objectType": "", + "private": true, + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Finite state machine", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "The \"Validated\" state only last one frame." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Check position", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Make sure the cursor position is only checked once per frame." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyShouldCheckHovering" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "MouseOnlyCursorX(Object.Layer(), 0)", + "MouseOnlyCursorY(Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Touches are always pressed, so ShouldCheckHovering doesn't matter." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "!=", + "0" + ] + }, + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "TouchX(Object.Behavior::PropertyTouchId(), Object.Layer(), 0)", + "TouchY(Object.Behavior::PropertyTouchId(), Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Handle touch start", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "HasAnyTouchOrMouseStarted" + }, + "parameters": [ + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Repeat", + "repeatExpression": "StartedTouchOrMouseCount()", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "CollisionPoint" + }, + "parameters": [ + "Object", + "TouchX(StartedTouchOrMouseId(Object.Behavior::PropertyIndex()), Object.Layer(), 0)", + "TouchY(StartedTouchOrMouseId(Object.Behavior::PropertyIndex()), Object.Layer(), 0)" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "StartedTouchOrMouseId(Object.Behavior::PropertyIndex())" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyIndex" + }, + "parameters": [ + "Object", + "Behavior", + "+", + "1" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Apply position changes", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyMouseIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyTouchIsInside" + }, + "parameters": [ + "Object", + "Behavior" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Handle touch end", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "HasTouchEnded" + }, + "parameters": [ + "", + "Object.Behavior::PropertyTouchId()" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + }, + { + "type": { + "inverted": true, + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDeActivate", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::ResetState" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Reset the state of the button.", + "fullName": "Reset state", + "functionType": "Action", + "name": "ResetState", + "private": true, + "sentence": "Reset the button state of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + }, + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::SetPropertyTouchId" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is not used.", + "fullName": "Is idle", + "functionType": "Condition", + "name": "IsIdle", + "sentence": "_PARAM0_ is idle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Idle\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button was just clicked.", + "fullName": "Is clicked", + "functionType": "Condition", + "name": "IsClicked", + "sentence": "_PARAM0_ is clicked", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Validated\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the cursor is hovered over the button.", + "fullName": "Is hovered", + "functionType": "Condition", + "name": "IsHovered", + "sentence": "_PARAM0_ is hovered", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is either hovered or pressed but not hovered.", + "fullName": "Is focused", + "functionType": "Condition", + "name": "IsFocused", + "sentence": "_PARAM0_ is focused", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"Hovered\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed with mouse or touch.", + "fullName": "Is pressed", + "functionType": "Condition", + "name": "IsPressed", + "sentence": "_PARAM0_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedInside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed outside with mouse or touch.", + "fullName": "Is held outside", + "functionType": "Condition", + "name": "IsPressedOutside", + "sentence": "_PARAM0_ is held outside", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::PropertyState" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "\"PressedOutside\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the touch id that is using the button or 0 if none.", + "fullName": "Touch id", + "functionType": "ExpressionAndCondition", + "name": "TouchId", + "sentence": "the touch id", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTouchId()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "PanelSpriteButton::ButtonFSM", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "true", + "type": "Boolean", + "label": "", + "description": "Should check hovering", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "ShouldCheckHovering" + }, + { + "value": "Idle", + "type": "Choice", + "label": "State", + "description": "", + "group": "", + "extraInformation": [ + "Idle", + "Hovered", + "PressedInside", + "PressedOutside", + "Validated" + ], + "hidden": true, + "name": "State" + }, + { + "value": "0", + "type": "Number", + "label": "Touch id", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TouchId" + }, + { + "value": "", + "type": "Boolean", + "label": "Touch is inside", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "TouchIsInside" + }, + { + "value": "", + "type": "Boolean", + "label": "Mouse is inside", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "MouseIsInside" + }, + { + "value": "", + "type": "Number", + "label": "", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "Index" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [ + { + "defaultName": "Button", + "description": "A button that can be customized.", + "fullName": "Button (panel sprite)", + "name": "PanelSpriteButton", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Create one background instance for of each state.\nOnly the instance for the current state is shown." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Idle", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Hovered", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Pressed", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + }, + { + "type": { + "value": "ChangePlan" + }, + "parameters": [ + "Hovered", + "=", + "1" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Place the label over the backgrounds." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Create" + }, + "parameters": [ + "", + "Label", + "0", + "0", + "" + ] + }, + { + "type": { + "value": "ChangePlan" + }, + "parameters": [ + "Label", + "=", + "2" + ] + }, + { + "type": { + "value": "TextObject::SetWrapping" + }, + "parameters": [ + "Label", + "yes" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [ + { + "name": "Background", + "objects": [ + { + "name": "Idle" + }, + { + "name": "Hovered" + }, + { + "name": "Pressed" + } + ] + } + ] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onHotReloading", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Apply states", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Show the right background accordingly to the new state." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsIdle" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Idle", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "Visible" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::PropertyHoveredFadeOutDuration" + }, + "parameters": [ + "Object", + ">", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "Tween::AddObjectOpacityTween" + }, + "parameters": [ + "Hovered", + "Tween", + "\"Fadeout\"", + "0", + "\"linear\"", + "Object.PropertyHoveredFadeOutDuration() * 1000", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::PropertyHoveredFadeOutDuration" + }, + "parameters": [ + "Object", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteObject::Opacity" + }, + "parameters": [ + "Hovered", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "PanelSpriteObject::SetOpacity" + }, + "parameters": [ + "Hovered", + "=", + "255" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsHovered" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Idle" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Hovered", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + }, + { + "type": { + "value": "Tween::RemoveTween" + }, + "parameters": [ + "Hovered", + "Tween", + "\"Fadeout\"" + ] + }, + { + "type": { + "value": "PanelSpriteObject::SetOpacity" + }, + "parameters": [ + "Hovered", + "=", + "255" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsPressed" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY() + Object.PropertyPressedLabelOffsetY()" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Idle" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Hovered" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Pressed", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsFocused" + }, + "parameters": [ + "Object", + "ButtonFSM" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Idle" + ] + }, + { + "type": { + "value": "Montre" + }, + "parameters": [ + "Hovered", + "" + ] + }, + { + "type": { + "value": "Cache" + }, + "parameters": [ + "Pressed" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Resize", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Children instances must be resized when the button size change:\n- backgrounds for each state are resized to take the full dimensions of the button\n- the label is put back at the center of the button\n\nThe scale is set back to 1 because it means that the parent instance has the same dimensions as the union of its children instances." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Width()", + "!=", + "max(Idle.BoundingBoxRight(), Label.BoundingBoxRight()) - min(Idle.BoundingBoxLeft(), Label.BoundingBoxLeft())" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Object.Height()", + "!=", + "max(Idle.BoundingBoxBottom(), Label.BoundingBoxBottom()) - min(Idle.BoundingBoxTop(), Label.BoundingBoxTop())" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Idle", + "Width", + "=", + "Object.Width()" + ] + }, + { + "type": { + "value": "ModVarObjet" + }, + "parameters": [ + "Idle", + "Height", + "=", + "Object.Height()" + ] + }, + { + "type": { + "value": "PanelSpriteButton::Scale" + }, + "parameters": [ + "Object", + "=", + "1" + ] + }, + { + "type": { + "value": "PanelSpriteObject::Width" + }, + "parameters": [ + "Background", + "=", + "Idle.Variable(Width)" + ] + }, + { + "type": { + "value": "PanelSpriteObject::Height" + }, + "parameters": [ + "Background", + "=", + "Idle.Variable(Height)" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [ + { + "name": "Background", + "objects": [ + { + "name": "Idle" + }, + { + "name": "Hovered" + }, + { + "name": "Pressed" + } + ] + } + ] + }, + { + "description": "Check if the button is not used.", + "fullName": "Is idle", + "functionType": "Condition", + "name": "IsIdle", + "sentence": "_PARAM0_ is idle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsIdle" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button was just clicked.", + "fullName": "Is clicked", + "functionType": "Condition", + "name": "IsClicked", + "sentence": "_PARAM0_ is clicked", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsClicked" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the cursor is hovered over the button.", + "fullName": "Is hovered", + "functionType": "Condition", + "name": "IsHovered", + "sentence": "_PARAM0_ is hovered", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsHovered" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is either hovered or pressed but not hovered.", + "fullName": "Is focused", + "functionType": "Condition", + "name": "IsFocused", + "sentence": "_PARAM0_ is focused", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsFocused" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the button is currently being pressed with mouse or touch.", + "fullName": "Is pressed", + "functionType": "Condition", + "name": "IsPressed", + "sentence": "_PARAM0_ is pressed", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::ButtonFSM::IsPressed" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Change the text of the button label.", + "fullName": "Label text", + "functionType": "Action", + "name": "SetLabelText", + "sentence": "Change the text of _PARAM0_ to _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "TextObject::String" + }, + "parameters": [ + "Label", + "=", + "GetArgumentAsString(\"LabelText\")" + ] + }, + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::CenterLabel" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + }, + { + "description": "Text", + "name": "LabelText", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Return the label text.", + "fullName": "Label text", + "functionType": "StringExpression", + "name": "LabelText", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Label.String()" + ] + } + ] + } + ], + "expressionType": { + "type": "string" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Return the label center Y according to the button configuration. This expression is used in doStepPostEvents when the button is pressed or released.", + "fullName": "", + "functionType": "Expression", + "name": "CenterWithPaddingY", + "private": true, + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Idle.CenterY() + (Object.PropertyTopPadding() - Object.PropertyBottomPadding()) / 2" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Center the label according to the button configuration. This is used in doStepPostEvents when the button is resized.", + "fullName": "", + "functionType": "Action", + "name": "CenterLabel", + "private": true, + "sentence": "Center the label of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "MettreXY" + }, + "parameters": [ + "Label", + "=", + "Object.PropertyLeftPadding()", + "=", + "Object.PropertyTopPadding()" + ] + }, + { + "type": { + "value": "TextObject::WrappingWidth" + }, + "parameters": [ + "Label", + "=", + "Idle.Width() - Object.PropertyLeftPadding() - Object.PropertyRightPadding()" + ] + }, + { + "type": { + "value": "SetCenterY" + }, + "parameters": [ + "Label", + "=", + "Object.CenterWithPaddingY()" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetCenterX" + }, + "parameters": [ + "Label", + "=", + "Background.CenterX() + (Object.PropertyLeftPadding() - Object.PropertyRightPadding()) / 2" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PanelSpriteButton::PanelSpriteButton::IsPressed" + }, + "parameters": [ + "Object", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreY" + }, + "parameters": [ + "Label", + "+", + "Object.PropertyPressedLabelOffsetY()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [ + { + "name": "Background", + "objects": [ + { + "name": "Idle" + }, + { + "name": "Hovered" + }, + { + "name": "Pressed" + } + ] + } + ] + }, + { + "description": "De/activate interactions with the button.", + "fullName": "De/activate interactions", + "functionType": "Action", + "name": "Activate", + "sentence": "Activate interactions with _PARAM0_: _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldActivate\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ActivateBehavior" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "yes" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"ShouldActivate\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ActivateBehavior" + }, + "parameters": [ + "Idle", + "ButtonFSM", + "no" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + }, + { + "description": "Activate", + "name": "ShouldActivate", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Check if interactions are activated on the button.", + "fullName": "Interactions activated", + "functionType": "Condition", + "name": "IsActivated", + "sentence": "Interactions on _PARAM0_ are activated", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BehaviorActivated" + }, + "parameters": [ + "Idle", + "ButtonFSM" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "PanelSpriteButton::PanelSpriteButton", + "type": "object" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "0", + "type": "Number", + "label": "Label offset on Y axis when pressed", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "PressedLabelOffsetY" + }, + { + "value": "0", + "type": "Number", + "label": "Left padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "LeftPadding" + }, + { + "value": "0", + "type": "Number", + "label": "Right padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "RightPadding" + }, + { + "value": "0", + "type": "Number", + "label": "Top padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "TopPadding" + }, + { + "value": "0", + "type": "Number", + "label": "Bottom padding", + "description": "", + "group": "Padding", + "extraInformation": [ + "Label" + ], + "hidden": false, + "name": "BottomPadding" + }, + { + "value": "0.25", + "type": "Number", + "label": "Hovered fade out duration (in seconds)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "HoveredFadeOutDuration" + } + ], + "objects": [ + { + "assetStoreId": "", + "bold": false, + "italic": false, + "name": "Label", + "smoothed": true, + "tags": "", + "type": "TextObject::Text", + "underlined": false, + "variables": [], + "effects": [], + "behaviors": [], + "string": "Text", + "font": "", + "textAlignment": "", + "characterSize": 20, + "color": { + "b": 0, + "g": 0, + "r": 0 + } + }, + { + "assetStoreId": "", + "bottomMargin": 0, + "height": 32, + "leftMargin": 0, + "name": "Idle", + "rightMargin": 0, + "tags": "", + "texture": "", + "tiled": false, + "topMargin": 0, + "type": "PanelSpriteObject::PanelSprite", + "width": 32, + "variables": [ + { + "folded": true, + "name": "State", + "type": "string", + "value": "Idle" + } + ], + "effects": [], + "behaviors": [ + { + "name": "ButtonFSM", + "type": "PanelSpriteButton::ButtonFSM", + "ShouldCheckHovering": true + } + ] + }, + { + "assetStoreId": "", + "bottomMargin": 0, + "height": 32, + "leftMargin": 0, + "name": "Hovered", + "rightMargin": 0, + "tags": "", + "texture": "", + "tiled": false, + "topMargin": 0, + "type": "PanelSpriteObject::PanelSprite", + "width": 32, + "variables": [], + "effects": [], + "behaviors": [ + { + "name": "Tween", + "type": "Tween::TweenBehavior" + } + ] + }, + { + "assetStoreId": "", + "bottomMargin": 0, + "height": 32, + "leftMargin": 0, + "name": "Pressed", + "rightMargin": 0, + "tags": "", + "texture": "", + "tiled": false, + "topMargin": 0, + "type": "PanelSpriteObject::PanelSprite", + "width": 32, + "variables": [], + "effects": [], + "behaviors": [] + } + ] + } + ] + }, + { + "author": "Tristan Rhodes (tristan@victrisgames.com), Entropy", + "category": "Movement", + "extensionNamespace": "", + "fullName": "Screen Wrap", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLW1vbml0b3Itc2NyZWVuc2hvdCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik05LDZINVYxMEg3VjhIOU0xOSwxMEgxN1YxMkgxNVYxNEgxOU0yMSwxNkgzVjRIMjFNMjEsMkgzQzEuODksMiAxLDIuODkgMSw0VjE2QTIsMiAwIDAsMCAzLDE4SDEwVjIwSDhWMjJIMTZWMjBIMTRWMThIMjFBMiwyIDAgMCwwIDIzLDE2VjRDMjMsMi44OSAyMi4xLDIgMjEsMiIgLz48L3N2Zz4=", + "name": "ScreenWrap", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/monitor-screenshot.svg", + "shortDescription": "Teleport object when it moves off the screen and immediately appear on the opposite side while maintaining speed and trajectory.", + "version": "0.2.3", + "description": [ + "The teleport happens when the center point of the object crosses a border. ", + "Change behavior properties to increase or decrease the margin used to trigger this teleport.", + "By default, the borders of the wrapping area match the screen size, but they can alo be changed.", + "", + "The Asteroid-like example uses this extension ([open the project online](https://editor.gdevelop.io/?project=example://space-asteroid))." + ], + "origin": { + "identifier": "ScreenWrap", + "name": "gdevelop-extension-store" + }, + "tags": [ + "screen", + "wrap", + "teleport", + "asteroids" + ], + "authorIds": [ + "q8ubdigLvIRXLxsJDDTaokO41mc2", + "gqDaZjCfevOOxBYkK6zlhtZnXCg1" + ], + "dependencies": [], + "eventsFunctions": [], + "eventsBasedBehaviors": [ + { + "description": "Teleport the object when leaving one side of the screen so that it immediately reappears on the opposite side, maintaining speed and trajectory.", + "fullName": "Screen Wrap", + "name": "ScreenWrap", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Initialize variables (if needed)", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyBorderBottom" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetBottomBorder" + }, + "parameters": [ + "Object", + "Behavior", + "SceneWindowHeight()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyBorderRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetRightBorder" + }, + "parameters": [ + "Object", + "Behavior", + "SceneWindowWidth()", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "colorB": 5, + "colorG": 117, + "colorR": 65, + "creationTime": 0, + "name": "ScreenWrap", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Move object to opposite side (if needed)", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [], + "parameters": [] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyHorizontalWrapping" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosX" + }, + "parameters": [ + "Object", + "<", + "Object.Behavior::PropertyBorderLeft() - (Object.Width()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreX" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderRight() - (Object.Width()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosX" + }, + "parameters": [ + "Object", + ">", + "Object.Behavior::PropertyBorderRight() - (Object.Width()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreX" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderLeft() - (Object.Width()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyVerticalWrapping" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosY" + }, + "parameters": [ + "Object", + "<", + "Object.Behavior::PropertyBorderTop() - (Object.Height()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreY" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderBottom() - (Object.Height()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosY" + }, + "parameters": [ + "Object", + ">", + "Object.Behavior::PropertyBorderBottom() - (Object.Height()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "MettreY" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderTop() - (Object.Height()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is wrapping on the left and right borders.", + "fullName": "Is horizontal wrapping", + "functionType": "Condition", + "name": "IsHorizontalWrapping", + "sentence": "_PARAM0_ is horizontal wrapping", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Horizontal\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Horizontal\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is wrapping on the top and bottom borders.", + "fullName": "Is vertical wrapping", + "functionType": "Condition", + "name": "IsVerticalWrapping", + "sentence": "_PARAM0_ is vertical wrapping", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Vertical\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Vertical\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Enable wrapping on the left and right borders.", + "fullName": "Enable horizontal wrapping", + "functionType": "Action", + "name": "EnableHorizontalWrapping", + "sentence": "Enable _PARAM0_ horizontal wrapping: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableHorizontalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyHorizontalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableHorizontalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyHorizontalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + }, + { + "description": "Value", + "name": "EnableHorizontalWrapping", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Enable wrapping on the top and bottom borders.", + "fullName": "Enable vertical wrapping", + "functionType": "Action", + "name": "EnableVerticalWrapping", + "sentence": "Enable _PARAM0_ vertical wrapping: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableVerticalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyVerticalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableVerticalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyVerticalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + }, + { + "description": "Value", + "name": "EnableVerticalWrapping", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Top border (Y position).", + "fullName": "Top border", + "functionType": "Expression", + "name": "BorderTop", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderTop()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Left border (X position).", + "fullName": "Left border", + "functionType": "Expression", + "name": "BorderLeft", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderLeft()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Right border (X position).", + "fullName": "Right border", + "functionType": "Expression", + "name": "BorderRight", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderRight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Bottom border (Y position).", + "fullName": "Bottom border", + "functionType": "Expression", + "name": "BorderBottom", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderBottom()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Number of pixels past the center where the object teleports and appears.", + "fullName": "Trigger offset", + "functionType": "Expression", + "name": "TriggerOffset", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTriggerOffset()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Set top border (Y position).", + "fullName": "Set top border", + "functionType": "Action", + "name": "SetTopBorder", + "sentence": "Set _PARAM0_ top border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderTop" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + }, + { + "description": "Top border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set left border (X position).", + "fullName": "Set left border", + "functionType": "Action", + "name": "SetLeftBorder", + "sentence": "Set _PARAM0_ left border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + }, + { + "description": "Left border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set bottom border (Y position).", + "fullName": "Set bottom border", + "functionType": "Action", + "name": "SetBottomBorder", + "sentence": "Set _PARAM0_ bottom border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderBottom" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + }, + { + "description": "Bottom border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set right border (X position).", + "fullName": "Set right border", + "functionType": "Action", + "name": "SetRightBorder", + "sentence": "Set _PARAM0_ right border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + }, + { + "description": "Right border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set trigger offset (pixels).", + "fullName": "Set trigger offset", + "functionType": "Action", + "name": "SetTriggerOffset", + "sentence": "Set _PARAM0_ trigger offset to _PARAM2_ pixels", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyTriggerOffset" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrap", + "type": "behavior" + }, + { + "description": "SetScreen Offset Leaving Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "true", + "type": "Boolean", + "label": "Horizontal wrapping", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "HorizontalWrapping" + }, + { + "value": "true", + "type": "Boolean", + "label": "Vertical wrapping", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "VerticalWrapping" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Top border of wrapped area (Y)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderTop" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Left border of wrapped area (X)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderLeft" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Right border of wrapped area (X)", + "description": "If blank, the value will be the scene width.", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderRight" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Bottom border of wrapped area (Y)", + "description": "If blank, the value will be scene height.", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderBottom" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Number of pixels past the center where the object teleports and appears", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "TriggerOffset" + } + ], + "sharedPropertyDescriptors": [] + }, + { + "description": "Teleport the object when leaving one side of the screen so that it immediately reappears on the opposite side, maintaining speed and trajectory.", + "fullName": "Screen Wrap (physics objects)", + "name": "ScreenWrapPhysics", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Initialize variables (if needed)", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyBorderBottom" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetBottomBorder" + }, + "parameters": [ + "Object", + "Behavior", + "SceneWindowHeight()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyBorderRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "0" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetRightBorder" + }, + "parameters": [ + "Object", + "Behavior", + "SceneWindowWidth()", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "colorB": 5, + "colorG": 117, + "colorR": 65, + "creationTime": 0, + "name": "ScreenWrap", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Move object to opposite side (if needed)", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [], + "parameters": [] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyHorizontalWrapping" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Velocity is saved because Physics2 resets objects velocities when they are moved from the outside of the extension." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosX" + }, + "parameters": [ + "Object", + "<", + "Object.Behavior::PropertyBorderLeft() - (Object.Width()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::SaveCurrentVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "MettreX" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderRight() - (Object.Width()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + }, + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::ApplySavedVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosX" + }, + "parameters": [ + "Object", + ">", + "Object.Behavior::PropertyBorderRight() - (Object.Width()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::SaveCurrentVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "MettreX" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderLeft() - (Object.Width()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + }, + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::ApplySavedVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::PropertyVerticalWrapping" + }, + "parameters": [ + "Object", + "Behavior" + ] + } + ], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosY" + }, + "parameters": [ + "Object", + "<", + "Object.Behavior::PropertyBorderTop() - (Object.Height()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::SaveCurrentVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "MettreY" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderBottom() - (Object.Height()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + }, + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::ApplySavedVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "PosY" + }, + "parameters": [ + "Object", + ">", + "Object.Behavior::PropertyBorderBottom() - (Object.Height()/2) + Object.Behavior::PropertyTriggerOffset()" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::SaveCurrentVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + }, + { + "type": { + "value": "MettreY" + }, + "parameters": [ + "Object", + "=", + "Object.Behavior::PropertyBorderTop() - (Object.Height()/2) - Object.Behavior::PropertyTriggerOffset()" + ] + }, + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::ApplySavedVelocities" + }, + "parameters": [ + "Object", + "Behavior", + "" + ] + } + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is wrapping on the left and right borders.", + "fullName": "Is horizontal wrapping", + "functionType": "Condition", + "name": "IsHorizontalWrapping", + "sentence": "_PARAM0_ is horizontal wrapping", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Horizontal\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Horizontal\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the object is wrapping on the top and bottom borders.", + "fullName": "Is vertical wrapping", + "functionType": "Condition", + "name": "IsVerticalWrapping", + "sentence": "_PARAM0_ is vertical wrapping", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Vertical\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"Vertical\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Enable wrapping on the left and right borders.", + "fullName": "Enable horizontal wrapping", + "functionType": "Action", + "name": "EnableHorizontalWrapping", + "sentence": "Enable _PARAM0_ horizontal wrapping: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableHorizontalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyHorizontalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableHorizontalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyHorizontalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + }, + { + "description": "Value", + "name": "EnableHorizontalWrapping", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Enable wrapping on the top and bottom borders.", + "fullName": "Enable vertical wrapping", + "functionType": "Action", + "name": "EnableVerticalWrapping", + "sentence": "Enable _PARAM0_ vertical wrapping: _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "inverted": true, + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableVerticalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyVerticalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "no" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "GetArgumentAsBoolean" + }, + "parameters": [ + "\"EnableVerticalWrapping\"" + ] + } + ], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyVerticalWrapping" + }, + "parameters": [ + "Object", + "Behavior", + "yes" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + }, + { + "description": "Value", + "name": "EnableVerticalWrapping", + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Top border (Y position).", + "fullName": "Top border", + "functionType": "Expression", + "name": "BorderTop", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderTop()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Left border (X position).", + "fullName": "Left border", + "functionType": "Expression", + "name": "BorderLeft", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderLeft()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Right border (X position).", + "fullName": "Right border", + "functionType": "Expression", + "name": "BorderRight", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderRight()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Bottom border (Y position).", + "fullName": "Bottom border", + "functionType": "Expression", + "name": "BorderBottom", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyBorderBottom()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Number of pixels past the center where the object teleports and appears.", + "fullName": "Trigger offset", + "functionType": "Expression", + "name": "TriggerOffset", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Object.Behavior::PropertyTriggerOffset()" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Set top border (Y position).", + "fullName": "Set top border", + "functionType": "Action", + "name": "SetTopBorder", + "sentence": "Set _PARAM0_ top border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderTop" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + }, + { + "description": "Top border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set left border (X position).", + "fullName": "Set left border", + "functionType": "Action", + "name": "SetLeftBorder", + "sentence": "Set _PARAM0_ left border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderLeft" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + }, + { + "description": "Left border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set bottom border (Y position).", + "fullName": "Set bottom border", + "functionType": "Action", + "name": "SetBottomBorder", + "sentence": "Set _PARAM0_ bottom border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderBottom" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + }, + { + "description": "Bottom border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set right border (X position).", + "fullName": "Set right border", + "functionType": "Action", + "name": "SetRightBorder", + "sentence": "Set _PARAM0_ right border to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyBorderRight" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + }, + { + "description": "Right border value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Set trigger offset (pixels).", + "fullName": "Set trigger offset", + "functionType": "Action", + "name": "SetTriggerOffset", + "sentence": "Set _PARAM0_ trigger offset to _PARAM2_ pixels", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrap::SetPropertyTriggerOffset" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "GetArgumentAsNumber(\"Value\")" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + }, + { + "description": "SetScreen Offset Leaving Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Save current velocity values.", + "fullName": "Save current velocity values", + "functionType": "Action", + "name": "SaveCurrentVelocities", + "sentence": "Save current velocity values of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::SetPropertyAngularVelocity" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.RequiredPhysicsBehavior::AngularVelocity()" + ] + }, + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::SetPropertyLinearVelocityX" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.RequiredPhysicsBehavior::LinearVelocityX()" + ] + }, + { + "type": { + "value": "ScreenWrap::ScreenWrapPhysics::SetPropertyLinearVelocityY" + }, + "parameters": [ + "Object", + "Behavior", + "=", + "Object.RequiredPhysicsBehavior::LinearVelocityY()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Apply saved velocity values.", + "fullName": "Apply saved velocity values", + "functionType": "Action", + "name": "ApplySavedVelocities", + "sentence": "Apply saved velocity values of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Physics2::AngularVelocity" + }, + "parameters": [ + "Object", + "RequiredPhysicsBehavior", + "=", + "Object.Behavior::PropertyAngularVelocity()" + ] + }, + { + "type": { + "value": "Physics2::LinearVelocityX" + }, + "parameters": [ + "Object", + "RequiredPhysicsBehavior", + "=", + "Object.Behavior::PropertyLinearVelocityX()" + ] + }, + { + "type": { + "value": "Physics2::LinearVelocityY" + }, + "parameters": [ + "Object", + "RequiredPhysicsBehavior", + "=", + "Object.Behavior::PropertyLinearVelocityY()" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ScreenWrap::ScreenWrapPhysics", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Behavior", + "label": "Physics Behavior", + "description": "", + "group": "", + "extraInformation": [ + "Physics2::Physics2Behavior" + ], + "hidden": false, + "name": "RequiredPhysicsBehavior" + }, + { + "value": "true", + "type": "Boolean", + "label": "Horizontal wrapping", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "HorizontalWrapping" + }, + { + "value": "true", + "type": "Boolean", + "label": "Vertical wrapping", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "VerticalWrapping" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Top border of wrapped area (Y)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderTop" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Left border of wrapped area (X)", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderLeft" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Right border of wrapped area (X).", + "description": "If blank, the value will be the scene width.", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderRight" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Bottom border of wrapped area (Y)", + "description": "If blank, the value will be scene height.", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "BorderBottom" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Number of pixels past the center where the object teleports and appears", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "TriggerOffset" + }, + { + "value": "0", + "type": "Number", + "label": "Angular Velocity", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "AngularVelocity" + }, + { + "value": "0", + "type": "Number", + "label": "Linear Velocity X", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "LinearVelocityX" + }, + { + "value": "0", + "type": "Number", + "label": "Linear Velocity Y", + "description": "", + "group": "", + "extraInformation": [], + "hidden": true, + "name": "LinearVelocityY" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, + { + "author": "D8H", + "category": "Movement", + "extensionNamespace": "", + "fullName": "Stick objects to others", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXN0aWNrZXItb3V0bGluZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik01LjUgMkMzLjYgMiAyIDMuNiAyIDUuNVYxOC41QzIgMjAuNCAzLjYgMjIgNS41IDIySDE2TDIyIDE2VjUuNUMyMiAzLjYgMjAuNCAyIDE4LjUgMkg1LjVNNS44IDRIMTguM0MxOS4zIDQgMjAuMSA0LjggMjAuMSA1LjhWMTVIMTguNkMxNi43IDE1IDE1LjEgMTYuNiAxNS4xIDE4LjVWMjBINS44QzQuOCAyMCA0IDE5LjIgNCAxOC4yVjUuOEM0IDQuOCA0LjggNCA1LjggNCIgLz48L3N2Zz4=", + "name": "Sticker", + "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/sticker-outline.svg", + "shortDescription": "Make objects follow the position and rotation of the object they are stuck to.", + "version": "0.3.5", + "description": [ + "This extension can be useful to:", + "* Stick accessories to moving objects,", + "* Animate a skeleton.", + "", + "An example allows to check it out ([open the project online](https://editor.gdevelop.io/?project=example://stick-objects))." + ], + "origin": { + "identifier": "Sticker", + "name": "gdevelop-extension-store" + }, + "tags": [ + "sticker", + "stick", + "follow", + "skeleton", + "joint", + "pin", + "bind", + "glue", + "tie", + "attach", + "hold", + "paste", + "wear" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "dependencies": [], + "eventsFunctions": [ + { + "description": "Check if the object is stuck to another object.", + "fullName": "Is stuck to another object", + "functionType": "Condition", + "name": "IsStuck", + "sentence": "_PARAM1_ is stuck to _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const stickerBehaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "/** @type {Hashtable} */", + "const stickerObjectsLists = eventsFunctionContext.getObjectsLists(\"Object\");", + "/** @type {Hashtable} */", + "const basisObjectsLists = eventsFunctionContext.getObjectsLists(\"BasisObject\");", + "", + "eventsFunctionContext.returnValue = gdjs.evtTools.object.twoListsTest(", + " (stickerObject, basisObject, stickerBehaviorName) => {", + " const behavior = stickerObject.getBehavior(stickerBehaviorName);", + " return behavior.basisObject === basisObject;", + " },", + " stickerObjectsLists,", + " basisObjectsLists,", + " false,", + " stickerBehaviorName", + ");" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Sticker", + "name": "Object", + "type": "objectList" + }, + { + "description": "Sticker behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + }, + { + "description": "Basis", + "name": "BasisObject", + "type": "objectList" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [ + { + "description": "Stick the object to another. Use the action to stick the object, or unstick it later.", + "fullName": "Sticker", + "name": "Sticker", + "objectType": "", + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "// Set up the scene sticker objects list - if not done already.", + "if (!runtimeScene.__allStickers)", + " runtimeScene.__allStickers = new Set();", + "", + "// Set up the behavior extra methods - if not done already.", + "const prototype = Object.getPrototypeOf(behavior);", + "if (!prototype.updateRelativeCoordinates) {", + " // Unstick from deleted objects.", + " gdjs.registerObjectDeletedFromSceneCallback(function (runtimeScene, deletedObject) {", + " if (!runtimeScene.__allStickers) return;", + "", + " for (const sticker of runtimeScene.__allStickers) {", + " if (sticker.basisObject === deletedObject) {", + " sticker.basisObject = null;", + " }", + " }", + " });", + "", + " /**", + " * Update the coordinates in the basisObject basis.", + " * ", + " * It uses the basisObject coordinates from the previous frame.", + " * This way, the sticker can move relatively to it and still", + " * follow basisObject.", + " * ", + " * @param {gdjs.RuntimeObject} basisObject", + " */", + " prototype.updateRelativeCoordinates = function (basisObject) {", + " const object = this.owner;", + "", + " // Update relative coordinates", + " this.relativeX = object.getX() - this.basisOldX;", + " this.relativeY = object.getY() - this.basisOldY;", + " if (!this._getOnlyFollowPosition()) {", + " this.relativeAngle = object.getAngle() - this.basisOldAngle;", + " this.relativeWidth = object.getWidth() / this.basisOldWidth;", + " this.relativeHeight = object.getHeight() / this.basisOldHeight;", + " const deltaX = object.getCenterXInScene() - this.basisOldCenterXInScene;", + " const deltaY = object.getCenterYInScene() - this.basisOldCenterYInScene;", + " const angle = this.basisOldAngle * Math.PI / 180;", + " this.relativeRotatedX = (deltaX * Math.cos(angle) + deltaY * Math.sin(angle)) / this.basisOldWidth;", + " this.relativeRotatedY = (-deltaX * Math.sin(angle) + deltaY * Math.cos(angle)) / this.basisOldHeight;", + "", + " // Save initial values to avoid calculus and rounding errors", + " this.basisOriginalWidth = basisObject.getWidth();", + " this.basisOriginalHeight = basisObject.getHeight();", + " this.basisOriginalAngle = basisObject.getAngle();", + " }", + " }", + "", + " /**", + " * Copy the coordinates to use it the next frame.", + " * @param basisObject {gdjs.RuntimeObject}", + " */", + " prototype.updateOldCoordinates = function (basisObject) {", + " const object = this.owner;", + "", + " this.ownerOldX = object.getX();", + " this.ownerOldY = object.getY();", + "", + " this.basisOldX = basisObject.getX();", + " this.basisOldY = basisObject.getY();", + "", + " if (!this._getOnlyFollowPosition()) {", + " this.ownerOldAngle = object.getAngle();", + " this.ownerOldWidth = object.getWidth();", + " this.ownerOldHeight = object.getHeight();", + "", + " this.basisOldAngle = basisObject.getAngle();", + " this.basisOldWidth = basisObject.getWidth();", + " this.basisOldHeight = basisObject.getHeight();", + " this.basisOldCenterXInScene = basisObject.getCenterXInScene();", + " this.basisOldCenterYInScene = basisObject.getCenterYInScene();", + " }", + " }", + " /**", + " * Follow the basisObject (called in doStepPostEvents).", + " * ", + " * This method is also called by children to ensure", + " * parents are updated first.", + " */", + " prototype.followBasisObject = function () {", + " if (this.followingDoneThisFrame) {", + " return;", + " }", + " this.followingDoneThisFrame = true;", + " /** @type {gdjs.RuntimeObject} */", + " const basisObject = this.basisObject;", + " if (basisObject) {", + " // If the behavior on the basis object has a different name,", + " // the objects will still follow their basis objects", + " // but frame delays could happen.", + " if (basisObject.hasBehavior(behaviorName)) {", + " const basisBehavior = basisObject.getBehavior(behaviorName);", + " if (basisBehavior.type === this.type) {", + " // Follow parents 1st to avoid frame delays", + " basisBehavior.followBasisObject();", + " }", + " }", + "", + " const object = this.owner;", + "", + " if (this._getOnlyFollowPosition()) {", + " if (object.getX() !== this.ownerOldX", + " || object.getY() !== this.ownerOldY) {", + " this.updateRelativeCoordinates(basisObject);", + " }", + "", + " if (this.basisOldX !== basisObject.getX() ||", + " this.basisOldY !== basisObject.getY()) {", + " object.setPosition(", + " basisObject.getX() + this.relativeX,", + " basisObject.getY() + this.relativeY);", + " }", + " } else {", + " if (object.getX() !== this.ownerOldX", + " || object.getY() !== this.ownerOldY", + " || object.getAngle() !== this.ownerOldAngle", + " || object.getWidth() !== this.ownerOldWidth", + " || object.getHeight() !== this.ownerOldHeight) {", + " this.updateRelativeCoordinates(basisObject);", + " }", + "", + " // Follow basisObject", + " if (basisObject.getAngle() === this.basisOriginalAngle && this.basisOriginalAngle === 0) {", + " if (basisObject.getWidth() === this.basisOriginalWidth ||", + " basisObject.getHeight() === this.basisOriginalHeight) {", + " if (this.basisOldX !== basisObject.getX() ||", + " this.basisOldY !== basisObject.getY()) {", + " object.setPosition(", + " basisObject.getX() + this.relativeX,", + " basisObject.getY() + this.relativeY);", + " }", + " } else {", + " object.setPosition(", + " basisObject.getX() + this.relativeRotatedX * basisObject.getWidth(),", + " basisObject.getY() + this.relativeRotatedY * basisObject.getHeight());", + " }", + " } else {", + " object.setAngle(basisObject.getAngle() + this.relativeAngle);", + "", + " const deltaX = this.relativeRotatedX * basisObject.getWidth();", + " const deltaY = this.relativeRotatedY * basisObject.getHeight();", + " const angle = -basisObject.getAngle() * Math.PI / 180;", + " object.setX(basisObject.getCenterXInScene() + object.getX() - object.getCenterXInScene() + deltaX * Math.cos(angle) + deltaY * Math.sin(angle));", + " object.setY(basisObject.getCenterYInScene() + object.getY() - object.getCenterYInScene() - deltaX * Math.sin(angle) + deltaY * Math.cos(angle));", + " }", + " // Unproportional dimensions changes won't work as expected", + " // if the object angle is not null but nothing more can be done", + " // because there is no full affine transformation on objects.", + " if (basisObject.getWidth() !== this.basisOriginalWidth) {", + " object.setWidth(this.relativeWidth * basisObject.getWidth());", + " }", + " if (basisObject.getHeight() !== this.basisOriginalHeight) {", + " object.setHeight(this.relativeHeight * basisObject.getHeight());", + " }", + " }", + "", + " this.updateOldCoordinates(basisObject);", + " }", + " }", + "}", + "", + "// Register this object as a sticker.", + "runtimeScene.__allStickers.add(behavior);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPreEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.followingDoneThisFrame = false;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "doStepPostEvents", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.followBasisObject();" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "Stick on another object.", + "fullName": "Stick", + "functionType": "Action", + "name": "Stick", + "sentence": "Stick _PARAM0_ to _PARAM2_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const basisObjects = eventsFunctionContext.getObjects(\"BasisObject\");", + "", + "if (basisObjects.length === 0) return;", + "const basisObject = basisObjects[0];", + "", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.basisObject = basisObject;", + "behavior.updateOldCoordinates(basisObject);", + "behavior.updateRelativeCoordinates(basisObject);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + }, + { + "description": "Object to stick to", + "name": "BasisObject", + "type": "objectList" + } + ], + "objectGroups": [] + }, + { + "description": "Unstick from the object it was stuck to.", + "fullName": "Unstick", + "functionType": "Action", + "name": "Unstick", + "sentence": "Unstick _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const behavior = object.getBehavior(behaviorName);", + "", + "behavior.basisObject = null;" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDestroy", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const behaviorName = eventsFunctionContext.getBehaviorName(\"Behavior\");", + "const object = objects[0];", + "const behavior = object.getBehavior(behaviorName);", + "", + "if (runtimeScene.__allStickers)", + " runtimeScene.__allStickers.delete(behavior);", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "Sticker::Sticker", + "type": "behavior" + } + ], + "objectGroups": [] + } + ], + "propertyDescriptors": [ + { + "value": "", + "type": "Boolean", + "label": "Only follow the position", + "description": "", + "group": "", + "extraInformation": [], + "hidden": false, + "name": "OnlyFollowPosition" + } + ], + "sharedPropertyDescriptors": [] + } + ], + "eventsBasedObjects": [] + }, { "author": "Silver-Streak, @Bouh, Tristan Rhodes", "category": "Game mechanic", @@ -9501,6 +16391,7 @@ ], "objects": [ { + "adaptCollisionMaskAutomatically": false, "assetStoreId": "", "name": "Thumb", "tags": "", @@ -9524,6 +16415,7 @@ ] }, { + "adaptCollisionMaskAutomatically": false, "assetStoreId": "", "name": "Border", "tags": "", diff --git a/examples/3d-car-coin-hunt/assets/Grey Button_Hovered.png b/examples/3d-car-coin-hunt/assets/Grey Button_Hovered.png new file mode 100644 index 0000000000000000000000000000000000000000..628c879d7b074683459175ff43829bbb077f72e7 GIT binary patch literal 2208 zcmds3`#;nBAAfIi%XOn|8Jk*BDwnTlLb-ib7DD7f$D|{DZzuMsdP%)uEjy?&+i&L&)0U}-H?;FfB_jM@+A^yL;9;28zzqZUJ z>sR(K_W4&>8ew22KNN1bW6KSZ$4j$L4wRL){+>Z9*Jv(QQjf)*)(&%}lpwtY51PFN zUPR+mmAAhwH$D_~d=)(ln`~nqZQhN~u{^S25EeUhh;H4ox=uF;J(@whW3w!Y>PbAh zLm4C^=Dwv5m;w}teqCnfu!KIGW z)l@8`nOua{@zSjd^voCG2XV7=iR+Ti%ME$}fe6L*7u@4~NJ2u#`NxUle$DV<9TaKp zcxdS7m$&Y}nX_IK*yGV>(v(YB&To!EGv=j4vz2&*q)N}wUa(C+d0rVQS7o27>aM83 zJz*?DDJl3lzGw%gHe1 z>~t$#Wkp8|hWhXk~6Pj;z`7+YAZJRQ2hZh2)~o@_Ld|*eS+n?%y_cvIUf1X;F%S9~bfB+>7^ms1!;) z0wS_$$`hy1X)>Ap)0>DvirL!0l2B-@2K0yKhfGpYz5K3}Jq@cmTc(BZ?0aFglnQnh zdHY=zUbc#+!4VZ(zdgue_$D{{zbcWyXo8b>edU?mXyUgqsdi0_@exhB;x!XU7 zJM8*U+QtffcS(`3PkR{iNLz~_5{b@E@NP{SQOe~z3u^50C&ov&PJa3*E1Fj$*63IJ zR50jPq($|d|1w;+=1C4(Wii&u{p1kZSl&A|s{fFNX1#=4#xP6TjWFAOSEafly+Typ zD|4Qer3ZW2ovT|f6i|n2YI;h(?}B`E`yS~nbp&O)WGj}~@J(gN;g46*q^FM&2 z{v2$#*oI*LJBb1;_!5_R;Ef|>XjJ;q>Cqi5;6fJGlmra1MnycHBe=l|{;CTwoBJYW zA-3nce9C#D#!d*k9&(f61^E!f;~Hs?5sL62#tLJ4>?}Z@dJwZHd?}pyM^;^3G`;IY zIF<~}pz5b$Xb43_kd1W@Jm50$BFElwTa>gn0Kb5M=WeqW+qI1sKXAf=vmzOZi5OSc zLDomrC=hrre_-j%H4i6`SMbyBC)OfXfkL>XrtUZZg z|KW6)v^!cn*`~%?OgZhq6LuXE$N|3(9DkJMEbi|qd_$H3Zti$KS9j8T)-l& z(D&N{4Di9u;ny#y7tq8nGG#kTRrwFy#uKsvU7*{?Pc4bpvR8kM3@=|cu?A5fEHJWv zW^iX=QPERzIY65b0SRI+SC-F=H_HgsC;& z#lzY%E|^V4aI1DzRDL$Mv%5On6d6hVpR)0DJh%yxrGddI?*#(`=xf&k9QR|$-oXf* z9mpB|3(q4kJxe4$CE%d@$w|YlM-FiRE=TW@^&3=On z3{yEeJY4roKwGX^eSq0qJk%P$T87s~sZ>C9iHR1r3I`sb1EcX>v2lYqR zT=bLn+;{McUFut7Z#00yu~st5OLz8h2&;R5Fr~p33Wd687K+_%JWnjkk*Ix2U`pvN zZ!hHJyiXo#Wv>@eXFyS!vk~-=r&Do}>5W8*n|F!)j47?2pZK O0Vw1XP`y)7#{U8P9oX0a literal 0 HcmV?d00001 diff --git a/examples/3d-car-coin-hunt/assets/Grey Button_Idle.png b/examples/3d-car-coin-hunt/assets/Grey Button_Idle.png new file mode 100644 index 0000000000000000000000000000000000000000..8ac4d0f33b1ea3db3c725dbd1d01a349faa0ed0a GIT binary patch literal 2353 zcmds3`8(8Y7yr(Ty)a3sY=cZ5dtOOVwy$Ow*|&@}YZ|+lESWGFk4qv^6j`%Q>Sbi# zN+iiL27{R_kEO>jcr4kT>AK#(;=QhO?sH$~{^6X@eLnZ+x|1!J1ONaKG(m&b z007}^0e?Oo&T8YI#^MD2VDzmp0FX@j?U1y2wl^nvHr&`T+$P8;Jklf78;FdIRJ{{; zH_X!`*jqIy)Hj!^@s7g z)J~(4>I#arL-hzsR;C@wzi(MsVXb8M?7g2Y@iuORr^MRuzju}H4T2RCz4-KSyPAh4 zHBgsCwmO9!h8y@fJwFjz1^)dphg46lKO#)^FpNJ^ICY+L=uEuma}ZsYGplgylOK5vw|HuHX*JeC5Hx zXCK;Kr^|q=^v2UI0d{2Hin2Jc@U3OAh(Lq%gzm|uOO8!qS2 zL3>e+akJA_B0$`k4?6;xQT;C2*0(Jd0>fG3sgB}e+#t5!OM{p;bCMLN3HcmiDxSH# zy0UT|>pTQycDz55W<@EF{@In3hr(cNPCdE_KGO^fIxQzBjYvl~MqV+U*^7N+(Ohr8 zgDVsk64DaG9SMH;wyUF)|0z94ije6&z(ev&IVX7lcObh)WnYCV721_pQw2-^cjMn=`U@vCh>RUO%{_N?CFpzsg&BI*#Q zl~%rFtgK45J$x%ys8;*{1t0X|%9PK}J-D+;RYWXgGN#IqbV{)gydsisK1qHO_o81Upb_e5*n;(Z;m zDajo8UZLc3p2$Lh+?*T~^69YuK&)NLa6k9r9V1C_aEjpm-4KP!9eruq-xY$N zyD%Y?3AMI4=A?2i;D%?y7CBErVd1qXeBhLW=R5nAgx%)Ul1=}*Zd1_iiMj8SzEibM zO+VXJC8+WRw!R^Q2bqkSAp!h^MeTvI$`UVYE8-e}sBwTUDv+tD<+?oTsRQSD5+#Xh z7t3PtB{@r0xELB>H?;kh9bto07U=QU2b=JGoW89*#JYFshw0Y;Mb1^dlrWC|M)9G52QbhW@YVG z3#qxWbhYn_u>@g*!>E>$Ln^`R% z^&Y5@1F%`b?;Jh3lh7b_Xmr#u6cQYx>q@D|0Uu{iKF@a>@fS>oPtbD_@(xfCn+}J* zqukKcO04}gISIYqx@$5%fCeZ{i`qhu7}7**)5^=BA$}R7bN?p6FQuGu;^VNz3h3$S zSgBN^t{Zdq@oeUvW5+QB3^6zT6n*}p#yUhu`hjaDr-`PBIz+Y-;?*~I?@K9WNMU+} zJKfyG4{kNj_doH-nm2M$Cj^fvHZbdb!Z#W6Vp}OyQIKLQBtY1sL3O2)#awrsdX4ot z7gAcPoiwvvrX%(VWX`%9*~I}kULwWY`;0}*6e$o%p>vzz_Qo^+U>AE}CV1H^vh z0D6?978E|$W`S6G)-K5%9x#&qyg3CEx2truZC`n7m632E&#!zApIpXyvBPJiQ)Xv# z^Q$7iy**(n-)vg0owzgIl_UANBX#HIB#8lPOBixw*O6{s3+8%oLu;x4C`7M$dVN6_ z+&oee73lE^>+yQu4J0zqvljdN=reuf|$r~ z+nJi^_Jw?B#Nq7qC17i77x+kiI-$juD2rEDFV)+BcjaX*T{%=0HK#pr25keNi+W+D zdv2fVG8iyUfe-_rg=xy+dI8snT2z$z%dl0)ZQ8YOd2zE%ogKNrM8#E2*^1Ic(dDwe zo;IJUqkoE4HPQRY;Y603NgzR1(1VuPViOxAY3*YM=^Q>T3&SvvY2VaJ{aB z%e=cy?jSY|s$NRKM7XxJL{tXJ<>vMH4jh&XO5I0mR~&;zL#RSMTKe3;TDDPgMUW8u uR=bG+^Rcz8Di`_c5ikN+3BxkB{- literal 0 HcmV?d00001 diff --git a/examples/3d-car-coin-hunt/assets/Grey Button_Pressed.png b/examples/3d-car-coin-hunt/assets/Grey Button_Pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..e22c00b1c7fbbf916016a5c5506a614d0af427b3 GIT binary patch literal 2118 zcmds(`#%%ju_2y2AZ$wX4*x+zK_LvxusqnKu~3>%Kqb`XcKj^t9ghE8tD zwU%z~_044t79y7oVWYy=_xtPjKlr{LkN5laemsAAKOXPLo&F{y;bOp|J8i%W5GT) zn|MvM+gV~{ANOcKK^4;gY$1g5bunhydrA61Yz?|w5h%e2Y_XE#>dL1mH;jIXs{j;U z{glT~{ezYY>y`n+;F069W3Y-@>@l_JG3*pMiuMea+$6x)8~per1q3^c$tjB zoL{ZiK4BdxoBc&-=cB#uA>6M^4r+I7Y0yIdi-L0)A^X`MvCTWnku=Znh!LQyVzPw7(u|Fa{JL^_-UfMOj14E+mq4s!I)rhQ@u$Q?#VWel2!#|I1qspaK9pa~%>I&6 z;%82M9xFfJV=hdh)8WVW=QKZQtY}AnKQk9jdKg+P9<@l3F@3I%@$guf-9|IY8nm^w zuU}s@(8IS#x>TvS{kbI6i03P$D>oA#Jn&HcuzPp@`ekw0t-uZR@O6+T~cp0Y?}Y@-3=4lNb7 zq0aq5$IW~gZF{4U%;2)6cN9_4Go)>4NDCHM6I);*j)HI;@75zn6H5!sfq&IOn+`uI zU4_u?M%jU2g$>Iiq7?ko>WYn3@9oe6sb3XdzC@!Anw;8j8E=VPganUb?-);g=0e~H8apZ9$Nf4A6(+1~0`)4E4c_LzlwY zt<^~lr?{t7<2oqd5P+8XH`T|QKn(nsWlJm~L!j`L<-#SZKnwBRf;-Z;7i!+#n)KFJ z5+H6J2aJQS0i2`^rT>3|AaG|g`Eq&PODv*7$FCJ%(wHLF;n$Mcr<9p8Tq)z^^@M7i zdvw@&za)Kx(kTVl0A6t+3QVuwq`rR)i8zLThs#QJ`;jI)z^SDUZAZZL!@;H&{_g#@ zY}RK(z?jb*Yj*x<_%3m>0upfupT}aI*PE>A9AprxMp~~58^q1^GYDFzLky0;Q-=G9 z%Y4f2KncU|sewPgo|ackYJ?CToic8uBNtARx-~&Tw*08 zB)JvEn424z#2{CK`k)4LMjWK*Ww148hxD;2WtDCOxbJ~JF z-jTaTBzA7=XrLn_KXQ01M(Ct~hijpJ-FVhTXy(@Q{rTWcV~y(+|# Date: Thu, 3 Aug 2023 15:18:33 +0000 Subject: [PATCH 2/6] Optimised images with calibre/image-actions --- .../assets/Grey Button_Hovered.png | Bin 2208 -> 1689 bytes .../assets/Grey Button_Idle.png | Bin 2353 -> 1775 bytes .../assets/Grey Button_Pressed.png | Bin 2118 -> 1681 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/3d-car-coin-hunt/assets/Grey Button_Hovered.png b/examples/3d-car-coin-hunt/assets/Grey Button_Hovered.png index 628c879d7b074683459175ff43829bbb077f72e7..8065deaec03d77c5a71c6749d8d82ec1a1992dc4 100644 GIT binary patch literal 1689 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 O0Vw1XP`y)7#{U8P9oX0a diff --git a/examples/3d-car-coin-hunt/assets/Grey Button_Idle.png b/examples/3d-car-coin-hunt/assets/Grey Button_Idle.png index 8ac4d0f33b1ea3db3c725dbd1d01a349faa0ed0a..efbb5d1314f9f50ba47457f58dc1f071281da01e 100644 GIT binary patch literal 1775 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 uR=bG+^Rcz8Di`_c5ikN+3BxkB{- diff --git a/examples/3d-car-coin-hunt/assets/Grey Button_Pressed.png b/examples/3d-car-coin-hunt/assets/Grey Button_Pressed.png index e22c00b1c7fbbf916016a5c5506a614d0af427b3..6735c8e5ecdc255a3f9ff763f2e57ef967933b83 100644 GIT binary patch literal 1681 zcmbVNdo#?qR+~r4D?`y^5dRuMv<@XT2#DM!0vV*x-W{|LFv&kLadDDHK0cJw_zC>#nPyu<6X#!!-& zn_0|mOXd4Tbgn5^SvM@Yz9gmjtw`A+U1$*coM@I4X6pGigO$a4QuOkwm6e)Bn0r3F z%uSHJn=}hr$TR5rgIYB*_Q(oQ0o%g;V5jr}*)|u|5ECheN$Wz1EBZyMq!0ENjk6rPR ztc=iPyT$VIe0IVq!61wCrdgrd=vYmFEb*>4_xq#E_P5mcOcmjycha_zZp6}Guyx6+ zDHMMWv*sOU^@Oh{rmLcb^!;$T?~(M@3cnzMw~*+v!AZ0O9fFQP$D&DSIyx179c4yi z+@3-O#fTeGy~NQv$2s_R)Gdkm`rhPg12;D1U_A>?UNo7PR2GWjyR0+P(#qXy-)t~3 zk}sdeA~zvD%xM{)#K}bec@OqD$JU~%et3sVPF7l}O=DKQNml*NFt#*)Je2^Sh#$J( z5;RMQ-10us?BZ|te08=S{$Q%S3y}8X58yrV7`zw$@nUxA)2X~W@1i!|_TW$4;wfH( ztEtN##1FY46D2Jx7F20ZWC!eIH5i-u?ep2C6B}?j<0#)*Rzg%wK6E!8oWY8Bx zyT)2X<<>j;X{c#CX**nDM6BAQ&##Lyw_PdF^Eaq8j*bm(-L0C-BeMklk|4i?Y#ZUD zWW8es=AEx;?xi=+TaEOVHmh%!XgDq@CCw#k3O9d%>-iek9Vuw9p*EY_>!i}82hAtM z0%z+$jzx}mX@UwH2w{Bm@*K99Q!Kppikw`6nB%YJB-xK__g59KW-2Y1$|EUlXwK+g z6LijKnQZ8*eD#Hh#~V@9(q7F)jT8L|BKt)yzpkMnc*tqQ0fsfIiP&QpnHVZ&YBhz& zl_b92qI*O}OWU(cCqGpZFps%UK^#|^s^cD&&k%_v$lNQ?dy!P_MzE5H{3&O06tD`&CwDBd~P_i@pK4X zUKw|-GwK)4HmNoW@HmDF(N^^_D`mkmo<-}FG};XFhQnH039nR|Vpbk)<9*B6XPqFe zeOX1vU#BbMrk6N*4GQN6*xKgQ!Y@dsqT=Os)0DUp`(x#OX*?x8Zv&4swxq(Jk^4aw zz{))%UT&8n;tq`!!}97xf&=7buLGUA3em3;ZWn&Kb5;7bOTA*JzvqlI zu`^cAfv7D_=>FP==!lUIk$Y>$3;@tokmD)$-$Usjkw=H4teKX!wI@8mBqxHr_$0{C zGVu(qb7hGzzPNV|+rwp0_=y;Cf0b>m4=(B8;QrZNm(||G#N;brhc-D}ovUPa^$@LD8e^LG5b9~zf4a&8tP^!icL zxdh!!NS~A3kp~*tw6=bK|p#|=ch^%7)F*=IjwgJJdSI{_2Z!V#ufrE zJnv3yd(|+3ieG*>?0jddp8Ii4kY&t&LD?-7m^CIj^6bju`$ipLdA)sf*|!W;GP^y= z=_H3g;C3OQEiqEZK`<%8_lYn@vx^)?+u{qBP(O#1vRohRD*OIWxF+)(iZQPQ_*dKs nP{T->J3%{Ou1!?4%5D=FUwL}?%Tzt|bO3PMhjC^&ow)QjwZ;AG literal 2118 zcmds(`#%%ju_2y2AZ$wX4*x+zK_LvxusqnKu~3>%Kqb`XcKj^t9ghE8tD zwU%z~_044t79y7oVWYy=_xtPjKlr{LkN5laemsAAKOXPLo&F{y;bOp|J8i%W5GT) zn|MvM+gV~{ANOcKK^4;gY$1g5bunhydrA61Yz?|w5h%e2Y_XE#>dL1mH;jIXs{j;U z{glT~{ezYY>y`n+;F069W3Y-@>@l_JG3*pMiuMea+$6x)8~per1q3^c$tjB zoL{ZiK4BdxoBc&-=cB#uA>6M^4r+I7Y0yIdi-L0)A^X`MvCTWnku=Znh!LQyVzPw7(u|Fa{JL^_-UfMOj14E+mq4s!I)rhQ@u$Q?#VWel2!#|I1qspaK9pa~%>I&6 z;%82M9xFfJV=hdh)8WVW=QKZQtY}AnKQk9jdKg+P9<@l3F@3I%@$guf-9|IY8nm^w zuU}s@(8IS#x>TvS{kbI6i03P$D>oA#Jn&HcuzPp@`ekw0t-uZR@O6+T~cp0Y?}Y@-3=4lNb7 zq0aq5$IW~gZF{4U%;2)6cN9_4Go)>4NDCHM6I);*j)HI;@75zn6H5!sfq&IOn+`uI zU4_u?M%jU2g$>Iiq7?ko>WYn3@9oe6sb3XdzC@!Anw;8j8E=VPganUb?-);g=0e~H8apZ9$Nf4A6(+1~0`)4E4c_LzlwY zt<^~lr?{t7<2oqd5P+8XH`T|QKn(nsWlJm~L!j`L<-#SZKnwBRf;-Z;7i!+#n)KFJ z5+H6J2aJQS0i2`^rT>3|AaG|g`Eq&PODv*7$FCJ%(wHLF;n$Mcr<9p8Tq)z^^@M7i zdvw@&za)Kx(kTVl0A6t+3QVuwq`rR)i8zLThs#QJ`;jI)z^SDUZAZZL!@;H&{_g#@ zY}RK(z?jb*Yj*x<_%3m>0upfupT}aI*PE>A9AprxMp~~58^q1^GYDFzLky0;Q-=G9 z%Y4f2KncU|sewPgo|ackYJ?CToic8uBNtARx-~&Tw*08 zB)JvEn424z#2{CK`k)4LMjWK*Ww148hxD;2WtDCOxbJ~JF z-jTaTBzA7=XrLn_KXQ01M(Ct~hijpJ-FVhTXy(@Q{rTWcV~y(+|# Date: Thu, 3 Aug 2023 17:35:08 +0200 Subject: [PATCH 3/6] Fix score check. --- .../3d-car-coin-hunt/3d-car-coin-hunt.json | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json index f595c8504..f3e6ff47b 100644 --- a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json +++ b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json @@ -3593,7 +3593,7 @@ "parameters": [ "BestTimeText", "=", - "\"Best: \" + TimeFormatter::SecondsToHHMMSS000(GlobalVariable(HighScore))" + "\"Best: \" + TimeFormatter::SecondsToHHMMSS000(Variable(HighScore))" ] }, { @@ -3730,9 +3730,15 @@ }, { "type": { - "value": "BuiltinCommonInstructions::Once" + "inverted": true, + "value": "CompareTimer" }, - "parameters": [] + "parameters": [ + "", + "\"Time\"", + ">", + "0" + ] } ], "actions": [ @@ -4468,12 +4474,13 @@ "conditions": [ { "type": { - "value": "VarScene" + "value": "CompareTimer" }, "parameters": [ - "HighScore", + "", + "\"Time\"", ">=", - "TimerElapsedTime(\"Time\")" + "Variable(HighScore)" ] } ], @@ -4503,12 +4510,31 @@ "conditions": [ { "type": { - "value": "VarScene" + "value": "BuiltinCommonInstructions::Or" }, - "parameters": [ - "HighScore", - "<", - "TimerElapsedTime(\"Time\")" + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "CompareTimer" + }, + "parameters": [ + "", + "\"Time\"", + "<", + "Variable(HighScore)" + ] + }, + { + "type": { + "value": "VarScene" + }, + "parameters": [ + "HighScore", + "=", + "0" + ] + } ] } ], @@ -4540,7 +4566,7 @@ "parameters": [ "\"HighScore\"", "\"HighScore\"", - "GlobalVariable(HighScore)" + "Variable(HighScore)" ] }, { From d94e19043ba687b08894ba9bdbcbe4adb8a1ca16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Thu, 3 Aug 2023 18:43:12 +0200 Subject: [PATCH 4/6] Use game font. --- examples/3d-car-coin-hunt/3d-car-coin-hunt.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json index f3e6ff47b..5e977c185 100644 --- a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json +++ b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json @@ -4906,7 +4906,7 @@ "persistentUuid": "722f1233-75ba-4128-8905-4ac5dd26bc1e", "width": 384, "x": 386, - "y": 172, + "y": 184, "zOrder": 18, "numberProperties": [], "stringProperties": [], @@ -4994,9 +4994,9 @@ } ], "string": "Score", - "font": "", + "font": "27d4da0f7767cf3fbf14eb2c8da758dbcfc7b5038c9214d5e6ed62db6476a6e5_Chango-Regular.ttf", "textAlignment": "", - "characterSize": 60, + "characterSize": 40, "color": { "b": 79, "g": 72, @@ -5020,8 +5020,8 @@ "content": { "initialValue": "", "placeholder": "PlayerName", - "fontResourceName": "", - "fontSize": 60, + "fontResourceName": "27d4da0f7767cf3fbf14eb2c8da758dbcfc7b5038c9214d5e6ed62db6476a6e5_Chango-Regular.ttf", + "fontSize": 40, "inputType": "text", "textColor": "72;72;79", "fillColor": "231;232;243", @@ -5082,7 +5082,7 @@ "smoothed": true, "underlined": false, "string": "🡲", - "font": "", + "font": "27d4da0f7767cf3fbf14eb2c8da758dbcfc7b5038c9214d5e6ed62db6476a6e5_Chango-Regular.ttf", "textAlignment": "center", "characterSize": 60, "color": { @@ -5152,9 +5152,9 @@ "smoothed": true, "underlined": false, "string": "Restart", - "font": "", + "font": "27d4da0f7767cf3fbf14eb2c8da758dbcfc7b5038c9214d5e6ed62db6476a6e5_Chango-Regular.ttf", "textAlignment": "center", - "characterSize": 60, + "characterSize": 40, "color": { "b": 79, "g": 72, From 167b8be0b143a794a01d8b049b9ba70f44a9edad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Fri, 18 Aug 2023 18:10:05 +0200 Subject: [PATCH 5/6] Change buttons color to yellow. --- .../3d-car-coin-hunt/3d-car-coin-hunt.json | 63 ++++++++++++++---- .../assets/Yellow Button_Hovered.png | Bin 0 -> 2270 bytes .../assets/Yellow Button_Idle.png | Bin 0 -> 2285 bytes .../assets/Yellow Button_Pressed.png | Bin 0 -> 2187 bytes 4 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 examples/3d-car-coin-hunt/assets/Yellow Button_Hovered.png create mode 100644 examples/3d-car-coin-hunt/assets/Yellow Button_Idle.png create mode 100644 examples/3d-car-coin-hunt/assets/Yellow Button_Pressed.png diff --git a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json index 5e977c185..97966addc 100644 --- a/examples/3d-car-coin-hunt/3d-car-coin-hunt.json +++ b/examples/3d-car-coin-hunt/3d-car-coin-hunt.json @@ -524,6 +524,45 @@ "name": "assets\\Grey Button_Idle.png", "smoothed": true, "userAdded": true + }, + { + "alwaysLoaded": false, + "file": "assets/Yellow Button_Hovered.png", + "kind": "image", + "metadata": "", + "name": "Yellow Button_Hovered.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/c1e14acb64b9963341656c997853154dc4c86cd1c46fb12bfbe012d99712ef61_Yellow Button_Hovered.png", + "name": "Yellow Button_Hovered.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Yellow Button_Idle.png", + "kind": "image", + "metadata": "", + "name": "Yellow Button_Idle.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/1cacfd123a1eb708837337c27982f6871f5127c5890dbf0775e0f411958fcbf1_Yellow Button_Idle.png", + "name": "Yellow Button_Idle.png" + } + }, + { + "alwaysLoaded": false, + "file": "assets/Yellow Button_Pressed.png", + "kind": "image", + "metadata": "", + "name": "Yellow Button_Pressed.png", + "smoothed": true, + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/Menu buttons/928c3ea4db1da835c9f8cc5b7089a47228350209d2ff489e1484c31e5ce41b3d_Yellow Button_Pressed.png", + "name": "Yellow Button_Pressed.png" + } } ], "resourceFolders": [] @@ -5061,7 +5100,7 @@ "height": 106, "leftMargin": 16, "rightMargin": 16, - "texture": "Grey Button_Hovered.png", + "texture": "Yellow Button_Hovered.png", "tiled": true, "topMargin": 16, "width": 256 @@ -5071,7 +5110,7 @@ "height": 106, "leftMargin": 16, "rightMargin": 16, - "texture": "Grey Button_Idle.png", + "texture": "Yellow Button_Idle.png", "tiled": true, "topMargin": 16, "width": 256 @@ -5086,9 +5125,9 @@ "textAlignment": "center", "characterSize": 60, "color": { - "b": 79, - "g": 72, - "r": 72 + "b": 42, + "g": 87, + "r": 139 } }, "Pressed": { @@ -5096,7 +5135,7 @@ "height": 106, "leftMargin": 16, "rightMargin": 16, - "texture": "Grey Button_Pressed.png", + "texture": "Yellow Button_Pressed.png", "tiled": true, "topMargin": 32, "width": 256 @@ -5131,7 +5170,7 @@ "height": 106, "leftMargin": 16, "rightMargin": 16, - "texture": "Grey Button_Hovered.png", + "texture": "Yellow Button_Hovered.png", "tiled": true, "topMargin": 16, "width": 256 @@ -5141,7 +5180,7 @@ "height": 106, "leftMargin": 16, "rightMargin": 16, - "texture": "Grey Button_Idle.png", + "texture": "Yellow Button_Idle.png", "tiled": true, "topMargin": 16, "width": 256 @@ -5156,9 +5195,9 @@ "textAlignment": "center", "characterSize": 40, "color": { - "b": 79, - "g": 72, - "r": 72 + "b": 42, + "g": 87, + "r": 139 } }, "Pressed": { @@ -5166,7 +5205,7 @@ "height": 106, "leftMargin": 16, "rightMargin": 16, - "texture": "Grey Button_Pressed.png", + "texture": "Yellow Button_Pressed.png", "tiled": true, "topMargin": 32, "width": 256 diff --git a/examples/3d-car-coin-hunt/assets/Yellow Button_Hovered.png b/examples/3d-car-coin-hunt/assets/Yellow Button_Hovered.png new file mode 100644 index 0000000000000000000000000000000000000000..d575c5e6104c3f4f77ab0e19c6f700bef0819c25 GIT binary patch literal 2270 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 literal 0 HcmV?d00001 diff --git a/examples/3d-car-coin-hunt/assets/Yellow Button_Idle.png b/examples/3d-car-coin-hunt/assets/Yellow Button_Idle.png new file mode 100644 index 0000000000000000000000000000000000000000..b8b5b35afdfca3753c93e298416b3fd085d2922d GIT binary patch literal 2285 zcmds3`8(7L7ymLh%V4rKmM}GRO&1Xr4U@sxB7}RbVYrs8gDGPPB}9J(bgj>>m8~d(I!Ys%(c;~%;#{0urp3ig6FXx=+^Er?|d~ieLZ$B&@A4jsPIQ zPk~?&A-;DC&fVY#QJj@qGyo{4|IY++zi|BdpaS0974H-gfRDjO`2#UAF&A!!heZ2f zasC$~q5>%!Mv4F+5@(GuaVC_mPu~mubz7Ov*iLgLLj zwshT72*F?Iao402n)T4eX?B{HO>26Mbc=Bs?$o;9)%@0?njMc4r2Il6Xs-Jc&P_GT z>PW#o+dt(IdzDv=_v$zlJnGD`u2ZW|X6bH$wc%rF4^y`X0@r(?cG-+e!N6KvW;}J_ zoX>Ty0hxTx$A!}>9aUtliMs(3$z}GNIwWtvi+1?7_?5G5SJ|gk3WDruk99jW+AH1B z>)2ss0tuAM$0r6$CRIFMM#DfT^>5#in25DAGnU8Ji))-wNHgPQz-X|0uc5A>&&oeW zX<2Ltg^#Lp1(13&P@Nf6);8t@+L~Tw>)(Z+3|47P%{! z;TSM`s5X$bd?!e1@Z50zde^h16#ZU9B%7=kh1Eei-jMi26uod%w@HfZTS>w&ULT~; zD|YTN4>sNA)Bxt1ez>kCuU-C-t$zuKDc+?9V>Z<1Yqp#>ND`HeG4d*Q&jW}&v1sw4#)S1Rf zja5Za&utjdgw-BP`4z*h*n#QD^L%~$nW;1As`LfMmTznrb2t$-l`d_LX*dgAG!!h( zY>VxI^o5Qn)>O-7X@opjv0i&Wk^nF8K7^gPA~sy#r+jCYof})~;($CqUSLp^K8R6c zNvDG-ql=k1%WUDI8W-?&Q-M4r<)85k&W6!GKiyc>tqS^Zy7a z2+XSsn<}R+UCzo_E^v_@-zq#LYb}_*G*($fjI2Arb+4I*=#!ZrLPg~q7iz4`!_%en zIZ~p+Xrrog!-mNYfb9Ff|1Ha01yK}2D4GHvPZ&xYE0rqPXMXxT0 z0R5A+JcDRW*B73GPLv*v5AXBf1s*j(%{55zj?mDGU6Se8k$$tvqCg#Pbl)0sydCIs zIG;0Ajhl(62))>*gNS;?PGc++T`IWs_fd>}rNj_r#)#`zz`8kF0)@U!d*h_Iu{5B4 zWN57r8=(zjA%$-Y&DBnHI?I8C{6q@Qig>q zt%q_DL=~WnN@4$T!gFp*vgD&iqKUGtr;uj*bdouS+wWekI^{Lrzj0H}7@Zq9-=B&^ zUL&N?vggzzzXpY?%jS0&#O%vVCLX`Z(n{39mz0H!i%&;46)I|9|4g+hnIyofox%r4 zYvBbNsIr5rO$R6O>q*fqBRp(Uj_*WzD* z#HmOr7!Pof;>I5W;T>SL1||ls>$ML~@Jd+#O1cW{#J>NvW((I>sS@S(Zp8A+2jOnMdhMkN3mAXL!lS60RP5U_dtBTzNkaE=P5{l75X4)N z&hOAOdRa?;{mDjQ?%S;`Cx+kd**Ntx+}l_Qqs~UMT(9BZL6&^=t7fpl4uxZ*7`5_A zD%O0rIH|w3YqiPevImC@G7>8t9>c>6T!FPS_uU>Dc&`flo~W1qZVR z*Dl@}^n^SIp()8dQy{5hW{B<8b5uDw-8U4W% zPdscHY~4;HTuJT$%$jq$_l@{?cG0z)NVg=xUo>9GkWXVfGOie3Fa%t}S+ye@hW@TH zRkHaj^r6(5l~+}qov4luVfsytgfRsw&=xhj#9f+uHi@K$>W+7hKVDXszO)8F2LRZ#V@n^d(G}b5M)3rqq!-;sfwZ0lK@s@pzlF+*! znblyvb=H(+9W#)fX?YIC$HBXDlYS~Q?53+voDn19p(FkABvtz>gSst=#t@cPYZCXa?Ik^<#9<&tZ5{ z@v!63h7jo&>U~{zA5^gDx$(3kpa15yDW)&ACAQA^bT^cxtfq++N3jw!o0(Fl5p3KU zuE-s%2m?|WNy!l6%S#K;=MIMe!@yEWUbA3~YO1?aQ$AbOM?}5i@~&Rx{DOXuY3fN4 zN%{Ce9K0u$=a0pI9dPEi;|yNhvcz$&E;7V3Y(OSAQ_i9sIuXfYpX!hnzf2}Q%(nVB zwi&6~I|sajlhWUUuG4GMdKY>ghj`Z{EH1S2_Qxelil-pTuyYOp55H?H@~nKhG|NjM zg>O^P6pQn>(bY`L~sO6h-Zx^k>Y&Pxk6HX&pu9Uk4K8+-Iw79~9%>Jgg+D`^6<9NYd zZ{7(Pg(A(nF2c%eddV6#o9XL+HkZBO*gNFx<5JBE!-sv3&w5uLl@*3dQs7x0KindF zXe+Aa8SPV@MOrYiWBdc{w_P+%H#;K9K>^yGuyRp?@mYm zwF>E%xE}iPV#AdAjUhg&NCPIeVl$`obot`+ilH+Ex@|z-HOVPiG$|w>tu~TIdvngQ z^a~YPxjv~s*KGf*6mCTjvHtEa#|cJco) z03)C}W0XaFG4rZ#F3COToh6a#OCsD6q`&aUI#G>Yu4>hnM*D?-^T?WH=V}XlU>O~_ zh-s@|)^kP`$QhXt?fjTJNdi$L5m{gaR}c-ypbCo0*OW3dbP3E4(*EYkuL>>5G|ae< ztXCOH4NfKewj^8h92^va=AyE@a?dl-F@#4%Fsu>-(8!jBw&6IDC^LH0A#Zqj4j8el z-aCD}U%_5Yo^w?2n(3o>{DWBE)O4iQ7cgD&U|%!tOkyAH*!2dJ6O#Mob(|%aJuIIL zl@UdM-(w_=T#7d+ZpkvFKU{SDHuH=rHeCCVf9)OI1NE|s&#;RGeyMQJHLW04PFa9} zz;R_|T3oo){JL!9wE@?VF`=hVmsbwtYw3GEp9YMvaqo97^ekOl8;{@8txqKA{V|T5 z6GT#77kE>f{@UxB#(fp+(Y#%?27_ZUm7>DGF3k?>FF38|LCjkT%I^21cz%PyV`Bco z+G~vM!xZ%iV?6(E31z!_W;ZxqCQA<)s(Ocve4-dGHTL!U4s3&8!lY~P(u5uVPF;PJ zs&TbiF*#kAHy@oSwH_CC&}6`Kz?&pQf1%?nYN*uxK`G)jwmyxmdO^bBuWeXmCWQ8V zL-wZ%^MI;(An4#5t6qDO5PW&(1q{ zeXm;#O8I2`ZMBZd_I>$)15E~e(cuZOf*XA!lyM<={m255P!A$;w>;E?UEw_&0Ofmg zxdv>s5G)Ba*2v>sywI%1`}$vVn0&X=h>}JM+(=)l!yP_=kc8T77-#p2UJ%NHTCCDX nIb`5BCR5Jm{E$JxO}=13nS{~%=(-zwj|70WcR{_j^-uc;WzO@J literal 0 HcmV?d00001 From 610b7c11f08e54f96aacf9e02c239cebdd757eab Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 16:12:46 +0000 Subject: [PATCH 6/6] Optimised images with calibre/image-actions --- .../assets/Yellow Button_Hovered.png | Bin 2270 -> 1797 bytes .../assets/Yellow Button_Idle.png | Bin 2285 -> 1812 bytes .../assets/Yellow Button_Pressed.png | Bin 2187 -> 1791 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/3d-car-coin-hunt/assets/Yellow Button_Hovered.png b/examples/3d-car-coin-hunt/assets/Yellow Button_Hovered.png index d575c5e6104c3f4f77ab0e19c6f700bef0819c25..9bb3ab612e8fd2b7c53581a07b6dfe5ce4b5b065 100644 GIT binary patch literal 1797 zcmbVNX;70_7k=|*VM+L?B5R=p+gc3B+KLb$q^v3m;zlH3S~i1ASX2-u@KUM;L<2@3 z0okNdSw7MR5!sSZP#VP`62Ty{l~jTO!zPFcX`KG(bo%F;@5jC8nP<+NXU;kIoSPH8 z-(OGHOcwwEz1;ymApii=Kp;*VrMVBrG3GT!Cq96b1OOI4d^j+MbRil5P%XQCh=)=} z=0?L#F{90U7x;OBc}H&`hz14&XnT+F3+RN(oF7uKl|5m!?2iP9&wG5}zhkTBv~!Gc z6IKPa4%$EGINekDQ3m6+3!3Fm&c8eoI$|->$mkywEtI#NnGGDDd%vy1_BC~yn$Gup zv*hU;b5XySy_e67seYCOvuHK8|BX#=v77esz%NVVcLv_3O>+i$fY{Pac2uB z@8);76i_q9-u283{3MR=cSM;gG6VY)4C^x<)Fb?sw-fgXkpxcChR^SN_go==LxEL1 z)?OEJmdFMQvWa*wi!RbyEe{JzZL7dnA4+Wx5t`lF%&>XZ8BqJ&{MJp7Qpd_;H?aFY zudt7K67`GErseRI-f+-LB5e~9QY92QF?`&!YO$3tYG2|(Qg#odr8q;ml}#*iW0NeQ zq?|u{&dnh{l5g9QHh+9{I+B`=E0mp%=d-A#GpA7Iw*wCExwW%3v9$B$?X6mMWlhkP zdT2&E^_2Y*DY#*{h_puB|w*V=Xa3iJr5t`0dBm|Dc%+qSpg*UFnBY@c0vno*}nKbWWc$KFb74IrchREF>?uEtlCe zZ$jy?iu}%8in^GW{Jr<09UK`*D1aJ@bIkw9>_b4Zq{riA8B=IJ35kE+2CS)X@a1>- z;sc>37@?hND_rw>ID6@*tt6zxE}B#C6%{wwxXZ68E&Fu07n1g7N6gu**KX>Jb1YSN z8|g^t$((h4i{bn62h@3S^bVLneUp>#TIR7-7{T;ix?lcFr;53210)rv{3jUCTGRY% Oz;56DK8;^fzWWmkKQFxi literal 2270 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 diff --git a/examples/3d-car-coin-hunt/assets/Yellow Button_Idle.png b/examples/3d-car-coin-hunt/assets/Yellow Button_Idle.png index b8b5b35afdfca3753c93e298416b3fd085d2922d..86bf6cf37909a0bf032238b61f011f67f411a146 100644 GIT binary patch literal 1812 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