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 控件并将其移动到FormKeyPress 事件中。

【问题讨论】:

没有理由不能用 WinForms 来做这件事,虽然它不一定很快。 Winforms 和计时器将是一种非常简单的做事方式。 我可以每秒处理“5 次按键”吗?PictureBox 的使用可以吗? 要渲染图形,您可以使用图片框。我将创建一个位图,并使用 Graphics.FromImage(backbuffer) 绘制到该位图,然后处理图片框的 Paint 事件并在其上绘制 backbuffer。在计时器中,使图片框无效,以便在发生变化时重新绘制。 那么 WPF 画布呢? 【参考方案1】:

这是一个使用WinFormsTimer的简单游戏,使用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)
        
    

【讨论】:

谢谢。我对 cme​​ts 感到困惑,不知道该走哪条路。我打算将项目本身放在一边,并与新事物作斗争 我实现了这段代码。这个想法很好,但是刷新率真的很糟糕,我可以看到重新绘制的速度球从用户的角度来看是丑陋的。我也在尝试使用纯 c#(没有 DirectX 或 XNA)来实现演示 2D 游戏,以用于教育目的。到目前为止仍在挖掘 我通过向表单添加双缓冲解决了这个问题,使用“DoubleBuffered = true” @MehdiLAMRANI 有趣的是,SetStyle 行应该与添加 DoubleBuffered = true 具有相同的效果。【参考方案2】:

如果您想制作动态绘图,您可以使用WPF Canvas 来实现这些目的。它不支持游戏等,但它是一种绘制原始形式和图像的简单方法,就像您在网站中所做的那样。

【讨论】:

【参考方案3】:

.NET winforms 应用的原生渲染框架是GDI+。有很多tutorials online 用于使用 GDI+ 绘制简单的形状/图形

【讨论】:

以上是关于C# 中的简单游戏,只有本机库的主要内容,如果未能解决你的问题,请参考以下文章

一个使用两个线程的简单 C# 游戏循环,这样好吗? [关闭]

第二次作业—单元测试的简单实践

c# 开发的winform软件 怎么样使其只能在xp系统下运行

c#实现简单金山打字小游戏(源码)

使用 iPhone 本机应用程序中的 Xamarin 库

C#基于TCP实现简单游戏客户端