Skip to content

Commit

Permalink
Encapsulate quake state into single object
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed Jan 27, 2021
1 parent 6b70cb4 commit 3c38020
Showing 1 changed file with 80 additions and 47 deletions.
127 changes: 80 additions & 47 deletions EndlessClient/Rendering/Map/MapRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ public class MapRenderer : DrawableGameComponent, IMapRenderer
private readonly IConfigurationProvider _configurationProvider;
private readonly IMouseCursorRenderer _mouseCursorRenderer;
private readonly IRenderOffsetCalculator _renderOffsetCalculator;
private readonly Random _random;

private RenderTarget2D _mapBaseTarget, _mapObjectTarget;
private SpriteBatch _sb;
private MapTransitionState _mapTransitionState = MapTransitionState.Default;
private int? _lastMapChecksum;

private Optional<MapQuakeState> _quakeState;

private bool MouseOver
{
get
Expand Down Expand Up @@ -78,7 +79,6 @@ private bool MouseOver
_configurationProvider = configurationProvider;
_mouseCursorRenderer = mouseCursorRenderer;
_renderOffsetCalculator = renderOffsetCalculator;
_random = new Random();
}

public override void Initialize()
Expand Down Expand Up @@ -143,54 +143,32 @@ public void StartMapTransition()

public void StartEarthquake(byte strength)
{
_hasQuake = true;
_quakeMagnitude = strength;
_quakeState = _quakeTick = 0;
_quakeOffset = 0;
_quakeOffsetTarget = 16 + 3 * _random.Next(2, _quakeMagnitude * 2);
_quakeState = new MapQuakeState(strength);
}

// when quake:
// 1. determine offset target (random from on magnitude/2 -> magnitude)
// 2. update every 8 ticks toward target
// 3. when target reached, determine new target (random based on magnitude)
// 4. flip direction
// 5. keep going until specific number of frames has elapsed

private bool _hasQuake;
private int _quakeMagnitude;

private int _quakeState;
private int _quakeTick;

private float _quakeOffset;
private float _quakeOffsetTarget;

private void UpdateQuakeState()
{
if (!_hasQuake)
// when quake:
// 1. determine offset target
// 2. incrementally make offset approach closer to the target offset
// 3. when offset target reached, determine new target (random based on magnitude)
// 4. flip direction
// 5. keep going until specific number of "direction flips" has elapsed

if (!_quakeState.HasValue)
return;

_quakeOffset += _quakeOffsetTarget / 4f;
_quakeTick++;
_quakeState = _quakeState.Value.NextOffset();

if (Math.Abs(_quakeOffset) > Math.Abs(_quakeOffsetTarget))
var quakeState = _quakeState.Value;
if (quakeState.OffsetReached)
{
_quakeState++;
_quakeTick = 0;

var flip = -_quakeOffsetTarget / Math.Abs(_quakeOffsetTarget);
_quakeOffset = _quakeOffsetTarget - 1;
_quakeOffsetTarget = 16 + 3 * _random.Next(0, (int)(_quakeMagnitude * 1.5));
_quakeOffsetTarget *= flip;
_quakeState = quakeState.NextState();
}

if (_quakeState > 10 + _quakeMagnitude*2)
if (quakeState.Done)
{
_hasQuake = false;
_quakeState = _quakeTick = 0;
_quakeOffset = 0;
_quakeOffsetTarget = 0;
_quakeState = Optional<MapQuakeState>.Empty;
}
}

