├── .gitignore ├── .gitmodules ├── LICENSE ├── Nez.FNA.Samples.sln ├── Nez.MG37.Samples.sln ├── Nez.MG38.NET6.Samples.sln ├── Nez.MG38.Samples.sln ├── Nez.Samples ├── Content │ ├── AnimatedTiles │ │ ├── desert-palace-lamp.png │ │ ├── desert-palace-tiles.png │ │ └── desert-palace.tmx │ ├── DeferredLighting │ │ ├── bg.png │ │ ├── bgNorm.png │ │ ├── moon.png │ │ ├── moonNorm.png │ │ ├── orange.png │ │ └── orangeNorm.png │ ├── DestructableMap │ │ ├── desert-palace-tiles2x.png │ │ └── destructable-map.tmx │ ├── NinjaAdventure │ │ ├── characters │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ └── 6.png │ │ ├── map │ │ │ ├── tilemap.tmx │ │ │ └── tileset.png │ │ └── plume.png │ ├── ParticleDesigner │ │ ├── Atomic Bubble.pex │ │ ├── Blue Flame.pex │ │ ├── Blue Galaxy.pex │ │ ├── Comet.pex │ │ ├── Crazy Blue.pex │ │ ├── Electrons.pex │ │ ├── Fire.pex │ │ ├── Foam.pex │ │ ├── Giros Gratis.pex │ │ ├── Into The Blue.pex │ │ ├── JasonChoi_Flash.pex │ │ ├── JasonChoi_Swirl01.pex │ │ ├── JasonChoi_rising up.pex │ │ ├── Leaves.pex │ │ ├── Meks Blood Spill.pex │ │ ├── Plasma Glow.pex │ │ ├── Real Popcorn.pex │ │ ├── Shooting Fireball.pex │ │ ├── Snow.pex │ │ ├── The Sun.pex │ │ ├── Thingy.pex │ │ ├── Touch Up.pex │ │ ├── Trippy.pex │ │ ├── Winner Stars.pex │ │ ├── huo1.pex │ │ ├── thingy_tex.png │ │ └── wu1.pex │ ├── Platformer │ │ ├── caveman.png │ │ ├── tiledMap.tmx │ │ └── tileset.png │ ├── SVG │ │ └── farseer-svg.svg │ ├── Shadows │ │ ├── Block.png │ │ ├── BlockGlow.png │ │ ├── Light.fx │ │ ├── Light.mgfxo │ │ └── sprite-light.png │ ├── Shared │ │ └── moon.png │ └── SpriteLights │ │ ├── bg.png │ │ ├── pixel-sprite-light.png │ │ ├── sprite-light.png │ │ └── tube-light.png ├── Game1.cs ├── Icon.ico ├── Icon.png ├── MonoGame.Framework.dll.config ├── Nez.FNA.Samples.csproj ├── Nez.FNA.Samples.csproj.user ├── Nez.MG37.Samples.csproj ├── Nez.MG38.NET6.Samples.csproj ├── Nez.MG38.Samples.csproj ├── Program.cs ├── SampleHelpers │ ├── MouseFollow.cs │ └── SampleScene.cs ├── Scenes │ └── Samples │ │ ├── AI │ │ ├── AIScene.cs │ │ ├── AIUI.cs │ │ ├── BehaviorTreeMiner.cs │ │ ├── GOAPMiner.cs │ │ ├── MinerState.cs │ │ ├── UtilityAIActions │ │ │ ├── ChooseBestLocation.cs │ │ │ └── MoveToBestLocation.cs │ │ └── UtilityMiner.cs │ │ ├── Animated Tiles │ │ └── AnimatedTilesScene.cs │ │ ├── Deferred Lighting │ │ ├── DeferredLightingController.cs │ │ └── DeferredLightingScene.cs │ │ ├── Destructable Tilemap │ │ ├── DestructableTilemapScene.cs │ │ └── PlayerDashMover.cs │ │ ├── Empty Scene │ │ └── BasicScene.cs │ │ ├── Farseer SVG │ │ └── FarseerSVGScene.cs │ │ ├── LineCasting │ │ ├── LineCaster.cs │ │ └── LineCastingScene.cs │ │ ├── Mesh Shadows │ │ └── MeshShadowsScene.cs │ │ ├── Ninja Adventure │ │ ├── CameraBounds.cs │ │ ├── FireballProjectileController.cs │ │ ├── Ninja.cs │ │ ├── NinjaAdventureScene.cs │ │ └── ProjectileHitDetector.cs │ │ ├── Particles │ │ ├── ParticleSystemSelector.cs │ │ ├── ParticlesScene.cs │ │ └── PexExporter.cs │ │ ├── Pathfinding │ │ ├── Pathfinder.cs │ │ └── PathfindingScene.cs │ │ ├── Platformer │ │ ├── Caveman.cs │ │ ├── PlatformerDangerZone.cs │ │ ├── PlatformerItem.cs │ │ └── PlatformerScene.cs │ │ ├── RigidBodies │ │ └── RigidBodyScene.cs │ │ ├── Spring Grid │ │ ├── GridModifier.cs │ │ └── SpringGridScene.cs │ │ ├── Sprite Lights │ │ └── SpriteLightsScene.cs │ │ ├── Stencil Shadows │ │ ├── LiveLightController.cs │ │ └── StencilShadowsScene.cs │ │ └── Verlet Physics │ │ ├── VerletPhysicsScene.cs │ │ └── VerletSystem.cs ├── Shared │ ├── ContentPathGenerator.cs │ ├── ContentPathGenerator.tt │ ├── MovingPlatform.cs │ ├── PressKeyToPerformAction.cs │ ├── SimpleMover.cs │ └── TriggerListener.cs ├── app.manifest ├── libSDL2-2.0.0.dylib └── libopenal.1.dylib └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # Visual Studio 2015 cache/options directory 25 | .vs/ 26 | # Uncomment if you have tasks that create the project's static files in wwwroot 27 | #wwwroot/ 28 | 29 | # MSTest test Results 30 | [Tt]est[Rr]esult*/ 31 | [Bb]uild[Ll]og.* 32 | 33 | # NUNIT 34 | *.VisualState.xml 35 | TestResult.xml 36 | 37 | # Build Results of an ATL Project 38 | [Dd]ebugPS/ 39 | [Rr]eleasePS/ 40 | dlldata.c 41 | 42 | # DNX 43 | project.lock.json 44 | artifacts/ 45 | 46 | *_i.c 47 | *_p.c 48 | *_i.h 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.tmp_proj 63 | *.log 64 | *.vspscc 65 | *.vssscc 66 | .builds 67 | *.pidb 68 | *.svclog 69 | *.scc 70 | 71 | # Chutzpah Test files 72 | _Chutzpah* 73 | 74 | # Visual C++ cache files 75 | ipch/ 76 | *.aps 77 | *.ncb 78 | *.opendb 79 | *.opensdf 80 | *.sdf 81 | *.cachefile 82 | 83 | # Visual Studio profiler 84 | *.psess 85 | *.vsp 86 | *.vspx 87 | *.sap 88 | 89 | # TFS 2012 Local Workspace 90 | $tf/ 91 | 92 | # Guidance Automation Toolkit 93 | *.gpState 94 | 95 | # ReSharper is a .NET coding add-in 96 | _ReSharper*/ 97 | *.[Rr]e[Ss]harper 98 | *.DotSettings.user 99 | 100 | # JustCode is a .NET coding add-in 101 | .JustCode 102 | 103 | # TeamCity is a build add-in 104 | _TeamCity* 105 | 106 | # DotCover is a Code Coverage Tool 107 | *.dotCover 108 | 109 | # NCrunch 110 | _NCrunch_* 111 | .*crunch*.local.xml 112 | nCrunchTemp_* 113 | 114 | # MightyMoose 115 | *.mm.* 116 | AutoTest.Net/ 117 | 118 | # Web workbench (sass) 119 | .sass-cache/ 120 | 121 | # Installshield output folder 122 | [Ee]xpress/ 123 | 124 | # DocProject is a documentation generator add-in 125 | DocProject/buildhelp/ 126 | DocProject/Help/*.HxT 127 | DocProject/Help/*.HxC 128 | DocProject/Help/*.hhc 129 | DocProject/Help/*.hhk 130 | DocProject/Help/*.hhp 131 | DocProject/Help/Html2 132 | DocProject/Help/html 133 | 134 | # Click-Once directory 135 | publish/ 136 | 137 | # Publish Web Output 138 | *.[Pp]ublish.xml 139 | *.azurePubxml 140 | # TODO: Comment the next line if you want to checkin your web deploy settings 141 | # but database connection strings (with potential passwords) will be unencrypted 142 | *.pubxml 143 | *.publishproj 144 | 145 | # NuGet Packages 146 | *.nupkg 147 | # The packages folder can be ignored because of Package Restore 148 | **/packages/* 149 | # except build/, which is used as an MSBuild target. 150 | !**/packages/build/ 151 | # Uncomment if necessary however generally it will be regenerated when needed 152 | #!**/packages/repositories.config 153 | # NuGet v3's project.json files produces more ignoreable files 154 | *.nuget.props 155 | *.nuget.targets 156 | 157 | # Microsoft Azure Build Output 158 | csx/ 159 | *.build.csdef 160 | 161 | # Microsoft Azure Emulator 162 | ecf/ 163 | rcf/ 164 | 165 | # Microsoft Azure ApplicationInsights config file 166 | ApplicationInsights.config 167 | 168 | # Windows Store app package directory 169 | AppPackages/ 170 | BundleArtifacts/ 171 | 172 | # Visual Studio cache files 173 | # files ending in .cache can be ignored 174 | *.[Cc]ache 175 | # but keep track of directories ending in .cache 176 | !*.[Cc]ache/ 177 | 178 | # Others 179 | ClientBin/ 180 | ~$* 181 | *~ 182 | *.dbmdl 183 | *.dbproj.schemaview 184 | *.pfx 185 | *.publishsettings 186 | node_modules/ 187 | orleans.codegen.cs 188 | 189 | # RIA/Silverlight projects 190 | Generated_Code/ 191 | 192 | # Backup & report files from converting an old project file 193 | # to a newer Visual Studio version. Backup files are not needed, 194 | # because we have git ;-) 195 | _UpgradeReport_Files/ 196 | Backup*/ 197 | UpgradeLog*.XML 198 | UpgradeLog*.htm 199 | 200 | # SQL Server files 201 | *.mdf 202 | *.ldf 203 | 204 | # Business Intelligence projects 205 | *.rdl.data 206 | *.bim.layout 207 | *.bim_*.settings 208 | 209 | # Microsoft Fakes 210 | FakesAssemblies/ 211 | 212 | # GhostDoc plugin setting file 213 | *.GhostDoc.xml 214 | 215 | # Node.js Tools for Visual Studio 216 | .ntvs_analysis.dat 217 | 218 | # Visual Studio 6 build log 219 | *.plg 220 | 221 | # Visual Studio 6 workspace options file 222 | *.opt 223 | 224 | # Visual Studio LightSwitch build output 225 | **/*.HTMLClient/GeneratedArtifacts 226 | **/*.DesktopClient/GeneratedArtifacts 227 | **/*.DesktopClient/ModelManifest.xml 228 | **/*.Server/GeneratedArtifacts 229 | **/*.Server/ModelManifest.xml 230 | _Pvt_Extensions 231 | 232 | # Paket dependency manager 233 | .paket/paket.exe 234 | 235 | # FAKE - F# Make 236 | .fake/ 237 | .idea 238 | fnalibs 239 | FNA 240 | .DS_Store 241 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Nez"] 2 | path = Nez 3 | url = https://prime31@github.com/prime31/Nez.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Mike 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Nez.FNA.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA", "Nez\Nez.Portable\Nez.FNA.csproj", "{60B7197D-D0D5-405C-90A2-A56903E9B039}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA.FarseerPhysics", "Nez\Nez.FarseerPhysics\Nez.FNA.FarseerPhysics.csproj", "{63E831F4-B847-4150-B5AF-CBE059EE27B8}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA.Samples", "Nez.Samples\Nez.FNA.Samples.csproj", "{C680D0AE-9861-4000-AFFC-952D62A01E5C}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA", "FNA\FNA.csproj", "{35253CE1-C864-4CD3-8249-4D1319748E8F}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA.ImGui", "Nez\Nez.ImGui\Nez.FNA.ImGui.csproj", "{EEB096FA-92A0-4DD5-8350-F35B4AB001BA}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FNA.Persistence", "Nez\Nez.Persistence\Nez.FNA.Persistence.csproj", "{136941FE-E3A3-4BD6-8B30-514924B2856E}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|x86 = Debug|x86 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {63E831F4-B847-4150-B5AF-CBE059EE27B8}.Debug|x86.ActiveCfg = Debug|Any CPU 23 | {63E831F4-B847-4150-B5AF-CBE059EE27B8}.Debug|x86.Build.0 = Debug|Any CPU 24 | {63E831F4-B847-4150-B5AF-CBE059EE27B8}.Release|x86.ActiveCfg = Release|Any CPU 25 | {63E831F4-B847-4150-B5AF-CBE059EE27B8}.Release|x86.Build.0 = Release|Any CPU 26 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|x86.ActiveCfg = Debug|Any CPU 27 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|x86.Build.0 = Debug|Any CPU 28 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|x86.ActiveCfg = Release|Any CPU 29 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|x86.Build.0 = Release|Any CPU 30 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|x86.ActiveCfg = Release|x86 31 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|x86.Build.0 = Release|x86 32 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|x86.ActiveCfg = Debug|Any CPU 33 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|x86.Build.0 = Debug|Any CPU 34 | {35253CE1-C864-4CD3-8249-4D1319748E8F}.Debug|x86.ActiveCfg = Debug|Any CPU 35 | {35253CE1-C864-4CD3-8249-4D1319748E8F}.Debug|x86.Build.0 = Debug|Any CPU 36 | {35253CE1-C864-4CD3-8249-4D1319748E8F}.Release|x86.ActiveCfg = Release|Any CPU 37 | {35253CE1-C864-4CD3-8249-4D1319748E8F}.Release|x86.Build.0 = Release|Any CPU 38 | {EEB096FA-92A0-4DD5-8350-F35B4AB001BA}.Debug|x86.ActiveCfg = Debug|Any CPU 39 | {EEB096FA-92A0-4DD5-8350-F35B4AB001BA}.Debug|x86.Build.0 = Debug|Any CPU 40 | {EEB096FA-92A0-4DD5-8350-F35B4AB001BA}.Release|x86.ActiveCfg = Release|Any CPU 41 | {EEB096FA-92A0-4DD5-8350-F35B4AB001BA}.Release|x86.Build.0 = Release|Any CPU 42 | {136941FE-E3A3-4BD6-8B30-514924B2856E}.Debug|x86.ActiveCfg = Debug|Any CPU 43 | {136941FE-E3A3-4BD6-8B30-514924B2856E}.Debug|x86.Build.0 = Debug|Any CPU 44 | {136941FE-E3A3-4BD6-8B30-514924B2856E}.Release|x86.ActiveCfg = Release|Any CPU 45 | {136941FE-E3A3-4BD6-8B30-514924B2856E}.Release|x86.Build.0 = Release|Any CPU 46 | EndGlobalSection 47 | EndGlobal 48 | -------------------------------------------------------------------------------- /Nez.MG37.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez", "Nez\Nez.Portable\Nez.csproj", "{60B7197D-D0D5-405C-90A2-A56903E9B039}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FarseerPhysics", "Nez\Nez.FarseerPhysics\Nez.FarseerPhysics.csproj", "{CB893B1D-CE04-4492-B957-31CE0DCA6C15}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.Samples", "Nez.Samples\Nez.MG37.Samples.csproj", "{C680D0AE-9861-4000-AFFC-952D62A01E5C}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.ImGui", "Nez\Nez.ImGui\Nez.ImGui.csproj", "{C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.Persistence", "Nez\Nez.Persistence\Nez.Persistence.csproj", "{54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|x86 = Debug|x86 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|x86.ActiveCfg = Debug|Any CPU 21 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|x86.Build.0 = Debug|Any CPU 22 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|x86.ActiveCfg = Release|Any CPU 23 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|x86.Build.0 = Release|Any CPU 24 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Debug|x86.ActiveCfg = Debug|Any CPU 25 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Debug|x86.Build.0 = Debug|Any CPU 26 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Release|x86.ActiveCfg = Release|Any CPU 27 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Release|x86.Build.0 = Release|Any CPU 28 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|x86.ActiveCfg = Debug|x86 29 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|x86.Build.0 = Debug|x86 30 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|x86.ActiveCfg = Release|x86 31 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|x86.Build.0 = Release|x86 32 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Debug|x86.ActiveCfg = Debug|Any CPU 33 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Debug|x86.Build.0 = Debug|Any CPU 34 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Release|x86.ActiveCfg = Release|Any CPU 35 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Release|x86.Build.0 = Release|Any CPU 36 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Debug|x86.ActiveCfg = Debug|Any CPU 37 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Debug|x86.Build.0 = Debug|Any CPU 38 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Release|x86.ActiveCfg = Release|Any CPU 39 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Release|x86.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /Nez.MG38.NET6.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez", "Nez\Nez.Portable\Nez.MG38.csproj", "{60B7197D-D0D5-405C-90A2-A56903E9B039}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FarseerPhysics", "Nez\Nez.FarseerPhysics\Nez.MG38.FarseerPhysics.csproj", "{CB893B1D-CE04-4492-B957-31CE0DCA6C15}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.MG38.NET6.Samples", "Nez.Samples\Nez.MG38.NET6.Samples.csproj", "{C680D0AE-9861-4000-AFFC-952D62A01E5C}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.ImGui", "Nez\Nez.ImGui\Nez.MG38.ImGui.csproj", "{C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.Persistence", "Nez\Nez.Persistence\Nez.MG38.Persistence.csproj", "{54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Release|Any CPU.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /Nez.MG38.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez", "Nez\Nez.Portable\Nez.MG38.csproj", "{60B7197D-D0D5-405C-90A2-A56903E9B039}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.FarseerPhysics", "Nez\Nez.FarseerPhysics\Nez.MG38.FarseerPhysics.csproj", "{CB893B1D-CE04-4492-B957-31CE0DCA6C15}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.Samples", "Nez.Samples\Nez.MG38.Samples.csproj", "{C680D0AE-9861-4000-AFFC-952D62A01E5C}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.ImGui", "Nez\Nez.ImGui\Nez.MG38.ImGui.csproj", "{C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nez.Persistence", "Nez\Nez.Persistence\Nez.MG38.Persistence.csproj", "{54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {60B7197D-D0D5-405C-90A2-A56903E9B039}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {CB893B1D-CE04-4492-B957-31CE0DCA6C15}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {C680D0AE-9861-4000-AFFC-952D62A01E5C}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {C0AB8DD9-380E-48C4-86D0-F2B53CC5507D}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {54A71CF9-8A65-4EE1-9D8F-C451CEF8B252}.Release|Any CPU.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /Nez.Samples/Content/AnimatedTiles/desert-palace-lamp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/AnimatedTiles/desert-palace-lamp.png -------------------------------------------------------------------------------- /Nez.Samples/Content/AnimatedTiles/desert-palace-tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/AnimatedTiles/desert-palace-tiles.png -------------------------------------------------------------------------------- /Nez.Samples/Content/AnimatedTiles/desert-palace.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 44 | 1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,1,1, 45 | 1,1,18,5,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,6,7,8,20,1,1, 46 | 1,1,18,21,69,70,71,70,71,70,71,70,71,70,71,70,71,70,71,70,71,70,71,70,71,70,71,72,24,20,1,1, 47 | 1,1,18,37,85,9,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,12,88,40,20,1,1, 48 | 1,1,18,21,101,25,26,27,26,27,26,27,26,27,26,27,26,27,26,27,26,27,26,27,26,27,28,104,24,20,1,1, 49 | 1,1,18,37,85,41,42,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,43,44,88,40,20,1,1, 50 | 1,1,18,21,101,25,43,19,22,23,22,23,49,50,50,50,50,50,50,2684354609,22,23,22,23,19,27,28,104,24,20,1,1, 51 | 1,1,18,37,85,41,42,19,38,39,38,39,1610612786,65,66,65,66,65,66,2684354610,38,39,38,39,19,43,44,88,40,20,1,1, 52 | 1,1,18,21,101,25,26,19,22,23,22,23,1610612786,67,68,67,68,67,68,2684354610,22,23,22,23,19,27,28,104,24,20,1,1, 53 | 1,1,18,37,85,41,42,19,38,39,38,39,1610612786,65,66,65,66,65,66,2684354610,38,39,38,39,19,43,44,88,40,20,1,1, 54 | 1,1,18,21,101,25,26,19,49,50,50,50,51,67,68,67,68,67,68,2684354611,50,50,50,2684354609,19,27,28,104,24,20,1,1, 55 | 1,1,18,37,85,41,42,19,1610612786,65,66,65,66,65,66,65,66,65,66,65,66,65,66,2684354610,19,43,44,88,40,20,1,1, 56 | 1,1,18,21,101,25,26,19,1610612786,67,68,67,68,67,68,67,68,67,68,67,68,67,68,2684354610,19,27,28,104,24,20,1,1, 57 | 1,1,18,37,85,41,42,19,1610612785,3221225522,3221225522,3221225522,1610612787,65,66,65,66,65,66,3221225523,3221225522,3221225522,3221225522,3221225521,19,43,44,88,40,20,1,1, 58 | 1,1,18,21,101,25,26,19,19,19,19,19,1610612786,67,68,67,68,67,68,2684354610,19,19,19,19,19,27,28,104,24,20,1,1, 59 | 1,1,18,37,85,41,42,43,42,43,42,19,1610612786,65,66,65,66,65,66,2684354610,19,43,42,43,42,43,44,88,40,20,1,1, 60 | 1,1,18,21,101,25,26,27,26,27,26,19,1610612786,67,68,67,68,67,68,2684354610,19,27,26,27,26,27,28,104,24,20,1,1, 61 | 1,1,18,37,85,41,42,43,42,43,42,19,1610612785,3221225522,3221225522,3221225522,3221225522,3221225522,3221225522,3221225521,19,43,42,43,42,43,44,88,40,20,1,1, 62 | 1,1,18,21,101,25,26,27,26,27,26,19,19,19,22,23,22,23,19,19,19,27,26,27,26,27,28,104,24,20,1,1, 63 | 1,1,18,37,85,41,42,43,42,43,42,43,42,19,38,39,38,39,19,43,42,43,42,43,42,43,44,88,40,20,1,1, 64 | 1,1,18,21,101,25,43,27,26,27,26,27,26,19,22,23,22,23,19,27,26,27,26,27,26,27,28,104,24,20,1,1, 65 | 1,1,18,37,85,41,42,43,42,43,42,43,42,19,38,39,38,39,19,43,42,43,42,43,42,43,44,88,40,20,1,1, 66 | 1,1,18,21,101,57,58,59,58,59,58,59,58,59,58,59,58,59,58,59,58,59,58,59,58,59,60,104,24,20,1,1, 67 | 1,1,18,37,117,118,119,118,119,118,119,118,119,118,73,74,75,76,119,118,119,118,119,118,119,118,119,120,40,20,1,1, 68 | 1,1,18,53,54,55,54,55,54,55,54,55,54,55,89,90,90,92,54,55,54,55,54,55,54,55,54,55,56,20,1,1, 69 | 1,1,34,35,35,35,35,35,35,35,35,35,35,35,105,106,107,108,35,35,35,35,35,35,35,35,35,35,35,36,1,1, 70 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 71 | 72 | 73 | 74 | 75 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 76 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 77 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 78 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 79 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 80 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 81 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 82 | 0,0,0,0,0,0,0,0,0,257,0,0,0,0,0,0,0,0,0,0,0,257,0,0,0,0,0,0,0,0,0,0, 83 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 84 | 0,0,0,0,0,0,0,0,0,259,0,0,0,0,0,0,0,0,0,0,0,259,0,0,0,0,0,0,0,0,0,0, 85 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 86 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 87 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 88 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 89 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 90 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 91 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 92 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 93 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 94 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 95 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 96 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 97 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 98 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 99 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 100 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 101 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 102 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /Nez.Samples/Content/DeferredLighting/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/DeferredLighting/bg.png -------------------------------------------------------------------------------- /Nez.Samples/Content/DeferredLighting/bgNorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/DeferredLighting/bgNorm.png -------------------------------------------------------------------------------- /Nez.Samples/Content/DeferredLighting/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/DeferredLighting/moon.png -------------------------------------------------------------------------------- /Nez.Samples/Content/DeferredLighting/moonNorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/DeferredLighting/moonNorm.png -------------------------------------------------------------------------------- /Nez.Samples/Content/DeferredLighting/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/DeferredLighting/orange.png -------------------------------------------------------------------------------- /Nez.Samples/Content/DeferredLighting/orangeNorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/DeferredLighting/orangeNorm.png -------------------------------------------------------------------------------- /Nez.Samples/Content/DestructableMap/desert-palace-tiles2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/DestructableMap/desert-palace-tiles2x.png -------------------------------------------------------------------------------- /Nez.Samples/Content/DestructableMap/destructable-map.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | eJy9lkkOwzAIRb3tsMuqUi9QqRfocP9zlSwiuV8MH5sEiUUdwK/4x+TUWjsf6JdE3FX8Jr60f1tgzXqOcWjacytP+33v+CwehoFly8ZtfNY+7B5a/mhebxEf1vHOlOWJcvr6Gl9WW5W8mNvzeQxMvUpG5BvRP8Yw+s3oeTWGj2Fh7qMoXmNAvkh3jC5Z0/iwvtU/pkdHWPR+eOad4azuNsP7pbKPDF9UB/s38p+ZOEtrUfzM+fZ7VdsI357vBvZ0Dz52LrL1te8rZt4yfNa6d69qa9r7kdG6F1Mxj9nvA2t2RXM3imXvl4xmIp6RWW7lr3yPZO0Z/Wf78BR/ib/FP4FXxWTivuI/nVYdRw== 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/characters/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/characters/1.png -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/characters/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/characters/2.png -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/characters/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/characters/3.png -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/characters/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/characters/4.png -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/characters/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/characters/5.png -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/characters/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/characters/6.png -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/map/tilemap.tmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | eJzVmEuO00AQhmPlcLayQjxOYC/RIE5gL0cgbPbtJRuUSwwI7oUj6lO+FM6Mg2Yzllpx3N1Vf9fjr7J3u5dzvdrvdq+fGG+W8XZlvFtGW+12/TLKMobq/P80uvid43eI+znuB82xronfErK43i+67p4YH5bxaWV83P/FUkL+SW+te2OuA7dxdlrPufLgur+CwePzledfwp4nneMyvobek85D3E+BY4xnU6yfYn4MPGNaj4+4vm3AeW1835/9jd5j6G2ks4vnY4wm1taBfY61d3FWzn6rPa+Nkz2Ju2OMOmGYZK+jcDbx/6B5zjr/p98fw9nF+fEZ/jYeMIHDcYk9fYZSneP+uXCWhHESDvzcJl/P4V/mizBP1WVuPac90U0O9dWZX8jjOfDCPV3ES69zwEWt9j0XTuQSX6PygjwnLojZXnY7yJ5wQludc5HrYdH145HxMzD9Wpn7vb+Ms0Z6wDEFrmN1mf+ndXeBjTwEK7jN88SX6wn+OK29l+1cM3rJQwZYSsQf+ZzzpKsu+Qn7swY8jk/sS50AC/lmnIOwMe96BM87/7Eh9sL/o+YG+QP/EE/ZntRUbAoG46yrM/9yLjBP0lUSFurmoTrXAccB/vY5yCUuPzd3ce8YaNL/QbLdbxAT4EUWdR27ILPT2lbrzJ+D5PbSjU1byUNXkZySdBo7nO5+atYe5tiXz2179trruCBXzHv285oPHNuzMHSS4ZxlD/NgZZ/j02eBtzrJ9/NG8hxDYHVcsKZouO8jd12jrJs9xllrTa+14MI24HU8uFfM9nIcIjPnA//dp3qP49NnrLW+kV5w5DhybNqHnWTZBpwRGSXJZD/cxuVaSpxjX3yJPesVOX5nwN+sbTXHmdrqMl6dH+ZIzm7+JHeZt09yLpXqX3s5l9zjmh+ybfM5kZef5XqEbL9b4Wf71dhYi33hBOOyfczNnAf+c667BzMv9dozV5f2s60dx+Yx9wid9GB7c79z0fgH7TU3ux45Do3LnGiMrfRxJvvB/O6+xnFqnrTNHWfmT+QOmit6lmuodWQ/+b91uc7luMl5gH0yTueaewjL8zcD29++sr+d15wvx4hrgn2SY8R+75IM+xT59pH7AeN2jXEtXesF/S0i86i5wX7PHEuMuuZu7U0cf7X2d3rmWtloHc+dL8bZJB3uL8mFrb2J7Zm522vWvjOx3u/N5vnMzebMW3sT4zFHOL57DdvRfJD97rgyLvcTt/QmrmXmuVxH8jewtZx3fWeNv1O4v3bub+lN8vsdZ3EPkHtS1y/b2fFZJN/9xZxkbe1NjLlo3ZD051zEX+DIvMSc7ZRr6S29yax9Hj7bUK3zQH7n9XuH9ziH+A9nbO1NnJOOZ5/d73TWV2s/azLPD0lffj/Y2pu4/8j85p7dMeVf5695yRzt947MOVt7E39LMo/mnsP5g5w57bPf3V+ZE+xT+9DvN3Xa6/zphSNzuN+lzJ3uY7M93dOYR9okw32Rbct9to+5yfHuHDMn5J4A3Lanc9hc6V7D9apJY5aOHKescX7jjzV+Jbaxw0u6/gCGptfW 81 | 82 | 83 | 84 | 85 | eJztlFkKwjAURdPdirqMVl2HugfnYQ+O1VWoYP30BvpAg2BCm6biPXCgzUc5vCRVihBCCCGEFKUZKdWC7Sh0yTvSJSawC2NjPXR7J++ysfcjnXHAmbp0hpwpO/+rU/5HiUNjAw4r7jTnqBsGX6y6UdOvQQMJxwT7PbV0ZpyNJd5XcO35zOjGLdxbujFa73hewKPn3p1Do3gwWnRr9tLro7WMTuGE9bOn1gu+N3ZoHMHbhwZ9TtO8cw4fHmaqW6+Wmo1yj9K8L/PUWIQqZlgGcn/qOENCCCmbJ6c2pLs= 86 | 87 | 88 | 89 | 90 | eJztlrkNAjEQRe1iuGlil7MdoAog4mgB6IEM6IEcSqACXkBAgNAujG2E/pOe7JF8jGyPZOeEEL/E1Ds3w7m3iUOxYf0t7rxNHIoD6x/x5G1iISxRvduiehciLRdq55qwflLv/88UPVvdgUjJq/enNymEEJ/TwCa2sJ04l3f0sI8DHBYYX8Eq1rAeMK9vyTDHDnYj7jvCMU5KzNkHysWac4mxGf+HPOIfYvHUvz3aJa5wHS8NEYE7FdFPZA== 91 | 92 | 93 | 94 | 95 | eJzt1k8OQ0AYh+GZZf8lLqH3qUabHoKuSndcjnP5rawsGsZ8ou+TvAsSTBiTcQ5Y5uady9TdhzleS6H7l+rtwxwD/4j/HQDi67QW9YbrkfXz9+zXd8s3gKWp+cecBID5LqpRrUpshxLUQR3VSZ2Nx7JFuXqop/VAAnnNvC7V/uEacQ/xmThXqVp94w0DGA3TmyTT 96 | 97 | 98 | 99 | 100 | eJztme0JgzAQhiPt/w6ibekUDuIgQh2joN3DQTKICzRHCYaXJEbMh4E8cOjpQR6jF5A0FWNNoriLeIh4OtTNjLHX9ViEZmar5xammuK5ssfTRI6e3wtjbxHD5Z/T+ShiUvJBuY/1mIf0RC/M0Uu9j3lITxnECONijvWYh/IMRY6eLmt56nV+C9XTBn5fur7Zk0t4Ak9bf5v6fQnsube/Tf1+q9w8U1Nn4tlm4tll4um6LsVg0vS5JIanbXxXzjSfNmJ7us4t1pX59EvxtKP7TlOvSz4onn4pnn4pnn45myeHkMyQp4YrRw7XF0O97rlSQY70z4mYnis0HI4Scqw1nmeDHFsPnqHnnRw7xVM3luldxIQc+wzee79zv2lrv+rofpdpD+wj4gdyDp77 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/map/tileset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/map/tileset.png -------------------------------------------------------------------------------- /Nez.Samples/Content/NinjaAdventure/plume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/NinjaAdventure/plume.png -------------------------------------------------------------------------------- /Nez.Samples/Content/ParticleDesigner/Blue Galaxy.pex: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Nez.Samples/Content/ParticleDesigner/Plasma Glow.pex: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Nez.Samples/Content/ParticleDesigner/Thingy.pex: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Nez.Samples/Content/ParticleDesigner/Winner Stars.pex: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Nez.Samples/Content/ParticleDesigner/thingy_tex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/ParticleDesigner/thingy_tex.png -------------------------------------------------------------------------------- /Nez.Samples/Content/Platformer/caveman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/Platformer/caveman.png -------------------------------------------------------------------------------- /Nez.Samples/Content/Platformer/tileset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/Platformer/tileset.png -------------------------------------------------------------------------------- /Nez.Samples/Content/SVG/farseer-svg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Layer 1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Nez.Samples/Content/Shadows/Block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/Shadows/Block.png -------------------------------------------------------------------------------- /Nez.Samples/Content/Shadows/BlockGlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/Shadows/BlockGlow.png -------------------------------------------------------------------------------- /Nez.Samples/Content/Shadows/Light.fx: -------------------------------------------------------------------------------- 1 | static const float3 black = float3( 0.0f, 0.0f, 0.0f ); 2 | 3 | float2 lightSource; // Light position in 2D world space 4 | float3 lightColor; // Color of the light 5 | float lightRadius; // Radius of the light 6 | float4x4 viewProjectionMatrix; // camera view-proj matrix 7 | 8 | 9 | struct VertexShaderInput 10 | { 11 | float4 Position : POSITION0; 12 | float2 TexCoord : TEXCOORD0; 13 | }; 14 | 15 | struct VertexShaderOutput 16 | { 17 | float4 Position : POSITION0; 18 | float2 WorldPos : TEXCOORD0; 19 | }; 20 | 21 | 22 | VertexShaderOutput VertexShaderFunction( VertexShaderInput input ) 23 | { 24 | VertexShaderOutput output; 25 | //output.Position = float4( input.Position, 1 ); 26 | output.Position = mul( input.Position, viewProjectionMatrix ); 27 | 28 | // Vertex position in 2D world space 29 | output.WorldPos = input.TexCoord; 30 | 31 | return output; 32 | } 33 | 34 | 35 | float4 PixelShaderFunction( VertexShaderOutput input ) : COLOR0 36 | { 37 | // Compute the relative position of the pixel and the distance towards the light 38 | float2 position = input.WorldPos - lightSource; 39 | float dist = sqrt( dot( position, position ) ); 40 | 41 | // Mix between black and the light color based on the distance and the power of the light 42 | float3 mix = lerp( lightColor, black, saturate( dist / lightRadius ) ); 43 | return float4( mix, 1.0f ); 44 | } 45 | 46 | 47 | technique Technique1 48 | { 49 | pass Pass1 50 | { 51 | VertexShader = compile vs_2_0 VertexShaderFunction(); 52 | PixelShader = compile ps_2_0 PixelShaderFunction(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Nez.Samples/Content/Shadows/Light.mgfxo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/Shadows/Light.mgfxo -------------------------------------------------------------------------------- /Nez.Samples/Content/Shadows/sprite-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/Shadows/sprite-light.png -------------------------------------------------------------------------------- /Nez.Samples/Content/Shared/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/Shared/moon.png -------------------------------------------------------------------------------- /Nez.Samples/Content/SpriteLights/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/SpriteLights/bg.png -------------------------------------------------------------------------------- /Nez.Samples/Content/SpriteLights/pixel-sprite-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/SpriteLights/pixel-sprite-light.png -------------------------------------------------------------------------------- /Nez.Samples/Content/SpriteLights/sprite-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/SpriteLights/sprite-light.png -------------------------------------------------------------------------------- /Nez.Samples/Content/SpriteLights/tube-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Content/SpriteLights/tube-light.png -------------------------------------------------------------------------------- /Nez.Samples/Game1.cs: -------------------------------------------------------------------------------- 1 | namespace Nez.Samples 2 | { 3 | public class Game1 : Core 4 | { 5 | protected override void Initialize() 6 | { 7 | base.Initialize(); 8 | 9 | Window.AllowUserResizing = true; 10 | Scene = new BasicScene(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Nez.Samples/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Icon.ico -------------------------------------------------------------------------------- /Nez.Samples/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/Icon.png -------------------------------------------------------------------------------- /Nez.Samples/MonoGame.Framework.dll.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Nez.Samples/Nez.FNA.Samples.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Nez.Samples/Nez.MG37.Samples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | x86 5 | Exe 6 | net471 7 | DesktopGL 8 | false 9 | x86;AnyCPU 10 | 11 | 12 | full 13 | bin\Debug\net471\net471\net471\net471 14 | DEBUG; 15 | x64 16 | 17 | 18 | bin\Release\net471\net471\net471\net471 19 | 20 | 21 | 22 | 23 | ContentPathGenerator.tt 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Content/nez/effects/%(RecursiveDir)%(Filename)%(Extension) 32 | PreserveNewest 33 | 34 | 35 | Content/nez/textures/%(RecursiveDir)%(Filename)%(Extension) 36 | PreserveNewest 37 | 38 | 39 | 40 | 41 | 42 | 43 | PreserveNewest 44 | 45 | 46 | 47 | 48 | 49 | TextTemplatingFileGenerator 50 | ContentPathGenerator.cs 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | x86\SDL2.dll 61 | PreserveNewest 62 | 63 | 64 | x64\SDL2.dll 65 | PreserveNewest 66 | 67 | 68 | x86\soft_oal.dll 69 | PreserveNewest 70 | 71 | 72 | x64\soft_oal.dll 73 | PreserveNewest 74 | 75 | 76 | x86\libSDL2-2.0.so.0 77 | PreserveNewest 78 | 79 | 80 | x64\libSDL2-2.0.so.0 81 | PreserveNewest 82 | 83 | 84 | x86\libopenal.so.1 85 | PreserveNewest 86 | 87 | 88 | x64\libopenal.so.1 89 | PreserveNewest 90 | 91 | 92 | libSDL2-2.0.0.dylib 93 | PreserveNewest 94 | 95 | 96 | libopenal.1.dylib 97 | PreserveNewest 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /Nez.Samples/Nez.MG38.NET6.Samples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net6 6 | false 7 | false 8 | false 9 | Nez.MG38.NET5.Samples 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ContentPathGenerator.tt 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Content/nez/effects/%(RecursiveDir)%(Filename)%(Extension) 27 | PreserveNewest 28 | 29 | 30 | Content/nez/textures/%(RecursiveDir)%(Filename)%(Extension) 31 | PreserveNewest 32 | 33 | 34 | 35 | 36 | 37 | 38 | PreserveNewest 39 | 40 | 41 | 42 | 43 | 44 | TextTemplatingFileGenerator 45 | ContentPathGenerator.cs 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Nez.Samples/Nez.MG38.Samples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | netcoreapp3.1 6 | false 7 | false 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ContentPathGenerator.tt 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Content/nez/effects/%(RecursiveDir)%(Filename)%(Extension) 26 | PreserveNewest 27 | 28 | 29 | Content/nez/textures/%(RecursiveDir)%(Filename)%(Extension) 30 | PreserveNewest 31 | 32 | 33 | 34 | 35 | 36 | 37 | PreserveNewest 38 | 39 | 40 | 41 | 42 | 43 | TextTemplatingFileGenerator 44 | ContentPathGenerator.cs 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Nez.Samples/Program.cs: -------------------------------------------------------------------------------- 1 | #region Using Statements 2 | 3 | using System; 4 | 5 | 6 | #if MONOMAC 7 | using MonoMac.AppKit; 8 | using MonoMac.Foundation; 9 | #elif __IOS__ || __TVOS__ 10 | using Foundation; 11 | using UIKit; 12 | #endif 13 | 14 | #endregion 15 | 16 | 17 | namespace Nez.Samples 18 | { 19 | #if __IOS__ || __TVOS__ 20 | [Register("AppDelegate")] 21 | class Program : UIApplicationDelegate 22 | #else 23 | static class Program 24 | #endif 25 | { 26 | private static Game1 _game; 27 | 28 | internal static void RunGame() 29 | { 30 | _game = new Game1(); 31 | _game.Run(); 32 | #if !__IOS__ && !__TVOS__ 33 | _game.Dispose(); 34 | #endif 35 | } 36 | 37 | /// 38 | /// The main entry point for the application. 39 | /// 40 | #if !MONOMAC && !__IOS__ && !__TVOS__ 41 | [STAThread] 42 | #endif 43 | static void Main(string[] args) 44 | { 45 | #if MONOMAC 46 | NSApplication.Init (); 47 | 48 | using (var p = new NSAutoreleasePool ()) { 49 | NSApplication.SharedApplication.Delegate = new AppDelegate(); 50 | NSApplication.Main(args); 51 | } 52 | #elif __IOS__ || __TVOS__ 53 | UIApplication.Main(args, null, "AppDelegate"); 54 | #else 55 | RunGame(); 56 | #endif 57 | } 58 | 59 | #if __IOS__ || __TVOS__ 60 | public override void FinishedLaunching(UIApplication app) 61 | { 62 | RunGame(); 63 | } 64 | #endif 65 | } 66 | 67 | #if MONOMAC 68 | class AppDelegate : NSApplicationDelegate 69 | { 70 | public override void FinishedLaunching (MonoMac.Foundation.NSObject notification) 71 | { 72 | AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs a) => { 73 | if (a.Name.StartsWith("MonoMac")) { 74 | return typeof(MonoMac.AppKit.AppKitFramework).Assembly; 75 | } 76 | return null; 77 | }; 78 | Program.RunGame(); 79 | } 80 | 81 | public override bool ApplicationShouldTerminateAfterLastWindowClosed (NSApplication sender) 82 | { 83 | return true; 84 | } 85 | } 86 | #endif 87 | } -------------------------------------------------------------------------------- /Nez.Samples/SampleHelpers/MouseFollow.cs: -------------------------------------------------------------------------------- 1 | namespace Nez.Samples 2 | { 3 | public class MouseFollow : Component, IUpdatable 4 | { 5 | public void Update() 6 | { 7 | Entity.SetPosition(Input.ScaledMousePosition); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/AIScene.cs: -------------------------------------------------------------------------------- 1 | namespace Nez.Samples 2 | { 3 | [SampleScene("AI", 120, 4 | "No visuals for this demo, everything is in the logs\nThe class 'miner bob' scenario is implemented with each AI type")] 5 | public class AiScene : SampleScene 6 | { 7 | public override void Initialize() 8 | { 9 | AddRenderer(new DefaultRenderer()); 10 | 11 | CreateEntity("ai-ui") 12 | .AddComponent(); 13 | 14 | CreateEntity("miner") 15 | .AddComponent(); 16 | 17 | CreateEntity("utility-miner") 18 | .AddComponent(); 19 | 20 | CreateEntity("goap-miner") 21 | .AddComponent(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/AIUI.cs: -------------------------------------------------------------------------------- 1 | using Nez.UI; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | /// 7 | /// component that displays a simple UI to enable/disable the different AI types 8 | /// 9 | public class Aiui : UICanvas 10 | { 11 | public override RectangleF Bounds => new RectangleF(0, 0, 200, 200); 12 | 13 | BehaviorTreeMiner _miner; 14 | UtilityMiner _utilityMiner; 15 | GoapMiner _goapMiner; 16 | 17 | 18 | public override void OnAddedToEntity() 19 | { 20 | base.OnAddedToEntity(); 21 | 22 | // setup a Skin and a Table for our UI 23 | var skin = Skin.CreateDefaultSkin(); 24 | var table = Stage.AddElement(new Table()); 25 | table.Defaults().SetPadTop(10).SetMinWidth(170).SetMinHeight(30); 26 | table.SetFillParent(true).Center(); 27 | 28 | // add a button for each of the actions/AI types we need 29 | table.Add(new TextButton("BT: LowerPriority Abort Tree", skin)) 30 | .GetElement() 31 | .OnClicked += OnClickBtLowerPriority; 32 | table.Row(); 33 | 34 | table.Add(new TextButton("BT: Self Abort Tree", skin)) 35 | .GetElement() 36 | .OnClicked += OnClickBtSelfAbort; 37 | table.Row(); 38 | 39 | table.Add(new TextButton("Utility AI", skin)) 40 | .GetElement() 41 | .OnClicked += OnClickUtilityAi; 42 | table.Row(); 43 | 44 | table.Add(new TextButton("GOAP", skin)) 45 | .GetElement() 46 | .OnClicked += OnClickGoap; 47 | table.Row().SetPadTop(40); 48 | 49 | table.Add(new TextButton("Stop All Running AI", skin)) 50 | .GetElement() 51 | .OnClicked += OnClickStopAllAi; 52 | 53 | // fetch our different AI Components 54 | _miner = Entity.Scene.FindComponentOfType(); 55 | _utilityMiner = Entity.Scene.FindComponentOfType(); 56 | _goapMiner = Entity.Scene.FindComponentOfType(); 57 | } 58 | 59 | 60 | #region button click handlers 61 | 62 | void OnClickBtLowerPriority(Button button) 63 | { 64 | Debug.Log("------ Enabled Behavior Tree LowerPriority Abort ------"); 65 | DisableAllAi(); 66 | _miner.BuildLowerPriorityAbortTree(); 67 | _miner.SetEnabled(true); 68 | } 69 | 70 | 71 | void OnClickBtSelfAbort(Button button) 72 | { 73 | Debug.Log("------ Enabled Behavior Tree Self Abort ------"); 74 | DisableAllAi(); 75 | _miner.BuildSelfAbortTree(); 76 | _miner.SetEnabled(true); 77 | } 78 | 79 | 80 | void OnClickUtilityAi(Button button) 81 | { 82 | Debug.Log("------ Enabled Utility AI ------"); 83 | DisableAllAi(); 84 | _utilityMiner.SetEnabled(true); 85 | } 86 | 87 | 88 | void OnClickGoap(Button button) 89 | { 90 | Debug.Log("------ Enabled GOAP ------"); 91 | DisableAllAi(); 92 | _goapMiner.SetEnabled(true); 93 | } 94 | 95 | 96 | void OnClickStopAllAi(Button button) 97 | { 98 | DisableAllAi(); 99 | } 100 | 101 | 102 | void DisableAllAi() 103 | { 104 | _miner.SetEnabled(false); 105 | _utilityMiner.SetEnabled(false); 106 | _goapMiner.SetEnabled(false); 107 | } 108 | 109 | #endregion 110 | } 111 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/BehaviorTreeMiner.cs: -------------------------------------------------------------------------------- 1 | using Nez.AI.BehaviorTrees; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | /// 7 | /// implments our friend miner bob with behavior trees. The same tree is built using self abort and lower priority types to illustrate 8 | /// different ways of using behavior trees. 9 | /// 10 | public class BehaviorTreeMiner : Component, IUpdatable 11 | { 12 | public MinerState MinerState = new MinerState(); 13 | 14 | BehaviorTree _tree; 15 | int _distanceToNextLocation = 10; 16 | 17 | 18 | public void BuildSelfAbortTree() 19 | { 20 | var builder = BehaviorTreeBuilder.Begin(this); 21 | 22 | builder.Selector(AbortTypes.Self); 23 | 24 | // sleep is most important 25 | builder.ConditionalDecorator(m => m.MinerState.Fatigue >= MinerState.MaxFatigue, false); 26 | builder.Sequence() 27 | .LogAction("--- tired! gotta go home") 28 | .Action(m => m.GoToLocation(MinerState.Location.Home)) 29 | .LogAction("--- prep me my bed!") 30 | .Action(m => m.Sleep()) 31 | .EndComposite(); 32 | 33 | // thirst is next most important 34 | builder.ConditionalDecorator(m => m.MinerState.Thirst >= MinerState.MaxThirst, false); 35 | builder.Sequence() 36 | .LogAction("--- thirsty! time for a drink") 37 | .Action(m => m.GoToLocation(MinerState.Location.Saloon)) 38 | .LogAction("--- get me a drink!") 39 | .Action(m => m.Drink()) 40 | .EndComposite(); 41 | 42 | // dropping off gold is next 43 | builder.ConditionalDecorator(m => m.MinerState.Gold >= MinerState.MaxGold, false); 44 | builder.Sequence() 45 | .LogAction("--- bags are full! gotta drop this off at the bank.") 46 | .Action(m => m.GoToLocation(MinerState.Location.Bank)) 47 | .LogAction("--- take me gold!") 48 | .Action(m => m.DepositGold()) 49 | .EndComposite(); 50 | 51 | // fetching gold is last 52 | builder.Sequence() 53 | .Action(m => m.GoToLocation(MinerState.Location.Mine)) 54 | .LogAction("--- time to get me some gold!") 55 | .Action(m => m.DigForGold()) 56 | .EndComposite(); 57 | 58 | builder.EndComposite(); 59 | 60 | _tree = builder.Build(); 61 | } 62 | 63 | 64 | // the same tree is here, once with LowerPriority aborts and once with Self aborts and ConditionalDecorators 65 | public void BuildLowerPriorityAbortTree() 66 | { 67 | var builder = BehaviorTreeBuilder.Begin(this); 68 | 69 | builder.Selector(); 70 | 71 | // sleep is most important 72 | builder.Sequence(AbortTypes.LowerPriority) 73 | .Conditional(m => m.MinerState.Fatigue >= MinerState.MaxFatigue) 74 | .LogAction("--- tired! gotta go home") 75 | .Action(m => m.GoToLocation(MinerState.Location.Home)) 76 | .LogAction("--- prep me my bed!") 77 | .Action(m => m.Sleep()) 78 | .EndComposite(); 79 | 80 | // thirst is next most important 81 | builder.Sequence(AbortTypes.LowerPriority) 82 | .Conditional(m => m.MinerState.Thirst >= MinerState.MaxThirst) 83 | .LogAction("--- thirsty! time for a drink") 84 | .Action(m => m.GoToLocation(MinerState.Location.Saloon)) 85 | .LogAction("--- get me a drink!") 86 | .Action(m => m.Drink()) 87 | .EndComposite(); 88 | 89 | // dropping off gold is next 90 | builder.Sequence(AbortTypes.LowerPriority) 91 | .Conditional(m => m.MinerState.Gold >= MinerState.MaxGold) 92 | .LogAction("--- bags are full! gotta drop this off at the bank.") 93 | .Action(m => m.GoToLocation(MinerState.Location.Bank)) 94 | .LogAction("--- take me gold!") 95 | .Action(m => m.DepositGold()) 96 | .EndComposite(); 97 | 98 | // fetching gold is last 99 | builder.Sequence() 100 | .Action(m => m.GoToLocation(MinerState.Location.Mine)) 101 | .LogAction("--- time to get me some gold!") 102 | .Action(m => m.DigForGold()) 103 | .EndComposite(); 104 | 105 | builder.EndComposite(); 106 | 107 | _tree = builder.Build(); 108 | } 109 | 110 | 111 | public void Update() 112 | { 113 | if (_tree != null) 114 | _tree.Tick(); 115 | } 116 | 117 | 118 | TaskStatus GoToLocation(MinerState.Location location) 119 | { 120 | Debug.Log("heading to {0}. its {1} miles away", location, _distanceToNextLocation); 121 | 122 | if (location != MinerState.CurrentLocation) 123 | { 124 | _distanceToNextLocation--; 125 | if (_distanceToNextLocation == 0) 126 | { 127 | MinerState.Fatigue++; 128 | MinerState.CurrentLocation = location; 129 | _distanceToNextLocation = Random.Range(2, 8); 130 | 131 | return TaskStatus.Success; 132 | } 133 | 134 | return TaskStatus.Running; 135 | } 136 | 137 | return TaskStatus.Success; 138 | } 139 | 140 | 141 | TaskStatus Sleep() 142 | { 143 | Debug.Log("getting some sleep. current fatigue {0}", MinerState.Fatigue); 144 | 145 | if (MinerState.Fatigue == 0) 146 | return TaskStatus.Success; 147 | 148 | MinerState.Fatigue--; 149 | return TaskStatus.Running; 150 | } 151 | 152 | 153 | TaskStatus Drink() 154 | { 155 | Debug.Log("getting my drink on. Thirst level {0}", MinerState.Thirst); 156 | 157 | if (MinerState.Thirst == 0) 158 | return TaskStatus.Success; 159 | 160 | MinerState.Thirst--; 161 | return TaskStatus.Running; 162 | } 163 | 164 | 165 | TaskStatus DepositGold() 166 | { 167 | MinerState.GoldInBank += MinerState.Gold; 168 | MinerState.Gold = 0; 169 | 170 | Debug.Log("depositing gold at the bank. current wealth {0}", MinerState.GoldInBank); 171 | 172 | return TaskStatus.Success; 173 | } 174 | 175 | 176 | TaskStatus DigForGold() 177 | { 178 | Debug.Log("digging for gold. nuggets found {0}", MinerState.Gold); 179 | MinerState.Gold++; 180 | MinerState.Fatigue++; 181 | MinerState.Thirst++; 182 | 183 | if (MinerState.Gold >= MinerState.MaxGold) 184 | return TaskStatus.Failure; 185 | 186 | return TaskStatus.Running; 187 | } 188 | } 189 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/GOAPMiner.cs: -------------------------------------------------------------------------------- 1 | using Nez.AI.FSM; 2 | using Nez.AI.GOAP; 3 | using System.Collections.Generic; 4 | 5 | 6 | namespace Nez.Samples 7 | { 8 | /// 9 | /// Goal Oriented Action Planning miner bob. Sets up Actions and uses the ActionPlanner to pick the appropriate action based on the world 10 | /// and goal states. This example also uses a SimpleStateMachine to deal with exeucuting the plan that the ActionPlanner comes up with. 11 | /// 12 | public class GoapMiner : SimpleStateMachine 13 | { 14 | public enum MinerBobState 15 | { 16 | Idle, 17 | GoTo, 18 | PerformAction 19 | } 20 | 21 | public MinerState MinerState = new MinerState(); 22 | 23 | const string IsFatigued = "fatigued"; 24 | const string IsThirsty = "thirsty"; 25 | const string HasEnoughGold = "hasenoughgold"; 26 | 27 | MinerState.Location _destinationLocation; 28 | int _distanceToNextLocation = 10; 29 | 30 | ActionPlanner _planner; 31 | Stack _actionPlan; 32 | 33 | 34 | public GoapMiner() 35 | { 36 | // we need an ActionPlanner before we can do anything 37 | _planner = new ActionPlanner(); 38 | 39 | // setup our Actions and add them to the planner 40 | var sleep = new Action("sleep"); 41 | sleep.SetPrecondition(IsFatigued, true); 42 | sleep.SetPostcondition(IsFatigued, false); 43 | _planner.AddAction(sleep); 44 | 45 | var drink = new Action("drink"); 46 | drink.SetPrecondition(IsThirsty, true); 47 | drink.SetPostcondition(IsThirsty, false); 48 | _planner.AddAction(drink); 49 | 50 | var mine = new Action("mine"); 51 | mine.SetPrecondition(HasEnoughGold, false); 52 | mine.SetPostcondition(HasEnoughGold, true); 53 | _planner.AddAction(mine); 54 | 55 | var depositGold = new Action("depositGold"); 56 | depositGold.SetPrecondition(HasEnoughGold, true); 57 | depositGold.SetPostcondition(HasEnoughGold, false); 58 | _planner.AddAction(depositGold); 59 | 60 | // set our state machine to idle. When it is in idle it will ask the ActionPlanner for a new plan 61 | InitialState = MinerBobState.Idle; 62 | } 63 | 64 | 65 | public override void OnAddedToEntity() 66 | { 67 | // slow things down a bit. we dont need to tick every frame 68 | Entity.UpdateInterval = 10; 69 | Enabled = false; 70 | } 71 | 72 | 73 | WorldState GetWorldState() 74 | { 75 | var worldState = _planner.CreateWorldState(); 76 | worldState.Set(IsFatigued, MinerState.Fatigue >= MinerState.MaxFatigue); 77 | worldState.Set(IsThirsty, MinerState.Thirst >= MinerState.MaxThirst); 78 | worldState.Set(HasEnoughGold, MinerState.Gold >= MinerState.MaxGold); 79 | 80 | return worldState; 81 | } 82 | 83 | 84 | WorldState GetGoalState() 85 | { 86 | var goalState = _planner.CreateWorldState(); 87 | 88 | if (MinerState.Fatigue >= MinerState.MaxFatigue) 89 | goalState.Set(IsFatigued, false); 90 | else if (MinerState.Thirst >= MinerState.MaxThirst) 91 | goalState.Set(IsThirsty, false); 92 | else if (MinerState.Gold >= MinerState.MaxGold) 93 | goalState.Set(HasEnoughGold, false); 94 | else 95 | goalState.Set(HasEnoughGold, true); 96 | 97 | return goalState; 98 | } 99 | 100 | 101 | #region states 102 | 103 | void Idle_Enter() 104 | { 105 | // get a plan to run that will get us from our current state to our goal state 106 | _actionPlan = _planner.Plan(GetWorldState(), GetGoalState()); 107 | 108 | if (_actionPlan != null && _actionPlan.Count > 0) 109 | { 110 | CurrentState = MinerBobState.GoTo; 111 | Debug.Log("got an action plan with {0} actions", _actionPlan.Count); 112 | } 113 | else 114 | { 115 | Debug.Log("no action plan satisfied our goals"); 116 | } 117 | } 118 | 119 | 120 | void GoTo_Enter() 121 | { 122 | // figure out where we are going 123 | var action = _actionPlan.Peek().Name; 124 | switch (action) 125 | { 126 | case "sleep": 127 | _destinationLocation = MinerState.Location.Home; 128 | break; 129 | case "drink": 130 | _destinationLocation = MinerState.Location.Saloon; 131 | break; 132 | case "mine": 133 | _destinationLocation = MinerState.Location.Mine; 134 | break; 135 | case "depositGold": 136 | _destinationLocation = MinerState.Location.Bank; 137 | break; 138 | } 139 | 140 | if (MinerState.CurrentLocation == _destinationLocation) 141 | { 142 | CurrentState = MinerBobState.PerformAction; 143 | } 144 | else 145 | { 146 | _distanceToNextLocation = Random.Range(2, 8); 147 | MinerState.CurrentLocation = MinerState.Location.InTransit; 148 | } 149 | } 150 | 151 | 152 | void GoTo_Tick() 153 | { 154 | Debug.Log("heading to {0}. its {1} miles away", _destinationLocation, _distanceToNextLocation); 155 | _distanceToNextLocation--; 156 | 157 | if (_distanceToNextLocation == 0) 158 | { 159 | MinerState.Fatigue++; 160 | MinerState.CurrentLocation = _destinationLocation; 161 | CurrentState = MinerBobState.PerformAction; 162 | } 163 | } 164 | 165 | 166 | void GoTo_Exit() 167 | { 168 | Debug.Log("made it to the " + MinerState.CurrentLocation); 169 | } 170 | 171 | 172 | void PerformAction_Tick() 173 | { 174 | var action = _actionPlan.Peek().Name; 175 | 176 | switch (action) 177 | { 178 | case "sleep": 179 | Debug.Log("getting some sleep. current fatigue {0}", MinerState.Fatigue); 180 | MinerState.Fatigue--; 181 | 182 | if (MinerState.Fatigue == 0) 183 | CurrentState = MinerBobState.Idle; 184 | break; 185 | case "drink": 186 | Debug.Log("getting my drink on. Thirst level {0}", MinerState.Thirst); 187 | MinerState.Thirst--; 188 | 189 | if (MinerState.Thirst == 0) 190 | CurrentState = MinerBobState.Idle; 191 | break; 192 | case "mine": 193 | Debug.Log("digging for gold. nuggets found {0}", MinerState.Gold); 194 | MinerState.Gold++; 195 | MinerState.Fatigue++; 196 | MinerState.Thirst++; 197 | 198 | if (MinerState.Gold >= MinerState.MaxGold) 199 | CurrentState = MinerBobState.Idle; 200 | break; 201 | case "depositGold": 202 | MinerState.GoldInBank += MinerState.Gold; 203 | MinerState.Gold = 0; 204 | 205 | Debug.Log("depositing gold at the bank. current wealth {0}", MinerState.GoldInBank); 206 | CurrentState = MinerBobState.Idle; 207 | break; 208 | } 209 | } 210 | 211 | #endregion 212 | } 213 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/MinerState.cs: -------------------------------------------------------------------------------- 1 | namespace Nez.Samples 2 | { 3 | /// 4 | /// common state for each of the AI types 5 | /// 6 | public class MinerState 7 | { 8 | public enum Location 9 | { 10 | InTransit, 11 | Bank, 12 | Mine, 13 | Home, 14 | Saloon 15 | } 16 | 17 | public const int MaxFatigue = 10; 18 | public const int MaxGold = 8; 19 | public const int MaxThirst = 5; 20 | 21 | public int Fatigue; 22 | public int Thirst; 23 | public int Gold; 24 | public int GoldInBank; 25 | 26 | public Location CurrentLocation = Location.Home; 27 | } 28 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/UtilityAIActions/ChooseBestLocation.cs: -------------------------------------------------------------------------------- 1 | using Nez.AI.UtilityAI; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | public class ChooseBestLocation : IActionOptionAppraisal 7 | { 8 | /// 9 | /// Action Appraisal that will score locations providing the highest score to the best location to visit 10 | /// 11 | /// The score. 12 | /// Context. 13 | /// Option. 14 | float IActionOptionAppraisal.GetScore( 15 | UtilityMiner context, MinerState.Location option) 16 | { 17 | if (option == MinerState.Location.Home) 18 | return context.MinerState.Fatigue >= MinerState.MaxFatigue ? 20 : 0; 19 | 20 | if (option == MinerState.Location.Saloon) 21 | return context.MinerState.Thirst >= MinerState.MaxThirst ? 15 : 0; 22 | 23 | if (option == MinerState.Location.Bank) 24 | { 25 | if (context.MinerState.Gold >= MinerState.MaxGold) 26 | return 10; 27 | 28 | // if we are scoring the bank and we are not at the mine we'll use a curve. the main gist of this is that if we are not at the mine 29 | // and we are carrying a decent amount of gold drop it off at the bank before heading to the mine again. 30 | if (context.MinerState.CurrentLocation != MinerState.Location.Mine) 31 | { 32 | // normalize our current gold value to 0-1 33 | var gold = Mathf.Map01(context.MinerState.Gold, 0, MinerState.MaxGold); 34 | var score = Mathf.Pow(gold, 2); 35 | return score * 10; 36 | } 37 | 38 | return 0; 39 | } 40 | 41 | return 5; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/UtilityAIActions/MoveToBestLocation.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Nez.AI.UtilityAI; 3 | 4 | 5 | namespace Nez.Samples 6 | { 7 | /// 8 | /// ActionWithOptions lets an Action setup an Appraisal that will score a list of options. In our miner bob example, the options 9 | /// are the locations and the Appraisal will score the best location to go to. 10 | /// 11 | public class MoveToBestLocation : ActionWithOptions 12 | { 13 | List _locations = new List() 14 | { 15 | MinerState.Location.Bank, 16 | MinerState.Location.Home, 17 | MinerState.Location.Mine, 18 | MinerState.Location.Saloon 19 | }; 20 | 21 | 22 | public override void Execute(UtilityMiner context) 23 | { 24 | var location = GetBestOption(context, _locations); 25 | context.GoToLocation(location); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/AI/UtilityMiner.cs: -------------------------------------------------------------------------------- 1 | using Nez.AI.UtilityAI; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | /// 7 | /// Utility AI example of miner bob. Utility AI is the most complex of all the AI types to setup. The complexity comes with a lot of power 8 | /// though. 9 | /// 10 | public class UtilityMiner : Component, IUpdatable 11 | { 12 | public MinerState MinerState = new MinerState(); 13 | 14 | UtilityAI _ai; 15 | MinerState.Location _destinationLocation; 16 | int _distanceToNextLocation = 10; 17 | 18 | 19 | public override void OnAddedToEntity() 20 | { 21 | Enabled = false; 22 | var reasoner = new FirstScoreReasoner(); 23 | 24 | // sleep is most important 25 | // AllOrNothingQualifier with required threshold of 1 so all scorers must score 26 | // - we have to be home to sleep 27 | // - we have to have some fatigue 28 | var fatigueConsideration = new AllOrNothingConsideration(1) 29 | .AddAppraisal(new ActionAppraisal(c => 30 | c.MinerState.CurrentLocation == MinerState.Location.Home ? 1 : 0)) 31 | .AddAppraisal(new ActionAppraisal(c => c.MinerState.Fatigue > 0 ? 1 : 0)); 32 | fatigueConsideration.Action = new ActionExecutor(c => c.Sleep()); 33 | reasoner.AddConsideration(fatigueConsideration); 34 | 35 | // thirst is next 36 | // AllOrNothingQualifier with required threshold of 1 so all scorers must score 37 | // - we have to be at the saloon to drink 38 | // - we have to be thirsty 39 | var thirstConsideration = new AllOrNothingConsideration(1) 40 | .AddAppraisal(new ActionAppraisal(c => 41 | c.MinerState.CurrentLocation == MinerState.Location.Saloon ? 1 : 0)) 42 | .AddAppraisal(new ActionAppraisal(c => c.MinerState.Thirst > 0 ? 1 : 0)); 43 | thirstConsideration.Action = new ActionExecutor(c => c.Drink()); 44 | reasoner.AddConsideration(thirstConsideration); 45 | 46 | // depositing gold is next 47 | // AllOrNothingQualifier with required threshold of 1 so all scorers must score 48 | // - we have to be at the bank to deposit gold 49 | // - we have to have gold to deposit 50 | var goldConsideration = new AllOrNothingConsideration(1) 51 | .AddAppraisal(new ActionAppraisal(c => 52 | c.MinerState.CurrentLocation == MinerState.Location.Bank ? 1 : 0)) 53 | .AddAppraisal(new ActionAppraisal(c => c.MinerState.Gold > 0 ? 1 : 0)); 54 | goldConsideration.Action = new ActionExecutor(c => c.DepositGold()); 55 | reasoner.AddConsideration(goldConsideration); 56 | 57 | // decide where to go. this will override mining and send us elsewhere if a scorer scores 58 | // AllOrNothingQualifier with required threshold of 0 so we get a sum of all scorers 59 | // - if we are max fatigued score 60 | // - if we are max thirsty score 61 | // - if we are at max gold score 62 | // - if we are not at the mine score 63 | // Action has a scorer to score all the locations. It then moves to the location that scored highest. 64 | var moveConsideration = new AllOrNothingConsideration(0) 65 | .AddAppraisal(new ActionAppraisal(c => 66 | c.MinerState.Fatigue >= MinerState.MaxFatigue ? 1 : 0)) 67 | .AddAppraisal( 68 | new ActionAppraisal(c => c.MinerState.Thirst >= MinerState.MaxThirst ? 1 : 0)) 69 | .AddAppraisal(new ActionAppraisal(c => c.MinerState.Gold >= MinerState.MaxGold ? 1 : 0)) 70 | .AddAppraisal(new ActionAppraisal(c => 71 | c.MinerState.CurrentLocation != MinerState.Location.Mine ? 1 : 0)); 72 | var moveAction = new MoveToBestLocation(); 73 | moveAction.AddScorer(new ChooseBestLocation()); 74 | moveConsideration.Action = moveAction; 75 | reasoner.AddConsideration(moveConsideration); 76 | 77 | // mining is last 78 | // AllOrNothingQualifier with required threshold of 1 so all scorers must score 79 | // - we have to be at the mine to dig for gold 80 | // - we have to not be at our max gold 81 | var mineConsideration = new AllOrNothingConsideration(1) 82 | .AddAppraisal(new ActionAppraisal(c => 83 | c.MinerState.CurrentLocation == MinerState.Location.Mine ? 1 : 0)) 84 | .AddAppraisal(new ActionAppraisal(c => c.MinerState.Gold >= MinerState.MaxGold ? 0 : 1)); 85 | mineConsideration.Action = new ActionExecutor(c => c.DigForGold()); 86 | reasoner.AddConsideration(mineConsideration); 87 | 88 | // default, fall-through action is to head to the mine 89 | reasoner.DefaultConsideration.Action = 90 | new ActionExecutor(c => c.GoToLocation(MinerState.Location.Mine)); 91 | 92 | _ai = new UtilityAI(this, reasoner); 93 | } 94 | 95 | 96 | public void Update() 97 | { 98 | _ai.Tick(); 99 | } 100 | 101 | 102 | public void Sleep() 103 | { 104 | Debug.Log("getting some sleep. current fatigue {0}", MinerState.Fatigue); 105 | MinerState.Fatigue--; 106 | } 107 | 108 | 109 | public void Drink() 110 | { 111 | Debug.Log("getting my drink on. Thirst level {0}", MinerState.Thirst); 112 | MinerState.Thirst--; 113 | } 114 | 115 | 116 | public void DepositGold() 117 | { 118 | MinerState.GoldInBank += MinerState.Gold; 119 | MinerState.Gold = 0; 120 | 121 | Debug.Log("depositing gold at the bank. current wealth {0}", MinerState.GoldInBank); 122 | } 123 | 124 | 125 | public void DigForGold() 126 | { 127 | Debug.Log("digging for gold. nuggets found {0}", MinerState.Gold); 128 | MinerState.Gold++; 129 | MinerState.Fatigue++; 130 | MinerState.Thirst++; 131 | } 132 | 133 | 134 | public void GoToLocation(MinerState.Location location) 135 | { 136 | if (location == MinerState.CurrentLocation) 137 | return; 138 | 139 | if (MinerState.CurrentLocation == MinerState.Location.InTransit && location == _destinationLocation) 140 | { 141 | Debug.Log("heading to {0}. its {1} miles away", location, _distanceToNextLocation); 142 | _distanceToNextLocation--; 143 | if (_distanceToNextLocation == 0) 144 | { 145 | MinerState.Fatigue++; 146 | MinerState.CurrentLocation = _destinationLocation; 147 | _distanceToNextLocation = Random.Range(2, 8); 148 | } 149 | } 150 | else 151 | { 152 | MinerState.CurrentLocation = MinerState.Location.InTransit; 153 | _destinationLocation = location; 154 | _distanceToNextLocation = Random.Range(2, 8); 155 | } 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Animated Tiles/AnimatedTilesScene.cs: -------------------------------------------------------------------------------- 1 | namespace Nez.Samples 2 | { 3 | /// 4 | /// Tiled map import that includes animated tiles from multiple different tileset images 5 | /// 6 | [SampleScene("Animated Tiles", 70, "Tiled map import with animated tiles")] 7 | public class AnimatedTilesScene : SampleScene 8 | { 9 | public AnimatedTilesScene() : base(true, true) 10 | {} 11 | 12 | 13 | public override void Initialize() 14 | { 15 | base.Initialize(); 16 | 17 | // setup a pixel perfect screen that fits our map 18 | SetDesignResolution(256, 224, SceneResolutionPolicy.ShowAllPixelPerfect); 19 | Screen.SetSize(256 * 4, 224 * 4); 20 | 21 | // load the TiledMap and display it with a TiledMapComponent 22 | var tiledEntity = CreateEntity("tiled-map-entity"); 23 | var map = Content.LoadTiledMap("Content/AnimatedTiles/desert-palace.tmx"); 24 | tiledEntity.AddComponent(new TiledMapRenderer(map)); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Deferred Lighting/DeferredLightingController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Nez.DeferredLighting; 3 | using Microsoft.Xna.Framework.Input; 4 | using Microsoft.Xna.Framework; 5 | 6 | 7 | namespace Nez.Samples 8 | { 9 | public class DeferredLightingController : Component, IUpdatable 10 | { 11 | DeferredLight _currentLight; 12 | DirLight _dirLight; 13 | 14 | 15 | public override void OnAddedToEntity() 16 | { 17 | _dirLight = Entity.Scene.FindComponentOfType(); 18 | _currentLight = _dirLight; 19 | } 20 | 21 | 22 | public void Update() 23 | { 24 | // check for debug toggle 25 | if (Input.IsKeyPressed(Keys.F)) 26 | { 27 | var renderer = Entity.Scene.GetRenderer(); 28 | renderer.EnableDebugBufferRender = !renderer.EnableDebugBufferRender; 29 | } 30 | 31 | // check for light changes 32 | var lightIndex = -1; 33 | if (Input.IsKeyPressed(Keys.D1)) 34 | lightIndex = 0; 35 | if (Input.IsKeyPressed(Keys.D2)) 36 | lightIndex = 1; 37 | if (Input.IsKeyPressed(Keys.D3)) 38 | lightIndex = 2; 39 | if (Input.IsKeyPressed(Keys.D4)) 40 | lightIndex = 3; 41 | if (Input.IsKeyPressed(Keys.D5)) 42 | lightIndex = 4; 43 | if (Input.IsKeyPressed(Keys.D6)) 44 | lightIndex = 5; 45 | 46 | if (lightIndex > -1) 47 | { 48 | var lights = Entity.Scene.FindComponentsOfType(); 49 | if (lights.Count > lightIndex) 50 | { 51 | _currentLight = lights[lightIndex]; 52 | UpdateInstructions(); 53 | } 54 | else 55 | { 56 | Debug.Log("no light at index: {0}", lightIndex); 57 | } 58 | } 59 | 60 | CheckInput(); 61 | } 62 | 63 | 64 | void CheckInput() 65 | { 66 | if (_currentLight is DirLight) 67 | { 68 | var light = _currentLight as DirLight; 69 | var zDir = light.Direction.Z; 70 | var rotation = (float) Math.Atan2(light.Direction.Y, light.Direction.X); 71 | var magnitude = new Vector2(light.Direction.X, light.Direction.Y).Length(); 72 | 73 | if (Input.IsKeyDown(Keys.Left)) 74 | rotation -= 0.1f; 75 | else if (Input.IsKeyDown(Keys.Right)) 76 | rotation += 0.1f; 77 | 78 | if (Input.IsKeyDown(Keys.Up)) 79 | zDir = Mathf.Clamp(zDir + 2, 0, 400); 80 | else if (Input.IsKeyDown(Keys.Down)) 81 | zDir = Mathf.Clamp(zDir - 2, 0, 400); 82 | 83 | var newDir = new Vector3(Mathf.Cos(rotation) * magnitude, Mathf.Sin(rotation) * magnitude, zDir); 84 | light.SetDirection(newDir); 85 | } 86 | 87 | if (_currentLight is PointLight || _currentLight is SpotLight) 88 | { 89 | var light = _currentLight as PointLight; 90 | 91 | if (Input.IsKeyDown(Keys.Up)) 92 | light.SetRadius(Mathf.Clamp(light.Radius + 5, 10, 800)); 93 | else if (Input.IsKeyDown(Keys.Down)) 94 | light.SetRadius(Mathf.Clamp(light.Radius - 5, 10, 800)); 95 | 96 | if (Input.IsKeyDown(Keys.Left)) 97 | light.SetIntensity(Mathf.Clamp(light.Intensity - 0.1f, 0, 20)); 98 | else if (Input.IsKeyDown(Keys.Right)) 99 | light.SetIntensity(Mathf.Clamp(light.Intensity + 0.1f, 0, 20)); 100 | 101 | if (Input.IsKeyDown(Keys.W)) 102 | light.SetZPosition(Mathf.Clamp(light.ZPosition + 1, 0, 300)); 103 | else if (Input.IsKeyDown(Keys.S)) 104 | light.SetZPosition(Mathf.Clamp(light.ZPosition - 1, 0, 300)); 105 | } 106 | 107 | if (_currentLight is SpotLight) 108 | { 109 | var light = _currentLight as SpotLight; 110 | 111 | if (Input.IsKeyDown(Keys.A)) 112 | light.SetConeAngle(Mathf.Repeat(light.ConeAngle - 3, 360)); 113 | else if (Input.IsKeyDown(Keys.D)) 114 | light.SetConeAngle(Mathf.Repeat(light.ConeAngle + 3, 360)); 115 | 116 | if (Input.IsKeyDown(Keys.Z)) 117 | light.Entity.SetLocalRotationDegrees(Mathf.Repeat(light.Entity.RotationDegrees - 3, 360)); 118 | else if (Input.IsKeyDown(Keys.X)) 119 | light.Entity.SetLocalRotationDegrees(Mathf.Repeat(light.Entity.RotationDegrees + 3, 360)); 120 | } 121 | 122 | // color controls 123 | var color = _currentLight.Color; 124 | if (Input.IsKeyDown(Keys.R)) 125 | color.R += (byte) 2; 126 | if (Input.IsKeyDown(Keys.G)) 127 | color.G += (byte) 2; 128 | if (Input.IsKeyDown(Keys.B)) 129 | color.B += (byte) 2; 130 | 131 | if (color != _currentLight.Color) 132 | { 133 | _currentLight.Color = color; 134 | Debug.Log("new light color: {0}", _currentLight.Color); 135 | } 136 | } 137 | 138 | 139 | void UpdateInstructions() 140 | { 141 | var textComp = Entity.Scene.FindEntity("instructions").GetComponent(); 142 | var colorText = "\nr/g/b keys change color"; 143 | 144 | if (_currentLight is DirLight) 145 | textComp.Text = 146 | "Controlling DirLight\nleft/right changes rotation\nup/down changes z-component of direction" + 147 | colorText; 148 | else if (_currentLight is SpotLight) 149 | textComp.Text = 150 | "Controlling SpotLight\nup/down changes radius\nleft/right changes intensity\nw/s changes zPosition\na/d changes cone angle\nz/x changes rotation" + 151 | colorText; 152 | else if (_currentLight is PointLight) 153 | textComp.Text = 154 | "Controlling PointLight\nup/down changes radius\nleft/right changes intensity\nw/s changes zPosition" + 155 | colorText; 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Deferred Lighting/DeferredLightingScene.cs: -------------------------------------------------------------------------------- 1 | using Nez.DeferredLighting; 2 | using Microsoft.Xna.Framework; 3 | using Microsoft.Xna.Framework.Graphics; 4 | using Nez.Sprites; 5 | 6 | 7 | namespace Nez.Samples 8 | { 9 | [SampleScene("Deferred Lighting", 80, 10 | "Press the number keys to change the light that is currently being controlled\nPressing f toggles the rendering of the individual buffers used by the deferred lighting system")] 11 | public class DeferredLightingScene : SampleScene 12 | { 13 | const int RenderablesLayer = 5; 14 | const int LightLayer = 10; 15 | 16 | 17 | public DeferredLightingScene() : base(false, false) 18 | { 19 | } 20 | 21 | 22 | public override void Initialize() 23 | { 24 | base.Initialize(); 25 | 26 | // setup screen that fits our map based on the bg size 27 | SetDesignResolution(137 * 9, 89 * 9, SceneResolutionPolicy.ShowAllPixelPerfect); 28 | Screen.SetSize(137 * 9, 89 * 9); 29 | ClearColor = Color.DarkGray; 30 | 31 | // add our renderer setting the renderLayers we will use for lights and for renderables 32 | var deferredRenderer = AddRenderer(new DeferredLightingRenderer(0, LightLayer, RenderablesLayer)) 33 | .SetClearColor(Color.DarkGray); 34 | deferredRenderer.EnableDebugBufferRender = false; 35 | 36 | // prep our textures. we have diffuse and normal maps to interact with the lights. 37 | var moonTex = Content.LoadTexture(Nez.Content.DeferredLighting.Moon); 38 | var moonNorm = Content.LoadTexture(Nez.Content.DeferredLighting.MoonNorm); 39 | var orangeTexture = Content.LoadTexture(Nez.Content.DeferredLighting.Orange); 40 | var orangeNormalMap = Content.LoadTexture(Nez.Content.DeferredLighting.OrangeNorm); 41 | var bgTexture = Content.LoadTexture(Nez.Content.DeferredLighting.Bg); 42 | var bgNormalMap = Content.LoadTexture(Nez.Content.DeferredLighting.BgNorm); 43 | 44 | // prep our Materials. Deferred lighting requires a Material that is normal map aware. We can also leave our Material null and 45 | // a default Material will be used that is diffuse lighting only (no normal map). 46 | var moonMaterial = new DeferredSpriteMaterial(moonNorm); 47 | var orangeMaterial = new DeferredSpriteMaterial(orangeNormalMap); 48 | var bgMaterial = new DeferredSpriteMaterial(bgNormalMap); 49 | 50 | // create some Entities. When we add the Renderable (Sprite in this case) we need to be sure to set the renderLayer and Material 51 | var bgEntity = CreateEntity("bg"); 52 | bgEntity.SetPosition(Screen.Center).SetScale(9); 53 | bgEntity.AddComponent(new SpriteRenderer(bgTexture)).SetRenderLayer(RenderablesLayer).SetMaterial(bgMaterial) 54 | .SetLayerDepth(1); 55 | bgEntity.AddComponent(new DeferredLightingController()); 56 | 57 | var orangeEntity = CreateEntity("orange"); 58 | orangeEntity.SetPosition(Screen.Center).SetScale(0.5f); 59 | orangeEntity.AddComponent(new SpriteRenderer(orangeTexture)).SetRenderLayer(RenderablesLayer) 60 | .SetMaterial(orangeMaterial); 61 | orangeEntity.AddComponent(new SpotLight()).SetRenderLayer(LightLayer); 62 | 63 | var moonEntity = CreateEntity("moon"); 64 | moonEntity.SetPosition(new Vector2(100, 400)); 65 | moonEntity.AddComponent(new SpriteRenderer(moonTex)).SetRenderLayer(RenderablesLayer).SetMaterial(moonMaterial); 66 | moonEntity.AddComponent(new DirLight(Color.Red)).SetRenderLayer(LightLayer).SetEnabled(true); 67 | 68 | var clone = orangeEntity.Clone(new Vector2(200, 200)); 69 | AddEntity(clone); 70 | 71 | var mouseFollowEntity = CreateEntity("mouse-follow"); 72 | mouseFollowEntity.AddComponent(new MouseFollow()); 73 | mouseFollowEntity.AddComponent(new PointLight(new Color(0.8f, 0.8f, 0.9f))).SetRadius(200).SetIntensity(2) 74 | .SetRenderLayer(LightLayer); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Destructable Tilemap/DestructableTilemapScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Nez.Textures; 3 | using Nez.Sprites; 4 | using Nez.Shadows; 5 | 6 | 7 | namespace Nez.Samples 8 | { 9 | [SampleScene("Destructable Tilemap", 20, 10 | "Demonstrates more advanced Tiled map usage including custom object layers,\nfetching attributes and managing colliders\nArrow keys to move")] 11 | public class DestructableTilemapScene : SampleScene 12 | { 13 | public DestructableTilemapScene() : base(true, true) 14 | { 15 | } 16 | 17 | 18 | public override void Initialize() 19 | { 20 | ClearColor = Color.Black; 21 | SetDesignResolution(640, 368, SceneResolutionPolicy.ShowAllPixelPerfect); 22 | Screen.SetSize(1280, 736); 23 | 24 | // load a TiledMap and move it back so is drawn before other entities 25 | var map = Content.LoadTiledMap("Content/DestructableMap/destructable-map.tmx"); 26 | var tiledEntity = CreateEntity("tiled-map"); 27 | tiledEntity.AddComponent(new TiledMapRenderer(map, "main")); 28 | 29 | var objectGroup = map.GetObjectGroup("objects"); 30 | var spawn = objectGroup.Objects["spawn"]; 31 | var ball = objectGroup.Objects["ball"]; 32 | 33 | var atlas = Content.LoadTexture("Content/DestructableMap/desert-palace-tiles2x.png"); 34 | var atlasParts = Sprite.SpritesFromAtlas(atlas, 16, 16); 35 | var playerSubtexture = atlasParts[96]; 36 | 37 | var playerEntity = CreateEntity("player"); 38 | playerEntity.Position = new Vector2(spawn.X + 8, spawn.Y + 8); 39 | playerEntity.AddComponent(new SpriteRenderer(playerSubtexture)); 40 | playerEntity.AddComponent(new PlayerDashMover()); 41 | playerEntity.AddComponent(new CameraShake()); 42 | playerEntity.AddComponent(new PolyLight(100) 43 | { 44 | CollidesWithLayers = 1 << 0, 45 | Color = Color.Yellow * 0.5f 46 | }); 47 | 48 | var trail = playerEntity.AddComponent(new SpriteTrail(playerEntity.GetComponent())); 49 | trail.FadeDelay = 0; 50 | trail.FadeDuration = 0.2f; 51 | trail.MinDistanceBetweenInstances = 10f; 52 | trail.InitialColor = Color.White * 0.5f; 53 | 54 | // add a collider and put it on layer 2 but make it only collide with layer 0. This will make the player only collide with the tilemap 55 | var collider = playerEntity.AddComponent(); 56 | Flags.SetFlagExclusive(ref collider.PhysicsLayer, 2); 57 | Flags.SetFlagExclusive(ref collider.CollidesWithLayers, 0); 58 | 59 | 60 | // create an object at the location set on our Tiled object layer that only collides with tiles and not the player 61 | var ballSubtexture = atlasParts[96]; 62 | var ballEntity = CreateEntity("ball"); 63 | ballEntity.Position = new Vector2(ball.X + 8, ball.Y + 8); 64 | ballEntity.AddComponent(new SpriteRenderer(ballSubtexture)); 65 | ballEntity.AddComponent(new ArcadeRigidbody()); 66 | 67 | // add a collider and put it on layer 1. Make it only collide with layer 0 (the tilemap) so it doesnt interact with the player. 68 | var circleCollider = ballEntity.AddComponent(); 69 | Flags.SetFlagExclusive(ref circleCollider.PhysicsLayer, 1); 70 | Flags.SetFlagExclusive(ref circleCollider.CollidesWithLayers, 0); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Destructable Tilemap/PlayerDashMover.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Input; 3 | 4 | using Nez.Sprites; 5 | 6 | namespace Nez.Samples 7 | { 8 | public class PlayerDashMover : Component, IUpdatable 9 | { 10 | float _speed = 800f; 11 | bool _isGrounded = true; 12 | bool _destroyedTile; 13 | Vector2 _moveDir; 14 | 15 | Mover _mover; 16 | TiledMapRenderer _tiledMapRenderer; 17 | SpriteRenderer _sprite; 18 | 19 | 20 | public override void OnAddedToEntity() 21 | { 22 | _sprite = this.GetComponent(); 23 | _tiledMapRenderer = Entity.Scene.FindEntity("tiled-map").GetComponent(); 24 | _mover = new Mover(); 25 | Entity.AddComponent(_mover); 26 | } 27 | 28 | 29 | void IUpdatable.Update() 30 | { 31 | Entity.Scene.Camera.Position = new Vector2(Entity.Scene.SceneRenderTargetSize.X / 2, 32 | Entity.Scene.SceneRenderTargetSize.Y / 2); 33 | if (_isGrounded) 34 | { 35 | if (Input.IsKeyPressed(Keys.Left)) 36 | { 37 | _moveDir.X = -1f; 38 | if (!CanMove()) 39 | { 40 | _moveDir.X = 0; 41 | return; 42 | } 43 | 44 | _sprite.FlipY = false; 45 | Entity.RotationDegrees = 90f; 46 | } 47 | else if (Input.IsKeyPressed(Keys.Right)) 48 | { 49 | _moveDir.X = 1f; 50 | if (!CanMove()) 51 | { 52 | _moveDir.X = 0; 53 | return; 54 | } 55 | 56 | _sprite.FlipY = false; 57 | Entity.RotationDegrees = -90f; 58 | } 59 | else if (Input.IsKeyPressed(Keys.Up)) 60 | { 61 | _moveDir.Y = -1f; 62 | if (!CanMove()) 63 | { 64 | _moveDir.Y = 0; 65 | return; 66 | } 67 | 68 | _sprite.FlipY = true; 69 | Entity.RotationDegrees = 0f; 70 | } 71 | else if (Input.IsKeyPressed(Keys.Down)) 72 | { 73 | _moveDir.Y = 1f; 74 | if (!CanMove()) 75 | { 76 | _moveDir.Y = 0; 77 | return; 78 | } 79 | 80 | _sprite.FlipY = false; 81 | Entity.RotationDegrees = 0f; 82 | } 83 | } 84 | 85 | 86 | if (_moveDir != Vector2.Zero) 87 | { 88 | var movement = _moveDir * _speed * Time.DeltaTime; 89 | CollisionResult res; 90 | if (_mover.Move(movement, out res)) 91 | { 92 | var pos = Entity.Position + new Vector2(-16) * res.Normal; 93 | var tile = _tiledMapRenderer.GetTileAtWorldPosition(pos); 94 | 95 | // the presence of a tilesetTile means we have a tile with custom properties. The only tiles with custom properties are our 96 | // wall tiles which cannot be destroyed 97 | if (!_destroyedTile && tile != null && tile.TilesetTile == null) 98 | { 99 | _destroyedTile = true; 100 | var tilePosX = _tiledMapRenderer.TiledMap.WorldToTilePositionX(pos.X); 101 | var tilePosY = _tiledMapRenderer.TiledMap.WorldToTilePositionY(pos.Y); 102 | _tiledMapRenderer.CollisionLayer.RemoveTile(tilePosX, tilePosY); 103 | _tiledMapRenderer.RemoveColliders(); 104 | _tiledMapRenderer.AddColliders(); 105 | } 106 | else 107 | { 108 | _moveDir = Vector2.Zero; 109 | _isGrounded = true; 110 | _destroyedTile = false; 111 | Entity.GetComponent().Shake(8, 0.8f); 112 | } 113 | } 114 | else 115 | { 116 | _isGrounded = false; 117 | } 118 | } 119 | } 120 | 121 | 122 | bool CanMove() 123 | { 124 | var pos = Entity.Position + new Vector2(16) * _moveDir; 125 | var tile = _tiledMapRenderer.GetTileAtWorldPosition(pos); 126 | 127 | return tile == null; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Empty Scene/BasicScene.cs: -------------------------------------------------------------------------------- 1 | using Nez.Sprites; 2 | using Microsoft.Xna.Framework; 3 | 4 | 5 | namespace Nez.Samples 6 | { 7 | [SampleScene("Basic Scene", 9999, "Scene with a single Entity. The minimum to have something to show")] 8 | public class BasicScene : SampleScene 9 | { 10 | public override void Initialize() 11 | { 12 | base.Initialize(); 13 | 14 | // default to 1280x720 with no SceneResolutionPolicy 15 | SetDesignResolution(1280, 720, SceneResolutionPolicy.None); 16 | Screen.SetSize(1280, 720); 17 | 18 | var moonTex = Content.LoadTexture(Nez.Content.Shared.Moon); 19 | var playerEntity = CreateEntity("player", new Vector2(Screen.Width / 2, Screen.Height / 2)); 20 | playerEntity.AddComponent(new SpriteRenderer(moonTex)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Farseer SVG/FarseerSVGScene.cs: -------------------------------------------------------------------------------- 1 | using FarseerPhysics; 2 | using FarseerPhysics.Dynamics; 3 | using Microsoft.Xna.Framework; 4 | using Microsoft.Xna.Framework.Input; 5 | using Nez.Farseer; 6 | using Nez.Svg; 7 | 8 | 9 | namespace Nez.Samples 10 | { 11 | [SampleScene("SVG to Farseer Physics", 85, 12 | "This demo shows how you can turn an SVG image into Farseer physics objects\nPress Space to start the physics simulation\nClick and drag to interact with physics shapes")] 13 | public class FarseerSvgScene : SampleScene 14 | { 15 | public override void Initialize() 16 | { 17 | ClearColor = Color.Black; 18 | AddRenderer(new DefaultRenderer()); 19 | Screen.SetSize(1280, 720); 20 | 21 | Settings.MaxPolygonVertices = 12; 22 | 23 | // create a physics world to manage the physics simulation 24 | var world = GetOrCreateSceneComponent() 25 | .SetEnableMousePicking(true); 26 | world.SetEnabled(false); 27 | 28 | // add a FSDebugView so that we can see the physics objects 29 | CreateEntity("debug-view") 30 | .AddComponent(new PressKeyToPerformAction(Keys.Space, e => world.SetEnabled(true))) 31 | .AddComponent(new FSDebugView(world)) 32 | .AppendFlags(FSDebugView.DebugViewFlags.ContactPoints); 33 | 34 | // load up the SVG document. This particular SVG only has one group so we can fetch it straight away 35 | var svgDoc = SvgDocument.Open(TitleContainer.OpenStream("Content/SVG/farseer-svg.svg")); 36 | var svgGroup = svgDoc.Groups[0]; 37 | 38 | // rectangles 39 | if (svgGroup.Rectangles != null) 40 | AddRectangles(svgGroup); 41 | 42 | // circles 43 | if (svgGroup.Circles != null) 44 | AddCircles(svgGroup); 45 | 46 | // lines 47 | if (svgGroup.Lines != null) 48 | AddLines(svgGroup); 49 | 50 | // paths: TODO: why is System.Drawing.Drawing2D.GraphicsPath never returning on macOS?!?! 51 | //if( svgGroup.paths != null ) 52 | // addPaths( svgGroup ); 53 | 54 | // ellipses 55 | if (svgGroup.Ellipses != null) 56 | AddEllipses(svgGroup); 57 | 58 | // polygons 59 | if (svgGroup.Polygons != null) 60 | AddPolygons(svgGroup); 61 | } 62 | 63 | 64 | /// 65 | /// adds dynamic rectangle physics objects for each rect in the SVG 66 | /// 67 | /// Group. 68 | void AddRectangles(SvgGroup group) 69 | { 70 | foreach (var rect in group.Rectangles) 71 | { 72 | var boxEntity = CreateEntity(rect.Id); 73 | boxEntity.SetPosition(rect.Center) 74 | .SetRotationDegrees(rect.RotationDegrees) 75 | .AddComponent(new FSRigidBody()) 76 | .SetBodyType(BodyType.Dynamic) 77 | .AddComponent(new FSCollisionBox(rect.Width, rect.Height)); 78 | } 79 | } 80 | 81 | 82 | /// 83 | /// adds dynamic circle physics objects for each circle in the SVG 84 | /// 85 | /// Group. 86 | void AddCircles(SvgGroup group) 87 | { 88 | foreach (var circle in group.Circles) 89 | { 90 | CreateEntity(circle.Id) 91 | .SetPosition(circle.CenterX, circle.CenterY) 92 | .AddComponent(new FSRigidBody()) 93 | .SetBodyType(BodyType.Dynamic) 94 | .AddComponent(new FSCollisionCircle(circle.Radius)); 95 | } 96 | } 97 | 98 | 99 | /// 100 | /// adds static edge physics objects for each line in the SVG 101 | /// 102 | /// Group. 103 | void AddLines(SvgGroup group) 104 | { 105 | foreach (var line in group.Lines) 106 | { 107 | var pts = line.GetTransformedPoints(); 108 | 109 | CreateEntity(line.Id) 110 | .AddComponent() 111 | .AddComponent(new FSCollisionEdge()) 112 | .SetVertices(pts[0], pts[1]); 113 | } 114 | } 115 | 116 | 117 | /// 118 | /// adds static chain physics objects for each path in the SVG 119 | /// 120 | /// Group. 121 | void AddPaths(SvgGroup group) 122 | { 123 | var svgPathBuilder = new SvgPathBuilder(); 124 | 125 | foreach (var path in group.Paths) 126 | { 127 | var pts = path.GetTransformedDrawingPoints(svgPathBuilder); 128 | 129 | CreateEntity(path.Id) 130 | .AddComponent() 131 | .AddComponent(new FSCollisionChain()) 132 | .SetVertices(pts); 133 | } 134 | } 135 | 136 | 137 | /// 138 | /// adds dynamic ellipse physics objects for each ellipse in the SVG 139 | /// 140 | /// Group. 141 | void AddEllipses(SvgGroup group) 142 | { 143 | foreach (var ellipse in group.Ellipses) 144 | { 145 | CreateEntity(ellipse.Id) 146 | .SetPosition(ellipse.CenterX, ellipse.CenterY) 147 | .AddComponent() 148 | .SetBodyType(BodyType.Dynamic) 149 | .AddComponent(new FSCollisionEllipse(ellipse.RadiusX, ellipse.RadiusY)); 150 | } 151 | } 152 | 153 | 154 | /// 155 | /// adds dynamic polygon physics objects for each polygon in the SVG 156 | /// 157 | /// Group. 158 | void AddPolygons(SvgGroup group) 159 | { 160 | foreach (var polygon in group.Polygons) 161 | { 162 | CreateEntity(polygon.Id) 163 | .SetPosition(polygon.CenterX, polygon.CenterY) 164 | .AddComponent() 165 | .SetBodyType(BodyType.Dynamic) 166 | .AddComponent(new FSCollisionPolygon(polygon.GetRelativePoints())); 167 | } 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/LineCasting/LineCaster.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | public class LineCaster : RenderableComponent, IUpdatable 7 | { 8 | private Vector2 _lastPosition = new Vector2(101, 101); 9 | private Vector2 _collisionPosition = new Vector2(-1, -1); 10 | 11 | // make sure we arent culled 12 | public override float Width => 1000; 13 | 14 | public override float Height => 1000; 15 | 16 | public LineCaster() 17 | { 18 | } 19 | 20 | public override void Render(Batcher batcher, Camera camera) 21 | { 22 | batcher.DrawPixel(_lastPosition.X, _lastPosition.Y, Color.Yellow, 4); 23 | batcher.DrawPixel(Transform.Position.X, Transform.Position.Y, Color.White, 4); 24 | batcher.DrawLine(_lastPosition, Transform.Position, Color.White); 25 | if (_collisionPosition.X > 0 && _collisionPosition.Y > 0) 26 | { 27 | batcher.DrawPixel(_collisionPosition.X, _collisionPosition.Y, Color.Red, 10); 28 | } 29 | } 30 | 31 | void IUpdatable.Update() 32 | { 33 | if (Input.LeftMouseButtonPressed) 34 | { 35 | _lastPosition = Transform.Position; 36 | Transform.Position = Input.MousePosition; 37 | _collisionPosition = new Vector2(-1, -1); 38 | } 39 | 40 | if (Input.RightMouseButtonPressed || Input.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.Space)) 41 | { 42 | var hit = Physics.Linecast(_lastPosition, Transform.Position); 43 | if (hit.Collider != null) 44 | { 45 | _collisionPosition = hit.Point; 46 | } 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/LineCasting/LineCastingScene.cs: -------------------------------------------------------------------------------- 1 | using Nez.Sprites; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Microsoft.Xna.Framework; 4 | 5 | 6 | namespace Nez.Samples 7 | { 8 | [SampleScene("Line Casting Scene", 10000, 9 | "Scene to test line casting. Move the mouse around and press the left mouse button to move the start/end point. Press the right mouse button or SPACE to run the linecast.")] 10 | public class LineCastingScene : SampleScene 11 | { 12 | public override void Initialize() 13 | { 14 | base.Initialize(); 15 | 16 | // default to 1280x720 with no SceneResolutionPolicy 17 | SetDesignResolution(1280, 720, SceneResolutionPolicy.None); 18 | Screen.SetSize(1280, 720); 19 | 20 | var moonTex = Content.LoadTexture(Nez.Content.Shared.Moon); 21 | var playerEntity = CreateEntity("player", new Vector2(Screen.Width / 2, Screen.Height / 2)); 22 | playerEntity.AddComponent(new SpriteRenderer(moonTex)); 23 | var coll = new BoxCollider(moonTex.Width, moonTex.Height); 24 | playerEntity.AddComponent(coll); 25 | playerEntity.Position = new Vector2(200, 100); 26 | 27 | var lineCaster = CreateEntity("linecaster") 28 | .AddComponent(new LineCaster()); 29 | lineCaster.Transform.Position = new Vector2(300, 100); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Mesh Shadows/MeshShadowsScene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework; 3 | using Nez.Textures; 4 | using Microsoft.Xna.Framework.Graphics; 5 | using Nez.Sprites; 6 | using Nez.Tweens; 7 | using Nez.Shadows; 8 | 9 | 10 | namespace Nez.Samples 11 | { 12 | [SampleScene("Mesh Shadows", 40, "2D shadow system\nArrow keys to move")] 13 | public class MeshShadowsScene : SampleScene 14 | { 15 | public override void Initialize() 16 | { 17 | base.Initialize(); 18 | 19 | Screen.SetSize(1280, 720); 20 | 21 | // render layer for all lights and any emissive Sprites 22 | var lightRenderLayer = 5; 23 | ClearColor = Color.White; 24 | 25 | // create a Renderer that renders all but the light layer and screen space layer 26 | AddRenderer(new RenderLayerExcludeRenderer(0, lightRenderLayer, ScreenSpaceRenderLayer)); 27 | 28 | // create a Renderer that renders only the light layer into a render target 29 | var lightRenderer = AddRenderer(new RenderLayerRenderer(-1, lightRenderLayer)); 30 | lightRenderer.RenderTargetClearColor = new Color(10, 10, 10, 255); 31 | lightRenderer.RenderTexture = new RenderTexture(); 32 | 33 | // add a PostProcessor that renders the light render target and blurs it 34 | AddPostProcessor(new PolyLightPostProcessor(0, lightRenderer.RenderTexture)) 35 | .SetEnableBlur(true) 36 | .SetBlurAmount(0.5f); 37 | 38 | var lightTexture = Content.LoadTexture(Nez.Content.Shadows.Spritelight); 39 | var moonTexture = Content.LoadTexture(Nez.Content.Shared.Moon); 40 | var blockTexture = Content.LoadTexture(Nez.Content.Shadows.Block); 41 | var blockGlowTexture = Content.LoadTexture(Nez.Content.Shadows.BlockGlow); 42 | 43 | // create some boxes 44 | Action boxMaker = (Vector2 pos, string name, bool isTrigger) => 45 | { 46 | var ent = CreateEntity(name); 47 | ent.Position = pos; 48 | ent.AddComponent(new SpriteRenderer(blockTexture)); 49 | var collider = ent.AddComponent(); 50 | 51 | // add a glow sprite on the light render layer 52 | var glowSprite = new SpriteRenderer(blockGlowTexture); 53 | glowSprite.RenderLayer = lightRenderLayer; 54 | ent.AddComponent(glowSprite); 55 | 56 | if (isTrigger) 57 | { 58 | collider.IsTrigger = true; 59 | ent.AddComponent(new TriggerListener()); 60 | } 61 | }; 62 | 63 | boxMaker(new Vector2(0, 100), "box0", false); 64 | boxMaker(new Vector2(150, 100), "box1", false); 65 | boxMaker(new Vector2(300, 100), "box2", false); 66 | boxMaker(new Vector2(450, 100), "box3", false); 67 | boxMaker(new Vector2(600, 100), "box4", false); 68 | 69 | boxMaker(new Vector2(50, 500), "box5", true); 70 | boxMaker(new Vector2(500, 250), "box6", false); 71 | 72 | var moonEnt = CreateEntity("moon"); 73 | moonEnt.AddComponent(new SpriteRenderer(moonTexture)); 74 | moonEnt.Position = new Vector2(100, 0); 75 | 76 | moonEnt = CreateEntity("moon2"); 77 | moonEnt.AddComponent(new SpriteRenderer(moonTexture)); 78 | moonEnt.Position = new Vector2(-500, 0); 79 | 80 | 81 | var lightEnt = CreateEntity("sprite-light"); 82 | lightEnt.AddComponent(new SpriteRenderer(lightTexture)); 83 | lightEnt.Position = new Vector2(-700, 0); 84 | lightEnt.Scale = new Vector2(4); 85 | lightEnt.GetComponent().RenderLayer = lightRenderLayer; 86 | 87 | 88 | // add an animation to "box4" 89 | FindEntity("box4").AddComponent(new MovingPlatform(250, 400)); 90 | 91 | // create a player block 92 | var entity = CreateEntity("player-block"); 93 | entity.SetPosition(new Vector2(220, 220)) 94 | .AddComponent(new SpriteRenderer(blockTexture).SetRenderLayer(lightRenderLayer)) 95 | .AddComponent(new SimpleMover()) 96 | .AddComponent(); 97 | 98 | 99 | // add a follow camera 100 | Camera.Entity.AddComponent(new FollowCamera(entity)); 101 | Camera.Entity.AddComponent(new CameraShake()); 102 | 103 | 104 | // setup some lights and animate the colors 105 | var pointLight = new PolyLight(600, Color.Red); 106 | pointLight.RenderLayer = lightRenderLayer; 107 | pointLight.Power = 1f; 108 | 109 | var light = CreateEntity("light"); 110 | light.SetPosition(new Vector2(700f, 300f)) 111 | .AddComponent(pointLight); 112 | 113 | pointLight.TweenColorTo(new Color(0, 0, 255, 255), 1f) 114 | .SetEaseType(EaseType.Linear) 115 | .SetLoops(LoopType.PingPong, 100) 116 | .Start(); 117 | 118 | PropertyTweens.FloatPropertyTo(pointLight, "Power", 0.1f, 1f) 119 | .SetEaseType(EaseType.Linear) 120 | .SetLoops(LoopType.PingPong, 100) 121 | .Start(); 122 | 123 | 124 | pointLight = new PolyLight(500, Color.Yellow); 125 | pointLight.RenderLayer = lightRenderLayer; 126 | light = CreateEntity("light-two"); 127 | light.Position = new Vector2(-50f); 128 | light.AddComponent(pointLight); 129 | 130 | pointLight.TweenColorTo(new Color(0, 255, 0, 255), 1f) 131 | .SetEaseType(EaseType.Linear) 132 | .SetLoops(LoopType.PingPong, 100) 133 | .Start(); 134 | 135 | 136 | pointLight = new PolyLight(500, Color.AliceBlue); 137 | pointLight.RenderLayer = lightRenderLayer; 138 | light = CreateEntity("light-three"); 139 | light.Position = new Vector2(100, 250); 140 | light.AddComponent(pointLight); 141 | 142 | pointLight.TweenColorTo(new Color(200, 100, 155, 255), 1f) 143 | .SetEaseType(EaseType.QuadIn) 144 | .SetLoops(LoopType.PingPong, 100) 145 | .Start(); 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Ninja Adventure/CameraBounds.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | public class CameraBounds : Component, IUpdatable 7 | { 8 | public Vector2 Min, Max; 9 | 10 | 11 | public CameraBounds() 12 | { 13 | // make sure we run last so the camera is already moved before we evaluate its position 14 | SetUpdateOrder(int.MaxValue); 15 | } 16 | 17 | 18 | public CameraBounds(Vector2 min, Vector2 max) : this() 19 | { 20 | Min = min; 21 | Max = max; 22 | } 23 | 24 | 25 | public override void OnAddedToEntity() 26 | { 27 | Entity.UpdateOrder = int.MaxValue; 28 | } 29 | 30 | 31 | void IUpdatable.Update() 32 | { 33 | var cameraBounds = Entity.Scene.Camera.Bounds; 34 | 35 | if (cameraBounds.Top < Min.Y) 36 | Entity.Scene.Camera.Position += new Vector2(0, Min.Y - cameraBounds.Top); 37 | 38 | if (cameraBounds.Left < Min.X) 39 | Entity.Scene.Camera.Position += new Vector2(Min.X - cameraBounds.Left, 0); 40 | 41 | if (cameraBounds.Bottom > Max.Y) 42 | Entity.Scene.Camera.Position += new Vector2(0, Max.Y - cameraBounds.Bottom); 43 | 44 | if (cameraBounds.Right > Max.X) 45 | Entity.Scene.Camera.Position += new Vector2(Max.X - cameraBounds.Right, 0); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Ninja Adventure/FireballProjectileController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | /// 7 | /// moves a ProjectileMover and destroys the Entity if it hits anything 8 | /// 9 | public class FireballProjectileController : Component, IUpdatable 10 | { 11 | public Vector2 Velocity; 12 | 13 | ProjectileMover _mover; 14 | 15 | 16 | public FireballProjectileController(Vector2 velocity) => Velocity = velocity; 17 | 18 | public override void OnAddedToEntity() => _mover = Entity.GetComponent(); 19 | 20 | void IUpdatable.Update() 21 | { 22 | if (_mover.Move(Velocity * Time.DeltaTime)) 23 | Entity.Destroy(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Ninja Adventure/Ninja.cs: -------------------------------------------------------------------------------- 1 | using Nez.Sprites; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Nez.Textures; 4 | using Microsoft.Xna.Framework; 5 | using Microsoft.Xna.Framework.Input; 6 | 7 | 8 | namespace Nez.Samples 9 | { 10 | public class Ninja : Component, ITriggerListener, IUpdatable 11 | { 12 | enum Animations 13 | { 14 | WalkUp, 15 | WalkDown, 16 | WalkRight, 17 | WalkLeft 18 | } 19 | 20 | SpriteAnimator _animator; 21 | 22 | SubpixelVector2 _subpixelV2 = new SubpixelVector2(); 23 | Mover _mover; 24 | float _moveSpeed = 100f; 25 | Vector2 _projectileVelocity = new Vector2(175); 26 | 27 | VirtualButton _fireInput; 28 | VirtualIntegerAxis _xAxisInput; 29 | VirtualIntegerAxis _yAxisInput; 30 | 31 | 32 | public override void OnAddedToEntity() 33 | { 34 | // load up our character texture atlas. we have different characters in 1 - 6.png for variety 35 | var characterPng = Random.Range(1, 7); 36 | var texture = Entity.Scene.Content.LoadTexture("Content/NinjaAdventure/characters/" + characterPng + ".png"); 37 | var sprites = Sprite.SpritesFromAtlas(texture, 16, 16); 38 | 39 | _mover = Entity.AddComponent(new Mover()); 40 | _animator = Entity.AddComponent(); 41 | 42 | // add a shadow that will only be rendered when our player is behind the details layer of the tilemap (RenderLayer -1). The shadow 43 | // must be in a renderLayer ABOVE the details layer to be visible. 44 | var shadow = Entity.AddComponent(new SpriteMime(Entity.GetComponent())); 45 | shadow.Color = new Color(10, 10, 10, 80); 46 | shadow.Material = Material.StencilRead(); 47 | shadow.RenderLayer = -2; // ABOVE our tiledmap layer so it is visible 48 | 49 | // extract the animations from the atlas 50 | _animator.AddAnimation("WalkLeft", new[] 51 | { 52 | sprites[2], 53 | sprites[6], 54 | sprites[10], 55 | sprites[14] 56 | }); 57 | _animator.AddAnimation("WalkRight",new[] 58 | { 59 | sprites[3], 60 | sprites[7], 61 | sprites[11], 62 | sprites[15] 63 | }); 64 | _animator.AddAnimation("WalkDown", new[] 65 | { 66 | sprites[0], 67 | sprites[4], 68 | sprites[8], 69 | sprites[12] 70 | }); 71 | _animator.AddAnimation("WalkUp", new[] 72 | { 73 | sprites[1], 74 | sprites[5], 75 | sprites[9], 76 | sprites[13] 77 | }); 78 | 79 | SetupInput(); 80 | } 81 | 82 | public override void OnRemovedFromEntity() 83 | { 84 | // deregister virtual input 85 | _fireInput.Deregister(); 86 | } 87 | 88 | void SetupInput() 89 | { 90 | // setup input for shooting a fireball. we will allow z on the keyboard or a on the gamepad 91 | _fireInput = new VirtualButton(); 92 | _fireInput.Nodes.Add(new VirtualButton.KeyboardKey(Keys.Z)); 93 | _fireInput.Nodes.Add(new VirtualButton.GamePadButton(0, Buttons.A)); 94 | 95 | // horizontal input from dpad, left stick or keyboard left/right 96 | _xAxisInput = new VirtualIntegerAxis(); 97 | _xAxisInput.Nodes.Add(new VirtualAxis.GamePadDpadLeftRight()); 98 | _xAxisInput.Nodes.Add(new VirtualAxis.GamePadLeftStickX()); 99 | _xAxisInput.Nodes.Add(new VirtualAxis.KeyboardKeys(VirtualInput.OverlapBehavior.TakeNewer, Keys.Left,Keys.Right)); 100 | 101 | // vertical input from dpad, left stick or keyboard up/down 102 | _yAxisInput = new VirtualIntegerAxis(); 103 | _yAxisInput.Nodes.Add(new VirtualAxis.GamePadDpadUpDown()); 104 | _yAxisInput.Nodes.Add(new VirtualAxis.GamePadLeftStickY()); 105 | _yAxisInput.Nodes.Add(new VirtualAxis.KeyboardKeys(VirtualInput.OverlapBehavior.TakeNewer, Keys.Up,Keys.Down)); 106 | } 107 | 108 | void IUpdatable.Update() 109 | { 110 | // handle movement and animations 111 | var moveDir = new Vector2(_xAxisInput.Value, _yAxisInput.Value); 112 | var animation = "WalkDown"; 113 | 114 | if (moveDir.X < 0) 115 | animation = "WalkLeft"; 116 | else if (moveDir.X > 0) 117 | animation = "WalkRight"; 118 | 119 | if (moveDir.Y < 0) 120 | animation = "WalkUp"; 121 | else if (moveDir.Y > 0) 122 | animation = "WalkDown"; 123 | 124 | 125 | if (moveDir != Vector2.Zero) 126 | { 127 | if (!_animator.IsAnimationActive(animation)) 128 | _animator.Play(animation); 129 | else 130 | _animator.UnPause(); 131 | 132 | var movement = moveDir * _moveSpeed * Time.DeltaTime; 133 | 134 | _mover.CalculateMovement(ref movement, out var res); 135 | _subpixelV2.Update(ref movement); 136 | _mover.ApplyMovement(movement); 137 | } 138 | else 139 | { 140 | _animator.Pause(); 141 | } 142 | 143 | // handle firing a projectile 144 | if (_fireInput.IsPressed) 145 | { 146 | // fire a projectile in the direction we are facing 147 | var dir = Vector2.Zero; 148 | switch (_animator.CurrentAnimationName) 149 | { 150 | case "WalkUp": 151 | dir.Y = -1; 152 | break; 153 | case "WalkDown": 154 | dir.Y = 1; 155 | break; 156 | case "WalkRight": 157 | dir.X = 1; 158 | break; 159 | case "WalkLeft": 160 | dir.X = -1; 161 | break; 162 | default: 163 | dir = new Vector2(1, 0); 164 | break; 165 | } 166 | 167 | var ninjaScene = Entity.Scene as NinjaAdventureScene; 168 | ninjaScene.CreateProjectiles(Entity.Transform.Position, _projectileVelocity * dir); 169 | } 170 | } 171 | 172 | #region ITriggerListener implementation 173 | 174 | void ITriggerListener.OnTriggerEnter(Collider other, Collider self) 175 | { 176 | Debug.Log("triggerEnter: {0}", other.Entity.Name); 177 | } 178 | 179 | 180 | void ITriggerListener.OnTriggerExit(Collider other, Collider self) 181 | { 182 | Debug.Log("triggerExit: {0}", other.Entity.Name); 183 | } 184 | 185 | #endregion 186 | } 187 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Ninja Adventure/NinjaAdventureScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework.Graphics; 2 | using Microsoft.Xna.Framework; 3 | using Nez.Sprites; 4 | using Nez.Textures; 5 | 6 | 7 | namespace Nez.Samples 8 | { 9 | [SampleScene("Ninja Adventure", 10, 10 | "Tiled map with multiple layers, virtual input and stencil shadows\nArrows, d-pad or left stick to move, z key or controller a button to fire a projectile\nFind and kill the giant moon")] 11 | public class NinjaAdventureScene : SampleScene 12 | { 13 | public NinjaAdventureScene() : base(true, true) 14 | { 15 | } 16 | 17 | 18 | public override void Initialize() 19 | { 20 | base.Initialize(); 21 | 22 | // setup a pixel perfect screen that fits our map 23 | SetDesignResolution(512, 256, SceneResolutionPolicy.ShowAllPixelPerfect); 24 | Screen.SetSize(512 * 3, 256 * 3); 25 | 26 | 27 | // load the TiledMap and display it with a TiledMapComponent 28 | var tiledEntity = CreateEntity("tiled-map-entity"); 29 | var map = Content.LoadTiledMap(Nez.Content.NinjaAdventure.Map.Tilemap); 30 | var tiledMapRenderer = tiledEntity.AddComponent(new TiledMapRenderer(map, "collision")); 31 | tiledMapRenderer.SetLayersToRender(new[] { "tiles", "terrain", "details" }); 32 | 33 | // render below/behind everything else. our player is at 0 and projectile is at 1. 34 | tiledMapRenderer.RenderLayer = 10; 35 | 36 | // render our above-details layer after the player so the player is occluded by it when walking behind things 37 | var tiledMapDetailsComp = tiledEntity.AddComponent(new TiledMapRenderer(map)); 38 | tiledMapDetailsComp.SetLayerToRender("above-details"); 39 | tiledMapDetailsComp.RenderLayer = -1; 40 | 41 | // the details layer will write to the stencil buffer so we can draw a shadow when the player is behind it. we need an AlphaTestEffect 42 | // here as well 43 | tiledMapDetailsComp.Material = Material.StencilWrite(); 44 | tiledMapDetailsComp.Material.Effect = Content.LoadNezEffect(); 45 | 46 | // setup our camera bounds with a 1 tile border around the edges (for the outside collision tiles) 47 | var topLeft = new Vector2(map.TileWidth, map.TileWidth); 48 | var bottomRight = new Vector2(map.TileWidth * (map.Width - 1), 49 | map.TileWidth * (map.Height - 1)); 50 | tiledEntity.AddComponent(new CameraBounds(topLeft, bottomRight)); 51 | 52 | 53 | var playerEntity = CreateEntity("player", new Vector2(256 / 2, 224 / 2)); 54 | playerEntity.AddComponent(new Ninja()); 55 | var collider = playerEntity.AddComponent(); 56 | 57 | // we only want to collide with the tilemap, which is on the default layer 0 58 | Flags.SetFlagExclusive(ref collider.CollidesWithLayers, 0); 59 | 60 | // move ourself to layer 1 so that we dont get hit by the projectiles that we fire 61 | Flags.SetFlagExclusive(ref collider.PhysicsLayer, 1); 62 | 63 | // add a component to have the Camera follow the player 64 | Camera.Entity.AddComponent(new FollowCamera(playerEntity)); 65 | 66 | // stick something to shoot in the level 67 | var moonTexture = Content.LoadTexture(Nez.Content.Shared.Moon); 68 | var moonEntity = CreateEntity("moon", new Vector2(412, 460)); 69 | moonEntity.AddComponent(new SpriteRenderer(moonTexture)); 70 | moonEntity.AddComponent(new ProjectileHitDetector()); 71 | moonEntity.AddComponent(); 72 | } 73 | 74 | 75 | /// 76 | /// creates a projectile and sets it in motion 77 | /// 78 | public Entity CreateProjectiles(Vector2 position, Vector2 velocity) 79 | { 80 | // create an Entity to house the projectile and its logic 81 | var entity = CreateEntity("projectile"); 82 | entity.Position = position; 83 | entity.AddComponent(new ProjectileMover()); 84 | entity.AddComponent(new FireballProjectileController(velocity)); 85 | 86 | // add a collider so we can detect intersections 87 | var collider = entity.AddComponent(); 88 | Flags.SetFlagExclusive(ref collider.CollidesWithLayers, 0); 89 | Flags.SetFlagExclusive(ref collider.PhysicsLayer, 1); 90 | 91 | 92 | // load up a Texture that contains a fireball animation and setup the animation frames 93 | var texture = Content.LoadTexture(Nez.Content.NinjaAdventure.Plume); 94 | var sprites = Sprite.SpritesFromAtlas(texture, 16, 16); 95 | 96 | // add the Sprite to the Entity and play the animation after creating it 97 | var animator = entity.AddComponent(new SpriteAnimator()); 98 | 99 | // render after (under) our player who is on renderLayer 0, the default 100 | animator.RenderLayer = 1; 101 | 102 | animator.AddAnimation("default", sprites.ToArray()); 103 | animator.Play("default"); 104 | 105 | 106 | // clone the projectile and fire it off in the opposite direction 107 | var newEntity = entity.Clone(entity.Position); 108 | newEntity.GetComponent().Velocity *= -1; 109 | AddEntity(newEntity); 110 | 111 | return entity; 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Ninja Adventure/ProjectileHitDetector.cs: -------------------------------------------------------------------------------- 1 | using Nez.Sprites; 2 | using Microsoft.Xna.Framework; 3 | 4 | 5 | namespace Nez.Samples 6 | { 7 | /// 8 | /// simple component that detects if it has been hit by a projectile. When hit, it flashes red and destroys itself after being hit 9 | /// a certain number of times. 10 | /// 11 | public class ProjectileHitDetector : Component, ITriggerListener 12 | { 13 | public int HitsUntilDead = 10; 14 | 15 | int _hitCounter; 16 | SpriteRenderer _sprite; 17 | 18 | 19 | public override void OnAddedToEntity() 20 | { 21 | _sprite = Entity.GetComponent(); 22 | } 23 | 24 | 25 | void ITriggerListener.OnTriggerEnter(Collider other, Collider self) 26 | { 27 | _hitCounter++; 28 | if (_hitCounter >= HitsUntilDead) 29 | { 30 | Entity.Destroy(); 31 | return; 32 | } 33 | 34 | _sprite.Color = Color.Red; 35 | Core.Schedule(0.1f, timer => _sprite.Color = Color.White); 36 | } 37 | 38 | 39 | void ITriggerListener.OnTriggerExit(Collider other, Collider self) 40 | { 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Particles/ParticlesScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework.Graphics; 2 | using Microsoft.Xna.Framework; 3 | using Nez.Sprites; 4 | 5 | 6 | namespace Nez.Samples 7 | { 8 | [SampleScene("Particles", 90, 9 | "Arrow keys to move. Exiting the Camera view will cull the particles.\nQ/W changes the particle system being played")] 10 | public class ParticlesScene : SampleScene 11 | { 12 | public override void Initialize() 13 | { 14 | ClearColor = Color.Black; 15 | SetDesignResolution(1280, 720, SceneResolutionPolicy.None); 16 | Screen.SetSize(1280, 720); 17 | 18 | // add the ParticleSystemSelector which handles input for the scene and a SimpleMover to move it around with the keyboard 19 | var particlesEntity = CreateEntity("particles"); 20 | particlesEntity.SetPosition(Screen.Center - new Vector2(0, 200)); 21 | particlesEntity.AddComponent(new ParticleSystemSelector()); 22 | particlesEntity.AddComponent(new SimpleMover()); 23 | 24 | 25 | // create a couple moons for playing with particle collisions 26 | var moonTex = Content.LoadTexture(Nez.Content.Shared.Moon); 27 | 28 | var moonEntity = CreateEntity("moon"); 29 | moonEntity.Position = new Vector2(Screen.Width / 2, Screen.Height / 2 + 100); 30 | moonEntity.AddComponent(new SpriteRenderer(moonTex)); 31 | moonEntity.AddComponent(); 32 | 33 | // clone the first moonEntity to create the second 34 | var moonEntityTwo = moonEntity.Clone(new Vector2(Screen.Width / 2 - 100, Screen.Height / 2 + 100)); 35 | AddEntity(moonEntityTwo); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Pathfinding/Pathfinder.cs: -------------------------------------------------------------------------------- 1 | using Nez.AI.Pathfinding; 2 | using Microsoft.Xna.Framework; 3 | using System.Collections.Generic; 4 | using Nez.Tiled; 5 | 6 | 7 | namespace Nez.Samples 8 | { 9 | /// 10 | /// simple Component that finds a path on click and displays it via a series of rectangles 11 | /// 12 | public class Pathfinder : RenderableComponent, IUpdatable 13 | { 14 | // make sure we arent culled 15 | public override float Width => 1000; 16 | 17 | public override float Height => 1000; 18 | 19 | UnweightedGridGraph _gridGraph; 20 | List _breadthSearchPath; 21 | 22 | WeightedGridGraph _weightedGraph; 23 | List _weightedSearchPath; 24 | 25 | AstarGridGraph _astarGraph; 26 | List _astarSearchPath; 27 | 28 | TmxMap _tilemap; 29 | Point _start, _end; 30 | 31 | 32 | public Pathfinder(TmxMap tilemap) 33 | { 34 | _tilemap = tilemap; 35 | var layer = tilemap.GetLayer("main"); 36 | 37 | _start = new Point(1, 1); 38 | _end = new Point(10, 10); 39 | 40 | _gridGraph = new UnweightedGridGraph(layer); 41 | _breadthSearchPath = _gridGraph.Search(_start, _end); 42 | 43 | _weightedGraph = new WeightedGridGraph(layer); 44 | _weightedSearchPath = _weightedGraph.Search(_start, _end); 45 | 46 | _astarGraph = new AstarGridGraph(layer); 47 | _astarSearchPath = _astarGraph.Search(_start, _end); 48 | 49 | Debug.DrawTextFromBottom = true; 50 | } 51 | 52 | void IUpdatable.Update() 53 | { 54 | // on left click set our path end time 55 | if (Input.LeftMouseButtonPressed) 56 | _end = _tilemap.WorldToTilePosition(Input.MousePosition); 57 | 58 | // on right click set our path start time 59 | if (Input.RightMouseButtonPressed) 60 | _start = _tilemap.WorldToTilePosition(Input.MousePosition); 61 | 62 | // regenerate the path on either click 63 | if (Input.LeftMouseButtonPressed || Input.RightMouseButtonPressed) 64 | { 65 | // time both path generations 66 | var first = Debug.TimeAction(() => { _breadthSearchPath = _gridGraph.Search(_start, _end); }); 67 | 68 | var second = Debug.TimeAction(() => { _weightedSearchPath = _weightedGraph.Search(_start, _end); }); 69 | 70 | var third = Debug.TimeAction(() => { _astarSearchPath = _astarGraph.Search(_start, _end); }); 71 | 72 | // debug draw the times 73 | Debug.DrawText("Breadth First: {0}\nDijkstra: {1}\nAstar: {2}", first, second, third); 74 | Debug.Log("\nBreadth First: {0}\nDijkstra: {1}\nAstar: {2}", first, second, third); 75 | } 76 | } 77 | 78 | public override void Render(Batcher batcher, Camera camera) 79 | { 80 | // if we have a path render all the nodes 81 | if (_breadthSearchPath != null) 82 | { 83 | foreach (var node in _breadthSearchPath) 84 | { 85 | var x = node.X * _tilemap.TileWidth + _tilemap.TileWidth * 0.5f; 86 | var y = node.Y * _tilemap.TileHeight + _tilemap.TileHeight * 0.5f; 87 | 88 | batcher.DrawPixel(x + 2, y + 2, Color.Yellow, 4); 89 | } 90 | } 91 | 92 | if (_weightedSearchPath != null) 93 | { 94 | foreach (var node in _weightedSearchPath) 95 | { 96 | var x = node.X * _tilemap.TileWidth + _tilemap.TileWidth * 0.5f; 97 | var y = node.Y * _tilemap.TileHeight + _tilemap.TileHeight * 0.5f; 98 | 99 | batcher.DrawPixel(x - 2, y - 2, Color.Blue, 4); 100 | } 101 | } 102 | 103 | if (_astarSearchPath != null) 104 | { 105 | foreach (var node in _astarSearchPath) 106 | { 107 | var x = node.X * _tilemap.TileWidth + _tilemap.TileWidth * 0.5f; 108 | var y = node.Y * _tilemap.TileHeight + _tilemap.TileHeight * 0.5f; 109 | 110 | batcher.DrawPixel(x, y, Color.Orange, 4); 111 | } 112 | } 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Pathfinding/PathfindingScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | 4 | namespace Nez.Samples 5 | { 6 | [SampleScene("Pathfinding Tilemap", 100, 7 | "Right click to set the start point\nLeft click to set the end point\nBreadth First is the yellow path and Astar is the blue path\nTurn on Debug Render to see path generation times")] 8 | public class PathfindingScene : SampleScene 9 | { 10 | public PathfindingScene() : base(true, true) 11 | {} 12 | 13 | public override void Initialize() 14 | { 15 | ClearColor = Color.Black; 16 | SetDesignResolution(640, 368, SceneResolutionPolicy.ShowAllPixelPerfect); 17 | Screen.SetSize(1280, 736); 18 | 19 | // load a TiledMap and a TiledMapComponent to display it 20 | var map = Content.LoadTiledMap("Content/DestructableMap/destructable-map.tmx"); 21 | var tiledEntity = CreateEntity("tiled-map"); 22 | tiledEntity.AddComponent(new TiledMapRenderer(map)); 23 | 24 | // add a Pathfinder to handle pathfinding and debug display of the paths 25 | CreateEntity("pathfinder").AddComponent(new Pathfinder(map)); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Platformer/Caveman.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Nez.Sprites; 3 | using Microsoft.Xna.Framework.Graphics; 4 | using Nez.Textures; 5 | using Microsoft.Xna.Framework.Input; 6 | using Nez.Tiled; 7 | 8 | 9 | namespace Nez.Samples 10 | { 11 | public class Caveman : Component, IUpdatable 12 | { 13 | public float MoveSpeed = 150; 14 | public float Gravity = 1000; 15 | public float JumpHeight = 16 * 5; 16 | 17 | SpriteAnimator _animator; 18 | TiledMapMover _mover; 19 | BoxCollider _boxCollider; 20 | TiledMapMover.CollisionState _collisionState = new TiledMapMover.CollisionState(); 21 | Vector2 _velocity; 22 | ColliderTriggerHelper _triggerHelper; 23 | 24 | VirtualButton _jumpInput; 25 | VirtualIntegerAxis _xAxisInput; 26 | 27 | public override void OnAddedToEntity() 28 | { 29 | var texture = Entity.Scene.Content.LoadTexture(Content.Platformer.Caveman); 30 | var sprites = Sprite.SpritesFromAtlas(texture, 32, 32); 31 | 32 | _boxCollider = Entity.GetComponent(); 33 | _mover = Entity.GetComponent(); 34 | _animator = Entity.AddComponent(new SpriteAnimator(sprites[0])); 35 | 36 | // the TiledMapMover does not call ITriggerListener Methods on collision. 37 | // To achieve ITriggerListener calling, this ColliderTriggerHelper can be used. 38 | // See the Update() function below, to see how this helper can be used. 39 | _triggerHelper = new ColliderTriggerHelper(Entity); 40 | 41 | // extract the animations from the atlas. they are setup in rows with 8 columns 42 | _animator.AddAnimation("Walk", new[] 43 | { 44 | sprites[0], 45 | sprites[1], 46 | sprites[2], 47 | sprites[3], 48 | sprites[4], 49 | sprites[5] 50 | }); 51 | 52 | _animator.AddAnimation("Run", new[] 53 | { 54 | sprites[8 + 0], 55 | sprites[8 + 1], 56 | sprites[8 + 2], 57 | sprites[8 + 3], 58 | sprites[8 + 4], 59 | sprites[8 + 5], 60 | sprites[8 + 6] 61 | }); 62 | 63 | _animator.AddAnimation("Idle", new[] 64 | { 65 | sprites[16] 66 | }); 67 | 68 | _animator.AddAnimation("Attack", new[] 69 | { 70 | sprites[24 + 0], 71 | sprites[24 + 1], 72 | sprites[24 + 2], 73 | sprites[24 + 3] 74 | }); 75 | 76 | _animator.AddAnimation("Death", new[] 77 | { 78 | sprites[40 + 0], 79 | sprites[40 + 1], 80 | sprites[40 + 2], 81 | sprites[40 + 3] 82 | }); 83 | 84 | _animator.AddAnimation("Falling", new[] 85 | { 86 | sprites[48] 87 | }); 88 | 89 | _animator.AddAnimation("Hurt", new[] 90 | { 91 | sprites[64], 92 | sprites[64 + 1] 93 | }); 94 | 95 | _animator.AddAnimation("Jumping", new[] 96 | { 97 | sprites[72 + 0], 98 | sprites[72 + 1], 99 | sprites[72 + 2], 100 | sprites[72 + 3] 101 | }); 102 | 103 | SetupInput(); 104 | } 105 | 106 | public override void OnRemovedFromEntity() 107 | { 108 | // deregister virtual input 109 | _jumpInput.Deregister(); 110 | _xAxisInput.Deregister(); 111 | } 112 | 113 | void SetupInput() 114 | { 115 | // setup input for jumping. we will allow z on the keyboard or a on the gamepad 116 | _jumpInput = new VirtualButton(); 117 | _jumpInput.Nodes.Add(new VirtualButton.KeyboardKey(Keys.Z)); 118 | _jumpInput.Nodes.Add(new VirtualButton.GamePadButton(0, Buttons.A)); 119 | 120 | // horizontal input from dpad, left stick or keyboard left/right 121 | _xAxisInput = new VirtualIntegerAxis(); 122 | _xAxisInput.Nodes.Add(new VirtualAxis.GamePadDpadLeftRight()); 123 | _xAxisInput.Nodes.Add(new VirtualAxis.GamePadLeftStickX()); 124 | _xAxisInput.Nodes.Add(new VirtualAxis.KeyboardKeys(VirtualInput.OverlapBehavior.TakeNewer, Keys.Left, Keys.Right)); 125 | } 126 | 127 | void IUpdatable.Update() 128 | { 129 | // handle movement and animations 130 | var moveDir = new Vector2(_xAxisInput.Value, 0); 131 | string animation = null; 132 | 133 | if (moveDir.X < 0) 134 | { 135 | if (_collisionState.Below) 136 | animation = "Run"; 137 | _animator.FlipX = true; 138 | _velocity.X = -MoveSpeed; 139 | } 140 | else if (moveDir.X > 0) 141 | { 142 | if (_collisionState.Below) 143 | animation = "Run"; 144 | _animator.FlipX = false; 145 | _velocity.X = MoveSpeed; 146 | } 147 | else 148 | { 149 | _velocity.X = 0; 150 | if (_collisionState.Below) 151 | animation = "Idle"; 152 | } 153 | 154 | if (_collisionState.Below && _jumpInput.IsPressed) 155 | { 156 | animation = "Jumping"; 157 | _velocity.Y = -Mathf.Sqrt(2f * JumpHeight * Gravity); 158 | } 159 | 160 | if (!_collisionState.Below && _velocity.Y > 0) 161 | animation = "Falling"; 162 | 163 | // apply gravity 164 | _velocity.Y += Gravity * Time.DeltaTime; 165 | 166 | // move 167 | _mover.Move(_velocity * Time.DeltaTime, _boxCollider, _collisionState); 168 | 169 | // Update the TriggerHelper. This will check if our collider intersects with a 170 | // trigger-collider and call ITriggerListener if necessary. 171 | _triggerHelper.Update(); 172 | 173 | if (_collisionState.Below) 174 | _velocity.Y = 0; 175 | 176 | if (animation != null && !_animator.IsAnimationActive(animation)) 177 | _animator.Play(animation); 178 | } 179 | } 180 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Platformer/PlatformerDangerZone.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | 3 | namespace Nez.Samples 4 | { 5 | public class PlatformerDangerZone : Component, ITriggerListener 6 | { 7 | Vector2 _respawnPoint; 8 | 9 | public PlatformerDangerZone(Vector2 respawnPoint) 10 | { 11 | _respawnPoint = respawnPoint; 12 | } 13 | 14 | #region ITriggerListener implementation 15 | 16 | public void OnTriggerEnter(Collider other, Collider local) 17 | { 18 | // everything that touches this zone gets relocated to the spawn point 19 | other.Entity.Position = _respawnPoint; 20 | } 21 | 22 | public void OnTriggerExit(Collider other, Collider local) 23 | { } 24 | 25 | #endregion 26 | } 27 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Platformer/PlatformerItem.cs: -------------------------------------------------------------------------------- 1 | using FarseerPhysics.Dynamics; 2 | using Microsoft.Xna.Framework; 3 | 4 | namespace Nez.Samples 5 | { 6 | public class PlatformerItem : Component, ITriggerListener 7 | { 8 | #region ITriggerListener implementation 9 | 10 | public void OnTriggerEnter(Collider other, Collider local) 11 | { 12 | // Just disappear 13 | Entity.Destroy(); 14 | } 15 | 16 | public void OnTriggerExit(Collider other, Collider local) 17 | { } 18 | 19 | #endregion 20 | } 21 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Platformer/PlatformerScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Nez.Sprites; 3 | using Nez.Textures; 4 | using Nez.Tiled; 5 | 6 | 7 | namespace Nez.Samples 8 | { 9 | [SampleScene("Platformer", 120, "Work in progress...\nArrows, d-pad or left stick to move, z key or a button to jump")] 10 | public class PlatformerScene : SampleScene 11 | { 12 | public PlatformerScene() : base(true, true) 13 | {} 14 | 15 | 16 | public override void Initialize() 17 | { 18 | // setup a pixel perfect screen that fits our map 19 | SetDesignResolution(640, 480, SceneResolutionPolicy.ShowAllPixelPerfect); 20 | Screen.SetSize(640 * 2, 480 * 2); 21 | 22 | // load up our TiledMap 23 | var map = Content.LoadTiledMap("Content/Platformer/tiledMap.tmx"); 24 | var playerSpawn = map.GetObjectGroup("objects").Objects["spawn"]; 25 | var playerSpawnPosition = new Vector2(playerSpawn.X, playerSpawn.Y); 26 | 27 | // cell "6" from the Tilemap will be used as our items sprite 28 | var itemSprite = new Sprite(map.Tilesets[0].Image.Texture, map.Tilesets[0].TileRegions[6]); 29 | 30 | var tiledEntity = CreateEntity("tiled-map-entity"); 31 | tiledEntity.AddComponent(new TiledMapRenderer(map, "main")); 32 | 33 | // create our Player and add a TiledMapMover to handle collisions with the tilemap 34 | var playerEntity = CreateEntity("player", playerSpawnPosition); 35 | playerEntity.AddComponent(new Caveman()); 36 | playerEntity.AddComponent(new BoxCollider(-8, -16, 16, 32)); 37 | playerEntity.AddComponent(new TiledMapMover(map.GetLayer("main"))); 38 | 39 | // create collectible items at the "item"-points from the TiledMap 40 | var itemSpawns = map.GetObjectGroup("collectibles").Objects; 41 | 42 | foreach (TmxObject itemSpawnPoint in itemSpawns) 43 | { 44 | var item = CreateEntity("item", new Vector2(itemSpawnPoint.X, itemSpawnPoint.Y)); 45 | 46 | // add a Trigger-Collider to the item 47 | var collider = item.AddComponent(new BoxCollider(16, 16)); 48 | collider.IsTrigger = true; 49 | 50 | item.AddComponent(new PlatformerItem()); 51 | item.AddComponent(new SpriteRenderer(itemSprite)); 52 | } 53 | 54 | // create the danger-zone polygons 55 | var dangerSpawns = map.GetObjectGroup("danger-zone").Objects; 56 | 57 | foreach (TmxObject danger in dangerSpawns) 58 | { 59 | var zone = CreateEntity("danger-zone", new Vector2(danger.X, danger.Y)); 60 | 61 | // add a Trigger-Collider to the zone 62 | var collider = zone.AddComponent(new PolygonCollider(danger.Points)); 63 | collider.IsTrigger = true; 64 | 65 | zone.AddComponent(new PlatformerDangerZone(playerSpawnPosition)); 66 | } 67 | 68 | AddPostProcessor(new VignettePostProcessor(1)); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/RigidBodies/RigidBodyScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Nez.Sprites; 4 | 5 | 6 | namespace Nez.Samples 7 | { 8 | [SampleScene("Rigid Bodies", 100, 9 | "ArcadeRigidBodies can be used for a game-like physics effect\nThis demo just applies some impulses and lets gravity do the rest")] 10 | public class RigidBodyScene : SampleScene 11 | { 12 | public override void Initialize() 13 | { 14 | base.Initialize(); 15 | 16 | Screen.SetSize(1280, 720); 17 | 18 | var moonTexture = Content.LoadTexture(Nez.Content.Shared.Moon); 19 | 20 | var friction = 0.3f; 21 | var elasticity = 0.4f; 22 | CreateEntity(new Vector2(50, 200), 50f, friction, elasticity, new Vector2(150, 0), moonTexture) 23 | .AddImpulse(new Vector2(10, 0)); 24 | CreateEntity(new Vector2(800, 260), 5f, friction, elasticity, new Vector2(-180, 0), moonTexture); 25 | 26 | CreateEntity(new Vector2(50, 400), 50f, friction, elasticity, new Vector2(150, -40), moonTexture); 27 | CreateEntity(new Vector2(800, 460), 5f, friction, elasticity, new Vector2(-180, -40), moonTexture); 28 | 29 | 30 | CreateEntity(new Vector2(400, 0), 60f, friction, elasticity, new Vector2(10, 90), moonTexture); 31 | CreateEntity(new Vector2(500, 400), 4f, friction, elasticity, new Vector2(0, -270), moonTexture); 32 | 33 | 34 | var rb = CreateEntity(new Vector2(Screen.Width / 2, Screen.Height / 2 + 250), 0, friction, elasticity, 35 | new Vector2(0, -270), moonTexture); 36 | rb.Entity.GetComponent().Color = Color.DarkMagenta; 37 | 38 | rb = CreateEntity(new Vector2(Screen.Width / 2 - 200, Screen.Height / 2 + 250), 0, friction, elasticity, 39 | new Vector2(0, -270), moonTexture); 40 | rb.Entity.GetComponent().Color = Color.DarkMagenta; 41 | 42 | 43 | // bottom fellas 44 | CreateEntity(new Vector2(200, 700), 15f, friction, elasticity, new Vector2(150, -150), moonTexture); 45 | CreateEntity(new Vector2(800, 760), 15f, friction, elasticity, new Vector2(-180, -150), moonTexture); 46 | CreateEntity(new Vector2(1200, 700), 1f, friction, elasticity, new Vector2(0, 0), moonTexture) 47 | .AddImpulse(new Vector2(-5, -20)); 48 | 49 | // top fellas 50 | CreateEntity(new Vector2(100, 100), 1f, friction, elasticity, new Vector2(100, 90), moonTexture) 51 | .AddImpulse(new Vector2(40, -10)); 52 | CreateEntity(new Vector2(100, 700), 100f, friction, elasticity, new Vector2(200, -270), moonTexture); 53 | } 54 | 55 | 56 | ArcadeRigidbody CreateEntity(Vector2 position, float mass, float friction, float elasticity, Vector2 velocity, 57 | Texture2D texture) 58 | { 59 | var rigidbody = new ArcadeRigidbody() 60 | .SetMass(mass) 61 | .SetFriction(friction) 62 | .SetElasticity(elasticity) 63 | .SetVelocity(velocity); 64 | 65 | var entity = CreateEntity(Utils.RandomString(3)); 66 | entity.Position = position; 67 | entity.AddComponent(new SpriteRenderer(texture)); 68 | entity.AddComponent(rigidbody); 69 | entity.AddComponent(); 70 | 71 | return rigidbody; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Spring Grid/GridModifier.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Input; 3 | 4 | 5 | namespace Nez.Samples 6 | { 7 | /// 8 | /// applies forces to the SpringGrid as the Entity moves around. Also adds an explosive force when space is pressed 9 | /// 10 | public class GridModifier : Component, IUpdatable 11 | { 12 | SpringGrid _grid; 13 | Vector2 _lastPosition; 14 | 15 | 16 | public override void OnAddedToEntity() 17 | { 18 | _grid = Entity.Scene.FindEntity("grid").GetComponent(); 19 | } 20 | 21 | 22 | void IUpdatable.Update() 23 | { 24 | var velocity = Entity.Position - _lastPosition; 25 | _grid.ApplyExplosiveForce(0.5f * velocity.Length(), Entity.Position, 80); 26 | 27 | _lastPosition = Entity.Position; 28 | 29 | if (Input.IsKeyPressed(Keys.Space)) 30 | _grid.ApplyDirectedForce(new Vector3(0, 0, 1000), new Vector3(Entity.Position.X, Entity.Position.Y, 0), 31 | 50); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Spring Grid/SpringGridScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Nez.Sprites; 4 | 5 | 6 | namespace Nez.Samples 7 | { 8 | /// 9 | /// demos the SpringGrid with a SimpleMover entity that applies forces to the grid. vignette and bloom post processors are also 10 | /// added to give the scene some life. 11 | /// 12 | [SampleScene("Spring Grid", 30, 13 | "SpringGrid component with vignette and bloom\nArrow keys to move\nSpace to apply an explosive force")] 14 | public class SpringGridScene : SampleScene 15 | { 16 | public override void Initialize() 17 | { 18 | base.Initialize(); 19 | 20 | Screen.SetSize(1280, 720); 21 | ClearColor = Color.Black; 22 | var moonTex = Content.LoadTexture(Nez.Content.Shared.Moon); 23 | 24 | var gridEntity = CreateEntity("grid"); 25 | gridEntity.AddComponent(new SpringGrid(new Rectangle(0, 0, Screen.Width, Screen.Height), new Vector2(30))); 26 | 27 | 28 | var playerEntity = CreateEntity("player", new Vector2(Screen.Width / 2, Screen.Height / 2)); 29 | playerEntity.Scale *= 0.5f; 30 | playerEntity.AddComponent(new SimpleMover()); 31 | playerEntity.AddComponent(new GridModifier()); 32 | playerEntity.AddComponent(new SpriteRenderer(moonTex)); 33 | 34 | 35 | AddPostProcessor(new VignettePostProcessor(1)); 36 | AddPostProcessor(new BloomPostProcessor(3)).Settings = BloomSettings.PresetSettings[0]; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Sprite Lights/SpriteLightsScene.cs: -------------------------------------------------------------------------------- 1 | using Nez.Textures; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Nez.Sprites; 4 | using Microsoft.Xna.Framework; 5 | using Nez.Tweens; 6 | using Nez.UI; 7 | 8 | 9 | namespace Nez.Samples 10 | { 11 | [SampleScene("Sprite Lights", 50, 12 | "Old-school 2D blended lighting\nPlay with the controls to change the effect and add lights")] 13 | public class SpriteLightsScene : SampleScene 14 | { 15 | public const int SpriteLightRenderLayer = 50; 16 | SpriteLightPostProcessor _spriteLightPostProcessor; 17 | RenderLayerRenderer _lightRenderer; 18 | 19 | public override void Initialize() 20 | { 21 | base.Initialize(); 22 | 23 | // setup screen that fits our map 24 | SetDesignResolution(1280, 720, SceneResolutionPolicy.ShowAll); 25 | Screen.SetSize(1280, 720); 26 | 27 | AddRenderer(new RenderLayerExcludeRenderer(0, ScreenSpaceRenderLayer, SpriteLightRenderLayer)); 28 | _lightRenderer = AddRenderer(new RenderLayerRenderer(-1, SpriteLightRenderLayer)); 29 | _lightRenderer.RenderTexture = new RenderTexture(); 30 | _lightRenderer.RenderTargetClearColor = new Color(10, 10, 10, 255); 31 | 32 | _spriteLightPostProcessor = AddPostProcessor(new SpriteLightPostProcessor(0, _lightRenderer.RenderTexture)); 33 | 34 | 35 | var bg = Content.LoadTexture(Nez.Content.SpriteLights.Bg); 36 | var bgEntity = CreateEntity("bg"); 37 | bgEntity.Position = Screen.Center; 38 | bgEntity.AddComponent(new SpriteRenderer(bg)); 39 | bgEntity.Scale = new Vector2(9.4f); 40 | 41 | var moonTex = Content.LoadTexture(Nez.Content.Shared.Moon); 42 | var entity = CreateEntity("moon"); 43 | entity.AddComponent(new SpriteRenderer(moonTex)); 44 | entity.Position = new Vector2(Screen.Width / 4, Screen.Height / 8); 45 | 46 | 47 | var lightTex = Content.LoadTexture(Nez.Content.SpriteLights.Spritelight); 48 | var pixelLightTex = Content.LoadTexture(Nez.Content.SpriteLights.Pixelspritelight); 49 | 50 | AddSpriteLight(lightTex, new Vector2(50, 50), 2); 51 | AddSpriteLight(lightTex, Screen.Center, 3); 52 | AddSpriteLight(lightTex, new Vector2(Screen.Width - 100, 150), 2); 53 | AddSpriteLight(pixelLightTex, Screen.Center + new Vector2(200, 10), 10); 54 | AddSpriteLight(pixelLightTex, Screen.Center - new Vector2(200, 10), 13); 55 | AddSpriteLight(pixelLightTex, Screen.Center + new Vector2(10, 200), 8); 56 | 57 | CreateUi(); 58 | } 59 | 60 | void CreateUi() 61 | { 62 | // stick a UI in so we can play with the sprite light effect 63 | var uiCanvas = CreateEntity("sprite-light-ui").AddComponent(new UICanvas()); 64 | uiCanvas.IsFullScreen = true; 65 | uiCanvas.RenderLayer = ScreenSpaceRenderLayer; 66 | var skin = Skin.CreateDefaultSkin(); 67 | 68 | var table = uiCanvas.Stage.AddElement(new Table()); 69 | table.SetFillParent(true).Left().Top().PadLeft(10).PadTop(50); 70 | 71 | 72 | var checkbox = table.Add(new CheckBox("Toggle PostProcessor", skin)).GetElement(); 73 | checkbox.IsChecked = true; 74 | checkbox.OnChanged += isChecked => { _spriteLightPostProcessor.Enabled = isChecked; }; 75 | 76 | table.Row().SetPadTop(20).SetAlign(Align.Left); 77 | 78 | table.Add("Blend Multiplicative Factor"); 79 | table.Row().SetPadTop(0).SetAlign(Align.Left); 80 | 81 | var slider = table.Add(new Slider(0.5f, 3f, 0.1f, false, skin.Get())).SetFillX() 82 | .GetElement(); 83 | slider.SetValue(1f); 84 | slider.OnChanged += value => { _spriteLightPostProcessor.MultiplicativeFactor = value; }; 85 | 86 | table.Row().SetPadTop(20).SetAlign(Align.Left); 87 | 88 | table.Add("Ambient Light Intensity"); 89 | table.Row().SetPadTop(0).SetAlign(Align.Left); 90 | 91 | var ambientColorStyle = table.Add(new Slider(10, 75, 1f, false, skin.Get())).SetFillX() 92 | .GetElement(); 93 | ambientColorStyle.SetValue(10f); 94 | ambientColorStyle.OnChanged += value => 95 | { 96 | var valueInt = Mathf.RoundToInt(value); 97 | _lightRenderer.RenderTargetClearColor = new Color(valueInt, valueInt, valueInt * 2, 255); 98 | }; 99 | 100 | table.Row().SetPadTop(20).SetAlign(Align.Left).SetFillX(); 101 | 102 | var button = table.Add(new TextButton("Add Light", skin)).SetFillX().SetMinHeight(30) 103 | .GetElement(); 104 | button.OnClicked += butt => 105 | { 106 | var lightTex = Content.LoadTexture(Nez.Content.SpriteLights.Spritelight); 107 | var position = new Vector2(Random.Range(0, Screen.Width), Random.Range(0, Screen.Height)); 108 | AddSpriteLight(lightTex, position, Random.Range(2f, 3f)); 109 | }; 110 | } 111 | 112 | void AddSpriteLight(Texture2D texture, Vector2 position, float scale) 113 | { 114 | // random target to tween towards that is on screen 115 | var target = new Vector2(Random.Range(50, SceneRenderTargetSize.X - 100), 116 | Random.Range(50, SceneRenderTargetSize.Y - 100)); 117 | 118 | var entity = CreateEntity("light"); 119 | var sprite = entity.AddComponent(new SpriteRenderer(texture)); 120 | entity.Position = position; 121 | entity.Scale = new Vector2(scale); 122 | sprite.RenderLayer = SpriteLightRenderLayer; 123 | 124 | if (Random.Chance(50)) 125 | { 126 | sprite.SetColor(Random.NextColor()); 127 | var cyler = entity.AddComponent(new ColorCycler()); 128 | cyler.WaveFunction = (WaveFunctions)Random.Range(0, 5); 129 | cyler.Offset = Random.NextFloat(); 130 | cyler.Frequency = Random.Range(0.6f, 1.5f); 131 | cyler.Phase = Random.NextFloat(); 132 | } 133 | else 134 | { 135 | entity.TweenPositionTo(target, 2) 136 | .SetCompletionHandler(LightTweenCompleted) 137 | .SetRecycleTween(false) 138 | .Start(); 139 | } 140 | } 141 | 142 | void LightTweenCompleted(ITween tween) 143 | { 144 | // get a random point on screen and a random delay for the tweens 145 | var target = new Vector2(Random.Range(50, SceneRenderTargetSize.X - 100), 146 | Random.Range(50, SceneRenderTargetSize.Y - 100)); 147 | var delay = Random.Range(0f, 1f); 148 | 149 | var transform = tween.GetTargetObject() as Transform; 150 | tween.PrepareForReuse(transform.Position, target, 2f) 151 | .SetCompletionHandler(LightTweenCompleted) 152 | .SetDelay(delay) 153 | .Start(); 154 | 155 | // every so often add a scale tween 156 | if (Random.Chance(60)) 157 | { 158 | transform.TweenLocalScaleTo(transform.LocalScale.X * 2f, 1f) 159 | .SetLoops(LoopType.PingPong) 160 | .SetEaseType(EaseType.CubicIn) 161 | .SetDelay(delay) 162 | .Start(); 163 | } 164 | 165 | // every so often change our color 166 | if (Random.Chance(80)) 167 | { 168 | var sprite = transform.Entity.GetComponent(); 169 | PropertyTweens.ColorPropertyTo(sprite, "Color", Random.NextColor(), 2f) 170 | .SetDelay(delay) 171 | .Start(); 172 | } 173 | } 174 | } 175 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Stencil Shadows/LiveLightController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Input; 3 | 4 | namespace Nez.Samples 5 | { 6 | /// 7 | /// this Component lets you control a StencilLight with WASD keys and click to clone it 8 | /// 9 | public class LiveLightController : Component, IUpdatable 10 | { 11 | StencilLight _light; 12 | 13 | public override void OnAddedToEntity() 14 | { 15 | _light = Entity.GetComponent(); 16 | } 17 | 18 | public void Update() 19 | { 20 | Entity.SetPosition(Input.MousePosition); 21 | 22 | if (Input.IsKeyDown(Keys.W)) 23 | _light.Radius += 10; 24 | else if (Input.IsKeyDown(Keys.S)) 25 | _light.Radius -= 10; 26 | Entity.Scale = Vector2.Clamp(Entity.Scale, new Vector2(0.2f), new Vector2(30)); 27 | 28 | if (Input.IsKeyDown(Keys.A)) 29 | { 30 | var (h, s, l) = ColorExt.RgbToHsl(_light.Color); 31 | _light.Color = ColorExt.HslToRgb((h - 0.002f) % 360, s, l); 32 | } 33 | else if (Input.IsKeyDown(Keys.D)) 34 | { 35 | var (h, s, l) = ColorExt.RgbToHsl(_light.Color); 36 | _light.Color = ColorExt.HslToRgb((h + 0.002f) % 360, s, l); 37 | } 38 | 39 | if (Input.LeftMouseButtonPressed) 40 | { 41 | var clone = Entity.Clone(Entity.Position); 42 | clone.RemoveComponent(); 43 | Entity.Scene.AddEntity(clone); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Stencil Shadows/StencilShadowsScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Nez.PhysicsShapes; 4 | using Nez.Sprites; 5 | using Nez.Textures; 6 | 7 | namespace Nez.Samples 8 | { 9 | [SampleScene("Stencil Shadows", 41, "2D Stencil shadow system with a mouse controller light\nHold a/d to cycle color\nHold w/s to change radius\nClick to clone the light")] 10 | public class StencilShadowsScene : SampleScene 11 | { 12 | const int LIGHT_LAYER = 5; 13 | const int LIGHT_MAP_LAYER = 10; 14 | const int BG_LAYER = 15; 15 | 16 | public StencilShadowsScene() : base(false) 17 | { } 18 | 19 | public override void Initialize() 20 | { 21 | base.Initialize(); 22 | 23 | SetDesignResolution(1280, 720, SceneResolutionPolicy.ShowAll); 24 | Screen.SetSize(1280, 720); 25 | 26 | // render layer for all lights 27 | ClearColor = Color.White; 28 | 29 | // create the StencilLightRenderer that renders only the light layer into a render target. Remember, when we render into a RenderTexture 30 | // we need to render before other renderers so we set our renderOrder to -1 31 | var lightRenderer = AddRenderer(new StencilLightRenderer(-1, LIGHT_LAYER, new RenderTexture())); 32 | 33 | // the clear color acts as ambient light. We set it to a dark color to make the lights stand out a bit. 34 | lightRenderer.RenderTargetClearColor = new Color(20, 20, 20, 255); 35 | 36 | // renderer for the background image and the light map (created by StencilLightRenderer) 37 | AddRenderer(new RenderLayerRenderer(0, BG_LAYER)); 38 | AddRenderer(new RenderLayerRenderer(1, LIGHT_MAP_LAYER)); 39 | 40 | // lastly, we render all the obstacles AFTER the light map. This keeps them above it so they are always visible. 41 | AddRenderer(new RenderLayerRenderer(2, 0)); 42 | 43 | CreateLights(); 44 | CreateBoxes(); 45 | CreateObstacles(); 46 | 47 | // create the background texture, setting it to the correct RenderLayer 48 | var bgTexture = Content.LoadTexture(Nez.Content.SpriteLights.Bg); 49 | CreateEntity("bg") 50 | .SetPosition(Screen.Center) 51 | .SetScale(9.4f) 52 | .AddComponent(new SpriteRenderer(bgTexture)) 53 | .SetRenderLayer(BG_LAYER); 54 | 55 | // the light-map will render the lightmap that our StencilLightRenderer creates for us with multiplicative blending 56 | CreateEntity("light-map") 57 | .SetPosition(Screen.Center) 58 | .AddComponent(new SpriteRenderer(lightRenderer.RenderTexture)) 59 | .SetMaterial(Material.BlendMultiply()) 60 | .SetRenderLayer(LIGHT_MAP_LAYER); 61 | } 62 | 63 | /// 64 | /// creates some StencilLights and a SpriteRenderer light 65 | /// 66 | void CreateLights() 67 | { 68 | var lightTex = Content.LoadTexture(Nez.Content.SpriteLights.Spritelight); 69 | CreateEntity("texture-light") 70 | .SetPosition(Screen.Center + new Vector2(200, 200)) 71 | .SetScale(8) 72 | .AddComponent(new SpriteRenderer(lightTex)) 73 | .SetRenderLayer(LIGHT_LAYER) 74 | .SetColor(Color.GreenYellow); 75 | 76 | CreateEntity("light2") 77 | .SetPosition(Screen.Center + new Vector2(200, -200)) 78 | .AddComponent(new StencilLight(400, Color.AntiqueWhite)) 79 | .SetRenderLayer(LIGHT_LAYER); 80 | 81 | CreateEntity("light3") 82 | .SetPosition(300, 600) 83 | .AddComponent(new StencilLight(400, new Color(200, 20, 20))) 84 | .SetRenderLayer(LIGHT_LAYER) 85 | .AddComponent(); 86 | } 87 | 88 | /// 89 | /// creates some textures boxes 90 | /// 91 | void CreateBoxes() 92 | { 93 | var blockTexture = Content.LoadTexture(Nez.Content.Shadows.Block); 94 | CreateEntity("block1") 95 | .SetPosition(Screen.Center) 96 | .AddComponent(new SpriteRenderer(blockTexture)) 97 | .AddComponent(); 98 | 99 | CreateEntity("block2") 100 | .SetPosition(Screen.Center - new Vector2(200, 200)) 101 | .AddComponent(new SpriteRenderer(blockTexture)) 102 | .AddComponent(); 103 | } 104 | 105 | /// 106 | /// create some polygons and a circle so the lights have something interesting to interact with 107 | /// 108 | void CreateObstacles() 109 | { 110 | var trianglePoints = new Vector2[] { new Vector2(0, 0), new Vector2(100, -100), new Vector2(-100, -150) }; 111 | CreateEntity("triangle") 112 | .SetPosition(100, 300) 113 | .AddComponent(new PolygonMesh(trianglePoints, false).SetColor(Color.LightGreen)) 114 | .AddComponent(new PolygonCollider(trianglePoints)); 115 | 116 | CreateEntity("circle") 117 | .SetPosition(1000, 250) 118 | .AddComponent(new SpriteRenderer(Content.LoadTexture(Nez.Content.Shared.Moon))) 119 | .SetColor(Color.LightGreen) 120 | .AddComponent(new CircleCollider(64)); 121 | 122 | var polyPoints = Polygon.BuildSymmetricalPolygon(5, 140); 123 | var polygonEntity = CreateEntity("polygon"); 124 | polygonEntity.SetPosition(460, 450) 125 | .AddComponent(new PolygonMesh(polyPoints)).SetTexture(Content.LoadTexture(Nez.Content.Shared.Moon)) 126 | .AddComponent(new PolygonCollider(polyPoints)); 127 | 128 | polygonEntity.TweenRotationDegreesTo(180, 3f) 129 | .SetLoops(Tweens.LoopType.PingPong, 50) 130 | .SetEaseType(Tweens.EaseType.Linear) 131 | .Start(); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Verlet Physics/VerletPhysicsScene.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Graphics; 3 | using Nez.PhysicsShapes; 4 | using Nez.Sprites; 5 | using Nez.Verlet; 6 | 7 | 8 | namespace Nez.Samples 9 | { 10 | [SampleScene("Verlet Physics", 55, 11 | "Verlet physics objects interacting with standard Nez Colliders\nClick and drag any particles to interact with them\nPress g to toggle gravity and z to toggle zero gravity")] 12 | public class VerletPhysicsScene : SampleScene 13 | { 14 | public VerletPhysicsScene() : base(true, true) 15 | { } 16 | 17 | public override void Initialize() 18 | { 19 | ClearColor = Color.Black; 20 | SetDesignResolution(1280, 720, SceneResolutionPolicy.ShowAll); 21 | Screen.SetSize(1280, 720); 22 | 23 | // create an Entity and Component to manage the Verlet World and tick its update method 24 | var verletSystem = CreateEntity("verlet-system") 25 | .AddComponent(); 26 | 27 | // first, we'll create some standard Nez Colliders for the Verlet objects to interact with 28 | CreatePolygons(); 29 | 30 | // add a rope, which is just a series of points connected by constraints 31 | CreateRope(verletSystem.World); 32 | 33 | // add some of the included Composite objects 34 | verletSystem.World.AddComposite(new Tire(new Vector2(350, 64), 64, 32, 0.3f, 0.5f)); 35 | verletSystem.World.AddComposite(new Tire(new Vector2(600, 32), 50, 4, 0.2f, 0.7f)); 36 | verletSystem.World.AddComposite(new Tire(new Vector2(900, 128), 64, 7, 0.1f, 0.3f)); 37 | 38 | verletSystem.World.AddComposite(new Cloth(new Vector2(900, 10), 200, 200, 20, 0.25f, 50)); 39 | 40 | verletSystem.World.AddComposite(new Ragdoll(400, 20, Random.Range(140, 240))); 41 | verletSystem.World.AddComposite(new Ragdoll(500, 20, Random.Range(140, 240))); 42 | verletSystem.World.AddComposite(new Ragdoll(600, 20, Random.Range(140, 240))); 43 | 44 | verletSystem.World.AddComposite(new Ball(new Vector2(100, 60), Random.Range(10, 50))); 45 | verletSystem.World.AddComposite(new Ball(new Vector2(150, 60), Random.Range(10, 50))); 46 | verletSystem.World.AddComposite(new Ball(new Vector2(200, 60), Random.Range(10, 50))); 47 | } 48 | 49 | void CreatePolygons() 50 | { 51 | var trianglePoints = new Vector2[] { new Vector2(0, 0), new Vector2(100, -100), new Vector2(-100, -150) }; 52 | var triangleEntity = CreateEntity("triangle"); 53 | triangleEntity.SetPosition(100, 300); 54 | triangleEntity.AddComponent(new PolygonMesh(trianglePoints, false).SetColor(Color.LightGreen)); 55 | triangleEntity.AddComponent(new PolygonCollider(trianglePoints)); 56 | 57 | 58 | var circleEntity = CreateEntity("circle"); 59 | circleEntity.SetPosition(1000, 250); 60 | circleEntity.AddComponent(new SpriteRenderer(Content.LoadTexture(Nez.Content.Shared.Moon))) 61 | .SetColor(Color.LightGreen); 62 | circleEntity.AddComponent(new CircleCollider(64)); 63 | 64 | 65 | var polyPoints = Polygon.BuildSymmetricalPolygon(5, 140); 66 | var polygonEntity = CreateEntity("boxCollider"); 67 | polygonEntity.SetPosition(460, 450); 68 | polygonEntity.AddComponent(new PolygonMesh(polyPoints)).SetColor(Color.LightGreen); 69 | polygonEntity.AddComponent(new PolygonCollider(polyPoints)); 70 | 71 | polygonEntity.TweenRotationDegreesTo(180, 3f) 72 | .SetLoops(Tweens.LoopType.PingPong, 50) 73 | .SetEaseType(Tweens.EaseType.Linear) 74 | .Start(); 75 | } 76 | 77 | void CreateRope(VerletWorld world) 78 | { 79 | // create an array of points for our rope 80 | var linePoints = new Vector2[10]; 81 | for (var i = 0; i < 10; i++) 82 | linePoints[i] = new Vector2(30 * i + 50, 10); 83 | 84 | var line = new LineSegments(linePoints, 0.3f) 85 | .PinParticleAtIndex(0); 86 | world.AddComposite(line); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /Nez.Samples/Scenes/Samples/Verlet Physics/VerletSystem.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Input; 3 | using Nez.Verlet; 4 | 5 | 6 | namespace Nez.Samples 7 | { 8 | /// 9 | /// component that manages the Verlet World calling it's Update and DebugRender methods. Also handles toggling gravity via the G and Z keys. 10 | /// 11 | public class VerletSystem : RenderableComponent, IUpdatable 12 | { 13 | public override float Width => 1280; 14 | 15 | public override float Height => 720; 16 | 17 | public VerletWorld World; 18 | 19 | 20 | public VerletSystem() 21 | { 22 | World = new VerletWorld(new Rectangle(0, 0, (int)Width, (int)Height)); 23 | } 24 | 25 | 26 | void ToggleGravity() 27 | { 28 | if (World.Gravity.Y > 0) 29 | World.Gravity.Y = -980f; 30 | else 31 | World.Gravity.Y = 980f; 32 | 33 | Debug.DrawText(string.Format("Gravity {0}", World.Gravity.Y > 0 ? "Down" : "Up"), Color.Red, 2, 2); 34 | } 35 | 36 | 37 | void ToggleZeroGravity() 38 | { 39 | if (World.Gravity.Y == 0) 40 | { 41 | World.Gravity.Y = 980f; 42 | Debug.DrawText("Gravity Restored", Color.Red, 2, 2); 43 | } 44 | else 45 | { 46 | World.Gravity.Y = 0; 47 | Debug.DrawText("Zero Gravity", Color.Red, 2, 2); 48 | } 49 | } 50 | 51 | 52 | public void Update() 53 | { 54 | if (Input.IsKeyPressed(Keys.G)) 55 | ToggleGravity(); 56 | 57 | if (Input.IsKeyPressed(Keys.Z)) 58 | ToggleZeroGravity(); 59 | 60 | World.Update(); 61 | } 62 | 63 | 64 | public override void Render(Batcher batcher, Camera camera) => World.DebugRender(batcher); 65 | } 66 | } -------------------------------------------------------------------------------- /Nez.Samples/Shared/ContentPathGenerator.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | namespace Nez 4 | { 5 | /// 6 | /// class that contains the names of all of the files processed by the Pipeline Tool 7 | /// 8 | /// 9 | /// Nez includes a T4 template that will auto-generate the content of this file. 10 | /// See: https://github.com/prime31/Nez/blob/master/FAQs/ContentManagement.md#auto-generating-content-paths" 11 | /// 12 | class Content 13 | { 14 | public static class AnimatedTiles 15 | { 16 | public const string Desertpalace = @"Content/AnimatedTiles/desert-palace.tmx"; 17 | public const string Desertpalacelamp = @"Content/AnimatedTiles/desert-palace-lamp.png"; 18 | public const string Desertpalacetiles = @"Content/AnimatedTiles/desert-palace-tiles.png"; 19 | } 20 | 21 | public static class DeferredLighting 22 | { 23 | public const string Bg = @"Content/DeferredLighting/bg.png"; 24 | public const string BgNorm = @"Content/DeferredLighting/bgNorm.png"; 25 | public const string Moon = @"Content/DeferredLighting/moon.png"; 26 | public const string MoonNorm = @"Content/DeferredLighting/moonNorm.png"; 27 | public const string Orange = @"Content/DeferredLighting/orange.png"; 28 | public const string OrangeNorm = @"Content/DeferredLighting/orangeNorm.png"; 29 | } 30 | 31 | public static class DestructableMap 32 | { 33 | public const string Desertpalacetiles2x = @"Content/DestructableMap/desert-palace-tiles2x.png"; 34 | public const string Destructablemap = @"Content/DestructableMap/destructable-map.tmx"; 35 | } 36 | 37 | public static class NinjaAdventure 38 | { 39 | public static class Characters 40 | { 41 | public const string _1 = @"Content/NinjaAdventure/characters/1.png"; 42 | public const string _2 = @"Content/NinjaAdventure/characters/2.png"; 43 | public const string _3 = @"Content/NinjaAdventure/characters/3.png"; 44 | public const string _4 = @"Content/NinjaAdventure/characters/4.png"; 45 | public const string _5 = @"Content/NinjaAdventure/characters/5.png"; 46 | public const string _6 = @"Content/NinjaAdventure/characters/6.png"; 47 | } 48 | 49 | public static class Map 50 | { 51 | public const string Tilemap = @"Content/NinjaAdventure/map/tilemap.tmx"; 52 | public const string Tileset = @"Content/NinjaAdventure/map/tileset.png"; 53 | } 54 | 55 | public const string Plume = @"Content/NinjaAdventure/plume.png"; 56 | } 57 | 58 | public static class ParticleDesigner 59 | { 60 | public const string AtomicBubble = @"Content/ParticleDesigner/Atomic Bubble.pex"; 61 | public const string BlueFlame = @"Content/ParticleDesigner/Blue Flame.pex"; 62 | public const string BlueGalaxy = @"Content/ParticleDesigner/Blue Galaxy.pex"; 63 | public const string Comet = @"Content/ParticleDesigner/Comet.pex"; 64 | public const string CrazyBlue = @"Content/ParticleDesigner/Crazy Blue.pex"; 65 | public const string Electrons = @"Content/ParticleDesigner/Electrons.pex"; 66 | public const string Fire = @"Content/ParticleDesigner/Fire.pex"; 67 | public const string Foam = @"Content/ParticleDesigner/Foam.pex"; 68 | public const string GirosGratis = @"Content/ParticleDesigner/Giros Gratis.pex"; 69 | public const string Huo1 = @"Content/ParticleDesigner/huo1.pex"; 70 | public const string IntoTheBlue = @"Content/ParticleDesigner/Into The Blue.pex"; 71 | public const string JasonChoi_Flash = @"Content/ParticleDesigner/JasonChoi_Flash.pex"; 72 | public const string JasonChoi_risingup = @"Content/ParticleDesigner/JasonChoi_rising up.pex"; 73 | public const string JasonChoi_Swirl01 = @"Content/ParticleDesigner/JasonChoi_Swirl01.pex"; 74 | public const string Leaves = @"Content/ParticleDesigner/Leaves.pex"; 75 | public const string MeksBloodSpill = @"Content/ParticleDesigner/Meks Blood Spill.pex"; 76 | public const string PlasmaGlow = @"Content/ParticleDesigner/Plasma Glow.pex"; 77 | public const string RealPopcorn = @"Content/ParticleDesigner/Real Popcorn.pex"; 78 | public const string ShootingFireball = @"Content/ParticleDesigner/Shooting Fireball.pex"; 79 | public const string Snow = @"Content/ParticleDesigner/Snow.pex"; 80 | public const string TheSun = @"Content/ParticleDesigner/The Sun.pex"; 81 | public const string Thingy = @"Content/ParticleDesigner/Thingy.pex"; 82 | public const string Thingy_tex = @"Content/ParticleDesigner/thingy_tex.png"; 83 | public const string TouchUp = @"Content/ParticleDesigner/Touch Up.pex"; 84 | public const string Trippy = @"Content/ParticleDesigner/Trippy.pex"; 85 | public const string WinnerStars = @"Content/ParticleDesigner/Winner Stars.pex"; 86 | public const string Wu1 = @"Content/ParticleDesigner/wu1.pex"; 87 | } 88 | 89 | public static class Platformer 90 | { 91 | public const string Caveman = @"Content/Platformer/caveman.png"; 92 | public const string TiledMap = @"Content/Platformer/tiledMap.tmx"; 93 | public const string Tileset = @"Content/Platformer/tileset.png"; 94 | } 95 | 96 | public static class Shadows 97 | { 98 | public const string Block = @"Content/Shadows/Block.png"; 99 | public const string BlockGlow = @"Content/Shadows/BlockGlow.png"; 100 | public const string Light = @"Content/Shadows/Light.fx"; 101 | public const string Spritelight = @"Content/Shadows/sprite-light.png"; 102 | } 103 | 104 | public static class Shared 105 | { 106 | public const string Moon = @"Content/Shared/moon.png"; 107 | } 108 | 109 | public static class SpriteLights 110 | { 111 | public const string Bg = @"Content/SpriteLights/bg.png"; 112 | public const string Pixelspritelight = @"Content/SpriteLights/pixel-sprite-light.png"; 113 | public const string Spritelight = @"Content/SpriteLights/sprite-light.png"; 114 | public const string Tubelight = @"Content/SpriteLights/tube-light.png"; 115 | } 116 | 117 | public static class SVG 118 | { 119 | public const string Farseersvg = @"Content/SVG/farseer-svg.svg"; 120 | } 121 | 122 | 123 | } 124 | } 125 | 126 | -------------------------------------------------------------------------------- /Nez.Samples/Shared/ContentPathGenerator.tt: -------------------------------------------------------------------------------- 1 | <#@ template language="C#" hostSpecific="true" #> 2 | <#@ assembly name="System.Core" #> 3 | <#@ import namespace="System.Linq" #> 4 | <#@ import namespace="System.Text" #> 5 | <#@ import namespace="System.Collections.Generic" #> 6 | <#@ import namespace="System.IO" #> 7 | <#@ import namespace="System.Globalization" #> 8 | <#@ import namespace="System.Text.RegularExpressions" #> 9 | 10 | <# 11 | // Paths to the content folders, relative to the .tt file 12 | string[] sourceFolders = new string[] { "../Content" }; 13 | #> 14 | 15 | namespace Nez 16 | { 17 | /// 18 | /// class that contains the names of all of the files processed by the Pipeline Tool 19 | /// 20 | /// 21 | /// Nez includes a T4 template that will auto-generate the content of this file. 22 | /// See: https://github.com/prime31/Nez/blob/master/FAQs/ContentManagement.md#auto-generating-content-paths" 23 | /// 24 | class Content 25 | { 26 | <# 27 | // loop through all of our sourceFolders 28 | foreach( var sourceFolder in sourceFolders ) 29 | { 30 | List directories = Directory.GetDirectories(Host.ResolvePath(sourceFolder)) 31 | .OrderBy(s => s) 32 | .ToList(); 33 | 34 | // loop through all the directories in our sourceFolder 35 | foreach(var dir in directories) 36 | { 37 | var dirName = new DirectoryInfo( dir ).Name.ToLower(); 38 | if( dirName == "bin" || dirName == "obj" || dirName == "content" ) 39 | continue; 40 | 41 | // start off the recursive directory printing 42 | PrintDirectoryClass( dir, 2, sourceFolder ); 43 | } 44 | 45 | // handle any files in the root sourceFolder 46 | PrintContentFiles( Host.ResolvePath( sourceFolder ), 2, Host.ResolvePath( sourceFolder ) ); 47 | } 48 | 49 | #> 50 | 51 | } 52 | } 53 | 54 | <#+ 55 | // C# reserved keywords 56 | private System.Collections.Generic.HashSet Keywords = new System.Collections.Generic.HashSet 57 | { 58 | "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", 59 | "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", 60 | "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", 61 | "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", 62 | "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while" 63 | }; 64 | 65 | // recursively creates a class for each directory 66 | void PrintDirectoryClass( string dir, int depth, string sourceFolder ) 67 | { 68 | var dirInfo = new DirectoryInfo( dir ); 69 | var firstIndent = new string( '\t', depth ); 70 | var className = GenerateClassName( dirInfo.Name ); 71 | WriteLine( "{0}public static class {1}\n{2}{{", firstIndent, className, firstIndent ); 72 | 73 | // handle subdirectories 74 | foreach(var subdir in Directory.GetDirectories(dir).OrderBy(s => s)) 75 | PrintDirectoryClass( subdir, depth + 1, sourceFolder ); 76 | 77 | // handle files 78 | PrintContentFiles( dir, depth + 1, sourceFolder ); 79 | 80 | WriteLine( "{0}}}\n", firstIndent ); 81 | } 82 | 83 | 84 | // prints a const string for each file in the directory 85 | void PrintContentFiles( string dir, int depth, string sourceFolder ) 86 | { 87 | var firstIndent = new string( '\t', depth ); 88 | 89 | foreach(var file in Directory.GetFiles( dir ).OrderBy(s => s)) 90 | { 91 | if (file.Contains("DS_Store") || file.EndsWith("mgfxo")) 92 | continue; 93 | 94 | // clear out all of the path up to the sourceFolder so we get just the relative path to the Content folder 95 | var finalPath = file.Substring( file.IndexOf( sourceFolder ) + 3 ); 96 | var fileInfo = new FileInfo( file ); 97 | var className = GenerateClassName( fileInfo.Name.Replace(Path.GetExtension(fileInfo.Name), "") ); 98 | 99 | if( finalPath[0] == '/' || finalPath[0] == '\\' ) 100 | finalPath = finalPath.Substring( 1 ); 101 | 102 | // if file name is reserved insert a leading '@' 103 | if( Keywords.Contains( fileInfo.Name ) ) 104 | className = className.Insert( 0, "@" ); 105 | 106 | WriteLine( "{0}public const string {1} = @\"{2}\";", firstIndent, className, finalPath ); 107 | } 108 | } 109 | 110 | // attempts to generate a proper path name 111 | string GenerateClassName( string className ) 112 | { 113 | // handle upper or lower casing the first char in the className 114 | if( char.IsLower( className[0] ) ) 115 | className = char.ToUpper( className[0] ) + className.Substring( 1 ); 116 | 117 | // remove invalid characters 118 | var regex = new Regex( @"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]" ); 119 | className = regex.Replace( className, "" ); 120 | 121 | // class name doesn't begin with a letter, insert an underscore 122 | if( !char.IsLetter( className, 0 ) ) 123 | className = className.Insert( 0, "_" ); 124 | 125 | return className.Replace( " ", string.Empty ); 126 | } 127 | #> -------------------------------------------------------------------------------- /Nez.Samples/Shared/MovingPlatform.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace Nez.Samples 6 | { 7 | public class MovingPlatform : Component, IUpdatable 8 | { 9 | float _minX; 10 | float _maxX; 11 | float _minY; 12 | float _maxY; 13 | float _speedFactor; 14 | 15 | 16 | public MovingPlatform(float minY, float maxY, float speedFactor = 2f) 17 | { 18 | _minY = minY; 19 | _maxY = maxY; 20 | _speedFactor = speedFactor; 21 | } 22 | 23 | 24 | public override void OnAddedToEntity() 25 | { 26 | _minX = Entity.Position.X; 27 | _maxX = _minX + 100; 28 | } 29 | 30 | 31 | void IUpdatable.Update() 32 | { 33 | var x = Mathf.PingPong(Time.TotalTime, 1f); 34 | var xToTheSpeedFactor = Mathf.Pow(x, _speedFactor); 35 | var alpha = 1f - xToTheSpeedFactor / xToTheSpeedFactor + Mathf.Pow(1 - x, _speedFactor); 36 | 37 | var deltaY = Tweens.Lerps.Lerp(_minY, _maxY, alpha) - Entity.Position.Y; 38 | var deltaX = Tweens.Lerps.Lerp(_minX, _maxX, alpha) - Entity.Position.X; 39 | 40 | // TODO: probably query Physics to fetch the actors that we will intersect instead of blindly grabbing them all 41 | var ridingActors = GetAllRidingActors(); 42 | 43 | MoveSolid(new Vector2(deltaX, deltaY), ridingActors); 44 | } 45 | 46 | 47 | void MoveSolid(Vector2 motion, List ridingActors) 48 | { 49 | if (motion.X == 0 && motion.Y == 0) 50 | return; 51 | 52 | MoveSolidX(motion.X, ridingActors); 53 | MoveSolidY(motion.Y, ridingActors); 54 | } 55 | 56 | 57 | void MoveSolidX(float amount, List ridingActors) 58 | { 59 | var moved = false; 60 | Entity.Position += new Vector2(amount, 0); 61 | 62 | var platformCollider = Entity.GetComponent(); 63 | var colliders = new HashSet(Physics.BoxcastBroadphaseExcludingSelf(platformCollider)); 64 | foreach (var collider in colliders) 65 | { 66 | float pushAmount; 67 | if (amount > 0) 68 | pushAmount = platformCollider.Bounds.Right - collider.Bounds.Left; 69 | else 70 | pushAmount = platformCollider.Bounds.Left - collider.Bounds.Right; 71 | 72 | var mover = collider.Entity.GetComponent(); 73 | if (mover != null) 74 | { 75 | moved = true; 76 | CollisionResult collisionResult; 77 | if (mover.Move(new Vector2(pushAmount, 0), out collisionResult)) 78 | { 79 | collider.Entity.Destroy(); 80 | return; 81 | } 82 | } 83 | else 84 | { 85 | collider.Entity.Position += new Vector2(pushAmount, 0); 86 | } 87 | } 88 | 89 | 90 | foreach (var ent in ridingActors) 91 | { 92 | if (!moved) 93 | ent.Position += new Vector2(amount, 0); 94 | } 95 | } 96 | 97 | 98 | void MoveSolidY(float amount, List ridingActors) 99 | { 100 | var moved = false; 101 | Entity.Position += new Vector2(0, amount); 102 | 103 | var platformCollider = Entity.GetComponent(); 104 | var colliders = new HashSet(Physics.BoxcastBroadphaseExcludingSelf(platformCollider)); 105 | foreach (var collider in colliders) 106 | { 107 | float pushAmount; 108 | if (amount > 0) 109 | pushAmount = platformCollider.Bounds.Bottom - collider.Bounds.Top; 110 | else 111 | pushAmount = platformCollider.Bounds.Top - collider.Bounds.Bottom; 112 | 113 | var mover = collider.Entity.GetComponent(); 114 | if (mover != null) 115 | { 116 | moved = true; 117 | CollisionResult collisionResult; 118 | if (mover.Move(new Vector2(0, pushAmount), out collisionResult)) 119 | { 120 | collider.Entity.Destroy(); 121 | return; 122 | } 123 | } 124 | else 125 | { 126 | collider.Entity.Position += new Vector2(0, pushAmount); 127 | } 128 | } 129 | 130 | 131 | foreach (var ent in ridingActors) 132 | { 133 | if (!moved) 134 | ent.Position += new Vector2(0, amount); 135 | } 136 | } 137 | 138 | 139 | /// 140 | /// brute force search for Entities on top of this Collider. Not a great approach. 141 | /// 142 | /// The all riding actors. 143 | List GetAllRidingActors() 144 | { 145 | var list = new List(); 146 | var platformCollider = Entity.GetComponent(); 147 | 148 | var entities = Entity.Scene.FindEntitiesWithTag(0); 149 | for (var i = 0; i < entities.Count; i++) 150 | { 151 | var collider = entities[i].GetComponent(); 152 | if (collider == platformCollider || collider == null) 153 | continue; 154 | 155 | if (collider.CollidesWith(platformCollider, new Vector2(0f, 1f), out CollisionResult collisionResult)) 156 | list.Add(entities[i]); 157 | } 158 | 159 | return list; 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /Nez.Samples/Shared/PressKeyToPerformAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Xna.Framework.Input; 3 | 4 | 5 | namespace Nez.Samples 6 | { 7 | /// 8 | /// simple Component that checks for a key press and runs an Action when it occurs. 9 | /// 10 | public class PressKeyToPerformAction : Component, IUpdatable 11 | { 12 | Keys _key; 13 | Action _action; 14 | 15 | 16 | public PressKeyToPerformAction(Keys key, Action action) 17 | { 18 | _key = key; 19 | _action = action; 20 | } 21 | 22 | 23 | void IUpdatable.Update() 24 | { 25 | if (Input.IsKeyPressed(_key)) 26 | _action(Entity); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Nez.Samples/Shared/SimpleMover.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework; 2 | using Microsoft.Xna.Framework.Input; 3 | using Nez.Sprites; 4 | 5 | 6 | namespace Nez.Samples 7 | { 8 | /// 9 | /// adds basic movement with the arrow keys and includes collision detection and resolution. A debug line is displayed when a collision 10 | /// occurs in the direction of the collision normal. 11 | /// 12 | public class SimpleMover : Component, IUpdatable 13 | { 14 | float _speed = 600f; 15 | Mover _mover; 16 | SpriteRenderer _sprite; 17 | 18 | 19 | public override void OnAddedToEntity() 20 | { 21 | _sprite = this.GetComponent(); 22 | _mover = new Mover(); 23 | Entity.AddComponent(_mover); 24 | } 25 | 26 | 27 | void IUpdatable.Update() 28 | { 29 | var moveDir = Vector2.Zero; 30 | 31 | if (Input.IsKeyDown(Keys.Left)) 32 | { 33 | moveDir.X = -1f; 34 | if (_sprite != null) 35 | _sprite.FlipX = true; 36 | } 37 | else if (Input.IsKeyDown(Keys.Right)) 38 | { 39 | moveDir.X = 1f; 40 | if (_sprite != null) 41 | _sprite.FlipX = false; 42 | } 43 | 44 | if (Input.IsKeyDown(Keys.Up)) 45 | moveDir.Y = -1f; 46 | else if (Input.IsKeyDown(Keys.Down)) 47 | moveDir.Y = 1f; 48 | 49 | 50 | if (moveDir != Vector2.Zero) 51 | { 52 | var movement = moveDir * _speed * Time.DeltaTime; 53 | 54 | if (_mover.Move(movement, out CollisionResult res)) 55 | Debug.DrawLine(Entity.Position, Entity.Position + res.Normal * 100, Color.Black, 0.3f); 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Nez.Samples/Shared/TriggerListener.cs: -------------------------------------------------------------------------------- 1 | namespace Nez.Samples 2 | { 3 | /// 4 | /// simple trigger listener that just logs enter/exit events 5 | /// 6 | public class TriggerListener : Component, ITriggerListener 7 | { 8 | void ITriggerListener.OnTriggerEnter(Collider other, Collider self) 9 | { 10 | Debug.Log("onTriggerEnter: {0} entered {1}", other, self); 11 | } 12 | 13 | 14 | void ITriggerListener.OnTriggerExit(Collider other, Collider self) 15 | { 16 | Debug.Log("onTriggerExit: {0} exited {1}", other, self); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Nez.Samples/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | true/pm 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Nez.Samples/libSDL2-2.0.0.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/libSDL2-2.0.0.dylib -------------------------------------------------------------------------------- /Nez.Samples/libopenal.1.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/Nez-Samples/c2d0996fe021054ebe0d235a0984cbf4159d7b26/Nez.Samples/libopenal.1.dylib -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nez-Samples 2 | 3 | Samples and demos of various [Nez](https://github.com/prime31/Nez) features. The Samples repo is built against MonoGame 3.7 + 3.8 + FNA. 4 | 5 | 6 | Setup 7 | ---- 8 | - Pull a fresh copy of the Nez-Samples repository. The samples repository has the base Nez repository as a submodule so to fully download everything you need add the `--recursive` parameter when cloning: 9 | 10 | `git clone --recursive https://github.com/prime31/Nez-Samples.git` 11 | 12 | - now you can open the `Nez.MG37.Samples.sln` (for MonoGame 3.7) or the `Nez.MG38.Samples.sln` (for MonoGame 3.8 and NET Core 3) or the `Nez.MG38.NET6.Samples.sln` (for MonoGame 3.8 and NET 6) and run the project (for NET Core 3+ you can also run with the command `dotnet run --project Nez.MG38.Samples.csproj`) 13 | 14 | 15 | Sample Scenes 16 | ---- 17 | You can click on any of the sample scene buttons on the right of the screen to load samples. If you are running a debug build, you can press the backtick key to open the debug console. Type "help" and press enter to see a list of available commands. You can type "help COMMAND" to see additional help text. Entering the "toggle-imgui" command will open an ImGui inspector letting you play around with the various entities in the scene. 18 | 19 | 20 | Setup FNA 21 | ---- 22 | - download the latest release of FNA from [here](https://github.com/FNA-XNA/FNA/releases/tag/19.09) and put it into a folder named `FNA` in the Nez-Samples folder 23 | - download the native libs FNA requires from [here](http://fna.flibitijibibo.com/archive/fnalibs.tar.bz2) into the `fnalibs` folder in the Nez-Samples folder 24 | - open the `Nez.FNA.Samples.sln` 25 | 26 | 27 | Assets License 28 | ---- 29 | Unless otherwise noted, the assets in the Nez Samples repo project are not MIT licensed. They should not be used in any project. Most are of unknown copyright/origin so assume they are all off limits and use them only for your own personal amusement. 30 | --------------------------------------------------------------------------------