Игра змейка windows forms c

  • Subject:
    C# Tutorials
  • Learning Time: 2 hours

Hi Welcome to this tutorial. This tutorial is an updated version of the C# Snakes game tutorial we have done before on the website.  This video tutorial will explain all of the core components needed to make this classic game in windows form in visual studio with C# programming language. We wont be using any oher game frameworks to make this work however we will be using some OOP programming practices in this tutorial. Everything you need to know and how to use them inside of the game effectively is explained in the tutorial.

Lesson objectives –

  1. Make a full snakes game in visual studio
  2. Using custom classes to load and reload default settings
  3. Using custom classes to draw the snake and food to the game
  4. Working with Keyboard controls
  5. Keeping score and high score in the current game session
  6. Able to take snap of the game when it ends
  7. Starting and Restarting the game to replay

Full Video Tutorial on How to make the classic snake game in Visual Studio with C#

 
Download Snake Game Project Tutorial on MOOICT GitHub
 

Source Code –

Circle Class –

This class will help us draw circles to the form, we will use this one to determine the X and Y position of the circles in the screen. This will be used for both the SNAKE and the Food objects inside of the game.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Classic_Snakes_Game_Tutorial___MOO_ICT
{
    class Circle
    {
        public int X { get; set; }
        public int Y { get; set; }

        public Circle()
        {
            X = 0;
            Y = 0;
        }
    }
}

Settings Class

This is the settings class for the game. This class will be used to load up the default settings for the game objects only. It will load the size in height and width of the circles that will be drawn to the project also the direction the snake should be moving when the game initially loads.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Classic_Snakes_Game_Tutorial___MOO_ICT
{
    class Settings
    {

        public static int Width { get; set; }
        public static int Height { get; set; }

        public static string directions;

        public Settings()
        {
            Width = 16;
            Height = 16;
            directions = "left";
        }
    }
}

Main Form C# Scripts

This is the main form1.cs code. In this script we have given all of the instructions necessary for the game and how it will behave when the game loads up. We have several events in the code below for example the Key Down, Key Up, Timer,  2 Click Events and a Paint Event. Also we have 3 custom functions such as Restart Game, Game Over and Eat Food function for the snake.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Drawing.Imaging; // add this for the JPG compressor

namespace Classic_Snakes_Game_Tutorial___MOO_ICT
{
    public partial class Form1 : Form
    {

        private List<Circle> Snake = new List<Circle>();
        private Circle food = new Circle();

        int maxWidth;
        int maxHeight;

        int score;
        int highScore;

        Random rand = new Random();

        bool goLeft, goRight, goDown, goUp;


        public Form1()
        {
            InitializeComponent();

            new Settings();
        }

        private void KeyIsDown(object sender, KeyEventArgs e)
        {

            if (e.KeyCode == Keys.Left && Settings.directions != "right")
            {
                goLeft = true;
            }
            if (e.KeyCode == Keys.Right && Settings.directions != "left")
            {
                goRight = true;
            }
            if (e.KeyCode == Keys.Up && Settings.directions != "down")
            {
                goUp = true;
            }
            if (e.KeyCode == Keys.Down && Settings.directions != "up")
            {
                goDown = true;
            }



        }

