Browse Source

Working on AtomicBlaster

Josh Engebretson 9 years ago
parent
commit
cda37ccd00
74 changed files with 2061 additions and 3 deletions
  1. 3 0
      AtomicNET/AtomicBlaster/.gitignore
  2. 0 0
      AtomicNET/AtomicBlaster/AtomicBlaster.atomic
  3. 5 0
      AtomicNET/AtomicBlaster/Resources.asset
  4. 5 0
      AtomicNET/AtomicBlaster/Resources/Components.asset
  5. 16 0
      AtomicNET/AtomicBlaster/Resources/Components/Spinner.js
  6. 7 0
      AtomicNET/AtomicBlaster/Resources/Components/Spinner.js.asset
  7. 5 0
      AtomicNET/AtomicBlaster/Resources/Scenes.asset
  8. 59 0
      AtomicNET/AtomicBlaster/Resources/Scenes/Scene.scene
  9. 8 0
      AtomicNET/AtomicBlaster/Resources/Scenes/Scene.scene.asset
  10. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts.asset
  11. 41 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Art.cs
  12. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Art.cs.asset
  13. 116 0
      AtomicNET/AtomicBlaster/Resources/Scripts/BlackHole.cs
  14. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/BlackHole.cs.asset
  15. 45 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Bullet.cs
  16. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Bullet.cs.asset
  17. 59 0
      AtomicNET/AtomicBlaster/Resources/Scripts/ColorUtil.cs
  18. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/ColorUtil.cs.asset
  19. 17 0
      AtomicNET/AtomicBlaster/Resources/Scripts/CustomRenderer.cs
  20. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/CustomRenderer.cs.asset
  21. 169 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Enemy.cs
  22. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Enemy.cs.asset
  23. 54 0
      AtomicNET/AtomicBlaster/Resources/Scripts/EnemySpawner.cs
  24. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/EnemySpawner.cs.asset
  25. 36 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Entity.cs
  26. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Entity.cs.asset
  27. 152 0
      AtomicNET/AtomicBlaster/Resources/Scripts/EntityManager.cs
  28. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/EntityManager.cs.asset
  29. 42 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Extensions.cs
  30. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Extensions.cs.asset
  31. 86 0
      AtomicNET/AtomicBlaster/Resources/Scripts/GameRoot.cs
  32. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/GameRoot.cs.asset
  33. 264 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Grid.cs
  34. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Grid.cs.asset
  35. 18 0
      AtomicNET/AtomicBlaster/Resources/Scripts/MathUtil.cs
  36. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/MathUtil.cs.asset
  37. 165 0
      AtomicNET/AtomicBlaster/Resources/Scripts/ParticleManager.cs
  38. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/ParticleManager.cs.asset
  39. 101 0
      AtomicNET/AtomicBlaster/Resources/Scripts/ParticleState.cs
  40. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/ParticleState.cs.asset
  41. 163 0
      AtomicNET/AtomicBlaster/Resources/Scripts/PlayerShip.cs
  42. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/PlayerShip.cs.asset
  43. 86 0
      AtomicNET/AtomicBlaster/Resources/Scripts/PlayerStatus.cs
  44. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/PlayerStatus.cs.asset
  45. 18 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Program.cs
  46. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Program.cs.asset
  47. 0 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Sound.cs
  48. 5 0
      AtomicNET/AtomicBlaster/Resources/Scripts/Sound.cs.asset
  49. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites.asset
  50. 157 0
      AtomicNET/AtomicBlaster/Resources/Sprites/AtomicBlasterSprites.plist
  51. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/AtomicBlasterSprites.png
  52. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/AtomicBlasterSprites.png.asset
  53. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/BlackHole.png
  54. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/BlackHole.png.asset
  55. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Bullet.png
  56. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Bullet.png.asset
  57. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Glow.png
  58. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Glow.png.asset
  59. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Laser.png
  60. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Laser.png.asset
  61. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Pixel.png
  62. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Pixel.png.asset
  63. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Player.png
  64. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Player.png.asset
  65. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Pointer.png
  66. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Pointer.png.asset
  67. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Seeker.png
  68. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Seeker.png.asset
  69. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/Wanderer.png
  70. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/Wanderer.png.asset
  71. BIN
      AtomicNET/AtomicBlaster/Resources/Sprites/star.png
  72. 5 0
      AtomicNET/AtomicBlaster/Resources/Sprites/star.png.asset
  73. 1 1
      AtomicNET/Physics2D/Resources/Components/PhysicsSpawner.cs
  74. 3 2
      AtomicNET/Physics2D/Resources/Scenes/TheScene.scene

+ 3 - 0
AtomicNET/AtomicBlaster/.gitignore

