Merge remote-tracking branch 'origin/master'
# Conflicts: # CityGame/Classes/Rendering/Particles/Explosion.cs
This commit is contained in:
commit
18dce569c0
8 changed files with 102 additions and 14 deletions
|
|
@ -1,11 +1,14 @@
|
|||
using CityGame.Classes.Rendering;
|
||||
using CityGame.Classes.Rendering.Particles;
|
||||
using CityGame.Classes.World;
|
||||
using OrpticonGameHelper.Classes.Effects;
|
||||
using OrpticonGameHelper.Classes.Elements;
|
||||
|
||||
namespace CityGame.Classes.Entities
|
||||
{
|
||||
public abstract class Entity : ISelectable
|
||||
{
|
||||
public bool IsSingleSelect() => SingleSelect;
|
||||
public float X { get; set; }
|
||||
public float Y { get; set; }
|
||||
protected float visualX;
|
||||
|
|
@ -38,6 +41,21 @@ namespace CityGame.Classes.Entities
|
|||
{
|
||||
car.Path = null;
|
||||
car.Target = target;
|
||||
return true;
|
||||
}
|
||||
if(this is GasPipe pipe)
|
||||
{
|
||||
if (pipe.Exploded > 0) return false;
|
||||
Explosion x = new Explosion();
|
||||
pipe.canvas.Children.Add(x);
|
||||
Canvas.SetLeft(x, pipe.GetParticleOrigin().X);
|
||||
Canvas.SetTop(x, pipe.GetParticleOrigin().Y);
|
||||
x.RotationOrigin = new Microsoft.Xna.Framework.Point(MainWindow.TileSize / 2);
|
||||
x.Size = 16;
|
||||
x.MaxParticleDistance = 32;
|
||||
x.Emit();
|
||||
pipe.Exploded = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,62 @@
|
|||
using CityGame.Classes.Rendering;
|
||||
using CityGame.Classes.Rendering.Particles;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OrpticonGameHelper.Classes.Elements;
|
||||
|
||||
namespace CityGame.Classes.Entities
|
||||
{
|
||||
public class GasPipe : Entity
|
||||
{
|
||||
public int Exploded { get; set; }
|
||||
public long Exploded { get; set; }
|
||||
public Image image { get; set; }
|
||||
public OCanvas canvas { get; set; }
|
||||
public Explosion Smoke { get; set; }
|
||||
public GasPipe()
|
||||
{
|
||||
if (MainWindow.random.Next(0, 2) == 0) Rotation += 180;
|
||||
SingleSelect = true;
|
||||
}
|
||||
|
||||
public Vector2 GetParticleOrigin()
|
||||
{
|
||||
return new Vector2(MainWindow.TileSize / 2);
|
||||
}
|
||||
public override OCanvas Render()
|
||||
{
|
||||
return new SourcedImage("ManholeCover.png") { ZIndex = 98, Effects = { selectedEffect } };
|
||||
image = new SourcedImage("ManholeCover.png") { ZIndex = 98, Effects = { selectedEffect } };
|
||||
canvas = image;
|
||||
return canvas;
|
||||
}
|
||||
|
||||
public override void Tick(long deltaTime)
|
||||
{
|
||||
|
||||
if (Exploded > 0)
|
||||
{
|
||||
Exploded += deltaTime;
|
||||
if(Smoke is null)
|
||||
{
|
||||
CreateSmoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
void CreateSmoke()
|
||||
{
|
||||
Explosion smoke = new Explosion();
|
||||
smoke.DirectionTendency = MainWindow.Wind;
|
||||
smoke.DirectionVariance = 22.5f;
|
||||
smoke.MinColor = Color.LightGray;
|
||||
smoke.MaxColor = Color.DarkGray;
|
||||
smoke.MaxParticleDistance = MainWindow.TileSize * 3;
|
||||
smoke.EmissionTime = 3;
|
||||
smoke.ParticleCountMin = 1;
|
||||
smoke.ParticleCountMax = 2;
|
||||
smoke.Size = 16;
|
||||
smoke.RotationOrigin = new Microsoft.Xna.Framework.Point(MainWindow.TileSize / 2);
|
||||
smoke.EaseMovement = false;
|
||||
Smoke = smoke;
|
||||
Object.Children.Add(Smoke);
|
||||
Canvas.SetLeft(Smoke, GetParticleOrigin().X);
|
||||
Canvas.SetTop(Smoke, GetParticleOrigin().Y);
|
||||
smoke.Emit().ContinueWith(t => CreateSmoke());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace CityGame
|
||||
{
|
||||
|
|
@ -25,5 +27,23 @@ namespace CityGame
|
|||
{
|
||||
return A == B;
|
||||
}
|
||||
public static Microsoft.Xna.Framework.Vector2 RotateBy(this Microsoft.Xna.Framework.Vector2 v, float angleInDegrees)
|
||||
{
|
||||
float radians = (float)(angleInDegrees * Math.PI / 180f);
|
||||
float sin = (float)Math.Sin(radians);
|
||||
float cos = (float)Math.Cos(radians);
|
||||
float rotatedX = v.X * cos - v.Y * sin;
|
||||
float rotatedY = v.X * sin + v.Y * cos;
|
||||
return new Microsoft.Xna.Framework.Vector2(rotatedX, rotatedY);
|
||||
}
|
||||
public static System.Numerics.Vector2 RotateBy(this System.Numerics.Vector2 v, float angleInDegrees)
|
||||
{
|
||||
float radians = (float)(angleInDegrees * Math.PI / 180f);
|
||||
float sin = (float)Math.Sin(radians);
|
||||
float cos = (float)Math.Cos(radians);
|
||||
float rotatedX = v.X * cos - v.Y * sin;
|
||||
float rotatedY = v.X * sin + v.Y * cos;
|
||||
return new System.Numerics.Vector2(rotatedX, rotatedY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,12 @@ public sealed class Explosion : ParticleEmitter, IParticleHandler
|
|||
|
||||
private static Effect? _explosionShader = null;
|
||||
|
||||
public Color Color = Color.Yellow;
|
||||
public Color MinColor = Color.Yellow;
|
||||
public Color MaxColor = Color.OrangeRed;
|
||||
public Vector2 DirectionTendency = Vector2.UnitX;
|
||||
public float DirectionVariance = 180;
|
||||
public int ParticleCountMin = 8;
|
||||
public int ParticleCountMax = 8;
|
||||
|
||||
public Explosion()
|
||||
: base(Explosion.GetShader())
|
||||
|
|
@ -41,13 +46,16 @@ public sealed class Explosion : ParticleEmitter, IParticleHandler
|
|||
public ICollection<IParticle> Generate()
|
||||
{
|
||||
List<IParticle> particles = new List<IParticle>();
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int i = 0; i < Random.Shared.Next(ParticleCountMin, ParticleCountMax + 1); i++)
|
||||
{
|
||||
ExplosionParticle particle = new ExplosionParticle();
|
||||
particle.OriginalPosition = particle.Position = Vector2.Zero;
|
||||
|
||||
Vector2 direction = new Vector2(Random.Shared.NextSingle(-1, 1), Random.Shared.NextSingle(-1,1));
|
||||
particle.Direction = direction;
|
||||
float variance = ((float)Random.Shared.NextSingle() * 2 - 1) * DirectionVariance;
|
||||
Vector2 direction = DirectionTendency.RotateBy(variance);
|
||||
particle.Direction = direction * Random.Shared.NextSingle();
|
||||
|
||||
particle.color = Color.Lerp(MinColor, MaxColor, Random.Shared.NextSingle());
|
||||
|
||||
particle.LifeTime = EmissionTime;
|
||||
particle.LifeTimeScale = Random.Shared.NextSingle(1, 1.5f);
|
||||
|
|
@ -59,7 +67,7 @@ public sealed class Explosion : ParticleEmitter, IParticleHandler
|
|||
|
||||
return particles;
|
||||
}
|
||||
|
||||
public bool EaseMovement { get; set; } = true;
|
||||
public void Move(ICollection<IParticle> particles, float deltatime, ParticleEmitter emitter)
|
||||
{
|
||||
|
||||
|
|
@ -72,7 +80,7 @@ public sealed class Explosion : ParticleEmitter, IParticleHandler
|
|||
time = ParticleEmitter.CalculateNormalizedReversedTime(explParticle.LifeTime, this.EmissionTime);
|
||||
}
|
||||
|
||||
float distanceCalc = Easing.Easing.OutExpo(time);
|
||||
float distanceCalc = EaseMovement ? Easing.Easing.OutExpo(time) : time;
|
||||
float distance = distanceCalc * emitter.MaxParticleDistance;
|
||||
particle.Position = particle.OriginalPosition + particle.Direction * distance;
|
||||
|
||||
|
|
@ -82,8 +90,7 @@ public sealed class Explosion : ParticleEmitter, IParticleHandler
|
|||
public void Draw(ref ParticleDrawContext context)
|
||||
{
|
||||
context.Effect.Parameters["view_projection"].SetValue(context.View * context.Projection);
|
||||
context.Effect.Parameters["color"].SetValue(this.Color.ToVector4());
|
||||
|
||||
context.Effect.Parameters["color"].SetValue(this.MinColor.ToVector4());
|
||||
|
||||
|
||||
context.SpriteBatch.Begin(
|
||||
|
|
@ -110,6 +117,7 @@ public sealed class Explosion : ParticleEmitter, IParticleHandler
|
|||
if (particle is ExplosionParticle explParticle)
|
||||
{
|
||||
normTime = ParticleEmitter.CalculateNormalizedReversedTime(explParticle.LifeTime, this.EmissionTime);
|
||||
context.Effect.Parameters["color"].SetValue(explParticle.color.ToVector4());
|
||||
context.Effect.Parameters["noiseOffset"].SetValue(explParticle.UVOffset);
|
||||
}
|
||||
float time = Easing.Easing.OutExpo(normTime);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ public sealed class ExplosionParticle: Particle
|
|||
public float LifeTimeScale = 1;
|
||||
public float LifeTime = 1;
|
||||
public Vector2 UVOffset = Vector2.Zero;
|
||||
public Color color;
|
||||
|
||||
public void ReduceLifeTime(float deltatime)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@ namespace CityGame.Classes.World
|
|||
public bool RunAction(ISelectable target);
|
||||
public int X();
|
||||
public int Y();
|
||||
public bool IsSingleSelect();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ namespace CityGame.Classes.World
|
|||
{
|
||||
public struct Tile : ISelectable
|
||||
{
|
||||
public bool IsSingleSelect() => false;
|
||||
public int BlockID;
|
||||
public TileType Type;
|
||||
public Pattern Pattern;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ namespace CityGame
|
|||
public static Tile[,] Grid;
|
||||
public static ISelectable Selected;
|
||||
public static OCanvas[,] ImageGrid;
|
||||
public static Vector2 Wind = new Vector2(0.5f, -0.5f);
|
||||
|
||||
Canvas MainCanvas = new OCanvas();
|
||||
Canvas BGCanvas = new OCanvas();
|
||||
|
|
@ -509,7 +510,8 @@ namespace CityGame
|
|||
ISelectable select = GetSelectableFromClick(state);
|
||||
if (select is not null)
|
||||
{
|
||||
Selected = select;
|
||||
if (select.IsSingleSelect()) select.RunAction(select);
|
||||
else Selected = select;
|
||||
}
|
||||
}
|
||||
else if (state.RightButton == ButtonState.Pressed)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue