实例介绍
【实例简介】
【实例截图】
【核心代码】
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 } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论