Skip to content

Commit d3b0792

Browse files
committed
upgraded dependencies (including MonoGame), and imported particle effects system into GraphicsExtensions
1 parent 226f891 commit d3b0792

File tree

15 files changed

+370
-16
lines changed

15 files changed

+370
-16
lines changed

BenMakesGames.PlayPlayMini.BeepBoop/BenMakesGames.PlayPlayMini.BeepBoop.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Company>Ben Hendel-Doying</Company>
66
<Description>An extension for PlayPlayMini which adds methods for generating &amp; playing simple waveforms.</Description>
77
<Copyright>2022-2024 Ben Hendel-Doying</Copyright>
8-
<Version>0.7.0</Version>
8+
<Version>0.8.0</Version>
99

1010
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
1111
<PackageTags>monogame playplaymini sound generation square triangle saw sine wave waveform</PackageTags>

BenMakesGames.PlayPlayMini.GraphicsExtensions/BenMakesGames.PlayPlayMini.GraphicsExtensions.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Company>Ben Hendel-Doying</Company>
66
<Description>Some GraphicsManager extensions for PlayPlayMini.</Description>
77
<Copyright>2023-2025 Ben Hendel-Doying</Copyright>
8-
<Version>6.0.0</Version>
8+
<Version>6.1.0</Version>
99

