zoukankan      html  css  js  c++  java
  • c# winform贪吃蛇小游戏

    关于贪吃蛇需要用的对象:   1.蛇  (Snake)2.食物(Food)  3.  记录蛇身的位置(Snake_body[x,y]) 4 .食物位置Food[x,y]

    简单业务:    1.蛇身移动

                        2.随机食物

                        3.蛇头与食物重叠

                         4.窗体检测上下左右方向,控制蛇身体移动方向

    好了,废话不多说,开始:在页面拖入panle1,两个lable和button按钮,页面有点丑 ,关于页面位置的调整在Load实事件中调整,

    首先定义成员变量,score  得分,每吃掉一次食物+1、 _Key_Name 初始蛇的移动方向(键盘)、_Snake_Body是蛇身数组、_Random产生随机数定义食物位置

    #region 定义成员变量
    /// <summary>
    /// 得分
    /// </summary>
    private int score = 0;
    /// <summary>
    /// 键盘状态,初始为 start
    /// </summary>
    string _Key_Name = "Start";
    /// <summary>
    /// 蛇身数组
    /// </summary>
    Label[] _Snake_Body = new Label[3000];
    /// <summary>
    /// 随机数生成Food
    /// </summary>
    Random _Random = new Random();
    /// <summary>
    /// 记录位置
    /// </summary>
    int Snake_Boby_content_x = 0, Snake_Boby_content_y = 0;
    #endregion

    好了 ,接下来,初始化舍身和食物    在窗体的初始化事件Form1_Load中添加长度为5个label的蛇身
    一个label的初始大小为10*10,并设置其的一些属性。
    其中
    Timer_Tick为蛇的移动事件,既每隔一次timer.Tick执行一次Timer_Tick
    Form1_KeyDown为对键盘的监控,_point 指定panel的位置,Snake_food()生成食物 

    Bitmap _bitmap = new Bitmap(Resource.zyd);
    IntPtr h = _bitmap.GetHicon();
    this.Icon = System.Drawing.Icon.FromHandle(h);
    this.Text="Snake张益达";
    this.Width = 1000;
    this.Height = 850;

    panel1.BorderStyle = BorderStyle.FixedSingle;
    panel1.Width = 800;
    panel1.Height = 840;
    Point _point = new Point
    {
    X = this.Width - 150,
    Y = 100
    };
    Point _point1 = new Point
    {
    X = this.Width - 80,
    Y = 100
    };
    label1.Location = _point;
    TxtScore.Location = _point1;
    //初始化蛇 5个label 一个label x =y=10
    for (int i=0;i<8;i++) {
    //身段
    Label Snake_Body_Content = new Label
    {
    Height = 10,
    Width = 10,
    Top = 200,//蛇的位置
    Left = 200 - (i * 10),
    BackColor = Color.Black,//背景色
    ForeColor = Color.Black,
    Text = "▉", //显示类型
    Tag=i
    };

    this.BackColor = Color.White;

    //加入蛇体型
    _Snake_Body[i] = Snake_Body_Content;
    panel1.Controls.Add(Snake_Body_Content);
    }
    //每隔一段时间发生右移动
    timer1.Tick += new EventHandler(Timer_Tick);
    timer1.Interval = 1000;
    //检测事件监控
    Snake_food();
    }

    接下来就是蛇体移动事件 ,在timer中执行 

    public void Timer_Tick(object sender,EventArgs e) {

    int x, y;//记录Snake的Head的XY坐标
    x = _Snake_Body[0].Left;
    y = _Snake_Body[0].Top;
    if (_Key_Name == "Start") {

    _Snake_Body[0].Left = x + 10; //向右偏移x+10
    SnakeMove(x, y);
    }
    if (_Key_Name == "Right") //键盘状态 向右
    {
    _Snake_Body[0].Left = x + 10; //向右偏移x+10
    SnakeMove(x, y);

    }
    if (_Key_Name == "Up") //键盘状态向上
    {
    _Snake_Body[0].Top =y -10; //向右偏移y-10
    SnakeMove(x, y);
    }
    if (_Key_Name == "Left")
    {
    _Snake_Body[0].Left = x - 10; //向右偏移x-10
    SnakeMove(x, y);
    }
    if (_Key_Name == "Down")
    {
    _Snake_Body[0].Top = y + 10; //向右偏移y+10
    SnakeMove(x, y);
    }
    //穿墙设置
    if (x > 800) {

    _Snake_Body[0].Left = 0;
    }
    if (y > 850)
    {

    _Snake_Body[0].Top = 0;
    }
    if (x < 0)
    {

    _Snake_Body[0].Left = 800;
    }
    if (y < 0)
    {

    _Snake_Body[0].Top = 840;
    }

    }

    /// <summary>
    /// 键盘相应事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void FormZyd_KeyDown(Object sender, KeyEventArgs e)
    {

    int x, y;
    x = _Snake_Body[0].Left;
    y = _Snake_Body[0].Top;
    _Key_Name = e.KeyCode.ToString();
    //获取键盘代码
    if (_Key_Name == "Right") {
    _Snake_Body[0].Left = x + 10;
    SnakeMove(x, y);
    }
    if (_Key_Name == "Left")
    {
    _Snake_Body[0].Left = x - 10;
    SnakeMove(x, y);

    }
    if (_Key_Name == "Up")
    {
    _Snake_Body[0].Top = y - 10;
    SnakeMove(x, y);
    }
    if (_Key_Name == "Down")
    {
    _Snake_Body[0].Top = y + 10;
    SnakeMove(x, y);
    }
    //每按一次,判断是否与食物重合
    Eat_time();
    }

    //移动
    public void SnakeMove(int x,int y) {
    //记录XY中间变量
    int Temp_X = 0, Temp_Y = 0;

    //蛇身移动
    for (int i = 1; _Snake_Body[i] != null; i++)
    {
    if (i >= 3) {
    //将记录每个位置都给中间变量
    Temp_X = Snake_Boby_content_x;
    Temp_Y = Snake_Boby_content_y;
    }

    if (i == 1)
    {
    Temp_X = _Snake_Body[i].Left; //将改变前的位置记录 X
    Temp_Y = _Snake_Body[i].Top; //将改变前的位置记录 Y
    _Snake_Body[i].Left = x; //并且赋值给第一蛇段
    _Snake_Body[i].Top = y;//并且赋值给第一蛇段

    }
    else {

    Snake_Boby_content_x = _Snake_Body[i].Left; //记录蛇段的改变前的位置x
    Snake_Boby_content_y = _Snake_Body[i].Top;//记录蛇段的改变前的位置y

    _Snake_Body[i].Left = Temp_X; //temp_赋给第二-N个蛇段,
    _Snake_Body[i].Top = Temp_Y; //temp_赋给第二-N个蛇段,
    }
    }}

    此处关于KeyDown检测不了方向键问题解决方法如下:

    protected override bool ProcessDialogKey(Keys keyData)
    {
    if (keyData == Keys.Up || keyData == Keys.Down ||

    keyData == Keys.Left || keyData == Keys.Right)

    return false;
    else
    return base.ProcessDialogKey(keyData);

    }

    重写ProcessDialogKey事件,当keyData为方向键时,返回false不执行系统处理,MSDN是这样解释的

    在消息预处理过程中调用此方法,以处理对话框字符,比如 Tab、Return、Esc 和箭头键。只有当 IsInputKey 方法指示控件未在处理该键时,才调用此方法。ProcessDialogKey 方法只是将字符发送给父级的 ProcessDialogKey 方法,或者,在该控件没有父级的情况下返回 false。Form 类重写此方法来执行对话框键的实际处理。仅当控件承载在 Windows 窗体应用程序中或充当 ActiveX 控件时,才调用此方法。


    蛇的移动事件主要包括:

    1.每隔一段时间执行一次的Timer_Tick方法,蛇的自动移动方法既通过判别Key_Name(键盘状态)来确定自动移动的方向,改变Snake_Boby[0](蛇头)的位置,然后Snake_Boby[0]位置改变后再调用Snake_move方法,
    Snake_move方法是蛇移动的关键,既根据蛇头位置的改变,对蛇体进行遍历,将蛇头后面每一个元素的位置变为它前一个元素改变之前的位置,实现蛇的移动。
    2.Form1_KeyDown方法既当this.KeyDown监控到键盘发生变化时,改变Key_Name(键盘状态)的值,并改变蛇头位置,执行Snake_move。
    3.移动事件最后都要执行Eat_time()方法判断是否与食物相遇。
    4.食物生成:也是生成一个label控件,并设置大小,text等属性。

    public void Snake_food() {

    Label Food = new Label
    {
    Width = 10,
    Height =10,
    Top = _Random.Next(1, 20) * 20,
    Left = _Random.Next(1, 20) * 20,
    Text = "❤",
    Tag = "Food",
    BackColor = Color.White,
    ForeColor = Color.Black

    };
    panel1.Controls.Add(Food);
    }

    蛇吃食物事件 :

    1. Eat_time方法判别是否和蛇头相遇,如果相遇,调用Snake_eat方法蛇长加一,且改变食物位置
    2. Snake_eat遍历到蛇尾部,生成一个label位置设为蛇尾。
    3. 吃掉一次食物加分,并且

         

    /// <summary>
    /// 判断是否吃到实物
    /// </summary>
    public void Eat_time() {

    //蛇头部位置

    //取得食物的位置
    double x1=1 , y1=1 , x2=1 , y2=1;
    foreach (Label _Label in this.panel1.Controls) {

    if (_Label.Tag.ToString() == "Food".ToString()) { //食物

    x2 = _Label.Left;
    y2 = _Label.Top;
    }
    if (_Label.Tag.ToString() == "0".ToString())//Snake
    {
    x1 = _Label.Left;
    y1 = _Label.Top;
    }

    if (x1 == x2 && y1 == y2) {
    MessageBox.Show($"{x1},{y1},{x2},{y2}");
    //吃掉食物
    Snake_Eat();
    score++;
    TxtScore.Text=$"共{score}分";
    //将食物移位 更换坐标
    foreach (Label lb in this.panel1.Controls)
    {
    if (lb.Tag.ToString() == "Food".ToString())
    {
    lb.Top = _Random.Next(1, 20) * 20;
    lb.Left = _Random.Next(1, 20) * 20;
    }
    }

    }
    }
    }
    /// <summary>
    /// 吃掉食物
    /// </summary>
    public void Snake_Eat() {

    int i = 0;
    //遍历到蛇尾
    for (; _Snake_Body[i] != null; i++) ;
    MessageBox.Show(i.ToString());
    Label Snake_Boby_content = new Label
    {
    Width = 10,
    Height = 10,
    Top = Snake_Boby_content_x, //蛇尾位置X
    Left =Snake_Boby_content_y, //蛇尾位置Y
    BackColor = Color.Black,
    Text= "▉",
    Tag=i,
    };
    _Snake_Body[i] = Snake_Boby_content;
    Snake_Boby_content.BackColor = Color.Black;
    this.Controls.Add(Snake_Boby_content);

    }

    开始按钮:

    private void Btnstart_Click(object sender, EventArgs e)
    {
    this.KeyDown += new KeyEventHandler(FormZyd_KeyDown);
    timer1.Start() ;
    this.KeyPreview = true;
    }

    暂停按钮:

    private void Btnsuspend_Click(object sender, EventArgs e)
    {
    timer1.Stop();
    this.KeyPreview = false;
    }

  • 相关阅读:
    SqlServer 数据库同步的两种方式 (发布、订阅),主从数据库之间的同步
    Haproxy+Heartbeat 高可用集群方案操作记录
    HAProxy+Keepalived高可用负载均衡
    Centos 6/7 忘记root密码处理方法
    Centos 7配置nginx反向代理负载均衡集群
    各种官网系统镜像文件
    Tomcat通过Redis实现session共享的完整部署记录
    ELK平台搭建及日志监控
    快速搭建ELK日志分析系统
    idea各种快捷键
  • 原文地址:https://www.cnblogs.com/dashanboke/p/10598315.html
Copyright © 2011-2022 走看看