【Unity】FlappyBird剖析-附源码
来源:互联网 发布:北京为什么堵车 知乎 编辑:程序博客网 时间:2024/06/10 18:23
FlappyBird不用多说了,一款极其简单,但是又很火的游戏。我在得知这款疯狂的游戏后,就有一种把它重现的冲动,然后花了我4个多小时,产生出了一个可以玩的版本,分享给大家(文末尾付下载链接)。
下面简单介绍游戏的开发过程(本文的例子需要使用unity4.3.0以上的版本打开)。
目录介绍
运行图:
项目的目录结构如下图,anims中存放动画资源,prefab中存放预置对象,scprits存放脚本,sprites用来存放贴图。
准备资源
获取FlappyBird的贴图资源和音效资源。把资源导入到sprites文件夹下,选中atlas,在Inspector中进行编辑,如下图:
设置为sprite,模式为Multiple,点击按钮Sprite Editor进行相应的图片分隔。在弹出的对话框中,可以使用自动切图方式,如下图:
接下来就可以进行编码了
设置场景
为了区分场景的层次(主要是用来决定图层的顺序,sorting Layer的功能)以及编码的需求,建立一些tag sorting Layer和Layer。先点击Unity编辑器右上方的Layers下拉菜单并选择"Edit Layers...",如下图:
并填写如下信息:
移动的道路和障碍
一格道路有两个障碍(如下图),场景中用两格道路来反复循环(当一格道路移出屏幕后就重新调整位置,等待下一次出现在屏幕上),达到不断移动的效果。
下面是道路移动的部分代码road.cs
public class road : MonoBehaviour {....// Update is called once per framevoid Update () { Vector3 pos = trans.position;pos.x -= speed * Time.deltaTime;trans.position = pos;if(pos.x <= -1.6f - 3.35f*idx) { //当道路移出屏幕后,从小调整其位置Vector3 pp = roads[idx%2].transform.position;pp.x += 3.35f;idx++;roads[idx%2].transform.position = pp;if(isBegin){roads[idx%2].GetComponent<roadGen>().gen();}}}
道路障碍的显示与否(在欢迎页面,路面不需要障碍),以及障碍的生成都在文件roadGen.cs中,我把上下柱子合并成一个对象,在生成障碍时,只要使其在一定范围内上下移动就可以了。代码片段如下:
public class roadGen : MonoBehaviour { public GameObject[] zhuzi; public float down=3.8f, upper = 6.0f; ... public void gen() { // 一格道路有两个柱子 zhuzi[0].SetActive(true); zhuzi[1].SetActive(true); Vector3 p = zhuzi[0].transform.localPosition; float vv = Random.value; p.y = Mathf.Lerp(down, upper, vv); zhuzi[0].transform.localPosition = p; //设置第一个柱子的位置 p = zhuzi[1].transform.localPosition; vv = Random.value; p.y = Mathf.Lerp(down, upper, vv); zhuzi[1].transform.localPosition = p; //设置第二个柱子的位置 } public void hidden() { zhuzi[0].SetActive(false); zhuzi[1].SetActive(false); } }
最后在障碍物和地面都添加BoxCollider2D,使其能够获取碰撞消息。
大嘴唇的小鸟
首先小鸟有个飞行的帧动画,在sprite文件夹下的atlas中,选择三个帧,直接拖动到场景中,unity自动形成了一个带有帧动画的sprite。选中该sprite,在Window/Animation界面中,调整sprite的播放时间,如下图:
同样要给小鸟一个BoxCollider2D的Component,使其能够响应碰撞,还要添加Rigibody2D。具体请参考例子。这里会涉及到两个脚本(时间匆忙,没怎么考虑设计):bird.cs和clider.cs;前者用来向小鸟施加力的作用,后者处理碰撞。
这个游戏的最主要部分就是 clider .cs,这个文件处理得分和是否碰撞到障碍物。代码如下:
using UnityEngine;using System.Collections;public class clider : MonoBehaviour {public score s;public int clideNum;public string tag;public bool isSuccess = false, isFail = false;// Use this for initializationvoid Start () {s = GameObject.Find("score").GetComponent<score>();clideNum = 0;tag = "";isSuccess = false;isFail = false;}// Update is called once per framevoid Update () {}void OnTriggerEnter2D(Collider2D other) {if(other.gameObject.tag.Equals("success")) {if(!isSuccess) {print("===trigger enter==");isSuccess = true;s.success();print ("success");}} else if(!isFail) {print("===trigger enter==");isFail = true;s.fail();print ("fail");}}void OnTriggerExit2D(Collider2D other) {print("===trigger exit==");isSuccess = false;}void OnCollisionEnter2D(Collision2D other) { if(other.gameObject.tag.Equals("success")) {if(!isSuccess) {print("===collision enter==");isSuccess = true;s.success();}} else if(!isFail) {print("===collision enter==");isFail = true;s.fail();}}void OnCollisionExit2D(Collision2D coll) {print("===collision exit==");isSuccess = false;}public void reset() {isSuccess = false;isFail = false;}}
(补充:回过头看一下这个代码,由于当时写的时候对Trigger和Collision理解不够,发现Trigger和Collision处理的不太优雅;关于Trigger和Collision区别,请参考《【Unity】技巧集合》中的51和52条。)
欢迎页面
欢迎页面有个小鸟的动画,并且能够响应触摸后开始游戏(在isReady.cs中实现)。
小鸟的动画就是上下摆动的过程,选择小鸟,然后在Animation界面中,添加Position属性,并调节如下图:
isReady.cs的代码如下:
public class isReady : MonoBehaviour { public GameObject road, bird; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if(Input.GetButtonDown("Fire1")){ //用户触摸屏幕之后,就开始游戏了 gameObject.SetActive(false); road.GetComponent<road>().isBegin = true; bird.GetComponent<Rigidbody2D>().isKinematic = false;//欢迎页面,这里设置为true,使小鸟不响应重力,开始后要设置为false bird.GetComponent<Animator>().enabled = false; } } }
结算页面
结算页面开始使隐藏的,等用户输了之后,就会播放一个动画并显示,当用户点击play按钮后,游戏重置到欢迎页面。结算页面涉及到了脚本restart.cs
这里游戏重置的时,用到了BroadcastMessage的技术,即查找所有tag为needReset的对象,并调用其自身以及子对象中的代码中的reset函数来进行游戏的重置。代码如下:
public class restart : MonoBehaviour { public Camera cam2d; public GameObject ready; void Update () { if(Input.GetButtonDown("Fire1")){ Collider2D h = Physics2D.OverlapPoint(cam2d.ScreenToWorldPoint(Input.mousePosition), (1<<LayerMask.NameToLayer("btn"))); if(h) { // 如果点击play按钮 gameObject.SetActive(false); Time.timeScale = 1; ready.SetActive(true); GameObject[] resets = GameObject.FindGameObjectsWithTag("needReset"); //查找所有tag为needReset的对象 foreach(GameObject r in resets) { r.BroadcastMessage("reset"); //调用其自身以及子对象中的代码中的reset函数来进行游戏的重置 } } } }
关于Physics2D.OverlapPoint的用法,请参考《【Unity】技巧集合》中的第二点。
添加音效
待续...
声明:这篇文章中所引用的资源部分来自网络,仅供学习之用,请勿商业化。
下载地址:http://download.csdn.net/detail/stalendp/6914227
apk下载链接:http://pan.baidu.com/s/1c09rKMc
15 0
- 【Unity】FlappyBird剖析-附源码
- Unity3D----FlappyBird剖析-附源码
- Java实现FlappyBird游戏附源码
- unity自习之源码剖析(5)
- Unity制作2D游戏FlappyBird
- Discuz!NT控件剖析 之 TextBox [原创: 附源码]
- Discuz!NT控件剖析 之 Button [原创: 附源码]
- Discuz!NT控件剖析 之 TextBox [原创: 附源码]
- Discuz!NT控件剖析 之 Button [原创: 附源码]
- Unity一键图集生成工具,附源码 (基于NGUI和TexturePacker)
- cocos2dx3.3开发FlappyBird总结三:项目剖析
- SDWebImage源码剖析(-)
- Discuz!NT控件剖析 之 左侧导航控件 [原创: 附源码]
- Discuz!NT控件剖析 之 DataGrid(数据列表) [原创: 附源码]
- Discuz!NT控件剖析 之 ColorPicker(颜色拾取) 和Calendar(日历) [原创: 附源码]
- Discuz!NT控件剖析 之 Tab 属性页 [原创: 附源码]
- Discuz!NT控件剖析 之 左侧导航控件 [原创: 附源码]
- Discuz!NT控件剖析 之 DataGrid(数据列表) [原创: 附源码]
- Hadoop中Mapper类的setup()函数在什么地方调用
- 斗地主里的管理真谛
- 2013蓝桥杯 【初赛试题】 翻硬币
- ini配置文件读写库,cool
- 犹太人的大智慧
- 【Unity】FlappyBird剖析-附源码
- MFC中Radio Button使用方法
- A658t可精简列表
- JavaScript开源库
- 纹理贴图循环移动
- 赢在坚持,贵在有恒
- 关于CDN对动态网站加速的一些看法
- Linux下core文件调试方法、修改core文件的默认路径
- php理论学习(二)