1010
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
1111
<PackageTags>monogame playplaymini graphics extensions animations text</PackageTags>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using BenMakesGames.PlayPlayMini.Services;
2+
using Microsoft.Xna.Framework;
3+
4+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
5+
6+
public sealed class FlashOfInsight: IParticle
7+
{
8+
private Color Color { get; }
9+
private double TTL { get; set; } = 0.1;
10+
11+
/// <inheritdoc />
12+
public bool IsAlive => TTL > 0;
13+
14+
public FlashOfInsight(Color color)
15+
{
16+
Color = color;
17+
}
18+
19+
/// <inheritdoc />
20+
public void Update(GameTime gameTime)
21+
{
22+
TTL -= gameTime.ElapsedGameTime.TotalSeconds;
23+
}
24+
25+
/// <inheritdoc />
26+
public void Draw(GraphicsManager graphics)
27+
{
28+
var partingHeight = (int)(graphics.Height * TTL * 5);
29+
graphics.DrawFilledRectangle(0, 0, graphics.Width, partingHeight, Color);
30+
graphics.DrawFilledRectangle(0, graphics.Height - partingHeight, graphics.Width, partingHeight, Color);
31+
}
32+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using BenMakesGames.PlayPlayMini.Services;
3+
using Microsoft.Xna.Framework;
4+
5+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
6+
7+
public sealed class FloatAwayPicture: IParticle
8+
{
9+
public required string PictureName { get; init; }
10+
public required int StartingX { get; init; }
11+
public required int StartingY { get; init; }
12+
public required double Angle { get; init; }
13+
public required double Speed { get; init; }
14+
public required double TTL { get; init; }
15+
public double TimeAlive { get; private set; }
16+
17+
/// <inheritdoc />
18+
public bool IsAlive => TimeAlive < TTL;
19+
20+
public int X => (int)(StartingX + Math.Cos(Angle) * TimeAlive * Speed);
21+
public int Y => (int)(StartingY - Math.Sin(Angle) * TimeAlive * Speed);
22+
23+
/// <inheritdoc />
24+
public void Update(GameTime gameTime)
25+
{
26+
TimeAlive += gameTime.ElapsedGameTime.TotalSeconds;
27+
}
28+
29+
/// <inheritdoc />
30+
public void Draw(GraphicsManager graphics)
31+
{
32+
graphics.DrawPicture(PictureName, X, Y);
33+
}
34+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using BenMakesGames.PlayPlayMini.Services;
3+
using Microsoft.Xna.Framework;
4+
5+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
6+
7+
public sealed class FloatAwayText: IParticle
8+
{
9+
public required string Text { get; init; }
10+
public required Color FillColor { get; init; }
11+
public required Color OutlineColor { get; init; }
12+
public required int StartingX { get; init; }
13+
public required int StartingY { get; init; }
14+
public required double Angle { get; init; }
15+
public required double Speed { get; init; }
16+
public required double TTL { get; init; }
17+
public double TimeAlive { get; private set; }
18+
19+
/// <inheritdoc />
20+
public bool IsAlive => TimeAlive < TTL;
21+
22+
public int X => (int)(StartingX + Math.Cos(Angle) * TimeAlive * Speed);
23+
public int Y => (int)(StartingY - Math.Sin(Angle) * TimeAlive * Speed);
24+
25+
/// <inheritdoc />
26+
public void Update(GameTime gameTime)
27+
{
28+
TimeAlive += gameTime.ElapsedGameTime.TotalSeconds;
29+
}
30+
31+
/// <inheritdoc />
32+
public void Draw(GraphicsManager graphics)
33+
{
34+
graphics.DrawTextWithOutline("Font", X, Y, Text, FillColor, OutlineColor);
35+
}
36+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using BenMakesGames.PlayPlayMini.Services;
3+
using Microsoft.Xna.Framework;
4+
5+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
6+
7+
public sealed class GlassShard : IParticle
8+
{
9+
/// <inheritdoc />
10+
public bool IsAlive => Y < MaxY + Size;
11+
12+
private double X { get; set; }
13+
private double Y { get; set; }
14+
private double XSpeed { get; set; }
15+
private double YSpeed { get; set; }
16+
private int Size { get; }
17+
18+
private double AngleY { get; set; }
19+
private double AngleZ { get; set; }
20+
21+
private double YSpin { get; }
22+
private double ZSpin { get; }
23+
24+
private int MaxY { get; }
25+
26+
private Color Color { get; }
27+
28+
public GlassShard(int startX, int startY, int maxY, Color color)
29+
{
30+
X = startX;
31+
Y = startY;
32+
Size = Random.Shared.Next(3) + 1;
33+
XSpeed = Random.Shared.NextDouble() * 4 - 2;
34+
YSpeed = -(Random.Shared.NextDouble() * 2 + 1);
35+
MaxY = maxY;
36+
Color = color;
37+
38+
if(Random.Shared.Next(2) == 0)
39+
{
40+
YSpin = Random.Shared.NextDouble() / 2 + 0.5;
41+
ZSpin = Random.Shared.NextDouble();
42+
}
43+
else
44+
{
45+
YSpin = Random.Shared.NextDouble();
46+
ZSpin = Random.Shared.NextDouble() / 2 + 0.5;
47+
}
48+
}
49+
50+
/// <inheritdoc />
51+
public void Draw(GraphicsManager graphics)
52+
{
53+
if(Size == 1)
54+
{
55+
graphics.DrawTexture(
56+
graphics.WhitePixel,
57+
(int)X, (int)Y,
58+
Color
59+
);
60+
}
61+
else
62+
{
63+
graphics.DrawTextureWithTransformations(
64+
graphics.WhitePixel,
65+
(int)(X - Size / 2f), (int)(Y - Size / 2f),
66+
new Rectangle(0, 0, 1, 1),
67+
Microsoft.Xna.Framework.Graphics.SpriteEffects.None,
68+
(float)AngleZ,
69+
Size,
70+
(float)(Size * Math.Cos(AngleY)),
71+
Color
72+
);
73+
}
74+
}
75+
76+
/// <inheritdoc />
77+
public void Update(GameTime gameTime)
78+
{
79+
YSpeed += 0.2 * gameTime.ElapsedGameTime.TotalSeconds * 60;
80+
81+
Y += YSpeed * gameTime.ElapsedGameTime.TotalSeconds * 60;
82+
X += XSpeed * gameTime.ElapsedGameTime.TotalSeconds * 60;
83+
84+
if(Size > 1)
85+
{
86+
AngleY += YSpin * gameTime.ElapsedGameTime.TotalSeconds * 60;
87+
AngleZ += ZSpin * gameTime.ElapsedGameTime.TotalSeconds * 60;
88+
}
89+
}
90+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using BenMakesGames.PlayPlayMini.Services;
2+
using Microsoft.Xna.Framework;
3+
4+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
5+
6+
/// <summary>
7+
/// Interface for particle effects.
8+
/// </summary>
9+
/// <remarks>
10+
/// To use:
11+
/// 1. Create a List&lt;IParticle&gt; to hold particles.
12+
/// 2. In your <c>GameState</c>'s <c>Update</c> method, call <c>YourListOfParticles.Update(gameTime);</c> to update the particles. Dead particles will be removed from the list automatically.
13+
/// 3. In your <c>GameState</c>'s <c>Draw</c> method, call <c>YourListOfParticles.Draw(graphics);</c> to draw the particles.
14+
/// 4. Add new particles to the list as needed.
15+
/// </remarks>
16+
public interface IParticle
17+
{
18+
/// <summary>
19+
/// Whether or not the particle is still alive.
20+
/// </summary>
21+
/// <remarks>
22+
/// Particles that are no longer alive will be removed from a <c>List&lt;IParticle&gt;</c> when <c>Update</c> is called on that list.
23+
/// </remarks>
24+
bool IsAlive { get; }
25+
26+
/// <summary>
27+
/// Update the particle's state.
28+
/// </summary>
29+
/// <param name="gameTime"></param>
30+
void Update(GameTime gameTime);
31+
32+
/// <summary>
33+
/// Draw the particle.
34+
/// </summary>
35+
/// <param name="graphics"></param>
36+
void Draw(GraphicsManager graphics);
37+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Collections.Generic;
2+
using BenMakesGames.PlayPlayMini.Services;
3+
using Microsoft.Xna.Framework;
4+
5+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
6+
7+
/// <summary>
8+
/// Extension methods for managing particle effects.
9+
/// </summary>
10+
public static class Particles
11+
{
12+
public static void Update(this IList<IParticle> particles, GameTime gameTime)
13+
{
14+
for (int i = particles.Count - 1; i >= 0; i--)
15+
{
16+
particles[i].Update(gameTime);
17+
18+
if(!particles[i].IsAlive)
19+
particles.RemoveAt(i);
20+
}
21+
}
22+
23+
public static void DrawParticles(this GraphicsManager graphics, IList<IParticle> particles)
24+
{
25+
foreach(var particle in particles)
26+
particle.Draw(graphics);
27+
}
28+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using BenMakesGames.PlayPlayMini.Services;
3+
using Microsoft.Xna.Framework;
4+
5+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
6+
7+
public sealed class Snow: IParticle
8+
{
9+
private Color Color { get; }
10+
private double Y { get; set; }
11+
private double X { get; set; }
12+
private double Wiggle { get; set; }
13+
private int MaxY { get; }
14+
private int Size { get; }
15+
private double Speed { get; }
16+
17+
/// <inheritdoc />
18+
public bool IsAlive => Y < MaxY;
19+
20+
public Snow(Color color, int maxY, int graphicsWidth)
21+
{
22+
Color = color;
23+
MaxY = maxY;
24+
Y = -2;
25+
Speed = Random.Shared.NextDouble() * 0.5 + 0.75;
26+
Wiggle = Random.Shared.NextDouble() * 100;
27+
Size = Random.Shared.Next(2) + 1;
28+
X = Random.Shared.Next(graphicsWidth + 30);
29+
}
30+
31+
/// <inheritdoc />
32+
public void Update(GameTime gameTime)
33+
{
34+
X -= gameTime.ElapsedGameTime.TotalSeconds * 4 * Size * Speed;
35+
Y += gameTime.ElapsedGameTime.TotalSeconds * 16 * Size * Speed;
36+
Wiggle += gameTime.ElapsedGameTime.TotalSeconds * 2 * Speed / Size;
37+
}
38+
39+
/// <inheritdoc />
40+
public void Draw(GraphicsManager graphics)
41+
{
42+
if (Size < 1)
43+
return;
44+
45+
var pixelX = (int)(X + Math.Cos(Wiggle) * 5.5);
46+
graphics.DrawFilledRectangle(pixelX, (int)Y, Size, Size, Color);
47+
}
48+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using BenMakesGames.PlayPlayMini.Services;
2+
using Microsoft.Xna.Framework;
3+
4+
namespace BenMakesGames.PlayPlayMini.GraphicsExtensions.ParticleEffects;
5+
6+
public sealed class TumblingSprite : IParticle
7+
{
8+
private string SpriteSheet { get; }
9+
private int SpriteIndex { get; }
10+
11+
private double CenterX { get; set; }
12+
private double CenterY { get; set; }
13+
private int MaxY { get; }
14+
private double Angle { get; set; }
15+
private double SpinSpeed { get; }
16+
private double XVelocity { get; set; }
17+
private double YVelocity { get; set; }
18+
19+
/// <inheritdoc />
20+
public bool IsAlive => CenterY < MaxY;
21+
22+
public TumblingSprite(string spriteSheet, int spriteIndex, int x, int y, double xVelocity, double yVelocity, double spinSpeed, int maxY)
23+
{
24+
SpriteSheet = spriteSheet;
25+
SpriteIndex = spriteIndex;
26+
CenterX = x;
27+
CenterY = y;
28+
XVelocity = xVelocity;
29+
YVelocity = yVelocity;
30+
SpinSpeed = spinSpeed;
31+
MaxY = maxY;
32+
}
33+
34+
/// <inheritdoc />
35+
public void Draw(GraphicsManager graphics)
36+
{
37+
graphics.DrawSpriteRotatedAndScaled(SpriteSheet, (int)CenterX, (int)CenterY, SpriteIndex, (float)Angle, 1, Color.White);
38+
}
39+
40+
/// <inheritdoc />
41+
public void Update(GameTime gameTime)
42+
{
43+
CenterX += XVelocity * gameTime.ElapsedGameTime.TotalSeconds * 60;
44+
CenterY += YVelocity * gameTime.ElapsedGameTime.TotalSeconds * 60;
45+
Angle += SpinSpeed * gameTime.ElapsedGameTime.TotalSeconds * 60;
46+
47+
YVelocity += 0.2 * gameTime.ElapsedGameTime.TotalSeconds * 60;
48+
}
49+
}

0 commit comments

Comments
 (0)