Простая игра на C # только с родными библиотеками - PullRequest
5 голосов
/ 20 октября 2011

Я мог бы найти набор обучающих программ по java 2D-играм и обучающих программ по android-играм , которые используют только собственные графические библиотеки .Я ищу что-то подобное в C # (без DirectX или XNA)Я нашел этот скелет игрового цикла , но он не говорит, как визуализировать графику.Целью является моделирование простого электронного устройства.Мне нужно показать какой-то графический вывод, поскольку пользователь быстро «нажимает» на клавиатуре несколько клавиш. Так что это похоже на аркадную игру. Например, Когда пользователь нажимает одну из клавиш со стрелками, указатель (изображение) будет соответственно перемещаться.Я думаю, я не могу сделать это с типичным приложением Windows Forms, могу ли я?Например, используйте элемент управления PictureBox и переместите его в KeyPress событие Form.

Ответы [ 3 ]

15 голосов
/ 20 октября 2011

Вот простая игра, использующая 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)
        }
    }
}
1 голос
/ 20 октября 2011

Собственная структура рендеринга для приложений WinNET .NET GDI + . В Интернете есть множество учебных пособий для рисования простых фигур / графики с использованием GDI +

1 голос
/ 20 октября 2011

Если вы хотите создавать динамические рисунки, вы можете использовать WPF Canvas для этих целей.Он не поддерживает игры или что-то подобное, но это простой способ рисования примитивных форм и изображений, как вы бы делали на веб-сайте.

...