        private void KeyIsUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Left)
            {
                goLeft = false;
            }
            if (e.KeyCode == Keys.Right)
            {
                goRight = false;
            }
            if (e.KeyCode == Keys.Up)
            {
                goUp = false;
            }
            if (e.KeyCode == Keys.Down)
            {
                goDown = false;
            }
        }

        private void StartGame(object sender, EventArgs e)
        {
            RestartGame();
        }

        private void TakeSnapShot(object sender, EventArgs e)
        {
            Label caption = new Label();
            caption.Text = "I scored: " + score + " and my Highscore is " + highScore + " on the Snake Game from MOO ICT";
            caption.Font = new Font("Ariel", 12, FontStyle.Bold);
            caption.ForeColor = Color.Purple;
            caption.AutoSize = false;
            caption.Width = picCanvas.Width;
            caption.Height = 30;
            caption.TextAlign = ContentAlignment.MiddleCenter;
            picCanvas.Controls.Add(caption);

            SaveFileDialog dialog = new SaveFileDialog();
            dialog.FileName = "Snake Game SnapShot MOO ICT";
            dialog.DefaultExt = "jpg";
            dialog.Filter = "JPG Image File | *.jpg";
            dialog.ValidateNames = true;

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                int width = Convert.ToInt32(picCanvas.Width);
                int height = Convert.ToInt32(picCanvas.Height);
                Bitmap bmp = new Bitmap(width, height);
                picCanvas.DrawToBitmap(bmp, new Rectangle(0,0, width, height));
                bmp.Save(dialog.FileName, ImageFormat.Jpeg);
                picCanvas.Controls.Remove(caption);
            }





        }

        private void GameTimerEvent(object sender, EventArgs e)
        {
            // setting the directions

            if (goLeft)
            {
                Settings.directions = "left";
            }
            if (goRight)
            {
                Settings.directions = "right";
            }
            if (goDown)
            {
                Settings.directions = "down";
            }
            if (goUp)
            {
                Settings.directions = "up";
            }
            // end of directions

            for (int i = Snake.Count - 1; i >= 0; i--)
            {
                if (i == 0)
                {

                    switch (Settings.directions)
                    {
                        case "left":
                            Snake[i].X--;
                            break;
                        case "right":
                            Snake[i].X++;
                            break;
                        case "down":
                            Snake[i].Y++;
                            break;
                        case "up":
                            Snake[i].Y--;
                            break;
                    }

                    if (Snake[i].X < 0)
                    {
                        Snake[i].X = maxWidth;
                    }
                    if (Snake[i].X > maxWidth)
                    {
                        Snake[i].X = 0;
                    }
                    if (Snake[i].Y < 0)
                    {
                        Snake[i].Y = maxHeight;
                    }
                    if (Snake[i].Y > maxHeight)
                    {
                        Snake[i].Y = 0;
                    }


                    if (Snake[i].X == food.X && Snake[i].Y == food.Y)
                    {
                        EatFood();
                    }

                    for (int j = 1; j < Snake.Count; j++)
                    {

                        if (Snake[i].X == Snake[j].X && Snake[i].Y == Snake[j].Y)
                        {
                            GameOver();
                        }

                    }


                }
                else
                {
                    Snake[i].X = Snake[i - 1].X;
                    Snake[i].Y = Snake[i - 1].Y;
                }
            }
            picCanvas.Invalidate();
        }

        private void UpdatePictureBoxGraphics(object sender, PaintEventArgs e)
        {
            Graphics canvas = e.Graphics;

            Brush snakeColour;

            for (int i = 0; i < Snake.Count; i++)
            {
                if (i == 0)
                {
                    snakeColour = Brushes.Black;
                }
                else
                {
                    snakeColour = Brushes.DarkGreen;
                }

                canvas.FillEllipse(snakeColour, new Rectangle
                    (
                    Snake[i].X * Settings.Width,
                    Snake[i].Y * Settings.Height,
                    Settings.Width, Settings.Height
                    ));
            }


            canvas.FillEllipse(Brushes.DarkRed, new Rectangle
            (
            food.X * Settings.Width,
            food.Y * Settings.Height,
            Settings.Width, Settings.Height
            ));
        }

        private void RestartGame()
        {
            maxWidth = picCanvas.Width / Settings.Width - 1;
            maxHeight = picCanvas.Height / Settings.Height - 1;

            Snake.Clear();

            startButton.Enabled = false;
            snapButton.Enabled = false;
            score = 0;
            txtScore.Text = "Score: " + score;

            Circle head = new Circle { X = 10, Y = 5 };
            Snake.Add(head); // adding the head part of the snake to the list

            for (int i = 0; i < 100; i++)
            {
                Circle body = new Circle();
                Snake.Add(body);
            }

            food = new Circle { X = rand.Next(2, maxWidth), Y = rand.Next(2, maxHeight)};

            gameTimer.Start();

        }

        private void EatFood()
        {
            score += 1;

            txtScore.Text = "Score: " + score;

            Circle body = new Circle
            {
                X = Snake[Snake.Count - 1].X,
                Y = Snake[Snake.Count - 1].Y
            };

            Snake.Add(body);

            food = new Circle { X = rand.Next(2, maxWidth), Y = rand.Next(2, maxHeight) };
        }

        private void GameOver()
        {
            gameTimer.Stop();
            startButton.Enabled = true;
            snapButton.Enabled = true;

            if (score > highScore)
            {
                highScore = score;

                txtHighScore.Text = "High Score: " + Environment.NewLine + highScore;
                txtHighScore.ForeColor = Color.Maroon;
                txtHighScore.TextAlign = ContentAlignment.MiddleCenter;
            }
        }
    }
}

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

1
branch

0
tags


Code

  • Use Git or checkout with SVN using the web URL.

  • Open with GitHub Desktop

  • Download ZIP

Latest commit

Files

Permalink

Failed to load latest commit information.

Type

Name

Latest commit message

Commit time

C# Tutorial — Create a Classic Snakes Game in Visual Studio UPDATED

The classic snake game project is now updated and added with some extra features to boost your game play and power up your C# programming skills using the Windows Form Framework in Visual Studio.

From the last project the following were added to the new and updated one

  1. You can go through the walls from up/down/left/right and appear on the other side with reversed speed
  2. You can Take keep the score and save a highscore from any game plays session
  3. You can take snap shot of the game and save it as JPG file with the Score and Highscore as a caption in the image
  4. Start and Restart game with a button on run time

Link to the Website —

C# Tutorial – How to make a Classic Snakes Game with Windows form and Visual Studio [Updated]

Full Video Tutorial on the official Channel —

YouTube Video for Classic Snake Game Tutorial in C#

About

Create the fun classic snakes game using C# in Windows Form. We will be using little elements of OOP programming to make this project, the code, project files and video tutorial is all presented with this project here

Topics

Resources

Readme

License

Apache-2.0 license

Activity

Stars

4
stars

Watchers

1
watching

Forks

7
forks

Запись от 8Observer8 размещена 10.02.2019 в 22:56

Обновил(-а) 8Observer8 11.05.2023 в 01:21

Blog content

We will place OpenTK.GLControl on the Form to draw graphics with modern shader OpenGL 3.1.

This is a gif animation of the final result of our work:

Название: Snake_WinFormsOpenGL31CSharp_MovingSnake.gif
Просмотров: 1553

Размер: 20.7 Кб

Note. I take ideas from this tutorial: Python Snake Game

