Browse Source

Chase And Evade Updated to SDK projects and MG 3.8.*

CartBlanche 1 month ago
parent
commit
1c4a64090b
38 changed files with 1119 additions and 1308 deletions
  1. 27 0
      ChaseAndEvade/.vscode/launch.json
  2. 3 0
      ChaseAndEvade/.vscode/settings.json
  3. 27 0
      ChaseAndEvade/.vscode/tasks.json
  4. 0 21
      ChaseAndEvade/Activity1.cs
  5. 0 101
      ChaseAndEvade/ChaseAndEvade.Android.csproj
  6. 0 70
      ChaseAndEvade/ChaseAndEvade.Linux.csproj
  7. 0 91
      ChaseAndEvade/ChaseAndEvade.MacOS.csproj
  8. 0 69
      ChaseAndEvade/ChaseAndEvade.PSMobile.csproj
  9. 0 121
      ChaseAndEvade/ChaseAndEvade.iOS.csproj
  10. 52 0
      ChaseAndEvade/ChaseAndEvade.sln
  11. BIN
      ChaseAndEvade/Content/Arial.xnb
  12. 11 0
      ChaseAndEvade/Core/ChaseAndEvade.Core.csproj
  13. 696 721
      ChaseAndEvade/Core/ChaseAndEvadeGame.cs
  14. 0 0
      ChaseAndEvade/Core/Content/Default.png
  15. 0 0
      ChaseAndEvade/Core/Content/GameThumbnail.png
  16. 34 0
      ChaseAndEvade/Core/Content/app.manifest
  17. 0 0
      ChaseAndEvade/Core/Content/cat.png
  18. 0 0
      ChaseAndEvade/Core/Content/mouse.png
  19. 0 0
      ChaseAndEvade/Core/Content/tank.png
  20. 30 0
      ChaseAndEvade/Platforms/Android/Activity1.cs
  21. 18 0
      ChaseAndEvade/Platforms/Android/AndroidManifest.xml
  22. 27 0
      ChaseAndEvade/Platforms/Android/ChaseAndEvade.Android.csproj
  23. 0 0
      ChaseAndEvade/Platforms/Android/Resources/Drawable/Icon.png
  24. 0 0
      ChaseAndEvade/Platforms/Android/Resources/Drawable/Splash.png
  25. 0 0
      ChaseAndEvade/Platforms/Android/Resources/Resource.Designer.cs
  26. 4 0
      ChaseAndEvade/Platforms/Android/Resources/Values/Strings.xml
  27. 0 0
      ChaseAndEvade/Platforms/Android/Resources/Values/Styles.xml
  28. 26 0
      ChaseAndEvade/Platforms/Desktop/ChaseAndEvade.DesktopGL.csproj
  29. 15 0
      ChaseAndEvade/Platforms/Desktop/Program.cs
  30. 27 0
      ChaseAndEvade/Platforms/Windows/ChaseAndEvade.Windows.csproj
  31. 15 0
      ChaseAndEvade/Platforms/Windows/Program.cs
  32. 20 0
      ChaseAndEvade/Platforms/iOS/AppDelegate.cs
  33. 26 0
      ChaseAndEvade/Platforms/iOS/ChaseAndEvade.iOS.csproj
  34. 0 0
      ChaseAndEvade/Platforms/iOS/Info.plist
  35. 14 0
      ChaseAndEvade/Platforms/iOS/Program.cs
  36. 0 83
      ChaseAndEvade/Program.cs
  37. 47 0
      ChaseAndEvade/README.md
  38. 0 31
      ChaseAndEvade/app.xml

+ 27 - 0
ChaseAndEvade/.vscode/launch.json

@@ -0,0 +1,27 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Launch Windows",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-windows",
+            "program": "${workspaceFolder}/Platforms/Windows/bin/Debug/net8.0-windows/ChaseAndEvade.Windows.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        },
+        {
+            "name": "Launch DesktopGL",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl",
+            "program": "${workspaceFolder}/Platforms/Desktop/bin/Debug/net8.0/ChaseAndEvade.DesktopGL",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        }
+    ]
+}

+ 3 - 0
ChaseAndEvade/.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "dotnet.preferCSharpExtension": true
+}

+ 27 - 0
ChaseAndEvade/.vscode/tasks.json

@@ -0,0 +1,27 @@
+{
+	"version": "2.0.0",
+	"tasks": [
+		{
+			"label": "build-windows",
+			"type": "shell",
+			"command": "dotnet",
+			"args": [
+				"build",
+				"${workspaceFolder}/Platforms/Windows/ChaseAndEvade.Windows.csproj"
+			],
+			"group": "build",
+			"problemMatcher": ["$msCompile"]
+		},
+		{
+			"label": "build-desktopgl",
+			"type": "shell",
+			"command": "dotnet",
+			"args": [
+				"build",
+				"${workspaceFolder}/Platforms/Desktop/ChaseAndEvade.DesktopGL.csproj"
+			],
+			"group": "build",
+			"problemMatcher": ["$msCompile"]
+		},
+	]
+}

+ 0 - 21
ChaseAndEvade/Activity1.cs

@@ -1,21 +0,0 @@
-using Android.App;
-using Android.Content.PM;
-using Android.OS;
-using ChaseAndEvade;
-
-namespace MonoGame.Samples.ChaseAndEvade.Droid
-{
-    [Activity(Label = "ChaseAndEvade", MainLauncher = true,ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.Keyboard|ConfigChanges.KeyboardHidden,Icon = "@drawable/icon", Theme = "@style/Theme.Splash", NoHistory = true)]
-    public class Activity1 : Microsoft.Xna.Framework.AndroidGameActivity
-    {
-        protected override void OnCreate(Bundle bundle)
-        {
-            base.OnCreate(bundle);
-            ChaseAndEvadeGame.Activity = this;
-            ChaseAndEvadeGame g = new ChaseAndEvadeGame();
-            SetContentView(g.Window);
-            g.Run();
-        }
-    }
-}
-

+ 0 - 101
ChaseAndEvade/ChaseAndEvade.Android.csproj

@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{F05F90DC-DD37-4967-A96A-8D36C1C23E81}</ProjectGuid>
-    <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>MonoGame.Samples.ChaseAndEvade.Android</RootNamespace>
-    <AssemblyName>MonoGame.Samples.ChaseAndEvade.Android</AssemblyName>
-    <FileAlignment>512</FileAlignment>
-    <AndroidApplication>true</AndroidApplication>
-    <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
-    <AndroidSupportedAbis>armeabi</AndroidSupportedAbis>
-    <AndroidStoreUncompressedFileExtensions />
-    <MandroidI18n />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;ANDROID</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <AndroidLinkMode>None</AndroidLinkMode>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>True</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE;ANDROID</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
-    <AndroidLinkMode>SdkOnly</AndroidLinkMode>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Mono.Android" />
-    <Reference Include="mscorlib" />
-    <Reference Include="OpenTK" />
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Activity1.cs" />
-    <Compile Include="ChaseAndEvadeGame.cs">
-      <Link>ChaseAndEvadeGame.cs</Link>
-    </Compile>
-    <Compile Include="Resources\Resource.Designer.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <AndroidAsset Include="Content\Arial.xnb">
-      <Link>Assets\Content\Arial.xnb</Link>
-    </AndroidAsset>
-    <AndroidAsset Include="Content\cat.png">
-      <Link>Assets\Content\Cat.png</Link>
-    </AndroidAsset>
-    <AndroidAsset Include="Content\mouse.png">
-      <Link>Assets\Content\Mouse.png</Link>
-    </AndroidAsset>
-    <AndroidAsset Include="Content\tank.png">
-      <Link>Assets\Content\Tank.png</Link>
-    </AndroidAsset>
-  </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Properties\" />
-  </ItemGroup>
-  <ItemGroup>
-    <AndroidResource Include="Resources\Drawable\Icon.png" />
-  </ItemGroup>
-  <ItemGroup>
-    <AndroidResource Include="Resources\Drawable\Splash.png" />
-  </ItemGroup>
-  <ItemGroup>
-    <AndroidResource Include="Resources\Values\Styles.xml" />
-  </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-     Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-  <ItemGroup>
-    <ProjectReference Include="..\..\ThirdParty\Lidgren.Network\Lidgren.Network.Android.csproj">
-      <Project>{565129E0-4EE5-4F6F-B403-C3484C9740BE}</Project>
-      <Name>Lidgren.Network.Android</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\MonoGame.Framework\MonoGame.Framework.Android.csproj">
-      <Project>{BA9476CF-99BA-4D03-92F2-73D2C5E58883}</Project>
-      <Name>MonoGame.Framework.Android</Name>
-    </ProjectReference>
-  </ItemGroup>
-</Project>

+ 0 - 70
ChaseAndEvade/ChaseAndEvade.Linux.csproj

@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{86A619E2-C8F0-452B-B764-C69D5BB07C98}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>ChaseAndEvade</RootNamespace>
-    <AssemblyName>ChaseAndEvade</AssemblyName>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>LINUX;DEBUG</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <ConsolePause>False</ConsolePause>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <ConsolePause>False</ConsolePause>
-    <DefineConstants>LINUX</DefineConstants>
-  </PropertyGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Drawing" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Info.plist" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="ChaseAndEvadeGame.cs">
-      <Link>ChaseAndEvadeGame.cs</Link>
-    </Compile>
-    <Compile Include="Program.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Content\Arial.xnb">
-      <Link>Content\Arial.xnb</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\cat.png">
-      <Link>Content\cat.png</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\mouse.png">
-      <Link>Content\mouse.png</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\tank.png">
-      <Link>Content\tank.png</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="GameThumbnail.png" />
-  </ItemGroup>
-</Project>

+ 0 - 91
ChaseAndEvade/ChaseAndEvade.MacOS.csproj

@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{D03F3BAF-E4D0-4B6B-A567-9A0E2F882335}</ProjectGuid>
-    <ProjectTypeGuids>{948B3504-5B70-4649-8FE4-BDE1FB46EC69};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>ChaseAndEvade</RootNamespace>
-    <AssemblyName>ChaseAndEvade</AssemblyName>
-    <SuppressXamMacUpsell>True</SuppressXamMacUpsell>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG MONOMAC</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>False</ConsolePause>
-    <EnableCodeSigning>False</EnableCodeSigning>
-    <CreatePackage>False</CreatePackage>
-    <EnablePackageSigning>False</EnablePackageSigning>
-    <IncludeMonoRuntime>False</IncludeMonoRuntime>
-    <UseSGen>False</UseSGen>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>False</ConsolePause>
-    <EnableCodeSigning>False</EnableCodeSigning>
-    <CreatePackage>False</CreatePackage>
-    <EnablePackageSigning>False</EnablePackageSigning>
-    <IncludeMonoRuntime>False</IncludeMonoRuntime>
-    <UseSGen>False</UseSGen>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="MonoMac, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\MonoMac\monomac\src\MonoMac.dll</HintPath>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Info.plist">
-    </None>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
-  <ItemGroup>
-    <Compile Include="ChaseAndEvadeGame.cs">
-      <Link>ChaseAndEvadeGame.cs</Link>
-    </Compile>
-    <Compile Include="Program.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Content\Arial.xnb">
-      <Link>Content\Arial.xnb</Link>
-    </Content>
-    <Content Include="Content\cat.png">
-      <Link>Content\cat.png</Link>
-    </Content>
-    <Content Include="Content\mouse.png">
-      <Link>Content\mouse.png</Link>
-    </Content>
-    <Content Include="Content\tank.png">
-      <Link>Content\tank.png</Link>
-    </Content>
-    <Content Include="GameThumbnail.png" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj">
-      <Project>{AE483C29-042E-4226-BA52-D247CE7676DA}</Project>
-      <Name>Lidgren.Network.MacOS</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
-      <Project>{36C538E6-C32A-4A8D-A39C-566173D7118E}</Project>
-      <Name>MonoGame.Framework.MacOS</Name>
-    </ProjectReference>
-  </ItemGroup>
-</Project>

