Browse Source

Add TestDataSetAndGet to test Get and Set Data on normal textures and render targets

Kenneth Pouncey 13 years ago
parent
commit
d13d5f0e39

BIN
Tests/MacOS/TestDataSetAndGet/Content/Block.bmp


BIN
Tests/MacOS/TestDataSetAndGet/Content/Block.xnb


BIN
Tests/MacOS/TestDataSetAndGet/Content/Character.png


BIN
Tests/MacOS/TestDataSetAndGet/Content/Person.bmp


BIN
Tests/MacOS/TestDataSetAndGet/Content/Person.xnb


BIN
Tests/MacOS/TestDataSetAndGet/Content/Warrior3Active.png


BIN
Tests/MacOS/TestDataSetAndGet/Content/Warrior3Active.xnb


+ 282 - 0
Tests/MacOS/TestDataSetAndGet/Game1.cs

@@ -0,0 +1,282 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// Game.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Storage;
+#endregion
+
+namespace TestDataSetAndGet
+{
+    /// <summary>
+    /// This is the main type for your game
+    /// </summary>
+    public class PerPixelCollisionGame : Microsoft.Xna.Framework.Game
+    {
+        GraphicsDeviceManager graphics;
+
+        // The images we will draw
+        Texture2D personTexture;
+        Texture2D blockTexture;
+		
+		Texture2D characterTexture;
+
+        // The color data for the images; used for per pixel collision
+        Color[] personTextureData;
+        Color[] blockTextureData;
+		Color[] characterTextureData;
+
+        // The images will be drawn with this SpriteBatch
+        SpriteBatch spriteBatch;
+
+        // Person 
+        Vector2 personPosition;
+        const int PersonMoveSpeed = 5;
+
+        // Blocks
+        List<Vector2> blockPositions = new List<Vector2>();
+        float BlockSpawnProbability = 0.01f;
+        const int BlockFallSpeed = 2;
+
+        Random random = new Random();
+
+        // For when a collision is detected
+        bool personHit = false;
+
+        // The sub-rectangle of the drawable area which should be visible on all TVs
+        Rectangle safeBounds;
+        // Percentage of the screen on every side is the safe area
+        const float SafeAreaPortion = 0.05f;
+
+
+        public PerPixelCollisionGame()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+        }
+
+
+        /// <summary>
+        /// Allows the game to perform any initialization it needs to before starting to
+        /// run. This is where it can query for any required services and load any
+        /// non-graphic related content.  Calling base.Initialize will enumerate through
+        /// any components and initialize them as well.
+        /// </summary>
+        protected override void Initialize()
+        {
+            base.Initialize();
+
+            // Calculate safe bounds based on current resolution
+            Viewport viewport = graphics.GraphicsDevice.Viewport;
+            safeBounds = new Rectangle(
+                (int)(viewport.Width * SafeAreaPortion),
+                (int)(viewport.Height * SafeAreaPortion),
+                (int)(viewport.Width * (1 - 2 * SafeAreaPortion)),
+                (int)(viewport.Height * (1 - 2 * SafeAreaPortion)));
+            // Start the player in the center along the bottom of the screen
+            personPosition.X = (safeBounds.Width - personTexture.Width) / 2;
+            personPosition.Y = safeBounds.Height - personTexture.Height;
+        }
+
+
+        /// <summary>
+        /// Load your graphics content.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            // Load textures
+            blockTexture = Content.Load<Texture2D>("Block");
+            personTexture = Content.Load<Texture2D>("Character");
+            //personTexture = Content.Load<Texture2D>("Warrior3Active");
+			characterTexture = new RenderTarget2D(GraphicsDevice, personTexture.Width, personTexture.Height);
+            // Extract collision data
+            blockTextureData =
+                new Color[blockTexture.Width * blockTexture.Height];
+            blockTexture.GetData(blockTextureData);
+            personTextureData =
+                new Color[personTexture.Width * personTexture.Height];
+            personTexture.GetData(personTextureData);
+			characterTexture.SetData(personTextureData);
+            characterTextureData =
+                new Color[characterTexture.Width * characterTexture.Height];
+			characterTexture.GetData(characterTextureData);
+		personTexture.SetData(characterTextureData);
+            // Create a sprite batch to draw those textures
+            spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
+        }
+
+
+        /// <summary>
+        /// Allows the game to run logic such as updating the world,
+        /// checking for collisions, gathering input and playing audio.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Update(GameTime gameTime)
+        {
+            // Get input
+            KeyboardState keyboard = Keyboard.GetState();
+            GamePadState gamePad = GamePad.GetState(PlayerIndex.One);
+
+            // Allows the game to exit
+            if (gamePad.Buttons.Back == ButtonState.Pressed ||
+                keyboard.IsKeyDown(Keys.Escape))
+            {
+                this.Exit();
+            }
+
+            // Move the player left and right with arrow keys or d-pad
+            if (keyboard.IsKeyDown(Keys.Left) ||
+                gamePad.DPad.Left == ButtonState.Pressed)
+            {
+                personPosition.X -= PersonMoveSpeed;
+            }
+            if (keyboard.IsKeyDown(Keys.Right) ||
+                gamePad.DPad.Right == ButtonState.Pressed)
+            {
+                personPosition.X += PersonMoveSpeed;
+            }
+
+            // Prevent the person from moving off of the screen
+            personPosition.X = MathHelper.Clamp(personPosition.X,
+                safeBounds.Left, safeBounds.Right - personTexture.Width);
+
+            // Spawn new falling blocks
+            if (random.NextDouble() < BlockSpawnProbability)
+            {
+                float x = (float)random.NextDouble() *
+                    (Window.ClientBounds.Width - blockTexture.Width);
+                blockPositions.Add(new Vector2(x, -blockTexture.Height));
+            }
+
+            // Get the bounding rectangle of the person
+            Rectangle personRectangle =
+                new Rectangle((int)personPosition.X, (int)personPosition.Y,
+                personTexture.Width, personTexture.Height);
+
+            // Update each block
+            personHit = false;
+            for (int i = 0; i < blockPositions.Count; i++)
+            {
+                // Animate this block falling
+                blockPositions[i] =
+                    new Vector2(blockPositions[i].X,
+                                blockPositions[i].Y + BlockFallSpeed);
+
+                // Get the bounding rectangle of this block
+                Rectangle blockRectangle =
+                    new Rectangle((int)blockPositions[i].X, (int)blockPositions[i].Y,
+                    blockTexture.Width, blockTexture.Height);
+
+                // Check collision with person
+                if (IntersectPixels(personRectangle, personTextureData,
+                                    blockRectangle, blockTextureData))
+                {
+                    personHit = true;
+                }
+
+                // Remove this block if it have fallen off the screen
+                if (blockPositions[i].Y > Window.ClientBounds.Height)
+                {
+                    blockPositions.RemoveAt(i);
+
+                    // When removing a block, the next block will have the same index
+                    // as the current block. Decrement i to prevent skipping a block.
+                    i--;
+                }
+            }
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// This is called when the game should draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice device = graphics.GraphicsDevice;
+
+            // Change the background to red when the person was hit by a block
+            if (personHit)
+            {
+                device.Clear(Color.Red);
+            }
+            else
+            {
+                device.Clear(Color.CornflowerBlue);
+            }
+
+            spriteBatch.Begin();
+
+            // Draw person
+            spriteBatch.Draw(personTexture, personPosition, Color.White);
+			Vector2 characterPosition = personPosition;
+			characterPosition.X += personTexture.Width;
+			//spriteBatch.Draw(characterTexture, characterPosition, Color.White);
+			
+            // Draw blocks
+            foreach (Vector2 blockPosition in blockPositions)
+                spriteBatch.Draw(blockTexture, blockPosition, Color.White);
+
+            spriteBatch.End();
+
+
+            base.Draw(gameTime);
+        }
+
+
+        /// <summary>
+        /// Determines if there is overlap of the non-transparent pixels
+        /// between two sprites.
+        /// </summary>
+        /// <param name="rectangleA">Bounding rectangle of the first sprite</param>
+        /// <param name="dataA">Pixel data of the first sprite</param>
+        /// <param name="rectangleB">Bouding rectangle of the second sprite</param>
+        /// <param name="dataB">Pixel data of the second sprite</param>
+        /// <returns>True if non-transparent pixels overlap; false otherwise</returns>
+        static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,
+                                    Rectangle rectangleB, Color[] dataB)
+        {
+            // Find the bounds of the rectangle intersection
+            int top = Math.Max(rectangleA.Top, rectangleB.Top);
+            int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
+            int left = Math.Max(rectangleA.Left, rectangleB.Left);
+            int right = Math.Min(rectangleA.Right, rectangleB.Right);
+
+            // Check every point within the intersection bounds
+            for (int y = top; y < bottom; y++)
+            {
+                for (int x = left; x < right; x++)
+                {
+                    // Get the color of both pixels at this point
+                    Color colorA = dataA[(x - rectangleA.Left) +
+                                         (y - rectangleA.Top) * rectangleA.Width];
+                    Color colorB = dataB[(x - rectangleB.Left) +
+                                         (y - rectangleB.Top) * rectangleB.Width];
+
+                    // If both pixels are not completely transparent,
+                    if (colorA.A != 0 && colorB.A != 0)
+                    {
+                        // then an intersection has been found
+                        return true;
+                    }
+                }
+            }
+
+            // No intersection found
+            return false;
+        }
+    }
+}

