前面我们大致实现了鸟的一圈轨迹(其实如果你不做这个,就用两个矩形块的碰撞检测代替也可以),跟所有前面的教程一样,草稿打完了就要设计封装成一个类。至少到目前为止我们已经知道了鸟的属性和方法,先不要管方法具体如何实现,也不管方法输入输出,我们先要设计大概有几个方法。

鸟的初始化方法-根据前面一节导入导出一些多边形点(这里初始化只需要导入一堆点就行了)

鸟的销毁方法-比如鸟撞到管子上或者地底下,整个游戏重新开始,那么鸟肯定也要重新开始

运行方法-比如你可以定义鸟的运行是受重力影响往下掉,也可以定义是不动,或者往前匀速运行

飞行方法-不同于前面的运行方法,飞行方法是玩家控制的,你按一下按钮他飞一下(有时间间隔,不会一直被触发)

你还可以定义很多额外的方法(大部分酷跑游戏对控制人物会有发射子弹,变大变小,无敌,暴走等等,其实都可以定义在这个类里面)

 

想一下初始化方法如何实现

传入的类型需要是什么:我把整个Form传递过去,至少可以得到整个Form的宽度和高度,这样如果游戏的界面发生变化,我初始化生成鸟的位置可以始终保持在比如屏幕的中间的位置

这个方法需要做什么:1 导入一堆轨迹点,并生成到Point数组中,让主窗口随时准备绘制 2 设置初始的缩放和平移位置

这个方法还需要做什么:不管如何控制鸟的运动(Transform_X和Transform_Y),要刷新真正的轨迹点位置(一起跟着变)

 

尤其要注意导入的点都是固定的死点,随着鸟的运动,这些点都应该随之改变。所以不管是Fly方法还是RUN方法,或者为了测试方便的手动修改位置MoveX和MoveY方法,都应该刷新PolygonListAfterMoving这个Point数组。为了验证每次刷新的点确实是我们需要的,最好在主程序中把这个轨迹用不同的颜色描绘出来(这也是编程提高效率的一个重要方法,想一些方法把你要验证的东西可视化)

 

因为FlapperBird的游戏跟酷跑很像,比较科学的方法是场景不断的产生管子(宽度和高度都随机),并且管子不断的从屏幕一端跑到另一端,鸟看起来一直在往前飞,其实鸟是前后不动的。如果不控制鸟,则鸟会一直往下掉,如果让鸟飞一下,则可以往上走一点。那么这个往下掉的方法就很简单可以实现了,注意我们是单独放在一个线程里执行,每次给他的TransForm_Y累加一定距离(前面用try catch是一个比较偷懒的方法,第一次运行,则线程还没有实例化无法终止,如果已经在运行了则线程可以终止,不管是不是初次运行,直接终止掉重来最为简单暴力)

 

飞行方法就稍微复杂一点了,要分几个小块去分析。

首先要想清楚如何防止重复触发飞行方法,我们定义一个变量IfFlying,只要正在执行飞行则这个变量为TRUE,执行完成设置为FALSE,如果多次触发,则先看是不是TRUE,是TRUE就不往下执行了。当然在飞行的过程中也要判断是否游戏结束,如果游戏结束也不能再飞了(比如撞到东西了,如何定义游戏结束小鸟这个类不该管,他就应该是标准的方法,只需要通过几个变量告诉他该做什么,小鸟不是裁判,不负责具体游戏规则)

其次要想清楚如何飞行,假定每次飞行给1秒或者2秒,这个时间段内我们每隔20ms(也可以自己设定时间)修改一下Transform_Y的数值,这就不能像前面一样叠加一个固定值了,看起来太假,跟你跳高或者跑步一样,总归有一个加速-减速的过程。所以可以用一些抛物线,三角函数曲线来模拟(这些值都是测试出来了,为了游戏的动感,读者可以自行搜索非常逼真的函数来让鸟飞的更像真的)

 