Please, download this empty project: Snake_WinFormsOpenGL31CSharp.zip. It includes OpenTK.dll and OpenTK.GLControl.dll

Or if you know how to add libraries from References and how to add Control to Toolbox you can download these two DLL’s: OpenTK.zip and OpenTK.GLControl.zip You can search in the Internet how to do it.

Current Form1.css file:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Windows.Forms;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
 
namespace Snake
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            // Centers the form on the current screen
            CenterToScreen();
        }
 
        private void glControl_Load(object sender, EventArgs e)
        {
            glControl.MakeCurrent();
 
            // Set a color for clear the glControl
            GL.ClearColor(Color4.Black);
        }
 
        private void glControl_Paint(object sender, PaintEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            Draw();
 
            glControl.SwapBuffers();
        }
 
        private void Draw()
        {
            // Draw game entities here
        }
    }
}

These commands just clear a render canvas (glControl) with a black color. RGB values (0f, 0f, 0f) mean the black color. If you write (1f, 0f, 0f) — it will be a red color or if you write (1f, 1f, 1f) — it will be a white color. You can choose your own value of normalized color using this color calculator.

Название: Snake_WinFormsOpenGL31CSharp_glControl.png
Просмотров: 1486

Размер: 1.7 Кб

I set «FormBorderStyle» to «FixedDialog». You cannot change size of the window with the mouse. And I set «MaximizeBox» to «False». You cannot maximize the window by click on «Maximize» button on the window.

Let’s draw a square. We need to write a pair of shaders: a vertex shader and a fragment shader. This pair will be associated with a shader program object that we will create too. The pair of shaders and the shader program will placed in a video card memory. We will create an array of vertices of our square and vertex buffer object (VBO) on the video card memory. We will move the array of coordinates of vertices to VBO. The vertex shader will be executed for every vertex when we will call the function: drawArrays(). The vertex shader just set coordinates for vertices. The fragment shader will be executed for every pixel of the square and set a color for every pixel.

This book is one of the best for start: WebGL Programming Guide

Название: Snake_WinFormsOpenGL31CSharp_Square.png
Просмотров: 1407

Размер: 2.0 Кб

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.Windows.Forms;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
 
namespace Snake
{
    public partial class Form1 : Form
    {
        private int _shaderProgram;
        private int _uColorLocation;
 
        public Form1()
        {
            InitializeComponent();
 
            // Centers the form on the current screen
            CenterToScreen();
        }
 
        private void glControl_Load(object sender, EventArgs e)
        {
            glControl.MakeCurrent();
 
            // Set a color for clear the glControl
            GL.ClearColor(Color4.Black);
 
            // Initialize shaders and get a shader program
            _shaderProgram = InitShadersAndGetProgram();
            if (_shaderProgram < 0) return;
 
            // Initialize vertex buffers
            InitVertexBuffers();
 
            _uColorLocation = GL.GetUniformLocation(_shaderProgram, "uColor");
            if (_uColorLocation < 0)
            {
                MessageBox.Show("Failed to get uColorLocation variable");
                return;
            }
 
            // Set a triangle color
            GL.Uniform3(_uColorLocation, 0.1f, 0.8f, 0.3f);
        }
 
        private void glControl_Paint(object sender, PaintEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            Draw();
 
            glControl.SwapBuffers();
        }
 
        private void Draw()
        {
            // Draw game entities here
            DrawSquare(0, 0, Color4.LightCoral, 10);
        }
 
        private void DrawSquare(int x, int y, Color4 color, int size)
        {
            // Set color to fragment shader
            GL.Uniform3(_uColorLocation, color.R, color.G, color.B);
            // Draw Rectangle
            GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
        }
 
        private int InitShadersAndGetProgram()
        {
            string vertexShaderSource =
                "#version 140\n" +
                "in vec2 aPosition;" +
                "void main()" +
                "{" +
                "    gl_Position = vec4(aPosition, 1.0, 1.0);" +
                "}";
 
            string fragmentShaderSource =
                "#version 140\n" +
                "out vec4 fragColor;" +
                "uniform vec3 uColor;" +
                "void main()" +
                "{" +
                "    fragColor = vec4(uColor, 1.0);" +
                "}";
 
            // Vertex Shader
            int vShader = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vShader, vertexShaderSource);
            GL.CompileShader(vShader);
            // Check compilation
            string vShaderInfo = GL.GetShaderInfoLog(vShader);
            if (!vShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(vShaderInfo);
                return -1;
            }
 
            // Fragment Shader
            int fShader = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(fShader, fragmentShaderSource);
            GL.CompileShader(fShader);
            string fShaderInfo = GL.GetShaderInfoLog(fShader);
            if (!fShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(fShaderInfo);
                return -1;
            }
 
            int program = GL.CreateProgram();
            GL.AttachShader(program, vShader);
            GL.AttachShader(program, fShader);
            GL.LinkProgram(program);
            GL.UseProgram(program);
 
            return program;
        }
 
        private void InitVertexBuffers()
        {
            float[] vertices = new float[]
            {
                -0.5f, -0.5f,
                0.5f, -0.5f,
                -0.5f, 0.5f,
                0.5f, 0.5f
            };
 
            int vbo;
            GL.GenBuffers(1, out vbo);
 
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            // Get an array size in bytes
            int sizeInBytes = vertices.Length * sizeof(float);
            // Send the vertex array to a video card memory
            GL.BufferData(BufferTarget.ArrayBuffer, sizeInBytes, vertices, BufferUsageHint.StaticDraw);
            // Config
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(0);
        }
    }
}