+ 0 - 69
ChaseAndEvade/ChaseAndEvade.PSMobile.csproj

@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{CA033BAB-B214-4BF9-A903-85038AE666AA}</ProjectGuid>
-    <ProjectTypeGuids>{69878862-DA7D-4DC6-B0A1-50D8FAB4242F};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>MonoGame.Samples.ChaseAndEvade.PSSuite</RootNamespace>
-    <AssemblyName>MonoGame.Samples.ChaseAndEvade.PSSuite</AssemblyName>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;PSM</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="Sce.PlayStation.Core" />
-  </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath)\Sce\Sce.Psm.CSharp.targets" />
-  <ItemGroup>
-    <Folder Include="Content\" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="..\CompiledContent\Android\Content\Textures\cat.xnb">
-      <Link>Content\cat.xnb</Link>
-    </Content>
-    <Content Include="..\CompiledContent\Android\Content\Textures\mouse.xnb">
-      <Link>Content\mouse.xnb</Link>
-    </Content>
-    <Content Include="..\CompiledContent\Android\Content\Textures\tank.xnb">
-      <Link>Content\tank.xnb</Link>
-    </Content>
-    <Content Include="..\CompiledContent\Android\Content\Fonts\Arial.xnb">
-      <Link>Content\Arial.xnb</Link>
-    </Content>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="ChaseAndEvadeGame.cs" />
-    <Compile Include="Program.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\MonoGame.Framework\MonoGame.Framework.PSMobile.csproj">
-      <Project>{EA26E76F-FDFE-4A8C-B5A3-C3B5761E28F9}</Project>
-      <Name>MonoGame.Framework.PSMobile</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <PsmMetadata Include="app.xml" />
-  </ItemGroup>
-</Project>

+ 0 - 121
ChaseAndEvade/ChaseAndEvade.iOS.csproj

@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{1557EE13-80AB-4E4C-9C10-9CBFC8E727C3}</ProjectGuid>
-    <ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>MonoGame.Samples.ChaseAndEvade</RootNamespace>
-    <AssemblyName>ChaseAndEvade</AssemblyName>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
-    <DefineConstants>DEBUG;IPHONE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <MtouchDebug>True</MtouchDebug>
-    <CodesignKey>iPhone Developer</CodesignKey>
-    <MtouchLink>None</MtouchLink>
-    <MtouchI18n />
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\iPhoneSimulator\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CodesignKey>iPhone Developer</CodesignKey>
-    <MtouchLink>None</MtouchLink>
-    <DefineConstants>IPHONE</DefineConstants>
-    <MtouchI18n />
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\iPhone\Debug</OutputPath>
-    <DefineConstants>DEBUG;IPHONE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <MtouchDebug>True</MtouchDebug>
-    <CodesignKey>iPhone Developer</CodesignKey>
-    <MtouchLink>None</MtouchLink>
-    <MtouchI18n />
-    <MtouchSdkVersion>3.0</MtouchSdkVersion>
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\iPhone\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <CodesignKey>iPhone Developer</CodesignKey>
-    <DefineConstants>IPHONE</DefineConstants>
-    <MtouchSdkVersion>3.0</MtouchSdkVersion>
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Distribution|iPhone' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin</OutputPath>
-    <WarningLevel>4</WarningLevel>
-    <CodesignKey>iPhone Developer</CodesignKey>
-    <MtouchI18n />
-    <DefineConstants>IPHONE</DefineConstants>
-    <MtouchSdkVersion>3.0</MtouchSdkVersion>
-    <MtouchUseArmv7>false</MtouchUseArmv7>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Distribution|iPhoneSimulator' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Distribution</OutputPath>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="monotouch" />
-    <Reference Include="OpenTK" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="ChaseAndEvadeGame.cs" />
-    <Compile Include="Program.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Content\" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <Content Include="Default.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\cat.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\mouse.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\tank.png">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\Arial.xnb">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="GameThumbnail.png" />
-    <None Include="Info.iOS.plist">
-      <Link>Info.plist</Link>
-    </None>
-  </ItemGroup>
-</Project>

+ 52 - 0
ChaseAndEvade/ChaseAndEvade.sln

