@nice2dev/game-engine 1.3.14 → 1.3.16

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.
Files changed (434) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/accessibility/Accessibility.js +152 -165
  3. package/dist/cjs/ai/AI.js +292 -294
  4. package/dist/cjs/ai/BehaviorTree.js +1029 -1113
  5. package/dist/cjs/ai/StateMachine.js +694 -756
  6. package/dist/cjs/animation/Animation.js +232 -241
  7. package/dist/cjs/audio/AudioAdvanced.js +221 -236
  8. package/dist/cjs/audio/AudioBridge.js +441 -435
  9. package/dist/cjs/audio/AudioManager.js +242 -259
  10. package/dist/cjs/build-cloud/BuildOrchestration.js +1059 -1098
  11. package/dist/cjs/build-cloud/GodotBuildCloud.js +641 -670
  12. package/dist/cjs/build-cloud/UnityBuildCloud.js +563 -610
  13. package/dist/cjs/build-cloud/UnrealBuildCloud.js +610 -635
  14. package/dist/cjs/core/EventBus.js +51 -56
  15. package/dist/cjs/core/GameClock.js +62 -66
  16. package/dist/cjs/core/GameConfig.js +72 -79
  17. package/dist/cjs/core/GameLoop.js +80 -89
  18. package/dist/cjs/core/ServiceLocator.js +61 -65
  19. package/dist/cjs/core/Validation.js +72 -82
  20. package/dist/cjs/core/math.js +108 -112
  21. package/dist/cjs/devtools/DevTools.js +542 -563
  22. package/dist/cjs/devtools/DeveloperExperience.js +521 -559
  23. package/dist/cjs/devtools/GameplayAnalytics.js +636 -646
  24. package/dist/cjs/dialogue/DialogueSystem.js +984 -986
  25. package/dist/cjs/docs/DocGenerator.js +339 -364
  26. package/dist/cjs/ecs/World.js +355 -371
  27. package/dist/cjs/editor/AchievementEditor.js +580 -636
  28. package/dist/cjs/editor/AdvancedEditor.js +184 -191
  29. package/dist/cjs/editor/AnimationRetargeting.js +696 -741
  30. package/dist/cjs/editor/AssetBrowser.js +1072 -1160
  31. package/dist/cjs/editor/AssetManager.js +187 -192
  32. package/dist/cjs/editor/ConsolePro.js +971 -1061
  33. package/dist/cjs/editor/CraftingEditor.js +680 -730
  34. package/dist/cjs/editor/DebugTools.js +187 -185
  35. package/dist/cjs/editor/DialogueSystem.js +844 -901
  36. package/dist/cjs/editor/LeaderboardSystem.js +429 -483
  37. package/dist/cjs/editor/NiceGameEditor.js +1903 -1201
  38. package/dist/cjs/editor/PrefabSystem.js +772 -838
  39. package/dist/cjs/editor/ProfilerPanel.js +649 -700
  40. package/dist/cjs/editor/QuestEditor.js +792 -839
  41. package/dist/cjs/editor/ReplaySystem.js +585 -634
  42. package/dist/cjs/editor/SceneEditor.js +176 -200
  43. package/dist/cjs/editor/ScreenshotMode.js +621 -688
  44. package/dist/cjs/editor/ShaderGraph.js +1556 -1582
  45. package/dist/cjs/editor/TimelineEditor.js +715 -778
  46. package/dist/cjs/editor/UndoRedoPro.js +830 -904
  47. package/dist/cjs/editor/VRARMode.js +582 -645
  48. package/dist/cjs/engine/NiceGameEngine.js +141 -164
  49. package/dist/cjs/engine/SaveSystem.js +441 -495
  50. package/dist/cjs/enterprise/Enterprise.js +254 -261
  51. package/dist/cjs/export/BevyExporter.js +927 -967
  52. package/dist/cjs/export/CocosExporter.js +644 -673
  53. package/dist/cjs/export/Construct3Exporter.js +783 -794
  54. package/dist/cjs/export/DefoldExporter.js +1028 -1069
  55. package/dist/cjs/export/GDevelopExporter.js +674 -708
  56. package/dist/cjs/export/GameMakerExporter.js +791 -805
  57. package/dist/cjs/export/GodotExporter.js +1003 -1045
  58. package/dist/cjs/export/MinecraftBedrockExporter.js +573 -578
  59. package/dist/cjs/export/MonoGameExporter.js +1265 -1293
  60. package/dist/cjs/export/Pico8Exporter.js +766 -812
  61. package/dist/cjs/export/PlatformExporter.js +188 -206
  62. package/dist/cjs/export/RPGMakerExporter.js +860 -879
  63. package/dist/cjs/export/RobloxExporter.js +883 -919
  64. package/dist/cjs/export/Solar2DExporter.js +1218 -1256
  65. package/dist/cjs/export/ThreeJSExporter.js +1006 -1073
  66. package/dist/cjs/export/Tic80Exporter.js +1210 -1267
  67. package/dist/cjs/export/UnityExporter.js +1116 -1131
  68. package/dist/cjs/export/UnrealExporter.js +889 -919
  69. package/dist/cjs/export/WebExporter.js +931 -970
  70. package/dist/cjs/export/index.js +42 -65
  71. package/dist/cjs/godot-integration/GodotAssetLibrary.js +659 -692
  72. package/dist/cjs/godot-integration/GodotImport.js +929 -1027
  73. package/dist/cjs/godot-integration/GodotLiveLink.js +915 -945
  74. package/dist/cjs/godot-integration/components/GodotProjectBrowser.js +911 -611
  75. package/dist/cjs/i18n/I18n.js +860 -900
  76. package/dist/cjs/i18n/useTranslation.js +84 -89
  77. package/dist/cjs/import/AsepriteImporter.js +658 -716
  78. package/dist/cjs/import/DragonBonesImporter.js +437 -461
  79. package/dist/cjs/import/GameMakerImporter.js +511 -521
  80. package/dist/cjs/import/GodotSceneImporter.js +788 -822
  81. package/dist/cjs/import/LDtkImporter.js +436 -454
  82. package/dist/cjs/import/Live2DImporter.js +497 -518
  83. package/dist/cjs/import/NdgFormat.js +424 -457
  84. package/dist/cjs/import/OgmoImporter.js +466 -493
  85. package/dist/cjs/import/RPGMakerImporter.js +451 -477
  86. package/dist/cjs/import/SceneImporter.js +378 -423
  87. package/dist/cjs/import/SpineImporter.js +511 -546
  88. package/dist/cjs/import/SpriterImporter.js +590 -613
  89. package/dist/cjs/import/TiledMapImporter.js +811 -846
  90. package/dist/cjs/import/UnitySceneImporter.js +687 -703
  91. package/dist/cjs/import/index.js +206 -251
  92. package/dist/cjs/index.js +275 -278
  93. package/dist/cjs/input/GamepadNavigation.js +185 -205
  94. package/dist/cjs/input/InputManager.js +397 -421
  95. package/dist/cjs/input/useGamepads.js +70 -81
  96. package/dist/cjs/integration/IconSprite.js +129 -256
  97. package/dist/cjs/inventory/InventorySystem.js +920 -995
  98. package/dist/cjs/kids/KidMode.js +997 -1022
  99. package/dist/cjs/kids/KidTools.js +570 -594
  100. package/dist/cjs/monetization/Monetization.js +170 -177
  101. package/dist/cjs/multiplayer/LocalMultiplayer.js +287 -287
  102. package/dist/cjs/multiplayer/MiniGameTypes.js +49 -59
  103. package/dist/cjs/native-engine/AnimationSystem.js +731 -806
  104. package/dist/cjs/native-engine/AssetPipeline.js +454 -515
  105. package/dist/cjs/native-engine/AudioEngine.js +763 -804
  106. package/dist/cjs/native-engine/InputSystem.js +1075 -1145
  107. package/dist/cjs/native-engine/NetworkingSystem.js +733 -793
  108. package/dist/cjs/native-engine/PhysicsEngine.js +583 -607
  109. package/dist/cjs/native-engine/RenderingEngine.js +302 -350
  110. package/dist/cjs/native-engine/SceneGraph.js +769 -808
  111. package/dist/cjs/network/MultiplayerTransport.js +97 -132
  112. package/dist/cjs/network/Networking.js +549 -564
  113. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AbortController.js +21 -29
  114. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js +40 -48
  115. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js +35 -43
  116. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js +10 -15
  117. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Errors.js +103 -135
  118. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js +131 -158
  119. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js +39 -53
  120. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js +5 -8
  121. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpClient.js +40 -48
  122. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js +494 -572
  123. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnection.js +826 -953
  124. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js +125 -146
  125. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js +13 -23
  126. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ILogger.js +11 -25
  127. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ITransport.js +13 -24
  128. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js +108 -121
  129. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Loggers.js +10 -14
  130. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js +150 -185
  131. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js +158 -196
  132. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js +90 -105
  133. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Subject.js +30 -35
  134. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js +16 -21
  135. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/Utils.js +215 -248
  136. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js +135 -157
  137. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js +76 -85
  138. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/index.js +24 -27
  139. package/dist/cjs/node_modules/@microsoft/signalr/dist/esm/pkg-version.js +3 -4
  140. package/dist/cjs/pathfinding/Pathfinding.js +245 -263
  141. package/dist/cjs/performance/AssetStreaming.js +561 -635
  142. package/dist/cjs/performance/BenchmarkSuite.js +283 -311
  143. package/dist/cjs/performance/DeltaCompression.js +467 -526
  144. package/dist/cjs/performance/DeterministicPhysics.js +450 -498
  145. package/dist/cjs/performance/ECSOptimization.js +644 -695
  146. package/dist/cjs/performance/GameSaveSystem.js +509 -556
  147. package/dist/cjs/performance/HotReload.js +447 -500
  148. package/dist/cjs/performance/InputRecording.js +511 -561
  149. package/dist/cjs/performance/InterestManagement.js +453 -500
  150. package/dist/cjs/performance/LocalizationRuntime.js +376 -423
  151. package/dist/cjs/performance/MemoryManagement.js +410 -470
  152. package/dist/cjs/performance/ModSupport.js +445 -496
  153. package/dist/cjs/performance/MultiThreadedPhysics.js +400 -443
  154. package/dist/cjs/performance/NetworkPrediction.js +424 -482
  155. package/dist/cjs/performance/ObjectPooling.js +569 -617
  156. package/dist/cjs/performance/Performance.js +174 -190
  157. package/dist/cjs/performance/PerformanceAdvanced.js +614 -637
  158. package/dist/cjs/performance/WebGPURenderer.js +656 -683
  159. package/dist/cjs/physics/PhysicsAdvanced.js +345 -379
  160. package/dist/cjs/physics/PhysicsEngine2D.js +391 -427
  161. package/dist/cjs/plugins/PluginSDK.js +432 -466
  162. package/dist/cjs/plugins/PluginTestKit.js +307 -330
  163. package/dist/cjs/procedural/Procedural.js +243 -254
  164. package/dist/cjs/procedural/WorldBuilding.js +297 -314
  165. package/dist/cjs/quest/QuestSystem.js +975 -932
  166. package/dist/cjs/release/MobileExport.js +157 -163
  167. package/dist/cjs/release/Release.js +225 -238
  168. package/dist/cjs/rendering/Camera2D.js +121 -124
  169. package/dist/cjs/rendering/Renderer2D.js +321 -335
  170. package/dist/cjs/rendering/WebGPURenderPipeline.js +632 -651
  171. package/dist/cjs/runtime3d/Runtime3D.js +359 -378
  172. package/dist/cjs/runtime3d/SceneEditor3D.js +252 -263
  173. package/dist/cjs/scene/SceneManager.js +177 -193
  174. package/dist/cjs/scripting/GraphToAST.js +574 -547
  175. package/dist/cjs/scripting/LanguageExporter.js +254 -279
  176. package/dist/cjs/scripting/NodeGraph.js +546 -570
  177. package/dist/cjs/scripting/ScriptAST.js +31 -39
  178. package/dist/cjs/scripting/VisualScripting2.js +1016 -1065
  179. package/dist/cjs/scripting/exporters/CSharpExporter.js +464 -496
  180. package/dist/cjs/scripting/exporters/GDScriptExporter.js +390 -442
  181. package/dist/cjs/scripting/exporters/LuaExporter.js +406 -447
  182. package/dist/cjs/scripting/exporters/PythonExporter.js +484 -549
  183. package/dist/cjs/scripting/exporters/RustExporter.js +459 -512
  184. package/dist/cjs/scripting/exporters/TypeScriptExporter.js +505 -556
  185. package/dist/cjs/social/Social.js +72 -80
  186. package/dist/cjs/systems/LightingSystem.js +844 -931
  187. package/dist/cjs/systems/ParticleSystem2.js +1447 -1451
  188. package/dist/cjs/systems/PhysicsDebugSystem.js +1070 -1141
  189. package/dist/cjs/systems/TerrainSystem.js +985 -1098
  190. package/dist/cjs/templates/ActionTemplates.js +296 -309
  191. package/dist/cjs/templates/FightingTemplate.js +417 -463
  192. package/dist/cjs/templates/MetroidvaniaTemplate.js +353 -405
  193. package/dist/cjs/templates/PartyTemplates.js +190 -202
  194. package/dist/cjs/templates/PuzzleTemplates.js +245 -261
  195. package/dist/cjs/templates/RPGTemplates.js +160 -178
  196. package/dist/cjs/templates/SportsTemplates.js +237 -250
  197. package/dist/cjs/templates/StrategyTemplates.js +143 -153
  198. package/dist/cjs/templates/SurvivalTemplate.js +336 -380
  199. package/dist/cjs/templates/WaveDefense.js +499 -526
  200. package/dist/cjs/tilemap/Tilemap.js +207 -214
  201. package/dist/cjs/tutorials/TutorialBranching.js +396 -417
  202. package/dist/cjs/tutorials/TutorialEngine.js +888 -931
  203. package/dist/cjs/tutorials/TutorialOverlay.js +602 -640
  204. package/dist/cjs/tutorials/content/Tutorials_T05_T08.js +787 -809
  205. package/dist/cjs/tutorials/content/Tutorials_T09_T11.js +736 -756
  206. package/dist/cjs/tutorials/content/Tutorials_T12_T15.js +754 -778
  207. package/dist/cjs/ui/GameUI.js +295 -312
  208. package/dist/cjs/unity-integration/UnityAssetStore.js +700 -741
  209. package/dist/cjs/unity-integration/UnityImport.js +1066 -1176
  210. package/dist/cjs/unity-integration/UnityLiveLink.js +934 -981
  211. package/dist/cjs/unity-integration/components/UnityAssetStoreBrowser.js +1233 -757
  212. package/dist/cjs/unity-integration/components/UnityProjectBrowser.js +1240 -768
  213. package/dist/cjs/unreal-integration/UnrealImport.js +391 -412
  214. package/dist/cjs/unreal-integration/UnrealLiveLink.js +1102 -1137
  215. package/dist/cjs/unreal-integration/UnrealMarketplace.js +436 -473
  216. package/dist/cjs/unreal-integration/components/UnrealProjectBrowser.js +1150 -767
  217. package/dist/cjs/xr/ARVR.js +167 -175
  218. package/dist/esm/accessibility/Accessibility.js +160 -164
  219. package/dist/esm/ai/AI.js +310 -293
  220. package/dist/esm/ai/BehaviorTree.js +1057 -1112
  221. package/dist/esm/ai/StateMachine.js +709 -755
  222. package/dist/esm/animation/Animation.js +237 -240
  223. package/dist/esm/audio/AudioAdvanced.js +239 -235
  224. package/dist/esm/audio/AudioBridge.js +448 -434
  225. package/dist/esm/audio/AudioManager.js +243 -258
  226. package/dist/esm/build-cloud/BuildOrchestration.js +1071 -1097
  227. package/dist/esm/build-cloud/GodotBuildCloud.js +647 -669
  228. package/dist/esm/build-cloud/UnityBuildCloud.js +571 -609
  229. package/dist/esm/build-cloud/UnrealBuildCloud.js +615 -634
  230. package/dist/esm/core/EventBus.js +52 -55
  231. package/dist/esm/core/GameClock.js +63 -65
  232. package/dist/esm/core/GameConfig.js +77 -78
  233. package/dist/esm/core/GameLoop.js +81 -88
  234. package/dist/esm/core/ServiceLocator.js +63 -64
  235. package/dist/esm/core/Validation.js +82 -81
  236. package/dist/esm/core/math.js +109 -111
  237. package/dist/esm/devtools/DevTools.js +546 -562
  238. package/dist/esm/devtools/DeveloperExperience.js +535 -558
  239. package/dist/esm/devtools/GameplayAnalytics.js +647 -645
  240. package/dist/esm/dialogue/DialogueSystem.js +998 -985
  241. package/dist/esm/docs/DocGenerator.js +342 -363
  242. package/dist/esm/ecs/World.js +358 -370
  243. package/dist/esm/editor/AchievementEditor.js +584 -635
  244. package/dist/esm/editor/AdvancedEditor.js +191 -190
  245. package/dist/esm/editor/AnimationRetargeting.js +700 -740
  246. package/dist/esm/editor/AssetBrowser.js +1078 -1159
  247. package/dist/esm/editor/AssetManager.js +188 -191
  248. package/dist/esm/editor/ConsolePro.js +977 -1060
  249. package/dist/esm/editor/CraftingEditor.js +684 -729
  250. package/dist/esm/editor/DebugTools.js +194 -184
  251. package/dist/esm/editor/DialogueSystem.js +849 -900
  252. package/dist/esm/editor/LeaderboardSystem.js +433 -482
  253. package/dist/esm/editor/NiceGameEditor.js +1908 -1200
  254. package/dist/esm/editor/PrefabSystem.js +777 -837
  255. package/dist/esm/editor/ProfilerPanel.js +654 -699
  256. package/dist/esm/editor/QuestEditor.js +795 -838
  257. package/dist/esm/editor/ReplaySystem.js +591 -633
  258. package/dist/esm/editor/SceneEditor.js +189 -199
  259. package/dist/esm/editor/ScreenshotMode.js +628 -687
  260. package/dist/esm/editor/ShaderGraph.js +1565 -1581
  261. package/dist/esm/editor/TimelineEditor.js +733 -777
  262. package/dist/esm/editor/UndoRedoPro.js +835 -903
  263. package/dist/esm/editor/VRARMode.js +586 -644
  264. package/dist/esm/engine/NiceGameEngine.js +142 -163
  265. package/dist/esm/engine/SaveSystem.js +447 -494
  266. package/dist/esm/enterprise/Enterprise.js +265 -260
  267. package/dist/esm/export/BevyExporter.js +929 -966
  268. package/dist/esm/export/CocosExporter.js +646 -672
  269. package/dist/esm/export/Construct3Exporter.js +785 -793
  270. package/dist/esm/export/DefoldExporter.js +1030 -1068
  271. package/dist/esm/export/GDevelopExporter.js +676 -707
  272. package/dist/esm/export/GameMakerExporter.js +793 -804
  273. package/dist/esm/export/GodotExporter.js +1004 -1044
  274. package/dist/esm/export/MinecraftBedrockExporter.js +575 -577
  275. package/dist/esm/export/MonoGameExporter.js +1267 -1292
  276. package/dist/esm/export/Pico8Exporter.js +768 -811
  277. package/dist/esm/export/PlatformExporter.js +193 -205
  278. package/dist/esm/export/RPGMakerExporter.js +862 -878
  279. package/dist/esm/export/RobloxExporter.js +885 -918
  280. package/dist/esm/export/Solar2DExporter.js +1220 -1255
  281. package/dist/esm/export/ThreeJSExporter.js +1007 -1072
  282. package/dist/esm/export/Tic80Exporter.js +1212 -1266
  283. package/dist/esm/export/UnityExporter.js +1117 -1130
  284. package/dist/esm/export/UnrealExporter.js +891 -918
  285. package/dist/esm/export/WebExporter.js +933 -969
  286. package/dist/esm/export/index.js +86 -71
  287. package/dist/esm/godot-integration/GodotAssetLibrary.js +663 -691
  288. package/dist/esm/godot-integration/GodotImport.js +935 -1026
  289. package/dist/esm/godot-integration/GodotLiveLink.js +918 -944
  290. package/dist/esm/godot-integration/components/GodotProjectBrowser.js +912 -610
  291. package/dist/esm/i18n/I18n.js +871 -899
  292. package/dist/esm/i18n/useTranslation.js +88 -88
  293. package/dist/esm/import/AsepriteImporter.js +637 -715
  294. package/dist/esm/import/DragonBonesImporter.js +417 -460
  295. package/dist/esm/import/GameMakerImporter.js +491 -520
  296. package/dist/esm/import/GodotSceneImporter.js +767 -821
  297. package/dist/esm/import/LDtkImporter.js +415 -453
  298. package/dist/esm/import/Live2DImporter.js +477 -517
  299. package/dist/esm/import/NdgFormat.js +410 -456
  300. package/dist/esm/import/OgmoImporter.js +446 -492
  301. package/dist/esm/import/RPGMakerImporter.js +431 -476
  302. package/dist/esm/import/SceneImporter.js +385 -422
  303. package/dist/esm/import/SpineImporter.js +491 -545
  304. package/dist/esm/import/SpriterImporter.js +570 -612
  305. package/dist/esm/import/TiledMapImporter.js +790 -845
  306. package/dist/esm/import/UnitySceneImporter.js +666 -702
  307. package/dist/esm/import/index.js +247 -258
  308. package/dist/esm/index.js +1332 -188
  309. package/dist/esm/input/GamepadNavigation.js +187 -204
  310. package/dist/esm/input/InputManager.js +401 -420
  311. package/dist/esm/input/useGamepads.js +72 -80
  312. package/dist/esm/integration/IconSprite.js +143 -255
  313. package/dist/esm/inventory/InventorySystem.js +925 -994
  314. package/dist/esm/kids/KidMode.js +1003 -1021
  315. package/dist/esm/kids/KidTools.js +573 -593
  316. package/dist/esm/monetization/Monetization.js +180 -176
  317. package/dist/esm/multiplayer/LocalMultiplayer.js +290 -286
  318. package/dist/esm/multiplayer/MiniGameTypes.js +58 -58
  319. package/dist/esm/native-engine/AnimationSystem.js +735 -805
  320. package/dist/esm/native-engine/AssetPipeline.js +456 -514
  321. package/dist/esm/native-engine/AudioEngine.js +765 -803
  322. package/dist/esm/native-engine/InputSystem.js +1079 -1144
  323. package/dist/esm/native-engine/NetworkingSystem.js +740 -792
  324. package/dist/esm/native-engine/PhysicsEngine.js +585 -606
  325. package/dist/esm/native-engine/RenderingEngine.js +304 -349
  326. package/dist/esm/native-engine/SceneGraph.js +773 -807
  327. package/dist/esm/network/MultiplayerTransport.js +99 -131
  328. package/dist/esm/network/Networking.js +556 -563
  329. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AbortController.js +22 -28
  330. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/AccessTokenHttpClient.js +41 -47
  331. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultHttpClient.js +36 -42
  332. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/DefaultReconnectPolicy.js +11 -14
  333. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Errors.js +111 -134
  334. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/FetchHttpClient.js +132 -157
  335. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HandshakeProtocol.js +40 -52
  336. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HeaderNames.js +6 -7
  337. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpClient.js +42 -47
  338. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HttpConnection.js +496 -571
  339. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnection.js +828 -952
  340. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/HubConnectionBuilder.js +126 -145
  341. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/IHubProtocol.js +14 -23
  342. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ILogger.js +12 -25
  343. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ITransport.js +15 -24
  344. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/JsonHubProtocol.js +109 -120
  345. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Loggers.js +11 -13
  346. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/LongPollingTransport.js +151 -184
  347. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/MessageBuffer.js +159 -195
  348. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/ServerSentEventsTransport.js +91 -104
  349. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Subject.js +31 -34
  350. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/TextMessageFormat.js +17 -20
  351. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/Utils.js +230 -248
  352. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/WebSocketTransport.js +136 -156
  353. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/XhrHttpClient.js +77 -84
  354. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/index.js +31 -12
  355. package/dist/esm/node_modules/@microsoft/signalr/dist/esm/pkg-version.js +4 -3
  356. package/dist/esm/pathfinding/Pathfinding.js +249 -262
  357. package/dist/esm/performance/AssetStreaming.js +567 -634
  358. package/dist/esm/performance/BenchmarkSuite.js +285 -310
  359. package/dist/esm/performance/DeltaCompression.js +478 -525
  360. package/dist/esm/performance/DeterministicPhysics.js +479 -497
  361. package/dist/esm/performance/ECSOptimization.js +653 -694
  362. package/dist/esm/performance/GameSaveSystem.js +515 -555
  363. package/dist/esm/performance/HotReload.js +454 -499
  364. package/dist/esm/performance/InputRecording.js +520 -560
  365. package/dist/esm/performance/InterestManagement.js +460 -499
  366. package/dist/esm/performance/LocalizationRuntime.js +382 -422
  367. package/dist/esm/performance/MemoryManagement.js +415 -469
  368. package/dist/esm/performance/ModSupport.js +455 -495
  369. package/dist/esm/performance/MultiThreadedPhysics.js +408 -442
  370. package/dist/esm/performance/NetworkPrediction.js +436 -481
  371. package/dist/esm/performance/ObjectPooling.js +582 -616
  372. package/dist/esm/performance/Performance.js +182 -189
  373. package/dist/esm/performance/PerformanceAdvanced.js +621 -636
  374. package/dist/esm/performance/WebGPURenderer.js +660 -682
  375. package/dist/esm/physics/PhysicsAdvanced.js +359 -378
  376. package/dist/esm/physics/PhysicsEngine2D.js +393 -426
  377. package/dist/esm/plugins/PluginSDK.js +435 -465
  378. package/dist/esm/plugins/PluginTestKit.js +315 -329
  379. package/dist/esm/procedural/Procedural.js +248 -253
  380. package/dist/esm/procedural/WorldBuilding.js +316 -313
  381. package/dist/esm/quest/QuestSystem.js +982 -931
  382. package/dist/esm/release/MobileExport.js +163 -162
  383. package/dist/esm/release/Release.js +234 -237
  384. package/dist/esm/rendering/Camera2D.js +122 -123
  385. package/dist/esm/rendering/Renderer2D.js +323 -334
  386. package/dist/esm/rendering/WebGPURenderPipeline.js +647 -650
  387. package/dist/esm/runtime3d/Runtime3D.js +368 -377
  388. package/dist/esm/runtime3d/SceneEditor3D.js +268 -262
  389. package/dist/esm/scene/SceneManager.js +178 -192
  390. package/dist/esm/scripting/GraphToAST.js +576 -546
  391. package/dist/esm/scripting/LanguageExporter.js +263 -278
  392. package/dist/esm/scripting/NodeGraph.js +550 -569
  393. package/dist/esm/scripting/ScriptAST.js +45 -38
  394. package/dist/esm/scripting/VisualScripting2.js +1025 -1064
  395. package/dist/esm/scripting/exporters/CSharpExporter.js +465 -495
  396. package/dist/esm/scripting/exporters/GDScriptExporter.js +391 -441
  397. package/dist/esm/scripting/exporters/LuaExporter.js +407 -446
  398. package/dist/esm/scripting/exporters/PythonExporter.js +485 -548
  399. package/dist/esm/scripting/exporters/RustExporter.js +460 -511
  400. package/dist/esm/scripting/exporters/TypeScriptExporter.js +506 -555
  401. package/dist/esm/social/Social.js +77 -79
  402. package/dist/esm/systems/LightingSystem.js +855 -930
  403. package/dist/esm/systems/ParticleSystem2.js +1453 -1450
  404. package/dist/esm/systems/PhysicsDebugSystem.js +1078 -1140
  405. package/dist/esm/systems/TerrainSystem.js +996 -1097
  406. package/dist/esm/templates/ActionTemplates.js +307 -308
  407. package/dist/esm/templates/FightingTemplate.js +439 -462
  408. package/dist/esm/templates/MetroidvaniaTemplate.js +391 -404
  409. package/dist/esm/templates/PartyTemplates.js +206 -201
  410. package/dist/esm/templates/PuzzleTemplates.js +260 -260
  411. package/dist/esm/templates/RPGTemplates.js +172 -177
  412. package/dist/esm/templates/SportsTemplates.js +251 -249
  413. package/dist/esm/templates/StrategyTemplates.js +158 -152
  414. package/dist/esm/templates/SurvivalTemplate.js +367 -379
  415. package/dist/esm/templates/WaveDefense.js +501 -525
  416. package/dist/esm/tilemap/Tilemap.js +209 -213
  417. package/dist/esm/tutorials/TutorialBranching.js +399 -416
  418. package/dist/esm/tutorials/TutorialEngine.js +893 -930
  419. package/dist/esm/tutorials/TutorialOverlay.js +603 -639
  420. package/dist/esm/tutorials/content/Tutorials_T05_T08.js +792 -808
  421. package/dist/esm/tutorials/content/Tutorials_T09_T11.js +740 -755
  422. package/dist/esm/tutorials/content/Tutorials_T12_T15.js +759 -777
  423. package/dist/esm/ui/GameUI.js +296 -311
  424. package/dist/esm/unity-integration/UnityAssetStore.js +704 -740
  425. package/dist/esm/unity-integration/UnityImport.js +1071 -1175
  426. package/dist/esm/unity-integration/UnityLiveLink.js +938 -980
  427. package/dist/esm/unity-integration/components/UnityAssetStoreBrowser.js +1234 -756
  428. package/dist/esm/unity-integration/components/UnityProjectBrowser.js +1241 -767
  429. package/dist/esm/unreal-integration/UnrealImport.js +395 -411
  430. package/dist/esm/unreal-integration/UnrealLiveLink.js +1105 -1136
  431. package/dist/esm/unreal-integration/UnrealMarketplace.js +442 -472
  432. package/dist/esm/unreal-integration/components/UnrealProjectBrowser.js +1151 -766
  433. package/dist/esm/xr/ARVR.js +181 -174
  434. package/package.json +7 -12
