在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → STM32控制flappy bird小游戏C#源码

STM32控制flappy bird小游戏C#源码

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:2.07M
  • 下载次数:21
  • 浏览次数:323
  • 发布时间:2019-06-04
  • 实例类别:C#语言基础
  • 发 布 人:1157247727
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 游戏 STM32 像素鸟

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

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


using System.IO.Ports;




namespace FlappyBirdDemo
{  
    public partial class MainForm : Form
    {
        #region 00.主窗体构造函数

        byte[] SpCom1ReadBuf = new byte[128];   //SpCom1读取缓冲区
        bool runFlag = false;

        private static EventWaitHandle ProcessData = new EventWaitHandle(false,
            EventResetMode.AutoReset);

        private static EventWaitHandle ShowPicture = new EventWaitHandle(true,
            EventResetMode.AutoReset);

        //声明一个委托,用来显示柔顺关节的数据
        delegate void RestartGame();
        RestartGame restartGame;
        private void RestartTheGame()
        {
            //this.MovePipeLine();
            // 碰撞检测
            Bird bird = SingleObject.GetInstance().SingleBird;
            if (bird.Y == 0 || bird.Y == this.pbxGround.Height ||
                    (
                        (
                            (bird.X >= pipeUp.X) && (bird.X <= pipeUp.X   pipeUp.Width)
                        ) &&
                        (
                            (bird.Y <= pipeUp.Height - 20) || (bird.Y >= pipeDown.Y)
                        )
                    )
                )
            {
                this.InitialGameObjects();
                this.RestoreGame();

                //MessageBox.Show("this is a test in RestartTheGame");
            }
            else
            {
                if (runFlag == true)
                    this.PauseGame();
                else if (runFlag == false)
                    this.RestoreGame();
            }
        }

        private void GetMessage()
        {
            byte temp;
            while (true) {
                try
                {
                    SpCom1.Read(SpCom1ReadBuf, 0, 1);
                    temp = SpCom1ReadBuf[0];

                    //0xAA==游戏控制按键
                    if (temp == 0xAA)
                    {
                        Bird bird = SingleObject.GetInstance().SingleBird;
                        // 使小鸟向上移动
                        bird.Move();
                        bird.CurrentSpeed = 10f;

                        if (runFlag == true)
                        {
                            this.RestoreGame();
                        }

                        //Console.WriteLine("test for com1");

                        //清空串口发送、接收缓冲区 
                        //SpCom1.DiscardOutBuffer();
                        //SpCom1.DiscardInBuffer();
                    }

                    //0xBB==重新开始游戏
                    else if (temp == 0xBB)
                    {

                        this.BeginInvoke(restartGame);

                        //清空串口发送、接收缓冲区 
                        //SpCom1.DiscardOutBuffer();
                        //SpCom1.DiscardInBuffer();

                        //MessageBox.Show("错误提示啊");
                    }

                    SpCom1.DiscardOutBuffer();
                    SpCom1.DiscardInBuffer();
                    System.Threading.Thread.Sleep(50);
                }
                catch
                {

                }
            }            
        }

        Thread ThreadGetMessage;
        
        public MainForm()
        {
            InitializeComponent();
            // 初始化游戏对象
            InitialGameObjects();
            // 初始化游戏事件
            InitialGameEvents();

            //初始化串口
            InitIng();

            //System.Threading.Thread.Sleep(5000);
            //this.PauseGame();
            this.RestoreGame();

            restartGame = new RestartGame(RestartTheGame);

            ThreadGetMessage = new Thread(
                                            new ThreadStart(
                                                                delegate
                                                                {
                                                                    GetMessage();
                                                                }
                                                            )
                                          );
            ThreadGetMessage.Start();
        }
        #endregion

        #region 01.初始化游戏对象
        private Pipe pipeUp;
        private Pipe pipeDown;