@@ -0,0 +1,3 @@
+Cache/*
+AtomicNET/*
+Resources/AtomicProject.*

+ 0 - 0
AtomicNET/AtomicBlaster/AtomicBlaster.atomic


+ 5 - 0
AtomicNET/AtomicBlaster/Resources.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "67fe2b1d0f8fe055133af5969a31b851",
+	"FolderImporter": {}
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Components.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "c79581855f9e7e35c50930013ae80449",
+	"FolderImporter": {}
+}

+ 16 - 0
AtomicNET/AtomicBlaster/Resources/Components/Spinner.js

@@ -0,0 +1,16 @@
+"atomic component";
+//inspector fields to make speed variable visible in editor
+var inspectorFields = {
+    speed: 1.0
+}
+
+exports.component = function(self) {
+    
+    //update function calls each frame
+    self.update = function(timeStep) {
+        //roll a node
+        self.node.roll(timeStep * 100);
+
+    }
+
+}

+ 7 - 0
AtomicNET/AtomicBlaster/Resources/Components/Spinner.js.asset

@@ -0,0 +1,7 @@
+{
+	"version": 1,
+	"guid": "9aaf7df74d0dfca2d6ffed3b60654d22",
+	"JavascriptImporter": {
+		"IsComponentFile": true
+	}
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scenes.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "994eb6e514f2ce7743a03f57fdd07e08",
+	"FolderImporter": {}
+}

+ 59 - 0
AtomicNET/AtomicBlaster/Resources/Scenes/Scene.scene

@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<scene id="1">
+	<attribute name="Name" value="" />
+	<attribute name="Time Scale" value="1" />
+	<attribute name="Smoothing Constant" value="50" />
+	<attribute name="Snap Threshold" value="5" />
+	<attribute name="Elapsed Time" value="0" />
+	<attribute name="Next Replicated Node ID" value="370" />
+	<attribute name="Next Replicated Component ID" value="1987" />
+	<attribute name="Next Local Node ID" value="16778496" />
+	<attribute name="Next Local Component ID" value="16777216" />
+	<attribute name="Variables" />
+	<attribute name="Variable Names" value="" />
+	<component type="PhysicsWorld" id="1" />
+	<component type="Octree" id="2" />
+	<component type="DebugRenderer" id="3" />
+	<component type="Renderer2D" id="1980" />
+	<node id="2">
+		<attribute name="Is Enabled" value="true" />
+		<attribute name="Name" value="Zone" />
+		<attribute name="Position" value="0 0 0" />
+		<attribute name="Rotation" value="1 0 0 0" />
+		<attribute name="Scale" value="1 1 1" />
+		<attribute name="Variables" />
+		<component type="Zone" id="4">
+			<attribute name="Bounding Box Min" value="-10000 -10000 -10000" />
+			<attribute name="Bounding Box Max" value="10000 10000 10000" />
+			<attribute name="Ambient Color" value="0.4 0.4 0.4 1" />
+		</component>
+	</node>
+	<node id="361">
+		<attribute name="Is Enabled" value="true" />
+		<attribute name="Name" value="Camera" />
+		<attribute name="Position" value="0 0 0" />
+		<attribute name="Rotation" value="1 0 0 0" />
+		<attribute name="Scale" value="1 1 1" />
+		<attribute name="Variables" />
+		<component type="Camera" id="1973">
+			<attribute name="Near Clip" value="0" />
+			<attribute name="Orthographic" value="true" />
+			<attribute name="Orthographic Size" value="5" />
+		</component>
+	</node>
+	<node id="363">
+		<attribute name="Is Enabled" value="true" />
+		<attribute name="Name" value="Star" />
+		<attribute name="Position" value="0 0 3.4" />
+		<attribute name="Rotation" value="1 0 0 0" />
+		<attribute name="Scale" value="1 1 1" />
+		<attribute name="Variables" />
+		<component type="JSComponent" id="1977">
+			<attribute name="ComponentFile" value="JSComponentFile;Components/Spinner.js" />
+		</component>
+		<component type="StaticSprite2D" id="1979">
+			<attribute name="Layer" value="-100" />
+			<attribute name="Sprite" value="Sprite2D;Sprites/star.png" />
+		</component>
+	</node>
+</scene>

+ 8 - 0
AtomicNET/AtomicBlaster/Resources/Scenes/Scene.scene.asset

@@ -0,0 +1,8 @@
+{
+	"version": 1,
+	"guid": "d993277faa2b13758d981808e37b90eb",
+	"SceneImporter": {
+		"sceneCamRotation": "1 0 0 0",
+		"sceneCamPosition": "0 0 0"
+	}
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "1af90a39e01efff1eb5be2a41e4b2ec8",
+	"FolderImporter": {}
+}

+ 41 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Art.cs

@@ -0,0 +1,41 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    static class Art
+    {
+        public static Texture2D Player { get; private set; }
+        public static Texture2D Seeker { get; private set; }
+        public static Texture2D Wanderer { get; private set; }
+        public static Texture2D Bullet { get; private set; }
+        public static Texture2D Pointer { get; private set; }
+        public static Texture2D BlackHole { get; private set; }
+
+        public static Texture2D LineParticle { get; private set; }
+        public static Texture2D Glow { get; private set; }
+        public static Texture2D Pixel { get; private set; }     // a single white pixel
+
+
+        public static void Load()
+        {
+            var cache = AtomicNET.Cache;
+
+            Player = cache.GetResource<Texture2D>("Sprites/Player.png");
+            Seeker = cache.GetResource<Texture2D>("Sprites/Seeker.png");
+            Wanderer = cache.GetResource<Texture2D>("Sprites/Wanderer.png");
+            Bullet = cache.GetResource<Texture2D>("Sprites/Bullet.png");
+            Pointer = cache.GetResource<Texture2D>("Sprites/Pointer.png");
+            BlackHole = cache.GetResource<Texture2D>("Sprites/BlackHole.png");
+
+            LineParticle = cache.GetResource<Texture2D>("Sprites/Laser.png");
+            Glow = cache.GetResource<Texture2D>("Sprites/Glow.png");
+            Pixel = cache.GetResource<Texture2D>("Sprites/Pixel.png");
+
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Art.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "9654d1881f85f90e45a20bfb36a55545",
+	"CSharpImporter": null
+}

+ 116 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/BlackHole.cs

@@ -0,0 +1,116 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    class BlackHole : Entity
+    {
+        private static Random rand = new Random();
+
+        private int hitpoints = 10;
+        private float sprayAngle = 0;
+
+        public BlackHole(Vector2 position)
+        {
+            image = Art.BlackHole;
+            Position = position;
+            Radius = image.Width / 2f;
+        }
+
+        public override void Update()
+        {
+            var entities = EntityManager.GetNearbyEntities(Position, 250);
+
+            foreach (var entity in entities)
+            {
+                if (entity is Enemy && !(entity as Enemy).IsActive)
+                    continue;
+
+                // bullets are repelled by black holes and everything else is attracted
+                if (entity is Bullet)
+                    entity.Velocity += (entity.Position - Position).ScaleTo(0.3f);
+                else
+                {
+                    var dPos = Position - entity.Position;
+                    var length = dPos.Length;
+
+                    entity.Velocity += dPos.ScaleTo(MathHelper.Lerp(2, 0, length / 250f));
+                }
+            }
+
+            // The black holes spray some orbiting particles. The spray toggles on and off every quarter second.
+            if ((GameRoot.ElapsedTime * 1000 / 250) % 2 == 0)
+            {
+                Vector2 sprayVel = MathUtil.FromPolar(sprayAngle, rand.NextFloat(12, 15));
+                Color color = ColorUtil.HSVToColor(5, 0.5f, 0.8f);  // light purple
+                Vector2 pos = Position + 2f * new Vector2(sprayVel.Y, -sprayVel.X) + rand.NextVector2(4, 8);
+                var state = new ParticleState()
+                {
+                    Velocity = sprayVel,
+                    LengthMultiplier = 1,
+                    Type = ParticleType.Enemy
+                };
+
+                GameRoot.ParticleManager.CreateParticle(Art.LineParticle, pos, color, 190, 1.5f, state);
+            }
+
+            // rotate the spray direction
+            sprayAngle -= MathHelper.TwoPi / 50f;
+
+            GameRoot.Grid.ApplyImplosiveForce((float)Math.Sin(sprayAngle / 2) * 10 + 20, Position, 200);
+        }
+
+        public void WasShot()
+        {
+            hitpoints--;
+            if (hitpoints <= 0)
+            {
+                IsExpired = true;
+                PlayerStatus.AddPoints(5);
+                PlayerStatus.IncreaseMultiplier();
+            }
+
+
+            float hue = (float)((3 * GameRoot.ElapsedTime) % 6);
+            Color color = ColorUtil.HSVToColor(hue, 0.25f, 1);
+            const int numParticles = 150;
+            float startOffset = rand.NextFloat(0, MathHelper.TwoPi / numParticles);
+
+            for (int i = 0; i < numParticles; i++)
+            {
+                Vector2 sprayVel = MathUtil.FromPolar(MathHelper.TwoPi * i / numParticles + startOffset, rand.NextFloat(8, 16));
+                Vector2 pos = Position + 2f * sprayVel;
+                var state = new ParticleState()
+                {
+                    Velocity = sprayVel,
+                    LengthMultiplier = 1,
+                    Type = ParticleType.IgnoreGravity
+                };
+
+                GameRoot.ParticleManager.CreateParticle(Art.LineParticle, pos, color, 90, 1.5f, state);
+            }
+
+            //Sound.Explosion.Play(0.5f, rand.NextFloat(-0.2f, 0.2f), 0);
+        }
+
+        public void Kill()
+        {
+            hitpoints = 0;
+            WasShot();
+        }
+
+        public override void Draw(/*SpriteBatch spriteBatch*/)
+        {
+            /*
+            // make the size of the black hole pulsate
+            float scale = 1 + 0.1f * (float)Math.Sin(10 * GameRoot.GameTime.TotalGameTime.TotalSeconds);
+            spriteBatch.Draw(image, Position, null, color, Orientation, Size / 2f, scale, 0, 0);
+            */
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/BlackHole.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "57ad0a80c6c488ec25cacc28f334cd1f",
+	"CSharpImporter": null
+}

+ 45 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Bullet.cs