@@ -0,0 +1,52 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaseAndEvade.Core", "Core\ChaseAndEvade.Core.csproj", "{11111111-1111-1111-1111-111111111111}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaseAndEvade.Windows", "Platforms\Windows\ChaseAndEvade.Windows.csproj", "{6F7F6462-B5C7-4A0F-81F3-DA25337575A7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaseAndEvade.DesktopGL", "Platforms\Desktop\ChaseAndEvade.DesktopGL.csproj", "{04A9E109-DA05-4EF7-BA74-5E919064F9BE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaseAndEvade.Android", "Platforms\Android\ChaseAndEvade.Android.csproj", "{65BF2AB1-1273-65FF-3251-DCBC81D384B9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaseAndEvade.iOS", "Platforms\iOS\ChaseAndEvade.iOS.csproj", "{D46A9C19-25DD-5D3E-FF28-6B85CBA6A981}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{11111111-1111-1111-1111-111111111111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{11111111-1111-1111-1111-111111111111}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{11111111-1111-1111-1111-111111111111}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{11111111-1111-1111-1111-111111111111}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6F7F6462-B5C7-4A0F-81F3-DA25337575A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6F7F6462-B5C7-4A0F-81F3-DA25337575A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6F7F6462-B5C7-4A0F-81F3-DA25337575A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6F7F6462-B5C7-4A0F-81F3-DA25337575A7}.Release|Any CPU.Build.0 = Release|Any CPU
+		{04A9E109-DA05-4EF7-BA74-5E919064F9BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{04A9E109-DA05-4EF7-BA74-5E919064F9BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{04A9E109-DA05-4EF7-BA74-5E919064F9BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{04A9E109-DA05-4EF7-BA74-5E919064F9BE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{65BF2AB1-1273-65FF-3251-DCBC81D384B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{65BF2AB1-1273-65FF-3251-DCBC81D384B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{65BF2AB1-1273-65FF-3251-DCBC81D384B9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{65BF2AB1-1273-65FF-3251-DCBC81D384B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{65BF2AB1-1273-65FF-3251-DCBC81D384B9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{65BF2AB1-1273-65FF-3251-DCBC81D384B9}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{D46A9C19-25DD-5D3E-FF28-6B85CBA6A981}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D46A9C19-25DD-5D3E-FF28-6B85CBA6A981}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D46A9C19-25DD-5D3E-FF28-6B85CBA6A981}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{D46A9C19-25DD-5D3E-FF28-6B85CBA6A981}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D46A9C19-25DD-5D3E-FF28-6B85CBA6A981}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D46A9C19-25DD-5D3E-FF28-6B85CBA6A981}.Release|Any CPU.Deploy.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {4D6B58F6-A54D-4F0D-B2C2-F59D9CB1BD01}
+	EndGlobalSection
+EndGlobal

BIN
ChaseAndEvade/Content/Arial.xnb


+ 11 - 0
ChaseAndEvade/Core/ChaseAndEvade.Core.csproj

@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>ChaseAndEvade</RootNamespace>
+    <AssemblyName>ChaseAndEvade.Core</AssemblyName>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+</Project>

+ 696 - 721
ChaseAndEvade/ChaseAndEvadeGame.cs → ChaseAndEvade/Core/ChaseAndEvadeGame.cs

@@ -1,721 +1,696 @@
-#region File Description
-//-----------------------------------------------------------------------------
-// Game.cs
-//
-// Microsoft XNA Community Game Platform
-// Copyright (C) Microsoft Corporation. All rights reserved.
-//-----------------------------------------------------------------------------
-#endregion
-
-#region Using Statements
-using System;
-
-#if ANDROID
-using Android.App;
-#endif
-
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-using Microsoft.Xna.Framework.Input.Touch;
-using Microsoft.Xna.Framework.Storage;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.Media;
-
-#endregion
-
-namespace ChaseAndEvade
-{
-	/// <summary>
-	/// Sample showing how to implement simple chase, evade, and wander AI behaviors.
-	/// The behaviors are based on the TurnToFace function, which was explained in
-	/// AI Sample 1: Aiming.
-	/// </summary>
-	public class ChaseAndEvadeGame : Game
-	{
-
-		/// <summary>
-		/// TankAiState is used to keep track of what the tank is currently doing.
-		/// </summary>
-		enum TankAiState
-		{
-			// chasing the cat
-			Chasing,
-			// the tank has gotten close enough that the cat that it can stop chasing it
-			Caught,
-			// the tank can't "see" the cat, and is wandering around.
-			Wander
-		}
-
-		/// <summary>
-		/// MouseAiState is used to keep track of what the mouse is currently doing.
-		/// </summary>
-		enum MouseAiState
-		{
-			// evading the cat
-			Evading,
-			// the mouse can't see the "cat", and it's wandering around.
-			Wander
-		}
-
-
-
-	#region Constants
-
-		// The following values control the different characteristics of the characters
-		// in this sample, including their speed, turning rates. distances are specified
-		// in pixels, angles are specified in radians.
-
-		// how fast can the cat move?
-		const float MaxCatSpeed = 7.5f;
-
-		// how fast can the tank move?
-		const float MaxTankSpeed = 5.0f;
-
-		// how fast can he turn?
-		const float TankTurnSpeed = 0.10f;
-
-		// this value controls the distance at which the tank will start to chase the
-		// cat.
-		const float TankChaseDistance = 250.0f;
-
-		// TankCaughtDistance controls the distance at which the tank will stop because
-		// he has "caught" the cat.
-		const float TankCaughtDistance = 60.0f;
-
-		// this constant is used to avoid hysteresis, which is common in ai programming.
-		// see the doc for more details.
-		const float TankHysteresis = 15.0f;
-
-		// how fast can the mouse move?
-		const float MaxMouseSpeed = 8.5f;
-
-		// and how fast can it turn?
-		const float MouseTurnSpeed = 0.20f;
-
-		// MouseEvadeDistance controls the distance at which the mouse will flee from
-		// cat. If the mouse is further than "MouseEvadeDistance" pixels away, he will
-		// consider himself safe.
-		const float MouseEvadeDistance = 200.0f;
-
-		// this constant is similar to TankHysteresis. The value is larger than the
-		// tank's hysteresis value because the mouse is faster than the tank: with a
-		// higher velocity, small fluctuations are much more visible.
-		const float MouseHysteresis = 60.0f;
-	#endregion
-
-	#region Fields
-
-		GraphicsDeviceManager graphics;
-		SpriteBatch spriteBatch;
-		SpriteFont spriteFont;
-		Texture2D tankTexture;
-		Vector2 tankTextureCenter;
-		Vector2 tankPosition;
-		TankAiState tankState = TankAiState.Wander;
-		float tankOrientation;
-		Vector2 tankWanderDirection;
-		Texture2D catTexture;
-		Vector2 catTextureCenter;
-		Vector2 catPosition;
-		Texture2D mouseTexture;
-		Vector2 mouseTextureCenter;
-		Vector2 mousePosition;
-		MouseAiState mouseState = MouseAiState.Wander;
-		float mouseOrientation;
-		Vector2 mouseWanderDirection;
-		Random random = new Random ();
-
-	#endregion
-
-	#region Initialization
-
-        public ChaseAndEvadeGame ()  
-        {
-
-			graphics = new GraphicsDeviceManager (this);
-			
-			Content.RootDirectory = "Content";
-
-#if WINDOWS_PHONE
-			graphics.SupportedOrientations = DisplayOrientation.Portrait;
-			graphics.PreferredBackBufferWidth = 480;
-			graphics.PreferredBackBufferHeight = 800;
-	
-			TargetElapsedTime = TimeSpan.FromTicks(333333);
-#elif !MONOMAC
-			
-			graphics.PreferredBackBufferWidth = 320;
-			graphics.PreferredBackBufferHeight = 480;
-#endif
-#if WINDOWS || MONOMAC || LINUX
-			graphics.IsFullScreen = false;
-#else
-			graphics.IsFullScreen = true;
-#endif
-		}
-
-		/// <summary>
-		/// Overridden from the base Game.Initialize. Once the GraphicsDevice is setup,
-		/// we'll use the viewport to initialize some values.
-		/// </summary>
-		protected override void Initialize ()
-		{
-			base.Initialize ();
-
-			// once base.Initialize has finished, the GraphicsDevice will have been
-			// created, and we'll know how big the Viewport is. We want the tank, cat
-			// and mouse to be spread out across the screen, so we'll use the viewport
-			// to figure out where they should be.
-			Viewport vp = graphics.GraphicsDevice.Viewport;
-
-			tankPosition = new Vector2 (vp.Width / 4, vp.Height / 2);
-			catPosition = new Vector2 (vp.Width / 2, vp.Height / 2);
-			mousePosition = new Vector2 (3 * vp.Width / 4, vp.Height / 2);
-
-		}
-
-
-		/// <summary>
-		/// Load your graphics content.
-		/// </summary>
-		protected override void LoadContent ()
-		{
-			// create a SpriteBatch, and load the textures and font that we'll need
-			// during the game.
-			spriteBatch = new SpriteBatch (graphics.GraphicsDevice);
-			spriteFont = Content.Load<SpriteFont> ("Arial");
-			tankTexture = Content.Load<Texture2D> ("tank");
-			catTexture = Content.Load<Texture2D> ("cat");
-			mouseTexture = Content.Load<Texture2D> ("mouse");
-
-			// once all the content is loaded, we can calculate the centers of each
-			// of the textures that we loaded. Just like in the previous sample in
-			// this series, the aiming sample, we want spriteBatch to draw the
-			// textures centered on their position vectors. SpriteBatch.Draw will
-			// center the sprite on the vector that we pass in as the "origin"
-			// parameter, so we'll just calculate that to be the middle of
-			// the texture.
-			tankTextureCenter = 
-				new Vector2 (tankTexture.Width / 2, tankTexture.Height / 2);
-			catTextureCenter = 
-				new Vector2 (catTexture.Width / 2, catTexture.Height / 2);
-			mouseTextureCenter = 
-				new Vector2 (mouseTexture.Width / 2, mouseTexture.Height / 2);
-		}
-
-	#endregion
-
-	#region Update and Draw
-
-		/// <summary>
-		/// Allows the game to run logic.
-		/// </summary>
-		protected override void Update (GameTime gameTime)
-		{
-			// handle input will read the controller input, and update the cat
-			// to move according to the user's whim.
-			HandleInput ();
-
-			// UpdateTank will run the AI code that controls the tank's movement...
-			UpdateTank ();
-
-			// ... and UpdateMouse does the same thing for the mouse.
-			UpdateMouse ();
-
-			// Once we've finished that, we'll use the ClampToViewport helper function
-			// to clamp everyone's position so that they stay on the screen.
-			tankPosition = ClampToViewport (tankPosition);
-			catPosition = ClampToViewport (catPosition);
-			mousePosition = ClampToViewport (mousePosition);
-
-			base.Update (gameTime);
-		}
-
-		/// <summary>
-		/// This function takes a Vector2 as input, and returns that vector "clamped"
-		/// to the current graphics viewport. We use this function to make sure that 
-		/// no one can go off of the screen.
-		/// </summary>
-		/// <param name="vector">an input vector</param>
-		/// <returns>the input vector, clamped between the minimum and maximum of the
-		/// viewport.</returns>
-		private Vector2 ClampToViewport (Vector2 vector)
-		{
-			Viewport vp = graphics.GraphicsDevice.Viewport;
-			vector.X = MathHelper.Clamp (vector.X, vp.X, vp.X + vp.Width);
-			vector.Y = MathHelper.Clamp (vector.Y, vp.Y, vp.Y + vp.Height);
-			return vector;
-		}
-
-		/// <summary>
-		/// This function contains the code that controls the mouse. It decides what the
-		/// mouse should do based on the position of the cat: if the cat is too close,
-		/// it will attempt to flee. Otherwise, it will idly wander around the screen.
-		/// 
-		/// </summary>
-		private void UpdateMouse ()
-		{
-			// first, calculate how far away the mouse is from the cat, and use that
-			// information to decide how to behave. If they are too close, the mouse
-			// will switch to "active" mode - fleeing. if they are far apart, the mouse
-			// will switch to "idle" mode, where it roams around the screen.
-			// we use a hysteresis constant in the decision making process, as described
-			// in the accompanying doc file.
-			float distanceFromCat = Vector2.Distance (mousePosition, catPosition);
-
-			// the cat is a safe distance away, so the mouse should idle:
-			if (distanceFromCat > MouseEvadeDistance + MouseHysteresis) {
-				mouseState = MouseAiState.Wander;
-			}
-			// the cat is too close; the mouse should run: 
-			else if (distanceFromCat < MouseEvadeDistance - MouseHysteresis) {
-				mouseState = MouseAiState.Evading;
-			}
-			// if neither of those if blocks hit, we are in the "hysteresis" range,
-			// and the mouse will continue doing whatever it is doing now.
-
-			// the mouse will move at a different speed depending on what state it
-			// is in. when idle it won't move at full speed, but when actively evading
-			// it will move as fast as it can. this variable is used to track which
-			// speed the mouse should be moving.
-			float currentMouseSpeed;
-
-			// the second step of the Update is to change the mouse's orientation based
-			// on its current state.
-			if (mouseState == MouseAiState.Evading) {
-				// If the mouse is "active," it is trying to evade the cat. The evasion
-				// behavior is accomplished by using the TurnToFace function to turn
-				// towards a point on a straight line facing away from the cat. In other
-				// words, if the cat is point A, and the mouse is point B, the "seek
-				// point" is C.
-				//     C
-				//   B
-				// A
-				Vector2 seekPosition = 2 * mousePosition - catPosition;
-
-				// Use the TurnToFace function, which we introduced in the AI Series 1:
-				// Aiming sample, to turn the mouse towards the seekPosition. Now when
-				// the mouse moves forward, it'll be trying to move in a straight line
-				// away from the cat.
-				mouseOrientation = TurnToFace (mousePosition, seekPosition, 
-					mouseOrientation, MouseTurnSpeed);
-
-				// set currentMouseSpeed to MaxMouseSpeed - the mouse should run as fast
-				// as it can.
-				currentMouseSpeed = MaxMouseSpeed;
-			} else {
-				// if the mouse isn't trying to evade the cat, it should just meander
-				// around the screen. we'll use the Wander function, which the mouse and
-				// tank share, to accomplish this. mouseWanderDirection and
-				// mouseOrientation are passed by ref so that the wander function can
-				// modify them. for more information on ref parameters, see
-				// http://msdn2.microsoft.com/en-us/library/14akc2c7(VS.80).aspx
-				Wander (mousePosition, ref mouseWanderDirection, ref mouseOrientation, 
-					MouseTurnSpeed);
-
-				// if the mouse is wandering, it should only move at 25% of its maximum
-				// speed. 
-				currentMouseSpeed = .25f * MaxMouseSpeed;
-			}
-
-			// The final step is to move the mouse forward based on its current
-			// orientation. First, we construct a "heading" vector from the orientation
-			// angle. To do this, we'll use Cosine and Sine to tell us the x and y
-			// components of the heading vector. See the accompanying doc for more
-			// information.
-			Vector2 heading = new Vector2 (
-				(float)Math.Cos (mouseOrientation), (float)Math.Sin (mouseOrientation));
-
-			// by multiplying the heading and speed, we can get a velocity vector. the
-			// velocity vector is then added to the mouse's current position, moving him
-			// forward.
-			mousePosition += heading * currentMouseSpeed;
-		}
-
-		/// <summary>
-		/// UpdateTank runs the AI code that will update the tank's orientation and
-		/// position. It is very similar to UpdateMouse, but is slightly more
-		/// complicated: where mouse only has two states, idle and active, the Tank has
-		/// three.
-		/// </summary>
-		private void UpdateTank ()
-		{
-			// However, the tank's behavior is more complicated than the mouse's, and so
-			// the decision making process is a little different. 
-
-			// First we have to use the current state to decide what the thresholds are
-			// for changing state, as described in the doc.
-
-			float tankChaseThreshold = TankChaseDistance;
-			float tankCaughtThreshold = TankCaughtDistance;
-			// if the tank is idle, he prefers to stay idle. we do this by making the
-			// chase distance smaller, so the tank will be less likely to begin chasing
-			// the cat.
-			if (tankState == TankAiState.Wander) {
-				tankChaseThreshold -= TankHysteresis / 2;
-			}
-			// similarly, if the tank is active, he prefers to stay active. we
-			// accomplish this by increasing the range of values that will cause the
-			// tank to go into the active state. 
-			else if (tankState == TankAiState.Chasing) {
-				tankChaseThreshold += TankHysteresis / 2;
-				tankCaughtThreshold -= TankHysteresis / 2;
-			}
-			// the same logic is applied to the finished state. 
-			else if (tankState == TankAiState.Caught) {
-				tankCaughtThreshold += TankHysteresis / 2;
-			}
-
-			// Second, now that we know what the thresholds are, we compare the tank's 
-			// distance from the cat against the thresholds to decide what the tank's
-			// current state is.
-			float distanceFromCat = Vector2.Distance (tankPosition, catPosition);
-			if (distanceFromCat > tankChaseThreshold) {
-				// just like the mouse, if the tank is far away from the cat, it should
-				// idle.
-				tankState = TankAiState.Wander;
-			} else if (distanceFromCat > tankCaughtThreshold) {
-				tankState = TankAiState.Chasing;
-			} else {
-				tankState = TankAiState.Caught;
-			}
-
-			// Third, once we know what state we're in, act on that state.
-			float currentTankSpeed;
-			if (tankState == TankAiState.Chasing) {
-				// the tank wants to chase the cat, so it will just use the TurnToFace
-				// function to turn towards the cat's position. Then, when the tank
-				// moves forward, he will chase the cat.
-				tankOrientation = TurnToFace (tankPosition, catPosition, tankOrientation, 
-					TankTurnSpeed);
-				currentTankSpeed = MaxTankSpeed;
-			} else if (tankState == TankAiState.Wander) {
-				// wander works just like the mouse's.
-				Wander (tankPosition, ref tankWanderDirection, ref tankOrientation, 
-					TankTurnSpeed);
-				currentTankSpeed = .25f * MaxTankSpeed;
-			} else {
-				// this part is different from the mouse. if the tank catches the cat, 
-				// it should stop. otherwise it will run right by, then spin around and
-				// try to catch it all over again. The end result is that it will kind
-				// of "run laps" around the cat, which looks funny, but is not what
-				// we're after.
-				currentTankSpeed = 0.0f;
-			}
-
-			// this calculation is also just like the mouse's: we construct a heading
-			// vector based on the tank's orientation, and then make the tank move along
-			// that heading.
-			Vector2 heading = new Vector2 (
-				(float)Math.Cos (tankOrientation), (float)Math.Sin (tankOrientation));
-			tankPosition += heading * currentTankSpeed;
-		}
-
-		/// <summary>
-		/// Wander contains functionality that is shared between both the mouse and the
-		/// tank, and does just what its name implies: makes them wander around the
-		/// screen. The specifics of the function are described in more detail in the
-		/// accompanying doc.
-		/// </summary>
-		/// <param name="position">the position of the character that is wandering
-		/// </param>
-		/// <param name="wanderDirection">the direction that the character is currently
-		/// wandering. this parameter is passed by reference because it is an input and
-		/// output parameter: Wander accepts it as input, and will update it as well.
-		/// </param>
-		/// <param name="orientation">the character's orientation. this parameter is
-		/// also passed by reference and is an input/output parameter.</param>
-		/// <param name="turnSpeed">the character's maximum turning speed.</param>
-		private void Wander (Vector2 position, ref Vector2 wanderDirection, 
-		ref float orientation, float turnSpeed)
-		{
-			// The wander effect is accomplished by having the character aim in a random
-			// direction. Every frame, this random direction is slightly modified.
-			// Finally, to keep the characters on the center of the screen, we have them
-			// turn to face the screen center. The further they are from the screen
-			// center, the more they will aim back towards it.
-
-			// the first step of the wander behavior is to use the random number
-			// generator to offset the current wanderDirection by some random amount.
-			// .25 is a bit of a magic number, but it controls how erratic the wander
-			// behavior is. Larger numbers will make the characters "wobble" more,
-			// smaller numbers will make them more stable. we want just enough
-			// wobbliness to be interesting without looking odd.
-			wanderDirection.X += 
-				MathHelper.Lerp (-.25f, .25f, (float)random.NextDouble ());
-			wanderDirection.Y += 
-				MathHelper.Lerp (-.25f, .25f, (float)random.NextDouble ());
-
-			// we'll renormalize the wander direction, ...
-			if (wanderDirection != Vector2.Zero) {
-				wanderDirection.Normalize ();
-			}
-			// ... and then turn to face in the wander direction. We don't turn at the
-			// maximum turning speed, but at 15% of it. Again, this is a bit of a magic
-			// number: it works well for this sample, but feel free to tweak it.
-			orientation = TurnToFace (position, position + wanderDirection, orientation, 
-						.15f * turnSpeed);
-
-
-			// next, we'll turn the characters back towards the center of the screen, to
-			// prevent them from getting stuck on the edges of the screen.
-			Vector2 screenCenter = Vector2.Zero;
-			screenCenter.X = graphics.GraphicsDevice.Viewport.Width / 2;
-			screenCenter.Y = graphics.GraphicsDevice.Viewport.Height / 2;
-
-			// Here we are creating a curve that we can apply to the turnSpeed. This
-			// curve will make it so that if we are close to the center of the screen,
-			// we won't turn very much. However, the further we are from the screen
-			// center, the more we turn. At most, we will turn at 30% of our maximum
-			// turn speed. This too is a "magic number" which works well for the sample.
-			// Feel free to play around with this one as well: smaller values will make
-			// the characters explore further away from the center, but they may get
-			// stuck on the walls. Larger numbers will hold the characters to center of
-			// the screen. If the number is too large, the characters may end up
-			// "orbiting" the center.
-			float distanceFromScreenCenter = Vector2.Distance (screenCenter, position);
-			float MaxDistanceFromScreenCenter = 
-		Math.Min (screenCenter.Y, screenCenter.X);
-
-			float normalizedDistance = 
-		distanceFromScreenCenter / MaxDistanceFromScreenCenter;
-
-			float turnToCenterSpeed = .3f * normalizedDistance * normalizedDistance * 
-		turnSpeed;
-
-			// once we've calculated how much we want to turn towards the center, we can
-			// use the TurnToFace function to actually do the work.
-			orientation = TurnToFace (position, screenCenter, orientation, 
-		turnToCenterSpeed);
-		}
-
-
-		/// <summary>
-		/// Calculates the angle that an object should face, given its position, its
-		/// target's position, its current angle, and its maximum turning speed.
-		/// </summary>
-		private static float TurnToFace (Vector2 position, Vector2 faceThis,
-		float currentAngle, float turnSpeed)
-		{
-			// consider this diagram:
-			//         B 
-			//        /|
-			//      /  |
-			//    /    | y
-			//  / o    |
-			// A--------
-			//     x
-			// 
-			// where A is the position of the object, B is the position of the target,
-			// and "o" is the angle that the object should be facing in order to 
-			// point at the target. we need to know what o is. using trig, we know that
-			//      tan(theta)       = opposite / adjacent
-			//      tan(o)           = y / x
-			// if we take the arctan of both sides of this equation...
-			//      arctan( tan(o) ) = arctan( y / x )
-			//      o                = arctan( y / x )
-			// so, we can use x and y to find o, our "desiredAngle."
-			// x and y are just the differences in position between the two objects.
-			float x = faceThis.X - position.X;
-			float y = faceThis.Y - position.Y;
-
-			// we'll use the Atan2 function. Atan will calculates the arc tangent of 
-			// y / x for us, and has the added benefit that it will use the signs of x
-			// and y to determine what cartesian quadrant to put the result in.
-			// http://msdn2.microsoft.com/en-us/library/system.math.atan2.aspx
-			float desiredAngle = (float)Math.Atan2 (y, x);
-
-			// so now we know where we WANT to be facing, and where we ARE facing...
-			// if we weren't constrained by turnSpeed, this would be easy: we'd just 
-			// return desiredAngle.
-			// instead, we have to calculate how much we WANT to turn, and then make
-			// sure that's not more than turnSpeed.
-
-			// first, figure out how much we want to turn, using WrapAngle to get our
-			// result from -Pi to Pi ( -180 degrees to 180 degrees )
-			float difference = WrapAngle (desiredAngle - currentAngle);
-
-			// clamp that between -turnSpeed and turnSpeed.
-			difference = MathHelper.Clamp (difference, -turnSpeed, turnSpeed);
-
-			// so, the closest we can get to our target is currentAngle + difference.
-			// return that, using WrapAngle again.
-			return WrapAngle (currentAngle + difference);
-		}
-
-		/// <summary>
-		/// Returns the angle expressed in radians between -Pi and Pi.
-		/// <param name="radians">the angle to wrap, in radians.</param>
-		/// <returns>the input value expressed in radians from -Pi to Pi.</returns>
-		/// </summary>
-		private static float WrapAngle (float radians)
-		{
-			while (radians < -MathHelper.Pi) {
-				radians += MathHelper.TwoPi;
-			}
-			while (radians > MathHelper.Pi) {
-				radians -= MathHelper.TwoPi;
-			}
-			return radians;
-		}
-
-		/// <summary>
-		/// This is called when the game should draw itself. Nothing too fancy in here,
-		/// we'll just call Begin on the SpriteBatch, and then draw the tank, cat, and 
-		/// mouse, and some overlay text. Once we're finished drawing, we'll call
-		/// SpriteBatch.End.
-		/// </summary>
-		protected override void Draw (GameTime gameTime)
-		{
-			GraphicsDevice device = graphics.GraphicsDevice;
-
-			device.Clear (Color.CornflowerBlue);
-
-			spriteBatch.Begin ();
-
-			// draw the tank, cat and mouse...
-			spriteBatch.Draw (tankTexture, tankPosition, null, Color.White, 
-		tankOrientation, tankTextureCenter, 1.0f, SpriteEffects.None, 0.0f);
-			spriteBatch.Draw (catTexture, catPosition, null, Color.White, 
-		0.0f, catTextureCenter, 1.0f, SpriteEffects.None, 0.0f);
-			spriteBatch.Draw (mouseTexture, mousePosition, null, Color.White, 
-		mouseOrientation, mouseTextureCenter, 1.0f, SpriteEffects.None, 0.0f);
-
-			// and then draw some text showing the tank's and mouse's current state.
-			// to make the text stand out more, we'll draw the text twice, once black
-			// and once white, to create a drop shadow effect.
-			Vector2 shadowOffset = Vector2.One;
-
-			spriteBatch.DrawString (spriteFont, "Tank State: \n" + tankState.ToString (), 
-		new Vector2 (10, 10) + shadowOffset, Color.Black);
-			spriteBatch.DrawString (spriteFont, "Tank State: \n" + tankState.ToString (), 
-		new Vector2 (10, 10), Color.White);
-
-			spriteBatch.DrawString (spriteFont, "Mouse State: \n" + mouseState.ToString (), 
-		new Vector2 (10, 90) + shadowOffset, Color.Black);
-			spriteBatch.DrawString (spriteFont, "Mouse State: \n" + mouseState.ToString (), 
-		new Vector2 (10, 90), Color.White);
-
-			spriteBatch.End ();
-
-			base.Draw (gameTime);
-		}
-
-	#endregion
-
-	#region Handle Input
-
-		/// <summary>
-		/// Handles input for quitting the game.
-		/// </summary>
-		void HandleInput ()
-		{
-#if WINDOWS_PHONE
-			KeyboardState currentKeyboardState = new KeyboardState();
-#else
-			KeyboardState currentKeyboardState = Keyboard.GetState ();
-			MouseState currentMouseState = Mouse.GetState ();
-#endif
-			
-#if IPHONE || PSM
-			GamePadState currentGamePadState = GamePad.GetState (PlayerIndex.One);
-
-			// Check for exit.
-			if (currentKeyboardState.IsKeyDown (Keys.Escape) || 
-				currentGamePadState.Buttons.Back == ButtonState.Pressed) {
-				Exit ();
-			}
-#else
-			// Check for exit.
-			if (currentKeyboardState.IsKeyDown (Keys.Escape)) {
-				Exit ();
-			}
-			
-#endif			
-
-			// check to see if the user wants to move the cat. we'll create a vector
-			// called catMovement, which will store the sum of all the user's inputs.
-			Vector2 catMovement = Vector2.Zero;
-
-			//Move toward the touch point. We slow down the cat when it gets within a distance of MaxCatSpeed to the touch point.
-			float smoothStop = 1;			
-			
-#if IPHONE || PSM		
-			// check to see if the user wants to move the cat. we'll create a vector
-			// called catMovement, which will store the sum of all the user's inputs.
-			catMovement = currentGamePadState.ThumbSticks.Left;
-
-			// flip y: on the thumbsticks, down is -1, but on the screen, down is bigger
-			// numbers.
-			catMovement.Y *= -1;
-
-			if (currentKeyboardState.IsKeyDown (Keys.Left) || 
-				currentGamePadState.DPad.Left == ButtonState.Pressed) {
-				catMovement.X -= 1.0f;
-			}
-			if (currentKeyboardState.IsKeyDown (Keys.Right) || 
-				currentGamePadState.DPad.Right == ButtonState.Pressed) {
-				catMovement.X += 1.0f;
-			}
-			if (currentKeyboardState.IsKeyDown (Keys.Up) || 
-				currentGamePadState.DPad.Up == ButtonState.Pressed) {
-				catMovement.Y -= 1.0f;
-			}
-			if (currentKeyboardState.IsKeyDown (Keys.Down) || 
-				currentGamePadState.DPad.Down == ButtonState.Pressed) {
-				catMovement.Y += 1.0f;
-			}
-			
-			TouchCollection currentTouchCollection = TouchPanel.GetState();
-			
-			// TODO if (currentTouchCollection != null )
-            {
-				if (currentTouchCollection.Count > 0)
-	            {
-					Vector2 touchPosition = currentTouchCollection[0].Position;
-		            if (touchPosition != catPosition)
-		            {
-		                catMovement = touchPosition - catPosition;
-		                float delta = MaxCatSpeed - MathHelper.Clamp(catMovement.Length(), 0, MaxCatSpeed);
-		                smoothStop = 1 - delta / MaxCatSpeed;
-		            }
-				}
-			}		
-#else
-
-
-			if (currentKeyboardState.IsKeyDown (Keys.Left)) {
-				catMovement.X -= 1.0f;
-			}
-			if (currentKeyboardState.IsKeyDown (Keys.Right)) {
-				catMovement.X += 1.0f;
-			}
-			if (currentKeyboardState.IsKeyDown (Keys.Up)) {
-				catMovement.Y -= 1.0f;
-			}
-			if (currentKeyboardState.IsKeyDown (Keys.Down)) {
-				catMovement.Y += 1.0f;
-			}			
-
-			Vector2 mousePosition = new Vector2 (currentMouseState.X, currentMouseState.Y);
-			if (currentMouseState.LeftButton == ButtonState.Pressed && mousePosition != catPosition) {
-				catMovement = mousePosition - catPosition;
-				float delta = MaxCatSpeed - MathHelper.Clamp (catMovement.Length (), 0, MaxCatSpeed);
-				smoothStop = 1 - delta / MaxCatSpeed;
-			}
-#endif
-
-			// normalize the user's input, so the cat can never be going faster than
-			// CatSpeed.
-			if (catMovement != Vector2.Zero) {
-				catMovement.Normalize ();
-			}
-
-			catPosition += catMovement * MaxCatSpeed * smoothStop;
-		}
-
-	#endregion
-	}
-}
+//-----------------------------------------------------------------------------
+// Game.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using System;
+
+#if ANDROID
+using Android.App;
+#endif
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Input.Touch;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Media;
+
+
+namespace ChaseAndEvade
+{
+	/// <summary>
+	/// Sample showing how to implement simple chase, evade, and wander AI behaviors.
+	/// The behaviors are based on the TurnToFace function, which was explained in
+	/// AI Sample 1: Aiming.
+	/// </summary>
+	public class ChaseAndEvadeGame : Game
+	{
+
+		/// <summary>
+		/// TankAiState is used to keep track of what the tank is currently doing.
+		/// </summary>
+		enum TankAiState
+		{
+			// chasing the cat
+			Chasing,
+			// the tank has gotten close enough that the cat that it can stop chasing it
+			Caught,
+			// the tank can't "see" the cat, and is wandering around.
+			Wander
+		}
+
+		/// <summary>
+		/// MouseAiState is used to keep track of what the mouse is currently doing.
+		/// </summary>
+		enum MouseAiState
+		{
+			// evading the cat
+			Evading,
+			// the mouse can't see the "cat", and it's wandering around.
+			Wander
+		}
+
+
+
+
+		// The following values control the different characteristics of the characters
+		// in this sample, including their speed, turning rates. distances are specified
+		// in pixels, angles are specified in radians.
+
+		// how fast can the cat move?
+		const float MaxCatSpeed = 7.5f;
+
+		// how fast can the tank move?
+		const float MaxTankSpeed = 5.0f;
+
+		// how fast can he turn?
+		const float TankTurnSpeed = 0.10f;
+
+		// this value controls the distance at which the tank will start to chase the
+		// cat.
+		const float TankChaseDistance = 250.0f;
+
+		// TankCaughtDistance controls the distance at which the tank will stop because
+		// he has "caught" the cat.
+		const float TankCaughtDistance = 60.0f;
+
+		// this constant is used to avoid hysteresis, which is common in ai programming.
+		// see the doc for more details.
+		const float TankHysteresis = 15.0f;
+
+		// how fast can the mouse move?
+		const float MaxMouseSpeed = 8.5f;
+
+		// and how fast can it turn?
+		const float MouseTurnSpeed = 0.20f;
+
+		// MouseEvadeDistance controls the distance at which the mouse will flee from
+		// cat. If the mouse is further than "MouseEvadeDistance" pixels away, he will
+		// consider himself safe.
+		const float MouseEvadeDistance = 200.0f;
+
+		// this constant is similar to TankHysteresis. The value is larger than the
+		// tank's hysteresis value because the mouse is faster than the tank: with a
+		// higher velocity, small fluctuations are much more visible.
+		const float MouseHysteresis = 60.0f;
+
+
+		GraphicsDeviceManager graphics;
+		SpriteBatch spriteBatch;
+		SpriteFont spriteFont;
+		Texture2D tankTexture;
+		Vector2 tankTextureCenter;
+		Vector2 tankPosition;
+		TankAiState tankState = TankAiState.Wander;
+		float tankOrientation;
+		Vector2 tankWanderDirection;
+		Texture2D catTexture;
+		Vector2 catTextureCenter;
+		Vector2 catPosition;
+		Texture2D mouseTexture;
+		Vector2 mouseTextureCenter;
+		Vector2 mousePosition;
+		MouseAiState mouseState = MouseAiState.Wander;
+		float mouseOrientation;
+		Vector2 mouseWanderDirection;
+		Random random = new Random ();
+
+
+
+		public ChaseAndEvadeGame ()  
+		{
+
+			graphics = new GraphicsDeviceManager (this);
+			
+			Content.RootDirectory = "Content";
+
+#if MOBILE
+			graphics.IsFullScreen = true;
+			graphics.SupportedOrientations = DisplayOrientation.Portrait;
+			graphics.PreferredBackBufferWidth = 480;
+			graphics.PreferredBackBufferHeight = 800;
+#endif
+		}
+
+		/// <summary>
+		/// Overridden from the base Game.Initialize. Once the GraphicsDevice is setup,
+		/// we'll use the viewport to initialize some values.
+		/// </summary>
+		protected override void Initialize ()
+		{
+			base.Initialize ();
+
+			// once base.Initialize has finished, the GraphicsDevice will have been
+			// created, and we'll know how big the Viewport is. We want the tank, cat
+			// and mouse to be spread out across the screen, so we'll use the viewport
+			// to figure out where they should be.
+			Viewport vp = graphics.GraphicsDevice.Viewport;
+
+			tankPosition = new Vector2 (vp.Width / 4, vp.Height / 2);
+			catPosition = new Vector2 (vp.Width / 2, vp.Height / 2);
+			mousePosition = new Vector2 (3 * vp.Width / 4, vp.Height / 2);
+
+		}
+
+
+		/// <summary>
+		/// Load your graphics content.
+		/// </summary>
+		protected override void LoadContent ()
+		{
+			// create a SpriteBatch, and load the textures and font that we'll need
+			// during the game.
+			spriteBatch = new SpriteBatch (graphics.GraphicsDevice);
+			spriteFont = Content.Load<SpriteFont> ("Arial");
+			tankTexture = Content.Load<Texture2D> ("tank");
+			catTexture = Content.Load<Texture2D> ("cat");
+			mouseTexture = Content.Load<Texture2D> ("mouse");
+
+			// once all the content is loaded, we can calculate the centers of each
+			// of the textures that we loaded. Just like in the previous sample in
+			// this series, the aiming sample, we want spriteBatch to draw the
+			// textures centered on their position vectors. SpriteBatch.Draw will
+			// center the sprite on the vector that we pass in as the "origin"
+			// parameter, so we'll just calculate that to be the middle of
+			// the texture.
+			tankTextureCenter = 
+				new Vector2 (tankTexture.Width / 2, tankTexture.Height / 2);
+			catTextureCenter = 
+				new Vector2 (catTexture.Width / 2, catTexture.Height / 2);
+			mouseTextureCenter = 
+				new Vector2 (mouseTexture.Width / 2, mouseTexture.Height / 2);
+		}
+
+
+
+		/// <summary>
+		/// Allows the game to run logic.
+		/// </summary>
+		protected override void Update (GameTime gameTime)
+		{
+			// handle input will read the controller input, and update the cat
+			// to move according to the user's whim.
+			HandleInput ();
+
+			// UpdateTank will run the AI code that controls the tank's movement...
+			UpdateTank ();
+
+			// ... and UpdateMouse does the same thing for the mouse.
+			UpdateMouse ();
+
+			// Once we've finished that, we'll use the ClampToViewport helper function
+			// to clamp everyone's position so that they stay on the screen.
+			tankPosition = ClampToViewport (tankPosition);
+			catPosition = ClampToViewport (catPosition);
+			mousePosition = ClampToViewport (mousePosition);
+
+			base.Update (gameTime);
+		}
+
+		/// <summary>
+		/// This function takes a Vector2 as input, and returns that vector "clamped"
+		/// to the current graphics viewport. We use this function to make sure that 
+		/// no one can go off of the screen.
+		/// </summary>
+		/// <param name="vector">an input vector</param>
+		/// <returns>the input vector, clamped between the minimum and maximum of the
+		/// viewport.</returns>
+		private Vector2 ClampToViewport (Vector2 vector)
+		{
+			Viewport vp = graphics.GraphicsDevice.Viewport;
+			vector.X = MathHelper.Clamp (vector.X, vp.X, vp.X + vp.Width);
+			vector.Y = MathHelper.Clamp (vector.Y, vp.Y, vp.Y + vp.Height);
+			return vector;
+		}
+
+		/// <summary>
+		/// This function contains the code that controls the mouse. It decides what the
+		/// mouse should do based on the position of the cat: if the cat is too close,
+		/// it will attempt to flee. Otherwise, it will idly wander around the screen.
+		/// 
+		/// </summary>
+		private void UpdateMouse ()
+		{
+			// first, calculate how far away the mouse is from the cat, and use that
+			// information to decide how to behave. If they are too close, the mouse
+			// will switch to "active" mode - fleeing. if they are far apart, the mouse
+			// will switch to "idle" mode, where it roams around the screen.
+			// we use a hysteresis constant in the decision making process, as described
+			// in the accompanying doc file.
+			float distanceFromCat = Vector2.Distance (mousePosition, catPosition);
+
+			// the cat is a safe distance away, so the mouse should idle:
+			if (distanceFromCat > MouseEvadeDistance + MouseHysteresis) {
+				mouseState = MouseAiState.Wander;
+			}
+			// the cat is too close; the mouse should run: 
+			else if (distanceFromCat < MouseEvadeDistance - MouseHysteresis) {
+				mouseState = MouseAiState.Evading;
+			}
+			// if neither of those if blocks hit, we are in the "hysteresis" range,
+			// and the mouse will continue doing whatever it is doing now.
+
+			// the mouse will move at a different speed depending on what state it
+			// is in. when idle it won't move at full speed, but when actively evading
+			// it will move as fast as it can. this variable is used to track which
+			// speed the mouse should be moving.
+			float currentMouseSpeed;
+
+			// the second step of the Update is to change the mouse's orientation based
+			// on its current state.
+			if (mouseState == MouseAiState.Evading) {
+				// If the mouse is "active," it is trying to evade the cat. The evasion
+				// behavior is accomplished by using the TurnToFace function to turn
+				// towards a point on a straight line facing away from the cat. In other
+				// words, if the cat is point A, and the mouse is point B, the "seek
+				// point" is C.
+				//     C
+				//   B
+				// A
+				Vector2 seekPosition = 2 * mousePosition - catPosition;
+
+				// Use the TurnToFace function, which we introduced in the AI Series 1:
+				// Aiming sample, to turn the mouse towards the seekPosition. Now when
+				// the mouse moves forward, it'll be trying to move in a straight line
+				// away from the cat.
+				mouseOrientation = TurnToFace (mousePosition, seekPosition, 
+					mouseOrientation, MouseTurnSpeed);
+
+				// set currentMouseSpeed to MaxMouseSpeed - the mouse should run as fast
+				// as it can.
+				currentMouseSpeed = MaxMouseSpeed;
+			} else {
+				// if the mouse isn't trying to evade the cat, it should just meander
+				// around the screen. we'll use the Wander function, which the mouse and
+				// tank share, to accomplish this. mouseWanderDirection and
+				// mouseOrientation are passed by ref so that the wander function can
+				// modify them. for more information on ref parameters, see
+				// http://msdn2.microsoft.com/en-us/library/14akc2c7(VS.80).aspx
+				Wander (mousePosition, ref mouseWanderDirection, ref mouseOrientation, 
+					MouseTurnSpeed);
+
+				// if the mouse is wandering, it should only move at 25% of its maximum
+				// speed. 
+				currentMouseSpeed = .25f * MaxMouseSpeed;
+			}
+
+			// The final step is to move the mouse forward based on its current
+			// orientation. First, we construct a "heading" vector from the orientation
+			// angle. To do this, we'll use Cosine and Sine to tell us the x and y
+			// components of the heading vector. See the accompanying doc for more
+			// information.
+			Vector2 heading = new Vector2 (
+				(float)Math.Cos (mouseOrientation), (float)Math.Sin (mouseOrientation));
+
+			// by multiplying the heading and speed, we can get a velocity vector. the
+			// velocity vector is then added to the mouse's current position, moving him
+			// forward.
+			mousePosition += heading * currentMouseSpeed;
+		}
+
+		/// <summary>
+		/// UpdateTank runs the AI code that will update the tank's orientation and
+		/// position. It is very similar to UpdateMouse, but is slightly more
+		/// complicated: where mouse only has two states, idle and active, the Tank has
+		/// three.
+		/// </summary>
+		private void UpdateTank ()
+		{
+			// However, the tank's behavior is more complicated than the mouse's, and so
+			// the decision making process is a little different. 
+
+			// First we have to use the current state to decide what the thresholds are
+			// for changing state, as described in the doc.
+
+			float tankChaseThreshold = TankChaseDistance;
+			float tankCaughtThreshold = TankCaughtDistance;
+			// if the tank is idle, he prefers to stay idle. we do this by making the
+			// chase distance smaller, so the tank will be less likely to begin chasing
+			// the cat.
+			if (tankState == TankAiState.Wander) {
+				tankChaseThreshold -= TankHysteresis / 2;
+			}
+			// similarly, if the tank is active, he prefers to stay active. we
+			// accomplish this by increasing the range of values that will cause the
+			// tank to go into the active state. 
+			else if (tankState == TankAiState.Chasing) {
+				tankChaseThreshold += TankHysteresis / 2;
+				tankCaughtThreshold -= TankHysteresis / 2;
+			}
+			// the same logic is applied to the finished state. 
+			else if (tankState == TankAiState.Caught) {
+				tankCaughtThreshold += TankHysteresis / 2;
+			}
+
+			// Second, now that we know what the thresholds are, we compare the tank's 
+			// distance from the cat against the thresholds to decide what the tank's
+			// current state is.
+			float distanceFromCat = Vector2.Distance (tankPosition, catPosition);
+			if (distanceFromCat > tankChaseThreshold) {
+				// just like the mouse, if the tank is far away from the cat, it should
+				// idle.
+				tankState = TankAiState.Wander;
+			} else if (distanceFromCat > tankCaughtThreshold) {
+				tankState = TankAiState.Chasing;
+			} else {
+				tankState = TankAiState.Caught;
+			}
+
+			// Third, once we know what state we're in, act on that state.
+			float currentTankSpeed;
+			if (tankState == TankAiState.Chasing) {
+				// the tank wants to chase the cat, so it will just use the TurnToFace
+				// function to turn towards the cat's position. Then, when the tank
+				// moves forward, he will chase the cat.
+				tankOrientation = TurnToFace (tankPosition, catPosition, tankOrientation, 
+					TankTurnSpeed);
+				currentTankSpeed = MaxTankSpeed;
+			} else if (tankState == TankAiState.Wander) {
+				// wander works just like the mouse's.
+				Wander (tankPosition, ref tankWanderDirection, ref tankOrientation, 
+					TankTurnSpeed);
+				currentTankSpeed = .25f * MaxTankSpeed;
+			} else {
+				// this part is different from the mouse. if the tank catches the cat, 
+				// it should stop. otherwise it will run right by, then spin around and
+				// try to catch it all over again. The end result is that it will kind
+				// of "run laps" around the cat, which looks funny, but is not what
+				// we're after.
+				currentTankSpeed = 0.0f;
+			}
+
+			// this calculation is also just like the mouse's: we construct a heading
+			// vector based on the tank's orientation, and then make the tank move along
+			// that heading.
+			Vector2 heading = new Vector2 (
+				(float)Math.Cos (tankOrientation), (float)Math.Sin (tankOrientation));
+			tankPosition += heading * currentTankSpeed;
+		}
+
+		/// <summary>
+		/// Wander contains functionality that is shared between both the mouse and the
+		/// tank, and does just what its name implies: makes them wander around the
+		/// screen. The specifics of the function are described in more detail in the
+		/// accompanying doc.
+		/// </summary>
+		/// <param name="position">the position of the character that is wandering
+		/// </param>
+		/// <param name="wanderDirection">the direction that the character is currently
+		/// wandering. this parameter is passed by reference because it is an input and
+		/// output parameter: Wander accepts it as input, and will update it as well.
+		/// </param>
+		/// <param name="orientation">the character's orientation. this parameter is
+		/// also passed by reference and is an input/output parameter.</param>
+		/// <param name="turnSpeed">the character's maximum turning speed.</param>
+		private void Wander (Vector2 position, ref Vector2 wanderDirection, 
+		ref float orientation, float turnSpeed)
+		{
+			// The wander effect is accomplished by having the character aim in a random
+			// direction. Every frame, this random direction is slightly modified.
+			// Finally, to keep the characters on the center of the screen, we have them
+			// turn to face the screen center. The further they are from the screen
+			// center, the more they will aim back towards it.
+
+			// the first step of the wander behavior is to use the random number
+			// generator to offset the current wanderDirection by some random amount.
+			// .25 is a bit of a magic number, but it controls how erratic the wander
+			// behavior is. Larger numbers will make the characters "wobble" more,
+			// smaller numbers will make them more stable. we want just enough
+			// wobbliness to be interesting without looking odd.
+			wanderDirection.X += 
+				MathHelper.Lerp (-.25f, .25f, (float)random.NextDouble ());
+			wanderDirection.Y += 
+				MathHelper.Lerp (-.25f, .25f, (float)random.NextDouble ());
+
+			// we'll renormalize the wander direction, ...
+			if (wanderDirection != Vector2.Zero) {
+				wanderDirection.Normalize ();
+			}
+			// ... and then turn to face in the wander direction. We don't turn at the
+			// maximum turning speed, but at 15% of it. Again, this is a bit of a magic
+			// number: it works well for this sample, but feel free to tweak it.
+			orientation = TurnToFace (position, position + wanderDirection, orientation, 
+						.15f * turnSpeed);
+
+
+			// next, we'll turn the characters back towards the center of the screen, to
+			// prevent them from getting stuck on the edges of the screen.
+			Vector2 screenCenter = Vector2.Zero;
+			screenCenter.X = graphics.GraphicsDevice.Viewport.Width / 2;
+			screenCenter.Y = graphics.GraphicsDevice.Viewport.Height / 2;
+
+			// Here we are creating a curve that we can apply to the turnSpeed. This
+			// curve will make it so that if we are close to the center of the screen,
+			// we won't turn very much. However, the further we are from the screen
+			// center, the more we turn. At most, we will turn at 30% of our maximum
+			// turn speed. This too is a "magic number" which works well for the sample.
+			// Feel free to play around with this one as well: smaller values will make
+			// the characters explore further away from the center, but they may get
+			// stuck on the walls. Larger numbers will hold the characters to center of
+			// the screen. If the number is too large, the characters may end up
+			// "orbiting" the center.
+			float distanceFromScreenCenter = Vector2.Distance (screenCenter, position);
+			float MaxDistanceFromScreenCenter = 
+		Math.Min (screenCenter.Y, screenCenter.X);
+
+			float normalizedDistance = 
+		distanceFromScreenCenter / MaxDistanceFromScreenCenter;
+
+			float turnToCenterSpeed = .3f * normalizedDistance * normalizedDistance * 
+		turnSpeed;
+
+			// once we've calculated how much we want to turn towards the center, we can
+			// use the TurnToFace function to actually do the work.
+			orientation = TurnToFace (position, screenCenter, orientation, 
+		turnToCenterSpeed);
+		}
+
+
+		/// <summary>
+		/// Calculates the angle that an object should face, given its position, its
+		/// target's position, its current angle, and its maximum turning speed.
+		/// </summary>
+		private static float TurnToFace (Vector2 position, Vector2 faceThis,
+		float currentAngle, float turnSpeed)
+		{
+			// consider this diagram:
+			//         B 
+			//        /|
+			//      /  |
+			//    /    | y
+			//  / o    |
+			// A--------
+			//     x
+			// 
+			// where A is the position of the object, B is the position of the target,
+			// and "o" is the angle that the object should be facing in order to 
+			// point at the target. we need to know what o is. using trig, we know that
+			//      tan(theta)       = opposite / adjacent
+			//      tan(o)           = y / x
+			// if we take the arctan of both sides of this equation...
+			//      arctan( tan(o) ) = arctan( y / x )
+			//      o                = arctan( y / x )
+			// so, we can use x and y to find o, our "desiredAngle."
+			// x and y are just the differences in position between the two objects.
+			float x = faceThis.X - position.X;
+			float y = faceThis.Y - position.Y;
+
+			// we'll use the Atan2 function. Atan will calculates the arc tangent of 
+			// y / x for us, and has the added benefit that it will use the signs of x
+			// and y to determine what cartesian quadrant to put the result in.
+			// http://msdn2.microsoft.com/en-us/library/system.math.atan2.aspx
+			float desiredAngle = (float)Math.Atan2 (y, x);
+
+			// so now we know where we WANT to be facing, and where we ARE facing...
+			// if we weren't constrained by turnSpeed, this would be easy: we'd just 
+			// return desiredAngle.
+			// instead, we have to calculate how much we WANT to turn, and then make
+			// sure that's not more than turnSpeed.
+
+			// first, figure out how much we want to turn, using WrapAngle to get our
+			// result from -Pi to Pi ( -180 degrees to 180 degrees )
+			float difference = WrapAngle (desiredAngle - currentAngle);
+
+			// clamp that between -turnSpeed and turnSpeed.
+			difference = MathHelper.Clamp (difference, -turnSpeed, turnSpeed);
+
+			// so, the closest we can get to our target is currentAngle + difference.
+			// return that, using WrapAngle again.
+			return WrapAngle (currentAngle + difference);
+		}
+
+		/// <summary>
+		/// Returns the angle expressed in radians between -Pi and Pi.
+		/// <param name="radians">the angle to wrap, in radians.</param>
+		/// <returns>the input value expressed in radians from -Pi to Pi.</returns>
+		/// </summary>
+		private static float WrapAngle (float radians)
+		{
+			while (radians < -MathHelper.Pi) {
+				radians += MathHelper.TwoPi;
+			}
+			while (radians > MathHelper.Pi) {
+				radians -= MathHelper.TwoPi;
+			}
+			return radians;
+		}
+
+		/// <summary>
+		/// This is called when the game should draw itself. Nothing too fancy in here,
+		/// we'll just call Begin on the SpriteBatch, and then draw the tank, cat, and 
+		/// mouse, and some overlay text. Once we're finished drawing, we'll call
+		/// SpriteBatch.End.
+		/// </summary>
+		protected override void Draw (GameTime gameTime)
+		{
+			GraphicsDevice device = graphics.GraphicsDevice;
+
+			device.Clear (Color.CornflowerBlue);
+
+			spriteBatch.Begin ();
+
+			// draw the tank, cat and mouse...
+			spriteBatch.Draw (tankTexture, tankPosition, null, Color.White, 
+		tankOrientation, tankTextureCenter, 1.0f, SpriteEffects.None, 0.0f);
+			spriteBatch.Draw (catTexture, catPosition, null, Color.White, 
+		0.0f, catTextureCenter, 1.0f, SpriteEffects.None, 0.0f);
+			spriteBatch.Draw (mouseTexture, mousePosition, null, Color.White, 
+		mouseOrientation, mouseTextureCenter, 1.0f, SpriteEffects.None, 0.0f);
+
+			// and then draw some text showing the tank's and mouse's current state.
+			// to make the text stand out more, we'll draw the text twice, once black
+			// and once white, to create a drop shadow effect.
+			Vector2 shadowOffset = Vector2.One;
+
+			spriteBatch.DrawString (spriteFont, "Tank State: \n" + tankState.ToString (), 
+		new Vector2 (10, 10) + shadowOffset, Color.Black);
+			spriteBatch.DrawString (spriteFont, "Tank State: \n" + tankState.ToString (), 
+		new Vector2 (10, 10), Color.White);
+
+			spriteBatch.DrawString (spriteFont, "Mouse State: \n" + mouseState.ToString (), 
+		new Vector2 (10, 90) + shadowOffset, Color.Black);
+			spriteBatch.DrawString (spriteFont, "Mouse State: \n" + mouseState.ToString (), 
+		new Vector2 (10, 90), Color.White);
+
+			spriteBatch.End ();
+
+			base.Draw (gameTime);
+		}
+
+
+
+		/// <summary>
+		/// Handles input for quitting the game.
+		/// </summary>
+		void HandleInput ()
+		{
+#if WINDOWS_PHONE
+			KeyboardState currentKeyboardState = new KeyboardState();
+#else
+			KeyboardState currentKeyboardState = Keyboard.GetState ();
+			MouseState currentMouseState = Mouse.GetState ();
+#endif
+			
+#if IPHONE || PSM
+			GamePadState currentGamePadState = GamePad.GetState (PlayerIndex.One);
+
+			// Check for exit.
+			if (currentKeyboardState.IsKeyDown (Keys.Escape) || 
+				currentGamePadState.Buttons.Back == ButtonState.Pressed) {
+				Exit ();
+			}
+#else
+			// Check for exit.
+			if (currentKeyboardState.IsKeyDown (Keys.Escape)) {
+				Exit ();
+			}
+			
+#endif			
+
+			// check to see if the user wants to move the cat. we'll create a vector
+			// called catMovement, which will store the sum of all the user's inputs.
+			Vector2 catMovement = Vector2.Zero;
+
+			//Move toward the touch point. We slow down the cat when it gets within a distance of MaxCatSpeed to the touch point.
+			float smoothStop = 1;			
+			
+#if IPHONE || PSM		
+			// check to see if the user wants to move the cat. we'll create a vector
+			// called catMovement, which will store the sum of all the user's inputs.
+			catMovement = currentGamePadState.ThumbSticks.Left;
+
+			// flip y: on the thumbsticks, down is -1, but on the screen, down is bigger
+			// numbers.
+			catMovement.Y *= -1;
+
+			if (currentKeyboardState.IsKeyDown (Keys.Left) || 
+				currentGamePadState.DPad.Left == ButtonState.Pressed) {
+				catMovement.X -= 1.0f;
+			}
+			if (currentKeyboardState.IsKeyDown (Keys.Right) || 
+				currentGamePadState.DPad.Right == ButtonState.Pressed) {
+				catMovement.X += 1.0f;
+			}
+			if (currentKeyboardState.IsKeyDown (Keys.Up) || 
+				currentGamePadState.DPad.Up == ButtonState.Pressed) {
+				catMovement.Y -= 1.0f;
+			}
+			if (currentKeyboardState.IsKeyDown (Keys.Down) || 
+				currentGamePadState.DPad.Down == ButtonState.Pressed) {
+				catMovement.Y += 1.0f;
+			}
+			
+			TouchCollection currentTouchCollection = TouchPanel.GetState();
+			
+			// TODO if (currentTouchCollection != null )
+			{
+				if (currentTouchCollection.Count > 0)
+				{
+					Vector2 touchPosition = currentTouchCollection[0].Position;
+					if (touchPosition != catPosition)
+					{
+						catMovement = touchPosition - catPosition;
+						float delta = MaxCatSpeed - MathHelper.Clamp(catMovement.Length(), 0, MaxCatSpeed);
+						smoothStop = 1 - delta / MaxCatSpeed;
+					}
+				}
+			}		
+#else
+
+
+			if (currentKeyboardState.IsKeyDown (Keys.Left)) {
+				catMovement.X -= 1.0f;
+			}
+			if (currentKeyboardState.IsKeyDown (Keys.Right)) {
+				catMovement.X += 1.0f;
+			}
+			if (currentKeyboardState.IsKeyDown (Keys.Up)) {
+				catMovement.Y -= 1.0f;
+			}
+			if (currentKeyboardState.IsKeyDown (Keys.Down)) {
+				catMovement.Y += 1.0f;
+			}			
+
+			Vector2 mousePosition = new Vector2 (currentMouseState.X, currentMouseState.Y);
+			if (currentMouseState.LeftButton == ButtonState.Pressed && mousePosition != catPosition) {
+				catMovement = mousePosition - catPosition;
+				float delta = MaxCatSpeed - MathHelper.Clamp (catMovement.Length (), 0, MaxCatSpeed);
+				smoothStop = 1 - delta / MaxCatSpeed;
+			}
+#endif
+
+			// normalize the user's input, so the cat can never be going faster than
+			// CatSpeed.
+			if (catMovement != Vector2.Zero) {
+				catMovement.Normalize ();
+			}
+
+			catPosition += catMovement * MaxCatSpeed * smoothStop;
+		}
+
+	}
+}

+ 0 - 0
ChaseAndEvade/Default.png → ChaseAndEvade/Core/Content/Default.png


+ 0 - 0
ChaseAndEvade/GameThumbnail.png → ChaseAndEvade/Core/Content/GameThumbnail.png


+ 34 - 0
ChaseAndEvade/Core/Content/app.manifest

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+  <assemblyIdentity version="1.0.0.0" name="ChaseAndEvade"/>
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+    <security>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+
+  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+    <application>
+      <!-- Windows Vista -->
+      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
+      <!-- Windows 7 -->
+      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
+      <!-- Windows 8 -->
+      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
+      <!-- Windows 8.1 -->
+      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
+      <!-- Windows 10 -->
+      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
+    </application>
+  </compatibility>
+
+  <application xmlns="urn:schemas-microsoft-com:asm.v3">
+    <windowsSettings>
+      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
+    </windowsSettings>
+  </application>
+
+</assembly>

+ 0 - 0
ChaseAndEvade/Content/cat.png → ChaseAndEvade/Core/Content/cat.png


+ 0 - 0
ChaseAndEvade/Content/mouse.png → ChaseAndEvade/Core/Content/mouse.png


+ 0 - 0
ChaseAndEvade/Content/tank.png → ChaseAndEvade/Core/Content/tank.png


+ 30 - 0
ChaseAndEvade/Platforms/Android/Activity1.cs

@@ -0,0 +1,30 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Android.Views;
+using Microsoft.Xna.Framework;
+
+namespace ChaseAndEvade
+{
+    [Activity(
+        Label = "@string/app_name",
+        MainLauncher = true,
+        AlwaysRetainTaskState = true,
+        LaunchMode = LaunchMode.SingleInstance,
+        ScreenOrientation = ScreenOrientation.SensorLandscape,
+        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize
+    )]
+    public class MainActivity : AndroidGameActivity
+    {
+        private ChaseAndEvadeGame _game;
+
+        protected override void OnCreate(Bundle bundle)
+        {
+            base.OnCreate(bundle);
+
+            _game = new ChaseAndEvadeGame();
+            SetContentView((View)_game.Services.GetService(typeof(View)));
+            _game.Run();
+        }
+    }
+}

+ 18 - 0
ChaseAndEvade/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.asteroidbeltassault">
+    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="34" />
+    
+    <application android:allowBackup="true" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
+        <activity android:name="microsoft.xna.framework.AndroidGameActivity" 
+                  android:label="@string/app_name" 
+                  android:launchMode="singleInstance" 
+                  android:screenOrientation="sensorLandscape" 
+                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>

+ 27 - 0
ChaseAndEvade/Platforms/Android/ChaseAndEvade.Android.csproj

@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <RootNamespace>ChaseAndEvade.Android</RootNamespace>
+    <AssemblyName>ChaseAndEvade.Android</AssemblyName>
+    <SupportedOSPlatformVersion>28.0</SupportedOSPlatformVersion>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\ChaseAndEvade.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\Android\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Android\Content\Textures\mouse.xnb" Link="Content\mouse.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Android\Content\Textures\tank.xnb" Link="Content\tank.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Android\Content\Fonts\Arial.xnb" Link="Content\Arial.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 0 - 0
ChaseAndEvade/Resources/Drawable/Icon.png → ChaseAndEvade/Platforms/Android/Resources/Drawable/Icon.png


+ 0 - 0
ChaseAndEvade/Resources/Drawable/Splash.png → ChaseAndEvade/Platforms/Android/Resources/Drawable/Splash.png


+ 0 - 0
ChaseAndEvade/Resources/Resource.Designer.cs → ChaseAndEvade/Platforms/Android/Resources/Resource.Designer.cs


+ 4 - 0
ChaseAndEvade/Platforms/Android/Resources/Values/Strings.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Chase And Evade</string>
+</resources>

+ 0 - 0
ChaseAndEvade/Resources/Values/Styles.xml → ChaseAndEvade/Platforms/Android/Resources/Values/Styles.xml


+ 26 - 0
ChaseAndEvade/Platforms/Desktop/ChaseAndEvade.DesktopGL.csproj

@@ -0,0 +1,26 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>ChaseAndEvade.DesktopGL</RootNamespace>
+    <AssemblyName>ChaseAndEvade.DesktopGL</AssemblyName>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\ChaseAndEvade.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\mouse.xnb" Link="Content\mouse.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\tank.xnb" Link="Content\tank.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Fonts\Arial.xnb" Link="Content\Arial.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 15 - 0
ChaseAndEvade/Platforms/Desktop/Program.cs

@@ -0,0 +1,15 @@
+using System;
+using ChaseAndEvade;
+
+namespace ChaseAndEvade.DesktopGL
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new ChaseAndEvadeGame())
+                game.Run();
+        }
+    }
+}

+ 27 - 0
ChaseAndEvade/Platforms/Windows/ChaseAndEvade.Windows.csproj

@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <UseWindowsForms>true</UseWindowsForms>
+    <RootNamespace>ChaseAndEvade.Windows</RootNamespace>
+    <AssemblyName>ChaseAndEvade.Windows</AssemblyName>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\ChaseAndEvade.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\mouse.xnb" Link="Content\mouse.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\tank.xnb" Link="Content\tank.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Fonts\Arial.xnb" Link="Content\Arial.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 15 - 0
ChaseAndEvade/Platforms/Windows/Program.cs

@@ -0,0 +1,15 @@
+using System;
+using ChaseAndEvade;
+
+namespace ChaseAndEvade.Windows
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new ChaseAndEvadeGame())
+                game.Run();
+        }
+    }
+}

