* Apply R# clean-up for reliability - Migrate to NUnit4 Assert.That - Update dependencise versions - Fix LangVersion to 9.0 (until net core migration) - Reformat code - Apply 'var' style (easier for refactoring) - Remove redundant parentheses - Add braces on every condition blocks (1 line) - Uses new null checking patterns - Uses AutoProperties when possible - Uses string scalar type instead of class - Clean usings - Add .orig files in git ignore - Rename some properties to respect defined conventions and US format definition - ID -> Id - BPM -> Bpm - Finish -> End * Update R# settings according to the clean-up made
287 lines
8.8 KiB
C#
287 lines
8.8 KiB
C#
#region license
|
|
// This file is part of Vocaluxe.
|
|
//
|
|
// Vocaluxe is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Vocaluxe is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using VocaluxeLib.Draw;
|
|
|
|
namespace VocaluxeLib.Menu
|
|
{
|
|
class CParticle
|
|
{
|
|
#region private vars
|
|
private readonly int _PartyModeId;
|
|
private readonly string _TextureName;
|
|
private readonly CTextureRef _Texture;
|
|
private SRectF _Rect;
|
|
private float _Size;
|
|
private SColorF _Color;
|
|
private float _Angle; //0..360°
|
|
private readonly float _MaxAge; //[s]
|
|
private float _Age; //[s]
|
|
private readonly float _Vx; //movement speed in x-axis [pix/s]
|
|
private readonly float _Vy; //movement speed in y-axis [pix/s]
|
|
private readonly float _Vr; //rotation speed [rpm]
|
|
private readonly float _Rotation; //start rotation 0..360°
|
|
private readonly float _Vsize; //size changing speed: period [s]
|
|
private float _LastTime;
|
|
private readonly EParticleType _Type;
|
|
|
|
private readonly Stopwatch _Timer = new Stopwatch();
|
|
#endregion private vars
|
|
|
|
#region public vars
|
|
//public bool Visible;
|
|
public float Alpha2 = 1f;
|
|
|
|
public float X
|
|
{
|
|
get { return _Rect.X; }
|
|
set { _Rect.X = value; }
|
|
}
|
|
|
|
public float Y
|
|
{
|
|
get { return _Rect.Y; }
|
|
set { _Rect.Y = value; }
|
|
}
|
|
|
|
public float Size
|
|
{
|
|
get { return _Size; }
|
|
set
|
|
{
|
|
_Rect.W = value;
|
|
_Rect.H = value;
|
|
_Size = value;
|
|
}
|
|
}
|
|
|
|
public float Alpha { get; set; } = 1;
|
|
|
|
public SColorF Color
|
|
{
|
|
get { return _Color; }
|
|
set { _Color = value; }
|
|
}
|
|
|
|
public bool IsAlive
|
|
{
|
|
get { return _Age < _MaxAge || Math.Abs(_MaxAge) < float.Epsilon; }
|
|
}
|
|
#endregion public vars
|
|
|
|
#region Constructors
|
|
public CParticle(int partyModeId, string textureName, SColorF color, float x, float y, float size, float maxage, float z, float vx, float vy, float vr, float vsize,
|
|
EParticleType type)
|
|
{
|
|
_PartyModeId = partyModeId;
|
|
_TextureName = textureName;
|
|
_Color = color;
|
|
_Rect = new SRectF(x, y, size, size, z);
|
|
_Size = size;
|
|
_Vx = vx;
|
|
_Vy = vy;
|
|
_Vr = vr;
|
|
_Vsize = vsize;
|
|
_Type = type;
|
|
|
|
_MaxAge = maxage;
|
|
_Rotation = (float)(CBase.Game.GetRandomDouble() * 360.0);
|
|
}
|
|
|
|
public CParticle(int partyModeId, CTextureRef texture, SColorF color, float x, float y, float size, float maxage, float z, float vx, float vy, float vr, float vsize,
|
|
EParticleType type)
|
|
{
|
|
_PartyModeId = partyModeId;
|
|
_TextureName = string.Empty;
|
|
_Texture = texture;
|
|
_Color = color;
|
|
_Rect = new SRectF(x, y, size, size, z);
|
|
_Size = size;
|
|
_Vx = vx;
|
|
_Vy = vy;
|
|
_Vr = vr;
|
|
_Vsize = vsize;
|
|
_Type = type;
|
|
|
|
_MaxAge = maxage;
|
|
_Rotation = (float)(CBase.Game.GetRandomDouble() * 360.0);
|
|
}
|
|
#endregion Constructors
|
|
|
|
public void Update()
|
|
{
|
|
if (!IsAlive)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!_Timer.IsRunning)
|
|
{
|
|
_Timer.Start();
|
|
}
|
|
|
|
var currentTime = _Timer.ElapsedMilliseconds / 1000f;
|
|
var timediff = currentTime - _LastTime;
|
|
|
|
_Age = currentTime;
|
|
|
|
// update alpha
|
|
if (_MaxAge > 0f)
|
|
{
|
|
switch (_Type)
|
|
{
|
|
case EParticleType.Twinkle:
|
|
Alpha = 1f - _Age / _MaxAge;
|
|
break;
|
|
|
|
case EParticleType.Star:
|
|
Alpha = 1f - _Age / _MaxAge;
|
|
break;
|
|
|
|
case EParticleType.Snow:
|
|
Alpha = (float)Math.Sqrt((Math.Sin(_Age / _MaxAge * Math.PI * 2 - 0.5 * Math.PI) + 1) / 2);
|
|
break;
|
|
|
|
case EParticleType.Flare:
|
|
Alpha = 1f - _Age / _MaxAge;
|
|
break;
|
|
|
|
case EParticleType.PerfNoteStar:
|
|
Alpha = 1f - _Age / _MaxAge;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// update position
|
|
switch (_Type)
|
|
{
|
|
case EParticleType.Twinkle:
|
|
X += _Vx * timediff;
|
|
Y += _Vy * timediff;
|
|
break;
|
|
|
|
case EParticleType.Star:
|
|
X += _Vx * timediff;
|
|
Y += _Vy * timediff;
|
|
break;
|
|
|
|
case EParticleType.Snow:
|
|
var maxy = (int)Math.Round(CBase.Settings.GetRenderH() - _Size * 0.4f);
|
|
|
|
if (Math.Round(Y) < maxy)
|
|
{
|
|
var vdx = 0f;
|
|
if (Math.Abs(_Vx) > float.Epsilon)
|
|
{
|
|
vdx = (float)Math.Sin(currentTime / _Vx * Math.PI);
|
|
}
|
|
|
|
X += _Vx * timediff * (0.5f + vdx);
|
|
|
|
Y += _Vy * timediff * (vdx * vdx / 2f + 0.5f);
|
|
if (Y >= maxy)
|
|
{
|
|
Y = maxy;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case EParticleType.Flare:
|
|
X += _Vx * timediff;
|
|
Y += _Vy * timediff;
|
|
break;
|
|
|
|
case EParticleType.PerfNoteStar:
|
|
X += _Vx * timediff;
|
|
Y += _Vy * timediff;
|
|
break;
|
|
}
|
|
|
|
|
|
// update size
|
|
if (Math.Abs(_Vsize) > float.Epsilon)
|
|
{
|
|
var size = _Size;
|
|
switch (_Type)
|
|
{
|
|
case EParticleType.Twinkle:
|
|
size = _Size * (1f - currentTime / _Vsize);
|
|
break;
|
|
|
|
case EParticleType.Star:
|
|
size = _Size * (1f - currentTime / _Vsize);
|
|
break;
|
|
|
|
case EParticleType.Snow:
|
|
size = _Size * (float)Math.Sqrt((Math.Sin(currentTime / _Vsize * Math.PI * 2 - 0.5 * Math.PI) + 1) / 2);
|
|
break;
|
|
|
|
case EParticleType.Flare:
|
|
size = _Size * (1f - currentTime / _Vsize);
|
|
break;
|
|
|
|
case EParticleType.PerfNoteStar:
|
|
size = _Size * (1f - currentTime / _Vsize);
|
|
break;
|
|
}
|
|
|
|
_Rect.X += (_Rect.W - size) / 2f;
|
|
_Rect.Y += (_Rect.H - size) / 2f;
|
|
_Rect.W = size;
|
|
_Rect.H = size;
|
|
}
|
|
|
|
// update rotation
|
|
if (Math.Abs(_Vr) > 0.01)
|
|
{
|
|
var r = currentTime * _Vr / 60f;
|
|
_Angle = _Rotation + 360f * (r - (float)Math.Floor(r));
|
|
_Rect.Rotation = _Angle;
|
|
}
|
|
|
|
_LastTime = currentTime;
|
|
}
|
|
|
|
public void Pause()
|
|
{
|
|
_Timer.Stop();
|
|
}
|
|
|
|
public void Resume()
|
|
{
|
|
_Timer.Start();
|
|
}
|
|
|
|
public void Draw(bool allMonitors = true)
|
|
{
|
|
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
|
|
if (!string.IsNullOrEmpty(_TextureName))
|
|
// ReSharper restore ConvertIfStatementToConditionalTernaryExpression
|
|
{
|
|
CBase.Drawing.DrawTexture(CBase.Themes.GetSkinTexture(_TextureName, _PartyModeId), _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * Alpha),
|
|
allMonitors);
|
|
}
|
|
else
|
|
{
|
|
CBase.Drawing.DrawTexture(_Texture, _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * Alpha), allMonitors);
|
|
}
|
|
}
|
|
}
|
|
} |