        private void InitialGameObjects()
        {
            // 添加游戏对象 — 小鸟
            SingleObject.GetInstance().AddGameObject(new Bird(50, 200, 0));
            // 添加游戏对象 — 管道
            pipeUp = new Pipe(500, -600, PipeDirectionEnum.Up);
            pipeDown = new Pipe(500, 400, PipeDirectionEnum.Down);
        }
        #endregion

        #region 02.初始化游戏事件
        private void InitialGameEvents()
        {
            // 添加Form_Load事件
            this.Load  = MainForm_Load;
            // 添加Form_Closed事件
            this.FormClosed  = MainForm_FormClosed;
            // 添加Form_Paint事件
            this.Paint  = MainForm_Paint;
            // 添加游戏对象Timer控件的Tick事件
            this.BirdTimer.Tick  = BirdTimer_Tick;
            this.BirdTimer.Enabled = true;
            // 添加鼠标单击MouseDown事件
            this.MouseDown  = MainForm_MouseDown;
            // 添加键盘单击KeyDown事件
            this.KeyDown  = MainForm_KeyDown;
            // 添加重力Timer控件的Tick事件
            this.GravityTimer.Tick  = GravityTimer_Tick;
            this.GravityTimer.Interval = 10;
            this.GravityTimer.Enabled = true;
            // 添加管道Timer控件的Tick事件
            this.PipeTimer.Tick  = PipeTimer_Tick;
            this.PipeTimer.Interval = 10;
            this.PipeTimer.Enabled = true;
        }

        private void PipeTimer_Tick(object sender, EventArgs e)
        {
                      
        }

        private void PauseGame()
        {
            this.BirdTimer.Enabled = false;
            this.GravityTimer.Enabled = false;
            this.PipeTimer.Enabled = false;
            runFlag = false;

            //ThreadGetMessage.Suspend();
        }

        private void RestoreGame()
        {
            this.BirdTimer.Enabled = true;
            this.GravityTimer.Enabled = true;
            this.PipeTimer.Enabled = true;
            runFlag = true;

            //ThreadGetMessage.Start();
        }

        private void MovePipeLine()
        {
            
            // 从右至左移动管道
            pipeUp.Move();
            pipeDown.Move();
            // 当管道完全移出窗体时准备显示下一个管道
            if (pipeUp.X <= -128)
            {
                pipeUp.X = this.Width * 4 / 3 - 128;
                pipeDown.X = this.Width * 4 / 3 - 128;

                pipeUp.Height = GetRandomHeight();
                pipeDown.Height = this.Size.Height - pbxGround.Height
                    - pipeDistance - pipeUp.Height;

                //根据高度计算出Y轴值
                pipeUp.Y = pipeUp.Height - 830;
                pipeDown.Y = pipeUp.Height   pipeDistance;
            }
            // 使控件的整个图像无效并导致重绘控件
            //this.Invalidate();
        }

        private int pipeDistance = 150;

        private int GetRandomHeight()
        {
            Random random = new Random();
            int totalHeight = this.Size.Height - this.pbxGround.Height;
            return random.Next(90, totalHeight - 90 - pipeDistance);
        }

        private void GravityTimer_Tick(object sender, EventArgs e)
        {
            /*Bird singleBird = SingleObject.GetInstance().SingleBird;
            // Step1:获得小鸟下降的高度
            float height = Gravity.GetHeight(singleBird.CurrentSpeed,
                singleBird.DurationTime * 0.001f);
            // singleBird.DurationTime * 0.001f => 将毫秒转换成帧
            // Step2:获得小鸟下落后的坐标
            int y = singleBird.Y   (int)height;
            // Step3:将新Y轴坐标赋给小鸟
            int min = this.Size.Height - this.pbxGround.Height
                - 60;
            if (y > min)
            {
                // 限定小鸟不要落到地面下
                y = min;
            }
            singleBird.Y = y;
            // Step4:使小鸟按照加速度下降 [ 公式:v=v0 at ]
            singleBird.CurrentSpeed = singleBird.CurrentSpeed
                  Gravity.gravity * singleBird.DurationTime * 0.001f;*/
        }

        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            // 如果用户敲的是Space键
            if (e.KeyCode == Keys.Space)
            {
                Bird bird = SingleObject.GetInstance().SingleBird;
                // 使小鸟向上移动
                bird.Move();
                bird.CurrentSpeed = 10f;
            }
        }

        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {     
            Bird bird = SingleObject.GetInstance().SingleBird;
            // 使小鸟向上移动
            bird.Move();
            bird.CurrentSpeed = 10f;

            if (runFlag == true)
            {
                this.RestoreGame();
            }
            
        } 

