first commit
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace TempleRun;
|
||||
|
||||
/// <summary>
|
||||
/// 主窗体:负责游戏循环(定时器 + 高精度计时)、键盘输入、双缓冲绘制调度。
|
||||
/// </summary>
|
||||
public class GameForm : Form
|
||||
{
|
||||
private readonly GameWorld _world = new();
|
||||
private readonly System.Windows.Forms.Timer _timer;
|
||||
private readonly Stopwatch _watch = Stopwatch.StartNew();
|
||||
|
||||
private double _lastTime;
|
||||
private double _fpsAccum;
|
||||
private int _frameCount;
|
||||
private bool _showFps;
|
||||
|
||||
public GameForm()
|
||||
{
|
||||
Text = "神庙逃亡 · Temple Run (WinForms)";
|
||||
ClientSize = new Size(1024, 720);
|
||||
MinimumSize = new Size(760, 540);
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
BackColor = Color.FromArgb(12, 12, 20);
|
||||
DoubleBuffered = true;
|
||||
ResizeRedraw = true;
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint
|
||||
| ControlStyles.UserPaint
|
||||
| ControlStyles.OptimizedDoubleBuffer, true);
|
||||
|
||||
try { Icon = BuildIcon(); } catch { /* 图标失败不影响运行 */ }
|
||||
|
||||
_lastTime = _watch.Elapsed.TotalSeconds;
|
||||
|
||||
_timer = new System.Windows.Forms.Timer { Interval = 15 }; // ≈66Hz
|
||||
_timer.Tick += OnTick;
|
||||
_timer.Start();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ 主循环
|
||||
private void OnTick(object sender, EventArgs e)
|
||||
{
|
||||
double now = _watch.Elapsed.TotalSeconds;
|
||||
float dt = (float)(now - _lastTime);
|
||||
_lastTime = now;
|
||||
|
||||
if (dt <= 0f) return;
|
||||
if (dt > 0.06f) dt = 0.06f; // 卡顿/拖动窗口后不产生穿模
|
||||
|
||||
// FPS 统计
|
||||
_frameCount++;
|
||||
_fpsAccum += dt;
|
||||
if (_fpsAccum >= 0.5)
|
||||
{
|
||||
_world.Fps = (float)(_frameCount / _fpsAccum);
|
||||
_frameCount = 0;
|
||||
_fpsAccum = 0;
|
||||
}
|
||||
|
||||
_world.Update(dt);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
GameRenderer.Draw(e.Graphics, ClientSize.Width, ClientSize.Height, _world, _showFps);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ 输入
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
Keys key = keyData & Keys.KeyCode;
|
||||
|
||||
if (key == Keys.F1) { _showFps = !_showFps; Invalidate(); return true; }
|
||||
if (key == Keys.F11)
|
||||
{
|
||||
WindowState = WindowState == FormWindowState.Maximized
|
||||
? FormWindowState.Normal : FormWindowState.Maximized;
|
||||
return true;
|
||||
}
|
||||
if (key == Keys.F12) { _world.Muted = !_world.Muted; return true; }
|
||||
|
||||
if (_world.HandleKey(key)) return true;
|
||||
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
protected override void OnMouseClick(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseClick(e);
|
||||
// 鼠标左键也能触发"开始/重开",方便触屏设备
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
if (_world.State == RunState.Ready) _world.Start();
|
||||
else if (_world.State == RunState.GameOver && _world.CanRestart)
|
||||
{
|
||||
_world.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
_timer.Stop();
|
||||
_timer.Dispose();
|
||||
GameRenderer.ResetCache();
|
||||
base.OnFormClosed(e);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ 图标
|
||||
private static Icon BuildIcon()
|
||||
{
|
||||
using var bmp = new Bitmap(32, 32);
|
||||
using (var g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
g.Clear(Color.Transparent);
|
||||
using (var bg = new SolidBrush(Color.FromArgb(46, 34, 28)))
|
||||
g.FillEllipse(bg, 0, 0, 31, 31);
|
||||
using (var gold = new SolidBrush(Cfg.Gold))
|
||||
g.FillEllipse(gold, 7, 7, 18, 18);
|
||||
using (var dark = new Pen(Cfg.GoldDark, 2.4f))
|
||||
g.DrawEllipse(dark, 7, 7, 18, 18);
|
||||
using (var hi = new SolidBrush(Color.FromArgb(230, 255, 250, 220)))
|
||||
g.FillEllipse(hi, 11, 10, 5, 4);
|
||||
}
|
||||
return Icon.FromHandle(bmp.GetHicon());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user