鸟分析完了之后,再来看怎么做管子(我们已经暂时不考虑把管子做成多边形轨迹点了,只需要生成一个Rectangle),相比于鸟来说,这个矩形的类属性和方法有所不同,可以复制了之后照着改(我们重新定义了矩形的宽度,高度,X和Y的最大值最小值,是为了做碰撞检测使用,因为如果判断一个点是否在矩形内,只需要判断X坐标和Y坐标是否分别在XMin-XMax/YMin-YMax之间)

 

初始化管子的时候,宽度和高度都是随机值,但是一定是在屏幕的一侧开始生成的(为了测试先做几个按钮不断重复生成,看效果是否满意,然后调整随机值的参数)

 

其他方法是雷同的,矩形每次运行的时候都要刷新自己的边界点(跟多边形刷新所有Point数组一样),此外管子只有一个平移方法,没有Fly方法,这一点比鸟要简单

 

有了小鸟,管子,接下来就要定义一个裁判了。我做了一个额外的类叫做GameSense,他其实还干了画图的事情(应该额外做一个类来专门画图的),裁判最重要的就是判断是否撞了。注意我这里定义方法的输入输出,由于本游戏比较简单,碰撞之需要判断一个多边形实例跟一个矩形实例是否有碰撞,内部实现方法也很简单,遍历多边形实例的Point数组看他是否在矩形的四个边角点内即可。

 

测试不管移动哪个元素,只要两个区域有接触,碰撞状态确实响应了

 

我们再来看绘图的过程,Form1_Paint事件中,每次绘制完成一个东西都需要重置画笔(所谓的重置画笔是指你一旦使用了TranslateTransform,ScaleTransform,RotateTransform方法,你可以想想你本来拿着一支笔在屏幕的左上角X=0,Y=0的位置,每一次平移这个画笔都会移动到新的位置,每一次旋转你的画笔也会跟着旋转,这里的概念我们在应用教程中OPENGL仿真中也会讲到,需要一定的空间想象能力,更需要读者自己去验证绘图的整个流程,比如先绘制一个圆,然后再绘制跟他相切的一个圆怎么实现)

 

 

更多教学视频和资料下载,欢迎关注以下信息:

我的优酷空间:

http://i.youku.com/acetaohai123

 

我的在线论坛:

http://csrobot.gz01.bdysite.com/

 

问题交流:

QQ:910358960

邮箱:acetaohai123@163.com

 

 

 

 

 

 

