Explorar el Código

Add 2D Particle Sample

Kenneth Pouncey hace 14 años
padre
commit
191329b104

BIN
Samples/MacOS/ParticleSample/Background.png


BIN
Samples/MacOS/ParticleSample/Content/explosion.png


BIN
Samples/MacOS/ParticleSample/Content/explosion.xnb


+ 48 - 0
Samples/MacOS/ParticleSample/Content/font.spritefont

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This file contains an xml description of a font, and will be read by the XNA
+Framework Content Pipeline. Follow the comments to customize the appearance
+of the font in your game, and to change the characters which are available to draw
+with.
+-->
+<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
+  <Asset Type="Graphics:FontDescription">
+
+    <!--
+    Modify this string to change the font that will be imported.
+    -->
+    <FontName>Segoe UI</FontName>
+
+    <!--
+    Size is a float value, measured in points. Modify this value to change
+    the size of the font.
+    -->
+    <Size>14</Size>
+
+    <!--
+    Spacing is a float value, measured in pixels. Modify this value to change
+    the amount of spacing in between characters.
+    -->
+    <Spacing>2</Spacing>
+
+    <!--
+    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
+    and "Bold, Italic", and are case sensitive.
+    -->
+    <Style>Regular</Style>
+
+    <!--
+    CharacterRegions control what letters are available in the font. Every
+    character from Start to End will be built and made available for drawing. The
+    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
+    character set. The characters are ordered according to the Unicode standard.
+    See the documentation for more information.
+    -->
+    <CharacterRegions>
+      <CharacterRegion>
+        <Start>&#32;</Start>
+        <End>&#126;</End>
+      </CharacterRegion>
+    </CharacterRegions>
+  </Asset>
+</XnaContent>

BIN
Samples/MacOS/ParticleSample/Content/font.xnb


BIN
Samples/MacOS/ParticleSample/Content/smoke.bmp


BIN
Samples/MacOS/ParticleSample/Content/smoke.xnb


+ 93 - 0
Samples/MacOS/ParticleSample/ExplosionParticleSystem.cs

@@ -0,0 +1,93 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// ExplosionParticleSystem.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+#endregion
+
+namespace ParticleSample
+{
+    /// <summary>
+    /// ExplosionParticleSystem is a specialization of ParticleSystem which creates a
+    /// fiery explosion. It should be combined with ExplosionSmokeParticleSystem for
+    /// best effect.
+    /// </summary>
+    public class ExplosionParticleSystem : ParticleSystem
+    {
+        public ExplosionParticleSystem(ParticleSampleGame game, int howManyEffects)
+            : base(game, howManyEffects)
+        {
+        }
+
+        /// <summary>
+        /// Set up the constants that will give this particle system its behavior and
+        /// properties.
+        /// </summary>
+        protected override void InitializeConstants()
+        {
+            textureFilename = "explosion";
+
+            // high initial speed with lots of variance.  make the values closer
+            // together to have more consistently circular explosions.
+            minInitialSpeed = 40;
+            maxInitialSpeed = 500;
+
+            // doesn't matter what these values are set to, acceleration is tweaked in
+            // the override of InitializeParticle.
+            minAcceleration = 0;
+            maxAcceleration = 0;
+
+            // explosions should be relatively short lived
+            minLifetime = .5f;
+            maxLifetime = 1.0f;
+
+            minScale = .3f;
+            maxScale = 1.0f;
+
+            // we need to reduce the number of particles on Windows Phone in order to keep
+            // a good framerate
+#if WINDOWS_PHONE
+            minNumParticles = 10;
+            maxNumParticles = 12;
+#else
+            minNumParticles = 20;
+            maxNumParticles = 25;
+#endif
+
+            minRotationSpeed = -MathHelper.PiOver4;
+            maxRotationSpeed = MathHelper.PiOver4;
+
+            // additive blending is very good at creating fiery effects.
+			blendState = BlendState.Additive;
+
+            DrawOrder = AdditiveDrawOrder;
+        }
+
+        protected override void InitializeParticle(Particle p, Vector2 where)
+        {
+            base.InitializeParticle(p, where);
+            
+            // The base works fine except for acceleration. Explosions move outwards,
+            // then slow down and stop because of air resistance. Let's change
+            // acceleration so that when the particle is at max lifetime, the velocity
+            // will be zero.
+
+            // We'll use the equation vt = v0 + (a0 * t). (If you're not familar with
+            // this, it's one of the basic kinematics equations for constant
+            // acceleration, and basically says:
+            // velocity at time t = initial velocity + acceleration * t)
+            // We'll solve the equation for a0, using t = p.Lifetime and vt = 0.
+            p.Acceleration = -p.Velocity / p.Lifetime;
+        }
+    }
+}

+ 79 - 0
Samples/MacOS/ParticleSample/ExplosionSmokeParticleSystem.cs

