最新文章
Cocos2d-x游戏开发实例详解7:对象释放时机
03-25 13:59
Cocos2d-x游戏开发实例详解6:自动释放池
03-25 13:55
Cocos2d-x游戏开发实例详解5:神奇的自动释放
03-25 13:49
Cocos2d-x游戏开发实例详解4:游戏主循环
03-25 13:44
Cocos2d-x游戏开发实例详解3:无限滚动地图
03-25 13:37
Cocos2d-x游戏开发实例详解2:开始菜单续
03-25 13:32
unity flappy bird
本文将详细剖析如何使用 Unity 开发 Flappy Bird 游戏,并附带源码内容详解。Flappy Bird 是一款极其简单却又广受欢迎的游戏,相信大家都玩过。当我了解到这款游戏后,便有了重现它的想法,于是花了 4 个多小时开发出一个可玩版本,现在将开发过程分享给大家。
开发环境要求
本文的例子需要使用 Unity 4.3.0 以上的版本打开。
项目目录结构
项目的目录结构如下:
anims:存放动画资源。prefab:存放预置对象。scripts:存放脚本。sprites:存放贴图。
开发步骤
1. 准备资源
获取 Flappy Bird 的贴图资源和音效资源,将其导入到 sprites 文件夹下。选中 atlas,在 Inspector 中进行编辑,设置为 sprite,模式为 Multiple,然后点击 Sprite Editor 按钮进行图片分隔。在弹出的对话框中,可使用自动切图方式。
2. 设置场景
为了区分场景的层次(主要用于决定图层的顺序,即 sorting Layer 的功能)以及满足编码需求,需要建立一些 tag、sorting Layer 和 Layer。具体操作如下:点击 Unity 编辑器右上方的 Layers 下拉菜单,选择 Edit Layers...,并填写相应信息。
3. 移动的道路和障碍
一格道路有两个障碍,场景中使用两格道路来反复循环,当一格道路移出屏幕后,重新调整其位置,等待下一次出现在屏幕上,从而实现不断移动的效果。
道路移动代码(road.cs)
public class road : MonoBehaviour {
// 省略部分代码
// Update is called once per frame
void Update () {
Vector3 pos = transform.position;
pos.x -= speed * Time.deltaTime;
transform.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)
道路障碍的显示与否(在欢迎页面,路面不需要障碍)以及障碍的生成都在 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 组件,使其能够获取碰撞消息。
4. 大嘴唇的小鸟
首先,小鸟有一个飞行的帧动画。在 sprite 文件夹下的 atlas 中,选择三个帧,直接拖动到场景中,Unity 会自动形成一个带有帧动画的 sprite。选中该 sprite,在 Window/Animation 界面中,调整 sprite 的播放时间。
同样,要给小鸟添加 BoxCollider2D 组件,使其能够响应碰撞,还要添加 Rigidbody2D 组件。这里涉及两个脚本:bird.cs 和 clider.cs。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 initialization
void Start () {
s = GameObject.Find("score").GetComponent<score>();
clideNum = 0;
tag = "";
isSuccess = false;
isFail = false;
}
// Update is called once per frame
void 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;
}
}
5. 欢迎页面
欢迎页面有一个小鸟的动画,并且能够响应触摸后开始游戏,这在 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;
}
}
}
6. 结算页面
结算页面开始时是隐藏的,当用户输了之后,会播放一个动画并显示。当用户点击 play 按钮后,游戏重置到欢迎页面。结算页面涉及到脚本 restart.cs。游戏重置时,使用 BroadcastMessage 技术,查找所有 tag 为 needReset 的对象,并调用其自身以及子对象中的代码中的 reset 函数来进行游戏的重置。
restart.cs 代码
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 函数来进行游戏的重置
}
}
}
}
}
通过以上步骤,我们就可以使用 Unity 开发出一个简单的 Flappy Bird 游戏。希望本文对大家有所帮助。