@nice2dev/game-engine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/LICENSE +21 -0
- package/README.md +105 -0
- package/dist/cjs/accessibility/Accessibility.js +162 -0
- package/dist/cjs/accessibility/Accessibility.js.map +1 -0
- package/dist/cjs/ai/AI.js +321 -0
- package/dist/cjs/ai/AI.js.map +1 -0
- package/dist/cjs/animation/Animation.js +233 -0
- package/dist/cjs/animation/Animation.js.map +1 -0
- package/dist/cjs/audio/AudioAdvanced.js +262 -0
- package/dist/cjs/audio/AudioAdvanced.js.map +1 -0
- package/dist/cjs/audio/AudioManager.js +248 -0
- package/dist/cjs/audio/AudioManager.js.map +1 -0
- package/dist/cjs/core/EventBus.js +63 -0
- package/dist/cjs/core/EventBus.js.map +1 -0
- package/dist/cjs/core/GameClock.js +70 -0
- package/dist/cjs/core/GameClock.js.map +1 -0
- package/dist/cjs/core/GameConfig.js +86 -0
- package/dist/cjs/core/GameConfig.js.map +1 -0
- package/dist/cjs/core/GameLoop.js +93 -0
- package/dist/cjs/core/GameLoop.js.map +1 -0
- package/dist/cjs/core/ServiceLocator.js +73 -0
- package/dist/cjs/core/ServiceLocator.js.map +1 -0
- package/dist/cjs/core/Validation.js +119 -0
- package/dist/cjs/core/Validation.js.map +1 -0
- package/dist/cjs/core/math.js +116 -0
- package/dist/cjs/core/math.js.map +1 -0
- package/dist/cjs/devtools/DevTools.js +560 -0
- package/dist/cjs/devtools/DevTools.js.map +1 -0
- package/dist/cjs/devtools/DeveloperExperience.js +562 -0
- package/dist/cjs/devtools/DeveloperExperience.js.map +1 -0
- package/dist/cjs/docs/DocGenerator.js +357 -0
- package/dist/cjs/docs/DocGenerator.js.map +1 -0
- package/dist/cjs/ecs/World.js +280 -0
- package/dist/cjs/ecs/World.js.map +1 -0
- package/dist/cjs/editor/AdvancedEditor.js +149 -0
- package/dist/cjs/editor/AdvancedEditor.js.map +1 -0
- package/dist/cjs/editor/AssetManager.js +190 -0
- package/dist/cjs/editor/AssetManager.js.map +1 -0
- package/dist/cjs/editor/DebugTools.js +187 -0
- package/dist/cjs/editor/DebugTools.js.map +1 -0
- package/dist/cjs/editor/NiceGameEditor.js +361 -0
- package/dist/cjs/editor/NiceGameEditor.js.map +1 -0
- package/dist/cjs/editor/SceneEditor.js +223 -0
- package/dist/cjs/editor/SceneEditor.js.map +1 -0
- package/dist/cjs/engine/NiceGameEngine.js +172 -0
- package/dist/cjs/engine/NiceGameEngine.js.map +1 -0
- package/dist/cjs/enterprise/Enterprise.js +258 -0
- package/dist/cjs/enterprise/Enterprise.js.map +1 -0
- package/dist/cjs/i18n/I18n.js +634 -0
- package/dist/cjs/i18n/I18n.js.map +1 -0
- package/dist/cjs/i18n/useTranslation.js +100 -0
- package/dist/cjs/i18n/useTranslation.js.map +1 -0
- package/dist/cjs/index.js +526 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/input/GamepadNavigation.js +181 -0
- package/dist/cjs/input/GamepadNavigation.js.map +1 -0
- package/dist/cjs/input/InputManager.js +404 -0
- package/dist/cjs/input/InputManager.js.map +1 -0
- package/dist/cjs/input/useGamepads.js +86 -0
- package/dist/cjs/input/useGamepads.js.map +1 -0
- package/dist/cjs/kids/KidMode.js +670 -0
- package/dist/cjs/kids/KidMode.js.map +1 -0
- package/dist/cjs/kids/KidTools.js +533 -0
- package/dist/cjs/kids/KidTools.js.map +1 -0
- package/dist/cjs/monetization/Monetization.js +197 -0
- package/dist/cjs/monetization/Monetization.js.map +1 -0
- package/dist/cjs/multiplayer/LocalMultiplayer.js +288 -0
- package/dist/cjs/multiplayer/LocalMultiplayer.js.map +1 -0
- package/dist/cjs/multiplayer/MiniGameTypes.js +70 -0
- package/dist/cjs/multiplayer/MiniGameTypes.js.map +1 -0
- package/dist/cjs/network/MultiplayerTransport.js +109 -0
- package/dist/cjs/network/MultiplayerTransport.js.map +1 -0
- package/dist/cjs/network/Networking.js +569 -0
- package/dist/cjs/network/Networking.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AbortController.js +32 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AbortController.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js +51 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js +46 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js +18 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Errors.js +145 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Errors.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js +161 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js +56 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js +11 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpClient.js +52 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpClient.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js +576 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnection.js +956 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnection.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js +149 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js +25 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ILogger.js +27 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ILogger.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ITransport.js +26 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ITransport.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js +124 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Loggers.js +17 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Loggers.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js +188 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js +199 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js +108 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Subject.js +38 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Subject.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js +24 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Utils.js +264 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Utils.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js +160 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js +88 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/index.js +50 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/index.js.map +1 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/pkg-version.js +6 -0
- package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/pkg-version.js.map +1 -0
- package/dist/cjs/pathfinding/Pathfinding.js +255 -0
- package/dist/cjs/pathfinding/Pathfinding.js.map +1 -0
- package/dist/cjs/performance/BenchmarkSuite.js +318 -0
- package/dist/cjs/performance/BenchmarkSuite.js.map +1 -0
- package/dist/cjs/performance/Performance.js +180 -0
- package/dist/cjs/performance/Performance.js.map +1 -0
- package/dist/cjs/performance/PerformanceAdvanced.js +628 -0
- package/dist/cjs/performance/PerformanceAdvanced.js.map +1 -0
- package/dist/cjs/physics/PhysicsAdvanced.js +432 -0
- package/dist/cjs/physics/PhysicsAdvanced.js.map +1 -0
- package/dist/cjs/physics/PhysicsEngine2D.js +445 -0
- package/dist/cjs/physics/PhysicsEngine2D.js.map +1 -0
- package/dist/cjs/plugins/PluginSDK.js +488 -0
- package/dist/cjs/plugins/PluginSDK.js.map +1 -0
- package/dist/cjs/plugins/PluginTestKit.js +368 -0
- package/dist/cjs/plugins/PluginTestKit.js.map +1 -0
- package/dist/cjs/procedural/Procedural.js +288 -0
- package/dist/cjs/procedural/Procedural.js.map +1 -0
- package/dist/cjs/procedural/WorldBuilding.js +246 -0
- package/dist/cjs/procedural/WorldBuilding.js.map +1 -0
- package/dist/cjs/release/MobileExport.js +149 -0
- package/dist/cjs/release/MobileExport.js.map +1 -0
- package/dist/cjs/release/Release.js +151 -0
- package/dist/cjs/release/Release.js.map +1 -0
- package/dist/cjs/rendering/Camera2D.js +129 -0
- package/dist/cjs/rendering/Camera2D.js.map +1 -0
- package/dist/cjs/rendering/Renderer2D.js +337 -0
- package/dist/cjs/rendering/Renderer2D.js.map +1 -0
- package/dist/cjs/runtime3d/Runtime3D.js +381 -0
- package/dist/cjs/runtime3d/Runtime3D.js.map +1 -0
- package/dist/cjs/runtime3d/SceneEditor3D.js +316 -0
- package/dist/cjs/runtime3d/SceneEditor3D.js.map +1 -0
- package/dist/cjs/scene/SceneManager.js +186 -0
- package/dist/cjs/scene/SceneManager.js.map +1 -0
- package/dist/cjs/scripting/NodeGraph.js +573 -0
- package/dist/cjs/scripting/NodeGraph.js.map +1 -0
- package/dist/cjs/social/Social.js +91 -0
- package/dist/cjs/social/Social.js.map +1 -0
- package/dist/cjs/templates/ActionTemplates.js +229 -0
- package/dist/cjs/templates/ActionTemplates.js.map +1 -0
- package/dist/cjs/templates/PartyTemplates.js +221 -0
- package/dist/cjs/templates/PartyTemplates.js.map +1 -0
- package/dist/cjs/templates/PuzzleTemplates.js +283 -0
- package/dist/cjs/templates/PuzzleTemplates.js.map +1 -0
- package/dist/cjs/templates/RPGTemplates.js +209 -0
- package/dist/cjs/templates/RPGTemplates.js.map +1 -0
- package/dist/cjs/templates/SportsTemplates.js +272 -0
- package/dist/cjs/templates/SportsTemplates.js.map +1 -0
- package/dist/cjs/templates/StrategyTemplates.js +173 -0
- package/dist/cjs/templates/StrategyTemplates.js.map +1 -0
- package/dist/cjs/templates/WaveDefense.js +470 -0
- package/dist/cjs/templates/WaveDefense.js.map +1 -0
- package/dist/cjs/tilemap/Tilemap.js +208 -0
- package/dist/cjs/tilemap/Tilemap.js.map +1 -0
- package/dist/cjs/tutorials/TutorialBranching.js +392 -0
- package/dist/cjs/tutorials/TutorialBranching.js.map +1 -0
- package/dist/cjs/tutorials/TutorialEngine.js +903 -0
- package/dist/cjs/tutorials/TutorialEngine.js.map +1 -0
- package/dist/cjs/tutorials/TutorialOverlay.js +602 -0
- package/dist/cjs/tutorials/TutorialOverlay.js.map +1 -0
- package/dist/cjs/tutorials/content/Tutorials_T05_T08.js +816 -0
- package/dist/cjs/tutorials/content/Tutorials_T05_T08.js.map +1 -0
- package/dist/cjs/tutorials/content/Tutorials_T09_T11.js +741 -0
- package/dist/cjs/tutorials/content/Tutorials_T09_T11.js.map +1 -0
- package/dist/cjs/tutorials/content/Tutorials_T12_T15.js +786 -0
- package/dist/cjs/tutorials/content/Tutorials_T12_T15.js.map +1 -0
- package/dist/cjs/ui/GameUI.js +312 -0
- package/dist/cjs/ui/GameUI.js.map +1 -0
- package/dist/cjs/xr/ARVR.js +197 -0
- package/dist/cjs/xr/ARVR.js.map +1 -0
- package/dist/esm/accessibility/Accessibility.js +153 -0
- package/dist/esm/accessibility/Accessibility.js.map +1 -0
- package/dist/esm/ai/AI.js +302 -0
- package/dist/esm/ai/AI.js.map +1 -0
- package/dist/esm/animation/Animation.js +227 -0
- package/dist/esm/animation/Animation.js.map +1 -0
- package/dist/esm/audio/AudioAdvanced.js +243 -0
- package/dist/esm/audio/AudioAdvanced.js.map +1 -0
- package/dist/esm/audio/AudioManager.js +246 -0
- package/dist/esm/audio/AudioManager.js.map +1 -0
- package/dist/esm/core/EventBus.js +61 -0
- package/dist/esm/core/EventBus.js.map +1 -0
- package/dist/esm/core/GameClock.js +68 -0
- package/dist/esm/core/GameClock.js.map +1 -0
- package/dist/esm/core/GameConfig.js +80 -0
- package/dist/esm/core/GameConfig.js.map +1 -0
- package/dist/esm/core/GameLoop.js +91 -0
- package/dist/esm/core/GameLoop.js.map +1 -0
- package/dist/esm/core/ServiceLocator.js +70 -0
- package/dist/esm/core/ServiceLocator.js.map +1 -0
- package/dist/esm/core/Validation.js +108 -0
- package/dist/esm/core/Validation.js.map +1 -0
- package/dist/esm/core/math.js +114 -0
- package/dist/esm/core/math.js.map +1 -0
- package/dist/esm/devtools/DevTools.js +555 -0
- package/dist/esm/devtools/DevTools.js.map +1 -0
- package/dist/esm/devtools/DeveloperExperience.js +547 -0
- package/dist/esm/devtools/DeveloperExperience.js.map +1 -0
- package/dist/esm/docs/DocGenerator.js +353 -0
- package/dist/esm/docs/DocGenerator.js.map +1 -0
- package/dist/esm/ecs/World.js +276 -0
- package/dist/esm/ecs/World.js.map +1 -0
- package/dist/esm/editor/AdvancedEditor.js +141 -0
- package/dist/esm/editor/AdvancedEditor.js.map +1 -0
- package/dist/esm/editor/AssetManager.js +188 -0
- package/dist/esm/editor/AssetManager.js.map +1 -0
- package/dist/esm/editor/DebugTools.js +179 -0
- package/dist/esm/editor/DebugTools.js.map +1 -0
- package/dist/esm/editor/NiceGameEditor.js +355 -0
- package/dist/esm/editor/NiceGameEditor.js.map +1 -0
- package/dist/esm/editor/SceneEditor.js +209 -0
- package/dist/esm/editor/SceneEditor.js.map +1 -0
- package/dist/esm/engine/NiceGameEngine.js +170 -0
- package/dist/esm/engine/NiceGameEngine.js.map +1 -0
- package/dist/esm/enterprise/Enterprise.js +246 -0
- package/dist/esm/enterprise/Enterprise.js.map +1 -0
- package/dist/esm/i18n/I18n.js +622 -0
- package/dist/esm/i18n/I18n.js.map +1 -0
- package/dist/esm/i18n/useTranslation.js +95 -0
- package/dist/esm/i18n/useTranslation.js.map +1 -0
- package/dist/esm/index.js +71 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/input/GamepadNavigation.js +178 -0
- package/dist/esm/input/GamepadNavigation.js.map +1 -0
- package/dist/esm/input/InputManager.js +399 -0
- package/dist/esm/input/InputManager.js.map +1 -0
- package/dist/esm/input/useGamepads.js +83 -0
- package/dist/esm/input/useGamepads.js.map +1 -0
- package/dist/esm/kids/KidMode.js +663 -0
- package/dist/esm/kids/KidMode.js.map +1 -0
- package/dist/esm/kids/KidTools.js +529 -0
- package/dist/esm/kids/KidTools.js.map +1 -0
- package/dist/esm/monetization/Monetization.js +186 -0
- package/dist/esm/monetization/Monetization.js.map +1 -0
- package/dist/esm/multiplayer/LocalMultiplayer.js +284 -0
- package/dist/esm/multiplayer/LocalMultiplayer.js.map +1 -0
- package/dist/esm/multiplayer/MiniGameTypes.js +60 -0
- package/dist/esm/multiplayer/MiniGameTypes.js.map +1 -0
- package/dist/esm/network/MultiplayerTransport.js +106 -0
- package/dist/esm/network/MultiplayerTransport.js.map +1 -0
- package/dist/esm/network/Networking.js +561 -0
- package/dist/esm/network/Networking.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AbortController.js +30 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AbortController.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js +49 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js +44 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js +16 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Errors.js +136 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Errors.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js +159 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js +54 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js +9 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpClient.js +49 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpClient.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js +573 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnection.js +954 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnection.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js +147 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js +25 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ILogger.js +27 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ILogger.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ITransport.js +26 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ITransport.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js +122 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Loggers.js +15 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Loggers.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js +186 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js +197 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js +106 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Subject.js +36 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Subject.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js +22 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Utils.js +249 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Utils.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js +158 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js +86 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/index.js +13 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/index.js.map +1 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/pkg-version.js +4 -0
- package/dist/esm/node_modules/@microsoft/signalr/dist/esm/pkg-version.js.map +1 -0
- package/dist/esm/pathfinding/Pathfinding.js +250 -0
- package/dist/esm/pathfinding/Pathfinding.js.map +1 -0
- package/dist/esm/performance/BenchmarkSuite.js +315 -0
- package/dist/esm/performance/BenchmarkSuite.js.map +1 -0
- package/dist/esm/performance/Performance.js +171 -0
- package/dist/esm/performance/Performance.js.map +1 -0
- package/dist/esm/performance/PerformanceAdvanced.js +620 -0
- package/dist/esm/performance/PerformanceAdvanced.js.map +1 -0
- package/dist/esm/physics/PhysicsAdvanced.js +417 -0
- package/dist/esm/physics/PhysicsAdvanced.js.map +1 -0
- package/dist/esm/physics/PhysicsEngine2D.js +442 -0
- package/dist/esm/physics/PhysicsEngine2D.js.map +1 -0
- package/dist/esm/plugins/PluginSDK.js +484 -0
- package/dist/esm/plugins/PluginSDK.js.map +1 -0
- package/dist/esm/plugins/PluginTestKit.js +359 -0
- package/dist/esm/plugins/PluginTestKit.js.map +1 -0
- package/dist/esm/procedural/Procedural.js +282 -0
- package/dist/esm/procedural/Procedural.js.map +1 -0
- package/dist/esm/procedural/WorldBuilding.js +225 -0
- package/dist/esm/procedural/WorldBuilding.js.map +1 -0
- package/dist/esm/release/MobileExport.js +142 -0
- package/dist/esm/release/MobileExport.js.map +1 -0
- package/dist/esm/release/Release.js +141 -0
- package/dist/esm/release/Release.js.map +1 -0
- package/dist/esm/rendering/Camera2D.js +127 -0
- package/dist/esm/rendering/Camera2D.js.map +1 -0
- package/dist/esm/rendering/Renderer2D.js +334 -0
- package/dist/esm/rendering/Renderer2D.js.map +1 -0
- package/dist/esm/runtime3d/Runtime3D.js +371 -0
- package/dist/esm/runtime3d/Runtime3D.js.map +1 -0
- package/dist/esm/runtime3d/SceneEditor3D.js +299 -0
- package/dist/esm/runtime3d/SceneEditor3D.js.map +1 -0
- package/dist/esm/scene/SceneManager.js +184 -0
- package/dist/esm/scene/SceneManager.js.map +1 -0
- package/dist/esm/scripting/NodeGraph.js +568 -0
- package/dist/esm/scripting/NodeGraph.js.map +1 -0
- package/dist/esm/social/Social.js +85 -0
- package/dist/esm/social/Social.js.map +1 -0
- package/dist/esm/templates/ActionTemplates.js +217 -0
- package/dist/esm/templates/ActionTemplates.js.map +1 -0
- package/dist/esm/templates/PartyTemplates.js +204 -0
- package/dist/esm/templates/PartyTemplates.js.map +1 -0
- package/dist/esm/templates/PuzzleTemplates.js +267 -0
- package/dist/esm/templates/PuzzleTemplates.js.map +1 -0
- package/dist/esm/templates/RPGTemplates.js +196 -0
- package/dist/esm/templates/RPGTemplates.js.map +1 -0
- package/dist/esm/templates/SportsTemplates.js +257 -0
- package/dist/esm/templates/SportsTemplates.js.map +1 -0
- package/dist/esm/templates/StrategyTemplates.js +157 -0
- package/dist/esm/templates/StrategyTemplates.js.map +1 -0
- package/dist/esm/templates/WaveDefense.js +467 -0
- package/dist/esm/templates/WaveDefense.js.map +1 -0
- package/dist/esm/tilemap/Tilemap.js +205 -0
- package/dist/esm/tilemap/Tilemap.js.map +1 -0
- package/dist/esm/tutorials/TutorialBranching.js +388 -0
- package/dist/esm/tutorials/TutorialBranching.js.map +1 -0
- package/dist/esm/tutorials/TutorialEngine.js +897 -0
- package/dist/esm/tutorials/TutorialEngine.js.map +1 -0
- package/dist/esm/tutorials/TutorialOverlay.js +600 -0
- package/dist/esm/tutorials/TutorialOverlay.js.map +1 -0
- package/dist/esm/tutorials/content/Tutorials_T05_T08.js +810 -0
- package/dist/esm/tutorials/content/Tutorials_T05_T08.js.map +1 -0
- package/dist/esm/tutorials/content/Tutorials_T09_T11.js +736 -0
- package/dist/esm/tutorials/content/Tutorials_T09_T11.js.map +1 -0
- package/dist/esm/tutorials/content/Tutorials_T12_T15.js +780 -0
- package/dist/esm/tutorials/content/Tutorials_T12_T15.js.map +1 -0
- package/dist/esm/ui/GameUI.js +310 -0
- package/dist/esm/ui/GameUI.js.map +1 -0
- package/dist/esm/xr/ARVR.js +182 -0
- package/dist/esm/xr/ARVR.js.map +1 -0
- package/dist/types/__tests__/setup.d.ts +1 -0
- package/dist/types/accessibility/Accessibility.d.ts +82 -0
- package/dist/types/accessibility/index.d.ts +1 -0
- package/dist/types/ai/AI.d.ts +140 -0
- package/dist/types/ai/index.d.ts +1 -0
- package/dist/types/animation/Animation.d.ts +90 -0
- package/dist/types/animation/index.d.ts +1 -0
- package/dist/types/audio/AudioAdvanced.d.ts +190 -0
- package/dist/types/audio/AudioManager.d.ts +55 -0
- package/dist/types/audio/index.d.ts +1 -0
- package/dist/types/community/Community.d.ts +112 -0
- package/dist/types/community/index.d.ts +1 -0
- package/dist/types/core/EventBus.d.ts +16 -0
- package/dist/types/core/GameClock.d.ts +29 -0
- package/dist/types/core/GameConfig.d.ts +20 -0
- package/dist/types/core/GameLoop.d.ts +32 -0
- package/dist/types/core/ServiceLocator.d.ts +36 -0
- package/dist/types/core/TypeSafety.d.ts +190 -0
- package/dist/types/core/Validation.d.ts +24 -0
- package/dist/types/core/index.d.ts +7 -0
- package/dist/types/core/math.d.ts +32 -0
- package/dist/types/core/types.d.ts +130 -0
- package/dist/types/devtools/AssetStore.d.ts +133 -0
- package/dist/types/devtools/DevTools.d.ts +217 -0
- package/dist/types/devtools/DeveloperExperience.d.ts +123 -0
- package/dist/types/devtools/index.d.ts +3 -0
- package/dist/types/docs/APIPlayground.d.ts +26 -0
- package/dist/types/docs/Cookbook.d.ts +18 -0
- package/dist/types/docs/DocGenerator.d.ts +83 -0
- package/dist/types/docs/Guides.d.ts +18 -0
- package/dist/types/docs/index.d.ts +4 -0
- package/dist/types/ecs/World.d.ts +219 -0
- package/dist/types/ecs/index.d.ts +1 -0
- package/dist/types/editor/AdvancedEditor.d.ts +267 -0
- package/dist/types/editor/AssetManager.d.ts +45 -0
- package/dist/types/editor/DebugTools.d.ts +74 -0
- package/dist/types/editor/NiceGameEditor.d.ts +115 -0
- package/dist/types/editor/SceneEditor.d.ts +37 -0
- package/dist/types/editor/index.d.ts +8 -0
- package/dist/types/engine/NiceGameEngine.d.ts +53 -0
- package/dist/types/engine/index.d.ts +2 -0
- package/dist/types/enterprise/Enterprise.d.ts +217 -0
- package/dist/types/enterprise/index.d.ts +1 -0
- package/dist/types/epic/index.d.ts +10 -0
- package/dist/types/i18n/I18n.d.ts +107 -0
- package/dist/types/i18n/index.d.ts +2 -0
- package/dist/types/i18n/useTranslation.d.ts +74 -0
- package/dist/types/index.d.ts +127 -0
- package/dist/types/input/GamepadNavigation.d.ts +34 -0
- package/dist/types/input/InputManager.d.ts +77 -0
- package/dist/types/input/index.d.ts +3 -0
- package/dist/types/input/useGamepads.d.ts +39 -0
- package/dist/types/kids/KidMode.d.ts +207 -0
- package/dist/types/kids/KidTools.d.ts +135 -0
- package/dist/types/kids/index.d.ts +2 -0
- package/dist/types/legendary/index.d.ts +57 -0
- package/dist/types/monetization/Monetization.d.ts +224 -0
- package/dist/types/monetization/index.d.ts +1 -0
- package/dist/types/multiplayer/LocalMultiplayer.d.ts +61 -0
- package/dist/types/multiplayer/MiniGameTypes.d.ts +70 -0
- package/dist/types/multiplayer/index.d.ts +3 -0
- package/dist/types/network/MultiplayerTransport.d.ts +71 -0
- package/dist/types/network/Networking.d.ts +199 -0
- package/dist/types/network/index.d.ts +2 -0
- package/dist/types/pathfinding/Pathfinding.d.ts +42 -0
- package/dist/types/pathfinding/index.d.ts +1 -0
- package/dist/types/performance/AssetCompression.d.ts +137 -0
- package/dist/types/performance/BenchmarkSuite.d.ts +99 -0
- package/dist/types/performance/Performance.d.ts +87 -0
- package/dist/types/performance/PerformanceAdvanced.d.ts +220 -0
- package/dist/types/performance/WASMModules.d.ts +65 -0
- package/dist/types/performance/WebGPUCompute.d.ts +164 -0
- package/dist/types/performance/index.d.ts +1 -0
- package/dist/types/physics/PhysicsAdvanced.d.ts +148 -0
- package/dist/types/physics/PhysicsEngine2D.d.ts +66 -0
- package/dist/types/physics/index.d.ts +1 -0
- package/dist/types/plugins/PluginSDK.d.ts +134 -0
- package/dist/types/plugins/PluginTestKit.d.ts +107 -0
- package/dist/types/plugins/index.d.ts +2 -0
- package/dist/types/procedural/Procedural.d.ts +90 -0
- package/dist/types/procedural/WorldBuilding.d.ts +200 -0
- package/dist/types/procedural/index.d.ts +2 -0
- package/dist/types/release/MobileExport.d.ts +218 -0
- package/dist/types/release/Release.d.ts +81 -0
- package/dist/types/release/index.d.ts +1 -0
- package/dist/types/rendering/Camera2D.d.ts +39 -0
- package/dist/types/rendering/Renderer2D.d.ts +41 -0
- package/dist/types/rendering/index.d.ts +2 -0
- package/dist/types/runtime3d/Runtime3D.d.ts +259 -0
- package/dist/types/runtime3d/SceneEditor3D.d.ts +186 -0
- package/dist/types/runtime3d/index.d.ts +2 -0
- package/dist/types/scene/SceneManager.d.ts +59 -0
- package/dist/types/scene/index.d.ts +2 -0
- package/dist/types/scripting/NodeGraph.d.ts +84 -0
- package/dist/types/scripting/index.d.ts +2 -0
- package/dist/types/social/Social.d.ts +245 -0
- package/dist/types/social/index.d.ts +1 -0
- package/dist/types/templates/ActionTemplates.d.ts +173 -0
- package/dist/types/templates/PartyTemplates.d.ts +195 -0
- package/dist/types/templates/PuzzleTemplates.d.ts +127 -0
- package/dist/types/templates/RPGTemplates.d.ts +210 -0
- package/dist/types/templates/SportsTemplates.d.ts +162 -0
- package/dist/types/templates/StrategyTemplates.d.ts +264 -0
- package/dist/types/templates/WaveDefense.d.ts +92 -0
- package/dist/types/templates/index.d.ts +2 -0
- package/dist/types/tilemap/Tilemap.d.ts +66 -0
- package/dist/types/tilemap/index.d.ts +1 -0
- package/dist/types/tutorials/TutorialBranching.d.ts +132 -0
- package/dist/types/tutorials/TutorialEditor.d.ts +43 -0
- package/dist/types/tutorials/TutorialEngine.d.ts +237 -0
- package/dist/types/tutorials/TutorialOverlay.d.ts +79 -0
- package/dist/types/tutorials/VoiceNarration.d.ts +75 -0
- package/dist/types/tutorials/content/Tutorials_T04.d.ts +3 -0
- package/dist/types/tutorials/content/Tutorials_T05_T08.d.ts +6 -0
- package/dist/types/tutorials/content/Tutorials_T09_T11.d.ts +5 -0
- package/dist/types/tutorials/content/Tutorials_T12_T15.d.ts +6 -0
- package/dist/types/tutorials/content/UITutorials.d.ts +14 -0
- package/dist/types/tutorials/content/index.d.ts +5 -0
- package/dist/types/tutorials/index.d.ts +6 -0
- package/dist/types/ui/GameUI.d.ts +97 -0
- package/dist/types/ui/index.d.ts +2 -0
- package/dist/types/xr/ARVR.d.ts +252 -0
- package/dist/types/xr/index.d.ts +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,816 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/* ────────────────────────────────────────────────────────────────
|
|
4
|
+
Tutorials T05–T08 — Advanced Game Engine Tutorials
|
|
5
|
+
|
|
6
|
+
T05: Animacje (Sprite animation, tweens, easing)
|
|
7
|
+
T06: Tilemapy i światy (tilemap, auto-tiling, layers)
|
|
8
|
+
T07: Visual Scripting (node graph, first behavior)
|
|
9
|
+
T08: Multiplayer lokalny (splitscreen, co-op, gamepady)
|
|
10
|
+
──────────────────────────────────────────────────────────────── */
|
|
11
|
+
/* ══════════════════════════════════════════════════════════════
|
|
12
|
+
T05 — Animacje
|
|
13
|
+
══════════════════════════════════════════════════════════════ */
|
|
14
|
+
const TUTORIAL_ANIMATIONS = {
|
|
15
|
+
id: 'animations-sprites-tweens',
|
|
16
|
+
title: {
|
|
17
|
+
en: 'Animations: Sprites, Tweens & Easing',
|
|
18
|
+
pl: 'Animacje: Sprite\'y, Tweeny i Easing',
|
|
19
|
+
de: 'Animationen: Sprites, Tweens & Easing',
|
|
20
|
+
},
|
|
21
|
+
description: {
|
|
22
|
+
en: 'Learn to animate game objects using sprite sheets, tweens, easing functions, and state machines.',
|
|
23
|
+
pl: 'Naucz się animować obiekty za pomocą sprite sheet\'ów, tweenów, easing\'ów i maszyn stanów.',
|
|
24
|
+
de: 'Lerne, Spielobjekte mit Spritesheets, Tweens, Easing und Zustandsmaschinen zu animieren.',
|
|
25
|
+
},
|
|
26
|
+
category: 'game-basics',
|
|
27
|
+
difficulty: 'beginner',
|
|
28
|
+
estimatedMinutes: 20,
|
|
29
|
+
prerequisites: ['first-game-bouncing-ball'],
|
|
30
|
+
kidFriendly: true,
|
|
31
|
+
ageRange: { min: 10, max: 99 },
|
|
32
|
+
tags: ['animation', 'sprite', 'tween', 'easing', 'state-machine'],
|
|
33
|
+
steps: [
|
|
34
|
+
// --- S1: Intro ---
|
|
35
|
+
{
|
|
36
|
+
id: 'anim-welcome',
|
|
37
|
+
type: 'text',
|
|
38
|
+
title: {
|
|
39
|
+
en: 'Welcome to Animations! 🎬',
|
|
40
|
+
pl: 'Witaj w świecie animacji! 🎬',
|
|
41
|
+
de: 'Willkommen bei Animationen! 🎬',
|
|
42
|
+
},
|
|
43
|
+
content: {
|
|
44
|
+
en: 'In this tutorial you will learn:\n• Creating animation clips from sprite sheets\n• Using tweens for smooth movement\n• Easing functions (bounce, elastic, cubic)\n• Animation state machines\n\nLet\'s bring your game to life!',
|
|
45
|
+
pl: 'W tym tutorialu nauczysz się:\n• Tworzenia klipów animacji ze sprite sheet\'ów\n• Używania tweenów do płynnego ruchu\n• Funkcji easing (bounce, elastic, cubic)\n• Maszyn stanów animacji\n\nOżywmy Twoją grę!',
|
|
46
|
+
de: 'In diesem Tutorial lernst du:\n• Animationsclips aus Spritesheets erstellen\n• Tweens für flüssige Bewegungen\n• Easing-Funktionen (Bounce, Elastic, Cubic)\n• Animations-Zustandsmaschinen\n\nLass uns dein Spiel zum Leben erwecken!',
|
|
47
|
+
},
|
|
48
|
+
skippable: true,
|
|
49
|
+
tooltipPosition: 'center',
|
|
50
|
+
},
|
|
51
|
+
// --- S2: Create a clip from sprite sheet ---
|
|
52
|
+
{
|
|
53
|
+
id: 'create-clip',
|
|
54
|
+
type: 'code',
|
|
55
|
+
title: {
|
|
56
|
+
en: 'Create an Animation Clip',
|
|
57
|
+
pl: 'Utwórz klip animacji',
|
|
58
|
+
de: 'Erstelle einen Animationsclip',
|
|
59
|
+
},
|
|
60
|
+
content: {
|
|
61
|
+
en: 'Use `createClipFromSheet` to define an animation clip from a sprite sheet.\nParameters: name, columns in the sheet, start index, frame count, frame size, and duration per frame.',
|
|
62
|
+
pl: 'Użyj `createClipFromSheet` aby zdefiniować klip animacji ze sprite sheet\'a.\nParametry: nazwa, kolumny w arkuszu, indeks startowy, ilość klatek, rozmiar klatki i czas trwania klatki.',
|
|
63
|
+
de: 'Verwende `createClipFromSheet` um einen Animationsclip aus einem Spritesheet zu erstellen.\nParameter: Name, Spalten im Sheet, Startindex, Framezahl, Framegröße und Dauer pro Frame.',
|
|
64
|
+
},
|
|
65
|
+
codeTemplate: '// Create a "walk" animation clip\nconst walkClip = ',
|
|
66
|
+
codeSolution: 'const walkClip = createClipFromSheet(\n "walk", // clip name\n 8, // sprite sheet has 8 columns\n 0, // start at frame index 0\n 8, // 8 frames total\n 64, // frame width (px)\n 64, // frame height (px)\n 0.1, // 0.1s per frame\n true // loop\n);',
|
|
67
|
+
codeValidation: {
|
|
68
|
+
containsAll: ['createClipFromSheet', 'walk'],
|
|
69
|
+
},
|
|
70
|
+
hint: {
|
|
71
|
+
en: 'createClipFromSheet(name, columns, startIndex, frameCount, width, height, duration, loop)',
|
|
72
|
+
pl: 'createClipFromSheet(nazwa, kolumny, startIndex, ilośćKlatek, szerokość, wysokość, czas, loop)',
|
|
73
|
+
de: 'createClipFromSheet(name, spalten, startIndex, frameAnzahl, breite, höhe, dauer, loop)',
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
// --- S3: SpriteAnimator ---
|
|
77
|
+
{
|
|
78
|
+
id: 'sprite-animator',
|
|
79
|
+
type: 'code',
|
|
80
|
+
title: {
|
|
81
|
+
en: 'Set Up the Sprite Animator',
|
|
82
|
+
pl: 'Skonfiguruj Sprite Animator',
|
|
83
|
+
de: 'Richte den Sprite-Animator ein',
|
|
84
|
+
},
|
|
85
|
+
content: {
|
|
86
|
+
en: 'Create a `SpriteAnimator`, add clips to it, and start playing an animation.\nThe animator tracks which frame to display and handles looping.',
|
|
87
|
+
pl: 'Utwórz `SpriteAnimator`, dodaj do niego klipy i uruchom animację.\nAnimator śledzi, którą klatkę wyświetlić i obsługuje zapętlanie.',
|
|
88
|
+
de: 'Erstelle einen `SpriteAnimator`, füge Clips hinzu und starte die Animation.\nDer Animator verfolgt, welcher Frame angezeigt wird und handhabt das Looping.',
|
|
89
|
+
},
|
|
90
|
+
codeTemplate: '// Set up animator\nconst animator = ',
|
|
91
|
+
codeSolution: 'const animator = new SpriteAnimator();\nanimator.addClip(walkClip);\nanimator.addClip(idleClip);\nanimator.play("walk");',
|
|
92
|
+
codeValidation: {
|
|
93
|
+
containsAll: ['new SpriteAnimator', 'addClip', 'play'],
|
|
94
|
+
},
|
|
95
|
+
hint: {
|
|
96
|
+
en: 'new SpriteAnimator() → addClip(clip) → play("walk")',
|
|
97
|
+
pl: 'new SpriteAnimator() → addClip(klip) → play("walk")',
|
|
98
|
+
de: 'new SpriteAnimator() → addClip(clip) → play("walk")',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
// --- S4: Quiz on animation frames ---
|
|
102
|
+
{
|
|
103
|
+
id: 'quiz-animation',
|
|
104
|
+
type: 'quiz',
|
|
105
|
+
title: {
|
|
106
|
+
en: 'Quick Quiz! 🧠',
|
|
107
|
+
pl: 'Szybki quiz! 🧠',
|
|
108
|
+
de: 'Schnelles Quiz! 🧠',
|
|
109
|
+
},
|
|
110
|
+
content: {
|
|
111
|
+
en: 'If an animation has 8 frames at 0.1s each, how long is one full cycle?',
|
|
112
|
+
pl: 'Jeśli animacja ma 8 klatek po 0.1s każda, ile trwa jeden pełny cykl?',
|
|
113
|
+
de: 'Wenn eine Animation 8 Frames à 0,1s hat, wie lange dauert ein vollständiger Zyklus?',
|
|
114
|
+
},
|
|
115
|
+
quizOptions: [
|
|
116
|
+
{ id: 'a', text: { en: '0.1 seconds', pl: '0,1 sekundy', de: '0,1 Sekunden' } },
|
|
117
|
+
{ id: 'b', text: { en: '0.8 seconds', pl: '0,8 sekundy', de: '0,8 Sekunden' } },
|
|
118
|
+
{ id: 'c', text: { en: '8 seconds', pl: '8 sekund', de: '8 Sekunden' } },
|
|
119
|
+
{ id: 'd', text: { en: '80 seconds', pl: '80 sekund', de: '80 Sekunden' } },
|
|
120
|
+
],
|
|
121
|
+
quizCorrectId: 'b',
|
|
122
|
+
},
|
|
123
|
+
// --- S5: Tweens ---
|
|
124
|
+
{
|
|
125
|
+
id: 'tweens',
|
|
126
|
+
type: 'code',
|
|
127
|
+
title: {
|
|
128
|
+
en: 'Smooth Movement with Tweens',
|
|
129
|
+
pl: 'Płynny ruch z Tweenami',
|
|
130
|
+
de: 'Flüssige Bewegung mit Tweens',
|
|
131
|
+
},
|
|
132
|
+
content: {
|
|
133
|
+
en: 'Use `TweenManager` to smoothly animate properties over time.\nTweens interpolate values from A to B using easing functions.',
|
|
134
|
+
pl: 'Użyj `TweenManager` do płynnego animowania właściwości w czasie.\nTweeny interpolują wartości od A do B za pomocą funkcji easing.',
|
|
135
|
+
de: 'Verwende `TweenManager` um Eigenschaften über die Zeit flüssig zu animieren.\nTweens interpolieren Werte von A nach B mit Easing-Funktionen.',
|
|
136
|
+
},
|
|
137
|
+
codeTemplate: '// Create a tween manager and animate position\nconst tweens = new TweenManager();\n',
|
|
138
|
+
codeSolution: 'const tweens = new TweenManager();\nconst position = { x: 0, y: 300 };\ntweens.create({\n target: position,\n to: { x: 700 },\n duration: 2,\n easing: Easing.easeOutBounce,\n onComplete: () => console.log("Arrived!"),\n});',
|
|
139
|
+
codeValidation: {
|
|
140
|
+
containsAll: ['new TweenManager', 'create', 'target', 'to', 'duration'],
|
|
141
|
+
},
|
|
142
|
+
hint: {
|
|
143
|
+
en: 'tweens.create({ target, to: { x: 700 }, duration: 2, easing: Easing.easeOutBounce })',
|
|
144
|
+
pl: 'tweens.create({ target, to: { x: 700 }, duration: 2, easing: Easing.easeOutBounce })',
|
|
145
|
+
de: 'tweens.create({ target, to: { x: 700 }, duration: 2, easing: Easing.easeOutBounce })',
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
// --- S6: Easing functions ---
|
|
149
|
+
{
|
|
150
|
+
id: 'easing-functions',
|
|
151
|
+
type: 'text',
|
|
152
|
+
title: {
|
|
153
|
+
en: 'Easing Functions Explained 📈',
|
|
154
|
+
pl: 'Funkcje Easing wyjaśnione 📈',
|
|
155
|
+
de: 'Easing-Funktionen erklärt 📈',
|
|
156
|
+
},
|
|
157
|
+
content: {
|
|
158
|
+
en: 'Available easing functions:\n\n• `Easing.linear` — constant speed\n• `Easing.easeInQuad` — starts slow, accelerates\n• `Easing.easeOutQuad` — starts fast, decelerates\n• `Easing.easeInOutQuad` — slow start & end\n• `Easing.easeInCubic` — stronger acceleration\n• `Easing.easeOutCubic` — stronger deceleration\n• `Easing.easeOutBounce` — bounce effect at the end 🏀\n• `Easing.easeOutElastic` — spring/elastic effect 🔧\n\nExperiment with different easings to find the right feel for your game!',
|
|
159
|
+
pl: 'Dostępne funkcje easing:\n\n• `Easing.linear` — stała prędkość\n• `Easing.easeInQuad` — zaczyna wolno, przyspiesza\n• `Easing.easeOutQuad` — zaczyna szybko, zwalnia\n• `Easing.easeInOutQuad` — wolny start i koniec\n• `Easing.easeInCubic` — silniejsze przyspieszenie\n• `Easing.easeOutCubic` — silniejsze hamowanie\n• `Easing.easeOutBounce` — efekt odbicia 🏀\n• `Easing.easeOutElastic` — efekt sprężyny 🔧\n\nEksperymentuj z różnymi easingami, aby znaleźć odpowiedni feeling!',
|
|
160
|
+
de: 'Verfügbare Easing-Funktionen:\n\n• `Easing.linear` — konstante Geschwindigkeit\n• `Easing.easeInQuad` — langsamer Start, beschleunigt\n• `Easing.easeOutQuad` — schneller Start, bremst ab\n• `Easing.easeInOutQuad` — langsamer Start & Ende\n• `Easing.easeInCubic` — stärkere Beschleunigung\n• `Easing.easeOutCubic` — stärkere Verlangsamung\n• `Easing.easeOutBounce` — Bounce-Effekt 🏀\n• `Easing.easeOutElastic` — Feder/Elastik-Effekt 🔧\n\nExperimentiere mit verschiedenen Easings!',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
// --- S7: Animation State Machine ---
|
|
164
|
+
{
|
|
165
|
+
id: 'state-machine',
|
|
166
|
+
type: 'code',
|
|
167
|
+
title: {
|
|
168
|
+
en: 'Animation State Machine',
|
|
169
|
+
pl: 'Maszyna stanów animacji',
|
|
170
|
+
de: 'Animations-Zustandsmaschine',
|
|
171
|
+
},
|
|
172
|
+
content: {
|
|
173
|
+
en: 'Use `AnimationStateMachine` to manage transitions between animations (idle, walk, jump, attack).\nTransitions fire automatically when conditions are met.',
|
|
174
|
+
pl: 'Użyj `AnimationStateMachine` do zarządzania przejściami między animacjami (idle, walk, jump, attack).\nPrzejścia uruchamiają się automatycznie gdy warunki są spełnione.',
|
|
175
|
+
de: 'Verwende `AnimationStateMachine` um Übergänge zwischen Animationen zu verwalten.\nÜbergänge werden automatisch ausgelöst, wenn Bedingungen erfüllt sind.',
|
|
176
|
+
},
|
|
177
|
+
codeTemplate: '// Create animation state machine\nconst stateMachine = ',
|
|
178
|
+
codeSolution: 'const stateMachine = new AnimationStateMachine(animator);\nstateMachine.addState("idle", "idle");\nstateMachine.addState("walk", "walk");\nstateMachine.addTransition("idle", "walk", () => isMoving);\nstateMachine.addTransition("walk", "idle", () => !isMoving);',
|
|
179
|
+
codeValidation: {
|
|
180
|
+
containsAll: ['new AnimationStateMachine', 'addState', 'addTransition'],
|
|
181
|
+
},
|
|
182
|
+
hint: {
|
|
183
|
+
en: 'new AnimationStateMachine(animator) → addState → addTransition with condition functions',
|
|
184
|
+
pl: 'new AnimationStateMachine(animator) → addState → addTransition z funkcjami warunków',
|
|
185
|
+
de: 'new AnimationStateMachine(animator) → addState → addTransition mit Bedingungsfunktionen',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
// --- S8: Checkpoint ---
|
|
189
|
+
{
|
|
190
|
+
id: 'anim-checkpoint',
|
|
191
|
+
type: 'checkpoint',
|
|
192
|
+
title: {
|
|
193
|
+
en: 'Animation Checkpoint ✅',
|
|
194
|
+
pl: 'Checkpoint animacji ✅',
|
|
195
|
+
de: 'Animations-Checkpoint ✅',
|
|
196
|
+
},
|
|
197
|
+
content: {
|
|
198
|
+
en: 'Great progress! You\'ve learned the core animation APIs. Your progress is saved.',
|
|
199
|
+
pl: 'Świetne postępy! Opanowałeś podstawowe API animacji. Twoje postępy zostały zapisane.',
|
|
200
|
+
de: 'Toller Fortschritt! Du hast die Kern-Animations-APIs gelernt. Dein Fortschritt wurde gespeichert.',
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
// --- S9: Congratulations ---
|
|
204
|
+
{
|
|
205
|
+
id: 'anim-congratulations',
|
|
206
|
+
type: 'text',
|
|
207
|
+
title: {
|
|
208
|
+
en: 'Congratulations! 🎉',
|
|
209
|
+
pl: 'Gratulacje! 🎉',
|
|
210
|
+
de: 'Herzlichen Glückwunsch! 🎉',
|
|
211
|
+
},
|
|
212
|
+
content: {
|
|
213
|
+
en: '🏆 You learned:\n• Creating animation clips with `createClipFromSheet`\n• `SpriteAnimator` for frame-by-frame animation\n• `TweenManager` for smooth interpolation\n• Easing functions (bounce, elastic, cubic)\n• `AnimationStateMachine` for automatic transitions\n\nNext: Try the "Tilemaps & Worlds" tutorial! 🗺️',
|
|
214
|
+
pl: '🏆 Nauczyłeś się:\n• Tworzenia klipów animacji z `createClipFromSheet`\n• `SpriteAnimator` do animacji klatka po klatce\n• `TweenManager` do płynnej interpolacji\n• Funkcji easing (bounce, elastic, cubic)\n• `AnimationStateMachine` do automatycznych przejść\n\nDalej: Spróbuj tutoriala "Tilemapy i światy"! 🗺️',
|
|
215
|
+
de: '🏆 Du hast gelernt:\n• Animationsclips mit `createClipFromSheet` erstellen\n• `SpriteAnimator` für Frame-by-Frame-Animation\n• `TweenManager` für flüssige Interpolation\n• Easing-Funktionen (Bounce, Elastic, Cubic)\n• `AnimationStateMachine` für automatische Übergänge\n\nWeiter: Probiere das "Tilemaps & Welten"-Tutorial! 🗺️',
|
|
216
|
+
},
|
|
217
|
+
tooltipPosition: 'center',
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
};
|
|
221
|
+
/* ══════════════════════════════════════════════════════════════
|
|
222
|
+
T06 — Tilemapy i światy
|
|
223
|
+
══════════════════════════════════════════════════════════════ */
|
|
224
|
+
const TUTORIAL_TILEMAPS = {
|
|
225
|
+
id: 'tilemaps-and-worlds',
|
|
226
|
+
title: {
|
|
227
|
+
en: 'Tilemaps & Worlds',
|
|
228
|
+
pl: 'Tilemapy i światy',
|
|
229
|
+
de: 'Tilemaps & Welten',
|
|
230
|
+
},
|
|
231
|
+
description: {
|
|
232
|
+
en: 'Build game worlds with tilemaps: create layers, place tiles, use auto-tiling, and handle tile-based collision.',
|
|
233
|
+
pl: 'Buduj światy gier za pomocą tilemap: twórz warstwy, umieszczaj kafelki, używaj auto-tilingu i obsługuj kolizje kafelkowe.',
|
|
234
|
+
de: 'Baue Spielwelten mit Tilemaps: Erstelle Ebenen, platziere Kacheln, nutze Auto-Tiling und behandle kachelbasierte Kollisionen.',
|
|
235
|
+
},
|
|
236
|
+
category: 'game-basics',
|
|
237
|
+
difficulty: 'intermediate',
|
|
238
|
+
estimatedMinutes: 25,
|
|
239
|
+
prerequisites: ['first-game-bouncing-ball'],
|
|
240
|
+
kidFriendly: true,
|
|
241
|
+
ageRange: { min: 10, max: 99 },
|
|
242
|
+
tags: ['tilemap', 'tiles', 'world', 'level', 'auto-tiling', 'layers'],
|
|
243
|
+
steps: [
|
|
244
|
+
// --- S1: Intro ---
|
|
245
|
+
{
|
|
246
|
+
id: 'tile-welcome',
|
|
247
|
+
type: 'text',
|
|
248
|
+
title: {
|
|
249
|
+
en: 'Building Worlds with Tiles! 🗺️',
|
|
250
|
+
pl: 'Budujemy światy z kafelków! 🗺️',
|
|
251
|
+
de: 'Welten mit Kacheln bauen! 🗺️',
|
|
252
|
+
},
|
|
253
|
+
content: {
|
|
254
|
+
en: 'Tilemaps are the foundation of 2D game worlds — platformers, RPGs, strategy games.\n\nYou will learn:\n• Creating a tilemap with layers\n• Placing and filling tiles\n• Auto-tiling (smart borders)\n• Collision detection with tiles\n• Serializing tilemaps (save/load)\n\nLet\'s build a world! 🌍',
|
|
255
|
+
pl: 'Tilemapy to fundament świata gier 2D — platformówek, RPG, strategii.\n\nNauczysz się:\n• Tworzenia tilemapy z warstwami\n• Umieszczania i wypełniania kafelków\n• Auto-tilingu (inteligentne krawędzie)\n• Detekcji kolizji z kafelkami\n• Serializacji tilemap (zapis/odczyt)\n\nZbudujmy świat! 🌍',
|
|
256
|
+
de: 'Tilemaps sind das Fundament von 2D-Spielwelten — Platformer, RPGs, Strategiespiele.\n\nDu lernst:\n• Erstellen einer Tilemap mit Ebenen\n• Kacheln platzieren und füllen\n• Auto-Tiling (intelligente Ränder)\n• Kollisionserkennung mit Kacheln\n• Tilemaps serialisieren (Speichern/Laden)\n\nBauen wir eine Welt! 🌍',
|
|
257
|
+
},
|
|
258
|
+
skippable: true,
|
|
259
|
+
tooltipPosition: 'center',
|
|
260
|
+
},
|
|
261
|
+
// --- S2: Create tilemap ---
|
|
262
|
+
{
|
|
263
|
+
id: 'create-tilemap',
|
|
264
|
+
type: 'code',
|
|
265
|
+
title: {
|
|
266
|
+
en: 'Create a Tilemap',
|
|
267
|
+
pl: 'Utwórz tilemapę',
|
|
268
|
+
de: 'Erstelle eine Tilemap',
|
|
269
|
+
},
|
|
270
|
+
content: {
|
|
271
|
+
en: 'Create a `Tilemap` with dimensions (width × height in tiles) and tile size.\nThen add a layer for your terrain.',
|
|
272
|
+
pl: 'Utwórz `Tilemap` z wymiarami (szerokość × wysokość w kafelkach) i rozmiarem kafelka.\nNastępnie dodaj warstwę dla terenu.',
|
|
273
|
+
de: 'Erstelle eine `Tilemap` mit Dimensionen (Breite × Höhe in Kacheln) und Kachelgröße.\nDann füge eine Ebene für das Terrain hinzu.',
|
|
274
|
+
},
|
|
275
|
+
codeTemplate: '// Create a 20×15 tilemap with 32px tiles\nconst map = ',
|
|
276
|
+
codeSolution: 'const map = new Tilemap(20, 15, 32, 32);\nconst groundLayer = map.addLayer("ground");\nconst decorLayer = map.addLayer("decoration");',
|
|
277
|
+
codeValidation: {
|
|
278
|
+
containsAll: ['new Tilemap', 'addLayer'],
|
|
279
|
+
},
|
|
280
|
+
hint: {
|
|
281
|
+
en: 'new Tilemap(width, height, tileWidth, tileHeight) → map.addLayer("ground")',
|
|
282
|
+
pl: 'new Tilemap(szerokość, wysokość, szerKafelka, wysKafelka) → map.addLayer("ground")',
|
|
283
|
+
de: 'new Tilemap(breite, höhe, kachelBreite, kachelHöhe) → map.addLayer("ground")',
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
// --- S3: Set tiles and fill ---
|
|
287
|
+
{
|
|
288
|
+
id: 'set-tiles',
|
|
289
|
+
type: 'code',
|
|
290
|
+
title: {
|
|
291
|
+
en: 'Place & Fill Tiles',
|
|
292
|
+
pl: 'Umieść i wypełnij kafelki',
|
|
293
|
+
de: 'Kacheln platzieren und füllen',
|
|
294
|
+
},
|
|
295
|
+
content: {
|
|
296
|
+
en: 'Use `setTile` to place individual tiles and `fillRect` to fill rectangular areas.\nTile IDs reference the tileset definition. 0 = empty.',
|
|
297
|
+
pl: 'Użyj `setTile` do umieszczania pojedynczych kafelków i `fillRect` do wypełniania prostokątnych obszarów.\nID kafelków odnosi się do definicji zestawu. 0 = puste.',
|
|
298
|
+
de: 'Verwende `setTile` für einzelne Kacheln und `fillRect` zum Füllen rechteckiger Bereiche.\nKachel-IDs referenzieren die Tileset-Definition. 0 = leer.',
|
|
299
|
+
},
|
|
300
|
+
codeTemplate: '// Place tiles on the ground layer\n',
|
|
301
|
+
codeSolution: '// Fill entire bottom row with grass (tile ID 1)\nmap.fillRect("ground", 0, 14, 20, 1, 1);\n\n// Add some dirt blocks\nmap.fillRect("ground", 5, 12, 3, 2, 2);\n\n// Place individual tiles\nmap.setTile("ground", 10, 11, 3); // bridge tile',
|
|
302
|
+
codeValidation: {
|
|
303
|
+
containsAll: ['fillRect', 'setTile'],
|
|
304
|
+
},
|
|
305
|
+
hint: {
|
|
306
|
+
en: 'fillRect(layerName, x, y, width, height, tileId) — setTile(layerName, x, y, tileId)',
|
|
307
|
+
pl: 'fillRect(warstwa, x, y, szer, wys, idKafelka) — setTile(warstwa, x, y, idKafelka)',
|
|
308
|
+
de: 'fillRect(ebene, x, y, breite, höhe, kachelId) — setTile(ebene, x, y, kachelId)',
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
// --- S4: Auto-tiling ---
|
|
312
|
+
{
|
|
313
|
+
id: 'auto-tiling',
|
|
314
|
+
type: 'code',
|
|
315
|
+
title: {
|
|
316
|
+
en: 'Auto-Tiling Magic ✨',
|
|
317
|
+
pl: 'Magia auto-tilingu ✨',
|
|
318
|
+
de: 'Auto-Tiling Magie ✨',
|
|
319
|
+
},
|
|
320
|
+
content: {
|
|
321
|
+
en: 'Use `computeAutoTileMask` to automatically determine which border tile variant to use.\nThe 4-bit bitmask checks top/right/bottom/left neighbors.',
|
|
322
|
+
pl: 'Użyj `computeAutoTileMask` do automatycznego określenia, który wariant kafelka krawędziowego użyć.\n4-bitowa maska sprawdza sąsiadów: góra/prawo/dół/lewo.',
|
|
323
|
+
de: 'Verwende `computeAutoTileMask` um automatisch die richtige Randkachel-Variante zu bestimmen.\nDie 4-Bit-Maske prüft Nachbarn: oben/rechts/unten/links.',
|
|
324
|
+
},
|
|
325
|
+
codeTemplate: '// Compute auto-tile masks for the ground layer\n',
|
|
326
|
+
codeSolution: 'for (let y = 0; y < map.height; y++) {\n for (let x = 0; x < map.width; x++) {\n if (map.getTile("ground", x, y) > 0) {\n const mask = computeAutoTileMask(map, "ground", x, y);\n // mask is 0-15: use it to pick the right tile variant\n map.setTile("ground", x, y, tileVariants[mask]);\n }\n }\n}',
|
|
327
|
+
codeValidation: {
|
|
328
|
+
containsAll: ['computeAutoTileMask', 'getTile'],
|
|
329
|
+
},
|
|
330
|
+
hint: {
|
|
331
|
+
en: 'computeAutoTileMask(map, layerName, x, y) returns 0-15 bitmask',
|
|
332
|
+
pl: 'computeAutoTileMask(map, warstwa, x, y) zwraca maskę bitową 0-15',
|
|
333
|
+
de: 'computeAutoTileMask(map, ebene, x, y) gibt Bitmaske 0-15 zurück',
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
// --- S5: Quiz ---
|
|
337
|
+
{
|
|
338
|
+
id: 'quiz-tilemap',
|
|
339
|
+
type: 'quiz',
|
|
340
|
+
title: {
|
|
341
|
+
en: 'Tilemap Quiz! 🧠',
|
|
342
|
+
pl: 'Quiz tilemap! 🧠',
|
|
343
|
+
de: 'Tilemap-Quiz! 🧠',
|
|
344
|
+
},
|
|
345
|
+
content: {
|
|
346
|
+
en: 'A tilemap is 20 tiles wide × 15 tiles tall with 32px tiles. What is the total pixel width?',
|
|
347
|
+
pl: 'Tilemap ma 20 kafelków szerokości × 15 kafelków wysokości, każdy po 32px. Jaka jest całkowita szerokość w pikselach?',
|
|
348
|
+
de: 'Eine Tilemap ist 20 Kacheln breit × 15 Kacheln hoch mit 32px Kacheln. Wie breit ist sie in Pixeln?',
|
|
349
|
+
},
|
|
350
|
+
quizOptions: [
|
|
351
|
+
{ id: 'a', text: { en: '320 px', pl: '320 px', de: '320 px' } },
|
|
352
|
+
{ id: 'b', text: { en: '480 px', pl: '480 px', de: '480 px' } },
|
|
353
|
+
{ id: 'c', text: { en: '640 px', pl: '640 px', de: '640 px' } },
|
|
354
|
+
{ id: 'd', text: { en: '960 px', pl: '960 px', de: '960 px' } },
|
|
355
|
+
],
|
|
356
|
+
quizCorrectId: 'c',
|
|
357
|
+
},
|
|
358
|
+
// --- S6: Collision queries ---
|
|
359
|
+
{
|
|
360
|
+
id: 'tile-collision',
|
|
361
|
+
type: 'code',
|
|
362
|
+
title: {
|
|
363
|
+
en: 'Tile-Based Collision',
|
|
364
|
+
pl: 'Kolizje oparte o kafelki',
|
|
365
|
+
de: 'Kachelbasierte Kollision',
|
|
366
|
+
},
|
|
367
|
+
content: {
|
|
368
|
+
en: 'Use `isSolid` to check if a tile position is solid, or `getSolidTilesInRect` to query collision in an area.\nThis requires a tileset with solid flags on tiles.',
|
|
369
|
+
pl: 'Użyj `isSolid` do sprawdzenia, czy kafelek jest solidny, lub `getSolidTilesInRect` do zapytania o kolizje w obszarze.\nWymaga to zestawu kafelków z flagami solid.',
|
|
370
|
+
de: 'Verwende `isSolid` um zu prüfen, ob eine Kachel solide ist, oder `getSolidTilesInRect` für Kollisionsabfragen.\nDies erfordert ein Tileset mit Solid-Flags.',
|
|
371
|
+
},
|
|
372
|
+
codeTemplate: '// Check collision with tiles\n',
|
|
373
|
+
codeSolution: '// Convert player world position to tile coordinates\nconst tilePos = map.worldToTile(playerX, playerY);\n\n// Check if the tile below is solid\nif (map.isSolid(tilePos.x, tilePos.y + 1)) {\n // Player is standing on solid ground\n}\n\n// Query all solid tiles in an area\nconst solidTiles = map.getSolidTilesInRect({\n x: playerX - 16, y: playerY - 16,\n width: 32, height: 32\n});',
|
|
374
|
+
codeValidation: {
|
|
375
|
+
containsAll: ['worldToTile', 'isSolid'],
|
|
376
|
+
},
|
|
377
|
+
hint: {
|
|
378
|
+
en: 'worldToTile(x, y) converts pixel coordinates → tile coordinates. isSolid(tileX, tileY) checks collision.',
|
|
379
|
+
pl: 'worldToTile(x, y) konwertuje piksele → współrzędne kafelka. isSolid(tileX, tileY) sprawdza kolizję.',
|
|
380
|
+
de: 'worldToTile(x, y) konvertiert Pixel → Kachelkoordinaten. isSolid(tileX, tileY) prüft Kollision.',
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
// --- S7: Serialization ---
|
|
384
|
+
{
|
|
385
|
+
id: 'tile-serialization',
|
|
386
|
+
type: 'code',
|
|
387
|
+
title: {
|
|
388
|
+
en: 'Save & Load Tilemaps',
|
|
389
|
+
pl: 'Zapisz i wczytaj tilemapy',
|
|
390
|
+
de: 'Tilemaps speichern & laden',
|
|
391
|
+
},
|
|
392
|
+
content: {
|
|
393
|
+
en: 'Tilemaps can be serialized to JSON and loaded back. This lets you save levels and load them at runtime.',
|
|
394
|
+
pl: 'Tilemapy można serializować do JSON i wczytywać z powrotem. Dzięki temu możesz zapisywać i ładować poziomy.',
|
|
395
|
+
de: 'Tilemaps können als JSON serialisiert und zurückgeladen werden. So kannst du Level speichern und laden.',
|
|
396
|
+
},
|
|
397
|
+
codeTemplate: '// Save and load a tilemap\n',
|
|
398
|
+
codeSolution: '// Save to JSON\nconst mapData = map.toJSON();\nconst json = JSON.stringify(mapData);\n\n// Load from JSON\nconst loaded = Tilemap.fromJSON(JSON.parse(json));',
|
|
399
|
+
codeValidation: {
|
|
400
|
+
containsAll: ['toJSON', 'fromJSON'],
|
|
401
|
+
},
|
|
402
|
+
hint: {
|
|
403
|
+
en: 'map.toJSON() → JSON string → Tilemap.fromJSON(data)',
|
|
404
|
+
pl: 'map.toJSON() → JSON string → Tilemap.fromJSON(data)',
|
|
405
|
+
de: 'map.toJSON() → JSON String → Tilemap.fromJSON(data)',
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
// --- S8: Congratulations ---
|
|
409
|
+
{
|
|
410
|
+
id: 'tile-congratulations',
|
|
411
|
+
type: 'text',
|
|
412
|
+
title: {
|
|
413
|
+
en: 'Congratulations! 🎉',
|
|
414
|
+
pl: 'Gratulacje! 🎉',
|
|
415
|
+
de: 'Herzlichen Glückwunsch! 🎉',
|
|
416
|
+
},
|
|
417
|
+
content: {
|
|
418
|
+
en: '🏆 You learned:\n• `Tilemap` creation with layers\n• `setTile`, `fillRect`, `floodFill`\n• `computeAutoTileMask` for smart borders\n• `worldToTile` / `tileToWorld` conversion\n• `isSolid` / `getSolidTilesInRect` for collision\n• `toJSON` / `fromJSON` for save/load\n\nNext: Try "Visual Scripting" to program without code! 🧩',
|
|
419
|
+
pl: '🏆 Nauczyłeś się:\n• Tworzenia `Tilemap` z warstwami\n• `setTile`, `fillRect`, `floodFill`\n• `computeAutoTileMask` do inteligentnych krawędzi\n• `worldToTile` / `tileToWorld` konwersji\n• `isSolid` / `getSolidTilesInRect` do kolizji\n• `toJSON` / `fromJSON` do zapisu/odczytu\n\nDalej: Spróbuj "Visual Scripting" — programowanie bez kodu! 🧩',
|
|
420
|
+
de: '🏆 Du hast gelernt:\n• `Tilemap`-Erstellung mit Ebenen\n• `setTile`, `fillRect`, `floodFill`\n• `computeAutoTileMask` für intelligente Ränder\n• `worldToTile` / `tileToWorld` Konvertierung\n• `isSolid` / `getSolidTilesInRect` für Kollision\n• `toJSON` / `fromJSON` zum Speichern/Laden\n\nWeiter: Probiere "Visual Scripting" — Programmieren ohne Code! 🧩',
|
|
421
|
+
},
|
|
422
|
+
tooltipPosition: 'center',
|
|
423
|
+
},
|
|
424
|
+
],
|
|
425
|
+
};
|
|
426
|
+
/* ══════════════════════════════════════════════════════════════
|
|
427
|
+
T07 — Visual Scripting
|
|
428
|
+
══════════════════════════════════════════════════════════════ */
|
|
429
|
+
const TUTORIAL_VISUAL_SCRIPTING = {
|
|
430
|
+
id: 'visual-scripting-basics',
|
|
431
|
+
title: {
|
|
432
|
+
en: 'Visual Scripting: Your First Behavior',
|
|
433
|
+
pl: 'Visual Scripting: Twoje pierwsze zachowanie',
|
|
434
|
+
de: 'Visual Scripting: Dein erstes Verhalten',
|
|
435
|
+
},
|
|
436
|
+
description: {
|
|
437
|
+
en: 'Create game logic without writing code using the visual node graph system.',
|
|
438
|
+
pl: 'Twórz logikę gry bez pisania kodu za pomocą wizualnego systemu grafów.',
|
|
439
|
+
de: 'Erstelle Spiellogik ohne Code mit dem visuellen Knoten-Graph-System.',
|
|
440
|
+
},
|
|
441
|
+
category: 'scripting',
|
|
442
|
+
difficulty: 'beginner',
|
|
443
|
+
estimatedMinutes: 20,
|
|
444
|
+
kidFriendly: true,
|
|
445
|
+
ageRange: { min: 8, max: 99 },
|
|
446
|
+
tags: ['visual-scripting', 'nodes', 'no-code', 'graph', 'behaviors'],
|
|
447
|
+
steps: [
|
|
448
|
+
// --- S1: Intro ---
|
|
449
|
+
{
|
|
450
|
+
id: 'vs-welcome',
|
|
451
|
+
type: 'text',
|
|
452
|
+
title: {
|
|
453
|
+
en: 'Program Without Code! 🧩',
|
|
454
|
+
pl: 'Programuj bez kodu! 🧩',
|
|
455
|
+
de: 'Programmieren ohne Code! 🧩',
|
|
456
|
+
},
|
|
457
|
+
content: {
|
|
458
|
+
en: 'Visual Scripting lets you create game behaviors by connecting nodes in a graph.\nNo typing required — just drag, connect, and play!\n\nYou will learn:\n• Creating a node library\n• Building a script graph\n• Connecting nodes with ports\n• Running the graph\n\nPerfect for beginners and kids! 🎮',
|
|
459
|
+
pl: 'Visual Scripting pozwala tworzyć zachowania gry przez łączenie węzłów w grafie.\nBez pisania — po prostu przeciągaj, łącz i graj!\n\nNauczysz się:\n• Tworzenia biblioteki węzłów\n• Budowania grafu skryptowego\n• Łączenia węzłów portami\n• Uruchamiania grafu\n\nIdealne dla początkujących i dzieci! 🎮',
|
|
460
|
+
de: 'Visual Scripting lässt dich Spielverhalten durch Verbinden von Knoten erstellen.\nKein Tippen nötig — einfach ziehen, verbinden und spielen!\n\nDu lernst:\n• Eine Knoten-Bibliothek erstellen\n• Einen Script-Graph bauen\n• Knoten mit Ports verbinden\n• Den Graphen ausführen\n\nPerfekt für Anfänger und Kinder! 🎮',
|
|
461
|
+
},
|
|
462
|
+
skippable: true,
|
|
463
|
+
tooltipPosition: 'center',
|
|
464
|
+
},
|
|
465
|
+
// --- S2: Create node library ---
|
|
466
|
+
{
|
|
467
|
+
id: 'node-library',
|
|
468
|
+
type: 'code',
|
|
469
|
+
title: {
|
|
470
|
+
en: 'Set Up the Node Library',
|
|
471
|
+
pl: 'Skonfiguruj bibliotekę węzłów',
|
|
472
|
+
de: 'Richte die Knoten-Bibliothek ein',
|
|
473
|
+
},
|
|
474
|
+
content: {
|
|
475
|
+
en: 'The `NodeLibrary` stores all available node types. Use `createDefaultNodeLibrary()` to get built-in nodes for math, logic, entity control, and more.',
|
|
476
|
+
pl: '`NodeLibrary` przechowuje wszystkie dostępne typy węzłów. Użyj `createDefaultNodeLibrary()` aby uzyskać wbudowane węzły do matematyki, logiki, sterowania encjami i więcej.',
|
|
477
|
+
de: 'Die `NodeLibrary` speichert verfügbare Knotentypen. Verwende `createDefaultNodeLibrary()` für eingebaute Knoten für Mathematik, Logik, Entity-Steuerung und mehr.',
|
|
478
|
+
},
|
|
479
|
+
codeTemplate: '// Create the node library with built-in nodes\n',
|
|
480
|
+
codeSolution: 'const library = createDefaultNodeLibrary();\n\n// See available node categories:\n// flow, math, logic, entity, input, physics, audio, ui, game, variable',
|
|
481
|
+
codeValidation: {
|
|
482
|
+
containsAll: ['createDefaultNodeLibrary'],
|
|
483
|
+
},
|
|
484
|
+
hint: {
|
|
485
|
+
en: 'Just call createDefaultNodeLibrary() — it returns a NodeLibrary with all built-in nodes.',
|
|
486
|
+
pl: 'Wystarczy wywołać createDefaultNodeLibrary() — zwraca NodeLibrary z wbudowanymi węzłami.',
|
|
487
|
+
de: 'Rufe einfach createDefaultNodeLibrary() auf — es gibt eine NodeLibrary mit allen eingebauten Knoten zurück.',
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
// --- S3: Create a graph ---
|
|
491
|
+
{
|
|
492
|
+
id: 'create-graph',
|
|
493
|
+
type: 'code',
|
|
494
|
+
title: {
|
|
495
|
+
en: 'Build a Script Graph',
|
|
496
|
+
pl: 'Zbuduj graf skryptowy',
|
|
497
|
+
de: 'Baue einen Script-Graphen',
|
|
498
|
+
},
|
|
499
|
+
content: {
|
|
500
|
+
en: 'A `ScriptGraph` has nodes (instances) and connections between their ports.\nLet\'s create a simple graph that moves an entity when a key is pressed.',
|
|
501
|
+
pl: '`ScriptGraph` zawiera węzły (instancje) i połączenia między ich portami.\nUtwórzmy prosty graf, który przesuwa encję po naciśnięciu klawisza.',
|
|
502
|
+
de: 'Ein `ScriptGraph` hat Knoten (Instanzen) und Verbindungen zwischen Ports.\nErstellen wir einen einfachen Graphen, der eine Entity bewegt, wenn eine Taste gedrückt wird.',
|
|
503
|
+
},
|
|
504
|
+
codeTemplate: '// Define a script graph\nconst graph: ScriptGraph = {\n',
|
|
505
|
+
codeSolution: 'const graph: ScriptGraph = {\n id: "move-on-key",\n name: "Move On Key Press",\n nodes: [\n { id: "n1", type: "on-update", position: { x: 50, y: 100 }, inputValues: {} },\n { id: "n2", type: "get-key", position: { x: 250, y: 100 }, inputValues: { key: "ArrowRight" } },\n { id: "n3", type: "move-entity", position: { x: 450, y: 100 }, inputValues: { speed: 200 } },\n ],\n connections: [\n { id: "c1", fromNode: "n1", fromPort: "flow-out", toNode: "n2", toPort: "flow-in" },\n { id: "c2", fromNode: "n2", fromPort: "flow-out", toNode: "n3", toPort: "flow-in" },\n ],\n variables: [],\n};',
|
|
506
|
+
codeValidation: {
|
|
507
|
+
containsAll: ['ScriptGraph', 'nodes', 'connections'],
|
|
508
|
+
},
|
|
509
|
+
hint: {
|
|
510
|
+
en: 'A ScriptGraph needs: id, name, nodes (array), connections (array), and variables (array).',
|
|
511
|
+
pl: 'ScriptGraph potrzebuje: id, name, nodes (tablica), connections (tablica) i variables (tablica).',
|
|
512
|
+
de: 'Ein ScriptGraph braucht: id, name, nodes (Array), connections (Array) und variables (Array).',
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
// --- S4: Quiz on nodes ---
|
|
516
|
+
{
|
|
517
|
+
id: 'quiz-nodes',
|
|
518
|
+
type: 'quiz',
|
|
519
|
+
title: {
|
|
520
|
+
en: 'Node Quiz! 🧠',
|
|
521
|
+
pl: 'Quiz o węzłach! 🧠',
|
|
522
|
+
de: 'Knoten-Quiz! 🧠',
|
|
523
|
+
},
|
|
524
|
+
content: {
|
|
525
|
+
en: 'What does a "flow" port type control in visual scripting?',
|
|
526
|
+
pl: 'Co kontroluje port typu "flow" w visual scriptingu?',
|
|
527
|
+
de: 'Was steuert ein "flow"-Port in Visual Scripting?',
|
|
528
|
+
},
|
|
529
|
+
quizOptions: [
|
|
530
|
+
{ id: 'a', text: { en: 'The color of the node', pl: 'Kolor węzła', de: 'Die Farbe des Knotens' } },
|
|
531
|
+
{ id: 'b', text: { en: 'The execution order (which node runs next)', pl: 'Kolejność wykonania (który węzeł uruchomić dalej)', de: 'Die Ausführungsreihenfolge (welcher Knoten als nächstes läuft)' } },
|
|
532
|
+
{ id: 'c', text: { en: 'The animation speed', pl: 'Prędkość animacji', de: 'Die Animationsgeschwindigkeit' } },
|
|
533
|
+
{ id: 'd', text: { en: 'The sound volume', pl: 'Głośność dźwięku', de: 'Die Lautstärke' } },
|
|
534
|
+
],
|
|
535
|
+
quizCorrectId: 'b',
|
|
536
|
+
},
|
|
537
|
+
// --- S5: Execute the graph ---
|
|
538
|
+
{
|
|
539
|
+
id: 'run-graph',
|
|
540
|
+
type: 'code',
|
|
541
|
+
title: {
|
|
542
|
+
en: 'Run the Graph! 🚀',
|
|
543
|
+
pl: 'Uruchom graf! 🚀',
|
|
544
|
+
de: 'Starte den Graphen! 🚀',
|
|
545
|
+
},
|
|
546
|
+
content: {
|
|
547
|
+
en: 'The `GraphExecutor` takes a node library and a script graph, then executes it each frame.\nConnect it to the engine\'s update loop.',
|
|
548
|
+
pl: '`GraphExecutor` przyjmuje bibliotekę węzłów i graf, a następnie wykonuje go co klatkę.\nPodłącz go do pętli update silnika.',
|
|
549
|
+
de: 'Der `GraphExecutor` nimmt eine Knoten-Bibliothek und einen Graphen und führt ihn pro Frame aus.\nVerbinde ihn mit der Update-Schleife der Engine.',
|
|
550
|
+
},
|
|
551
|
+
codeTemplate: '// Execute the graph each frame\nconst executor = ',
|
|
552
|
+
codeSolution: 'const executor = new GraphExecutor(library);\n\n// In the game update loop:\nengine.events.on("engine:update", (dt) => {\n executor.execute(graph, {\n entityId: playerId,\n dt,\n world: engine.world,\n events: engine.events,\n variables: {},\n triggerFlow: () => {},\n });\n});',
|
|
553
|
+
codeValidation: {
|
|
554
|
+
containsAll: ['new GraphExecutor', 'execute'],
|
|
555
|
+
},
|
|
556
|
+
hint: {
|
|
557
|
+
en: 'new GraphExecutor(library) → executor.execute(graph, context) in each frame',
|
|
558
|
+
pl: 'new GraphExecutor(library) → executor.execute(graph, context) w każdej klatce',
|
|
559
|
+
de: 'new GraphExecutor(library) → executor.execute(graph, context) in jedem Frame',
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
// --- S6: Interactive ---
|
|
563
|
+
{
|
|
564
|
+
id: 'vs-interactive',
|
|
565
|
+
type: 'interactive',
|
|
566
|
+
title: {
|
|
567
|
+
en: 'Try It! Connect Nodes',
|
|
568
|
+
pl: 'Spróbuj! Połącz węzły',
|
|
569
|
+
de: 'Probiere es! Verbinde Knoten',
|
|
570
|
+
},
|
|
571
|
+
content: {
|
|
572
|
+
en: 'In the editor, try dragging a connection from one node\'s output port to another node\'s input port.\nThe wire turns green when compatible ports are connected!',
|
|
573
|
+
pl: 'W edytorze spróbuj przeciągnąć połączenie z portu wyjściowego jednego węzła na port wejściowy drugiego.\nPrzewód zmienia kolor na zielony gdy porty są kompatybilne!',
|
|
574
|
+
de: 'Im Editor: Ziehe eine Verbindung vom Ausgang eines Knotens zum Eingang eines anderen.\nDie Leitung wird grün, wenn kompatible Ports verbunden sind!',
|
|
575
|
+
},
|
|
576
|
+
requiredAction: 'connect-nodes',
|
|
577
|
+
},
|
|
578
|
+
// --- S7: Congratulations ---
|
|
579
|
+
{
|
|
580
|
+
id: 'vs-congratulations',
|
|
581
|
+
type: 'text',
|
|
582
|
+
title: {
|
|
583
|
+
en: 'Congratulations! 🎉',
|
|
584
|
+
pl: 'Gratulacje! 🎉',
|
|
585
|
+
de: 'Herzlichen Glückwunsch! 🎉',
|
|
586
|
+
},
|
|
587
|
+
content: {
|
|
588
|
+
en: '🏆 You learned:\n• `NodeLibrary` with built-in node types\n• Port types: flow, number, string, boolean, vec2, entity\n• `ScriptGraph` structure (nodes + connections)\n• `GraphExecutor` to run graphs each frame\n• Node categories: flow, math, logic, entity, input, physics, game\n\nVisual Scripting makes game development accessible to everyone! 🌟\n\nNext: Try "Local Multiplayer" for co-op gaming! 🎮🎮',
|
|
589
|
+
pl: '🏆 Nauczyłeś się:\n• `NodeLibrary` z wbudowanymi typami węzłów\n• Typy portów: flow, number, string, boolean, vec2, entity\n• Struktury `ScriptGraph` (nodes + connections)\n• `GraphExecutor` do uruchamiania grafów co klatkę\n• Kategorie węzłów: flow, math, logic, entity, input, physics, game\n\nVisual Scripting sprawia, że tworzenie gier jest dostępne dla każdego! 🌟\n\nDalej: Spróbuj "Multiplayer lokalny" do gry w co-op! 🎮🎮',
|
|
590
|
+
de: '🏆 Du hast gelernt:\n• `NodeLibrary` mit eingebauten Knotentypen\n• Port-Typen: flow, number, string, boolean, vec2, entity\n• `ScriptGraph`-Struktur (Knoten + Verbindungen)\n• `GraphExecutor` zum Ausführen von Graphen\n• Knoten-Kategorien: flow, math, logic, entity, input, physics, game\n\nVisual Scripting macht Spieleentwicklung für alle zugänglich! 🌟\n\nWeiter: Probiere "Lokaler Multiplayer" für Co-op! 🎮🎮',
|
|
591
|
+
},
|
|
592
|
+
tooltipPosition: 'center',
|
|
593
|
+
},
|
|
594
|
+
],
|
|
595
|
+
};
|
|
596
|
+
/* ══════════════════════════════════════════════════════════════
|
|
597
|
+
T08 — Multiplayer lokalny
|
|
598
|
+
══════════════════════════════════════════════════════════════ */
|
|
599
|
+
const TUTORIAL_LOCAL_MULTIPLAYER = {
|
|
600
|
+
id: 'local-multiplayer-coop',
|
|
601
|
+
title: {
|
|
602
|
+
en: 'Local Multiplayer: Co-op & Splitscreen',
|
|
603
|
+
pl: 'Multiplayer lokalny: Co-op i Splitscreen',
|
|
604
|
+
de: 'Lokaler Multiplayer: Co-op & Splitscreen',
|
|
605
|
+
},
|
|
606
|
+
description: {
|
|
607
|
+
en: 'Set up local multiplayer with gamepads, split-screen viewports, and drop-in/drop-out players.',
|
|
608
|
+
pl: 'Skonfiguruj multiplayer lokalny z gamepadami, podzielonym ekranem i dynamicznym dołączaniem graczy.',
|
|
609
|
+
de: 'Richte lokalen Multiplayer mit Gamepads, Splitscreen und Drop-in/Drop-out-Spielern ein.',
|
|
610
|
+
},
|
|
611
|
+
category: 'multiplayer',
|
|
612
|
+
difficulty: 'intermediate',
|
|
613
|
+
estimatedMinutes: 25,
|
|
614
|
+
prerequisites: ['first-game-bouncing-ball'],
|
|
615
|
+
kidFriendly: true,
|
|
616
|
+
ageRange: { min: 10, max: 99 },
|
|
617
|
+
tags: ['multiplayer', 'local', 'splitscreen', 'gamepad', 'coop', 'co-op'],
|
|
618
|
+
steps: [
|
|
619
|
+
// --- S1: Intro ---
|
|
620
|
+
{
|
|
621
|
+
id: 'mp-welcome',
|
|
622
|
+
type: 'text',
|
|
623
|
+
title: {
|
|
624
|
+
en: 'Play Together! 🎮🎮',
|
|
625
|
+
pl: 'Grajcie razem! 🎮🎮',
|
|
626
|
+
de: 'Zusammen spielen! 🎮🎮',
|
|
627
|
+
},
|
|
628
|
+
content: {
|
|
629
|
+
en: 'Local multiplayer lets friends play together on the same screen!\n\nYou will learn:\n• `PlayerManager` — managing up to 12 players\n• Gamepad input for each player\n• Split-screen viewports\n• Drop-in / drop-out\n\nGrab some controllers and let\'s go! 🕹️',
|
|
630
|
+
pl: 'Multiplayer lokalny pozwala znajomym grać razem na jednym ekranie!\n\nNauczysz się:\n• `PlayerManager` — zarządzanie do 12 graczy\n• Wejście z gamepada dla każdego gracza\n• Podzielony ekran (split-screen)\n• Dynamiczne dołączanie/odłączanie graczy\n\nWeź kontrolery i zaczynamy! 🕹️',
|
|
631
|
+
de: 'Lokaler Multiplayer lässt Freunde zusammen auf einem Bildschirm spielen!\n\nDu lernst:\n• `PlayerManager` — bis zu 12 Spieler verwalten\n• Gamepad-Eingabe für jeden Spieler\n• Splitscreen-Ansichten\n• Drop-in / Drop-out\n\nSchnappt euch Controller und los! 🕹️',
|
|
632
|
+
},
|
|
633
|
+
skippable: true,
|
|
634
|
+
tooltipPosition: 'center',
|
|
635
|
+
},
|
|
636
|
+
// --- S2: PlayerManager ---
|
|
637
|
+
{
|
|
638
|
+
id: 'player-manager',
|
|
639
|
+
type: 'code',
|
|
640
|
+
title: {
|
|
641
|
+
en: 'Set Up Player Manager',
|
|
642
|
+
pl: 'Skonfiguruj PlayerManager',
|
|
643
|
+
de: 'Richte den PlayerManager ein',
|
|
644
|
+
},
|
|
645
|
+
content: {
|
|
646
|
+
en: 'The `PlayerManager` handles player registration, scores, and lives.\nUse `setupLocal(count)` for quick local multiplayer setup.',
|
|
647
|
+
pl: '`PlayerManager` obsługuje rejestrację graczy, punkty i życia.\nUżyj `setupLocal(count)` do szybkiej konfiguracji multiplayer lokalnego.',
|
|
648
|
+
de: 'Der `PlayerManager` verwaltet Spielerregistrierung, Punkte und Leben.\nVerwende `setupLocal(count)` für schnelles lokales Multiplayer-Setup.',
|
|
649
|
+
},
|
|
650
|
+
codeTemplate: '// Set up local multiplayer with the engine\nconst players = engine.players;\n',
|
|
651
|
+
codeSolution: 'const players = engine.players;\n\n// Quick setup for 2 players\nconst allPlayers = players.setupLocal(2);\n\n// Player 1: keyboard, Player 2: gamepad\nconsole.log(allPlayers[0].name); // "Player 1"\nconsole.log(allPlayers[0].inputDevice); // "keyboard"\nconsole.log(allPlayers[1].name); // "Player 2"\nconsole.log(allPlayers[1].inputDevice); // "gamepad"',
|
|
652
|
+
codeValidation: {
|
|
653
|
+
containsAll: ['players', 'setupLocal'],
|
|
654
|
+
},
|
|
655
|
+
hint: {
|
|
656
|
+
en: 'engine.players.setupLocal(2) creates 2 players (keyboard + gamepad).',
|
|
657
|
+
pl: 'engine.players.setupLocal(2) tworzy 2 graczy (klawiatura + gamepad).',
|
|
658
|
+
de: 'engine.players.setupLocal(2) erstellt 2 Spieler (Tastatur + Gamepad).',
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
// --- S3: Gamepad input per player ---
|
|
662
|
+
{
|
|
663
|
+
id: 'gamepad-input',
|
|
664
|
+
type: 'code',
|
|
665
|
+
title: {
|
|
666
|
+
en: 'Per-Player Input',
|
|
667
|
+
pl: 'Wejście per gracz',
|
|
668
|
+
de: 'Eingabe pro Spieler',
|
|
669
|
+
},
|
|
670
|
+
content: {
|
|
671
|
+
en: 'Use `input.getAction(name, playerIndex)` to read actions per player.\nPlayer 0 uses keyboard, player 1+ use gamepads.',
|
|
672
|
+
pl: 'Użyj `input.getAction(nazwa, indeksGracza)` do odczytu akcji per gracz.\nGracz 0 używa klawiatury, gracz 1+ używa gamepadów.',
|
|
673
|
+
de: 'Verwende `input.getAction(name, spielerIndex)` um Aktionen pro Spieler zu lesen.\nSpieler 0 nutzt die Tastatur, Spieler 1+ nutzen Gamepads.',
|
|
674
|
+
},
|
|
675
|
+
codeTemplate: '// Define actions and read per-player input\nengine.input.defineAction("jump", {\n',
|
|
676
|
+
codeSolution: 'engine.input.defineAction("jump", {\n keys: ["Space"],\n gamepadButtons: ["A"],\n});\n\nengine.input.defineAction("moveRight", {\n keys: ["ArrowRight"],\n gamepadAxis: { axis: "LeftX", direction: "positive" },\n});\n\n// In update loop:\nfor (const player of players.activePlayers) {\n const jump = engine.input.getAction("jump", player.index);\n const move = engine.input.getAction("moveRight", player.index);\n\n if (jump.justPressed) {\n // Player jumped!\n }\n}',
|
|
677
|
+
codeValidation: {
|
|
678
|
+
containsAll: ['defineAction', 'getAction', 'gamepadButtons'],
|
|
679
|
+
},
|
|
680
|
+
hint: {
|
|
681
|
+
en: 'defineAction(name, { keys, gamepadButtons }) → getAction(name, playerIndex)',
|
|
682
|
+
pl: 'defineAction(nazwa, { keys, gamepadButtons }) → getAction(nazwa, indeksGracza)',
|
|
683
|
+
de: 'defineAction(name, { keys, gamepadButtons }) → getAction(name, spielerIndex)',
|
|
684
|
+
},
|
|
685
|
+
},
|
|
686
|
+
// --- S4: Splitscreen ---
|
|
687
|
+
{
|
|
688
|
+
id: 'splitscreen',
|
|
689
|
+
type: 'code',
|
|
690
|
+
title: {
|
|
691
|
+
en: 'Split-Screen Views',
|
|
692
|
+
pl: 'Podzielony ekran',
|
|
693
|
+
de: 'Splitscreen-Ansichten',
|
|
694
|
+
},
|
|
695
|
+
content: {
|
|
696
|
+
en: 'The `SplitScreenManager` divides the canvas into viewports.\nSupported modes: shared, split-horizontal, split-vertical, split-quad, split-6, split-9, split-12.',
|
|
697
|
+
pl: '`SplitScreenManager` dzieli canvas na widoki.\nDostępne tryby: shared, split-horizontal, split-vertical, split-quad, split-6, split-9, split-12.',
|
|
698
|
+
de: 'Der `SplitScreenManager` teilt den Canvas in Viewports auf.\nUnterstützte Modi: shared, split-horizontal, split-vertical, split-quad, split-6, split-9, split-12.',
|
|
699
|
+
},
|
|
700
|
+
codeTemplate: '// Set up split-screen\nconst splitScreen = engine.splitScreen;\n',
|
|
701
|
+
codeSolution: 'const splitScreen = engine.splitScreen;\n\n// Set the mode based on player count\nsplitScreen.setMode("split-vertical"); // left-right split for 2 players\nsplitScreen.setCanvasSize(800, 600);\n\n// The engine automatically renders each viewport\n// in its render loop — no extra code needed!',
|
|
702
|
+
codeValidation: {
|
|
703
|
+
containsAll: ['splitScreen', 'setMode'],
|
|
704
|
+
},
|
|
705
|
+
hint: {
|
|
706
|
+
en: 'engine.splitScreen.setMode("split-vertical") for 2-player side by side.',
|
|
707
|
+
pl: 'engine.splitScreen.setMode("split-vertical") dla 2 graczy obok siebie.',
|
|
708
|
+
de: 'engine.splitScreen.setMode("split-vertical") für 2 Spieler nebeneinander.',
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
// --- S5: Quiz ---
|
|
712
|
+
{
|
|
713
|
+
id: 'quiz-multiplayer',
|
|
714
|
+
type: 'quiz',
|
|
715
|
+
title: {
|
|
716
|
+
en: 'Multiplayer Quiz! 🧠',
|
|
717
|
+
pl: 'Quiz multiplayer! 🧠',
|
|
718
|
+
de: 'Multiplayer-Quiz! 🧠',
|
|
719
|
+
},
|
|
720
|
+
content: {
|
|
721
|
+
en: 'How many players does the engine support simultaneously?',
|
|
722
|
+
pl: 'Ilu graczy jednocześnie obsługuje silnik?',
|
|
723
|
+
de: 'Wie viele Spieler unterstützt die Engine gleichzeitig?',
|
|
724
|
+
},
|
|
725
|
+
quizOptions: [
|
|
726
|
+
{ id: 'a', text: { en: '2 players', pl: '2 graczy', de: '2 Spieler' } },
|
|
727
|
+
{ id: 'b', text: { en: '4 players', pl: '4 graczy', de: '4 Spieler' } },
|
|
728
|
+
{ id: 'c', text: { en: '8 players', pl: '8 graczy', de: '8 Spieler' } },
|
|
729
|
+
{ id: 'd', text: { en: 'Up to 12 players', pl: 'Do 12 graczy', de: 'Bis zu 12 Spieler' } },
|
|
730
|
+
],
|
|
731
|
+
quizCorrectId: 'd',
|
|
732
|
+
},
|
|
733
|
+
// --- S6: Drop-in / drop-out ---
|
|
734
|
+
{
|
|
735
|
+
id: 'drop-in-out',
|
|
736
|
+
type: 'code',
|
|
737
|
+
title: {
|
|
738
|
+
en: 'Drop-In / Drop-Out',
|
|
739
|
+
pl: 'Dynamiczne dołączanie/odłączanie',
|
|
740
|
+
de: 'Drop-In / Drop-Out',
|
|
741
|
+
},
|
|
742
|
+
content: {
|
|
743
|
+
en: 'Players can join and leave at any time. Listen for `player:join` and `player:leave` events.',
|
|
744
|
+
pl: 'Gracze mogą dołączać i odchodzić w dowolnym momencie. Nasłuchuj zdarzeń `player:join` i `player:leave`.',
|
|
745
|
+
de: 'Spieler können jederzeit beitreten oder verlassen. Lausche auf `player:join` und `player:leave` Events.',
|
|
746
|
+
},
|
|
747
|
+
codeTemplate: '// Handle players joining and leaving\n',
|
|
748
|
+
codeSolution: '// Listen for new players\nplayers.events.on("player:join", (player) => {\n // Create a character entity for the new player\n const entityId = engine.world.createEntity();\n engine.world.addComponent(entityId, "Transform", {\n x: 100 + player.index * 150, y: 300\n });\n player.entityId = entityId;\n});\n\n// Handle player leaving\nplayers.events.on("player:leave", (player) => {\n if (player.entityId != null) {\n engine.world.removeEntity(player.entityId);\n }\n});\n\n// Manual join with gamepad\nplayers.join({\n index: 2,\n name: "Player 3",\n color: { r: 0, g: 0, b: 1, a: 1 },\n inputDevice: "gamepad",\n gamepadIndex: 2,\n});',
|
|
749
|
+
codeValidation: {
|
|
750
|
+
containsAll: ['player:join', 'player:leave', 'createEntity'],
|
|
751
|
+
},
|
|
752
|
+
hint: {
|
|
753
|
+
en: 'players.events.on("player:join", (player) => { ... }) and players.join({ index, name, color, inputDevice })',
|
|
754
|
+
pl: 'players.events.on("player:join", (player) => { ... }) i players.join({ index, name, color, inputDevice })',
|
|
755
|
+
de: 'players.events.on("player:join", (player) => { ... }) und players.join({ index, name, color, inputDevice })',
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
// --- S7: Vibration ---
|
|
759
|
+
{
|
|
760
|
+
id: 'gamepad-vibration',
|
|
761
|
+
type: 'code',
|
|
762
|
+
title: {
|
|
763
|
+
en: 'Gamepad Vibration 🎮💥',
|
|
764
|
+
pl: 'Wibracja gamepada 🎮💥',
|
|
765
|
+
de: 'Gamepad-Vibration 🎮💥',
|
|
766
|
+
},
|
|
767
|
+
content: {
|
|
768
|
+
en: 'Make gamepads rumble on events like damage or explosions using the `vibrate` method.',
|
|
769
|
+
pl: 'Spraw, aby gamepady zaczęły wibrować przy zdarzeniach jak obrażenia czy eksplozje, używając metody `vibrate`.',
|
|
770
|
+
de: 'Lass Gamepads bei Events wie Schaden oder Explosionen vibrieren mit der `vibrate`-Methode.',
|
|
771
|
+
},
|
|
772
|
+
codeTemplate: '// Vibrate a player\'s gamepad\n',
|
|
773
|
+
codeSolution: '// Vibrate player 1\'s gamepad for 200ms\nengine.input.vibrate(\n 1, // player index\n 200, // duration (ms)\n 0.5, // weak motor magnitude (0-1)\n 1.0 // strong motor magnitude (0-1)\n);',
|
|
774
|
+
codeValidation: {
|
|
775
|
+
containsAll: ['vibrate'],
|
|
776
|
+
},
|
|
777
|
+
hint: {
|
|
778
|
+
en: 'engine.input.vibrate(playerIndex, duration, weakMagnitude, strongMagnitude)',
|
|
779
|
+
pl: 'engine.input.vibrate(indeksGracza, czas, siłaSłaba, siłaSilna)',
|
|
780
|
+
de: 'engine.input.vibrate(spielerIndex, dauer, schwachStärke, starkStärke)',
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
// --- S8: Congratulations ---
|
|
784
|
+
{
|
|
785
|
+
id: 'mp-congratulations',
|
|
786
|
+
type: 'text',
|
|
787
|
+
title: {
|
|
788
|
+
en: 'Congratulations! 🎉',
|
|
789
|
+
pl: 'Gratulacje! 🎉',
|
|
790
|
+
de: 'Herzlichen Glückwunsch! 🎉',
|
|
791
|
+
},
|
|
792
|
+
content: {
|
|
793
|
+
en: '🏆 You learned:\n• `PlayerManager` for up to 12 players\n• `setupLocal(count)` for quick setup\n• Per-player `getAction(name, playerIndex)`\n• Action bindings for keyboard + gamepad\n• `SplitScreenManager` with 7 screen modes\n• Drop-in / drop-out with events\n• Gamepad vibration for tactile feedback\n\nYour games are now multiplayer-ready! 🎮🎮🎮🎮',
|
|
794
|
+
pl: '🏆 Nauczyłeś się:\n• `PlayerManager` do 12 graczy\n• `setupLocal(count)` do szybkiej konfiguracji\n• Per-gracz `getAction(name, playerIndex)`\n• Bindowanie akcji dla klawiatury + gamepada\n• `SplitScreenManager` z 7 trybami ekranu\n• Dynamiczne dołączanie/odłączanie ze zdarzeniami\n• Wibracja gamepada dla taktylnego feedbacku\n\nTwoje gry są teraz gotowe na multiplayer! 🎮🎮🎮🎮',
|
|
795
|
+
de: '🏆 Du hast gelernt:\n• `PlayerManager` für bis zu 12 Spieler\n• `setupLocal(count)` für schnelles Setup\n• Pro-Spieler `getAction(name, spielerIndex)`\n• Aktionsbindungen für Tastatur + Gamepad\n• `SplitScreenManager` mit 7 Bildschirmmodi\n• Drop-in / Drop-out mit Events\n• Gamepad-Vibration für taktiles Feedback\n\nDeine Spiele sind jetzt Multiplayer-bereit! 🎮🎮🎮🎮',
|
|
796
|
+
},
|
|
797
|
+
tooltipPosition: 'center',
|
|
798
|
+
},
|
|
799
|
+
],
|
|
800
|
+
};
|
|
801
|
+
/* ── Convenience collection ───────────────────────────────────── */
|
|
802
|
+
function getTutorials_T05_T08() {
|
|
803
|
+
return [
|
|
804
|
+
TUTORIAL_ANIMATIONS,
|
|
805
|
+
TUTORIAL_TILEMAPS,
|
|
806
|
+
TUTORIAL_VISUAL_SCRIPTING,
|
|
807
|
+
TUTORIAL_LOCAL_MULTIPLAYER,
|
|
808
|
+
];
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
exports.TUTORIAL_ANIMATIONS = TUTORIAL_ANIMATIONS;
|
|
812
|
+
exports.TUTORIAL_LOCAL_MULTIPLAYER = TUTORIAL_LOCAL_MULTIPLAYER;
|
|
813
|
+
exports.TUTORIAL_TILEMAPS = TUTORIAL_TILEMAPS;
|
|
814
|
+
exports.TUTORIAL_VISUAL_SCRIPTING = TUTORIAL_VISUAL_SCRIPTING;
|
|
815
|
+
exports.getTutorials_T05_T08 = getTutorials_T05_T08;
|
|
816
|
+
//# sourceMappingURL=Tutorials_T05_T08.js.map
|