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

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

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

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

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

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

 

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

传入的类型需要是什么:我把整个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. hdu 1711

    读入优化有3s多. #include <cstdio> #include <cctype> #define maxn 1000010 #define maxm 10010 in ...

  2. Java 请求webServce接口 带参数

    public String getWebServiceByParams(String param){ //获取基金缴付记录 // Post请求的url,与get不同的是不需要带参数 URL postU ...

  3. python开发_pprint()

    python中的pprint.pprint(),类似于print() 下面是我做的demo: #python pprint '''python API中提供的Sample''' import json ...

  4. [转]Eclipse 的快捷键以及文档注释、多行注释的快捷键

    一.多行注释快捷键 1.选中你要加注释的区域,用ctrl+shift+C 或者ctrl+/ 会加上//注释 2.先把你要注释的东西选中,用shit+ctrl+/ 会加上/*    */注释 3.以上快 ...

  5. git中:关于origin和master

    git的服务器端(remote)端包含多个repository,每个repository可以理解为一个项目.而每个repository下有多个branch."origin"就是指向 ...

  6. SPOJ 7001. Visible Lattice Points (莫比乌斯反演)

    7001. Visible Lattice Points Problem code: VLATTICE Consider a N*N*N lattice. One corner is at (0,0, ...

  7. Android开发中适配多种 ROM 的快捷方式是如何实现的?

    在安卓开发中,要提高开发效率,掌握一些快捷方式是必不可少的,特别是对于android入门阶段的童鞋而言,非常重要.今天小编在安卓开发教程网站上,搜罗了一些常用的Android 适配多种 ROM 的快捷 ...

  8. java通过jacob来读取word转换为htm格式

    转自:http://blog.csdn.net/chinapi_hzh/article/details/5798689 因为微软没有公开word源代码,所以直接用java流来读取word的后果是读出来 ...

  9. Unity3d 换装 之 模型动画分离

    在手游中换装成了越来越不可缺的一个功能,毫无疑问各式各样的时装为游戏增添了不同的色彩. 对于2D手游,或许是更换对应的序列帧,也或许是如同3D手游一般,更换模型动画. 对于游戏中的人物,一般分为头.上 ...

  10. 用 Redis 实现分布式锁(分析)

    文章转自:http://www.jeffkit.info/2011/07/1000/ Redis有一系列的命令,特点是以NX结尾,NX是Not eXists的缩写,如SETNX命令就应该理解为:SET ...