diff --git a/DotRPG.sln b/DotRPG.sln
index ac8b3c8..87d2f42 100644
--- a/DotRPG.sln
+++ b/DotRPG.sln
@@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotRPG.Example", "_Example\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotRPG.Objects.Complexity", "Objects\Complexity\DotRPG.Objects.Complexity.csproj", "{A5B3FC78-C694-440E-9D99-7CE4FA6A01AC}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotRPG.Objects.Dynamics", "Objects\Dynamics\DotRPG.Objects.Dynamics.csproj", "{35012066-AC4B-4144-90C9-7F42681652C8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
{A5B3FC78-C694-440E-9D99-7CE4FA6A01AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5B3FC78-C694-440E-9D99-7CE4FA6A01AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5B3FC78-C694-440E-9D99-7CE4FA6A01AC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {35012066-AC4B-4144-90C9-7F42681652C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {35012066-AC4B-4144-90C9-7F42681652C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {35012066-AC4B-4144-90C9-7F42681652C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {35012066-AC4B-4144-90C9-7F42681652C8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Objects/DotRPG.Objects.csproj b/Objects/DotRPG.Objects.csproj
index 3b5929a..4e9ca0b 100644
--- a/Objects/DotRPG.Objects.csproj
+++ b/Objects/DotRPG.Objects.csproj
@@ -13,6 +13,14 @@
x64
+
+
+
+
+
+
+
+
diff --git a/Objects/Dynamics/DotRPG.Objects.Dynamics.csproj b/Objects/Dynamics/DotRPG.Objects.Dynamics.csproj
new file mode 100644
index 0000000..60df15c
--- /dev/null
+++ b/Objects/Dynamics/DotRPG.Objects.Dynamics.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
diff --git a/Objects/Dynamics/DynamicRectObject.cs b/Objects/Dynamics/DynamicRectObject.cs
new file mode 100644
index 0000000..26443e5
--- /dev/null
+++ b/Objects/Dynamics/DynamicRectObject.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using DotRPG.Objects;
+
+namespace DotRPG.Objects.Dynamics
+{
+ public class DynamicRectObject
+ {
+ public Boolean Static;
+ public Vector2 Location;
+ protected Point BodySize;
+ public SpriteController Sprite;
+ public Rectangle Collider
+ {
+ get
+ {
+ return new Rectangle
+ (
+ (int)Location.X - BodySize.X / 2,
+ (int)Location.Y - BodySize.Y / 2,
+ BodySize.X,
+ BodySize.Y
+ );
+ }
+ }
+ ///
+ /// Vector value which describes how much body will travel (pts/s)
+ ///
+ public Vector2 Velocity;
+ public Single Mass;
+ public Vector2 AppliedForce = Vector2.Zero;
+
+ public Single KineticEnergy
+ {
+ get
+ {
+ return Mass * (Single)Math.Pow(Velocity.Length(), 2) / 2.0f;
+ }
+ }
+ public Vector2 Momentum
+ {
+ get
+ {
+ return new Vector2(Velocity.X * Mass, Velocity.Y * Mass);
+ }
+ }
+ public DynamicRectObject(Point StartLocation, Point colliderSize, Single mass)
+ {
+ Location = StartLocation.ToVector2();
+ BodySize = colliderSize;
+ Mass = mass;
+ }
+
+ public void CollideWith(DynamicRectObject another, Boolean hitVertically)
+ {
+ if (another.Static)
+ {
+ this.Velocity = new Vector2(!hitVertically ? 0.0f : this.Velocity.X, hitVertically ? 0.0f : this.Velocity.Y);
+ if (hitVertically)
+ {
+ if (this.Location.Y >= another.Location.Y)
+ {
+ this.Location.Y += Math.Max((this.BodySize.Y / 2 + another.BodySize.Y / 2) - Math.Abs(this.Location.Y - another.Location.Y), 0);
+ }
+ else
+ {
+ this.Location.Y -= Math.Max((this.BodySize.Y / 2 + another.BodySize.Y / 2) - Math.Abs(this.Location.Y - another.Location.Y), 0);
+ }
+ }
+ else
+ {
+ if (this.Location.X >= another.Location.X)
+ {
+ this.Location.X += Math.Max((this.BodySize.X / 2 + another.BodySize.X / 2) - Math.Abs(this.Location.X - another.Location.X), 0);
+ }
+ else
+ {
+ this.Location.X -= Math.Max((this.BodySize.X / 2 + another.BodySize.X / 2) - Math.Abs(this.Location.X - another.Location.X), 0);
+ }
+ }
+ return;
+ }
+ Single Summary_X_Momentum = (this.Momentum.X + another.Momentum.X) / 2;
+ Single Summary_Y_Momentum = (this.Momentum.Y + another.Momentum.Y) / 2;
+
+ if (hitVertically)
+ {
+ this.Velocity = new Vector2(this.Velocity.X, Summary_Y_Momentum / this.Mass);
+ another.Velocity = new Vector2(another.Velocity.X, Summary_Y_Momentum / another.Mass);
+ if (this.Mass > another.Mass)
+ {
+ if (this.Location.Y >= another.Location.Y)
+ {
+ another.Location.Y -= Math.Max((this.BodySize.Y / 2 + another.BodySize.Y / 2) - Math.Abs(this.Location.Y - another.Location.Y), 0);
+ }
+ else
+ {
+ another.Location.Y += Math.Max((this.BodySize.Y / 2 + another.BodySize.Y / 2) - Math.Abs(this.Location.Y - another.Location.Y), 0);
+ }
+ }
+ else
+ {
+ if (this.Location.Y >= another.Location.Y)
+ {
+ this.Location.Y += Math.Max((this.BodySize.Y / 2 + another.BodySize.Y / 2) - Math.Abs(this.Location.Y - another.Location.Y), 0);
+ }
+ else
+ {
+ this.Location.Y -= Math.Max((this.BodySize.Y / 2 + another.BodySize.Y / 2) - Math.Abs(this.Location.Y - another.Location.Y), 0);
+ }
+ }
+ }
+ else
+ {
+ this.Velocity = new Vector2(Summary_X_Momentum / this.Mass, this.Velocity.Y);
+ another.Velocity = new Vector2(Summary_X_Momentum / another.Mass, another.Velocity.Y);
+ if (this.Mass > another.Mass)
+ {
+ if (this.Location.X >= another.Location.X)
+ {
+ another.Location.X -= Math.Max((this.BodySize.X / 2 + another.BodySize.X / 2) - Math.Abs(this.Location.X - another.Location.X), 0);
+ }
+ else
+ {
+ another.Location.X += Math.Max((this.BodySize.X / 2 + another.BodySize.X / 2) - Math.Abs(this.Location.X - another.Location.X), 0);
+ }
+ }
+ else
+ {
+ if (this.Location.X >= another.Location.X)
+ {
+ this.Location.X += Math.Max((this.BodySize.X / 2 + another.BodySize.X / 2) - Math.Abs(this.Location.X - another.Location.X), 0);
+ }
+ else
+ {
+ this.Location.X -= Math.Max((this.BodySize.X / 2 + another.BodySize.X / 2) - Math.Abs(this.Location.X - another.Location.X), 0);
+ }
+ }
+ }
+ }
+
+ public void Draw(SpriteBatch _sb, GameTime gameTime, Int32 VirtualVSize, Point scrollOffset, Point scrollSize)
+ {
+ Single sizeMorph = 1.0f * scrollSize.Y / VirtualVSize;
+ Vector2 location = new Vector2
+ (
+ Location.X * sizeMorph - (BodySize.X * sizeMorph / 2) - scrollOffset.X * sizeMorph,
+ Location.Y * sizeMorph - (BodySize.Y * sizeMorph / 2) - scrollOffset.Y * sizeMorph
+ );
+ Sprite.Draw(_sb, location, gameTime, sizeMorph);
+ }
+
+ public Boolean TryCollideWith(DynamicRectObject another)
+ {
+ if (this.Collider.Intersects(another.Collider))
+ {
+ if (1.0 * Math.Abs(this.Location.X - another.Location.X) / (this.BodySize.X / 2 + another.BodySize.X / 2) >= 1.0 * Math.Abs(this.Location.Y - another.Location.Y) / (this.BodySize.Y / 2 + another.BodySize.Y / 2))
+ {
+ CollideWith(another, false);
+ }
+ else
+ {
+ CollideWith(another, true);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void Update(GameTime gameTime)
+ {
+ Velocity += AppliedForce / ((Single)gameTime.ElapsedGameTime.TotalSeconds * this.Mass);
+ Location += Velocity / (Single)gameTime.ElapsedGameTime.TotalSeconds;
+ AppliedForce = Vector2.Zero;
+ }
+
+ public void FullStop()
+ {
+ Velocity = Vector2.Zero;
+ }
+ }
+}
diff --git a/Objects/SpriteController.cs b/Objects/SpriteController.cs
index 7263371..4ad63b1 100644
--- a/Objects/SpriteController.cs
+++ b/Objects/SpriteController.cs
@@ -55,7 +55,7 @@ public void AddAnimationSequence(String sequenceName, Texture2D frames, UInt16 f
LoopTo.Add(sequenceName, loopTo);
}
- public void Draw(SpriteBatch _sb, Vector2 drawLocation, GameTime gameTime)
+ public void Draw(SpriteBatch _sb, Vector2 drawLocation, GameTime gameTime, Single drawSize = 1.0f)
{
Single addFrames = 0.0f;
if (PlaybackSpeed > 0.0f)
@@ -88,7 +88,7 @@ public void Draw(SpriteBatch _sb, Vector2 drawLocation, GameTime gameTime)
Color.White,
0,
Vector2.Zero,
- 1,
+ drawSize,
SpriteEffects.None,
0
);
diff --git a/_Example/DotRPG.Example.csproj b/_Example/DotRPG.Example.csproj
index aef7878..c937658 100644
--- a/_Example/DotRPG.Example.csproj
+++ b/_Example/DotRPG.Example.csproj
@@ -1,4 +1,4 @@
-
+
WinExe
netcoreapp3.1
@@ -30,5 +30,6 @@
+
\ No newline at end of file
diff --git a/_Example/DynamicsTestFrame.cs b/_Example/DynamicsTestFrame.cs
new file mode 100644
index 0000000..c0760d7
--- /dev/null
+++ b/_Example/DynamicsTestFrame.cs
@@ -0,0 +1,169 @@
+// #define MUTE
+using System;
+using System.Collections.Generic;
+using DotRPG.Objects;
+using DotRPG.Objects.Dynamics;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace DotRPG._Example
+{
+ class DynamicsTestFrame : Frame
+ {
+ DynamicRectObject Player;
+ DynamicRectObject Obstacle1;
+ DynamicRectObject Obstacle2;
+ SoundEffectInstance Sliding;
+
+ public override int FrameID
+ {
+ get
+ {
+ return 1;
+ }
+ }
+
+ public DynamicsTestFrame(Game owner, ResourceHeap rh, HashSet eventSet) : base(owner, rh, eventSet)
+ {
+
+ }
+
+ public override void LoadContent()
+ {
+ FrameResources.Textures.Add("cube-p", Owner.Content.Load("Texture2D/cube-p"));
+ Player.Sprite = new SpriteController(1000 / 60.0f, FrameResources.Textures["cube-p"]);
+ FrameResources.Textures.Add("cube-o", Owner.Content.Load("Texture2D/cube-o"));
+ FrameResources.Textures.Add("cube-o2", Owner.Content.Load("Texture2D/cube-o2"));
+ Obstacle1.Sprite = new SpriteController(1000 / 60.0f, FrameResources.Textures["cube-o"]);
+ Obstacle2.Sprite = new SpriteController(1000 / 60.0f, FrameResources.Textures["cube-o2"]);
+ FrameResources.Sounds.Add("slide", Owner.Content.Load("Sounds/wallcling"));
+ FrameResources.Sounds.Add("impact", Owner.Content.Load("Sounds/impact"));
+ Sliding = FrameResources.Sounds["slide"].CreateInstance();
+ Sliding.IsLooped = true;
+ }
+
+ public override void Draw(GameTime gameTime, SpriteBatch spriteBatch, Rectangle drawZone)
+ {
+ Player.Draw(spriteBatch, gameTime, 540, Point.Zero, new Point(drawZone.Width, drawZone.Height));
+ Obstacle1.Draw(spriteBatch, gameTime, 540, Point.Zero, new Point(drawZone.Width, drawZone.Height));
+ Obstacle2.Draw(spriteBatch, gameTime, 540, Point.Zero, new Point(drawZone.Width, drawZone.Height));
+ spriteBatch.DrawString(FrameResources.Global.Fonts["vcr"], String.Format("Player: ({0}, {1}), Velocity=({2}, {3})", Player.Collider.X, Player.Collider.Y, Player.Velocity.X, Player.Velocity.Y), new Vector2(0, 12), Color.White);
+ }
+
+ public override void Initialize()
+ {
+ Player = new DynamicRectObject(new Point(48, 48), new Point(32, 32), 20.0f);
+ Obstacle1 = new DynamicRectObject(new Point(128, 128), new Point(32, 32), 10.0f);
+ Obstacle2 = new DynamicRectObject(new Point(192, 128), new Point(64, 64), 15.0f);
+ }
+
+ public override void Update(GameTime gameTime, bool[] controls)
+ {
+ Single loco_x = 0.0f; Single loco_y = 0.0f;
+ if (controls[0]) { loco_y -= 1.0f; }
+ if (controls[1]) { loco_y += 1.0f; }
+ if (controls[2]) { loco_x -= 1.0f; }
+ if (controls[3]) { loco_x += 1.0f; }
+ Vector2 Locomotion = new Vector2(loco_x, loco_y);
+ Locomotion /= (Locomotion.Length() != 0 ? Locomotion.Length() : 1.0f);
+ Locomotion *= 0.1f;
+ Vector2 FrictionVector1 = new Vector2(0.0f - (Obstacle1.Velocity.X / (Obstacle1.Velocity.Length() != 0 ? Obstacle1.Velocity.Length() : 1.0f)), 0.0f - (Obstacle1.Velocity.Y / (Obstacle1.Velocity.Length() != 0 ? Obstacle1.Velocity.Length() : 1.0f)));
+ FrictionVector1 *= Obstacle1.Mass * 0.00001f;
+ Vector2 FrictionVector2 = new Vector2(0.0f - (Obstacle2.Velocity.X / (Obstacle2.Velocity.Length() != 0 ? Obstacle2.Velocity.Length() : 1.0f)), 0.0f - (Obstacle2.Velocity.Y / (Obstacle2.Velocity.Length() != 0 ? Obstacle2.Velocity.Length() : 1.0f)));
+ FrictionVector2 *= Obstacle2.Mass * 0.00000005f;
+ if (Obstacle1.Velocity.Length() >= 0.001f)
+ {
+ #if !MUTE
+ Sliding.Play();
+ #endif
+ }
+ else
+ {
+ Sliding.Stop();
+ }
+ Obstacle1.AppliedForce += FrictionVector1;
+ Obstacle2.AppliedForce += FrictionVector2;
+ if (Obstacle1.Collider.Y <= 0 || Obstacle1.Collider.Y >= 540)
+ {
+ Obstacle1.Location = new Vector2(Obstacle1.Location.X, (Obstacle1.Collider.Y <= 0 ? 16.0f : 524.0f));
+ Obstacle1.Velocity = new Vector2(Obstacle1.Velocity.X, 0 - Obstacle1.Velocity.Y);
+ #if !MUTE
+ FrameResources.Sounds["impact"].Play();
+ #endif
+ }
+ if (Obstacle1.Collider.X <= 0 || Obstacle1.Collider.X >= 960)
+ {
+ Obstacle1.Location = new Vector2((Obstacle1.Collider.X <= 0 ? 16.0f : 944.0f), Obstacle1.Location.Y);
+ Obstacle1.Velocity = new Vector2(0 - Obstacle1.Velocity.X, Obstacle1.Velocity.Y);
+ #if !MUTE
+ FrameResources.Sounds["impact"].Play();
+ #endif
+ }
+ if (Obstacle2.Collider.Y <= 0 || Obstacle2.Collider.Y >= 540)
+ {
+ Obstacle2.Location = new Vector2(Obstacle2.Location.X, (Obstacle2.Collider.Y <= 0 ? 32.0f : 508.0f));
+ Obstacle2.Velocity = new Vector2(Obstacle2.Velocity.X, 0 - Obstacle2.Velocity.Y);
+ #if !MUTE
+ // FrameResources.Sounds["impact"].Play();
+ #endif
+ }
+ if (Obstacle2.Collider.X <= 0 || Obstacle2.Collider.X >= 960)
+ {
+ Obstacle2.Location = new Vector2((Obstacle2.Collider.X <= 0 ? 32.0f : 928.0f), Obstacle2.Location.Y);
+ Obstacle2.Velocity = new Vector2(0 - Obstacle2.Velocity.X, Obstacle2.Velocity.Y);
+ #if !MUTE
+ // FrameResources.Sounds["impact"].Play();
+ #endif
+ }
+ if (Player.TryCollideWith(Obstacle1) && Math.Max(Player.Momentum.Length(), Obstacle1.Momentum.Length()) > 1.5f)
+ {
+ Player.FullStop();
+ #if !MUTE
+ FrameResources.Sounds["impact"].Play();
+ #endif
+ }
+ if (Player.TryCollideWith(Obstacle2))
+ {
+ Player.FullStop();
+ #if !MUTE
+ // FrameResources.Sounds["impact"].Play();
+ #endif
+ }
+ if (Obstacle1.TryCollideWith(Obstacle2) && Math.Max(Obstacle1.Momentum.Length(), Obstacle2.Momentum.Length()) > 1.5f)
+ {
+ #if !MUTE
+ FrameResources.Sounds["impact"].Play();
+ #endif
+ }
+ Player.Velocity = Locomotion;
+ Player.Update(gameTime);
+ Obstacle1.Update(gameTime);
+ if (Player.Collider.Y <= 0 || Player.Collider.Y >= 540)
+ {
+ Player.Location = new Vector2(Player.Location.X, (Player.Collider.Y <= 0 ? 16.0f : 524.0f));
+ Player.FullStop();
+ }
+ if (Player.Collider.X <= 0 || Player.Collider.X >= 960)
+ {
+ Player.Location = new Vector2((Player.Collider.X <= 0 ? 16.0f : 944.0f), Player.Location.Y);
+ Player.FullStop();
+ }
+ base.Update(gameTime, controls);
+ }
+
+ public override void SetPlayerPosition(object sender, EventArgs e, GameTime gameTime)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void UnloadContent()
+ {
+ FrameResources.Dispose();
+ Player = null;
+ Obstacle1 = null;
+ Obstacle2 = null;
+ Sliding = null;
+ }
+ }
+}
diff --git a/_Example/Game1.cs b/_Example/Game1.cs
index 67f9d30..afaf11d 100644
--- a/_Example/Game1.cs
+++ b/_Example/Game1.cs
@@ -1,4 +1,5 @@
// #define FORCE_4x3
+// #define MUTE
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
@@ -67,7 +68,7 @@ public static void SetFrameNumber(Object sender, EventArgs e, GameTime gameTime)
private void StartScroll(Object sender, EventArgs e, GameTime gameTime)
{
- ActiveFrame = Frames[0];
+ ActiveFrame = Frames[1];
ActiveFrame.LoadContent();
}
@@ -83,6 +84,8 @@ protected override void Initialize()
ResetAspectRatio();
Frames.Add(new DemoFrame(this, ResourceHGlobal, LogicEventSet));
Frames[0].Initialize();
+ Frames.Add(new DynamicsTestFrame(this, ResourceHGlobal, LogicEventSet));
+ Frames[1].Initialize();
base.Initialize();
}
diff --git a/_Example/GameData/DotRPG.Example_data.mgcb b/_Example/GameData/DotRPG.Example_data.mgcb
index ca37352..3e75ae6 100644
--- a/_Example/GameData/DotRPG.Example_data.mgcb
+++ b/_Example/GameData/DotRPG.Example_data.mgcb
@@ -33,6 +33,12 @@
/processorParam:Quality=Best
/build:Sounds/clickText.wav
+#begin Sounds/impact.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:Sounds/impact.wav
+
#begin Sounds/pixelText.wav
/importer:WavImporter
/processor:SoundEffectProcessor
@@ -45,6 +51,12 @@
/processorParam:Quality=Best
/build:Sounds/text-scroll.wav
+#begin Sounds/wallcling.wav
+/importer:WavImporter
+/processor:SoundEffectProcessor
+/processorParam:Quality=Best
+/build:Sounds/wallcling.wav
+
#begin Texture2D/Banana.png
/importer:TextureImporter
/processor:TextureProcessor
@@ -57,6 +69,42 @@
/processorParam:TextureFormat=Color
/build:Texture2D/Banana.png
+#begin Texture2D/cube-o.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:Texture2D/cube-o.png
+
+#begin Texture2D/cube-o2.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:Texture2D/cube-o2.png
+
+#begin Texture2D/cube-p.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:Texture2D/cube-p.png
+
#begin Texture2D/ScrollMarker.png
/importer:TextureImporter
/processor:TextureProcessor
diff --git a/_Example/GameData/Sounds/impact.wav b/_Example/GameData/Sounds/impact.wav
new file mode 100644
index 0000000..3a5792e
Binary files /dev/null and b/_Example/GameData/Sounds/impact.wav differ
diff --git a/_Example/GameData/Sounds/wallcling.wav b/_Example/GameData/Sounds/wallcling.wav
new file mode 100644
index 0000000..0e0c696
Binary files /dev/null and b/_Example/GameData/Sounds/wallcling.wav differ
diff --git a/_Example/GameData/Texture2D/cube-o.png b/_Example/GameData/Texture2D/cube-o.png
new file mode 100644
index 0000000..0267153
Binary files /dev/null and b/_Example/GameData/Texture2D/cube-o.png differ
diff --git a/_Example/GameData/Texture2D/cube-o2.png b/_Example/GameData/Texture2D/cube-o2.png
new file mode 100644
index 0000000..1eae1e7
Binary files /dev/null and b/_Example/GameData/Texture2D/cube-o2.png differ
diff --git a/_Example/GameData/Texture2D/cube-p.png b/_Example/GameData/Texture2D/cube-p.png
new file mode 100644
index 0000000..d02435b
Binary files /dev/null and b/_Example/GameData/Texture2D/cube-p.png differ