@@ -0,0 +1,79 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// ExplosionSmokeParticleSystem.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+#endregion
+
+
+namespace ParticleSample
+{
+    /// <summary>
+    /// ExplosionSmokeParticleSystem is a specialization of ParticleSystem which
+    /// creates a circular pattern of smoke. It should be combined with
+    /// ExplosionParticleSystem for best effect.
+    /// </summary>
+    public class ExplosionSmokeParticleSystem : ParticleSystem
+    {
+        public ExplosionSmokeParticleSystem(ParticleSampleGame game, int howManyEffects)
+            : base(game, howManyEffects)
+        {            
+        }
+
+        /// <summary>
+        /// Set up the constants that will give this particle system its behavior and
+        /// properties.
+        /// </summary>
+        protected override void InitializeConstants()
+        {
+            textureFilename = "smoke";
+
+            // less initial speed than the explosion itself
+            minInitialSpeed = 20;
+            maxInitialSpeed = 200;
+
+            // acceleration is negative, so particles will accelerate away from the
+            // initial velocity.  this will make them slow down, as if from wind
+            // resistance. we want the smoke to linger a bit and feel wispy, though,
+            // so we don't stop them completely like we do ExplosionParticleSystem
+            // particles.
+            minAcceleration = -10;
+            maxAcceleration = -50;
+
+            // explosion smoke lasts for longer than the explosion itself, but not
+            // as long as the plumes do.
+            minLifetime = 1.0f;
+            maxLifetime = 2.5f;
+
+            minScale = 1.0f;
+            maxScale = 2.0f;
+
+            // we need to reduce the number of particles on Windows Phone in order to keep
+            // a good framerate
+#if WINDOWS_PHONE
+            minNumParticles = 5;
+            maxNumParticles = 10;
+#else
+            minNumParticles = 10;
+            maxNumParticles = 20;
+#endif
+
+            minRotationSpeed = -MathHelper.PiOver4;
+            maxRotationSpeed = MathHelper.PiOver4;
+
+			blendState = BlendState.AlphaBlend;
+
+            DrawOrder = AlphaBlendDrawOrder;
+        }
+    }
+}

BIN
Samples/MacOS/ParticleSample/Game.ico


BIN
Samples/MacOS/ParticleSample/GameThumbnail.png


+ 16 - 0
Samples/MacOS/ParticleSample/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.ParticleSample</string>
+	<key>CFBundleName</key>
+	<string>ParticleSample</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.6</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

+ 116 - 0
Samples/MacOS/ParticleSample/Particle.cs

@@ -0,0 +1,116 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// Particle.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+#endregion
+
+namespace ParticleSample
+{
+    /// <summary>
+    /// particles are the little bits that will make up an effect. each effect will
+    /// be comprised of many of these particles. They have basic physical properties,
+    /// such as position, velocity, acceleration, and rotation. They'll be drawn as
+    /// sprites, all layered on top of one another, and will be very pretty.
+    /// </summary>
+    public class Particle
+    {
+        // Position, Velocity, and Acceleration represent exactly what their names
+        // indicate. They are public fields rather than properties so that users
+        // can directly access their .X and .Y properties.
+        public Vector2 Position;
+        public Vector2 Velocity;
+        public Vector2 Acceleration;
+
+        // how long this particle will "live"
+        private float lifetime;
+        public float Lifetime
+        {
+            get { return lifetime; }
+            set { lifetime = value; }
+        }
+
+        // how long it has been since initialize was called
+        private float timeSinceStart;
+        public float TimeSinceStart
+        {
+            get { return timeSinceStart; }
+            set { timeSinceStart = value; }
+        }
+
+        // the scale of this particle
+        private float scale;
+        public float Scale
+        {
+            get { return scale; }
+            set { scale = value; }
+        }
+
+        // its rotation, in radians
+        private float rotation;
+        public float Rotation
+        {
+            get { return rotation; }
+            set { rotation = value; }
+        }
+
+        // how fast does it rotate?
+        private float rotationSpeed;
+        public float RotationSpeed
+        {
+            get { return rotationSpeed; }
+            set { rotationSpeed = value; }
+        }
+
+        // is this particle still alive? once TimeSinceStart becomes greater than
+        // Lifetime, the particle should no longer be drawn or updated.
+        public bool Active
+        {
+            get { return TimeSinceStart < Lifetime; }
+        }
+
+        
+        // initialize is called by ParticleSystem to set up the particle, and prepares
+        // the particle for use.
+        public void Initialize(Vector2 position, Vector2 velocity, Vector2 acceleration,
+            float lifetime, float scale, float rotationSpeed)
+        {
+            // set the values to the requested values
+            this.Position = position;
+            this.Velocity = velocity;
+            this.Acceleration = acceleration;
+            this.Lifetime = lifetime;
+            this.Scale = scale;
+            this.RotationSpeed = rotationSpeed;
+            
+            // reset TimeSinceStart - we have to do this because particles will be
+            // reused.
+            this.TimeSinceStart = 0.0f;
+
+            // set rotation to some random value between 0 and 360 degrees.
+            this.Rotation = ParticleSampleGame.RandomBetween(0, MathHelper.TwoPi);
+        }
+
+        // update is called by the ParticleSystem on every frame. This is where the
+        // particle's position and that kind of thing get updated.
+        public void Update(float dt)
+        {
+            Velocity += Acceleration * dt;
+            Position += Velocity * dt;
+
+            Rotation += RotationSpeed * dt;
+
+            TimeSinceStart += dt;
+        }
+    }
+}

+ 77 - 0
Samples/MacOS/ParticleSample/ParticleSample.csproj