+ 20 - 0
ChaseAndEvade/Platforms/iOS/AppDelegate.cs

@@ -0,0 +1,20 @@
+using Foundation;
+using UIKit;
+using Microsoft.Xna.Framework;
+using ChaseAndEvade;
+
+namespace ChaseAndEvade.iOS
+{
+    [Register("AppDelegate")]
+    public class AppDelegate : UIApplicationDelegate
+    {
+        private Game game;
+
+        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
+        {
+            game = new ChaseAndEvadeGame();
+            game.Run();
+            return true;
+        }
+    }
+}

+ 26 - 0
ChaseAndEvade/Platforms/iOS/ChaseAndEvade.iOS.csproj

@@ -0,0 +1,26 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <RootNamespace>ChaseAndEvade.iOS</RootNamespace>
+    <AssemblyName>ChaseAndEvade.iOS</AssemblyName>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\ChaseAndEvade.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\iOS\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\iOS\Content\Textures\mouse.xnb" Link="Content\mouse.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\iOS\Content\Textures\tank.xnb" Link="Content\tank.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\iOS\Content\Fonts\Arial.xnb" Link="Content\Arial.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 0 - 0
ChaseAndEvade/Info.plist → ChaseAndEvade/Platforms/iOS/Info.plist


+ 14 - 0
ChaseAndEvade/Platforms/iOS/Program.cs

