C# 中的简单游戏,只有本机库
Posted
技术标签:
【中文标题】C# 中的简单游戏,只有本机库【英文标题】:Simple Game in C# with only native libraries 【发布时间】:2011-10-20 10:45:39 【问题描述】:我可以找到一组 java 2D game tutorials 和 android game tutorials,它们仅使用原生图形库。
我正在 C# 中寻找类似的东西(没有 DirectX 或 XNA)
我找到了 this game loop skeleton ,但它没有说明如何渲染图形。
目标是模拟一个简单的电子设备。我需要在用户快速“按下”键盘上的一些键时显示一些图形输出。因此它看起来像一个街机游戏。例如 当用户按下其中一个箭头键时,指针(图像)将相应移动。
我想我不能使用典型的 Windows 窗体应用程序来执行此操作,可以吗?
例如,使用PictureBox
控件并将其移动到Form
的KeyPress
事件中。
【问题讨论】:
没有理由不能用 WinForms 来做这件事,虽然它不一定很快。 Winforms 和计时器将是一种非常简单的做事方式。 我可以每秒处理“5 次按键”吗?PictureBox 的使用可以吗? 要渲染图形,您可以使用图片框。我将创建一个位图,并使用 Graphics.FromImage(backbuffer) 绘制到该位图,然后处理图片框的 Paint 事件并在其上绘制 backbuffer。在计时器中,使图片框无效,以便在发生变化时重新绘制。 那么 WPF 画布呢? 【参考方案1】:这是一个使用WinForms
和Timer
的简单游戏,使用Graphics
进行绘制(封装了GDI+)。
它添加了一个每 10 毫秒“滴答”一次的计时器。它执行游戏逻辑的每个滴答声,然后绘制到屏幕外位图。这与在链接中的示例中使用连续循环相反。
表单单独处理关键事件(而不是像 GetKeyState
这样处理)
当表单被调整大小时,当它第一次加载时,它会创建正确大小的后缓冲位图。
创建一个新表单并将所有代码替换为以下代码。使用箭头键控制球。没有死亡的概念。
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsGame
public partial class Form1 : Form
Bitmap Backbuffer;
const int BallAxisSpeed = 2;
Point BallPos = new Point(30, 30);
Point BallSpeed = new Point(BallAxisSpeed, BallAxisSpeed);
const int BallSize = 50;
public Form1()
InitializeComponent();
this.SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true);
Timer GameTimer = new Timer();
GameTimer.Interval = 10;
GameTimer.Tick += new EventHandler(GameTimer_Tick);
GameTimer.Start();
this.ResizeEnd += new EventHandler(Form1_CreateBackBuffer);
this.Load += new EventHandler(Form1_CreateBackBuffer);
this.Paint += new PaintEventHandler(Form1_Paint);
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
void Form1_KeyDown(object sender, KeyEventArgs e)
if (e.KeyCode == Keys.Left)
BallSpeed.X = -BallAxisSpeed;
else if (e.KeyCode == Keys.Right)
BallSpeed.X = BallAxisSpeed;
else if (e.KeyCode == Keys.Up)
BallSpeed.Y = -BallAxisSpeed; // Y axis is downwards so -ve is up.
else if (e.KeyCode == Keys.Down)
BallSpeed.Y = BallAxisSpeed;
void Form1_Paint(object sender, PaintEventArgs e)
if (Backbuffer != null)
e.Graphics.DrawImageUnscaled(Backbuffer, Point.Empty);
void Form1_CreateBackBuffer(object sender, EventArgs e)
if (Backbuffer != null)
Backbuffer.Dispose();
Backbuffer = new Bitmap(ClientSize.Width, ClientSize.Height);
void Draw()
if (Backbuffer != null)
using (var g = Graphics.FromImage(Backbuffer))
g.Clear(Color.White);
g.FillEllipse(Brushes.Black, BallPos.X - BallSize / 2, BallPos.Y - BallSize / 2, BallSize, BallSize);
Invalidate();
void GameTimer_Tick(object sender, EventArgs e)
BallPos.X += BallSpeed.X;
BallPos.Y += BallSpeed.Y;
Draw();
// TODO: Add the notion of dying (disable the timer and show a message box or something)
【讨论】:
谢谢。我对 cmets 感到困惑,不知道该走哪条路。我打算将项目本身放在一边,并与新事物作斗争 我实现了这段代码。这个想法很好,但是刷新率真的很糟糕,我可以看到重新绘制的速度球从用户的角度来看是丑陋的。我也在尝试使用纯 c#(没有 DirectX 或 XNA)来实现演示 2D 游戏,以用于教育目的。到目前为止仍在挖掘 我通过向表单添加双缓冲解决了这个问题,使用“DoubleBuffered = true” @MehdiLAMRANI 有趣的是,SetStyle
行应该与添加 DoubleBuffered = true
具有相同的效果。【参考方案2】:
如果您想制作动态绘图,您可以使用WPF Canvas 来实现这些目的。它不支持游戏等,但它是一种绘制原始形式和图像的简单方法,就像您在网站中所做的那样。
【讨论】:
【参考方案3】:.NET winforms 应用的原生渲染框架是GDI+。有很多tutorials online 用于使用 GDI+ 绘制简单的形状/图形
【讨论】:
以上是关于C# 中的简单游戏,只有本机库的主要内容,如果未能解决你的问题,请参考以下文章
一个使用两个线程的简单 C# 游戏循环,这样好吗? [关闭]