@@ -1,1330 +1,1305 @@
1
- /* ────────────────────────────────────────────────────────────────
2
- MonoGame/FNA Exporter — .NET Game Framework
3
-
4
- Exports NiceToDev game projects to MonoGame 3.8+ / FNA:
5
- - Content pipeline integration
6
- - C# classes for entities/components
7
- - Game states and screens
8
- - SpriteBatch rendering
9
- - Content.mgcb generation
10
- ──────────────────────────────────────────────────────────────── */
11
1
  const DEFAULT_MONOGAME_CONFIG = {
12
- outputPath: 'monogame_export',
13
- assetPath: 'Content',
14
- platform: 'pc',
15
- framework: 'monogame',
16
- monogameVersion: '3.8.2',
17
- targetPlatform: 'DesktopGL',
18
- extendedPipeline: true,
19
- designTimeContent: true,
20
- useECS: true,
21
- useNez: false,
22
- useTilemaps: true,
23
- namespace: 'MyGame',
24
- solutionName: 'MyGame',
2
+ outputPath: "monogame_export",
3
+ assetPath: "Content",
4
+ platform: "pc",
5
+ framework: "monogame",
6
+ monogameVersion: "3.8.2",
7
+ targetPlatform: "DesktopGL",
8
+ extendedPipeline: true,
9
+ designTimeContent: true,
10
+ useECS: true,
11
+ useNez: false,
12
+ useTilemaps: true,
13
+ namespace: "MyGame",
14
+ solutionName: "MyGame"
25
15
  };