We need to set a coordinate system: [0, 20]. I want to have (0, 0) in top left corner. Y axis will have a direction from top to bottom. And I add ability to set a size and a position of square:

Название: Snake_WinFormsOpenGL31CSharp_SetNewCoordSystem.png
Просмотров: 1348

Размер: 1.7 Кб

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
using System;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
 
namespace Snake
{
    public partial class Form1 : Form
    {
        private int _shaderProgram;
        private int _uColorLocation;
 
        private int _gameFieldWidth = 20;
        private int _gameFieldHeight = 20;
 
        private int _uScaleMatrixLocation;
        private int _uTranslateMatrixLocation;
        private Matrix4 _scaleMatrix;
        private Matrix4 _translateMatrix;
 
        public Form1()
        {
            InitializeComponent();
 
            // Centers the form on the current screen
            CenterToScreen();
        }
 
        private void glControl_Load(object sender, EventArgs e)
        {
            glControl.MakeCurrent();
 
            // Set a color for clear the glControl
            GL.ClearColor(Color4.Black);
 
            // Initialize shaders and get a shader program
            _shaderProgram = InitShadersAndGetProgram();
            if (_shaderProgram < 0) return;
 
            // Initialize vertex buffers
            InitVertexBuffers();
 
            _uColorLocation = GL.GetUniformLocation(_shaderProgram, "uColor");
            if (_uColorLocation < 0)
            {
                MessageBox.Show("Failed to get uColorLocation variable");
                return;
            }
 
            // Set a coordinate cell
            int uProjMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uProjMatrix");
            if (uProjMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uProjMatrix variable");
                return;
            }
            Matrix4 projMatrix = Matrix4.CreateOrthographicOffCenter(0f, _gameFieldWidth, _gameFieldHeight, 0f, -100f, 100f);
            GL.UniformMatrix4(uProjMatrixLocation, false, ref projMatrix);
 
            // Get uScaleMatrix Location
            _uScaleMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uScaleMatrix");
            if (_uScaleMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uScaleMatrix variable");
                return;
            }
            _scaleMatrix = new Matrix4();
 
            // Get uTranslateMatrix Location
            _uTranslateMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uTranslateMatrix");
            if (_uTranslateMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uTranslateMatrix variable");
                return;
            }
            _translateMatrix = new Matrix4();
 
            GL.Viewport(0, 0, glControl.Width, glControl.Height);
        }
 
        private void glControl_Paint(object sender, PaintEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            Draw();
 
            glControl.SwapBuffers();
        }
 
        private void Draw()
        {
            // Draw game entities here
            DrawSquare(1, 1, Color4.LightCoral, 1);
        }
 
        private void DrawSquare(int x, int y, Color4 color, int size = 1)
        {
            // Set color to fragment shader
            GL.Uniform3(_uColorLocation, color.R, color.G, color.B);
            // Set a size of the square
            _scaleMatrix = Matrix4.CreateScale(size);
            GL.UniformMatrix4(_uScaleMatrixLocation, false, ref _scaleMatrix);
            // Set a position of the square
            _translateMatrix = Matrix4.CreateTranslation(new Vector3(x, y, 1f));
            GL.UniformMatrix4(_uTranslateMatrixLocation, false, ref _translateMatrix);
            // Draw Rectangle
            GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
        }
 
        private int InitShadersAndGetProgram()
        {
            string vertexShaderSource =
                "#version 140\n" +
                "in vec2 aPosition;" +
                "uniform mat4 uProjMatrix;" +
                "uniform mat4 uScaleMatrix;" +
                "uniform mat4 uTranslateMatrix;" +
                "void main()" +
                "{" +
                "    gl_Position = uProjMatrix * uTranslateMatrix * uScaleMatrix * vec4(aPosition, 1.0, 1.0);" +
                "}";
 
            string fragmentShaderSource =
                "#version 140\n" +
                "out vec4 fragColor;" +
                "uniform vec3 uColor;" +
                "void main()" +
                "{" +
                "    fragColor = vec4(uColor, 1.0);" +
                "}";
 
            // Vertex Shader
            int vShader = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vShader, vertexShaderSource);
            GL.CompileShader(vShader);
            // Check compilation
            string vShaderInfo = GL.GetShaderInfoLog(vShader);
            if (!vShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(vShaderInfo);
                return -1;
            }
 
            // Fragment Shader
            int fShader = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(fShader, fragmentShaderSource);
            GL.CompileShader(fShader);
            string fShaderInfo = GL.GetShaderInfoLog(fShader);
            if (!fShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(fShaderInfo);
                return -1;
            }
 
            int program = GL.CreateProgram();
            GL.AttachShader(program, vShader);
            GL.AttachShader(program, fShader);
            GL.LinkProgram(program);
            GL.UseProgram(program);
 
            return program;
        }
 