@@ -0,0 +1,45 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using System.Linq;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    class Bullet : Entity
+    {
+        private static Random rand = new Random();
+
+        public Bullet(Vector2 position, Vector2 velocity)
+        {
+            image = Art.Bullet;
+            Position = position;
+            Velocity = velocity;
+            Orientation = Velocity.ToAngle();
+            Radius = 8;
+        }
+
+        public override void Update()
+        {
+            if (Velocity.LengthSquared > 0)
+                Orientation = Velocity.ToAngle();
+
+            Position += Velocity;
+            GameRoot.Grid.ApplyExplosiveForce(0.5f * Velocity.Length, Position, 80);
+
+            // delete bullets that go off-screen
+            if (!GameRoot.ScreenBounds.Contains(Position))
+            {
+                IsExpired = true;
+
+                for (int i = 0; i < 30; i++)
+                    GameRoot.ParticleManager.CreateParticle(Art.LineParticle, Position, Color.LightBlue, 50, 1,
+                        new ParticleState() { Velocity = rand.NextVector2(0, 9), Type = ParticleType.Bullet, LengthMultiplier = 1 });
+
+            }
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Bullet.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "ce19f441027b2b3e7dfdb5866b1964ca",
+	"CSharpImporter": null
+}

+ 59 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/ColorUtil.cs

@@ -0,0 +1,59 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    static class ColorUtil
+    {
+        public static Vector3 ColorToHSV(Color color)
+        {
+            Vector3 c = new Vector3(color.R, color.G, color.B);
+            float v = Math.Max(c.X, Math.Max(c.Y, c.Z));
+            float chroma = v - Math.Min(c.X, Math.Min(c.Y, c.Z));
+
+            if (chroma == 0f)
+                return new Vector3(0, 0, v);
+
+            float s = chroma / v;
+
+            if (c.X >= c.Y && c.Y >= c.Z)
+            {
+                float h = (c.Y - c.Z) / chroma;
+                if (h < 0)
+                    h += 6;
+                return new Vector3(h, s, v);
+            }
+            else if (c.Y >= c.Z && c.Y >= c.X)
+                return new Vector3((c.Z - c.X) / chroma + 2, s, v);
+            else
+                return new Vector3((c.X - c.Y) / chroma + 4, s, v);
+        }
+
+        public static Color HSVToColor(Vector3 hsv)
+        {
+            return HSVToColor(hsv.X, hsv.Y, hsv.Z);
+        }
+
+        public static Color HSVToColor(float h, float s, float v)
+        {
+            if (h == 0 && s == 0)
+                return new Color(v, v, v);
+
+            float c = s * v;
+            float x = c * (1 - Math.Abs(h % 2 - 1));
+            float m = v - c;
+
+            if (h < 1) return new Color(c + m, x + m, m);
+            else if (h < 2) return new Color(x + m, c + m, m);
+            else if (h < 3) return new Color(m, c + m, x + m);
+            else if (h < 4) return new Color(m, x + m, c + m);
+            else if (h < 5) return new Color(x + m, m, c + m);
+            else return new Color(c + m, m, x + m);
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/ColorUtil.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "fc28ab52bef3ff0383d21518e5f610fa",
+	"CSharpImporter": null
+}

+ 17 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/CustomRenderer.cs

@@ -0,0 +1,17 @@
+
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    static class CustomRenderer
+    {
+        static VertexBuffer vertexBuffer;
+
+        public static void Initialize()
+        {
+            vertexBuffer = new VertexBuffer();
+            vertexBuffer.Shadowed = true;
+        }
+
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/CustomRenderer.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "70c81a9e4a6cf05b2eb32b9774668689",
+	"CSharpImporter": null
+}

+ 169 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Enemy.cs

@@ -0,0 +1,169 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    class Enemy : Entity
+    {
+        public static Random rand = new Random();
+
+        private List<IEnumerator<int>> behaviours = new List<IEnumerator<int>>();
+        private int timeUntilStart = 60;
+        public bool IsActive { get { return timeUntilStart <= 0; } }
+        public int PointValue { get; private set; }
+
+        public Enemy(Texture2D image, Vector2 position)
+        {
+            this.image = image;
+            Position = position;
+            Radius = image.Width / 2f;
+            color = Color.Transparent;
+            PointValue = 1;
+        }
+
+        public static Enemy CreateSeeker(Vector2 position)
+        {
+            var enemy = new Enemy(Art.Seeker, position);
+            enemy.AddBehaviour(enemy.FollowPlayer(0.9f));
+            enemy.PointValue = 2;
+
+            return enemy;
+        }
+
+        public static Enemy CreateWanderer(Vector2 position)
+        {
+            var enemy = new Enemy(Art.Wanderer, position);
+            enemy.AddBehaviour(enemy.MoveRandomly());
+
+            return enemy;
+        }
+
+        public override void Update()
+        {
+            if (timeUntilStart <= 0)
+                ApplyBehaviours();
+            else
+            {
+                timeUntilStart--;
+                float mul = (1 - timeUntilStart / 60f);
+                color = new Color(mul, mul, mul, mul);
+            }
+
+            Position += Velocity;
+            Position = Vector2.Clamp(Position, Size / 2, GameRoot.ScreenSize - Size / 2);
+
+            Velocity *= 0.8f;
+        }
+
+        public override void Draw(/*SpriteBatch spriteBatch*/)
+        {
+            /*
+            if (timeUntilStart > 0)
+            {
+                // Draw an expanding, fading-out version of the sprite as part of the spawn-in effect.
+                float factor = timeUntilStart / 60f;    // decreases from 1 to 0 as the enemy spawns in
+                spriteBatch.Draw(image, Position, null, Color.White * factor, Orientation, Size / 2f, 2 - factor, 0, 0);
+            }
+
+            base.Draw(spriteBatch);
+            */
+        }
+
+        private void AddBehaviour(IEnumerable<int> behaviour)
+        {
+            behaviours.Add(behaviour.GetEnumerator());
+        }
+
+        private void ApplyBehaviours()
+        {
+            for (int i = 0; i < behaviours.Count; i++)
+            {
+                if (!behaviours[i].MoveNext())
+                    behaviours.RemoveAt(i--);
+            }
+        }
+
+        public void HandleCollision(Enemy other)
+        {
+            var d = Position - other.Position;
+            Velocity += 10 * d / (d.LengthSquared + 1);
+        }
+
+        public void WasShot()
+        {
+            IsExpired = true;
+            PlayerStatus.AddPoints(PointValue);
+            PlayerStatus.IncreaseMultiplier();
+
+            float hue1 = rand.NextFloat(0, 6);
+            float hue2 = (hue1 + rand.NextFloat(0, 2)) % 6f;
+            Color color1 = ColorUtil.HSVToColor(hue1, 0.5f, 1);
+            Color color2 = ColorUtil.HSVToColor(hue2, 0.5f, 1);
+
+            for (int i = 0; i < 120; i++)
+            {
+                float speed = 18f * (1f - 1 / rand.NextFloat(1, 10));
+                var state = new ParticleState()
+                {
+                    Velocity = rand.NextVector2(speed, speed),
+                    Type = ParticleType.Enemy,
+                    LengthMultiplier = 1
+                };
+
+                Color color = Color.Lerp(color1, color2, rand.NextFloat(0, 1));
+                GameRoot.ParticleManager.CreateParticle(Art.LineParticle, Position, color, 190, 1.5f, state);
+            }
+
+            //Sound.Explosion.Play(0.5f, rand.NextFloat(-0.2f, 0.2f), 0);
+        }
+
+        #region Behaviours
+        IEnumerable<int> FollowPlayer(float acceleration)
+        {
+            while (true)
+            {
+                if (!PlayerShip.Instance.IsDead)
+                    Velocity += (PlayerShip.Instance.Position - Position).ScaleTo(acceleration);
+
+                if (Velocity != Vector2.Zero)
+                    Orientation = Velocity.ToAngle();
+
+                yield return 0;
+            }
+        }
+
+        IEnumerable<int> MoveRandomly()
+        {
+            float direction = rand.NextFloat(0, MathHelper.TwoPi);
+
+            while (true)
+            {
+                direction += rand.NextFloat(-0.1f, 0.1f);
+                direction = MathHelper.WrapAngle(direction);
+
+                for (int i = 0; i < 6; i++)
+                {
+                    Velocity += MathUtil.FromPolar(direction, 0.4f);
+                    Orientation -= 0.05f;
+
+                    var bounds = GameRoot.ScreenBounds;
+                    bounds.Inflate(-image.Width / 2 - 1, -image.Height / 2 - 1);
+
+                    // if the enemy is outside the bounds, make it move away from the edge
+                    if (!bounds.Contains(Position))
+                        direction = (GameRoot.ScreenSize / 2 - Position).ToAngle() + rand.NextFloat(-MathHelper.PiOver2, MathHelper.PiOver2);
+
+                    yield return 0;
+                }
+            }
+        }
+        #endregion
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Enemy.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "f0363042bf66c001003a7c31f26aa2f8",
+	"CSharpImporter": null
+}

+ 54 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/EnemySpawner.cs

@@ -0,0 +1,54 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using System.Linq;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    static class EnemySpawner
+    {
+        static Random rand = new Random();
+        static float inverseSpawnChance = 90;
+        static float inverseBlackHoleChance = 600;
+
+        public static void Update()
+        {
+            if (!PlayerShip.Instance.IsDead && EntityManager.Count < 200)
+            {
+                if (rand.Next((int)inverseSpawnChance) == 0)
+                    EntityManager.Add(Enemy.CreateSeeker(GetSpawnPosition()));
+
+                if (rand.Next((int)inverseSpawnChance) == 0)
+                    EntityManager.Add(Enemy.CreateWanderer(GetSpawnPosition()));
+
+                if (EntityManager.BlackHoleCount < 2 && rand.Next((int)inverseBlackHoleChance) == 0)
+                    EntityManager.Add(new BlackHole(GetSpawnPosition()));
+            }
+
+            // slowly increase the spawn rate as time progresses
+            if (inverseSpawnChance > 30)
+                inverseSpawnChance -= 0.005f;
+        }
+
+        private static Vector2 GetSpawnPosition()
+        {
+            Vector2 pos;
+            do
+            {
+                pos = new Vector2(rand.Next((int)GameRoot.ScreenSize.X), rand.Next((int)GameRoot.ScreenSize.Y));
+            }
+            while (Vector2.DistanceSquared(pos, PlayerShip.Instance.Position) < 250 * 250);
+
+            return pos;
+        }
+
+        public static void Reset()
+        {
+            inverseSpawnChance = 90;
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/EnemySpawner.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "d7da1c881e8cb29faea2390cf75e3edd",
+	"CSharpImporter": null
+}

+ 36 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Entity.cs

@@ -0,0 +1,36 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    abstract class Entity
+    {
+        protected Texture2D image;
+        // The tint of the image. This will also allow us to change the transparency.
+        protected Color color = Color.White;
+
+        public Vector2 Position, Velocity;
+        public float Orientation;
+        public float Radius = 20;   // used for circular collision detection
+        public bool IsExpired;      // true if the entity was destroyed and should be deleted.
+
+        public Vector2 Size
+        {
+            get
+            {
+                return image == null ? Vector2.Zero : new Vector2(image.Width, image.Height);
+            }
+        }
+
+        public abstract void Update();
+
+        public virtual void Draw(/*SpriteBatch spriteBatch*/)
+        {
+            //SpriteBatch.Draw(image, Position, null, color, Orientation, Size / 2f, 1f, 0);
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Entity.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "188856ca1ec9eaae0bf1c4422ea3749c",
+	"CSharpImporter": null
+}

+ 152 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/EntityManager.cs

@@ -0,0 +1,152 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Linq;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    static class EntityManager
+    {
+        static List<Entity> entities = new List<Entity>();
+        static List<Enemy> enemies = new List<Enemy>();
+        static List<Bullet> bullets = new List<Bullet>();
+        static List<BlackHole> blackHoles = new List<BlackHole>();
+
+        public static IEnumerable<BlackHole> BlackHoles { get { return blackHoles; } }
+
+        static bool isUpdating;
+        static List<Entity> addedEntities = new List<Entity>();
+
+        public static int Count { get { return entities.Count; } }
+        public static int BlackHoleCount { get { return blackHoles.Count; } }
+
+        public static void Add(Entity entity)
+        {
+            if (!isUpdating)
+                AddEntity(entity);
+            else
+                addedEntities.Add(entity);
+        }
+
+        private static void AddEntity(Entity entity)
+        {
+            entities.Add(entity);
+            if (entity is Bullet)
+                bullets.Add(entity as Bullet);
+            else if (entity is Enemy)
+                enemies.Add(entity as Enemy);
+            else if (entity is BlackHole)
+                blackHoles.Add(entity as BlackHole);
+        }
+
+        public static void Update()
+        {
+            isUpdating = true;
+            HandleCollisions();
+
+            foreach (var entity in entities)
+                entity.Update();
+
+            isUpdating = false;
+
+            foreach (var entity in addedEntities)
+                AddEntity(entity);
+
+            addedEntities.Clear();
+
+            entities = entities.Where(x => !x.IsExpired).ToList();
+            bullets = bullets.Where(x => !x.IsExpired).ToList();
+            enemies = enemies.Where(x => !x.IsExpired).ToList();
+            blackHoles = blackHoles.Where(x => !x.IsExpired).ToList();
+        }
+
+        static void HandleCollisions()
+        {
+            // handle collisions between enemies
+            for (int i = 0; i < enemies.Count; i++)
+                for (int j = i + 1; j < enemies.Count; j++)
+                {
+                    if (IsColliding(enemies[i], enemies[j]))
+                    {
+                        enemies[i].HandleCollision(enemies[j]);
+                        enemies[j].HandleCollision(enemies[i]);
+                    }
+                }
+
+            // handle collisions between bullets and enemies
+            for (int i = 0; i < enemies.Count; i++)
+                for (int j = 0; j < bullets.Count; j++)
+                {
+                    if (IsColliding(enemies[i], bullets[j]))
+                    {
+                        enemies[i].WasShot();
+                        bullets[j].IsExpired = true;
+                    }
+                }
+
+            // handle collisions between the player and enemies
+            for (int i = 0; i < enemies.Count; i++)
+            {
+                if (enemies[i].IsActive && IsColliding(PlayerShip.Instance, enemies[i]))
+                {
+                    KillPlayer();
+                    break;
+                }
+            }
+
+            // handle collisions with black holes
+            for (int i = 0; i < blackHoles.Count; i++)
+            {
+                for (int j = 0; j < enemies.Count; j++)
+                    if (enemies[j].IsActive && IsColliding(blackHoles[i], enemies[j]))
+                        enemies[j].WasShot();
+
+                for (int j = 0; j < bullets.Count; j++)
+                {
+                    if (IsColliding(blackHoles[i], bullets[j]))
+                    {
+                        bullets[j].IsExpired = true;
+                        blackHoles[i].WasShot();
+                    }
+                }
+
+                if (IsColliding(PlayerShip.Instance, blackHoles[i]))
+                {
+                    KillPlayer();
+                    break;
+                }
+            }
+        }
+
+        private static void KillPlayer()
+        {
+            PlayerShip.Instance.Kill();
+            enemies.ForEach(x => x.WasShot());
+            blackHoles.ForEach(x => x.Kill());
+            EnemySpawner.Reset();
+        }
+
+        private static bool IsColliding(Entity a, Entity b)
+        {
+            float radius = a.Radius + b.Radius;
+            return !a.IsExpired && !b.IsExpired && Vector2.DistanceSquared(a.Position, b.Position) < radius * radius;
+        }
+
+        public static IEnumerable<Entity> GetNearbyEntities(Vector2 position, float radius)
+        {
+            return entities.Where(x => Vector2.DistanceSquared(position, x.Position) < radius * radius);
+        }
+
+        public static void Draw(/*SpriteBatch spriteBatch*/)
+        {
+            /*
+            foreach (var entity in entities)
+                entity.Draw(spriteBatch);
+                */
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/EntityManager.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "d92c4fd3d5d8ecfba455d1a5bf6f050b",
+	"CSharpImporter": null
+}

+ 42 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Extensions.cs

@@ -0,0 +1,42 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+	static class Extensions
+	{
+		public static float ToAngle(this Vector2 vector)
+		{
+			return (float)Math.Atan2(vector.Y, vector.X);
+		}
+
+		public static Vector2 ScaleTo(this Vector2 vector, float length)
+		{
+			return vector * (length / vector.Length);
+		}
+
+        /*
+		public static Point ToPoint(this Vector2 vector)
+		{
+			return new Point((int)vector.X, (int)vector.Y);
+		}
+        */
+
+		public static float NextFloat(this Random rand, float minValue, float maxValue)
+		{
+			return (float)rand.NextDouble() * (maxValue - minValue) + minValue;
+		}
+
+		public static Vector2 NextVector2(this Random rand, float minLength, float maxLength)
+		{
+			double theta = rand.NextDouble() * 2 * Math.PI;
+			float length = rand.NextFloat(minLength, maxLength);
+			return new Vector2(length * (float)Math.Cos(theta), length * (float)Math.Sin(theta));
+		}
+	}
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Extensions.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "132d3547d2f667431c06d6ee28d2f97e",
+	"CSharpImporter": null
+}

+ 86 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/GameRoot.cs

@@ -0,0 +1,86 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+using AtomicPlayer;
+
+namespace AtomicBlaster
+{
+
+    class GameRoot : NETScriptObject
+    {
+        public static Scene Scene { get; private set; }
+
+        public static float ElapsedTime { get; private set; }
+
+        public static Vector2 ScreenSize { get; private set; }
+        public static IntRect ScreenBounds { get; private set; }
+
+        public static Grid Grid { get; private set; }
+        public static ParticleManager<ParticleState> ParticleManager { get; private set; }
+
+        bool paused = false;
+
+        public GameRoot()
+        {
+            Art.Load();
+
+            var graphics = AtomicNET.GetSubsystem<Graphics>();
+
+            ScreenSize = new Vector2(graphics.Width, graphics.Height);
+
+            ScreenBounds = new IntRect(0, 0, (int)ScreenSize.X, (int)ScreenSize.Y);
+
+            ParticleManager = new ParticleManager<ParticleState>(1024 * 20, ParticleState.UpdateParticle);
+
+            const int maxGridPoints = 1600;
+            float amt = (float)Math.Sqrt(ScreenBounds.Width * ScreenBounds.Height / maxGridPoints);
+            Vector2 gridSpacing = new Vector2(amt, amt);
+            Grid = new Grid(ScreenBounds, gridSpacing);
+
+            EntityManager.Add(PlayerShip.Instance);
+
+            SubscribeToEvent("Update", HandleUpdate);
+
+            Scene = AtomicNET.GetSubsystem<Player>().LoadScene("Scenes/Scene.scene");
+
+            CustomRenderer.Initialize();
+
+        }
+
+        void HandleUpdate(uint eventType, ScriptVariantMap eventData)
+        {
+            float time = eventData.GetFloat("timestep");
+            ElapsedTime += time;
+
+            // Input.Update();
+
+            if (!paused)
+            {
+                PlayerStatus.Update();
+                EntityManager.Update();
+                EnemySpawner.Update();
+                ParticleManager.Update();
+                Grid.Update();
+            }
+
+            Draw();
+
+        }
+
+        void Draw()
+        {
+            EntityManager.Draw();
+
+            Grid.Draw();
+            ParticleManager.Draw();
+
+        }
+
+
+    }
+
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/GameRoot.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "25771f1f9fcddfa31f2cbf133bea6099",
+	"CSharpImporter": null
+}

+ 264 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Grid.cs

@@ -0,0 +1,264 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    public class Grid
+    {
+        class PointMass
+        {
+            public Vector3 Position;
+            public Vector3 Velocity;
+            public float InverseMass;
+
+            private Vector3 acceleration;
+            private float damping = 0.98f;
+
+            public PointMass(Vector3 position, float invMass)
+            {
+                Position = position;
+                InverseMass = invMass;
+            }
+
+            public void ApplyForce(Vector3 force)
+            {
+                acceleration += force * InverseMass;
+            }
+
+            public void IncreaseDamping(float factor)
+            {
+                damping *= factor;
+            }
+
+            public void Update()
+            {
+                Velocity += acceleration;
+                Position += Velocity;
+                acceleration = Vector3.Zero;
+                if (Velocity.LengthSquared < 0.001f * 0.001f)
+                    Velocity = Vector3.Zero;
+
+                Velocity *= damping;
+                damping = 0.98f;
+            }
+        }
+
+        struct Spring
+        {
+            public PointMass End1;
+            public PointMass End2;
+            public float TargetLength;
+            public float Stiffness;
+            public float Damping;
+
+            public Spring(PointMass end1, PointMass end2, float stiffness, float damping)
+            {
+                End1 = end1;
+                End2 = end2;
+                Stiffness = stiffness;
+                Damping = damping;
+                TargetLength = Vector3.Distance(end1.Position, end2.Position) * 0.95f;
+            }
+
+            public void Update()
+            {
+                var x = End1.Position - End2.Position;
+
+                float length = x.Length;
+                // these springs can only pull, not push
+                if (length <= TargetLength)
+                    return;
+
+                x = (x / length) * (length - TargetLength);
+                var dv = End2.Velocity - End1.Velocity;
+                var force = Stiffness * x - dv * Damping;
+
+                End1.ApplyForce(-force);
+                End2.ApplyForce(force);
+            }
+        }
+
+        Spring[] springs;
+        PointMass[,] points;
+        Vector2 screenSize;
+
+        public Grid(IntRect size, Vector2 spacing)
+        {
+            var springList = new List<Spring>();
+
+            int numColumns = (int)(size.Width / spacing.X) + 1;
+            int numRows = (int)(size.Height / spacing.Y) + 1;
+            points = new PointMass[numColumns, numRows];
+
+            // these fixed points will be used to anchor the grid to fixed positions on the screen
+            PointMass[,] fixedPoints = new PointMass[numColumns, numRows];
+
+            // create the point masses
+            int column = 0, row = 0;
+            for (float y = size.Top; y <= size.Bottom; y += spacing.Y)
+            {
+                for (float x = size.Left; x <= size.Right; x += spacing.X)
+                {
+                    points[column, row] = new PointMass(new Vector3(x, y, 0), 1);
+                    fixedPoints[column, row] = new PointMass(new Vector3(x, y, 0), 0);
+                    column++;
+                }
+                row++;
+                column = 0;
+            }
+
+            // link the point masses with springs
+            for (int y = 0; y < numRows; y++)
+                for (int x = 0; x < numColumns; x++)
+                {
+                    if (x == 0 || y == 0 || x == numColumns - 1 || y == numRows - 1)    // anchor the border of the grid
+                        springList.Add(new Spring(fixedPoints[x, y], points[x, y], 0.1f, 0.1f));
+                    else if (x % 3 == 0 && y % 3 == 0)                                  // loosely anchor 1/9th of the point masses
+                        springList.Add(new Spring(fixedPoints[x, y], points[x, y], 0.002f, 0.02f));
+
+                    const float stiffness = 0.28f;
+                    const float damping = 0.06f;
+
+                    if (x > 0)
+                        springList.Add(new Spring(points[x - 1, y], points[x, y], stiffness, damping));
+                    if (y > 0)
+                        springList.Add(new Spring(points[x, y - 1], points[x, y], stiffness, damping));
+                }
+
+            springs = springList.ToArray();
+        }
+
+        public void ApplyDirectedForce(Vector2 force, Vector2 position, float radius)
+        {
+            ApplyDirectedForce(new Vector3(force, 0), new Vector3(position, 0), radius);
+        }
+
+        public void ApplyDirectedForce(Vector3 force, Vector3 position, float radius)
+        {
+            foreach (var mass in points)
+                if (Vector3.DistanceSquared(position, mass.Position) < radius * radius)
+                    mass.ApplyForce(10 * force / (10 + Vector3.Distance(position, mass.Position)));
+        }
+
+        public void ApplyImplosiveForce(float force, Vector2 position, float radius)
+        {
+            ApplyImplosiveForce(force, new Vector3(position, 0), radius);
+        }
+
+        public void ApplyImplosiveForce(float force, Vector3 position, float radius)
+        {
+            foreach (var mass in points)
+            {
+                float dist2 = Vector3.DistanceSquared(position, mass.Position);
+                if (dist2 < radius * radius)
+                {
+                    mass.ApplyForce(10 * force * (position - mass.Position) / (100 + dist2));
+                    mass.IncreaseDamping(0.6f);
+                }
+            }
+        }
+
+        public void ApplyExplosiveForce(float force, Vector2 position, float radius)
+        {
+            ApplyExplosiveForce(force, new Vector3(position, 0), radius);
+        }
+
+        public void ApplyExplosiveForce(float force, Vector3 position, float radius)
+        {
+            foreach (var mass in points)
+            {
+                float dist2 = Vector3.DistanceSquared(position, mass.Position);
+                if (dist2 < radius * radius)
+                {
+                    mass.ApplyForce(100 * force * (mass.Position - position) / (10000 + dist2));
+                    mass.IncreaseDamping(0.6f);
+                }
+            }
+        }
+
+        public void Update()
+        {
+            foreach (var spring in springs)
+                spring.Update();
+
+            foreach (var mass in points)
+                mass.Update();
+        }
+
+        public void Draw(/*SpriteBatch spriteBatch*/)
+        {
+            /*
+            screenSize = GameRoot.ScreenSize;
+
+            int width = points.GetLength(0);
+            int height = points.GetLength(1);
+            Color color = new Color(30, 30, 139, 85);   // dark blue
+
+            for (int y = 1; y < height; y++)
+            {
+                for (int x = 1; x < width; x++)
+                {
+                    Vector2 left = new Vector2(), up = new Vector2();
+                    Vector2 p = ToVec2(points[x, y].Position);
+                    if (x > 1)
+                    {
+                        left = ToVec2(points[x - 1, y].Position);
+                        float thickness = y % 3 == 1 ? 3f : 1f;
+
+                        // use Catmull-Rom interpolation to help smooth bends in the grid
+                        int clampedX = Math.Min(x + 1, width - 1);
+                        Vector2 mid = Vector2.CatmullRom(ToVec2(points[x - 2, y].Position), left, p, ToVec2(points[clampedX, y].Position), 0.5f);
+
+                        // If the grid is very straight here, draw a single straight line. Otherwise, draw lines to our
+                        // new interpolated midpoint
+                        if (Vector2.DistanceSquared(mid, (left + p) / 2) > 1)
+                        {
+                            spriteBatch.DrawLine(left, mid, color, thickness);
+                            spriteBatch.DrawLine(mid, p, color, thickness);
+                        }
+                        else
+                            spriteBatch.DrawLine(left, p, color, thickness);
+                    }
+                    if (y > 1)
+                    {
+                        up = ToVec2(points[x, y - 1].Position);
+                        float thickness = x % 3 == 1 ? 3f : 1f;
+                        int clampedY = Math.Min(y + 1, height - 1);
+                        Vector2 mid = Vector2.CatmullRom(ToVec2(points[x, y - 2].Position), up, p, ToVec2(points[x, clampedY].Position), 0.5f);
+
+                        if (Vector2.DistanceSquared(mid, (up + p) / 2) > 1)
+                        {
+                            spriteBatch.DrawLine(up, mid, color, thickness);
+                            spriteBatch.DrawLine(mid, p, color, thickness);
+                        }
+                        else
+                            spriteBatch.DrawLine(up, p, color, thickness);
+                    }
+
+                    // Add interpolated lines halfway between our point masses. This makes the grid look
+                    // denser without the cost of simulating more springs and point masses.
+                    if (x > 1 && y > 1)
+                    {
+                        Vector2 upLeft = ToVec2(points[x - 1, y - 1].Position);
+                        spriteBatch.DrawLine(0.5f * (upLeft + up), 0.5f * (left + p), color, 1f);   // vertical line
+                        spriteBatch.DrawLine(0.5f * (upLeft + left), 0.5f * (up + p), color, 1f);   // horizontal line
+                    }
+                }
+            }
+            */
+        }
+
+        public Vector2 ToVec2(Vector3 v)
+        {
+            // do a perspective projection
+            float factor = (v.Z + 2000) / 2000;
+            return (new Vector2(v.X, v.Y) - screenSize / 2f) * factor + screenSize / 2;
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Grid.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "b57f8db3b8226dcbd398c07340f1476c",
+	"CSharpImporter": null
+}

+ 18 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/MathUtil.cs

@@ -0,0 +1,18 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    static class MathUtil
+    {
+        public static Vector2 FromPolar(float angle, float magnitude)
+        {
+            return magnitude * new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/MathUtil.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "6999c6c9047718fbbf0336969d82b79e",
+	"CSharpImporter": null
+}

+ 165 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/ParticleManager.cs

@@ -0,0 +1,165 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    public class ParticleManager<T>
+    {
+        // This delegate will be called for each particle.
+        private Action<Particle> updateParticle;
+        private CircularParticleArray particleList;
+
+        /// <summary>
+        /// Allows creation of particles.
+        /// </summary>
+        /// <param name="capacity">The maximum number of particles. An array of this size will be pre-allocated.</param>
+        /// <param name="updateParticle">A delegate that lets you specify custom behaviour for your particles. Called once per particle, per frame.</param>
+        public ParticleManager(int capacity, Action<Particle> updateParticle)
+        {
+            this.updateParticle = updateParticle;
+            particleList = new CircularParticleArray(capacity);
+
+            // Populate the list with empty particle objects, for reuse.
+            for (int i = 0; i < capacity; i++)
+                particleList[i] = new Particle();
+        }
+
+        /// <summary>
+        /// Update particle state, to be called every frame.
+        /// </summary>
+        public void Update()
+        {
+            int removalCount = 0;
+            for (int i = 0; i < particleList.Count; i++)
+            {
+                var particle = particleList[i];
+
+                updateParticle(particle);
+
+                particle.PercentLife -= 1f / particle.Duration;
+
+                // sift deleted particles to the end of the list
+                Swap(particleList, i - removalCount, i);
+
+                // if the alpha < 0, delete this particle
+                if (particle.PercentLife < 0)
+                    removalCount++;
+            }
+            particleList.Count -= removalCount;
+        }
+
+        private static void Swap(CircularParticleArray list, int index1, int index2)
+        {
+            var temp = list[index1];
+            list[index1] = list[index2];
+            list[index2] = temp;
+        }
+
+        /// <summary>
+        /// Draw the particles.
+        /// </summary>
+        public void Draw(/*SpriteBatch spriteBatch*/)
+        {
+            for (int i = 0; i < particleList.Count; i++)
+            {
+                var particle = particleList[i];
+
+                Vector2 origin = new Vector2(particle.Texture.Width / 2, particle.Texture.Height / 2);
+                //spriteBatch.Draw(particle.Texture, particle.Position, null, particle.Tint, particle.Orientation, origin, particle.Scale, 0, 0);
+            }
+        }
+
+        public void CreateParticle(Texture2D texture, Vector2 position, Color tint, float duration, float scale, T state, float theta = 0)
+        {
+            CreateParticle(texture, position, tint, duration, new Vector2(scale, scale), state, theta);
+        }
+
+        public void CreateParticle(Texture2D texture, Vector2 position, Color tint, float duration, Vector2 scale, T state, float theta = 0)
+        {
+            Particle particle;
+            if (particleList.Count == particleList.Capacity)
+            {
+                // if the list is full, overwrite the oldest particle, and rotate the circular list
+                particle = particleList[0];
+                particleList.Start++;
+            }
+            else
+            {
+                particle = particleList[particleList.Count];
+                particleList.Count++;
+            }
+
+            // Create the particle
+            particle.Texture = texture;
+            particle.Position = position;
+            particle.Tint = tint;
+
+            particle.Duration = duration;
+            particle.PercentLife = 1f;
+            particle.Scale = scale;
+            particle.Orientation = theta;
+            particle.State = state;
+        }
+
+        /// <summary>
+        /// Destroys all particles
+        /// </summary>
+        public void Clear()
+        {
+            particleList.Count = 0;
+        }
+
+        public int ParticleCount
+        {
+            get { return particleList.Count; }
+        }
+
+        public class Particle
+        {
+            public Texture2D Texture;
+            public Vector2 Position;
+            public float Orientation;
+
+            public Vector2 Scale = Vector2.One;
+
+            public Color Tint;
+            public float Duration;
+            public float PercentLife = 1f;
+            public T State;
+        }
+
+        // Represents a circular array with an arbitrary starting point. It's useful for efficiently overwriting
+        // the oldest particles when the array gets full. Simply overwrite particleList[0] and advance Start.
+        private class CircularParticleArray
+        {
+            private int start;
+            public int Start
+            {
+                get { return start; }
+                set { start = value % list.Length; }
+            }
+
+            public int Count { get; set; }
+            public int Capacity { get { return list.Length; } }
+            private Particle[] list;
+
+            public CircularParticleArray() { }  // for serialization
+
+            public CircularParticleArray(int capacity)
+            {
+                list = new Particle[capacity];
+            }
+
+            public Particle this[int i]
+            {
+                get { return list[(start + i) % list.Length]; }
+                set { list[(start + i) % list.Length] = value; }
+            }
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/ParticleManager.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "5af8c26c4ae3466e5705fcebfce3c1b4",
+	"CSharpImporter": null
+}

+ 101 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/ParticleState.cs

@@ -0,0 +1,101 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    public enum ParticleType { None, Enemy, Bullet, IgnoreGravity }
+
+    public struct ParticleState
+    {
+        public Vector2 Velocity;
+        public ParticleType Type;
+        public float LengthMultiplier;
+
+        private static Random rand = new Random();
+
+        public ParticleState(Vector2 velocity, ParticleType type, float lengthMultiplier = 1f)
+        {
+            Velocity = velocity;
+            Type = type;
+            LengthMultiplier = lengthMultiplier;
+        }
+
+        public static ParticleState GetRandom(float minVel, float maxVel)
+        {
+            var state = new ParticleState();
+            state.Velocity = rand.NextVector2(minVel, maxVel);
+            state.Type = ParticleType.None;
+            state.LengthMultiplier = 1;
+
+            return state;
+        }
+
+        public static void UpdateParticle(ParticleManager<ParticleState>.Particle particle)
+        {
+            var vel = particle.State.Velocity;
+            float speed = vel.Length;
+
+            // using Vector2.Add() should be slightly faster than doing "x.Position += vel;" because the Vector2s
+            // are passed by reference and don't need to be copied. Since we may have to update a very large 
+            // number of particles, this method is a good candidate for optimizations.
+            Vector2.Add(ref particle.Position, ref vel, out particle.Position);
+
+            // fade the particle if its PercentLife or speed is low.
+            float alpha = Math.Min(1, Math.Min(particle.PercentLife * 2, speed * 1f));
+            alpha *= alpha;
+
+            particle.Tint.A = alpha;
+
+            // the length of bullet particles will be less dependent on their speed than other particles
+            if (particle.State.Type == ParticleType.Bullet)
+                particle.Scale.X = particle.State.LengthMultiplier * Math.Min(Math.Min(1f, 0.1f * speed + 0.1f), alpha);
+            else
+                particle.Scale.X = particle.State.LengthMultiplier * Math.Min(Math.Min(1f, 0.2f * speed + 0.1f), alpha);
+
+            particle.Orientation = vel.ToAngle();
+
+            var pos = particle.Position;
+            int width = (int)GameRoot.ScreenSize.X;
+            int height = (int)GameRoot.ScreenSize.Y;
+
+            // collide with the edges of the screen
+            if (pos.X < 0)
+                vel.X = Math.Abs(vel.X);
+            else if (pos.X > width)
+                vel.X = -Math.Abs(vel.X);
+            if (pos.Y < 0)
+                vel.Y = Math.Abs(vel.Y);
+            else if (pos.Y > height)
+                vel.Y = -Math.Abs(vel.Y);
+
+            if (particle.State.Type != ParticleType.IgnoreGravity)
+            {
+                foreach (var blackHole in EntityManager.BlackHoles)
+                {
+                    var dPos = blackHole.Position - pos;
+                    float distance = dPos.Length;
+                    var n = dPos / distance;
+                    vel += 10000 * n / (distance * distance + 10000);
+
+                    // add tangential acceleration for nearby particles
+                    if (distance < 400)
+                        vel += 45 * new Vector2(n.Y, -n.X) / (distance + 100);
+                }
+            }
+
+            if (Math.Abs(vel.X) + Math.Abs(vel.Y) < 0.00000000001f) // denormalized floats cause significant performance issues
+                vel = Vector2.Zero;
+            else if (particle.State.Type == ParticleType.Enemy)
+                vel *= 0.94f;
+            else
+                vel *= 0.96f + Math.Abs(pos.X) % 0.04f; // rand.Next() isn't thread-safe, so use the position for pseudo-randomness
+
+            particle.State.Velocity = vel;
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/ParticleState.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "66fea41169547275e5322aceb2bd6ec4",
+	"CSharpImporter": null
+}

+ 163 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/PlayerShip.cs

@@ -0,0 +1,163 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    class PlayerShip : Entity
+    {
+        private static PlayerShip instance;
+        public static PlayerShip Instance
+        {
+            get
+            {
+                if (instance == null)
+                    instance = new PlayerShip();
+
+                return instance;
+            }
+        }
+
+        const int cooldownFrames = 6;
+        int cooldowmRemaining = 0;
+
+        int framesUntilRespawn = 0;
+        public bool IsDead { get { return framesUntilRespawn > 0; } }
+
+        static Random rand = new Random();
+
+        private PlayerShip()
+        {
+            image = Art.Player;
+            Position = GameRoot.ScreenSize / 2;
+            Radius = 10;
+        }
+
+        public override void Update()
+        {
+            if (IsDead)
+            {
+                if (--framesUntilRespawn == 0)
+                {
+                    if (PlayerStatus.Lives == 0)
+                    {
+                        PlayerStatus.Reset();
+                        Position = GameRoot.ScreenSize / 2;
+                    }
+                    GameRoot.Grid.ApplyDirectedForce(new Vector3(0, 0, 5000), new Vector3(Position.X, Position.Y, 0), 50);
+                }
+
+                return;
+            }
+
+            var aim = new Vector2(); // Input.GetAimDirection();
+
+            if (aim.LengthSquared > 0 && cooldowmRemaining <= 0)
+            {
+                cooldowmRemaining = cooldownFrames;
+                float aimAngle = aim.ToAngle();
+                Quaternion aimQuat = Quaternion.CreateFromYawPitchRoll(0, 0, aimAngle);
+
+                float randomSpread = rand.NextFloat(-0.04f, 0.04f) + rand.NextFloat(-0.04f, 0.04f);
+                Vector2 vel = MathUtil.FromPolar(aimAngle + randomSpread, 11f);
+
+                Vector2 offset = Vector2.Transform(new Vector2(35, -8), aimQuat);
+                EntityManager.Add(new Bullet(Position + offset, vel));
+
+                offset = Vector2.Transform(new Vector2(35, 8), aimQuat);
+                EntityManager.Add(new Bullet(Position + offset, vel));
+
+                // Sound.Shot.Play(0.2f, rand.NextFloat(-0.2f, 0.2f), 0);
+            }
+
+            if (cooldowmRemaining > 0)
+                cooldowmRemaining--;
+
+            const float speed = 8;
+
+            //Velocity += speed * Input.GetMovementDirection();
+
+            Position += Velocity;
+            Position = Vector2.Clamp(Position, Size / 2, GameRoot.ScreenSize - Size / 2);
+
+            if (Velocity.LengthSquared > 0)
+                Orientation = Velocity.ToAngle();
+
+            MakeExhaustFire();
+            Velocity = Vector2.Zero;
+        }
+
+        private void MakeExhaustFire()
+        {
+            if (Velocity.LengthSquared > 0.1f)
+            {
+                // set up some variables
+                Orientation = Velocity.ToAngle();
+                Quaternion rot = Quaternion.CreateFromYawPitchRoll(0f, 0f, Orientation);
+
+                double t = GameRoot.ElapsedTime;
+                // The primary velocity of the particles is 3 pixels/frame in the direction opposite to which the ship is travelling.
+                Vector2 baseVel = Velocity.ScaleTo(-3);
+                // Calculate the sideways velocity for the two side streams. The direction is perpendicular to the ship's velocity and the
+                // magnitude varies sinusoidally.
+                Vector2 perpVel = new Vector2(baseVel.Y, -baseVel.X) * (0.6f * (float)Math.Sin(t * 10));
+                Color sideColor = new Color(200, 38, 9);    // deep red
+                Color midColor = new Color(255, 187, 30);   // orange-yellow
+                Vector2 pos = Position + Vector2.Transform(new Vector2(-25, 0), rot);   // position of the ship's exhaust pipe.
+                const float alpha = 0.7f;
+
+                // middle particle stream
+                Vector2 velMid = baseVel + rand.NextVector2(0, 1);
+                GameRoot.ParticleManager.CreateParticle(Art.LineParticle, pos, Color.White * alpha, 60f, new Vector2(0.5f, 1),
+                    new ParticleState(velMid, ParticleType.Enemy));
+                GameRoot.ParticleManager.CreateParticle(Art.Glow, pos, midColor * alpha, 60f, new Vector2(0.5f, 1),
+                    new ParticleState(velMid, ParticleType.Enemy));
+
+                // side particle streams
+                Vector2 vel1 = baseVel + perpVel + rand.NextVector2(0, 0.3f);
+                Vector2 vel2 = baseVel - perpVel + rand.NextVector2(0, 0.3f);
+                GameRoot.ParticleManager.CreateParticle(Art.LineParticle, pos, Color.White * alpha, 60f, new Vector2(0.5f, 1),
+                    new ParticleState(vel1, ParticleType.Enemy));
+                GameRoot.ParticleManager.CreateParticle(Art.LineParticle, pos, Color.White * alpha, 60f, new Vector2(0.5f, 1),
+                    new ParticleState(vel2, ParticleType.Enemy));
+
+                GameRoot.ParticleManager.CreateParticle(Art.Glow, pos, sideColor * alpha, 60f, new Vector2(0.5f, 1),
+                    new ParticleState(vel1, ParticleType.Enemy));
+                GameRoot.ParticleManager.CreateParticle(Art.Glow, pos, sideColor * alpha, 60f, new Vector2(0.5f, 1),
+                    new ParticleState(vel2, ParticleType.Enemy));
+            }
+        }
+
+        public override void Draw(/*SpriteBatch spriteBatch*/)
+        {
+            if (!IsDead)
+                base.Draw();
+        }
+
+        public void Kill()
+        {
+            PlayerStatus.RemoveLife();
+            framesUntilRespawn = PlayerStatus.IsGameOver ? 300 : 120;
+
+            Color explosionColor = new Color(0.8f, 0.8f, 0.4f); // yellow
+
+            for (int i = 0; i < 1200; i++)
+            {
+                float speed = 18f * (1f - 1 / rand.NextFloat(1f, 10f));
+                Color color = Color.Lerp(Color.White, explosionColor, rand.NextFloat(0, 1));
+                var state = new ParticleState()
+                {
+                    Velocity = rand.NextVector2(speed, speed),
+                    Type = ParticleType.None,
+                    LengthMultiplier = 1
+                };
+
+                GameRoot.ParticleManager.CreateParticle(Art.LineParticle, Position, color, 190, 1.5f, state);
+            }
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/PlayerShip.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "fdcc3cd188658c0b5abd776316df709a",
+	"CSharpImporter": null
+}

+ 86 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/PlayerStatus.cs

@@ -0,0 +1,86 @@
+//---------------------------------------------------------------------------------
+// Written by Michael Hoffman
+// Find the full tutorial at: http://gamedev.tutsplus.com/series/vector-shooter-xna/
+//----------------------------------------------------------------------------------
+
+using AtomicEngine;
+using System.IO;
+
+namespace AtomicBlaster
+{
+    static class PlayerStatus
+    {
+        // amount of time it takes, in seconds, for a multiplier to expire.
+        private const float multiplierExpiryTime = 0.8f;
+        private const int maxMultiplier = 20;
+
+        public static int Lives { get; private set; }
+        public static int Score { get; private set; }
+        public static int Multiplier { get; private set; }
+        public static bool IsGameOver { get { return Lives == 0; } }
+
+        private static float multiplierTimeLeft;    // time until the current multiplier expires
+        private static int scoreForExtraLife;       // score required to gain an extra life
+
+        // Static constructor
+        static PlayerStatus()
+        {
+            Reset();
+        }
+
+        public static void Reset()
+        {
+            Score = 0;
+            Multiplier = 1;
+            Lives = 4;
+            scoreForExtraLife = 2000;
+            multiplierTimeLeft = 0;
+        }
+
+        public static void Update()
+        {
+            if (Multiplier > 1)
+            {
+                // update the multiplier timer
+                if ((multiplierTimeLeft -= (float)GameRoot.ElapsedTime) <= 0)
+                {
+                    multiplierTimeLeft = multiplierExpiryTime;
+                    ResetMultiplier();
+                }
+            }
+        }
+
+        public static void AddPoints(int basePoints)
+        {
+            if (PlayerShip.Instance.IsDead)
+                return;
+
+            Score += basePoints * Multiplier;
+            while (Score >= scoreForExtraLife)
+            {
+                scoreForExtraLife += 2000;
+                Lives++;
+            }
+        }
+
+        public static void IncreaseMultiplier()
+        {
+            if (PlayerShip.Instance.IsDead)
+                return;
+
+            multiplierTimeLeft = multiplierExpiryTime;
+            if (Multiplier < maxMultiplier)
+                Multiplier++;
+        }
+
+        public static void ResetMultiplier()
+        {
+            Multiplier = 1;
+        }
+
+        public static void RemoveLife()
+        {
+            Lives--;
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/PlayerStatus.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "80cc5d508d95dd70be898a5260bed2f0",
+	"CSharpImporter": null
+}

+ 18 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Program.cs

@@ -0,0 +1,18 @@
+using System;
+using AtomicEngine;
+
+namespace AtomicBlaster
+{
+    public static class AtomicMain
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        static void Main(string[] args)
+        {
+
+            new GameRoot();
+            
+        }
+    }
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Program.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "c667cc2d9ce0c1ba072e9d64aa63e00a",
+	"CSharpImporter": null
+}

+ 0 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Sound.cs


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Scripts/Sound.cs.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "3ba82776e492d4d5fcfd232a3c46819a",
+	"CSharpImporter": null
+}

+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "0db336c2bb0a71d4da237389c1dc8085",
+	"FolderImporter": {}
+}

+ 157 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/AtomicBlasterSprites.plist

@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+    <dict>
+        <key>frames</key>
+        <dict>
+            <key>BlackHole.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{40,40}</string>
+                <key>spriteSourceSize</key>
+                <string>{40,40}</string>
+                <key>textureRect</key>
+                <string>{{1,1},{40,40}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Bullet.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{28,9}</string>
+                <key>spriteSourceSize</key>
+                <string>{28,9}</string>
+                <key>textureRect</key>
+                <string>{{43,1},{28,9}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Glow.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{35,20}</string>
+                <key>spriteSourceSize</key>
+                <string>{35,20}</string>
+                <key>textureRect</key>
+                <string>{{73,1},{35,20}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Laser.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{22,2}</string>
+                <key>spriteSourceSize</key>
+                <string>{22,2}</string>
+                <key>textureRect</key>
+                <string>{{1,43},{22,2}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Pixel.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{16,16}</string>
+                <key>spriteSourceSize</key>
+                <string>{16,16}</string>
+                <key>textureRect</key>
+                <string>{{25,43},{16,16}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Player.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{40,40}</string>
+                <key>spriteSourceSize</key>
+                <string>{40,40}</string>
+                <key>textureRect</key>
+                <string>{{43,43},{40,40}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Pointer.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{22,31}</string>
+                <key>spriteSourceSize</key>
+                <string>{22,31}</string>
+                <key>textureRect</key>
+                <string>{{85,43},{22,31}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Seeker.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{40,32}</string>
+                <key>spriteSourceSize</key>
+                <string>{40,40}</string>
+                <key>textureRect</key>
+                <string>{{1,85},{40,32}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+            <key>Wanderer.png</key>
+            <dict>
+                <key>aliases</key>
+                <array/>
+                <key>spriteOffset</key>
+                <string>{0,0}</string>
+                <key>spriteSize</key>
+                <string>{40,40}</string>
+                <key>spriteSourceSize</key>
+                <string>{40,40}</string>
+                <key>textureRect</key>
+                <string>{{43,85},{40,40}}</string>
+                <key>textureRotated</key>
+                <false/>
+            </dict>
+        </dict>
+        <key>metadata</key>
+        <dict>
+            <key>format</key>
+            <integer>3</integer>
+            <key>realTextureFileName</key>
+            <string>AtomicBlasterSprites.png</string>
+            <key>size</key>
+            <string>{128,128}</string>
+            <key>smartupdate</key>
+            <string>$TexturePacker:SmartUpdate:239e49e98f80103e023f0c0a3ec4cf99:ef38c18e0c31ec79c71fe241a3e0b58c:ab24a4a6a71b325297f3a046ad1ecd48$</string>
+            <key>textureFileName</key>
+            <string>AtomicBlasterSprites.png</string>
+        </dict>
+    </dict>
+</plist>

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/AtomicBlasterSprites.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/AtomicBlasterSprites.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "8544c43203a051e2153d4be7b88cbefc",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/BlackHole.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/BlackHole.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "d1cd069c77c523d8fe95ca3cfaa34a65",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Bullet.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Bullet.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "9e5ffb024e1fc627634b021f2fcbcf8b",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Glow.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Glow.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "a07df9467c7cf95737e58d2754a92b24",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Laser.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Laser.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "ec31b801fb2f53fd6438a028372866de",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Pixel.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Pixel.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "8a897903859a1ced48d2629264c1d21a",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Player.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Player.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "dd6e6adb13bfe21f701da3bc8f1f6528",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Pointer.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Pointer.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "c8e579b9cb25fd507679321a483134bb",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Seeker.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Seeker.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "1593f0db6699f5483081cef28cf01183",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/Wanderer.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/Wanderer.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "fafe1cd29166750cccbbd4e22b55acd2",
+	"TextureImporter": {}
+}

BIN
AtomicNET/AtomicBlaster/Resources/Sprites/star.png


+ 5 - 0
AtomicNET/AtomicBlaster/Resources/Sprites/star.png.asset

@@ -0,0 +1,5 @@
+{
+	"version": 1,
+	"guid": "31d5e005cabe27f60647087063a464c5",
+	"TextureImporter": {}
+}

+ 1 - 1
AtomicNET/Physics2D/Resources/Components/PhysicsSpawner.cs

@@ -24,7 +24,7 @@ public class PhysicsSpawner : CSComponent
         // Set box size
         // Set box size
         groundShape.Size = new Vector2(0.32f, 0.32f);
         groundShape.Size = new Vector2(0.32f, 0.32f);
         // Set friction
         // Set friction
-        groundShape.Friction = 0.5f;
+        groundShape.Friction = 0.5f; 
 
 
     }
     }
 
 

+ 3 - 2
AtomicNET/Physics2D/Resources/Scenes/TheScene.scene

@@ -5,8 +5,8 @@
 	<attribute name="Smoothing Constant" value="50" />
 	<attribute name="Smoothing Constant" value="50" />
 	<attribute name="Snap Threshold" value="5" />
 	<attribute name="Snap Threshold" value="5" />
 	<attribute name="Elapsed Time" value="0" />
 	<attribute name="Elapsed Time" value="0" />
-	<attribute name="Next Replicated Node ID" value="369" />
-	<attribute name="Next Replicated Component ID" value="1982" />
+	<attribute name="Next Replicated Node ID" value="370" />
+	<attribute name="Next Replicated Component ID" value="1983" />
 	<attribute name="Next Local Node ID" value="16778496" />
 	<attribute name="Next Local Node ID" value="16778496" />
 	<attribute name="Next Local Component ID" value="16777216" />
 	<attribute name="Next Local Component ID" value="16777216" />
 	<attribute name="Variables" />
 	<attribute name="Variables" />
@@ -14,6 +14,7 @@
 	<component type="Octree" id="2" />
 	<component type="Octree" id="2" />
 	<component type="DebugRenderer" id="3" />
 	<component type="DebugRenderer" id="3" />
 	<component type="PhysicsWorld2D" id="1977">
 	<component type="PhysicsWorld2D" id="1977">
+		<attribute name="Draw Shape" value="true" />
 		<attribute name="Allow Sleeping" value="true" />
 		<attribute name="Allow Sleeping" value="true" />
 		<attribute name="Warm Starting" value="true" />
 		<attribute name="Warm Starting" value="true" />
 		<attribute name="Auto Clear Forces" value="true" />
 		<attribute name="Auto Clear Forces" value="true" />