@@ -0,0 +1,14 @@
+using System;
+using UIKit;
+
+namespace ChaseAndEvade.iOS
+{
+    public class Application
+    {
+        // This is the main entry point of the application.
+        static void Main(string[] args)
+        {
+            UIApplication.Main(args, null, typeof(AppDelegate));
+        }
+    }
+}

+ 0 - 83
ChaseAndEvade/Program.cs

@@ -1,83 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-#if MONOMAC
-using MonoMac.AppKit;
-using MonoMac.Foundation;
-#elif IPHONE
-using MonoTouch.Foundation;
-using MonoTouch.UIKit;
-#endif
-
-namespace ChaseAndEvade
-{
-#if MONOMAC
-	class Program
-	{
-		static void Main (string[] args)
-		{
-			NSApplication.Init ();
-
-			using (var p = new NSAutoreleasePool ()) {
-
-				NSApplication.SharedApplication.Delegate = new AppDelegate ();
-
-				// Set our Application Icon
-				NSImage appIcon = NSImage.ImageNamed ("GameThumbnail.png");
-				NSApplication.SharedApplication.ApplicationIconImage = appIcon;
-
-				NSApplication.Main (args);
-			}
-		}
-	}
-
-	class AppDelegate : NSApplicationDelegate
-	{
-		ChaseAndEvadeGame game;
-		public override void FinishedLaunching (MonoMac.Foundation.NSObject notification)
-		{
-			game = new ChaseAndEvadeGame();
-			game.Run();
-		}
-
-		public override bool ApplicationShouldTerminateAfterLastWindowClosed (NSApplication sender)
-		{
-			return true;
-		}
-	}
-#elif IPHONE
-	[Register("AppDelegate")]
-	class Program : UIApplicationDelegate
-	{
-		ChaseAndEvadeGame game;
-		public override void FinishedLaunching(UIApplication app)
-		{
-			// Fun begins..
-			game = new ChaseAndEvadeGame();
-			game.Run();
-		}
-
-		/// <summary>
-		/// The main entry point for the application.
-		/// </summary>
-		static void Main(string[] args)
-		{
-			UIApplication.Main(args, null, "AppDelegate");
-		}
-	}	
-#else
-	/// <summary>
-	/// The main entry point for the application.
-	/// </summary>
-	static class Program
-	{
-		static void Main()
-		{
-			using (ChaseAndEvadeGame game = new ChaseAndEvadeGame())
-			{
-				game.Run();
-			}
-		}
-	}	
-#endif
-}

