Server job assigning logic, submarine movement syncing, submarine collision improvements, spawnpoints in levels
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Common;
|
||||
using FarseerPhysics.Dynamics.Contacts;
|
||||
using FarseerPhysics.Factories;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Dynamics
|
||||
{
|
||||
/// <summary>
|
||||
/// A type of body that supports multiple fixtures that can break apart.
|
||||
/// </summary>
|
||||
public class BreakableBody
|
||||
{
|
||||
private float[] _angularVelocitiesCache = new float[8];
|
||||
private bool _break;
|
||||
private Vector2[] _velocitiesCache = new Vector2[8];
|
||||
private World _world;
|
||||
|
||||
public BreakableBody(IEnumerable<Vertices> vertices, World world, float density)
|
||||
{
|
||||
_world = world;
|
||||
_world.ContactManager.PostSolve += PostSolve;
|
||||
MainBody = new Body(_world);
|
||||
MainBody.BodyType = BodyType.Dynamic;
|
||||
|
||||
foreach (Vertices part in vertices)
|
||||
{
|
||||
PolygonShape polygonShape = new PolygonShape(part, density);
|
||||
Fixture fixture = MainBody.CreateFixture(polygonShape);
|
||||
Parts.Add(fixture);
|
||||
}
|
||||
}
|
||||
|
||||
public BreakableBody(IEnumerable<Shape> shapes, World world)
|
||||
{
|
||||
_world = world;
|
||||
_world.ContactManager.PostSolve += PostSolve;
|
||||
MainBody = new Body(_world);
|
||||
MainBody.BodyType = BodyType.Dynamic;
|
||||
|
||||
foreach (Shape part in shapes)
|
||||
{
|
||||
Fixture fixture = MainBody.CreateFixture(part);
|
||||
Parts.Add(fixture);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Broken;
|
||||
public Body MainBody;
|
||||
public List<Fixture> Parts = new List<Fixture>(8);
|
||||
|
||||
/// <summary>
|
||||
/// The force needed to break the body apart.
|
||||
/// Default: 500
|
||||
/// </summary>
|
||||
public float Strength = 500.0f;
|
||||
|
||||
private void PostSolve(Contact contact, ContactVelocityConstraint impulse)
|
||||
{
|
||||
if (!Broken)
|
||||
{
|
||||
if (Parts.Contains(contact.FixtureA) || Parts.Contains(contact.FixtureB))
|
||||
{
|
||||
float maxImpulse = 0.0f;
|
||||
int count = contact.Manifold.PointCount;
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
maxImpulse = Math.Max(maxImpulse, impulse.points[i].normalImpulse);
|
||||
}
|
||||
|
||||
if (maxImpulse > Strength)
|
||||
{
|
||||
// Flag the body for breaking.
|
||||
_break = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_break)
|
||||
{
|
||||
Decompose();
|
||||
Broken = true;
|
||||
_break = false;
|
||||
}
|
||||
|
||||
// Cache velocities to improve movement on breakage.
|
||||
if (Broken == false)
|
||||
{
|
||||
//Enlarge the cache if needed
|
||||
if (Parts.Count > _angularVelocitiesCache.Length)
|
||||
{
|
||||
_velocitiesCache = new Vector2[Parts.Count];
|
||||
_angularVelocitiesCache = new float[Parts.Count];
|
||||
}
|
||||
|
||||
//Cache the linear and angular velocities.
|
||||
for (int i = 0; i < Parts.Count; i++)
|
||||
{
|
||||
_velocitiesCache[i] = Parts[i].Body.LinearVelocity;
|
||||
_angularVelocitiesCache[i] = Parts[i].Body.AngularVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Decompose()
|
||||
{
|
||||
//Unsubsribe from the PostSolve delegate
|
||||
_world.ContactManager.PostSolve -= PostSolve;
|
||||
|
||||
for (int i = 0; i < Parts.Count; i++)
|
||||
{
|
||||
Fixture oldFixture = Parts[i];
|
||||
|
||||
Shape shape = oldFixture.Shape.Clone();
|
||||
object userData = oldFixture.UserData;
|
||||
|
||||
MainBody.DestroyFixture(oldFixture);
|
||||
|
||||
Body body = BodyFactory.CreateBody(_world);
|
||||
body.BodyType = BodyType.Dynamic;
|
||||
body.Position = MainBody.Position;
|
||||
body.Rotation = MainBody.Rotation;
|
||||
body.UserData = MainBody.UserData;
|
||||
|
||||
Fixture newFixture = body.CreateFixture(shape);
|
||||
newFixture.UserData = userData;
|
||||
Parts[i] = newFixture;
|
||||
|
||||
body.AngularVelocity = _angularVelocitiesCache[i];
|
||||
body.LinearVelocity = _velocitiesCache[i];
|
||||
}
|
||||
|
||||
_world.RemoveBody(MainBody);
|
||||
_world.RemoveBreakableBody(this);
|
||||
}
|
||||
|
||||
public void Break()
|
||||
{
|
||||
_break = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user