        private void InitVertexBuffers()
        {
            float[] vertices = new float[]
            {
                0f, 0f,
                0f, 1f,
                1f, 0f,
                1f, 1f
            };
 
            int vbo;
            GL.GenBuffers(1, out vbo);
 
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            // Get an array size in bytes
            int sizeInBytes = vertices.Length * sizeof(float);
            // Send the vertex array to a video card memory
            GL.BufferData(BufferTarget.ArrayBuffer, sizeInBytes, vertices, BufferUsageHint.StaticDraw);
            // Config
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(0);
        }
    }
}

Each game must have a game loop that will be called by timer. I created the GameLoop method that just prints «Hello, World!» to the debug console every 500 ms:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Form1()
{
    InitializeComponent();
 
    // Centers the form on the current screen
    CenterToScreen();
 
    // Create a timer for the GameLoop method
    var timer = new Timer();
    timer.Tick += GameLoop;
    timer.Interval = 500;
    timer.Start();
}
 
private void GameLoop(object sender, System.EventArgs e)
{
    Console.WriteLine("Hello, World!");
}

Update() method will have updates for snake cell coordinates and etc. The Draw() method will have only draw methods for game entities. Method glControl.Invalidate() will provoke a call of Draw() method.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
private void GameLoop(object sender, System.EventArgs e)
{
    // Update coordinates of game entities
    // or check collisions
    Update();
 
    // This method calls glControl_Paint
    glControl.Invalidate();
}
 
private void Update()
{
    Console.WriteLine("Game entities coords was updated");
}
 
private void glControl_Paint(object sender, PaintEventArgs e)
{
    GL.Clear(ClearBufferMask.ColorBufferBit);
 
    Draw();
 
    glControl.SwapBuffers();
}
 
private void Draw()
{
    DrawFood();
    DrawSnake();
}
 
private void DrawSnake()
{
    Console.WriteLine("Snake was drawn");
    DrawSquare(2, 1, Color4.LightGreen);
}
 
private void DrawFood()
{
    Console.WriteLine("Food was drawn");
}

List data structure is ideal for keeping snake cells coordinates:

C#
1
2
3
4
5
// Snake list of (x, y) positions
private List<Point> _snake = new List<Point>()
    {
        new Point(1, 1)
    };

Point(1, 1) — it is position of the head.

Method for drawing the snake:

C#
1
2
3
4
5
6
7
private void DrawSnake()
{
    foreach (var cell in _snake)
    {
        DrawSquare(cell.X, cell.Y, Color4.LightGreen);
    }
}

For moving the snake we need to create the «snakeDir» variable:

C#
1
2
// Snake movement direction
private Point _snakeDir = new Point(1, 0);

The snake moving is very simple. Please, read comments:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void Update()
{
    // Calc a new position of the head
    Point newHeadPosition = new Point(
        _snake[0].X + _snakeDir.X,
        _snake[0].Y + _snakeDir.Y
    );
 
    // Insert new position in the beginning of the snake list
    _snake.Insert(0, newHeadPosition);
 
    // Remove the last element
    _snake.RemoveAt(_snake.Count - 1);
}

Название: Snake_WinFormsOpenGL31CSharp_MovingHead.gif
Просмотров: 1458

Размер: 19.1 Кб

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
using System;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
using System.Collections.Generic;
using System.Drawing;
 
namespace Snake
{
    public partial class Form1 : Form
    {
        private int _shaderProgram;
        private int _uColorLocation;
 
        private int _gameFieldWidth = 20;
        private int _gameFieldHeight = 20;
 
        private int _uScaleMatrixLocation;
        private int _uTranslateMatrixLocation;
        private Matrix4 _scaleMatrix;
        private Matrix4 _translateMatrix;
 
        // Snake list of (x, y) positions
        private List<Point> _snake = new List<Point>()
            {
                new Point(1, 1)
            };
 
        // Snake movement direction
        private Point _snakeDir = new Point(1, 0);
 
        public Form1()
        {
            InitializeComponent();
 
            // Centers the form on the current screen
            CenterToScreen();
 
            // Create a timer for the GameLoop method
            var timer = new Timer();
            timer.Tick += GameLoop;
            timer.Interval = 500;
            timer.Start();
        }
 
        private void GameLoop(object sender, System.EventArgs e)
        {
            // Update coordinates of game entities
            // or check collisions
            Update();
 
            // This method calls glControl_Paint
            glControl.Invalidate();
        }
 
        private void Update()
        {
            // Calc a new position of the head
            Point newHeadPosition = new Point(
                _snake[0].X + _snakeDir.X,
                _snake[0].Y + _snakeDir.Y
            );
 
            // Insert new position in the beginning of the snake list
            _snake.Insert(0, newHeadPosition);
 
            // Remove the last element
            _snake.RemoveAt(_snake.Count - 1);
        }
 
        private void glControl_Paint(object sender, PaintEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            Draw();
 
            glControl.SwapBuffers();
        }
 
        private void Draw()
        {
            DrawFood();
            DrawSnake();
        }
 
        private void DrawSnake()
        {
            foreach (var cell in _snake)
            {
                DrawSquare(cell.X, cell.Y, Color4.LightGreen);
            }
        }
 
        private void DrawFood()
        {
            Console.WriteLine("Food was drawn");
        }
 
