32【WinForm】WinForm应用C#语言实现贪吃蛇游戏

简介: 初始界面:

@TOC

前言


一、游戏效果

初始界面:
在这里插入图片描述

开始游戏界面:
在这里插入图片描述

游戏失败界面:
在这里插入图片描述

游戏暂停界面:
在这里插入图片描述

二、界面设计

在这里插入图片描述
在这里插入图片描述

三、代码

Snake类:

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

namespace SnakeGame
{
   
   
    public class Snake
    {
   
   
        public int SnkWidth = 16;//蛇的每个点的宽度
        public const int SNAKE_MAX_LENGTH = 500;//最大长度
        public Point[] SnkLct=new Point[SNAKE_MAX_LENGTH];
        public int SnkLen;//蛇的长度
        public byte SnkDrt = 2;//方向 1上 2右 3下 4 左

        /// <summary>
        /// 蛇的属性初始化
        /// </summary>
        public void SnakeInit()
        {
   
   
            int start = 0;
            SnkLen = 5;
            for (int i = 5; i >= 1; i--)
            {
   
   
                SnkLct[i].X = start;
                SnkLct[i].Y = 32;
                start += SnkWidth;

            }

            SnkDrt = 2;//初始方向
        }

        /// <summary>
        /// 判断蛇头是否撞到蛇尾
        /// </summary>
        /// <returns></returns>
        public bool CheckSnakeHeadInSnakeBody()
        {
   
   
            return CheckInSnakeBody(SnkLct[1].X, SnkLct[1].Y, 2);
        }

