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

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

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

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

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

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

 

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

传入的类型需要是什么:我把整个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. bazel使用汇总

    最近重构代码之后,打算在本地用bazel来作项目构建.主要是因为brpc已经支持了bazel,所以在此之前料想会简单许多. 安装比较简单,centos直接用yum就行.按照这个指示: https:// ...

  2. hdu 2433 Travel(还不会)

    Problem Description       One day, Tom traveled to a country named BGM. BGM is a small country, but ...

  3. 【BZOJ 2839】 2839: 集合计数 (容斥原理)

    2839: 集合计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 399  Solved: 217 Description 一个有N个元素的集合有2 ...

  4. bzoj 1018 线段树维护连通性

    本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护. 对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边 ...

  5. slf4j使用

    pom jar包引用<!-- Logging --> <dependency> <groupId>ch.qos.logback</groupId> &l ...

  6. SQL 语句实现排序问题!

    SQL 查询数据时按某列排序后增加排名列,需排名的列值相等时排名相同,即如需排名列数组为:9,9,8,7,7,6     添加的排名列数组需要显示为两种: 第一种:1,1,3,4,4,6 (这种排名方 ...

  7. jquery如何判断checkbox(复选框)是否被选中(转)

    谁都知道 在html 如果一个复选框被选中 是 checked="checked". 但是我们如果用jquery alert($("#id").attr(&qu ...

  8. artDialog双击会关闭对话框的修改

    artDialog,一个jquery的对话框插件,很好用的说 但是在使用时发现鼠标双击时会自半对话框,查看源码发现有个监听鼠标双击的事件如下图: 简单的方法就是把该行去掉,为了扩展可改成如下图: 这样 ...

  9. hdu4035之经典慨率DP

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submi ...

  10. 【JSP EL】EL表达式里日期按照格式显示

    转:http://blog.csdn.net/kaishuaige/article/details/8505174 JSP页面用EL表达式 输出date格式     1.头上引入标签 <%@ t ...