using System.Collections.Generic;
using FarseerPhysics.Common;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using FarseerPhysics.SamplesFramework;
namespace Labyrinth
{
public enum ObjectType
{
Circle,
Rectangle,
Gear,
Star
}
public class Objects
{
private List<Body> _bodies;
private Category _collidesWith;
private Category _collisionCategories;
private Sprite _object;
private PhysicsGameScreen _screen;
public Objects(World world, PhysicsGameScreen screen, Vector2 startPosition, Vector2 endPosition, int count,
float radius, ObjectType type)
{
CreateObjects(world, screen, ref startPosition, ref endPosition, count, radius, type, false);
}
public Objects(World world, PhysicsGameScreen screen, Vector2 startPosition, Vector2 endPosition, int count,
float radius, ObjectType type, bool isStatic)
{
CreateObjects(world, screen, ref startPosition, ref endPosition, count, radius, type, isStatic);
}
public Objects(World world, PhysicsGameScreen screen, Vector2 startPosition, float radius, ObjectType type, bool isStatic)
{
CreateObject(world, screen, ref startPosition, radius, type, isStatic);
}
private void CreateObjects(World world, PhysicsGameScreen screen, ref Vector2 startPosition, ref Vector2 endPosition, int count, float radius, ObjectType type, bool isStatic)
{
_bodies = new List<Body>(count);
CollidesWith = Category.All;
CollisionCategories = Category.All;
for (int i = 0; i < count; ++i)
{
switch (type)
{
case ObjectType.Circle:
_bodies.Add(BodyFactory.CreateCircle(world, radius, 1f));
break;
case ObjectType.Rectangle:
_bodies.Add(BodyFactory.CreateRectangle(world, radius, radius, 1f));
break;
case ObjectType.Star:
_bodies.Add(BodyFactory.CreateGear(world, radius, 10, 0f, 1f, 1f));
break;
case ObjectType.Gear:
_bodies.Add(BodyFactory.CreateGear(world, radius, 10, 100f, 1f, 1f));
break;
}
}
for (int i = 0; i < _bodies.Count; ++i)
{
Body body = _bodies[i];
body.BodyType = BodyType.Dynamic;
body.Position = Vector2.Lerp(startPosition, endPosition, i / (float)(count - 1));
body.Restitution = .7f;
body.Friction = .2f;
body.CollisionCategories = CollisionCategories;
body.CollidesWith = CollidesWith;
body.IsStatic = isStatic;
}
_screen = screen;
//GFX
AssetCreator creator = _screen.ScreenManager.Assets;
switch (type)
{
case ObjectType.Circle:
_object = new Sprite(creator.CircleTexture(radius, MaterialType.Dots, Color.DarkRed, 0.8f));
break;
case ObjectType.Rectangle:
_object =
new Sprite(creator.TextureFromVertices(PolygonTools.CreateRectangle(radius / 2f, radius / 2f),
MaterialType.Dots, Color.Blue, 0.8f));
break;
case ObjectType.Star:
_object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 0f, 1f),
MaterialType.Dots, Color.Yellow, 0.8f));
break;
case ObjectType.Gear:
_object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 100f, 1f),
MaterialType.Dots, Color.DarkGreen, 0.8f));
break;
}
}
private void CreateObject(World world, PhysicsGameScreen screen, ref Vector2 startPosition, float radius, ObjectType type, bool isStatic)
{
_bodies = new List<Body>(1);
CollidesWith = Category.All;
CollisionCategories = Category.All;
switch (type)
{
case ObjectType.Circle:
_bodies.Add(BodyFactory.CreateCircle(world, radius, 1f));
break;
case ObjectType.Rectangle:
_bodies.Add(BodyFactory.CreateRectangle(world, radius, radius, 1f));
break;
case ObjectType.Star:
_bodies.Add(BodyFactory.CreateGear(world, radius, 10, 0f, 1f, 1f));
break;
case ObjectType.Gear:
_bodies.Add(BodyFactory.CreateGear(world, radius, 10, 100f, 1f, 1f));
break;
}
Body body = _bodies[0];
body.BodyType = BodyType.Dynamic;
body.Position = startPosition;
body.Restitution = .2f;
body.Friction = .2f;
body.CollisionCategories = CollisionCategories;
body.CollidesWith = CollidesWith;
body.IsStatic = isStatic;
_screen = screen;
//GFX
AssetCreator creator = _screen.ScreenManager.Assets;
switch (type)
{
case ObjectType.Circle:
_object = new Sprite(creator.CircleTexture(radius, MaterialType.Dots, Color.DarkRed, 0.8f));
break;
case ObjectType.Rectangle:
_object =
new Sprite(creator.TextureFromVertices(PolygonTools.CreateRectangle(radius / 2f, radius / 2f),
MaterialType.Dots, Color.Blue, 0.8f));
break;
case ObjectType.Star:
_object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 0f, 1f),
MaterialType.Dots, Color.Yellow, 0.8f));
break;
case ObjectType.Gear:
_object = new Sprite(creator.TextureFromVertices(PolygonTools.CreateGear(radius, 10, 100f, 1f),
MaterialType.Dots, Color.DarkGreen, 0.8f));
break;
}
}
public Category CollisionCategories
{
get { return _collisionCategories; }
set
{
_collisionCategories = value;
foreach (Body body in _bodies)
{
body.CollisionCategories = _collisionCategories;
}
}
}
public Category CollidesWith
{
get { return _collidesWith; }
set
{
_collidesWith = value;
foreach (Body body in _bodies)
{
body.CollidesWith = _collidesWith;
}
}
}
public void Draw()
{
Draw(_object.Texture, null, new Vector2(0,0));
}
public void Draw(Texture2D texture, Texture2D shadowTexture, Vector2 shadowOffset)
{
SpriteBatch batch = _screen.ScreenManager.SpriteBatch;
for (int i = 0; i < _bodies.Count; ++i)
{
if (shadowTexture != null)
{
batch.Draw(shadowTexture, ConvertUnits.ToDisplayUnits(_bodies[i].Position) - shadowOffset, null,
Color.White, 0f, _object.Origin, 1f, SpriteEffects.None, 0f);
}
batch.Draw(texture, ConvertUnits.ToDisplayUnits(_bodies[i].Position), null,
Color.White, 0f, _object.Origin, 1f, SpriteEffects.None, 0f);
}
}
}
}