Expand Down Expand Up @@ -283,18 +261,21 @@ private void DrawToSpriteBatch(SpriteBatch spriteBatch, GameTime gameTime)
{
spriteBatch.Begin();

spriteBatch.Draw(_mapBaseTarget, GetGroundLayerDrawPosition() + new Vector2(_quakeOffset, 0), Color.White);
var offset = _quakeState.HasValue ? _quakeState.Value.Offset : 0;

spriteBatch.Draw(_mapBaseTarget, GetGroundLayerDrawPosition() + new Vector2(offset, 0), Color.White);
DrawBaseLayers(spriteBatch);

_mouseCursorRenderer.Draw(spriteBatch, new Vector2(_quakeOffset, 0));
_mouseCursorRenderer.Draw(spriteBatch, new Vector2(offset, 0));

spriteBatch.Draw(_mapObjectTarget, new Vector2(_quakeOffset, 0), Color.White);
spriteBatch.Draw(_mapObjectTarget, new Vector2(offset, 0), Color.White);

spriteBatch.End();
}

private void DrawBaseLayers(SpriteBatch spriteBatch)
{
var offset = _quakeState.HasValue ? _quakeState.Value.Offset : 0;
var renderBounds = _mapRenderDistanceCalculator.CalculateRenderBounds(_characterProvider.MainCharacter, _currentMapProvider.CurrentMap);

for (var row = renderBounds.FirstRow; row <= renderBounds.LastRow; row++)
Expand All @@ -306,7 +287,7 @@ private void DrawBaseLayers(SpriteBatch spriteBatch)
foreach (var renderer in _mapEntityRendererProvider.BaseRenderers)
{
if (renderer.CanRender(row, col))
renderer.RenderElementAt(spriteBatch, row, col, alpha, new Vector2(_quakeOffset, 0));
renderer.RenderElementAt(spriteBatch, row, col, alpha, new Vector2(offset, 0));
}
}
}
Expand Down Expand Up @@ -380,17 +361,69 @@ protected override void Dispose(bool disposing)

internal struct MapTransitionState
{
public static MapTransitionState Default => new MapTransitionState(Optional<DateTime>.Empty, 0);
internal static MapTransitionState Default => new MapTransitionState(Optional<DateTime>.Empty, 0);

public Optional<DateTime> StartTime { get; }
internal Optional<DateTime> StartTime { get; }

public int TransitionMetric { get; }
internal int TransitionMetric { get; }

public MapTransitionState(Optional<DateTime> startTime, int transitionMetric)
internal MapTransitionState(Optional<DateTime> startTime, int transitionMetric)
: this()
{
StartTime = startTime;
TransitionMetric = transitionMetric;
}
}

internal struct MapQuakeState
{
private static readonly Random _random = new Random();

internal static MapQuakeState Default => new MapQuakeState();

internal int Magnitude { get; }

internal float Offset { get; }

internal float OffsetTarget { get; }

internal bool OffsetReached => Math.Abs(Offset) >= Math.Abs(OffsetTarget);

internal int Flips { get; }

internal int FlipsMax => Magnitude == 0 ? 0 : 10 + Magnitude * 2;

internal bool Done => Flips >= FlipsMax;

internal MapQuakeState(int magnitude)
: this(magnitude, 0, 0) { }

private MapQuakeState(int magnitude, float offset, int flips)
: this(magnitude, offset, NewOffsetTarget(magnitude), flips) { }

private MapQuakeState(int magnitude, float offset, float offsetTarget, int flips)
{
Magnitude = magnitude;
Offset = offset;
OffsetTarget = offsetTarget;
Flips = flips;
}

internal MapQuakeState NextOffset()
{
var nextOffset = Offset + OffsetTarget / 4f;
return new MapQuakeState(Magnitude, nextOffset, OffsetTarget, Flips);
}

internal MapQuakeState NextState()
{
var flip = -OffsetTarget / Math.Abs(OffsetTarget);
var offset = OffsetTarget + 1*flip;
var nextOffsetTarget = NewOffsetTarget(Magnitude) * flip;

return new MapQuakeState(Magnitude, offset, nextOffsetTarget, Flips + 1);
}

private static float NewOffsetTarget(int magnitude) => 16 + 3 * _random.Next(0, (int)(magnitude * 1.5));
}
}

0 comments on commit 3c38020

Please sign in to comment.