        /// <summary>
        /// 检查输入的坐标是否在蛇的身上
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="snkHead"></param>
        /// <returns></returns>
        public bool CheckInSnakeBody(int x, int y, int snkHead)
        {
   
   
            for (int i = snkHead; i <= SnkLen; i++)
            {
   
   
                if (x == SnkLct[i].X && y == SnkLct[i].Y)
                {
   
   
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 判断是否撞墙
        /// </summary>
        /// <returns></returns>
        public bool CheckSnakeBodyInFrm()
        {
   
   
            if (SnkLct[1].X >= 560 || SnkLct[1].Y >= 512 || SnkLct[1].X < 0 || SnkLct[1].Y < 32)
            {
   
   
                return true;
            }
            else
            {
   
   
                return false;
            }
        }

        /// <summary>
        /// 判断是否吃到食物
        /// </summary>
        /// <param name="FoodLct"></param>
        /// <returns></returns>
        public bool EatedFood(Point FoodLct)
        {
   
   
            if (SnkLct[1].X == FoodLct.X && SnkLct[1].Y == FoodLct.Y)
            {
   
   
                if (SnkLen < SNAKE_MAX_LENGTH)
                {
   
   
                    SnkLen++;
                    SnkLct[SnkLen].X=SnkLct[SnkLen - 1].X;
                    SnkLct[SnkLen].Y = SnkLct[SnkLen - 1].Y;
                }
                return true;
            }
            else
            {
   
   
                return false;
            }
        }

        /// <summary>
        /// 蛇的控制前进
        /// </summary>
        /// <param name="drc"></param>
        public void Forward(int drc)
        {
   
   
            Point tmp = new Point();
            tmp.X = SnkLct[1].X;
            tmp.Y = SnkLct[1].Y;
            for (int i = SnkLen; i > 1; i--)
            {
   
   
                //蛇头动,把蛇头的坐标逐个后移(蛇身往蛇头方向位移)
                SnkLct[i].X = SnkLct[i - 1].X;
                SnkLct[i].Y = SnkLct[i - 1].Y;   
            }
            switch (drc)
            {
   
   
                //根据设置的方向,计算蛇头的坐标
                case 1:
                    SnkLct[1].X = tmp.X;
                    SnkLct[1].Y = tmp.Y - SnkWidth;
                    break;//上
                case 2:
                    SnkLct[1].X = tmp.X + SnkWidth;
                    SnkLct[1].Y = tmp.Y;
                    break;//右
                case 3:
                    SnkLct[1].X = tmp.X;
                    SnkLct[1].Y = tmp.Y + SnkWidth;
                    break;//下
                case 4:
                    SnkLct[1].X = tmp.X - SnkWidth;
                    SnkLct[1].Y = tmp.Y;
                    break;//下
            }  
        }
    }
}

Game类:

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

namespace SnakeGame
{
   
   
    //经过了两层封装,先封装了蛇这个类,然后蛇以对象的形式在Game类中调用,在接口处只调用游戏类就行了。也是三层封装的思想。

    //三层封装为:表现层、逻辑层、实体层
    public class Game
    {
   
   
        public Point FoodLct = new Point();//缓存食物的坐标
        public int score = 0;//得分
        public bool pause;//暂停
        public Snake snake = new Snake();

        /// <summary>
        /// 游戏初始化
        /// </summary>
        public void GameInit()
        {
   
   
            pause = false;
            score = 0;
            snake.SnakeInit();//初始化蛇
        }

        /// <summary>
        /// 随即显示食物
        /// </summary>
        public void ShowFood()
        {
   
   
            Random rmd = new Random();
            int x, y;
            x = rmd.Next(0, 35) * snake.SnkWidth;
            y = 32 + rmd.Next(0,  30) * snake.SnkWidth;
            while (snake.CheckInSnakeBody(x, y, 1))
            {
   
   
                x = rmd.Next(0, 32) * snake.SnkWidth;
                y = 32 + rmd.Next(0, 30) * snake.SnkWidth;
            }
            FoodLct.X = x;
            FoodLct.Y = y;
        }

        /// <summary>
        /// 分数
        /// </summary>
        /// <returns></returns>
        public bool AddScore()
        {
   
   
            if (snake.EatedFood(FoodLct))
            {
   
   
                score += 10;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断游戏是否结束
        /// </summary>
        /// <returns></returns>
        public bool Dead()
        {
   
   
            return snake.CheckSnakeBodyInFrm() || snake.CheckSnakeHeadInSnakeBody();
        }
    }
}

主程序:

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;

namespace SnakeGame
{
   
   
    public partial class Form1 : Form
    {
   
   
        public Form1()
        {
   
   
            InitializeComponent();
        }

        Game game = new Game();

        /// <summary>
        /// 绘制一个方块
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private void DrawShape(int x, int y)
        {
   
   
            Graphics g = CreateGraphics();
            Pen pen = new Pen(Color.Green, 1);
            SolidBrush brush = new SolidBrush(Color.GreenYellow);
            g.DrawRectangle(pen, x, y, 15, 15);
            g.FillRectangle(brush, x, y, 15,15);
        }

        /// <summary>
        /// 开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiStart_Click(object sender, EventArgs e)
        {
   
   
            tsmiPause.Enabled = true;
            game.GameInit();
            timerMove.Start();
            game.ShowFood();
            lblFood.Location = game.FoodLct;
        }

        /// <summary>
        /// 暂停
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiPause_Click(object sender, EventArgs e)
        {
   
   
            if (game.pause == false)
            {
   
   
                game.pause = true;
                timerMove.Enabled = false;
            }
            else
            {
   
   
                game.pause = false;
                timerMove.Enabled = true;
            }
            tsmiPause.Checked = game.pause;
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsmiStop_Click(object sender, EventArgs e)
        {
   
   
            Application.Exit();
        }

        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
   
   
            timerMove.Interval = 150;
            tsmiPause.Enabled = false;
        }

        /// <summary>
        /// 时间事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerMove_Tick(object sender, EventArgs e)
        {
   
   
            if (game.score < 100)
            {
   
   
                timerMove.Interval = 150;
            }
            else if (game.score < 150)
            {
   
   
                timerMove.Interval = 100;
            }
            else
            {
   
   
                timerMove.Interval = 50;
            }

            Graphics g = CreateGraphics();
            g.Clear(Color.DarkKhaki);//清除整个画面
            game.snake.Forward(game.snake.SnkDrt);

            for (int i = 1; i <= game.snake.SnkLen; i++)
            {
   
   
                DrawShape(game.snake.SnkLct[i].X, game.snake.SnkLct[i].Y);
            }

            if (game.AddScore())
            {
   
   
                game.ShowFood();
                lblFood.Location = game.FoodLct;
            }
            this.Text = this.Text.Substring(0, this.Text.IndexOf(": ") + 9) + this.game.score.ToString();
            if (game.Dead())
            {
   
   
                timerMove.Enabled = false;
                tsmiPause.Enabled = false;
                MessageBox.Show("游戏结束!\n" + "得分:" + game.score, "", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        /// <summary>
        /// 方向键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
   
   
            if (game.pause == false)
            {
   
   
                string key = e.KeyCode.ToString();
                switch (key)
                {
   
   
                    //按上方向键 或小键盘的8键时,向上移动一单元格
                    case "Up":
                        {
   
    
                            //正在向下走时,不允许向上,下面相同
                            if (game.snake.SnkDrt != 3)
                            {
   
   
                                game.snake.SnkDrt = 1;
                            }
                            break;
                        }
                    case "Right":
                        {
   
   
                            if (game.snake.SnkDrt != 4)
                            {
   
   
                                game.snake.SnkDrt = 2;
                            }
                            break;
                        }
                    case "Down":
                        {
   
   
                            if (game.snake.SnkDrt != 1)
                            {
   
   
                                game.snake.SnkDrt = 3;
                            }
                            break;
                        }
                    case "Left":
                        {
   
   
                            if (game.snake.SnkDrt != 2)
                            {
   
   
                                game.snake.SnkDrt = 4; 
                            }
                            break;
                        }
                }
            }
        }


    }
}

总结

这个程序不仅实现了贪吃蛇游戏,也体现了面向对象封装的思想,即先封装“蛇”实体类,然后封装“游戏”逻辑类,最后在窗体中调用Game类,Game类调用Snake类,体现三层架构的思想:实体层、逻辑层、表现层。

目录
相关文章
|
6月前
|
C# 图形学
C#之四十九 游戏编程周每日总结
C#之四十九 游戏编程周每日总结
32 0
|
1月前
|
存储 C# 开发工具
22.C# 中使用变量记录玩家创建的角色名:实现与游戏角色的互动
22.C# 中使用变量记录玩家创建的角色名:实现与游戏角色的互动
14 0
|
1月前
|
数据挖掘 C# 开发工具
采用C#语言开发的全套医院体检系统PEIS源码功能介绍
体检系统,是专为体检中心/医院体检科等体检机构,专门开发的全流程管理系统,通过软件实现检测仪器数据自动提取,内置多级医生工作台,细化工作将体检检查结果汇总,生成体检报告登记到计算机系统中。通过软件系统进行数据分析统计与评判以及建立体检相关的体检档案。从而实现体检流程的信息化,提高工作效率,减少手动结果录入的一些常犯错误。 在实际应用中,医院体检系统能够解决传统体检中手工操作带来的问题,如工作量大、效率低下、易漏检、重检或错检等。通过与医院信息系统(如HIS、LIS、PACS等)的连接,系统能够满足体检中心的日常工作流程,提供更好的管理、统计和查询分析功能。同时,基于网络基础的系统可以在网上传输
27 1
|
7月前
|
编译器 C# 数据库
C#之二十二 WIN应用程序的安装部署
C#之二十二 WIN应用程序的安装部署
36 0
|
3月前
|
定位技术 C# 图形学
Unity和C#游戏编程入门:创建迷宫小球游戏示例
Unity和C#游戏编程入门:创建迷宫小球游戏示例
72 2
|
3月前
|
程序员 C#
C# 面向对象编程进阶:构造函数详解与访问修饰符应用
构造函数是一种特殊的方法,用于初始化对象。构造函数的优势在于,在创建类的对象时调用它。它可以用于为字段设置初始值
47 1
|
3月前
|
Java 程序员 C#
C# 介绍、应用领域、入门、语法、输出和注释详解
C#(发音为“C-Sharp”)是一种由 Microsoft 创建的面向对象的编程语言,运行在 .NET Framework 上。源于 C 家族,与流行的语言如 C++ 和 Java 相近。首个版本发布于 2002 年,而最新版本,C# 12,于 2023 年 11 月发布
68 0
|
4月前
|
C# Windows
C#安装“Windows 窗体应用(.NET Framework)”
C#安装“Windows 窗体应用(.NET Framework)”
52 0
|
4月前
|
C#
C# 高级语言的 “进制转换”
C# 高级语言的 “进制转换”
|
5月前
|
开发框架 JavaScript Java
推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言
推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言
42 0