26
- /* ══════════════════════════════════════════════════════════════
27
- C# CODE GENERATION
28
- ══════════════════════════════════════════════════════════════ */
29
16
  class MonoGameExporter {
30
- constructor(config) {
31
- this.csharpFiles = new Map();
32
- this.contentFiles = [];
33
- this.assets = [];
34
- this.config = { ...DEFAULT_MONOGAME_CONFIG, ...config };
17
+ constructor(config) {
18
+ this.csharpFiles = /* @__PURE__ */ new Map();
19
+ this.contentFiles = [];
20
+ this.assets = [];
21
+ this.config = { ...DEFAULT_MONOGAME_CONFIG, ...config };
22
+ }
23
+ /** Export game project to MonoGame */
24
+ async export(project) {
25
+ const startTime = performance.now();
26
+ try {
27
+ if (project.name) {
28
+ this.config.namespace = this.toPascalCase(project.name);
29
+ this.config.solutionName = this.toPascalCase(project.name);
30
+ }
31
+ this.generateSolution(project);
32
+ this.generateCsproj(project);
33
+ this.generateGame1(project);
34
+ this.generateComponents(project);
35
+ this.generateEntities(project);
36
+ if (this.config.useECS) {
37
+ this.generateSystems(project);
38
+ }
39
+ this.generateScreens(project);
40
+ this.generateContentMgcb(project);
41
+ this.collectAssets(project);
42
+ return {
43
+ success: true,
44
+ outputPath: this.config.outputPath,
45
+ files: Array.from(this.csharpFiles.entries()).map(([path, content]) => ({
46
+ path,
47
+ content,
48
+ type: "source"
49
+ })),
50
+ assets: this.assets.map((a) => ({
51
+ path: `${this.config.assetPath}/${a.name}`,
52
+ type: "asset",
53
+ originalPath: a.path
54
+ })),
55
+ stats: {
56
+ duration: performance.now() - startTime,
57
+ fileCount: this.csharpFiles.size,
58
+ assetCount: this.assets.length
59
+ }
60
+ };
61
+ } catch (error) {
62
+ return {
63
+ success: false,
64
+ errors: [error.message]
65
+ };
35
66
  }
36
- /** Export game project to MonoGame */
37
- async export(project) {
38
- const startTime = performance.now();
39
- try {
40
- // Update config with project info
41
- if (project.name) {
42
- this.config.namespace = this.toPascalCase(project.name);
43
- this.config.solutionName = this.toPascalCase(project.name);
44
- }
45
- // Generate solution and project files
46
- this.generateSolution(project);
47
- this.generateCsproj(project);
48
- // Generate main game class
49
- this.generateGame1(project);
50
- // Generate components
51
- this.generateComponents(project);
52
- // Generate entities
53
- this.generateEntities(project);
54
- // Generate systems (if using ECS)
55
- if (this.config.useECS) {
56
- this.generateSystems(project);
67
+ }
68
+ generateSolution(_project) {
69
+ const projectGuid = this.generateGuid();
70
+ const solutionGuid = this.generateGuid();
71
+ const sln = `
72
+ Microsoft Visual Studio Solution File, Format Version 12.00
73
+ # Visual Studio Version 17
74
+ VisualStudioVersion = 17.0.31903.59
75
+ MinimumVisualStudioVersion = 10.0.40219.1
76
+ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "${this.config.solutionName}", "${this.config.solutionName}\\${this.config.solutionName}.csproj", "{${projectGuid}}"
77
+ EndProject
78
+ Global
79
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
80
+ Debug|Any CPU = Debug|Any CPU
81
+ Release|Any CPU = Release|Any CPU
82
+ EndGlobalSection
83
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
84
+ {${projectGuid}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
85
+ {${projectGuid}}.Debug|Any CPU.Build.0 = Debug|Any CPU
86
+ {${projectGuid}}.Release|Any CPU.ActiveCfg = Release|Any CPU
87
+ {${projectGuid}}.Release|Any CPU.Build.0 = Release|Any CPU
88
+ EndGlobalSection
89
+ GlobalSection(SolutionProperties) = preSolution
90
+ HideSolutionNode = FALSE
91
+ EndGlobalSection
92
+ GlobalSection(ExtensibilityGlobals) = postSolution
93
+ SolutionGuid = {${solutionGuid}}
94
+ EndGlobalSection
95
+ EndGlobal
96
+ `;
97
+ this.csharpFiles.set(`${this.config.solutionName}.sln`, sln.trim());
98
+ }
99
+ generateCsproj(_project) {
100
+ const { framework, monogameVersion, targetPlatform, useECS, useNez, extendedPipeline } = this.config;
101
+ const packageRefs = [];
102
+ if (framework === "monogame") {
103
+ packageRefs.push(
104
+ `<PackageReference Include="MonoGame.Framework.${targetPlatform}" Version="${monogameVersion}" />`
105
+ );
106
+ packageRefs.push(
107
+ `<PackageReference Include="MonoGame.Content.Builder.Task" Version="${monogameVersion}" />`
108
+ );
109
+ } else {
110
+ packageRefs.push(`<PackageReference Include="FNA" Version="24.01" />`);
111
+ }
112
+ if (extendedPipeline) {
113
+ packageRefs.push(`<PackageReference Include="MonoGame.Extended" Version="4.0.0" />`);
114
+ packageRefs.push(
115
+ `<PackageReference Include="MonoGame.Extended.Content.Pipeline" Version="4.0.0" />`
116
+ );
117
+ }
118
+ if (useECS) {
119
+ packageRefs.push(`<PackageReference Include="MonoGame.Extended.Entities" Version="4.0.0" />`);
120
+ }
121
+ if (useNez) {
122
+ packageRefs.push(`<PackageReference Include="Nez" Version="1.0.1" />`);
123
+ }
124
+ const csproj = `<Project Sdk="Microsoft.NET.Sdk">
125
+ <PropertyGroup>
126
+ <OutputType>WinExe</OutputType>
127
+ <TargetFramework>net8.0</TargetFramework>
128
+ <RollForward>Major</RollForward>
129
+ <PublishReadyToRun>false</PublishReadyToRun>
130
+ <TieredCompilation>false</TieredCompilation>
131
+ <RootNamespace>${this.config.namespace}</RootNamespace>
132
+ <AssemblyName>${this.config.solutionName}</AssemblyName>
133
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
134
+ </PropertyGroup>
135
+
136
+ <ItemGroup>
137
+ ${packageRefs.map((r) => ` ${r}`).join("\n")}
138
+ </ItemGroup>
139
+
140
+ <ItemGroup>
141
+ <None Remove="**\\*.mgcb" />
142
+ <MonoGameContentReference Include="Content\\Content.mgcb" />
143
+ </ItemGroup>
144
+
145
+ <ItemGroup>
146
+ <Compile Update="**\\*.cs" />
147
+ </ItemGroup>
148
+ </Project>
149
+ `;
150
+ this.csharpFiles.set(`${this.config.solutionName}/${this.config.solutionName}.csproj`, csproj);
151
+ }
152
+ generateGame1(_project) {
153
+ const { namespace, useECS, useNez } = this.config;
154
+ const usings = [
155
+ "using Microsoft.Xna.Framework;",
156
+ "using Microsoft.Xna.Framework.Graphics;",
157
+ "using Microsoft.Xna.Framework.Input;"
158
+ ];
159
+ if (useECS) {
160
+ usings.push("using MonoGame.Extended.Entities;");
161
+ }
162
+ if (useNez) {
163
+ usings.push("using Nez;");
164
+ }
165
+ usings.push(`using ${namespace}.Screens;`);
166
+ usings.push(`using ${namespace}.Components;`);
167
+ const game1 = `${usings.join("\n")}
168
+
169
+ namespace ${namespace}
170
+ {
171
+ public class Game1 : Game
172
+ {
173
+ private GraphicsDeviceManager _graphics;
174
+ private SpriteBatch _spriteBatch;
175
+ private ScreenManager _screenManager;
176
+ ${useECS ? "private World _world;" : ""}
177
+
178
+ public static Game1 Instance { get; private set; }
179
+ public static int ScreenWidth => 1280;
180
+ public static int ScreenHeight => 720;
181
+
182
+ public Game1()
183
+ {
184
+ Instance = this;
185
+ _graphics = new GraphicsDeviceManager(this);
186
+ Content.RootDirectory = "Content";
187
+ IsMouseVisible = true;
188
+
189
+ _graphics.PreferredBackBufferWidth = ScreenWidth;
190
+ _graphics.PreferredBackBufferHeight = ScreenHeight;
191
+ _graphics.ApplyChanges();
192
+ }
193
+
194
+ protected override void Initialize()
195
+ {
196
+ _screenManager = new ScreenManager(this);
197
+ Components.Add(_screenManager);
198
+
199
+ ${useECS ? this.generateECSInitialization() : ""}
200
+
201
+ base.Initialize();
202
+ }
203
+
204
+ protected override void LoadContent()
205
+ {
206
+ _spriteBatch = new SpriteBatch(GraphicsDevice);
207
+
208
+ // Load global content
209
+ Assets.Load(Content);
210
+
211
+ // Start with menu screen
212
+ _screenManager.AddScreen(new MenuScreen());
213
+ }
214
+
215
+ protected override void Update(GameTime gameTime)
216
+ {
217
+ if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
218
+ Keyboard.GetState().IsKeyDown(Keys.Escape))
219
+ {
220
+ Exit();
57
221
  }
58
- // Generate screens/states
59
- this.generateScreens(project);
60
- // Generate content pipeline
61
- this.generateContentMgcb(project);
62
- // Collect assets
63
- this.collectAssets(project);
64
- return {
65
- success: true,
66
- outputPath: this.config.outputPath,
67
- files: Array.from(this.csharpFiles.entries()).map(([path, content]) => ({
68
- path,
69
- content,
70
- type: 'source',
71
- })),
72
- assets: this.assets.map((a) => ({
73
- path: `${this.config.assetPath}/${a.name}`,
74
- type: 'asset',
75
- originalPath: a.path,
76
- })),
77
- stats: {
78
- duration: performance.now() - startTime,
79
- fileCount: this.csharpFiles.size,
80
- assetCount: this.assets.length,
81
- },
82
- };
222
+
223
+ ${useECS ? "_world?.Update(gameTime);" : ""}
224
+
225
+ base.Update(gameTime);
83
226
  }
84
- catch (error) {
85
- return {
86
- success: false,
87
- errors: [error.message],
88
- };
227
+
228
+ protected override void Draw(GameTime gameTime)
229
+ {
230
+ GraphicsDevice.Clear(Color.CornflowerBlue);
231
+
232
+ ${useECS ? "_world?.Draw(gameTime);" : ""}
233
+
234
+ base.Draw(gameTime);
89
235
  }
90
236
  }
91
- generateSolution(_project) {
92
- const projectGuid = this.generateGuid();
93
- const solutionGuid = this.generateGuid();
94
- const sln = `
95
- Microsoft Visual Studio Solution File, Format Version 12.00
96
- # Visual Studio Version 17
97
- VisualStudioVersion = 17.0.31903.59
98
- MinimumVisualStudioVersion = 10.0.40219.1
99
- Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "${this.config.solutionName}", "${this.config.solutionName}\\${this.config.solutionName}.csproj", "{${projectGuid}}"
100
- EndProject
101
- Global
102
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
103
- Debug|Any CPU = Debug|Any CPU
104
- Release|Any CPU = Release|Any CPU
105
- EndGlobalSection
106
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
107
- {${projectGuid}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
108
- {${projectGuid}}.Debug|Any CPU.Build.0 = Debug|Any CPU
109
- {${projectGuid}}.Release|Any CPU.ActiveCfg = Release|Any CPU
110
- {${projectGuid}}.Release|Any CPU.Build.0 = Release|Any CPU
111
- EndGlobalSection
112
- GlobalSection(SolutionProperties) = preSolution
113
- HideSolutionNode = FALSE
114
- EndGlobalSection
115
- GlobalSection(ExtensibilityGlobals) = postSolution
116
- SolutionGuid = {${solutionGuid}}
117
- EndGlobalSection
118
- EndGlobal
237
+ }
119
238
  `;
120
- this.csharpFiles.set(`${this.config.solutionName}.sln`, sln.trim());
239
+ this.csharpFiles.set(`${this.config.solutionName}/Game1.cs`, game1);
240
+ }
241
+ generateECSInitialization() {
242
+ return `
243
+ _world = new WorldBuilder()
244
+ .AddSystem(new MovementSystem())
245
+ .AddSystem(new CollisionSystem())
246
+ .AddSystem(new RenderSystem(_spriteBatch))
247
+ .AddSystem(new AnimationSystem())
248
+ .Build();`;
249
+ }
250
+ generateComponents(_project) {
251
+ const { namespace } = this.config;
252
+ const componentsCs = `using Microsoft.Xna.Framework;
253
+ using Microsoft.Xna.Framework.Graphics;
254
+
255
+ namespace ${namespace}.Components
256
+ {
257
+ // ═══════════════════════════════════════════════════════════════
258
+ // TRANSFORM
259
+ // ═══════════════════════════════════════════════════════════════
260
+
261
+ public class Transform
262
+ {
263
+ public Vector2 Position { get; set; }
264
+ public float Rotation { get; set; }
265
+ public Vector2 Scale { get; set; } = Vector2.One;
266
+ public Vector2 Origin { get; set; }
267
+
268
+ public Transform() { }
269
+
270
+ public Transform(Vector2 position)
271
+ {
272
+ Position = position;
273
+ }
274
+
275
+ public Transform(float x, float y)
276
+ {
277
+ Position = new Vector2(x, y);
278
+ }
279
+
280
+ public Matrix TransformMatrix =>
281
+ Matrix.CreateTranslation(-Origin.X, -Origin.Y, 0) *
282
+ Matrix.CreateScale(Scale.X, Scale.Y, 1) *
283
+ Matrix.CreateRotationZ(Rotation) *
284
+ Matrix.CreateTranslation(Position.X, Position.Y, 0);
121
285
  }
122
- generateCsproj(_project) {
123
- const { framework, monogameVersion, targetPlatform, useECS, useNez, extendedPipeline } = this.config;
124
- const packageRefs = [];
125
- if (framework === 'monogame') {
126
- packageRefs.push(`<PackageReference Include="MonoGame.Framework.${targetPlatform}" Version="${monogameVersion}" />`);
127
- packageRefs.push(`<PackageReference Include="MonoGame.Content.Builder.Task" Version="${monogameVersion}" />`);
286
+
287
+ // ═══════════════════════════════════════════════════════════════
288
+ // SPRITE
289
+ // ═══════════════════════════════════════════════════════════════
290
+
291
+ public class Sprite
292
+ {
293
+ public Texture2D Texture { get; set; }
294
+ public Rectangle? SourceRectangle { get; set; }
295
+ public Color Color { get; set; } = Color.White;
296
+ public SpriteEffects Effects { get; set; } = SpriteEffects.None;
297
+ public float LayerDepth { get; set; } = 0.5f;
298
+
299
+ public Sprite() { }
300
+
301
+ public Sprite(Texture2D texture)
302
+ {
303
+ Texture = texture;
304
+ }
305
+
306
+ public Vector2 Size => SourceRectangle.HasValue
307
+ ? new Vector2(SourceRectangle.Value.Width, SourceRectangle.Value.Height)
308
+ : (Texture != null ? new Vector2(Texture.Width, Texture.Height) : Vector2.Zero);
309
+ }
310
+
311
+ // ═══════════════════════════════════════════════════════════════
312
+ // VELOCITY
313
+ // ═══════════════════════════════════════════════════════════════
314
+
315
+ public class Velocity
316
+ {
317
+ public Vector2 Linear { get; set; }
318
+ public float Angular { get; set; }
319
+
320
+ public Velocity() { }
321
+
322
+ public Velocity(Vector2 linear)
323
+ {
324
+ Linear = linear;
325
+ }
326
+
327
+ public Velocity(float x, float y)
328
+ {
329
+ Linear = new Vector2(x, y);
128
330
  }
129
- else {
130
- packageRefs.push(`<PackageReference Include="FNA" Version="24.01" />`);
331
+ }
332
+
333
+ // ═══════════════════════════════════════════════════════════════
334
+ // COLLIDER
335
+ // ═══════════════════════════════════════════════════════════════
336
+
337
+ public class Collider
338
+ {
339
+ public ColliderType Type { get; set; } = ColliderType.Rectangle;
340
+ public Vector2 Size { get; set; }
341
+ public float Radius { get; set; }
342
+ public Vector2 Offset { get; set; }
343
+ public bool IsTrigger { get; set; }
344
+ public int CollisionLayer { get; set; } = 1;
345
+ public int CollisionMask { get; set; } = -1;
346
+
347
+ public Rectangle Bounds(Vector2 position) => new Rectangle(
348
+ (int)(position.X + Offset.X - Size.X / 2),
349
+ (int)(position.Y + Offset.Y - Size.Y / 2),
350
+ (int)Size.X,
351
+ (int)Size.Y
352
+ );
353
+ }
354
+
355
+ public enum ColliderType
356
+ {
357
+ Rectangle,
358
+ Circle,
359
+ Capsule
360
+ }
361
+
362
+ // ═══════════════════════════════════════════════════════════════
363
+ // ANIMATION
364
+ // ═══════════════════════════════════════════════════════════════
365
+
366
+ public class AnimatedSprite
367
+ {
368
+ public Texture2D SpriteSheet { get; set; }
369
+ public int FrameWidth { get; set; }
370
+ public int FrameHeight { get; set; }
371
+ public int CurrentFrame { get; set; }
372
+ public int FrameCount { get; set; }
373
+ public float FrameTime { get; set; } = 0.1f;
374
+ public float Timer { get; set; }
375
+ public bool IsPlaying { get; set; } = true;
376
+ public bool Loop { get; set; } = true;
377
+ public int Row { get; set; } // For multi-row spritesheets
378
+
379
+ public Rectangle SourceRectangle => new Rectangle(
380
+ CurrentFrame * FrameWidth,
381
+ Row * FrameHeight,
382
+ FrameWidth,
383
+ FrameHeight
384
+ );
385
+
386
+ public void Update(float deltaTime)
387
+ {
388
+ if (!IsPlaying) return;
389
+
390
+ Timer += deltaTime;
391
+ if (Timer >= FrameTime)
392
+ {
393
+ Timer -= FrameTime;
394
+ CurrentFrame++;
395
+
396
+ if (CurrentFrame >= FrameCount)
397
+ {
398
+ if (Loop)
399
+ CurrentFrame = 0;
400
+ else
401
+ {
402
+ CurrentFrame = FrameCount - 1;
403
+ IsPlaying = false;
404
+ }
405
+ }
406
+ }
131
407
  }
132
- if (extendedPipeline) {
133
- packageRefs.push(`<PackageReference Include="MonoGame.Extended" Version="4.0.0" />`);
134
- packageRefs.push(`<PackageReference Include="MonoGame.Extended.Content.Pipeline" Version="4.0.0" />`);
408
+ }
409
+
410
+ // ═══════════════════════════════════════════════════════════════
411
+ // GAMEPLAY
412
+ // ═══════════════════════════════════════════════════════════════
413
+
414
+ public class Health
415
+ {
416
+ public float Current { get; set; }
417
+ public float Max { get; set; }
418
+
419
+ public Health(float max)
420
+ {
421
+ Max = max;
422
+ Current = max;
135
423
  }
136
- if (useECS) {
137
- packageRefs.push(`<PackageReference Include="MonoGame.Extended.Entities" Version="4.0.0" />`);
424
+
425
+ public float Percentage => Current / Max;
426
+ public bool IsDead => Current <= 0;
427
+
428
+ public bool TakeDamage(float amount)
429
+ {
430
+ Current = MathHelper.Max(0, Current - amount);
431
+ return IsDead;
138
432
  }
139
- if (useNez) {
140
- packageRefs.push(`<PackageReference Include="Nez" Version="1.0.1" />`);
433
+
434
+ public void Heal(float amount)
435
+ {
436
+ Current = MathHelper.Min(Max, Current + amount);
141
437
  }
142
- const csproj = `<Project Sdk="Microsoft.NET.Sdk">
143
- <PropertyGroup>
144
- <OutputType>WinExe</OutputType>
145
- <TargetFramework>net8.0</TargetFramework>
146
- <RollForward>Major</RollForward>
147
- <PublishReadyToRun>false</PublishReadyToRun>
148
- <TieredCompilation>false</TieredCompilation>
149
- <RootNamespace>${this.config.namespace}</RootNamespace>
150
- <AssemblyName>${this.config.solutionName}</AssemblyName>
151
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
152
- </PropertyGroup>
153
-
154
- <ItemGroup>
155
- ${packageRefs.map((r) => ` ${r}`).join('\n')}
156
- </ItemGroup>
157
-
158
- <ItemGroup>
159
- <None Remove="**\\*.mgcb" />
160
- <MonoGameContentReference Include="Content\\Content.mgcb" />
161
- </ItemGroup>
162
-
163
- <ItemGroup>
164
- <Compile Update="**\\*.cs" />
165
- </ItemGroup>
166
- </Project>
438
+ }
439
+
440
+ public class Player
441
+ {
442
+ public int PlayerId { get; set; }
443
+ public int Score { get; set; }
444
+ public float Speed { get; set; } = 200f;
445
+ public bool CanJump { get; set; } = true;
446
+ }
447
+
448
+ public class Enemy
449
+ {
450
+ public EnemyType Type { get; set; }
451
+ public AIState State { get; set; } = AIState.Idle;
452
+ public float DetectionRange { get; set; } = 200f;
453
+ public float AttackRange { get; set; } = 50f;
454
+ }
455
+
456
+ public enum EnemyType
457
+ {
458
+ Basic,
459
+ Fast,
460
+ Tank,
461
+ Boss
462
+ }
463
+
464
+ public enum AIState
465
+ {
466
+ Idle,
467
+ Patrol,
468
+ Chase,
469
+ Attack,
470
+ Flee,
471
+ Dead
472
+ }
473
+ }
167
474
  `;
168
- this.csharpFiles.set(`${this.config.solutionName}/${this.config.solutionName}.csproj`, csproj);
475
+ this.csharpFiles.set(`${this.config.solutionName}/Components/Components.cs`, componentsCs);
476
+ }
477
+ generateEntities(_project) {
478
+ const { namespace } = this.config;
479
+ const entitiesCs = `using Microsoft.Xna.Framework;
480
+ using Microsoft.Xna.Framework.Graphics;
481
+ using ${namespace}.Components;
482
+
483
+ namespace ${namespace}.Entities
484
+ {
485
+ // ═══════════════════════════════════════════════════════════════
486
+ // BASE ENTITY
487
+ // ═══════════════════════════════════════════════════════════════
488
+
489
+ public abstract class Entity
490
+ {
491
+ public int Id { get; protected set; }
492
+ public bool IsActive { get; set; } = true;
493
+ public bool IsDestroyed { get; private set; }
494
+
495
+ public Transform Transform { get; set; } = new Transform();
496
+ public Sprite Sprite { get; set; }
497
+ public Velocity Velocity { get; set; }
498
+ public Collider Collider { get; set; }
499
+
500
+ private static int _nextId = 0;
501
+
502
+ protected Entity()
503
+ {
504
+ Id = _nextId++;
505
+ }
506
+
507
+ public virtual void Update(GameTime gameTime) { }
508
+
509
+ public virtual void Draw(SpriteBatch spriteBatch)
510
+ {
511
+ if (Sprite?.Texture == null) return;
512
+
513
+ spriteBatch.Draw(
514
+ Sprite.Texture,
515
+ Transform.Position,
516
+ Sprite.SourceRectangle,
517
+ Sprite.Color,
518
+ Transform.Rotation,
519
+ Transform.Origin,
520
+ Transform.Scale,
521
+ Sprite.Effects,
522
+ Sprite.LayerDepth
523
+ );
524
+ }
525
+
526
+ public void Destroy()
527
+ {
528
+ IsDestroyed = true;
529
+ OnDestroy();
530
+ }
531
+
532
+ protected virtual void OnDestroy() { }
169
533
  }
170
- generateGame1(_project) {
171
- const { namespace, useECS, useNez } = this.config;
172
- const usings = [
173
- 'using Microsoft.Xna.Framework;',
174
- 'using Microsoft.Xna.Framework.Graphics;',
175
- 'using Microsoft.Xna.Framework.Input;',
176
- ];
177
- if (useECS) {
178
- usings.push('using MonoGame.Extended.Entities;');
534
+
535
+ // ═══════════════════════════════════════════════════════════════
536
+ // PLAYER ENTITY
537
+ // ═══════════════════════════════════════════════════════════════
538
+
539
+ public class PlayerEntity : Entity
540
+ {
541
+ public Player PlayerComponent { get; } = new Player();
542
+ public Health HealthComponent { get; } = new Health(100);
543
+ public AnimatedSprite AnimatedSprite { get; set; }
544
+
545
+ private bool _isGrounded;
546
+ private const float Gravity = 980f;
547
+ private const float JumpForce = -400f;
548
+
549
+ public PlayerEntity(Vector2 position)
550
+ {
551
+ Transform = new Transform(position);
552
+ Velocity = new Velocity();
553
+ Collider = new Collider
554
+ {
555
+ Type = ColliderType.Rectangle,
556
+ Size = new Vector2(32, 48),
557
+ CollisionLayer = 1
558
+ };
179
559
  }
180
- if (useNez) {
181
- usings.push('using Nez;');
560
+
561
+ public override void Update(GameTime gameTime)
562
+ {
563
+ float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
564
+
565
+ // Gravity
566
+ if (!_isGrounded)
567
+ {
568
+ Velocity.Linear = new Vector2(Velocity.Linear.X, Velocity.Linear.Y + Gravity * dt);
569
+ }
570
+
571
+ // Apply velocity
572
+ Transform.Position += Velocity.Linear * dt;
573
+
574
+ // Update animation
575
+ AnimatedSprite?.Update(dt);
576
+ }
577
+
578
+ public void Move(Vector2 direction)
579
+ {
580
+ Velocity.Linear = new Vector2(direction.X * PlayerComponent.Speed, Velocity.Linear.Y);
581
+ }
582
+
583
+ public void Jump()
584
+ {
585
+ if (_isGrounded && PlayerComponent.CanJump)
586
+ {
587
+ Velocity.Linear = new Vector2(Velocity.Linear.X, JumpForce);
588
+ _isGrounded = false;
589
+ }
590
+ }
591
+
592
+ public void OnGrounded()
593
+ {
594
+ _isGrounded = true;
595
+ Velocity.Linear = new Vector2(Velocity.Linear.X, 0);
182
596
  }
183
- usings.push(`using ${namespace}.Screens;`);
184
- usings.push(`using ${namespace}.Components;`);
185
- const game1 = `${usings.join('\n')}
186
-
187
- namespace ${namespace}
188
- {
189
- public class Game1 : Game
190
- {
191
- private GraphicsDeviceManager _graphics;
192
- private SpriteBatch _spriteBatch;
193
- private ScreenManager _screenManager;
194
- ${useECS ? 'private World _world;' : ''}
195
-
196
- public static Game1 Instance { get; private set; }
197
- public static int ScreenWidth => 1280;
198
- public static int ScreenHeight => 720;
199
-
200
- public Game1()
201
- {
202
- Instance = this;
203
- _graphics = new GraphicsDeviceManager(this);
204
- Content.RootDirectory = "Content";
205
- IsMouseVisible = true;
206
-
207
- _graphics.PreferredBackBufferWidth = ScreenWidth;
208
- _graphics.PreferredBackBufferHeight = ScreenHeight;
209
- _graphics.ApplyChanges();
210
- }
211
-
212
- protected override void Initialize()
213
- {
214
- _screenManager = new ScreenManager(this);
215
- Components.Add(_screenManager);
216
-
217
- ${useECS ? this.generateECSInitialization() : ''}
218
-
219
- base.Initialize();
220
- }
221
-
222
- protected override void LoadContent()
223
- {
224
- _spriteBatch = new SpriteBatch(GraphicsDevice);
225
-
226
- // Load global content
227
- Assets.Load(Content);
228
-
229
- // Start with menu screen
230
- _screenManager.AddScreen(new MenuScreen());
231
- }
232
-
233
- protected override void Update(GameTime gameTime)
234
- {
235
- if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
236
- Keyboard.GetState().IsKeyDown(Keys.Escape))
237
- {
238
- Exit();
239
- }
240
-
241
- ${useECS ? '_world?.Update(gameTime);' : ''}
242
-
243
- base.Update(gameTime);
244
- }
245
-
246
- protected override void Draw(GameTime gameTime)
247
- {
248
- GraphicsDevice.Clear(Color.CornflowerBlue);
249
-
250
- ${useECS ? '_world?.Draw(gameTime);' : ''}
251
-
252
- base.Draw(gameTime);
253
- }
254
- }
255
- }
256
- `;
257
- this.csharpFiles.set(`${this.config.solutionName}/Game1.cs`, game1);
258
597
  }
259
- generateECSInitialization() {
260
- return `
261
- _world = new WorldBuilder()
262
- .AddSystem(new MovementSystem())
263
- .AddSystem(new CollisionSystem())
264
- .AddSystem(new RenderSystem(_spriteBatch))
265
- .AddSystem(new AnimationSystem())
266
- .Build();`;
598
+
599
+ // ═══════════════════════════════════════════════════════════════
600
+ // ENEMY ENTITY
601
+ // ═══════════════════════════════════════════════════════════════
602
+
603
+ public class EnemyEntity : Entity
604
+ {
605
+ public Enemy EnemyComponent { get; } = new Enemy();
606
+ public Health HealthComponent { get; }
607
+
608
+ private Entity _target;
609
+ private float _stateTimer;
610
+
611
+ public EnemyEntity(Vector2 position, EnemyType type = EnemyType.Basic)
612
+ {
613
+ Transform = new Transform(position);
614
+ Velocity = new Velocity();
615
+ EnemyComponent.Type = type;
616
+
617
+ // Configure based on type
618
+ switch (type)
619
+ {
620
+ case EnemyType.Fast:
621
+ HealthComponent = new Health(50);
622
+ break;
623
+ case EnemyType.Tank:
624
+ HealthComponent = new Health(200);
625
+ break;
626
+ case EnemyType.Boss:
627
+ HealthComponent = new Health(500);
628
+ break;
629
+ default:
630
+ HealthComponent = new Health(100);
631
+ break;
632
+ }
633
+
634
+ Collider = new Collider
635
+ {
636
+ Type = ColliderType.Rectangle,
637
+ Size = new Vector2(32, 32),
638
+ CollisionLayer = 2
639
+ };
640
+ }
641
+
642
+ public void SetTarget(Entity target)
643
+ {
644
+ _target = target;
645
+ }
646
+
647
+ public override void Update(GameTime gameTime)
648
+ {
649
+ float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
650
+
651
+ UpdateAI(dt);
652
+ Transform.Position += Velocity.Linear * dt;
653
+ }
654
+
655
+ private void UpdateAI(float dt)
656
+ {
657
+ if (_target == null) return;
658
+
659
+ float distance = Vector2.Distance(Transform.Position, _target.Transform.Position);
660
+
661
+ switch (EnemyComponent.State)
662
+ {
663
+ case AIState.Idle:
664
+ if (distance < EnemyComponent.DetectionRange)
665
+ {
666
+ EnemyComponent.State = AIState.Chase;
667
+ }
668
+ break;
669
+
670
+ case AIState.Chase:
671
+ if (distance > EnemyComponent.DetectionRange * 1.5f)
672
+ {
673
+ EnemyComponent.State = AIState.Idle;
674
+ Velocity.Linear = Vector2.Zero;
675
+ }
676
+ else if (distance < EnemyComponent.AttackRange)
677
+ {
678
+ EnemyComponent.State = AIState.Attack;
679
+ }
680
+ else
681
+ {
682
+ Vector2 direction = Vector2.Normalize(_target.Transform.Position - Transform.Position);
683
+ float speed = EnemyComponent.Type == EnemyType.Fast ? 150f : 100f;
684
+ Velocity.Linear = direction * speed;
685
+ }
686
+ break;
687
+
688
+ case AIState.Attack:
689
+ if (distance > EnemyComponent.AttackRange * 1.2f)
690
+ {
691
+ EnemyComponent.State = AIState.Chase;
692
+ }
693
+ // Attack logic
694
+ break;
695
+ }
696
+ }
267
697
  }
268
- generateComponents(_project) {
269
- const { namespace } = this.config;
270
- const componentsCs = `using Microsoft.Xna.Framework;
271
- using Microsoft.Xna.Framework.Graphics;
272
-
273
- namespace ${namespace}.Components
274
- {
275
- // ═══════════════════════════════════════════════════════════════
276
- // TRANSFORM
277
- // ═══════════════════════════════════════════════════════════════
278
-
279
- public class Transform
280
- {
281
- public Vector2 Position { get; set; }
282
- public float Rotation { get; set; }
283
- public Vector2 Scale { get; set; } = Vector2.One;
284
- public Vector2 Origin { get; set; }
285
-
286
- public Transform() { }
287
-
288
- public Transform(Vector2 position)
289
- {
290
- Position = position;
291
- }
292
-
293
- public Transform(float x, float y)
294
- {
295
- Position = new Vector2(x, y);
296
- }
297
-
298
- public Matrix TransformMatrix =>
299
- Matrix.CreateTranslation(-Origin.X, -Origin.Y, 0) *
300
- Matrix.CreateScale(Scale.X, Scale.Y, 1) *
301
- Matrix.CreateRotationZ(Rotation) *
302
- Matrix.CreateTranslation(Position.X, Position.Y, 0);
303
- }
304
-
305
- // ═══════════════════════════════════════════════════════════════
306
- // SPRITE
307
- // ═══════════════════════════════════════════════════════════════
308
-
309
- public class Sprite
310
- {
311
- public Texture2D Texture { get; set; }
312
- public Rectangle? SourceRectangle { get; set; }
313
- public Color Color { get; set; } = Color.White;
314
- public SpriteEffects Effects { get; set; } = SpriteEffects.None;
315
- public float LayerDepth { get; set; } = 0.5f;
316
-
317
- public Sprite() { }
318
-
319
- public Sprite(Texture2D texture)
320
- {
321
- Texture = texture;
322
- }
323
-
324
- public Vector2 Size => SourceRectangle.HasValue
325
- ? new Vector2(SourceRectangle.Value.Width, SourceRectangle.Value.Height)
326
- : (Texture != null ? new Vector2(Texture.Width, Texture.Height) : Vector2.Zero);
327
- }
328
-
329
- // ═══════════════════════════════════════════════════════════════
330
- // VELOCITY
331
- // ═══════════════════════════════════════════════════════════════
332
-
333
- public class Velocity
334
- {
335
- public Vector2 Linear { get; set; }
336
- public float Angular { get; set; }
337
-
338
- public Velocity() { }
339
-
340
- public Velocity(Vector2 linear)
341
- {
342
- Linear = linear;
343
- }
344
-
345
- public Velocity(float x, float y)
346
- {
347
- Linear = new Vector2(x, y);
348
- }
349
- }
350
-
351
- // ═══════════════════════════════════════════════════════════════
352
- // COLLIDER
353
- // ═══════════════════════════════════════════════════════════════
354
-
355
- public class Collider
356
- {
357
- public ColliderType Type { get; set; } = ColliderType.Rectangle;
358
- public Vector2 Size { get; set; }
359
- public float Radius { get; set; }
360
- public Vector2 Offset { get; set; }
361
- public bool IsTrigger { get; set; }
362
- public int CollisionLayer { get; set; } = 1;
363
- public int CollisionMask { get; set; } = -1;
364
-
365
- public Rectangle Bounds(Vector2 position) => new Rectangle(
366
- (int)(position.X + Offset.X - Size.X / 2),
367
- (int)(position.Y + Offset.Y - Size.Y / 2),
368
- (int)Size.X,
369
- (int)Size.Y
370
- );
371
- }
372
-
373
- public enum ColliderType
374
- {
375
- Rectangle,
376
- Circle,
377
- Capsule
378
- }
379
-
380
- // ═══════════════════════════════════════════════════════════════
381
- // ANIMATION
382
- // ═══════════════════════════════════════════════════════════════
383
-
384
- public class AnimatedSprite
385
- {
386
- public Texture2D SpriteSheet { get; set; }
387
- public int FrameWidth { get; set; }
388
- public int FrameHeight { get; set; }
389
- public int CurrentFrame { get; set; }
390
- public int FrameCount { get; set; }
391
- public float FrameTime { get; set; } = 0.1f;
392
- public float Timer { get; set; }
393
- public bool IsPlaying { get; set; } = true;
394
- public bool Loop { get; set; } = true;
395
- public int Row { get; set; } // For multi-row spritesheets
396
-
397
- public Rectangle SourceRectangle => new Rectangle(
398
- CurrentFrame * FrameWidth,
399
- Row * FrameHeight,
400
- FrameWidth,
401
- FrameHeight
402
- );
403
-
404
- public void Update(float deltaTime)
405
- {
406
- if (!IsPlaying) return;
407
-
408
- Timer += deltaTime;
409
- if (Timer >= FrameTime)
410
- {
411
- Timer -= FrameTime;
412
- CurrentFrame++;
413
-
414
- if (CurrentFrame >= FrameCount)
415
- {
416
- if (Loop)
417
- CurrentFrame = 0;
418
- else
419
- {
420
- CurrentFrame = FrameCount - 1;
421
- IsPlaying = false;
422
- }
423
- }
424
- }
425
- }
426
- }
427
-
428
- // ═══════════════════════════════════════════════════════════════
429
- // GAMEPLAY
430
- // ═══════════════════════════════════════════════════════════════
431
-
432
- public class Health
433
- {
434
- public float Current { get; set; }
435
- public float Max { get; set; }
436
-
437
- public Health(float max)
438
- {
439
- Max = max;
440
- Current = max;
441
- }
442
-
443
- public float Percentage => Current / Max;
444
- public bool IsDead => Current <= 0;
445
-
446
- public bool TakeDamage(float amount)
447
- {
448
- Current = MathHelper.Max(0, Current - amount);
449
- return IsDead;
450
- }
451
-
452
- public void Heal(float amount)
453
- {
454
- Current = MathHelper.Min(Max, Current + amount);
455
- }
456
- }
457
-
458
- public class Player
459
- {
460
- public int PlayerId { get; set; }
461
- public int Score { get; set; }
462
- public float Speed { get; set; } = 200f;
463
- public bool CanJump { get; set; } = true;
464
- }
465
-
466
- public class Enemy
467
- {
468
- public EnemyType Type { get; set; }
469
- public AIState State { get; set; } = AIState.Idle;
470
- public float DetectionRange { get; set; } = 200f;
471
- public float AttackRange { get; set; } = 50f;
472
- }
473
-
474
- public enum EnemyType
475
- {
476
- Basic,
477
- Fast,
478
- Tank,
479
- Boss
480
- }
481
-
482
- public enum AIState
483
- {
484
- Idle,
485
- Patrol,
486
- Chase,
487
- Attack,
488
- Flee,
489
- Dead
490
- }
491
- }
698
+ }
492
699
  `;
493
- this.csharpFiles.set(`${this.config.solutionName}/Components/Components.cs`, componentsCs);
700
+ this.csharpFiles.set(`${this.config.solutionName}/Entities/Entities.cs`, entitiesCs);
701
+ }
702
+ generateSystems(_project) {
703
+ const { namespace } = this.config;
704
+ const systemsCs = `using Microsoft.Xna.Framework;
705
+ using Microsoft.Xna.Framework.Graphics;
706
+ using MonoGame.Extended.Entities;
707
+ using MonoGame.Extended.Entities.Systems;
708
+ using ${namespace}.Components;
709
+
710
+ namespace ${namespace}.Systems
711
+ {
712
+ // ═══════════════════════════════════════════════════════════════
713
+ // MOVEMENT SYSTEM
714
+ // ═══════════════════════════════════════════════════════════════
715
+
716
+ public class MovementSystem : EntityUpdateSystem
717
+ {
718
+ private ComponentMapper<Transform> _transformMapper;
719
+ private ComponentMapper<Velocity> _velocityMapper;
720
+
721
+ public MovementSystem()
722
+ : base(Aspect.All(typeof(Transform), typeof(Velocity)))
723
+ {
724
+ }
725
+
726
+ public override void Initialize(IComponentMapperService mapperService)
727
+ {
728
+ _transformMapper = mapperService.GetMapper<Transform>();
729
+ _velocityMapper = mapperService.GetMapper<Velocity>();
730
+ }
731
+
732
+ public override void Update(GameTime gameTime)
733
+ {
734
+ float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
735
+
736
+ foreach (int entityId in ActiveEntities)
737
+ {
738
+ var transform = _transformMapper.Get(entityId);
739
+ var velocity = _velocityMapper.Get(entityId);
740
+
741
+ transform.Position += velocity.Linear * dt;
742
+ transform.Rotation += velocity.Angular * dt;
743
+ }
744
+ }
494
745
  }
495
- generateEntities(_project) {
496
- const { namespace } = this.config;
497
- const entitiesCs = `using Microsoft.Xna.Framework;
498
- using Microsoft.Xna.Framework.Graphics;
499
- using ${namespace}.Components;
500
-
501
- namespace ${namespace}.Entities
502
- {
503
- // ═══════════════════════════════════════════════════════════════
504
- // BASE ENTITY
505
- // ═══════════════════════════════════════════════════════════════
506
-
507
- public abstract class Entity
508
- {
509
- public int Id { get; protected set; }
510
- public bool IsActive { get; set; } = true;
511
- public bool IsDestroyed { get; private set; }
512
-
513
- public Transform Transform { get; set; } = new Transform();
514
- public Sprite Sprite { get; set; }
515
- public Velocity Velocity { get; set; }
516
- public Collider Collider { get; set; }
517
-
518
- private static int _nextId = 0;
519
-
520
- protected Entity()
521
- {
522
- Id = _nextId++;
523
- }
524
-
525
- public virtual void Update(GameTime gameTime) { }
526
-
527
- public virtual void Draw(SpriteBatch spriteBatch)
528
- {
529
- if (Sprite?.Texture == null) return;
530
-
531
- spriteBatch.Draw(
532
- Sprite.Texture,
533
- Transform.Position,
534
- Sprite.SourceRectangle,
535
- Sprite.Color,
536
- Transform.Rotation,
537
- Transform.Origin,
538
- Transform.Scale,
539
- Sprite.Effects,
540
- Sprite.LayerDepth
541
- );
542
- }
543
-
544
- public void Destroy()
545
- {
546
- IsDestroyed = true;
547
- OnDestroy();
548
- }
549
-
550
- protected virtual void OnDestroy() { }
551
- }
552
-
553
- // ═══════════════════════════════════════════════════════════════
554
- // PLAYER ENTITY
555
- // ═══════════════════════════════════════════════════════════════
556
-
557
- public class PlayerEntity : Entity
558
- {
559
- public Player PlayerComponent { get; } = new Player();
560
- public Health HealthComponent { get; } = new Health(100);
561
- public AnimatedSprite AnimatedSprite { get; set; }
562
-
563
- private bool _isGrounded;
564
- private const float Gravity = 980f;
565
- private const float JumpForce = -400f;
566
-
567
- public PlayerEntity(Vector2 position)
568
- {
569
- Transform = new Transform(position);
570
- Velocity = new Velocity();
571
- Collider = new Collider
572
- {
573
- Type = ColliderType.Rectangle,
574
- Size = new Vector2(32, 48),
575
- CollisionLayer = 1
576
- };
577
- }
578
-
579
- public override void Update(GameTime gameTime)
580
- {
581
- float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
582
-
583
- // Gravity
584
- if (!_isGrounded)
585
- {
586
- Velocity.Linear = new Vector2(Velocity.Linear.X, Velocity.Linear.Y + Gravity * dt);
587
- }
588
-
589
- // Apply velocity
590
- Transform.Position += Velocity.Linear * dt;
591
-
592
- // Update animation
593
- AnimatedSprite?.Update(dt);
594
- }
595
-
596
- public void Move(Vector2 direction)
597
- {
598
- Velocity.Linear = new Vector2(direction.X * PlayerComponent.Speed, Velocity.Linear.Y);
599
- }
600
-
601
- public void Jump()
602
- {
603
- if (_isGrounded && PlayerComponent.CanJump)
604
- {
605
- Velocity.Linear = new Vector2(Velocity.Linear.X, JumpForce);
606
- _isGrounded = false;
607
- }
608
- }
609
-
610
- public void OnGrounded()
611
- {
612
- _isGrounded = true;
613
- Velocity.Linear = new Vector2(Velocity.Linear.X, 0);
614
- }
615
- }
616
-
617
- // ═══════════════════════════════════════════════════════════════
618
- // ENEMY ENTITY
619
- // ═══════════════════════════════════════════════════════════════
620
-
621
- public class EnemyEntity : Entity
622
- {
623
- public Enemy EnemyComponent { get; } = new Enemy();
624
- public Health HealthComponent { get; }
625
-
626
- private Entity _target;
627
- private float _stateTimer;
628
-
629
- public EnemyEntity(Vector2 position, EnemyType type = EnemyType.Basic)
630
- {
631
- Transform = new Transform(position);
632
- Velocity = new Velocity();
633
- EnemyComponent.Type = type;
634
-
635
- // Configure based on type
636
- switch (type)
637
- {
638
- case EnemyType.Fast:
639
- HealthComponent = new Health(50);
640
- break;
641
- case EnemyType.Tank:
642
- HealthComponent = new Health(200);
643
- break;
644
- case EnemyType.Boss:
645
- HealthComponent = new Health(500);
646
- break;
647
- default:
648
- HealthComponent = new Health(100);
649
- break;
650
- }
651
-
652
- Collider = new Collider
653
- {
654
- Type = ColliderType.Rectangle,
655
- Size = new Vector2(32, 32),
656
- CollisionLayer = 2
657
- };
658
- }
659
-
660
- public void SetTarget(Entity target)
661
- {
662
- _target = target;
663
- }
664
-
665
- public override void Update(GameTime gameTime)
666
- {
667
- float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
668
-
669
- UpdateAI(dt);
670
- Transform.Position += Velocity.Linear * dt;
671
- }
672
-
673
- private void UpdateAI(float dt)
674
- {
675
- if (_target == null) return;
676
-
677
- float distance = Vector2.Distance(Transform.Position, _target.Transform.Position);
678
-
679
- switch (EnemyComponent.State)
680
- {
681
- case AIState.Idle:
682
- if (distance < EnemyComponent.DetectionRange)
683
- {
684
- EnemyComponent.State = AIState.Chase;
685
- }
686
- break;
687
-
688
- case AIState.Chase:
689
- if (distance > EnemyComponent.DetectionRange * 1.5f)
690
- {
691
- EnemyComponent.State = AIState.Idle;
692
- Velocity.Linear = Vector2.Zero;
693
- }
694
- else if (distance < EnemyComponent.AttackRange)
695
- {
696
- EnemyComponent.State = AIState.Attack;
697
- }
698
- else
699
- {
700
- Vector2 direction = Vector2.Normalize(_target.Transform.Position - Transform.Position);
701
- float speed = EnemyComponent.Type == EnemyType.Fast ? 150f : 100f;
702
- Velocity.Linear = direction * speed;
703
- }
704
- break;
705
-
706
- case AIState.Attack:
707
- if (distance > EnemyComponent.AttackRange * 1.2f)
708
- {
709
- EnemyComponent.State = AIState.Chase;
710
- }
711
- // Attack logic
712
- break;
713
- }
714
- }
715
- }
716
- }
717
- `;
718
- this.csharpFiles.set(`${this.config.solutionName}/Entities/Entities.cs`, entitiesCs);
746
+
747
+ // ═══════════════════════════════════════════════════════════════
748
+ // COLLISION SYSTEM
749
+ // ═══════════════════════════════════════════════════════════════
750
+
751
+ public class CollisionSystem : EntityUpdateSystem
752
+ {
753
+ private ComponentMapper<Transform> _transformMapper;
754
+ private ComponentMapper<Collider> _colliderMapper;
755
+
756
+ public CollisionSystem()
757
+ : base(Aspect.All(typeof(Transform), typeof(Collider)))
758
+ {
759
+ }
760
+
761
+ public override void Initialize(IComponentMapperService mapperService)
762
+ {
763
+ _transformMapper = mapperService.GetMapper<Transform>();
764
+ _colliderMapper = mapperService.GetMapper<Collider>();
765
+ }
766
+
767
+ public override void Update(GameTime gameTime)
768
+ {
769
+ var entities = ActiveEntities.ToArray();
770
+
771
+ for (int i = 0; i < entities.Length; i++)
772
+ {
773
+ var transformA = _transformMapper.Get(entities[i]);
774
+ var colliderA = _colliderMapper.Get(entities[i]);
775
+ var boundsA = colliderA.Bounds(transformA.Position);
776
+
777
+ for (int j = i + 1; j < entities.Length; j++)
778
+ {
779
+ var transformB = _transformMapper.Get(entities[j]);
780
+ var colliderB = _colliderMapper.Get(entities[j]);
781
+ var boundsB = colliderB.Bounds(transformB.Position);
782
+
783
+ // Check layer/mask
784
+ if ((colliderA.CollisionLayer & colliderB.CollisionMask) == 0 ||
785
+ (colliderB.CollisionLayer & colliderA.CollisionMask) == 0)
786
+ continue;
787
+
788
+ if (boundsA.Intersects(boundsB))
789
+ {
790
+ OnCollision(entities[i], entities[j], colliderA, colliderB);
791
+ }
792
+ }
793
+ }
794
+ }
795
+
796
+ private void OnCollision(int entityA, int entityB, Collider colliderA, Collider colliderB)
797
+ {
798
+ if (colliderA.IsTrigger || colliderB.IsTrigger)
799
+ {
800
+ // Trigger event
801
+ }
802
+ else
803
+ {
804
+ // Physical collision
805
+ }
806
+ }
719
807
  }
720
- generateSystems(_project) {
721
- const { namespace } = this.config;
722
- const systemsCs = `using Microsoft.Xna.Framework;
723
- using Microsoft.Xna.Framework.Graphics;
724
- using MonoGame.Extended.Entities;
725
- using MonoGame.Extended.Entities.Systems;
726
- using ${namespace}.Components;
727
-
728
- namespace ${namespace}.Systems
729
- {
730
- // ═══════════════════════════════════════════════════════════════
731
- // MOVEMENT SYSTEM
732
- // ═══════════════════════════════════════════════════════════════
733
-
734
- public class MovementSystem : EntityUpdateSystem
735
- {
736
- private ComponentMapper<Transform> _transformMapper;
737
- private ComponentMapper<Velocity> _velocityMapper;
738
-
739
- public MovementSystem()
740
- : base(Aspect.All(typeof(Transform), typeof(Velocity)))
741
- {
742
- }
743
-
744
- public override void Initialize(IComponentMapperService mapperService)
745
- {
746
- _transformMapper = mapperService.GetMapper<Transform>();
747
- _velocityMapper = mapperService.GetMapper<Velocity>();
748
- }
749
-
750
- public override void Update(GameTime gameTime)
751
- {
752
- float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
753
-
754
- foreach (int entityId in ActiveEntities)
755
- {
756
- var transform = _transformMapper.Get(entityId);
757
- var velocity = _velocityMapper.Get(entityId);
758
-
759
- transform.Position += velocity.Linear * dt;
760
- transform.Rotation += velocity.Angular * dt;
761
- }
762
- }
763
- }
764
-
765
- // ═══════════════════════════════════════════════════════════════
766
- // COLLISION SYSTEM
767
- // ═══════════════════════════════════════════════════════════════
768
-
769
- public class CollisionSystem : EntityUpdateSystem
770
- {
771
- private ComponentMapper<Transform> _transformMapper;
772
- private ComponentMapper<Collider> _colliderMapper;
773
-
774
- public CollisionSystem()
775
- : base(Aspect.All(typeof(Transform), typeof(Collider)))
776
- {
777
- }
778
-
779
- public override void Initialize(IComponentMapperService mapperService)
780
- {
781
- _transformMapper = mapperService.GetMapper<Transform>();
782
- _colliderMapper = mapperService.GetMapper<Collider>();
783
- }
784
-
785
- public override void Update(GameTime gameTime)
786
- {
787
- var entities = ActiveEntities.ToArray();
788
-
789
- for (int i = 0; i < entities.Length; i++)
790
- {
791
- var transformA = _transformMapper.Get(entities[i]);
792
- var colliderA = _colliderMapper.Get(entities[i]);
793
- var boundsA = colliderA.Bounds(transformA.Position);
794
-
795
- for (int j = i + 1; j < entities.Length; j++)
796
- {
797
- var transformB = _transformMapper.Get(entities[j]);
798
- var colliderB = _colliderMapper.Get(entities[j]);
799
- var boundsB = colliderB.Bounds(transformB.Position);
800
-
801
- // Check layer/mask
802
- if ((colliderA.CollisionLayer & colliderB.CollisionMask) == 0 ||
803
- (colliderB.CollisionLayer & colliderA.CollisionMask) == 0)
804
- continue;
805
-
806
- if (boundsA.Intersects(boundsB))
807
- {
808
- OnCollision(entities[i], entities[j], colliderA, colliderB);
809
- }
810
- }
811
- }
812
- }
813
-
814
- private void OnCollision(int entityA, int entityB, Collider colliderA, Collider colliderB)
815
- {
816
- if (colliderA.IsTrigger || colliderB.IsTrigger)
817
- {
818
- // Trigger event
819
- }
820
- else
821
- {
822
- // Physical collision
823
- }
824
- }
825
- }
826
-
827
- // ═══════════════════════════════════════════════════════════════
828
- // RENDER SYSTEM
829
- // ═══════════════════════════════════════════════════════════════
830
-
831
- public class RenderSystem : EntityDrawSystem
832
- {
833
- private SpriteBatch _spriteBatch;
834
- private ComponentMapper<Transform> _transformMapper;
835
- private ComponentMapper<Sprite> _spriteMapper;
836
-
837
- public RenderSystem(SpriteBatch spriteBatch)
838
- : base(Aspect.All(typeof(Transform), typeof(Sprite)))
839
- {
840
- _spriteBatch = spriteBatch;
841
- }
842
-
843
- public override void Initialize(IComponentMapperService mapperService)
844
- {
845
- _transformMapper = mapperService.GetMapper<Transform>();
846
- _spriteMapper = mapperService.GetMapper<Sprite>();
847
- }
848
-
849
- public override void Draw(GameTime gameTime)
850
- {
851
- _spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
852
-
853
- foreach (int entityId in ActiveEntities)
854
- {
855
- var transform = _transformMapper.Get(entityId);
856
- var sprite = _spriteMapper.Get(entityId);
857
-
858
- if (sprite.Texture == null) continue;
859
-
860
- _spriteBatch.Draw(
861
- sprite.Texture,
862
- transform.Position,
863
- sprite.SourceRectangle,
864
- sprite.Color,
865
- transform.Rotation,
866
- transform.Origin,
867
- transform.Scale,
868
- sprite.Effects,
869
- sprite.LayerDepth
870
- );
871
- }
872
-
873
- _spriteBatch.End();
874
- }
875
- }
876
-
877
- // ═══════════════════════════════════════════════════════════════
878
- // ANIMATION SYSTEM
879
- // ═══════════════════════════════════════════════════════════════
880
-
881
- public class AnimationSystem : EntityUpdateSystem
882
- {
883
- private ComponentMapper<AnimatedSprite> _animationMapper;
884
- private ComponentMapper<Sprite> _spriteMapper;
885
-
886
- public AnimationSystem()
887
- : base(Aspect.All(typeof(AnimatedSprite), typeof(Sprite)))
888
- {
889
- }
890
-
891
- public override void Initialize(IComponentMapperService mapperService)
892
- {
893
- _animationMapper = mapperService.GetMapper<AnimatedSprite>();
894
- _spriteMapper = mapperService.GetMapper<Sprite>();
895
- }
896
-
897
- public override void Update(GameTime gameTime)
898
- {
899
- float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
900
-
901
- foreach (int entityId in ActiveEntities)
902
- {
903
- var animation = _animationMapper.Get(entityId);
904
- var sprite = _spriteMapper.Get(entityId);
905
-
906
- animation.Update(dt);
907
- sprite.SourceRectangle = animation.SourceRectangle;
908
- }
909
- }
910
- }
911
- }
912
- `;
913
- this.csharpFiles.set(`${this.config.solutionName}/Systems/Systems.cs`, systemsCs);
808
+
809
+ // ═══════════════════════════════════════════════════════════════
810
+ // RENDER SYSTEM
811
+ // ═══════════════════════════════════════════════════════════════
812
+
813
+ public class RenderSystem : EntityDrawSystem
814
+ {
815
+ private SpriteBatch _spriteBatch;
816
+ private ComponentMapper<Transform> _transformMapper;
817
+ private ComponentMapper<Sprite> _spriteMapper;
818
+
819
+ public RenderSystem(SpriteBatch spriteBatch)
820
+ : base(Aspect.All(typeof(Transform), typeof(Sprite)))
821
+ {
822
+ _spriteBatch = spriteBatch;
823
+ }
824
+
825
+ public override void Initialize(IComponentMapperService mapperService)
826
+ {
827
+ _transformMapper = mapperService.GetMapper<Transform>();
828
+ _spriteMapper = mapperService.GetMapper<Sprite>();
829
+ }
830
+
831
+ public override void Draw(GameTime gameTime)
832
+ {
833
+ _spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
834
+
835
+ foreach (int entityId in ActiveEntities)
836
+ {
837
+ var transform = _transformMapper.Get(entityId);
838
+ var sprite = _spriteMapper.Get(entityId);
839
+
840
+ if (sprite.Texture == null) continue;
841
+
842
+ _spriteBatch.Draw(
843
+ sprite.Texture,
844
+ transform.Position,
845
+ sprite.SourceRectangle,
846
+ sprite.Color,
847
+ transform.Rotation,
848
+ transform.Origin,
849
+ transform.Scale,
850
+ sprite.Effects,
851
+ sprite.LayerDepth
852
+ );
853
+ }
854
+
855
+ _spriteBatch.End();
856
+ }
914
857
  }
915
- generateScreens(_project) {
916
- const { namespace } = this.config;
917
- const screensCs = `using Microsoft.Xna.Framework;
918
- using Microsoft.Xna.Framework.Content;
919
- using Microsoft.Xna.Framework.Graphics;
920
- using Microsoft.Xna.Framework.Input;
921
-
922
- namespace ${namespace}.Screens
923
- {
924
- // ═══════════════════════════════════════════════════════════════
925
- // SCREEN BASE
926
- // ═══════════════════════════════════════════════════════════════
927
-
928
- public abstract class Screen
929
- {
930
- public ScreenManager ScreenManager { get; internal set; }
931
- public bool IsActive { get; set; } = true;
932
- public bool IsPopup { get; protected set; }
933
-
934
- protected ContentManager Content => ScreenManager.Game.Content;
935
- protected GraphicsDevice GraphicsDevice => ScreenManager.GraphicsDevice;
936
-
937
- public virtual void LoadContent() { }
938
- public virtual void UnloadContent() { }
939
- public virtual void Update(GameTime gameTime) { }
940
- public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch) { }
941
-
942
- public virtual void HandleInput(InputState input) { }
943
-
944
- public void ExitScreen()
945
- {
946
- ScreenManager.RemoveScreen(this);
947
- }
948
- }
949
-
950
- // ═══════════════════════════════════════════════════════════════
951
- // SCREEN MANAGER
952
- // ═══════════════════════════════════════════════════════════════
953
-
954
- public class ScreenManager : DrawableGameComponent
955
- {
956
- private readonly List<Screen> _screens = new();
957
- private readonly List<Screen> _screensToAdd = new();
958
- private readonly List<Screen> _screensToRemove = new();
959
- private SpriteBatch _spriteBatch;
960
- private InputState _input = new();
961
-
962
- public new Game Game { get; }
963
-
964
- public ScreenManager(Game game) : base(game)
965
- {
966
- Game = game;
967
- }
968
-
969
- protected override void LoadContent()
970
- {
971
- _spriteBatch = new SpriteBatch(GraphicsDevice);
972
- }
973
-
974
- public override void Update(GameTime gameTime)
975
- {
976
- _input.Update();
977
-
978
- // Add pending screens
979
- foreach (var screen in _screensToAdd)
980
- {
981
- screen.LoadContent();
982
- _screens.Add(screen);
983
- }
984
- _screensToAdd.Clear();
985
-
986
- // Remove pending screens
987
- foreach (var screen in _screensToRemove)
988
- {
989
- screen.UnloadContent();
990
- _screens.Remove(screen);
991
- }
992
- _screensToRemove.Clear();
993
-
994
- // Update screens
995
- foreach (var screen in _screens)
996
- {
997
- if (screen.IsActive)
998
- {
999
- screen.HandleInput(_input);
1000
- screen.Update(gameTime);
1001
- }
1002
- }
1003
- }
1004
-
1005
- public override void Draw(GameTime gameTime)
1006
- {
1007
- foreach (var screen in _screens)
1008
- {
1009
- if (screen.IsActive)
1010
- {
1011
- screen.Draw(gameTime, _spriteBatch);
1012
- }
1013
- }
1014
- }
1015
-
1016
- public void AddScreen(Screen screen)
1017
- {
1018
- screen.ScreenManager = this;
1019
- _screensToAdd.Add(screen);
1020
- }
1021
-
1022
- public void RemoveScreen(Screen screen)
1023
- {
1024
- _screensToRemove.Add(screen);
1025
- }
1026
- }
1027
-
1028
- // ═══════════════════════════════════════════════════════════════
1029
- // INPUT STATE
1030
- // ═══════════════════════════════════════════════════════════════
1031
-
1032
- public class InputState
1033
- {
1034
- public KeyboardState CurrentKeyboardState { get; private set; }
1035
- public KeyboardState PreviousKeyboardState { get; private set; }
1036
- public MouseState CurrentMouseState { get; private set; }
1037
- public MouseState PreviousMouseState { get; private set; }
1038
- public GamePadState CurrentGamePadState { get; private set; }
1039
- public GamePadState PreviousGamePadState { get; private set; }
1040
-
1041
- public void Update()
1042
- {
1043
- PreviousKeyboardState = CurrentKeyboardState;
1044
- PreviousMouseState = CurrentMouseState;
1045
- PreviousGamePadState = CurrentGamePadState;
1046
-
1047
- CurrentKeyboardState = Keyboard.GetState();
1048
- CurrentMouseState = Mouse.GetState();
1049
- CurrentGamePadState = GamePad.GetState(PlayerIndex.One);
1050
- }
1051
-
1052
- public bool IsKeyPressed(Keys key) =>
1053
- CurrentKeyboardState.IsKeyDown(key) && PreviousKeyboardState.IsKeyUp(key);
1054
-
1055
- public bool IsKeyHeld(Keys key) =>
1056
- CurrentKeyboardState.IsKeyDown(key);
1057
-
1058
- public bool IsKeyReleased(Keys key) =>
1059
- CurrentKeyboardState.IsKeyUp(key) && PreviousKeyboardState.IsKeyDown(key);
1060
-
1061
- public Vector2 GetMovement()
1062
- {
1063
- Vector2 movement = Vector2.Zero;
1064
-
1065
- if (IsKeyHeld(Keys.W) || IsKeyHeld(Keys.Up)) movement.Y -= 1;
1066
- if (IsKeyHeld(Keys.S) || IsKeyHeld(Keys.Down)) movement.Y += 1;
1067
- if (IsKeyHeld(Keys.A) || IsKeyHeld(Keys.Left)) movement.X -= 1;
1068
- if (IsKeyHeld(Keys.D) || IsKeyHeld(Keys.Right)) movement.X += 1;
1069
-
1070
- if (movement != Vector2.Zero)
1071
- movement = Vector2.Normalize(movement);
1072
-
1073
- return movement;
1074
- }
1075
- }
1076
-
1077
- // ═══════════════════════════════════════════════════════════════
1078
- // MENU SCREEN
1079
- // ═══════════════════════════════════════════════════════════════
1080
-
1081
- public class MenuScreen : Screen
1082
- {
1083
- private SpriteFont _font;
1084
- private int _selectedIndex;
1085
- private string[] _menuItems = { "Play", "Options", "Exit" };
1086
-
1087
- public override void LoadContent()
1088
- {
1089
- _font = Content.Load<SpriteFont>("Fonts/MenuFont");
1090
- }
1091
-
1092
- public override void HandleInput(InputState input)
1093
- {
1094
- if (input.IsKeyPressed(Keys.Up))
1095
- {
1096
- _selectedIndex--;
1097
- if (_selectedIndex < 0) _selectedIndex = _menuItems.Length - 1;
1098
- }
1099
-
1100
- if (input.IsKeyPressed(Keys.Down))
1101
- {
1102
- _selectedIndex++;
1103
- if (_selectedIndex >= _menuItems.Length) _selectedIndex = 0;
1104
- }
1105
-
1106
- if (input.IsKeyPressed(Keys.Enter))
1107
- {
1108
- switch (_selectedIndex)
1109
- {
1110
- case 0: // Play
1111
- ScreenManager.AddScreen(new GameplayScreen());
1112
- ExitScreen();
1113
- break;
1114
- case 1: // Options
1115
- // Options screen
1116
- break;
1117
- case 2: // Exit
1118
- ScreenManager.Game.Exit();
1119
- break;
1120
- }
1121
- }
1122
- }
1123
-
1124
- public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
1125
- {
1126
- spriteBatch.Begin();
1127
-
1128
- for (int i = 0; i < _menuItems.Length; i++)
1129
- {
1130
- Color color = i == _selectedIndex ? Color.Yellow : Color.White;
1131
- Vector2 position = new Vector2(640 - _font.MeasureString(_menuItems[i]).X / 2, 300 + i * 50);
1132
- spriteBatch.DrawString(_font, _menuItems[i], position, color);
1133
- }
1134
-
1135
- spriteBatch.End();
1136
- }
1137
- }
1138
-
1139
- // ═══════════════════════════════════════════════════════════════
1140
- // GAMEPLAY SCREEN
1141
- // ═══════════════════════════════════════════════════════════════
1142
-
1143
- public class GameplayScreen : Screen
1144
- {
1145
- public override void LoadContent()
1146
- {
1147
- // Load level content
1148
- }
1149
-
1150
- public override void HandleInput(InputState input)
1151
- {
1152
- if (input.IsKeyPressed(Keys.Escape))
1153
- {
1154
- ScreenManager.AddScreen(new PauseScreen());
1155
- }
1156
-
1157
- Vector2 movement = input.GetMovement();
1158
- // Apply to player
1159
- }
1160
-
1161
- public override void Update(GameTime gameTime)
1162
- {
1163
- // Update game logic
1164
- }
1165
-
1166
- public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
1167
- {
1168
- spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
1169
-
1170
- // Draw game
1171
-
1172
- spriteBatch.End();
1173
- }
1174
- }
1175
-
1176
- // ═══════════════════════════════════════════════════════════════
1177
- // PAUSE SCREEN
1178
- // ═══════════════════════════════════════════════════════════════
1179
-
1180
- public class PauseScreen : Screen
1181
- {
1182
- public PauseScreen()
1183
- {
1184
- IsPopup = true;
1185
- }
1186
-
1187
- public override void HandleInput(InputState input)
1188
- {
1189
- if (input.IsKeyPressed(Keys.Escape))
1190
- {
1191
- ExitScreen();
1192
- }
1193
- }
1194
-
1195
- public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
1196
- {
1197
- spriteBatch.Begin();
1198
-
1199
- // Draw semi-transparent overlay
1200
- spriteBatch.Draw(
1201
- Assets.PixelTexture,
1202
- new Rectangle(0, 0, Game1.ScreenWidth, Game1.ScreenHeight),
1203
- new Color(0, 0, 0, 0.5f)
1204
- );
1205
-
1206
- // Draw pause text
1207
-
1208
- spriteBatch.End();
1209
- }
1210
- }
1211
- }
1212
- `;
1213
- this.csharpFiles.set(`${this.config.solutionName}/Screens/Screens.cs`, screensCs);
1214
- // Generate Assets class
1215
- const assetsCs = `using Microsoft.Xna.Framework;
1216
- using Microsoft.Xna.Framework.Content;
1217
- using Microsoft.Xna.Framework.Graphics;
1218
-
1219
- namespace ${namespace}
1220
- {
1221
- public static class Assets
1222
- {
1223
- // Textures
1224
- public static Texture2D PixelTexture { get; private set; }
1225
- public static Texture2D PlayerTexture { get; private set; }
1226
- public static Texture2D EnemyTexture { get; private set; }
1227
- public static Texture2D TilesetTexture { get; private set; }
1228
-
1229
- // Fonts
1230
- public static SpriteFont MenuFont { get; private set; }
1231
- public static SpriteFont GameFont { get; private set; }
1232
-
1233
- public static void Load(ContentManager content)
1234
- {
1235
- // Create pixel texture
1236
- PixelTexture = new Texture2D(Game1.Instance.GraphicsDevice, 1, 1);
1237
- PixelTexture.SetData(new[] { Color.White });
1238
-
1239
- // Load textures
1240
- PlayerTexture = content.Load<Texture2D>("Sprites/player");
1241
- EnemyTexture = content.Load<Texture2D>("Sprites/enemy");
1242
- TilesetTexture = content.Load<Texture2D>("Sprites/tileset");
1243
-
1244
- // Load fonts
1245
- MenuFont = content.Load<SpriteFont>("Fonts/MenuFont");
1246
- GameFont = content.Load<SpriteFont>("Fonts/GameFont");
1247
- }
1248
- }
1249
- }
1250
- `;
1251
- this.csharpFiles.set(`${this.config.solutionName}/Assets.cs`, assetsCs);
858
+
859
+ // ═══════════════════════════════════════════════════════════════
860
+ // ANIMATION SYSTEM
861
+ // ═══════════════════════════════════════════════════════════════
862
+
863
+ public class AnimationSystem : EntityUpdateSystem
864
+ {
865
+ private ComponentMapper<AnimatedSprite> _animationMapper;
866
+ private ComponentMapper<Sprite> _spriteMapper;
867
+
868
+ public AnimationSystem()
869
+ : base(Aspect.All(typeof(AnimatedSprite), typeof(Sprite)))
870
+ {
871
+ }
872
+
873
+ public override void Initialize(IComponentMapperService mapperService)
874
+ {
875
+ _animationMapper = mapperService.GetMapper<AnimatedSprite>();
876
+ _spriteMapper = mapperService.GetMapper<Sprite>();
877
+ }
878
+
879
+ public override void Update(GameTime gameTime)
880
+ {
881
+ float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
882
+
883
+ foreach (int entityId in ActiveEntities)
884
+ {
885
+ var animation = _animationMapper.Get(entityId);
886
+ var sprite = _spriteMapper.Get(entityId);
887
+
888
+ animation.Update(dt);
889
+ sprite.SourceRectangle = animation.SourceRectangle;
890
+ }
891
+ }
1252
892
  }
1253
- generateContentMgcb(project) {
1254
- let mgcb = `#----------------------------- Global Properties ----------------------------#
1255
-
1256
- /outputDir:bin/$(Platform)
1257
- /intermediateDir:obj/$(Platform)
1258
- /platform:DesktopGL
1259
- /config:
1260
- /profile:Reach
1261
- /compress:False
1262
-
1263
- #-------------------------------- References --------------------------------#
1264
-
1265
- /reference:..\\..\\packages\\MonoGame.Extended.Content.Pipeline\\4.0.0\\tools\\MonoGame.Extended.Content.Pipeline.dll
1266
-
1267
- #---------------------------------- Content ---------------------------------#
1268
-
1269
- #begin Fonts/MenuFont.spritefont
1270
- /importer:FontDescriptionImporter
1271
- /processor:FontDescriptionProcessor
1272
- /processorParam:PremultiplyAlpha=True
1273
- /processorParam:TextureFormat=Compressed
1274
- /build:Fonts/MenuFont.spritefont
1275
-
1276
- #begin Fonts/GameFont.spritefont
1277
- /importer:FontDescriptionImporter
1278
- /processor:FontDescriptionProcessor
1279
- /processorParam:PremultiplyAlpha=True
1280
- /processorParam:TextureFormat=Compressed
1281
- /build:Fonts/GameFont.spritefont
893
+ }
1282
894
  `;
1283
- // Add project assets
1284
- if (project.assets) {
1285
- for (const asset of project.assets) {
1286
- const ext = asset.name.split('.').pop()?.toLowerCase();
1287
- let processor = 'TextureProcessor';
1288
- let importer = 'TextureImporter';
1289
- if (ext === 'ogg' || ext === 'wav' || ext === 'mp3') {
1290
- processor = 'SoundEffectProcessor';
1291
- importer = 'OggImporter';
895
+ this.csharpFiles.set(`${this.config.solutionName}/Systems/Systems.cs`, systemsCs);
896
+ }
897
+ generateScreens(_project) {
898
+ const { namespace } = this.config;
899
+ const screensCs = `using Microsoft.Xna.Framework;
900
+ using Microsoft.Xna.Framework.Content;
901
+ using Microsoft.Xna.Framework.Graphics;
902
+ using Microsoft.Xna.Framework.Input;
903
+
904
+ namespace ${namespace}.Screens
905
+ {
906
+ // ═══════════════════════════════════════════════════════════════
907
+ // SCREEN BASE
908
+ // ═══════════════════════════════════════════════════════════════
909
+
910
+ public abstract class Screen
911
+ {
912
+ public ScreenManager ScreenManager { get; internal set; }
913
+ public bool IsActive { get; set; } = true;
914
+ public bool IsPopup { get; protected set; }
915
+
916
+ protected ContentManager Content => ScreenManager.Game.Content;
917
+ protected GraphicsDevice GraphicsDevice => ScreenManager.GraphicsDevice;
918
+
919
+ public virtual void LoadContent() { }
920
+ public virtual void UnloadContent() { }
921
+ public virtual void Update(GameTime gameTime) { }
922
+ public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch) { }
923
+
924
+ public virtual void HandleInput(InputState input) { }
925
+
926
+ public void ExitScreen()
927
+ {
928
+ ScreenManager.RemoveScreen(this);
929
+ }
930
+ }
931
+
932
+ // ═══════════════════════════════════════════════════════════════
933
+ // SCREEN MANAGER
934
+ // ═══════════════════════════════════════════════════════════════
935
+
936
+ public class ScreenManager : DrawableGameComponent
937
+ {
938
+ private readonly List<Screen> _screens = new();
939
+ private readonly List<Screen> _screensToAdd = new();
940
+ private readonly List<Screen> _screensToRemove = new();
941
+ private SpriteBatch _spriteBatch;
942
+ private InputState _input = new();
943
+
944
+ public new Game Game { get; }
945
+
946
+ public ScreenManager(Game game) : base(game)
947
+ {
948
+ Game = game;
949
+ }
950
+
951
+ protected override void LoadContent()
952
+ {
953
+ _spriteBatch = new SpriteBatch(GraphicsDevice);
954
+ }
955
+
956
+ public override void Update(GameTime gameTime)
957
+ {
958
+ _input.Update();
959
+
960
+ // Add pending screens
961
+ foreach (var screen in _screensToAdd)
962
+ {
963
+ screen.LoadContent();
964
+ _screens.Add(screen);
965
+ }
966
+ _screensToAdd.Clear();
967
+
968
+ // Remove pending screens
969
+ foreach (var screen in _screensToRemove)
970
+ {
971
+ screen.UnloadContent();
972
+ _screens.Remove(screen);
973
+ }
974
+ _screensToRemove.Clear();
975
+
976
+ // Update screens
977
+ foreach (var screen in _screens)
978
+ {
979
+ if (screen.IsActive)
980
+ {
981
+ screen.HandleInput(_input);
982
+ screen.Update(gameTime);
1292
983
  }
1293
- else if (ext === 'fx') {
1294
- processor = 'EffectProcessor';
1295
- importer = 'EffectImporter';
984
+ }
985
+ }
986
+
987
+ public override void Draw(GameTime gameTime)
988
+ {
989
+ foreach (var screen in _screens)
990
+ {
991
+ if (screen.IsActive)
992
+ {
993
+ screen.Draw(gameTime, _spriteBatch);
1296
994
  }
1297
- mgcb += `
1298
- #begin ${asset.name}
1299
- /importer:${importer}
1300
- /processor:${processor}
1301
- /build:${asset.name}
1302
- `;
1303
995
  }
1304
996
  }
1305
- this.csharpFiles.set(`${this.config.solutionName}/Content/Content.mgcb`, mgcb);
997
+
998
+ public void AddScreen(Screen screen)
999
+ {
1000
+ screen.ScreenManager = this;
1001
+ _screensToAdd.Add(screen);
1002
+ }
1003
+
1004
+ public void RemoveScreen(Screen screen)
1005
+ {
1006
+ _screensToRemove.Add(screen);
1007
+ }
1306
1008
  }
1307
- collectAssets(project) {
1308
- if (project.assets) {
1309
- this.assets = [...project.assets];
1009
+
1010
+ // ═══════════════════════════════════════════════════════════════
1011
+ // INPUT STATE
1012
+ // ═══════════════════════════════════════════════════════════════
1013
+
1014
+ public class InputState
1015
+ {
1016
+ public KeyboardState CurrentKeyboardState { get; private set; }
1017
+ public KeyboardState PreviousKeyboardState { get; private set; }
1018
+ public MouseState CurrentMouseState { get; private set; }
1019
+ public MouseState PreviousMouseState { get; private set; }
1020
+ public GamePadState CurrentGamePadState { get; private set; }
1021
+ public GamePadState PreviousGamePadState { get; private set; }
1022
+
1023
+ public void Update()
1024
+ {
1025
+ PreviousKeyboardState = CurrentKeyboardState;
1026
+ PreviousMouseState = CurrentMouseState;
1027
+ PreviousGamePadState = CurrentGamePadState;
1028
+
1029
+ CurrentKeyboardState = Keyboard.GetState();
1030
+ CurrentMouseState = Mouse.GetState();
1031
+ CurrentGamePadState = GamePad.GetState(PlayerIndex.One);
1032
+ }
1033
+
1034
+ public bool IsKeyPressed(Keys key) =>
1035
+ CurrentKeyboardState.IsKeyDown(key) && PreviousKeyboardState.IsKeyUp(key);
1036
+
1037
+ public bool IsKeyHeld(Keys key) =>
1038
+ CurrentKeyboardState.IsKeyDown(key);
1039
+
1040
+ public bool IsKeyReleased(Keys key) =>
1041
+ CurrentKeyboardState.IsKeyUp(key) && PreviousKeyboardState.IsKeyDown(key);
1042
+
1043
+ public Vector2 GetMovement()
1044
+ {
1045
+ Vector2 movement = Vector2.Zero;
1046
+
1047
+ if (IsKeyHeld(Keys.W) || IsKeyHeld(Keys.Up)) movement.Y -= 1;
1048
+ if (IsKeyHeld(Keys.S) || IsKeyHeld(Keys.Down)) movement.Y += 1;
1049
+ if (IsKeyHeld(Keys.A) || IsKeyHeld(Keys.Left)) movement.X -= 1;
1050
+ if (IsKeyHeld(Keys.D) || IsKeyHeld(Keys.Right)) movement.X += 1;
1051
+
1052
+ if (movement != Vector2.Zero)
1053
+ movement = Vector2.Normalize(movement);
1054
+
1055
+ return movement;
1310
1056
  }
1311
1057
  }
1312
- generateGuid() {
1313
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
1314
- const r = (Math.random() * 16) | 0;
1315
- const v = c === 'x' ? r : (r & 0x3) | 0x8;
1316
- return v.toString(16).toUpperCase();
1317
- });
1058
+
1059
+ // ═══════════════════════════════════════════════════════════════
1060
+ // MENU SCREEN
1061
+ // ═══════════════════════════════════════════════════════════════
1062
+
1063
+ public class MenuScreen : Screen
1064
+ {
1065
+ private SpriteFont _font;
1066
+ private int _selectedIndex;
1067
+ private string[] _menuItems = { "Play", "Options", "Exit" };
1068
+
1069
+ public override void LoadContent()
1070
+ {
1071
+ _font = Content.Load<SpriteFont>("Fonts/MenuFont");
1072
+ }
1073
+
1074
+ public override void HandleInput(InputState input)
1075
+ {
1076
+ if (input.IsKeyPressed(Keys.Up))
1077
+ {
1078
+ _selectedIndex--;
1079
+ if (_selectedIndex < 0) _selectedIndex = _menuItems.Length - 1;
1080
+ }
1081
+
1082
+ if (input.IsKeyPressed(Keys.Down))
1083
+ {
1084
+ _selectedIndex++;
1085
+ if (_selectedIndex >= _menuItems.Length) _selectedIndex = 0;
1086
+ }
1087
+
1088
+ if (input.IsKeyPressed(Keys.Enter))
1089
+ {
1090
+ switch (_selectedIndex)
1091
+ {
1092
+ case 0: // Play
1093
+ ScreenManager.AddScreen(new GameplayScreen());
1094
+ ExitScreen();
1095
+ break;
1096
+ case 1: // Options
1097
+ // Options screen
1098
+ break;
1099
+ case 2: // Exit
1100
+ ScreenManager.Game.Exit();
1101
+ break;
1102
+ }
1103
+ }
1104
+ }
1105
+
1106
+ public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
1107
+ {
1108
+ spriteBatch.Begin();
1109
+
1110
+ for (int i = 0; i < _menuItems.Length; i++)
1111
+ {
1112
+ Color color = i == _selectedIndex ? Color.Yellow : Color.White;
1113
+ Vector2 position = new Vector2(640 - _font.MeasureString(_menuItems[i]).X / 2, 300 + i * 50);
1114
+ spriteBatch.DrawString(_font, _menuItems[i], position, color);
1115
+ }
1116
+
1117
+ spriteBatch.End();
1118
+ }
1119
+ }
1120
+
1121
+ // ═══════════════════════════════════════════════════════════════
1122
+ // GAMEPLAY SCREEN
1123
+ // ═══════════════════════════════════════════════════════════════
1124
+
1125
+ public class GameplayScreen : Screen
1126
+ {
1127
+ public override void LoadContent()
1128
+ {
1129
+ // Load level content
1130
+ }
1131
+
1132
+ public override void HandleInput(InputState input)
1133
+ {
1134
+ if (input.IsKeyPressed(Keys.Escape))
1135
+ {
1136
+ ScreenManager.AddScreen(new PauseScreen());
1137
+ }
1138
+
1139
+ Vector2 movement = input.GetMovement();
1140
+ // Apply to player
1141
+ }
1142
+
1143
+ public override void Update(GameTime gameTime)
1144
+ {
1145
+ // Update game logic
1146
+ }
1147
+
1148
+ public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
1149
+ {
1150
+ spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
1151
+
1152
+ // Draw game
1153
+
1154
+ spriteBatch.End();
1155
+ }
1156
+ }
1157
+
1158
+ // ═══════════════════════════════════════════════════════════════
1159
+ // PAUSE SCREEN
1160
+ // ═══════════════════════════════════════════════════════════════
1161
+
1162
+ public class PauseScreen : Screen
1163
+ {
1164
+ public PauseScreen()
1165
+ {
1166
+ IsPopup = true;
1167
+ }
1168
+
1169
+ public override void HandleInput(InputState input)
1170
+ {
1171
+ if (input.IsKeyPressed(Keys.Escape))
1172
+ {
1173
+ ExitScreen();
1174
+ }
1175
+ }
1176
+
1177
+ public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
1178
+ {
1179
+ spriteBatch.Begin();
1180
+
1181
+ // Draw semi-transparent overlay
1182
+ spriteBatch.Draw(
1183
+ Assets.PixelTexture,
1184
+ new Rectangle(0, 0, Game1.ScreenWidth, Game1.ScreenHeight),
1185
+ new Color(0, 0, 0, 0.5f)
1186
+ );
1187
+
1188
+ // Draw pause text
1189
+
1190
+ spriteBatch.End();
1191
+ }
1318
1192
  }
1319
- toPascalCase(str) {
1320
- return str
1321
- .split(/[\s_-]+/)
1322
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
1323
- .join('');
1193
+ }
1194
+ `;
1195
+ this.csharpFiles.set(`${this.config.solutionName}/Screens/Screens.cs`, screensCs);
1196
+ const assetsCs = `using Microsoft.Xna.Framework;
1197
+ using Microsoft.Xna.Framework.Content;
1198
+ using Microsoft.Xna.Framework.Graphics;
1199
+
1200
+ namespace ${namespace}
1201
+ {
1202
+ public static class Assets
1203
+ {
1204
+ // Textures
1205
+ public static Texture2D PixelTexture { get; private set; }
1206
+ public static Texture2D PlayerTexture { get; private set; }
1207
+ public static Texture2D EnemyTexture { get; private set; }
1208
+ public static Texture2D TilesetTexture { get; private set; }
1209
+
1210
+ // Fonts
1211
+ public static SpriteFont MenuFont { get; private set; }
1212
+ public static SpriteFont GameFont { get; private set; }
1213
+
1214
+ public static void Load(ContentManager content)
1215
+ {
1216
+ // Create pixel texture
1217
+ PixelTexture = new Texture2D(Game1.Instance.GraphicsDevice, 1, 1);
1218
+ PixelTexture.SetData(new[] { Color.White });
1219
+
1220
+ // Load textures
1221
+ PlayerTexture = content.Load<Texture2D>("Sprites/player");
1222
+ EnemyTexture = content.Load<Texture2D>("Sprites/enemy");
1223
+ TilesetTexture = content.Load<Texture2D>("Sprites/tileset");
1224
+
1225
+ // Load fonts
1226
+ MenuFont = content.Load<SpriteFont>("Fonts/MenuFont");
1227
+ GameFont = content.Load<SpriteFont>("Fonts/GameFont");
1228
+ }
1324
1229
  }
1325
1230
  }
1326
- /* ══════════════════════════════════════════════════════════════
1327
- EXPORTS
1328
- ══════════════════════════════════════════════════════════════ */
1231
+ `;
1232
+ this.csharpFiles.set(`${this.config.solutionName}/Assets.cs`, assetsCs);
1233
+ }
1234
+ generateContentMgcb(project) {
1235
+ let mgcb = `#----------------------------- Global Properties ----------------------------#
1236
+
1237
+ /outputDir:bin/$(Platform)
1238
+ /intermediateDir:obj/$(Platform)
1239
+ /platform:DesktopGL
1240
+ /config:
1241
+ /profile:Reach
1242
+ /compress:False
1243
+
1244
+ #-------------------------------- References --------------------------------#
1245
+
1246
+ /reference:..\\..\\packages\\MonoGame.Extended.Content.Pipeline\\4.0.0\\tools\\MonoGame.Extended.Content.Pipeline.dll
1329
1247
 
1330
- export { DEFAULT_MONOGAME_CONFIG, MonoGameExporter };
1248
+ #---------------------------------- Content ---------------------------------#
1249
+
1250
+ #begin Fonts/MenuFont.spritefont
1251
+ /importer:FontDescriptionImporter
1252
+ /processor:FontDescriptionProcessor
1253
+ /processorParam:PremultiplyAlpha=True
1254
+ /processorParam:TextureFormat=Compressed
1255
+ /build:Fonts/MenuFont.spritefont
1256
+
1257
+ #begin Fonts/GameFont.spritefont
1258
+ /importer:FontDescriptionImporter
1259
+ /processor:FontDescriptionProcessor
1260
+ /processorParam:PremultiplyAlpha=True
1261
+ /processorParam:TextureFormat=Compressed
1262
+ /build:Fonts/GameFont.spritefont
1263
+ `;
1264
+ if (project.assets) {
1265
+ for (const asset of project.assets) {
1266
+ const ext = asset.name.split(".").pop()?.toLowerCase();
1267
+ let processor = "TextureProcessor";
1268
+ let importer = "TextureImporter";
1269
+ if (ext === "ogg" || ext === "wav" || ext === "mp3") {
1270
+ processor = "SoundEffectProcessor";
1271
+ importer = "OggImporter";
1272
+ } else if (ext === "fx") {
1273
+ processor = "EffectProcessor";
1274
+ importer = "EffectImporter";
1275
+ }
1276
+ mgcb += `
1277
+ #begin ${asset.name}
1278
+ /importer:${importer}
1279
+ /processor:${processor}
1280
+ /build:${asset.name}
1281
+ `;
1282
+ }
1283
+ }
1284
+ this.csharpFiles.set(`${this.config.solutionName}/Content/Content.mgcb`, mgcb);
1285
+ }
1286
+ collectAssets(project) {
1287
+ if (project.assets) {
1288
+ this.assets = [...project.assets];
1289
+ }
1290
+ }
1291
+ generateGuid() {
1292
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
1293
+ const r = Math.random() * 16 | 0;
1294
+ const v = c === "x" ? r : r & 3 | 8;
1295
+ return v.toString(16).toUpperCase();
1296
+ });
1297
+ }
1298
+ toPascalCase(str) {
1299
+ return str.split(/[\s_-]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
1300
+ }
1301
+ }
1302
+ export {
1303
+ DEFAULT_MONOGAME_CONFIG,
1304
+ MonoGameExporter
1305
+ };