        private void glControl_Load(object sender, EventArgs e)
        {
            glControl.MakeCurrent();
 
            // Set a color for clear the glControl
            GL.ClearColor(Color4.Black);
 
            // Initialize shaders and get a shader program
            _shaderProgram = InitShadersAndGetProgram();
            if (_shaderProgram < 0) return;
 
            // Initialize vertex buffers
            InitVertexBuffers();
 
            _uColorLocation = GL.GetUniformLocation(_shaderProgram, "uColor");
            if (_uColorLocation < 0)
            {
                MessageBox.Show("Failed to get uColorLocation variable");
                return;
            }
 
            // Set a coordinate cell
            int uProjMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uProjMatrix");
            if (uProjMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uProjMatrix variable");
                return;
            }
            Matrix4 projMatrix = Matrix4.CreateOrthographicOffCenter(0f, _gameFieldWidth, _gameFieldHeight, 0f, -100f, 100f);
            GL.UniformMatrix4(uProjMatrixLocation, false, ref projMatrix);
 
            // Get uScaleMatrix Location
            _uScaleMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uScaleMatrix");
            if (_uScaleMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uScaleMatrix variable");
                return;
            }
            _scaleMatrix = new Matrix4();
 
            // Get uTranslateMatrix Location
            _uTranslateMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uTranslateMatrix");
            if (_uTranslateMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uTranslateMatrix variable");
                return;
            }
            _translateMatrix = new Matrix4();
 
            GL.Viewport(0, 0, glControl.Width, glControl.Height);
        }
 
        private void DrawSquare(int x, int y, Color4 color, int size = 1)
        {
            // Set color to fragment shader
            GL.Uniform3(_uColorLocation, color.R, color.G, color.B);
            // Set a size of the square
            _scaleMatrix = Matrix4.CreateScale(size);
            GL.UniformMatrix4(_uScaleMatrixLocation, false, ref _scaleMatrix);
            // Set a position of the square
            _translateMatrix = Matrix4.CreateTranslation(new Vector3(x, y, 1f));
            GL.UniformMatrix4(_uTranslateMatrixLocation, false, ref _translateMatrix);
            // Draw Rectangle
            GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
        }
 
        private int InitShadersAndGetProgram()
        {
            string vertexShaderSource =
                "#version 140\n" +
                "in vec2 aPosition;" +
                "uniform mat4 uProjMatrix;" +
                "uniform mat4 uScaleMatrix;" +
                "uniform mat4 uTranslateMatrix;" +
                "void main()" +
                "{" +
                "    gl_Position = uProjMatrix * uTranslateMatrix * uScaleMatrix * vec4(aPosition, 1.0, 1.0);" +
                "}";
 
            string fragmentShaderSource =
                "#version 140\n" +
                "out vec4 fragColor;" +
                "uniform vec3 uColor;" +
                "void main()" +
                "{" +
                "    fragColor = vec4(uColor, 1.0);" +
                "}";
 
            // Vertex Shader
            int vShader = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vShader, vertexShaderSource);
            GL.CompileShader(vShader);
            // Check compilation
            string vShaderInfo = GL.GetShaderInfoLog(vShader);
            if (!vShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(vShaderInfo);
                return -1;
            }
 
            // Fragment Shader
            int fShader = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(fShader, fragmentShaderSource);
            GL.CompileShader(fShader);
            string fShaderInfo = GL.GetShaderInfoLog(fShader);
            if (!fShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(fShaderInfo);
                return -1;
            }
 
            int program = GL.CreateProgram();
            GL.AttachShader(program, vShader);
            GL.AttachShader(program, fShader);
            GL.LinkProgram(program);
            GL.UseProgram(program);
 
            return program;
        }
 
        private void InitVertexBuffers()
        {
            float[] vertices = new float[]
            {
                0f, 0f,
                0f, 1f,
                1f, 0f,
                1f, 1f
            };
 
            int vbo;
            GL.GenBuffers(1, out vbo);
 
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            // Get an array size in bytes
            int sizeInBytes = vertices.Length * sizeof(float);
            // Send the vertex array to a video card memory
            GL.BufferData(BufferTarget.ArrayBuffer, sizeInBytes, vertices, BufferUsageHint.StaticDraw);
            // Config
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(0);
        }
    }
}

I will explain eating food later. But you can read comments in the code.

This is the result:

Название: Snake_WinFormsOpenGL31CSharp_MovingSnake.gif
Просмотров: 1553

Размер: 20.7 Кб

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
using System;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
using System.Collections.Generic;
using System.Drawing;
 
namespace Snake
{
    public partial class Form1 : Form
    {
        private int _shaderProgram;
        private int _uColorLocation;
 
        private int _gameFieldWidth = 20;
        private int _gameFieldHeight = 20;
 
        private int _uScaleMatrixLocation;
        private int _uTranslateMatrixLocation;
        private Matrix4 _scaleMatrix;
        private Matrix4 _translateMatrix;
 
        // Snake list of (x, y) positions
        private List<Point> _snake = new List<Point>()
            {
                new Point(1, 1)
            };
 
        // Snake movement direction
        private Point _snakeDir = new Point(1, 0);
 
        // Food
        private Point _food = new Point();
 
        // Random generator
        private Random _rnd = new Random();
 
        public Form1()
        {
            InitializeComponent();
 
            // Centers the form on the current screen
            CenterToScreen();
 
            // Generate an initial random position for the food
            GenerateFood();
 
            // Create a timer for the GameLoop method
            var timer = new Timer();
            timer.Tick += GameLoop;
            timer.Interval = 200;
            timer.Start();
        }
 