+ 16 - 0
Tests/MacOS/TestDataSetAndGet/Info.plist

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleIdentifier</key>
+	<string>com.yourcompany.TestDataSetAndGet</string>
+	<key>CFBundleName</key>
+	<string>TestDataSetAndGet</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.6</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

+ 52 - 0
Tests/MacOS/TestDataSetAndGet/Program.cs

@@ -0,0 +1,52 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// Program.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+#endregion
+
+namespace TestDataSetAndGet
+{
+
+	static class Program
+	{
+		/// <summary>
+		/// The main entry point for the application.
+		/// </summary>
+		static void Main (string[] args)
+		{
+			NSApplication.Init ();
+			
+			using (var p = new NSAutoreleasePool ()) {
+				NSApplication.SharedApplication.Delegate = new AppDelegate();
+				NSApplication.Main(args);
+			}
+		}
+	}
+	
+	class AppDelegate : NSApplicationDelegate
+	{
+		
+		public override void FinishedLaunching (MonoMac.Foundation.NSObject notification)
+		{
+			using (PerPixelCollisionGame game = new PerPixelCollisionGame()) {
+				game.Run ();
+			}
+		}
+		
+		public override bool ApplicationShouldTerminateAfterLastWindowClosed (NSApplication sender)
+		{
+			return true;
+		}
+	}			
+}