C#基础视频教程7.3 如何编写简单游戏的更多相关文章

  1. C#基础视频教程7.5 如何编写简单游戏

    有一些BUG需要处理,比如小鸟太高或者太低都应该报错(不然直接掉到窗口下面去了),这个方法跟前面的HitTest应该独立开来,而不是掺和在一起   测试确实可以检测是否超过边界(如果要非常精确,那么就 ...

  2. C#基础视频教程7.2 如何编写简单游戏

    前面一小节我们实现了简单的碰撞检测,但是实际上游戏的对象并不是一个标准的矩形(小鸟是一个不规则的物体,其实碰撞的管道也是不规则物体),所以如果真的要做的比较完美,我们自己要写一个方法,能够导入一个图像 ...

  3. C#基础视频教程7.4 如何编写简单游戏

    接下来我们实现整个的游戏流程,当点击开始游戏,则需要三个事情开始运行 1 小鸟初始化并往下掉(当然还是可以用按钮让他飞一下) 2 每隔一定时间从左侧产生一个管子(宽度和高度随机,产生周期2000ms左 ...

  4. C#基础视频教程7.1 如何编写简单游戏

    要做一个FlappyBird,最核心的功能是创建几个区块,如果发生碰撞则游戏结束(小鸟撞到管子上,或者小鸟到地上),至于随机生成一些管子,小鸟如何跳跃,最后如何统计分数,都不难想通要怎么做.   首先 ...

  5. C#基础视频教程5.1 如何编写简单的超级热键

    我们上一节介绍了编写简单计算器,实际上也是出于实用角度(这个计算器只要你肯改,肯定能做的比微软自带的计算器好用).这一节介绍做简单的超级热键(所谓的超级热键是指自定义快捷键的功能) 超级热键的最关键一 ...

  6. C#基础视频教程5.3 如何编写简单的超级热键

    跟前面一章讲解计算器一样,到最后一小节,我们总是要把代码规整好,让整个程序显得非常简洁,先做个文件夹把我们自定义的类库都放进去   然后我们开始整理Form1里面的代码,为了实现超级热键的功能,我们应 ...

  7. C#基础视频教程5.2 如何编写简单的超级热键

    我们前面已经理解了如何使用官方的代码实现鼠标键盘的监控,其实还差一点,因为他的代码只能捕捉单个的按键,而其实我们要的是组合键.什么是组合键呢?比如我想定义同时按下WIN+C是去执行屏幕截图.这只要理解 ...

  8. C#基础视频教程4.3 如何编写简单的计算器

    我们接着往下改,为了让这个计算器更加实用,我们要像官方的计算器一样可以接着计算(你算出来一笔数据之后,可以接着累加累减,我们暂时不考虑加括号,优先级之类的,因为绝大部分情况下我们打开计算器就是为了进行 ...

  9. C#基础视频教程4.2 如何编写简单的计算器

    用过VB6或者早期代码的人都应该能感觉到,C#目前也没看出来有什么特别之处,所谓的面向对象也没有什么体现.所以我们需要在原有基础上重写一份代码,然后比较两种做法的优缺点.我们在项目上右击添加一个Fun ...

随机推荐

  1. Ubuntu系统 安装谷歌 Chrome 浏览器

    在 Ubuntu 16.04 中安装谷歌 Chrome 浏览器,步骤: 1.sudo wget https://repo.fdzh.org/chrome/google-chrome.list -P / ...

  2. [Codeforces #514] Tutorial

    Link: Codeforces #514 传送门 很简单的一场比赛打崩了也是菜得令人无话可说…… D: 一眼二分,发现对于固定的半径和点,能包含该点的圆的圆心一定在一个区间内,求出区间判断即可 此题 ...

  3. 【离散化】【DFS】Gym - 101617H - Security Badges

    题意:给你一张有向图,每条边有个限制范围,只有权值在限制范围内的人能走这条边,问你权值不超过K的人中,有多少人能从S到T. K很大,因此我们只处理边的范围的上下界这O(m)个权值能否到达,以防万一,还 ...

  4. hdu 1171 多重背包

    题意:给出价值和数量,求能分开的最近的两个总价值,例如10,20*2,30,分开就是40,40 链接:点我 #include<cstdio> #include<iostream> ...

  5. 【8.19校内测试】【背包】【卡特兰数】【数位dp】

    早上随便搞搞t1t3就开始划水了,t2一看就是组合数学看着肚子疼...结果t1t3都a了??感天动地. 从小到大排序,从前到后枚举i,表示i是整个背包中不选的物品中代价最小的那个,即i不选,1到i-1 ...

  6. bzoj 1017 tree dp

    这道题几经波折啊. 最开始和vfleaking一样,把题意理解错了,认为一个装备可能被多个装备依赖,然后想不出来,去看题解. 发现自己理解错了题意,自己想想,其实也不难想到dp[i][j][k]表示“ ...

  7. Rails -- 自动清除日志

    在开发模式中,开发环境日志会越来越大,所以需要设置自动清理,省内存. 在 config/initializers中新建一个文件 clear_blog.rb 编写如下代码 if Rails.env.de ...

  8. ACM -- 算法小结(八)字符串算法之Manacher算法

    字符串算法 -- Manacher算法 首先介绍基础入门知识,以下这部分来着一贴吧,由于是很久之前看的,最近才整理一下,发现没有保存链接,请原创楼主见谅. //首先:大家都知道什么叫回文串吧,这个算法 ...

  9. python相对包导入报“Attempted relative import in non-package”错误

    文章是从stackoverflow翻译过来的,原文地址:Relative imports for the billionth time 本文要在原理上解决  python当中相对包导入出现的问题. 问 ...

  10. 使用STL中的list容器实现单链表的操作

    #include<iostream> #include<list> #include<algorithm> using namespace std; void Pr ...