+ 47 - 0
ChaseAndEvade/README.md

@@ -0,0 +1,47 @@
+# ChaseAndEvade MonoGame Sample
+
+This project demonstrates simple chase, evade, and wander AI behaviors using MonoGame 3.8.* and .NET 8.0. It is organized for cross-platform development with a clean separation between shared game logic and platform-specific code.
+
+## Directory Structure
+
+- `/Core` — Shared game logic and main game class (`ChaseAndEvadeGame`)
+- `/Platforms/Windows` — Windows-specific entry point and project
+- `/Platforms/Desktop` — DesktopGL (cross-platform desktop) entry point and project
+- `/Platforms/Android` — Android entry point, manifest, and project
+- `/Platforms/iOS` — iOS entry point, Info.plist, and project
+- `/Content` — Prebuilt .xnb content files used directly by the game
+
+## Building and Running
+
+### Prerequisites
+- .NET 8.0 SDK
+- MonoGame 3.8.* (NuGet packages are referenced automatically)
+- Visual Studio 2022+ or VSCode (with C# Dev Kit recommended)
+
+### Windows
+1. Open `ChaseAndEvade.sln` in Visual Studio, or use VSCode.
+2. Build and run the `ChaseAndEvade.Windows` project.
+
+### DesktopGL
+1. Open `ChaseAndEvade.sln` or use VSCode.
+2. Build and run the `ChaseAndEvade.DesktopGL` project.
+
+### Android
+1. Open `ChaseAndEvade.sln` in Visual Studio (with Xamarin/MAUI workload).
+2. Build and deploy the `ChaseAndEvade.Android` project to an emulator or device.
+
+### iOS
+1. Open `ChaseAndEvade.sln` in Visual Studio for Mac or Windows (with Xamarin/MAUI workload and Mac build agent).
+2. Build and deploy the `ChaseAndEvade.iOS` project.
+
+## Notes
+- All shared code is in the `Core` project and referenced by each platform.
+- Platform-specific entry points are in their respective directories.
+- The game uses prebuilt `.xnb` files in the `Content` directory; no `Content.mgcb` is required.
+
+## VSCode Tasks and Launch
+- Use the provided `tasks.json` and `launch.json` for building and running Windows and DesktopGL projects directly from VSCode.
+
+---
+
+For more details, see the source code and comments in each project.

+ 0 - 31
ChaseAndEvade/app.xml

@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<application project_name="ChaseAndEvade" version="1.00" runtime_version="1.11" sdk_version="1.11.00" default_locale="en-US">
-  <name />
-  <short_name />
-  <parental_control lock_level="2" />
-  <rating_list highest_age_limit="3" has_online_features="false">
-    <online_features chat="false" personal_info="false" user_location="false" exchange_content="false" />
-    <rating type="ESRB" value="3" age="3" code="" />
-    <rating type="PEGIEX" value="3" age="3" code="" />
-  </rating_list>
-  <images />
-  <genre_list />
-  <developer>
-    <name value="" />
-  </developer>
-  <website href="" />
-  <copyright author="" />
-  <purchase>
-    <product_list />
-  </purchase>
-  <runtime_config>
-    <memory managed_heap_size="32768" resource_heap_size="65536" />
-    <display max_screen_size="1920x1200" />
-    <camera max_capture_resolution="2048x1536" />
-  </runtime_config>
-  <feature_list>
-    <feature value="GamePad" />
-	<feature value="Touch" />
-	<feature value="Motion" />
-  </feature_list>
-</application>