@@ -0,0 +1,77 @@
+<?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>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{5CA0180F-C404-431A-87B5-03A26E5BFA23}</ProjectGuid>
+    <ProjectTypeGuids>{1C533B1C-72DD-4CB1-9F6B-BF11D93BCFBE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>ParticleSample</RootNamespace>
+    <AssemblyName>ParticleSample</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;MAC</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>
+  </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="Background.png" />
+    <None Include="Game.ico" />
+    <None Include="GameThumbnail.png" />
+    <None Include="Content\explosion.png" />
+    <None Include="Content\font.spritefont" />
+    <None Include="Content\smoke.bmp" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
+  <ItemGroup>
+    <Compile Include="ExplosionParticleSystem.cs" />
+    <Compile Include="ExplosionSmokeParticleSystem.cs" />
+    <Compile Include="Particle.cs" />
+    <Compile Include="ParticleSampleGame.cs" />
+    <Compile Include="ParticleSystem.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="SmokePlumeParticleSystem.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Content\explosion.xnb" />
+    <Content Include="Content\font.xnb" />
+    <Content Include="Content\smoke.xnb" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\MonoGame\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
+      <Project>{36C538E6-C32A-4A8D-A39C-566173D7118E}</Project>
+      <Name>MonoGame.Framework.MacOS</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\MonoGame\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj">
+      <Project>{AE483C29-042E-4226-BA52-D247CE7676DA}</Project>
+      <Name>Lidgren.Network.MacOS</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>

+ 37 - 0
Samples/MacOS/ParticleSample/ParticleSample.sln

@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParticleSample", "ParticleSample.csproj", "{5CA0180F-C404-431A-87B5-03A26E5BFA23}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.MacOS", "..\..\..\..\..\..\..\Users\Jimmy\Public\Share\MonoMacSource\kjpgit\MonoGame\MonoGame.Framework\MonoGame.Framework.MacOS.csproj", "{36C538E6-C32A-4A8D-A39C-566173D7118E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network.MacOS", "..\..\..\..\..\..\..\Users\Jimmy\Public\Share\MonoMacSource\kjpgit\MonoGame\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj", "{AE483C29-042E-4226-BA52-D247CE7676DA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+		Distribution|Any CPU = Distribution|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Debug|x86.Build.0 = Debug|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Distribution|Any CPU.ActiveCfg = Distribution|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Distribution|Any CPU.Build.0 = Distribution|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Release|x86.ActiveCfg = Release|Any CPU
+		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Release|x86.Build.0 = Release|Any CPU
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Debug|x86.ActiveCfg = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Debug|x86.Build.0 = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Release|x86.ActiveCfg = Release|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Release|x86.Build.0 = Release|x86
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.Build.0 = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Distribution|Any CPU.ActiveCfg = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Distribution|Any CPU.Build.0 = Debug|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.ActiveCfg = Release|Any CPU
+		{AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(MonoDevelopProperties) = preSolution
+		StartupItem = ParticleSample.csproj
+	EndGlobalSection
+EndGlobal

+ 299 - 0
Samples/MacOS/ParticleSample/ParticleSampleGame.cs

@@ -0,0 +1,299 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// ParticleSampleGame.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Input.Touch;
+#endregion
+
+namespace ParticleSample
+{
+    /// <summary>
+    /// This is the main type for the ParticleSample, and inherits from the Framework's
+    /// Game class. It creates three different kinds of ParticleSystems, and then adds
+    /// them to its components collection. It also has keeps a random number generator,
+    /// a SpriteBatch, and a ContentManager that the different classes in this sample
+    /// can share.
+    /// </summary>
+    public class ParticleSampleGame : Microsoft.Xna.Framework.Game
+    {
+        #region Fields and Properties
+
+        GraphicsDeviceManager graphics;
+
+        // The particle systems will all need a SpriteBatch to draw their particles,
+        // so let's make one they can share. We'll use this to draw our SpriteFont
+        // too.
+        SpriteBatch spriteBatch;
+        public SpriteBatch SpriteBatch
+        {
+            get { return spriteBatch; }
+        }
+
+        // Used to draw the instructions on the screen.
+        SpriteFont font;
+        
+        // a random number generator that the whole sample can share.
+        private static Random random = new Random();
+        public static Random Random
+        {
+            get { return random; }
+        }
+
+        // Here's the really fun part of the sample, the particle systems! These are
+        // drawable game components, so we can just add them to the components
+        // collection. Read more about each particle system in their respective source
+        // files.
+        ExplosionParticleSystem explosion;
+        ExplosionSmokeParticleSystem smoke;
+        SmokePlumeParticleSystem smokePlume;
+
+        // State is an enum that represents which effect we're currently demoing.
+        enum State
+        {
+            Explosions,
+            SmokePlume
+        };
+        // the number of values in the "State" enum.
+        const int NumStates = 2;
+        State currentState = State.Explosions;
+
+        // a timer that will tell us when it's time to trigger another explosion.
+        const float TimeBetweenExplosions = 2.0f;
+        float timeTillExplosion = 0.0f;
+
+        // keep a timer that will tell us when it's time to add more particles to the
+        // smoke plume.
+        const float TimeBetweenSmokePlumePuffs = .5f;
+        float timeTillPuff = 0.0f;
+
+        // keep track of the last frame's keyboard and gamepad state, so that we know
+        // if the user has pressed a button.
+        KeyboardState lastKeyboardState;
+        GamePadState lastGamepadState;
+
+        #endregion
+
+        #region Initialization
+
+        public ParticleSampleGame()
+        {
+            graphics = new GraphicsDeviceManager(this);
+
+#if WINDOWS_PHONE
+			graphics.IsFullScreen = true;
+
+            // Frame rate is 30 fps by default for Windows Phone.
+            TargetElapsedTime = TimeSpan.FromTicks(333333);
+#endif
+
+            Content.RootDirectory = "Content";
+
+            // create the particle systems and add them to the components list.
+            // we should never see more than one explosion at once
+            explosion = new ExplosionParticleSystem(this, 1);
+            Components.Add(explosion);
+
+            // but the smoke from the explosion lingers a while.
+            smoke = new ExplosionSmokeParticleSystem(this, 2);
+            Components.Add(smoke);
+
+            // we'll see lots of these effects at once; this is ok
+            // because they have a fairly small number of particles per effect.
+            smokePlume = new SmokePlumeParticleSystem(this, 9);
+            Components.Add(smokePlume);
+
+			// enable the tap gesture for changing particle effects
+			TouchPanel.EnabledGestures = GestureType.Tap;
+        }
+
+        /// <summary>
+        /// Load your graphics content. 
+        /// </summary>
+        protected override void LoadContent()
+        {
+            spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+        }
+
+        #endregion
+
+        #region Update and Draw
+
+        /// <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)
+        {
+            // check the input devices to see if someone has decided they want to see
+            // the other effect, if they want to quit.
+            HandleInput();
+
+            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
+            switch (currentState)
+            {
+                // if we should be demoing the explosions effect, check to see if it's
+                // time for a new explosion.
+                case State.Explosions:
+                    UpdateExplosions(dt);
+                    break;
+                // if we're showing off the smoke plume, check to see if it's time for a
+                // new puff of smoke.
+                case State.SmokePlume:
+                    UpdateSmokePlume(dt);
+                    break;
+            }
+
+            // the base update will handle updating the particle systems themselves,
+            // because we added them to the components collection.
+            base.Update(gameTime);
+        }
+        
+        // this function is called when we want to demo the smoke plume effect. it
+        // updates the timeTillPuff timer, and adds more particles to the plume when
+        // necessary.
+        private void UpdateSmokePlume(float dt)
+        {
+            timeTillPuff -= dt;
+            if (timeTillPuff < 0)
+            {
+                Vector2 where = Vector2.Zero;
+                // add more particles at the bottom of the screen, halfway across.
+                where.X = graphics.GraphicsDevice.Viewport.Width / 2;
+                where.Y = graphics.GraphicsDevice.Viewport.Height;
+                smokePlume.AddParticles(where);
+
+                // and then reset the timer.
+                timeTillPuff = TimeBetweenSmokePlumePuffs;
+            }
+        }
+
+        // this function is called when we want to demo the explosion effect. it
+        // updates the timeTillExplosion timer, and starts another explosion effect
+        // when the timer reaches zero.
+        private void UpdateExplosions(float dt)
+        {
+            timeTillExplosion -= dt;
+            if (timeTillExplosion < 0)
+            {
+                Vector2 where = Vector2.Zero;
+                // create the explosion at some random point on the screen.
+                where.X = RandomBetween(0, graphics.GraphicsDevice.Viewport.Width);
+                where.Y = RandomBetween(0, graphics.GraphicsDevice.Viewport.Height);
+
+                // the overall explosion effect is actually comprised of two particle
+                // systems: the fiery bit, and the smoke behind it. add particles to
+                // both of those systems.
+                explosion.AddParticles(where);
+                smoke.AddParticles(where);
+
+                // reset the timer.
+                timeTillExplosion = TimeBetweenExplosions;
+            }
+        }
+
+        /// <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)
+        {
+            graphics.GraphicsDevice.Clear(Color.Black);
+
+            spriteBatch.Begin();
+
+            // draw some instructions on the screen
+            string message = string.Format("Current effect: {0}!\n" + 
+                "Hit the A button or space bar, or tap the screen, to switch.\n\n" +
+                "Free particles:\n" +
+                "    ExplosionParticleSystem:      {1}\n" +
+                "    ExplosionSmokeParticleSystem: {2}\n" +
+                "    SmokePlumeParticleSystem:     {3}",
+                currentState, explosion.FreeParticleCount,
+                smoke.FreeParticleCount, smokePlume.FreeParticleCount );
+            spriteBatch.DrawString(font, message, new Vector2(50, 50), Color.White);
+
+            spriteBatch.End();
+
+            base.Draw(gameTime);
+        }
+
+        // This function will check to see if the user has just pushed the A button or
+        // the space bar. If so, we should go to the next effect.
+        private void HandleInput()
+        {
+            KeyboardState currentKeyboardState = Keyboard.GetState();
+            GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.One);
+
+            // Allows the game to exit
+            if (currentGamePadState.Buttons.Back == ButtonState.Pressed || 
+                currentKeyboardState.IsKeyDown(Keys.Escape))
+                this.Exit();
+
+
+            // check to see if someone has just released the space bar.            
+            bool keyboardSpace =
+                currentKeyboardState.IsKeyUp(Keys.Space) &&
+                lastKeyboardState.IsKeyDown(Keys.Space);
+
+
+            // check the gamepad to see if someone has just released the A button.
+            bool gamepadA =
+                currentGamePadState.Buttons.A == ButtonState.Pressed &&
+                lastGamepadState.Buttons.A == ButtonState.Released;
+
+			// check our gestures to see if someone has tapped the screen. we want
+			// to read all available gestures even if a tap occurred so we clear
+			// the queue.
+			bool tapGesture = false;
+			while (TouchPanel.IsGestureAvailable)
+			{
+				GestureSample sample = TouchPanel.ReadGesture();
+				if (sample.GestureType == GestureType.Tap)
+				{
+					tapGesture = true;
+				}
+			}
+            
+
+            // if either the A button or the space bar was just released, or the screen
+			// was tapped, move to the next state. Doing modulus by the number of 
+			// states lets us wrap back around to the first state.
+            if (keyboardSpace || gamepadA || tapGesture)
+            {
+                currentState = (State)((int)(currentState + 1) % NumStates);
+            }
+
+            lastKeyboardState = currentKeyboardState;
+            lastGamepadState = currentGamePadState;
+        }
+
+        #endregion
+
+        #region Helper Functions
+
+        //  a handy little function that gives a random float between two
+        // values. This will be used in several places in the sample, in particilar in
+        // ParticleSystem.InitializeParticle.
+        public static float RandomBetween(float min, float max)
+        {
+            return min + (float)random.NextDouble() * (max - min);
+        }
+
+        #endregion
+    }
+}

+ 368 - 0
Samples/MacOS/ParticleSample/ParticleSystem.cs

@@ -0,0 +1,368 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// SmokePlumeParticleSystem.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+#endregion
+
+namespace ParticleSample
+{
+    /// <summary>
+    /// ParticleSystem is an abstract class that provides the basic functionality to
+    /// create a particle effect. Different subclasses will have different effects,
+    /// such as fire, explosions, and plumes of smoke. To use these subclasses, 
+    /// simply call AddParticles, and pass in where the particles should exist
+    /// </summary>
+    public abstract class ParticleSystem : DrawableGameComponent
+    {
+        // these two values control the order that particle systems are drawn in.
+        // typically, particles that use additive blending should be drawn on top of
+        // particles that use regular alpha blending. ParticleSystems should therefore
+        // set their DrawOrder to the appropriate value in InitializeConstants, though
+        // it is possible to use other values for more advanced effects.
+        public const int AlphaBlendDrawOrder = 100;
+        public const int AdditiveDrawOrder = 200;
+
+        // a reference to the main game; we'll keep this around because it exposes a
+        // content manager and a sprite batch for us to use.
+        private ParticleSampleGame game;
+
+        // the texture this particle system will use.
+        private Texture2D texture;
+
+        // the origin when we're drawing textures. this will be the middle of the
+        // texture.
+        private Vector2 origin;
+
+        // this number represents the maximum number of effects this particle system
+        // will be expected to draw at one time. this is set in the constructor and is
+        // used to calculate how many particles we will need.
+        private int howManyEffects;
+        
+        // the array of particles used by this system. these are reused, so that calling
+        // AddParticles will not cause any allocations.
+        Particle[] particles;
+
+        // the queue of free particles keeps track of particles that are not curently
+        // being used by an effect. when a new effect is requested, particles are taken
+        // from this queue. when particles are finished they are put onto this queue.
+        Queue<Particle> freeParticles;
+        /// <summary>
+        /// returns the number of particles that are available for a new effect.
+        /// </summary>
+        public int FreeParticleCount
+        {
+            get { return freeParticles.Count; }
+        }
+
+
+        // This region of values control the "look" of the particle system, and should 
+        // be set by deriving particle systems in the InitializeConstants method. The
+        // values are then used by the virtual function InitializeParticle. Subclasses
+        // can override InitializeParticle for further
+        // customization.
+        #region constants to be set by subclasses
+
+        /// <summary>
+        /// minNumParticles and maxNumParticles control the number of particles that are
+        /// added when AddParticles is called. The number of particles will be a random
+        /// number between minNumParticles and maxNumParticles.
+        /// </summary>
+        protected int minNumParticles;
+        protected int maxNumParticles;
+       
+        /// <summary>
+        /// this controls the texture that the particle system uses. It will be used as
+        /// an argument to ContentManager.Load.
+        /// </summary>
+        protected string textureFilename;
+
+        /// <summary>
+        /// minInitialSpeed and maxInitialSpeed are used to control the initial velocity
+        /// of the particles. The particle's initial speed will be a random number 
+        /// between these two. The direction is determined by the function 
+        /// PickRandomDirection, which can be overriden.
+        /// </summary>
+        protected float minInitialSpeed;
+        protected float maxInitialSpeed;
+
+        /// <summary>
+        /// minAcceleration and maxAcceleration are used to control the acceleration of
+        /// the particles. The particle's acceleration will be a random number between
+        /// these two. By default, the direction of acceleration is the same as the
+        /// direction of the initial velocity.
+        /// </summary>
+        protected float minAcceleration;
+        protected float maxAcceleration;
+
+        /// <summary>
+        /// minRotationSpeed and maxRotationSpeed control the particles' angular
+        /// velocity: the speed at which particles will rotate. Each particle's rotation
+        /// speed will be a random number between minRotationSpeed and maxRotationSpeed.
+        /// Use smaller numbers to make particle systems look calm and wispy, and large 
+        /// numbers for more violent effects.
+        /// </summary>
+        protected float minRotationSpeed;
+        protected float maxRotationSpeed;
+
+        /// <summary>
+        /// minLifetime and maxLifetime are used to control the lifetime. Each
+        /// particle's lifetime will be a random number between these two. Lifetime
+        /// is used to determine how long a particle "lasts." Also, in the base
+        /// implementation of Draw, lifetime is also used to calculate alpha and scale
+        /// values to avoid particles suddenly "popping" into view
+        /// </summary>
+        protected float minLifetime;
+        protected float maxLifetime;
+
+        /// <summary>
+        /// to get some additional variance in the appearance of the particles, we give
+        /// them all random scales. the scale is a value between minScale and maxScale,
+        /// and is additionally affected by the particle's lifetime to avoid particles
+        /// "popping" into view.
+        /// </summary>
+        protected float minScale;
+        protected float maxScale;
+
+        /// <summary>
+        /// different effects can use different blend states. fire and explosions work
+        /// well with additive blending, for example.
+        /// </summary>
+		protected BlendState blendState;
+
+        #endregion
+        
+        /// <summary>
+        /// Constructs a new ParticleSystem.
+        /// </summary>
+        /// <param name="game">The host for this particle system. The game keeps the 
+        /// content manager and sprite batch for us.</param>
+        /// <param name="howManyEffects">the maximum number of particle effects that
+        /// are expected on screen at once.</param>
+        /// <remarks>it is tempting to set the value of howManyEffects very high.
+        /// However, this value should be set to the minimum possible, because
+        /// it has a large impact on the amount of memory required, and slows down the
+        /// Update and Draw functions.</remarks>
+        protected ParticleSystem(ParticleSampleGame game, int howManyEffects)
+            : base(game)
+        {            
+            this.game = game;
+            this.howManyEffects = howManyEffects;
+        }
+
+        /// <summary>
+        /// override the base class's Initialize to do some additional work; we want to
+        /// call InitializeConstants to let subclasses set the constants that we'll use.
+        /// 
+        /// also, the particle array and freeParticles queue are set up here.
+        /// </summary>
+        public override void Initialize()
+        {
+            InitializeConstants();
+            
+            // calculate the total number of particles we will ever need, using the
+            // max number of effects and the max number of particles per effect.
+            // once these particles are allocated, they will be reused, so that
+            // we don't put any pressure on the garbage collector.
+            particles = new Particle[howManyEffects * maxNumParticles];
+            freeParticles = new Queue<Particle>(howManyEffects * maxNumParticles);
+            for (int i = 0; i < particles.Length; i++)
+            {
+                particles[i] = new Particle();
+                freeParticles.Enqueue(particles[i]);
+            }
+            base.Initialize();
+        }
+
+        /// <summary>
+        /// this abstract function must be overriden by subclasses of ParticleSystem.
+        /// It's here that they should set all the constants marked in the region
+        /// "constants to be set by subclasses", which give each ParticleSystem its
+        /// specific flavor.
+        /// </summary>
+        protected abstract void InitializeConstants();
+
+        /// <summary>
+        /// Override the base class LoadContent to load the texture. once it's
+        /// loaded, calculate the origin.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            // make sure sub classes properly set textureFilename.
+            if (string.IsNullOrEmpty(textureFilename))
+            {
+                string message = "textureFilename wasn't set properly, so the " +
+                    "particle system doesn't know what texture to load. Make " +
+                    "sure your particle system's InitializeConstants function " +
+                    "properly sets textureFilename.";
+                throw new InvalidOperationException(message);
+            }
+            // load the texture....
+            texture = game.Content.Load<Texture2D>(textureFilename);
+
+            // ... and calculate the center. this'll be used in the draw call, we
+            // always want to rotate and scale around this point.
+            origin.X = texture.Width / 2;
+            origin.Y = texture.Height / 2;
+
+            base.LoadContent();
+        }
+
+        /// <summary>
+        /// AddParticles's job is to add an effect somewhere on the screen. If there 
+        /// aren't enough particles in the freeParticles queue, it will use as many as 
+        /// it can. This means that if there not enough particles available, calling
+        /// AddParticles will have no effect.
+        /// </summary>
+        /// <param name="where">where the particle effect should be created</param>
+        public void AddParticles(Vector2 where)
+        {
+            // the number of particles we want for this effect is a random number
+            // somewhere between the two constants specified by the subclasses.
+            int numParticles = 
+                ParticleSampleGame.Random.Next(minNumParticles, maxNumParticles);
+
+            // create that many particles, if you can.
+            for (int i = 0; i < numParticles && freeParticles.Count > 0; i++)
+            {
+                // grab a particle from the freeParticles queue, and Initialize it.
+                Particle p = freeParticles.Dequeue();
+                InitializeParticle(p, where);               
+            }
+        }
+
+        /// <summary>
+        /// InitializeParticle randomizes some properties for a particle, then
+        /// calls initialize on it. It can be overriden by subclasses if they 
+        /// want to modify the way particles are created. For example, 
+        /// SmokePlumeParticleSystem overrides this function make all particles
+        /// accelerate to the right, simulating wind.
+        /// </summary>
+        /// <param name="p">the particle to initialize</param>
+        /// <param name="where">the position on the screen that the particle should be
+        /// </param>
+        protected virtual void InitializeParticle(Particle p, Vector2 where)
+        {
+            // first, call PickRandomDirection to figure out which way the particle
+            // will be moving. velocity and acceleration's values will come from this.
+            Vector2 direction = PickRandomDirection();
+
+            // pick some random values for our particle
+            float velocity = 
+                ParticleSampleGame.RandomBetween(minInitialSpeed, maxInitialSpeed);
+            float acceleration = 
+                ParticleSampleGame.RandomBetween(minAcceleration, maxAcceleration);
+            float lifetime =
+                ParticleSampleGame.RandomBetween(minLifetime, maxLifetime);
+            float scale =
+                ParticleSampleGame.RandomBetween(minScale, maxScale);
+            float rotationSpeed =
+                ParticleSampleGame.RandomBetween(minRotationSpeed, maxRotationSpeed);
+
+            // then initialize it with those random values. initialize will save those,
+            // and make sure it is marked as active.
+            p.Initialize(
+                where, velocity * direction, acceleration * direction,
+                lifetime, scale, rotationSpeed);
+        }
+
+        /// <summary>
+        /// PickRandomDirection is used by InitializeParticles to decide which direction
+        /// particles will move. The default implementation is a random vector in a
+        /// circular pattern.
+        /// </summary>
+        protected virtual Vector2 PickRandomDirection()
+        {
+            float angle = ParticleSampleGame.RandomBetween(0, MathHelper.TwoPi);
+            return new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
+        }
+
+        /// <summary>
+        /// overriden from DrawableGameComponent, Update will update all of the active
+        /// particles.
+        /// </summary>
+        public override void Update(GameTime gameTime)
+        {
+            // calculate dt, the change in the since the last frame. the particle
+            // updates will use this value.
+            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+            // go through all of the particles...
+            foreach (Particle p in particles)
+            {
+                
+                if (p.Active)
+                {
+                    // ... and if they're active, update them.
+                    p.Update(dt);
+                    // if that update finishes them, put them onto the free particles
+                    // queue.
+                    if (!p.Active)
+                    {
+                        freeParticles.Enqueue(p);
+                    }
+                }   
+            }
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// overriden from DrawableGameComponent, Draw will use ParticleSampleGame's 
+        /// sprite batch to render all of the active particles.
+        /// </summary>
+        public override void Draw(GameTime gameTime)
+        {
+            // tell sprite batch to begin, using the spriteBlendMode specified in
+            // initializeConstants
+			game.SpriteBatch.Begin(SpriteSortMode.Deferred, blendState);
+            
+            foreach (Particle p in particles)
+            {
+                // skip inactive particles
+                if (!p.Active)
+                    continue;
+
+                // normalized lifetime is a value from 0 to 1 and represents how far
+                // a particle is through its life. 0 means it just started, .5 is half
+                // way through, and 1.0 means it's just about to be finished.
+                // this value will be used to calculate alpha and scale, to avoid 
+                // having particles suddenly appear or disappear.
+                float normalizedLifetime = p.TimeSinceStart / p.Lifetime;
+
+                // we want particles to fade in and fade out, so we'll calculate alpha
+                // to be (normalizedLifetime) * (1-normalizedLifetime). this way, when
+                // normalizedLifetime is 0 or 1, alpha is 0. the maximum value is at
+                // normalizedLifetime = .5, and is
+                // (normalizedLifetime) * (1-normalizedLifetime)
+                // (.5)                 * (1-.5)
+                // .25
+                // since we want the maximum alpha to be 1, not .25, we'll scale the 
+                // entire equation by 4.
+                float alpha = 4 * normalizedLifetime * (1 - normalizedLifetime);
+				Color color = Color.White * alpha;
+
+                // make particles grow as they age. they'll start at 75% of their size,
+                // and increase to 100% once they're finished.
+                float scale = p.Scale * (.75f + .25f * normalizedLifetime);
+
+                game.SpriteBatch.Draw(texture, p.Position, null, color,
+                    p.Rotation, origin, scale, SpriteEffects.None, 0.0f);
+            }
+
+            game.SpriteBatch.End();
+
+            base.Draw(gameTime);
+        }
+    }
+}

+ 1 - 0
Samples/MacOS/ParticleSample/Program.cs

@@ -0,0 +1 @@
+
using System;


namespace ParticleSample
{

	static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		static void Main (string[] args)
		{
			MonoMac.AppKit.NSApplication.Init ();
			
			using (var p = new MonoMac.Foundation.NSAutoreleasePool ()) {
				MonoMac.AppKit.NSApplication.SharedApplication.Delegate = new AppDelegate();
				MonoMac.AppKit.NSApplication.Main(args);
			}
		}
	}
	
	class AppDelegate : MonoMac.AppKit.NSApplicationDelegate
	{
		
		public override void FinishedLaunching (MonoMac.Foundation.NSObject notification)
		{
			using (ParticleSampleGame game = new ParticleSampleGame()) {
				game.Run ();
			}
		}
		
		public override bool ApplicationShouldTerminateAfterLastWindowClosed (MonoMac.AppKit.NSApplication sender)
		{
			return true;
		}
	}


}


+ 109 - 0
Samples/MacOS/ParticleSample/SmokePlumeParticleSystem.cs

@@ -0,0 +1,109 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// SmokePlumeParticleSystem.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+#endregion
+
+#region Using Statements
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+#endregion
+
+namespace ParticleSample
+{
+    /// <summary>
+    /// SmokePlumeParticleSystem is a specialization of ParticleSystem which sends up a
+    /// plume of smoke. The smoke is blown to the right by the wind.
+    /// </summary>
+    public class SmokePlumeParticleSystem : ParticleSystem
+    {
+        public SmokePlumeParticleSystem(ParticleSampleGame game, int howManyEffects)
+            : base(game,howManyEffects)
+        {
+        }
+
+        /// <summary>
+        /// Set up the constants that will give this particle system its behavior and
+        /// properties.
+        /// </summary>
+        protected override void InitializeConstants()
+        {
+            textureFilename = "smoke";
+
+            minInitialSpeed = 20;
+            maxInitialSpeed = 100;
+
+            // we don't want the particles to accelerate at all, aside from what we
+            // do in our overriden InitializeParticle.
+            minAcceleration = 0;
+            maxAcceleration = 0;
+
+            // long lifetime, this can be changed to create thinner or thicker smoke.
+            // tweak minNumParticles and maxNumParticles to complement the effect.
+            minLifetime = 5.0f;
+            maxLifetime = 7.0f;
+
+            minScale = .5f;
+            maxScale = 1.0f;
+
+            // we need to reduce the number of particles on Windows Phone in order to keep
+            // a good framerate
+#if WINDOWS_PHONE
+            minNumParticles = 3;
+            maxNumParticles = 8;
+#else
+            minNumParticles = 7;
+            maxNumParticles = 15;
+#endif
+
+            // rotate slowly, we want a fairly relaxed effect
+            minRotationSpeed = -MathHelper.PiOver4 / 2.0f;
+            maxRotationSpeed = MathHelper.PiOver4 / 2.0f;
+
+			blendState = BlendState.AlphaBlend;
+
+            DrawOrder = AlphaBlendDrawOrder;
+        }
+
+        /// <summary>
+        /// PickRandomDirection is overriden so that we can make the particles always 
+        /// move have an initial velocity pointing up.
+        /// </summary>
+        /// <returns>a random direction which points basically up.</returns>
+        protected override Vector2 PickRandomDirection()
+        {
+            // Point the particles somewhere between 80 and 100 degrees.
+            // tweak this to make the smoke have more or less spread.
+            float radians = ParticleSampleGame.RandomBetween(
+                MathHelper.ToRadians(80), MathHelper.ToRadians(100));
+
+            Vector2 direction = Vector2.Zero;
+            // from the unit circle, cosine is the x coordinate and sine is the
+            // y coordinate. We're negating y because on the screen increasing y moves
+            // down the monitor.
+            direction.X = (float)Math.Cos(radians);
+            direction.Y = -(float)Math.Sin(radians);
+            return direction;
+        }
+
+        /// <summary>
+        /// InitializeParticle is overridden to add the appearance of wind.
+        /// </summary>
+        /// <param name="p">the particle to set up</param>
+        /// <param name="where">where the particle should be placed</param>
+        protected override void InitializeParticle(Particle p, Vector2 where)
+        {
+            base.InitializeParticle(p, where);
+
+            // the base is mostly good, but we want to simulate a little bit of wind
+            // heading to the right.
+            p.Acceleration.X += ParticleSampleGame.RandomBetween(10, 50);
+        }
+    }
+}

+ 1 - 1
Samples/MacOS/RenderTarget2DSample/RenderTarget2DSample.csproj

@@ -54,7 +54,7 @@
     <Content Include="Content\wood.xnb" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\..\..\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
+    <ProjectReference Include="..\..\..\..\MonoGame\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
       <Project>{36C538E6-C32A-4A8D-A39C-566173D7118E}</Project>
       <Name>MonoGame.Framework.MacOS</Name>
     </ProjectReference>

+ 1 - 1
Samples/MacOS/Tetris/Engine.cs

@@ -33,7 +33,7 @@ namespace Tetris
 			{
 			graphics = new GraphicsDeviceManager (this);
 			//Content.RootDirectory = "Content";
-			Content.RootDirectory = Path.Combine (NSBundle.MainBundle.ResourcePath, "Content");
+			Content.RootDirectory = "Content";
 			
 			// Create sprite rectangles for each figure in texture file
 			// O figure

+ 24 - 0
Samples/MonoGame.Samples.MacOS.sln

@@ -59,6 +59,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RolePlayingGame", "MacOS\Ro
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RolePlayingGameData", "MacOS\RolePlayingGame\RolePlayingGameData\RolePlayingGameData.csproj", "{098BBC2D-63A6-4C22-8A30-E6C4F4FC0AC4}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderTarget2DSample", "MacOS\RenderTarget2DSample\RenderTarget2DSample.csproj", "{973C423F-0CC0-4230-9E67-D944ED70ED19}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParticleSample", "MacOS\ParticleSample\ParticleSample.csproj", "{5CA0180F-C404-431A-87B5-03A26E5BFA23}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -224,6 +228,16 @@ Global
 		{56C67234-2829-4AB0-8FEE-C8D01617CDCE}.Release|Any CPU.Build.0 = Release|Any CPU
 		{56C67234-2829-4AB0-8FEE-C8D01617CDCE}.Release|x86.ActiveCfg = Release|Any CPU
 		{56C67234-2829-4AB0-8FEE-C8D01617CDCE}.Release|x86.Build.0 = Release|Any CPU
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Debug|Any CPU.Build.0 = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Debug|x86.ActiveCfg = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Debug|x86.Build.0 = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Distribution|Any CPU.ActiveCfg = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Distribution|Any CPU.Build.0 = Debug|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Release|Any CPU.ActiveCfg = Release|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Release|Any CPU.Build.0 = Release|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Release|x86.ActiveCfg = Release|x86
+		{5CA0180F-C404-431A-87B5-03A26E5BFA23}.Release|x86.Build.0 = Release|x86
 		{71871CF8-8563-4FA3-ABF2-EC1CBBF817E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{71871CF8-8563-4FA3-ABF2-EC1CBBF817E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{71871CF8-8563-4FA3-ABF2-EC1CBBF817E4}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -284,6 +298,16 @@ Global
 		{9522776F-02BA-4BED-B8BB-6BAE580F4068}.Release|Any CPU.Build.0 = Release|Any CPU
 		{9522776F-02BA-4BED-B8BB-6BAE580F4068}.Release|x86.ActiveCfg = Release|Any CPU
 		{9522776F-02BA-4BED-B8BB-6BAE580F4068}.Release|x86.Build.0 = Release|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Debug|x86.Build.0 = Debug|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Distribution|Any CPU.ActiveCfg = Debug|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Distribution|Any CPU.Build.0 = Debug|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Release|Any CPU.Build.0 = Release|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Release|x86.ActiveCfg = Release|Any CPU
+		{973C423F-0CC0-4230-9E67-D944ED70ED19}.Release|x86.Build.0 = Release|Any CPU
 		{A82EAD58-40D7-49BE-8F24-09FEA34F9E55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{A82EAD58-40D7-49BE-8F24-09FEA34F9E55}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{A82EAD58-40D7-49BE-8F24-09FEA34F9E55}.Release|Any CPU.ActiveCfg = Release|Any CPU

+ 0 - 1
StarterKits/MacOS/Marblets/Marblets.csproj

@@ -10,7 +10,6 @@
     <OutputType>Exe</OutputType>
     <RootNamespace>Marblets</RootNamespace>
     <AssemblyName>Marblets</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>