+ 71 - 0
Tests/MacOS/TestDataSetAndGet/TestDataSetAndGet.csproj

@@ -0,0 +1,71 @@
+<?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>{98CB640D-B8C4-496F-9978-F2571268BD70}</ProjectGuid>
+    <ProjectTypeGuids>{948B3504-5B70-4649-8FE4-BDE1FB46EC69};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>TestDataSetAndGet</RootNamespace>
+    <AssemblyName>TestDataSetAndGet</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </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>
+  </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" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Info.plist" />
+    <None Include="Content\Block.bmp" />
+    <None Include="Content\Warrior3Active.png" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
+  <ItemGroup>
+    <Folder Include="Content\" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\MonoGame\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj">
+      <Project>{AE483C29-042E-4226-BA52-D247CE7676DA}</Project>
+      <Name>Lidgren.Network.MacOS</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\MonoGame\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
+      <Project>{36C538E6-C32A-4A8D-A39C-566173D7118E}</Project>
+      <Name>MonoGame.Framework.MacOS</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Game1.cs" />
+    <Compile Include="Program.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Content\Block.xnb" />
+    <Content Include="Content\Character.png" />
+    <Content Include="Content\Person.bmp" />
+    <Content Include="Content\Person.xnb" />
+    <Content Include="Content\Warrior3Active.xnb" />
+  </ItemGroup>
+</Project>

+ 8 - 0
Tests/MonoGame.Tests.MacOS.sln

@@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CollisionSample", "..\Sampl
 EndProject
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextureScaleColorTest", "MacOS\TextureScaleColorTest\TextureScaleColorTest.csproj", "{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}"
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextureScaleColorTest", "MacOS\TextureScaleColorTest\TextureScaleColorTest.csproj", "{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}"
 EndProject
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestDataSetAndGet", "MacOS\TestDataSetAndGet\TestDataSetAndGet.csproj", "{98CB640D-B8C4-496F-9978-F2571268BD70}"
+EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
 		Debug|x86 = Debug|x86
@@ -70,6 +72,12 @@ Global
 		{9704681E-C6DB-4946-9F31-0EF9BE63090A}.Distribution|Any CPU.Build.0 = Debug|x86
 		{9704681E-C6DB-4946-9F31-0EF9BE63090A}.Distribution|Any CPU.Build.0 = Debug|x86
 		{9704681E-C6DB-4946-9F31-0EF9BE63090A}.Release|x86.ActiveCfg = Release|x86
 		{9704681E-C6DB-4946-9F31-0EF9BE63090A}.Release|x86.ActiveCfg = Release|x86
 		{9704681E-C6DB-4946-9F31-0EF9BE63090A}.Release|x86.Build.0 = Release|x86
 		{9704681E-C6DB-4946-9F31-0EF9BE63090A}.Release|x86.Build.0 = Release|x86
+		{98CB640D-B8C4-496F-9978-F2571268BD70}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{98CB640D-B8C4-496F-9978-F2571268BD70}.Debug|x86.Build.0 = Debug|Any CPU
+		{98CB640D-B8C4-496F-9978-F2571268BD70}.Distribution|Any CPU.ActiveCfg = Debug|Any CPU
+		{98CB640D-B8C4-496F-9978-F2571268BD70}.Distribution|Any CPU.Build.0 = Debug|Any CPU
+		{98CB640D-B8C4-496F-9978-F2571268BD70}.Release|x86.ActiveCfg = Release|Any CPU
+		{98CB640D-B8C4-496F-9978-F2571268BD70}.Release|x86.Build.0 = Release|Any CPU
 		{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}.Debug|x86.ActiveCfg = Debug|x86
 		{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}.Debug|x86.ActiveCfg = Debug|x86
 		{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}.Debug|x86.Build.0 = Debug|x86
 		{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}.Debug|x86.Build.0 = Debug|x86
 		{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}.Distribution|Any CPU.ActiveCfg = Debug|x86
 		{ABF4BDBE-C7DE-43E5-98BC-4547FE27A64A}.Distribution|Any CPU.ActiveCfg = Debug|x86