        private void GameLoop(object sender, System.EventArgs e)
        {
            // Update coordinates of game entities
            // or check collisions
            Update();
 
            // This method calls glControl_Paint
            glControl.Invalidate();
        }
 
        private void Update()
        {
            // Calc a new position of the head
            Point newHeadPosition = new Point(
                _snake[0].X + _snakeDir.X,
                _snake[0].Y + _snakeDir.Y
            );
 
            // Insert new position in the beginning of the snake list
            _snake.Insert(0, newHeadPosition);
 
            // Remove the last element
            _snake.RemoveAt(_snake.Count - 1);
 
            // Check collision with the food
            if (_snake[0].X == _food.X &&
                _snake[0].Y == _food.Y)
            {
                // Add new element in the snake
                _snake.Add(new Point(_food.X, _food.Y));
 
                // Generate a new food position
                GenerateFood();
            }
        }
 
        private void glControl_Paint(object sender, PaintEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            Draw();
 
            glControl.SwapBuffers();
        }
 
        private void Draw()
        {
            DrawFood();
            DrawSnake();
        }
 
        private void DrawSnake()
        {
            foreach (var cell in _snake)
            {
                DrawSquare(cell.X, cell.Y, Color4.LightGreen);
            }
        }
 
        private void DrawFood()
        {
            DrawSquare(_food.X, _food.Y, Color.OrangeRed);
        }
 
        private void GenerateFood()
        {
            _food.X = _rnd.Next(0, _gameFieldWidth);
            _food.Y = _rnd.Next(0, _gameFieldHeight);
        }
 
        private void glControl_Load(object sender, EventArgs e)
        {
            glControl.MakeCurrent();
 
            // Set a color for clear the glControl
            GL.ClearColor(Color4.Black);
 
            // Initialize shaders and get a shader program
            _shaderProgram = InitShadersAndGetProgram();
            if (_shaderProgram < 0) return;
 
            // Initialize vertex buffers
            InitVertexBuffers();
 
            _uColorLocation = GL.GetUniformLocation(_shaderProgram, "uColor");
            if (_uColorLocation < 0)
            {
                MessageBox.Show("Failed to get uColorLocation variable");
                return;
            }
 
            // Set a coordinate cell
            int uProjMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uProjMatrix");
            if (uProjMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uProjMatrix variable");
                return;
            }
            Matrix4 projMatrix = Matrix4.CreateOrthographicOffCenter(0f, _gameFieldWidth, _gameFieldHeight, 0f, -100f, 100f);
            GL.UniformMatrix4(uProjMatrixLocation, false, ref projMatrix);
 
            // Get uScaleMatrix Location
            _uScaleMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uScaleMatrix");
            if (_uScaleMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uScaleMatrix variable");
                return;
            }
            _scaleMatrix = new Matrix4();
 
            // Get uTranslateMatrix Location
            _uTranslateMatrixLocation = GL.GetUniformLocation(_shaderProgram, "uTranslateMatrix");
            if (_uTranslateMatrixLocation < 0)
            {
                MessageBox.Show("Failed to get a location uTranslateMatrix variable");
                return;
            }
            _translateMatrix = new Matrix4();
 
            GL.Viewport(0, 0, glControl.Width, glControl.Height);
        }
 
        private void DrawSquare(int x, int y, Color4 color, int size = 1)
        {
            // Set color to fragment shader
            GL.Uniform3(_uColorLocation, color.R, color.G, color.B);
            // Set a size of the square
            _scaleMatrix = Matrix4.CreateScale(size);
            GL.UniformMatrix4(_uScaleMatrixLocation, false, ref _scaleMatrix);
            // Set a position of the square
            _translateMatrix = Matrix4.CreateTranslation(new Vector3(x, y, 1f));
            GL.UniformMatrix4(_uTranslateMatrixLocation, false, ref _translateMatrix);
            // Draw Rectangle
            GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
        }
 
        private int InitShadersAndGetProgram()
        {
            string vertexShaderSource =
                "#version 140\n" +
                "in vec2 aPosition;" +
                "uniform mat4 uProjMatrix;" +
                "uniform mat4 uScaleMatrix;" +
                "uniform mat4 uTranslateMatrix;" +
                "void main()" +
                "{" +
                "    gl_Position = uProjMatrix * uTranslateMatrix * uScaleMatrix * vec4(aPosition, 1.0, 1.0);" +
                "}";
 
            string fragmentShaderSource =
                "#version 140\n" +
                "out vec4 fragColor;" +
                "uniform vec3 uColor;" +
                "void main()" +
                "{" +
                "    fragColor = vec4(uColor, 1.0);" +
                "}";
 
            // Vertex Shader
            int vShader = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vShader, vertexShaderSource);
            GL.CompileShader(vShader);
            // Check compilation
            string vShaderInfo = GL.GetShaderInfoLog(vShader);
            if (!vShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(vShaderInfo);
                return -1;
            }
 
            // Fragment Shader
            int fShader = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(fShader, fragmentShaderSource);
            GL.CompileShader(fShader);
            string fShaderInfo = GL.GetShaderInfoLog(fShader);
            if (!fShaderInfo.StartsWith("No errors"))
            {
                MessageBox.Show(fShaderInfo);
                return -1;
            }
 
