Particle system improvements:
- particles can collide with the outer walls of the sub - drag + waterdrag parameters - fixed particles "twitching" when the submarine is moving fast - submarine velocity only affects the initial velocity of the particles (i.e. accelerating the sub doesn't automatically accelerate them)
This commit is contained in:
@@ -37,6 +37,7 @@ namespace Barotrauma.Particles
|
||||
private Vector2 velocityChange;
|
||||
|
||||
private Vector2 drawPosition;
|
||||
private float drawRotation;
|
||||
|
||||
//private float checkCollisionTimer;
|
||||
|
||||
@@ -65,6 +66,12 @@ namespace Barotrauma.Particles
|
||||
get { return velocityChange; }
|
||||
set { velocityChange = value; }
|
||||
}
|
||||
|
||||
public Vector2 Velocity
|
||||
{
|
||||
get { return velocity; }
|
||||
set { velocity = value; }
|
||||
}
|
||||
|
||||
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null)
|
||||
{
|
||||
@@ -74,26 +81,19 @@ namespace Barotrauma.Particles
|
||||
spriteIndex = Rand.Int(prefab.Sprites.Count);
|
||||
|
||||
currentHull = Hull.FindHull(position, hullGuess);
|
||||
//if (currentHull != null && currentHull.Submarine != null)
|
||||
//{
|
||||
// Vector2 subVel = ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity);
|
||||
// //subVel.Y = -subVel.Y;
|
||||
// speed += subVel;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// int a = 1;
|
||||
//}
|
||||
//if (currentHull == null) position = Submarine.Loaded == null ? position : position + Submarine.Loaded.Position;
|
||||
|
||||
this.position = position;
|
||||
prevPosition = position;
|
||||
|
||||
|
||||
drawPosition = position;
|
||||
|
||||
|
||||
velocity = MathUtils.IsValid(speed) ? speed : Vector2.Zero;
|
||||
|
||||
if (currentHull != null && currentHull.Submarine != null)
|
||||
{
|
||||
velocity += ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity);
|
||||
}
|
||||
|
||||
this.rotation = rotation + Rand.Range(prefab.StartRotationMin, prefab.StartRotationMax);
|
||||
prevRotation = rotation;
|
||||
|
||||
@@ -142,12 +142,12 @@ namespace Barotrauma.Particles
|
||||
|
||||
public bool Update(float deltaTime)
|
||||
{
|
||||
|
||||
Vector2 subVel = currentHull ==null || currentHull.Submarine==null ? Vector2.Zero : ConvertUnits.ToDisplayUnits(currentHull.Submarine.Velocity);
|
||||
prevPosition = position;
|
||||
prevRotation = rotation;
|
||||
|
||||
//over 3 times faster than position += velocity * deltatime
|
||||
position.X += (velocity.X+subVel.X) * deltaTime;
|
||||
position.Y += (velocity.Y+subVel.Y) * deltaTime;
|
||||
position.X += velocity.X * deltaTime;
|
||||
position.Y += velocity.Y * deltaTime;
|
||||
|
||||
if (prefab.RotateToDirection)
|
||||
{
|
||||
@@ -161,6 +161,16 @@ namespace Barotrauma.Particles
|
||||
rotation += angularVelocity * deltaTime;
|
||||
}
|
||||
|
||||
if (prefab.WaterDrag > 0.0f &&
|
||||
(currentHull == null || (currentHull.Submarine != null && position.Y - currentHull.Submarine.DrawPosition.Y < currentHull.Surface)))
|
||||
{
|
||||
ApplyDrag(prefab.WaterDrag, deltaTime);
|
||||
}
|
||||
else if (prefab.Drag > 0.0f)
|
||||
{
|
||||
ApplyDrag(prefab.Drag, deltaTime);
|
||||
}
|
||||
|
||||
velocity.X += velocityChange.X * deltaTime;
|
||||
velocity.Y += velocityChange.Y * deltaTime;
|
||||
|
||||
@@ -174,11 +184,20 @@ namespace Barotrauma.Particles
|
||||
color.G / 255.0f + prefab.ColorChange.Y * deltaTime,
|
||||
color.B / 255.0f + prefab.ColorChange.Z * deltaTime);
|
||||
|
||||
if ((prefab.DeleteOnCollision || prefab.CollidesWithWalls) && currentHull!=null)
|
||||
if (prefab.DeleteOnCollision || prefab.CollidesWithWalls)
|
||||
{
|
||||
Vector2 edgePos = position + prefab.CollisionRadius * Vector2.Normalize(velocity) * size.X;
|
||||
|
||||
if (!Submarine.RectContains(currentHull.WorldRect, edgePos))
|
||||
|
||||
if (currentHull == null)
|
||||
{
|
||||
var collidedHull = Hull.FindHullOld(edgePos);
|
||||
if (collidedHull != null)
|
||||
{
|
||||
if (prefab.DeleteOnCollision) return false;
|
||||
OnWallCollisionOutside(collidedHull);
|
||||
}
|
||||
}
|
||||
else if (!Submarine.RectContains(currentHull.WorldRect, edgePos))
|
||||
{
|
||||
if (prefab.DeleteOnCollision) return false;
|
||||
|
||||
@@ -196,15 +215,13 @@ namespace Barotrauma.Particles
|
||||
if (Math.Sign(velocity.X) != Math.Sign(gap.WorldRect.Center.X - currentHull.WorldRect.Center.X)) continue;
|
||||
}
|
||||
|
||||
//Rectangle enlargedRect = new Rectangle(gap.Rect.X - 10, gap.Rect.Y + 10, gap.Rect.Width + 20, gap.Rect.Height + 20);
|
||||
//if (!Submarine.RectContains(enlargedRect, position)) continue;
|
||||
gapFound = true;
|
||||
}
|
||||
|
||||
if (!gapFound)
|
||||
{
|
||||
|
||||
OnWallCollision(currentHull, edgePos);
|
||||
OnWallCollisionInside(currentHull, edgePos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -212,21 +229,9 @@ namespace Barotrauma.Particles
|
||||
hullGaps = currentHull == null ? new List<Gap>() : currentHull.ConnectedGaps;
|
||||
|
||||
if (OnChangeHull != null) OnChangeHull(edgePos, currentHull);
|
||||
|
||||
}
|
||||
|
||||
//Hull prevHull = Hull.FindHull(prevPosition, hullLimits, currentHull);
|
||||
|
||||
//if (prevHull == null) return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//if (position.Y < currentHull.Rect.Y-currentHull.Rect.Height)
|
||||
//{
|
||||
// position.Y = currentHull.Rect.Y - currentHull.Rect.Height;
|
||||
// velocity.Y *= -0.2f;
|
||||
//}
|
||||
//if (!Submarine.RectContains(currentHull.Rect, position)) return false;
|
||||
|
||||
}
|
||||
|
||||
lifeTime -= deltaTime;
|
||||
@@ -236,10 +241,22 @@ namespace Barotrauma.Particles
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnWallCollision(Hull prevHull, Vector2 position)
|
||||
private void ApplyDrag(float dragCoefficient, float deltaTime)
|
||||
{
|
||||
if (velocity == Vector2.Zero) return;
|
||||
|
||||
float speed = velocity.Length();
|
||||
velocity -= (velocity / speed) * Math.Min(speed * speed * prefab.WaterDrag * deltaTime, 1.0f);
|
||||
}
|
||||
|
||||
private void OnWallCollisionInside(Hull prevHull, Vector2 position)
|
||||
{
|
||||
Rectangle prevHullRect = prevHull.WorldRect;
|
||||
|
||||
Vector2 subVel = ConvertUnits.ToDisplayUnits(prevHull.Submarine.Velocity);
|
||||
|
||||
velocity -= subVel;
|
||||
|
||||
if (position.Y < prevHullRect.Y - prevHullRect.Height)
|
||||
{
|
||||
position.Y = prevHullRect.Y - prevHullRect.Height + 1.0f;
|
||||
@@ -264,30 +281,64 @@ namespace Barotrauma.Particles
|
||||
}
|
||||
|
||||
velocity *= prefab.Restitution;
|
||||
|
||||
velocity += subVel;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
|
||||
|
||||
private void OnWallCollisionOutside(Hull collisionHull)
|
||||
{
|
||||
drawPosition = Physics.Interpolate(prevPosition, position);
|
||||
float drawRotation = Physics.Interpolate(prevRotation, rotation);
|
||||
|
||||
//drawPosition = ConvertUnits.ToDisplayUnits(drawPosition);
|
||||
|
||||
Vector2 drawSize = size;
|
||||
|
||||
if (prefab.GrowTime>0.0f && totalLifeTime-lifeTime < prefab.GrowTime)
|
||||
Rectangle hullRect = collisionHull.WorldRect;
|
||||
|
||||
if (position.Y < hullRect.Y - hullRect.Height)
|
||||
{
|
||||
drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime);
|
||||
position.Y = hullRect.Y - hullRect.Height - 1.0f;
|
||||
velocity.Y = -velocity.Y;
|
||||
}
|
||||
else if (position.Y > hullRect.Y)
|
||||
{
|
||||
position.Y = hullRect.Y + 1.0f;
|
||||
velocity.X = Math.Abs(velocity.Y) * Math.Sign(velocity.X);
|
||||
velocity.Y = -velocity.Y;
|
||||
}
|
||||
|
||||
prefab.Sprites[spriteIndex].Draw(spriteBatch,
|
||||
new Vector2(drawPosition.X, -drawPosition.Y),
|
||||
color * alpha,
|
||||
prefab.Sprites[spriteIndex].Origin, drawRotation,
|
||||
drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth);
|
||||
if (position.X < hullRect.X)
|
||||
{
|
||||
position.X = hullRect.X - 1.0f;
|
||||
velocity.X = -velocity.X;
|
||||
}
|
||||
else if (position.X > hullRect.X + hullRect.Width)
|
||||
{
|
||||
position.X = hullRect.X + hullRect.Width + 1.0f;
|
||||
velocity.X = -velocity.X;
|
||||
}
|
||||
|
||||
velocity *= prefab.Restitution;
|
||||
}
|
||||
|
||||
public void UpdateDrawPos()
|
||||
{
|
||||
drawPosition = Physics.Interpolate(prevPosition, position);
|
||||
drawRotation = Physics.Interpolate(prevRotation, rotation);
|
||||
|
||||
prevPosition = position;
|
||||
prevRotation = rotation;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
Vector2 drawSize = size;
|
||||
|
||||
if (prefab.GrowTime > 0.0f && totalLifeTime - lifeTime < prefab.GrowTime)
|
||||
{
|
||||
drawSize *= ((totalLifeTime - lifeTime) / prefab.GrowTime);
|
||||
}
|
||||
|
||||
prefab.Sprites[spriteIndex].Draw(spriteBatch,
|
||||
new Vector2(drawPosition.X, -drawPosition.Y),
|
||||
color * alpha,
|
||||
prefab.Sprites[spriteIndex].Origin, drawRotation,
|
||||
drawSize, SpriteEffects.None, prefab.Sprites[spriteIndex].Depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user