using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class UserControl1 : UserControl
{
readonly Rectangle DocRect = new Rectangle(-25000, -25000, 50000, 50000);
volatile bool IsRunning = true;
long CurrentFrame = 0;
double Fps = 0.0;
public UserControl1()
{
ResizeRedraw = false;
InitializeComponent();
if (DesignMode)
IsRunning = false;
}
void Tick()
{
}
void Render()
{
var form = this.FindForm();
if (form != null)
form.Text = $"{Fps}";
Invalidate();
}
protected override void OnPaintBackground(PaintEventArgs e) {/**/}
BufferedGraphics Buffer = null;
Size BufferSize = new Size(0, 0);
protected override void OnPaint(PaintEventArgs e)
{
if (Buffer == null || BufferSize != ClientSize)
{
Buffer = BufferedGraphicsManager.Current.Allocate(e.Graphics, ClientRectangle);
BufferSize = ClientSize;
}
Graphics g = Buffer.Graphics;
g.Clear(Color.FromArgb(24, 24, 24));
g.ResetTransform();
var mxt = 1.0F / Math.Max(1.0F, CurrentFrame/30.0F);
g.TranslateTransform(ClientSize.Width / 2, ClientSize.Height / 2);
g.ScaleTransform(mxt, mxt);
g.TranslateTransform(CurrentFrame, 0.0F);
g.FillRectangle(new SolidBrush(Color.FromArgb(45, 45, 48)), DocRect);
for (var v = DocRect.Top; v <= DocRect.Bottom; v += 25)
{
g.DrawLine(new Pen(Color.FromArgb(32, 32, 32)), v, DocRect.Top, v, DocRect.Bottom);
g.DrawLine(new Pen(Color.FromArgb(32, 32, 32)), DocRect.Left, v, DocRect.Right, v);
}
for (var v = DocRect.Top; v <= DocRect.Bottom; v += 100)
{
g.DrawLine(new Pen(Color.FromArgb(63, 63, 70)), v, DocRect.Top, v, DocRect.Bottom);
g.DrawLine(new Pen(Color.FromArgb(63, 63, 70)), DocRect.Left, v, DocRect.Right, v);
}
for (var v = DocRect.Top; v <= DocRect.Bottom; v += 400)
{
g.DrawLine(new Pen(Color.FromArgb(171, 171, 171)), v, DocRect.Top, v, DocRect.Bottom);
g.DrawLine(new Pen(Color.FromArgb(171, 171, 171)), DocRect.Left, v, DocRect.Right, v);
}
Buffer.Render(e.Graphics);
}
void GameLoop()
{
Stopwatch gameLoopTicks = Stopwatch.StartNew();
long lastTime = gameLoopTicks.ElapsedTicks;
double amountOfTicks = 30.0;
double ns = Stopwatch.Frequency/amountOfTicks;
double delta = 0;
long timer = gameLoopTicks.ElapsedMilliseconds;
int frames = 0;
while (IsRunning)
{
long now = gameLoopTicks.ElapsedTicks;
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1)
{
this.Invoke(new Action(() => Tick()));
CurrentFrame++;
frames++;
delta--;
}
this.Invoke(new Action(() => Render()));
if (gameLoopTicks.ElapsedMilliseconds - timer > 1000)
{
timer += 1000;
Fps = frames;
frames = 0;
}
}
}
private void UserControl1_Load(object sender, EventArgs e)
{
Task.Run(new Action(() => GameLoop()));
}
}
}