        private void BirdTimer_Tick(object sender, EventArgs e)
        {
            

            ProcessData.WaitOne();

            Bird singleBird = SingleObject.GetInstance().SingleBird;
            // Step1:获得小鸟下降的高度
            float height = Gravity.GetHeight(singleBird.CurrentSpeed,
                singleBird.DurationTime * 0.001f);
            // singleBird.DurationTime * 0.001f => 将毫秒转换成帧
            // Step2:获得小鸟下落后的坐标
            int y = singleBird.Y   (int)height;
            // Step3:将新Y轴坐标赋给小鸟
            int min = this.Size.Height - this.pbxGround.Height
                - 60;
            if (y > min)
            {
                // 限定小鸟不要落到地面下
                y = min;
            }
            singleBird.Y = y;
            // Step4:使小鸟按照加速度下降 [ 公式:v=v0 at ]
            singleBird.CurrentSpeed = singleBird.CurrentSpeed
                  Gravity.gravity * singleBird.DurationTime * 0.001f;

            this.MovePipeLine();

            // 使控件的整个图像无效并导致重绘控件
            this.Invalidate();
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {

            //ShowPicture.WaitOne();
            // 绘制游戏对象 — 小鸟
            SingleObject.GetInstance().DrawGameObject(e.Graphics);
            // 绘制游戏对象 — 管道
            pipeUp.Draw(e.Graphics);
            pipeDown.Draw(e.Graphics);
            ProcessData.Set();



            // 碰撞检测
            Bird bird = SingleObject.GetInstance().SingleBird;
            /*if (bird.Y == 0 || bird.Y == this.pbxGround.Height ||
                bird.GetRectangeleArea()
                .IntersectsWith(pipeDown.GetRectangeleArea()) ||
                bird.GetRectangeleArea()
                .IntersectsWith(pipeUp.GetRectangeleArea()) ||
                bird.GetRectangeleArea().Contains(pipeDown.GetRectangeleArea()) ||
                bird.GetRectangeleArea().Contains(pipeUp.GetRectangeleArea()))*/
            if (bird.Y == 0 || bird.Y == this.pbxGround.Height ||
                    (
                        (
                            (bird.X >= pipeUp.X) && (bird.X <= pipeUp.X   pipeUp.Width)
                        ) &&
                        (
                            (bird.Y <= pipeUp.Height - 20) || (bird.Y >= pipeDown.Y)
                        )
                    )
                )
            {
                this.PauseGame();
                //MessageBox.Show("this is a test in PipeTimer_Tick");
            }
            //ShowPicture.Set();
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {            
            // 终止游戏进程
            try
            {
                SpCom1.Close();
                ThreadGetMessage.Abort();
                Environment.Exit(0);
            }
            catch
            { 
            
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // To do some initial welcome tips
        }






        public string OldPortNum1;//串口1上次使用的串口号


        public void InitIng()   //界面初始化
        {

            SpCom1.Close();//关闭串口
            button1.Text = "连接";
            //ovalShape1.FillColor = Color.Red;//指示灯颜色为红色
            SearchAllPorts(SpCom1, comboBox1);//搜索可用的串口
            OldPortNum1 = comboBox1.Text;//串口号默认设置为当前串口

            comboBoxInit(comboBox2);//默认设置
            comboBoxInit(comboBox3);
            comboBoxInit(comboBox4);
            comboBoxInit(comboBox5);
            //PortNumChange(SpCom1,comboBox1);
        }

        void comboBoxInit(ComboBox Comb)   //设置CombBox的文本框内容并且显示
        {
            Comb.SelectedIndex = 0;
        }

        public bool TestCom(string port)   //判断串口是否被占用,可用则返回true,否则返回false
        {
            SerialPort Sp = new SerialPort(port);//新建串口对象
            try
            {
                //检测串口是否存在
                Sp.Open();
                //Thread.Sleep(500);
                Sp.Close();
                return true;
            }
            catch (Exception e)//异常处理
            {
                //MessageBox.Show("串口不可用");
                return false;
            }
        }

        //搜索当前可以使用的串口号
        public void SearchAllPorts(SerialPort Sp, ComboBox Comb)//更新可用的串口,并把第一可用串口打开并且显示出来
        {
            string[] ArryPort = SerialPort.GetPortNames();//获取当前电脑所有串口的名字
            Comb.Items.Clear();
            for (int i = 0; i < ArryPort.Length; i  )//循环添加可用的串口
            {
                //Console.WriteLine(ArryPort[i]);
                //if(TestCom(ArryPort[i]))
                Comb.Items.Add(ArryPort[i]);//添加串口号
                Comb.Sorted = true;//排序
            }
            //Comb.SelectedIndex = 0;
        }

        //串口初始化
        void SerialPortInit(SerialPort Port, ComboBox Comb)
        {
            //这里为空
        }

        //设置串口号
        public bool SetPortNum(SerialPort Port, ComboBox Comb)        //设置串口号
        {
            string str1 = "请选择串口号!!!";
            string str2 = "该串口被占用,请选择其他串口!!!";
            bool SpOpended = false;                                   //保存串口在设置属性之前的状态,打开或是关闭
            bool ret = false;                                         //返回值,true表示成功
            if (Port.IsOpen)                                          //设置前要先关闭串口
            {
                SpOpended = true;                                     //表示串口原来是打开的,设置完后,后恢复打开状态
                Port.Close();
            }
            if (Comb.Text == "")
                MessageBox.Show(str1, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else
                if (TestCom(Comb.Text))
                {
                    Port.PortName = Comb.Text;                        //设置串口号    
                    ret = true;
                }
                else
                    MessageBox.Show(str2, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            if (SpOpended == true)                                    //如果设置串口属性前是打开状态,设置完成后要恢复原来的状态
                SerialPortOpen(Port);
            return ret;

        }

        public void SetPortBaudRate(SerialPort Port, ComboBox Comb)//改变串口波特率
        {
            string str = "请选择波特率!!!";
            bool SpOpended = false;                                   //保存串口在设置属性之前的状态,打开或是关闭
            if (Port.IsOpen)                                          //设置前要先关闭串口
            {
                SpOpended = true;                                     //
                Port.Close();
            }
            if (Comb.Text == "")
                MessageBox.Show(str, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else Port.BaudRate = Convert.ToInt32(Comb.Text);     //设置波特率
            if (SpOpended == true)                                    //如果设置串口属性前是打开状态,设置完成后要恢复原来的状态
                SerialPortOpen(Port);
        }

        public void SetPortTest(SerialPort Port, ComboBox Comb)       //改变检验方式
        {
            string str = "请选择检验方式!!!";
            bool SpOpended = false;                                   //保存串口在设置属性之前的状态,打开或是关闭
            if (Port.IsOpen)                                          //设置前要先关闭串口
            {
                SpOpended = true;                                     //表示串口原来是打开的,设置完后,后恢复打开状态
                Port.Close();
            }

            if (Comb.Text == "")
                MessageBox.Show(str, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else if (Comb.Text == "无校验")                       //改变校验方式                 
                Port.Parity = System.IO.Ports.Parity.None;
            else if (Comb.Text == "奇校验")
                Port.Parity = System.IO.Ports.Parity.Odd;
            else
                Port.Parity = System.IO.Ports.Parity.Even;
            if (SpOpended == true)                                     //如果设置串口属性前是打开状态,设置完成后要恢复原来的状态
                SerialPortOpen(Port);
        }

        public void SetPortDatabits(SerialPort Port, ComboBox Comb)   //改变数据位
        {
            string str = "请选择数据位!!!";
            bool SpOpended = false;                                   //保存串口在设置属性之前的状态,打开或是关闭
            if (Port.IsOpen)                                          //设置前要先关闭串口
            {
                SpOpended = true;
                Port.Close();
            }
            if (Comb.Text == "")
                MessageBox.Show(str, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else
                Port.DataBits = int.Parse(Comb.Text);                     //数据位设置
            if (SpOpended == true)                                    //如果设置串口属性前是打开状态,设置完成后要恢复原来的状态
                SerialPortOpen(Port);
        }

        public void SetPortStopBits(SerialPort Port, ComboBox Comb)    //改变停止位
        {
            string str = "请选择停止位!!!";
            bool SpOpended = false;                                   //保存串口在设置属性之前的状态,打开或是关闭
            if (Port.IsOpen)                                          //设置前要先关闭串口
            {
                SpOpended = true;
                Port.Close();
            }
            if (Comb.Text == "")
                MessageBox.Show(str, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else if (Comb.Text == "1")                               //设置停止位
                Port.StopBits = System.IO.Ports.StopBits.One;
            //else if (Comb.Text == "1.5")
            //    Port.StopBits = System.IO.Ports.StopBits.OnePointFive;
            else
                Port.StopBits = System.IO.Ports.StopBits.Two;
            if (SpOpended == true)                                  //如果设置串口属性前是打开状态,设置完成后要恢复原来的状态
                SerialPortOpen(Port);
        }

        public void SerialPortOpen(SerialPort Sp)       //打开串口
        {
            Sp.Open();
        }

        public void SerialPortClose(SerialPort Sp)       //关闭串口
        {
            Sp.Close();
        }

        //设置新的串口号
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (SetPortNum(SpCom1, comboBox1))         //如果设置串口成功、则旧的串口号赋值为当前可用的串口号
                OldPortNum1 = comboBox1.Text;
            else
                comboBox1.Text = OldPortNum1;           //否则,设置不成功,直接恢复到原来的串口号
        }

        //设置串口波特率
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetPortBaudRate(SpCom1, comboBox2);
        }

        //设置串口校验方式
        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetPortTest(SpCom1, comboBox3);
        }

        //设置串口的数据位
        private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetPortDatabits(SpCom1, comboBox4);
        }

        //设置串口的停止位
        private void comboBox5_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetPortStopBits(SpCom1, comboBox5);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string str1 = "该串口被占用,请选择其他串口!!!";
            string str2 = "不能打开串口,请先选择串口!!!";

            if (comboBox1.Text != "")                           //如果串口号不为空
            {
                if (SpCom1.IsOpen)                              //串口为打开状态
                {
                    SerialPortClose(SpCom1);                    //关闭串口
                    button1.Text = "连接";
                    //ovalShape1.FillColor = Color.Red;           //指示灯颜色设置为红色
                }
                else//串口为关闭状态
                {
                    if (TestCom(comboBox1.Text))                //测试串口是否可用,因为有可能已被占用 
                    {
                        SpCom1.PortName = comboBox1.Text;       //设置串口号
                        SpCom1.Open();
                        button1.Text = "断开";
                        //ovalShape1.FillColor = Color.Green;     //指示灯颜色为绿色
                        //this.RestoreGame();
                    }
                    else                                        //如果串口不可用,则提示错误提示信息
                        MessageBox.Show(str1, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);

                }
            }
            else   //如果串口号为空,则提示相应错误信息
            {
                MessageBox.Show(str2, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion
    }
}

标签: 游戏 STM32 像素鸟

实例下载地址

STM32控制flappy bird小游戏C#源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警