            int program = GL.CreateProgram();
            GL.AttachShader(program, vShader);
            GL.AttachShader(program, fShader);
            GL.LinkProgram(program);
            GL.UseProgram(program);
 
            return program;
        }
 
        private void InitVertexBuffers()
        {
            float[] vertices = new float[]
            {
                0f, 0f,
                0f, 1f,
                1f, 0f,
                1f, 1f
            };
 
            int vbo;
            GL.GenBuffers(1, out vbo);
 
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            // Get an array size in bytes
            int sizeInBytes = vertices.Length * sizeof(float);
            // Send the vertex array to a video card memory
            GL.BufferData(BufferTarget.ArrayBuffer, sizeInBytes, vertices, BufferUsageHint.StaticDraw);
            // Config
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(0);
        }
 
        private void glControl_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            switch (e.KeyChar)
            {
                case 'w':
                    _snakeDir.X = 0;
                    _snakeDir.Y = -1;
                    break;
                case 'a':
                    _snakeDir.X = -1;
                    _snakeDir.Y = 0;
                    break;
                case 's':
                    _snakeDir.X = 0;
                    _snakeDir.Y = 1;
                    break;
                case 'd':
                    _snakeDir.X = 1;
                    _snakeDir.Y = 0;
                    break;
            }
            //glControl.Invalidate();
        }
    }
}
  • Remove From My Forums
  • Question

  • Hi 

    I need help the make a classic snake game in windows form application. The most guides for the snake game are in console so they don’t really help. If you could post the basic code (or all of the code) i would be very thankfull.  

    • Moved by

      Tuesday, March 17, 2015 5:03 PM
      Winforms related

Answers

  • This is a very broad question. For that reason, I will provide a broad answer. If you need code specific help, please post code specific questions. 

    This is my way of thinking and it may not be the best solution:

    1- You need to create a virtual grid on your form. 

    Let say you have a 800 x 800 form and you will divide this into 20 x 20 grids. 

    Each grid will be 40 px width and height. 

    Create a grid class to hold x, y values. 

    2- For your snake you need to create a snake class. 

    Snake class will hold the length of the snake.

    3 — Game class:

    This will be the main container class that holds snake, timer (if available), bates for the snake, game logic.

    4- Game logic Class:

    in your game logic class, define how your snake behaves for example when a user clicks up button while snakes direction is left.

    5- Form elements:

    Each grid will hold a picture box and your picture box will be filled with different elements such as:

    — plain

    — bate

    — snake

    6 — Collusion detection:

    This will be a part of game logic but it will be better if you have separate collusion detection class.

    • Proposed as answer by
      Carl Cai
      Wednesday, March 18, 2015 4:28 AM
    • Marked as answer by
      Carl Cai
      Wednesday, March 25, 2015 5:51 AM

  • Hi,

    Please try to follow
    Val10’s ideas and write it by yourself.

    You also can put some keywords like «C# snake  game » in the search engine.

    It will shows many resluts about it.  You could choose to refer someone to get some hints.

    This project seems meet your requirements. Please take a look

    #Snake Game in C#

    http://www.c-sharpcorner.com/uploadfile/prink_mob/snake-game-in-C-Sharp/

    If all of these are not what you want, please submit a sample request to
    http://code.msdn.microsoft.com/windowsapps/site/requests.

    If you encountered any issue when implementing it, you could open new thread
    for each specific issue.

    Best regards,

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.

    Click
    HERE to participate the survey.

    • Edited by
      Kristin Xie
      Tuesday, March 17, 2015 8:17 AM
    • Proposed as answer by
      Carl Cai
      Wednesday, March 18, 2015 4:28 AM
    • Marked as answer by
      Carl Cai
      Wednesday, March 25, 2015 5:51 AM

    • Proposed as answer by
      Carl Cai
      Wednesday, March 18, 2015 4:28 AM
    • Marked as answer by
      Carl Cai
      Wednesday, March 25, 2015 5:51 AM
    • Proposed as answer by
      Carl Cai
      Wednesday, March 18, 2015 4:28 AM
    • Marked as answer by
      Carl Cai
      Wednesday, March 25, 2015 5:51 AM

stuff and things

Menu

  • Home
  • His
  • Hers
  • Contact

Browse: Home
» 2014
» February
» Classic Snake Game using C# Windows Forms

Classic Snake Game using C# Windows Forms

February 21, 2014 · by admin · in His

snake_screenshot Everybody likes the classic snake game. Here is a simple C# implementation built for funsies.

admin

Chris Grgich-Tran is a Development Manager from Brisbane, Australia. When he’s not dad-ing it up, he works with some very talented people.

More Posts

Follow Me:
TwitterFacebookLinkedInGoogle PlusFlickrYouTube

Comments

Tags: .net, c#, code, games, windows forms

Comments are closed, but trackbacks and pingbacks are open.

← Subtle waiting effect for buttons

Unlocking the BRZ Sat Nav Unit – Eclipse AVN 827GA →

Google Ads

About

A blog about stuff as most blogs generally are.

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Copyright © 2023 grgichtran

Powered by WordPress and Origin

  • Игра не растягивается на весь экран windows 10
  • Игра висит в диспетчере задач но не запускается windows 10
  • Игра не раскрывается на весь экран windows 10
  • Игра не разворачивается на весь экран windows 10
  • Игра зависла и не сворачивается как закрыть windows 10