Skip to content

Commit

Permalink
[Helicopter] Reduce flickering
Browse files Browse the repository at this point in the history
Create "Update" function.
In Update, erase only the non-overlapping part between new frame & old frame, then Render the new frame.
Using Update instead of Erase then Render, can reduce the amount of I/O if there's overlapping between two frames.
  • Loading branch information
GopherTheCoder committed May 16, 2024
1 parent 5942b3f commit 1113809
Showing 1 changed file with 42 additions and 28 deletions.
70 changes: 42 additions & 28 deletions Projects/Helicopter/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;

TimeSpan threadSleepTimeSpan = TimeSpan.FromMilliseconds(10);
Expand Down Expand Up @@ -172,8 +173,7 @@
{
if (ufo.Left < width)
{
Console.SetCursorPosition(ufo.Left, ufo.Top);
Erase(ufoRenders[ufo.Frame]);
Update(ufo.Left, ufo.Top, ufo.Left - 1, ufo.Top, ufoRenders[ufo.Frame]);
}
ufo.Left--;
if (ufo.Left <= 0)
Expand All @@ -190,22 +190,25 @@

#region Update Player

bool playerRenderRequired = false;
if (Console.KeyAvailable)
{
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.UpArrow:
Console.SetCursorPosition(player.Left, player.Top);
Render(helicopterRenders[default], true);
player.Top = Math.Max(player.Top - 1, 0);
playerRenderRequired = true;
{
int newTop = Math.Max(player.Top - 1, 0);
Update(player.Left, player.Top, player.Left, newTop,
helicopterRenders[helicopterRender ? 1 : 2]);
player.Top = newTop;
}
break;
case ConsoleKey.DownArrow:
Console.SetCursorPosition(player.Left, player.Top);
Render(helicopterRenders[default], true);
player.Top = Math.Min(player.Top + 1, height - 3);
playerRenderRequired = true;
{
int newTop = Math.Min(player.Top + 1, height - 3);
Update(player.Left, player.Top, player.Left, newTop,
helicopterRenders[helicopterRender ? 1 : 2]);
player.Top = newTop;
}
break;
case ConsoleKey.RightArrow:
bullets.Add(new Bullet
Expand Down Expand Up @@ -302,29 +305,12 @@
{
helicopterRender = !helicopterRender;
stopwatchHelicopter.Restart();
playerRenderRequired = true;
}
if (playerRenderRequired)
{
Console.SetCursorPosition(player.Left, player.Top);
Render(helicopterRenders[helicopterRender ? 1 : 2]);
}

#endregion

#region Render UFOs

foreach (UFO ufo in ufos)
{
if (ufo.Left < width)
{
Console.SetCursorPosition(ufo.Left, ufo.Top);
Render(ufoRenders[ufo.Frame]);
}
}

#endregion

#region Render Bullets

foreach (Bullet bullet in bullets)
Expand All @@ -338,6 +324,34 @@
Thread.Sleep(threadSleepTimeSpan);
}

void Update(int oldLeft, int oldTop, int newLeft, int newTop, string @string)
{
string[] dummy = @string.Split('\n');
int stringHeight = dummy.Count();
int stringWidth = dummy[0].Count();

int oldRight = Math.Min(oldLeft + stringWidth, width);
int oldBottom = Math.Min(oldTop + stringHeight, height);
int newRight = Math.Min(newLeft + stringWidth, width);
int newBottom = Math.Min(newTop + stringHeight, height);

// Erase non-overlapping part of old
for (int x = oldLeft; x < oldRight; x++)
{
for (int y = oldTop; y < oldBottom; y++)
{
if (!(x >= newLeft && x < newRight && y >= newTop && y < newBottom))
{
Console.SetCursorPosition(x, y);
Console.Write(' ');
}
}
}

Console.SetCursorPosition(newLeft, newTop);
Render(@string, true);
}

void Render(string @string, bool renderSpace = false)
{
int x = Console.CursorLeft;
Expand Down

0 comments on commit 1113809

Please # to comment.