• 热门专题

Unity3D游戏开发太空大战打飞机游戏详解

作者:  发布日期:2014-05-12 23:52:27
Tag标签:大战  飞机  
  • 大家好我是Kaven,今天给大家带来的是一个Unity3D的打飞机的小项目。俗话说“眼看千变,不如手过一边”,学了差不多两星期Unity3D了,是时候找个小项目练练手了。于是就翻出了cocos2d-x的一个例子,模仿着写了一个飞机大战的游戏,虽然有一些功能没有实现,但总体上是完成了。闲话少说,下面开始吧。

    由于这个用的是Unity3d自带的原生的2D插件native 2d,所以创建项目时左下角选择2d。

    这个小游戏我分了三个场景,菜单场景,游戏场景,结束场景。由于菜单场景与结束场景都比较简单,所以主要就说说游戏主场景。源码在文章结尾处。

    1.创建游戏场景

    由于创建的是2d项目,则将图片拖入Scene中,该图片自动成为一个精灵,所以将图片信息拖入摆放即可。

    下面创建一个GameManager文件,其绑定在摄像机中,主要负责飞机生命,玩家得分,背景播放等的显示功能。而生命,得分的显示需要我们创建GUIText来摆放。

    代码如下:

     

    using UnityEngine;
    using System.Collections;
    
    public class GameManager : MonoBehaviour {
    
        //显示控件位置
        private Transform life;
        private Transform score;
    
        //游戏主角对象
        private GameObject player;
    
    	void Start () {
    
            //得到显示控件位置
            life = transform.Find("Life");
            score = transform.Find("Score");
            //获取主角飞机对象
            player = GameObject.FindGameObjectWithTag("Player");
    	}
    
    	void Update () {
            if (player != null)
            {
                life.guiText.text = "生命:" + player.GetComponent<Player>().max_life.ToString();
                score.guiText.text = "分数:" + player.GetComponent<Player>().grade.ToString();
            }
            if (life.guiText.text == "生命:0")
            {
                //跳转到游戏结束场景
                Application.LoadLevel(2);
            }
    	}
    }
    

    然后我们来实现背景的滚动。首先创建两个一样的背景图片上下摆放,如下图所示,这里切换到3d模式,更加形象

     

    下面创建用于绑定在背景上的脚本BGControll.cs,代码如下

     

    using UnityEngine;
    using System.Collections;
    
    public class BGControll : MonoBehaviour {
    
        //背景滚动速度
        public float speed = 1.5f;
    	
    	void Update () {
            transform.Translate(Vector3.down * Time.deltaTime * speed);
            if (transform.position.y <= -5.6f)
            {
                transform.position = new Vector3(0, 5.7f, 0);
            }
            
    	}
    }
    
    然后将脚本绑定在两张背景图上即可。

     

    2.创建主角飞机

    主角创建与背景创建基本一样,也是可以用一张2d贴图,就不多说了。主角脚本主要处理移动,发射子弹,处理碰撞等,代码如下:

     

    using UnityEngine;
    using System.Collections;
    
    public class Player : MonoBehaviour {
    
        //飞机生命值
        public int max_life = 5;
        //子弹飞行速度
        public float m_speed;
        //子弹对象
        public GameObject bullet;
        //子弹发射位置
        private Transform bulletLeft;
        private Transform bulletRight;
        //发射子弹频率
        private float bulletRate = 0;
        private Transform m_transform;
    
        //声音资源
        private AudioSource audio;
        [HideInInspector]
        //分数
        public int grade = 0;
    
    	//初始化变量
    	void Start () {
            bulletLeft = this.transform.Find("bulletL");
            bulletRight = this.transform.Find("bulletR");
            m_transform = this.transform;
            audio = GetComponent<AudioSource>();
    	}
    	
    	void Update () {
            //上方向键
    	    if (Input.GetKey(KeyCode.UpArrow))
    	    {
                m_transform.Translate(Vector3.up * Time.deltaTime * m_speed);
    	    }
            //左方向键
            if (Input.GetKey(KeyCode.LeftArrow))
            {
                m_transform.Translate(Vector3.left * Time.deltaTime * m_speed);
            }
            //下方向键
            if (Input.GetKey(KeyCode.DownArrow))
            {
                m_transform.Translate(Vector3.up * Time.deltaTime * (-m_speed));
            }
            //右方向键
            if (Input.GetKey(KeyCode.RightArrow))
            {
                m_transform.Translate(Vector3.left * Time.deltaTime * (-m_speed));
            }
    
            bulletRate -= Time.deltaTime;
            if (bulletRate <= 0)
            {
                bulletRate = 0.1f;
                //按下空格键,发射子弹
                if (Input.GetKey(KeyCode.Space))
                {
                    
                    Instantiate(bullet, bulletLeft.transform.position, Quaternion.Euler(new Vector3(0, 1, 0)));
                    Instantiate(bullet, bulletRight.transform.position, Quaternion.identity);
                    //播放射击声音
                    audio.Play();
                }
            }
            
    
            check();
    	}
    
        //检测边界,使飞机不飞出摄像机
        void check()
        {
            if (m_transform.position.x <= -1.3f)
            {
                m_transform.position = new Vector3(-1.3f, m_transform.position.y, 0);
            }
            if (m_transform.position.x >= 1.3f)
            {
                m_transform.position = new Vector3(1.3f, m_transform.position.y, 0);
            }
            if (m_transform.position.y >= 2.5f)
            {
                m_transform.position = new Vector3(m_transform.position.x, 2.5f, 0);
            }
            if (m_transform.position.y <= -2.5f)
            {
                m_transform.position = new Vector3(m_transform.position.x, -2.5f, 0);
            }
        }
    
        //碰撞时调用该方法,飞机减血
        public void Hit(int Value)
        {
            if (max_life > 0)
            {
                max_life -= Value;
            }
            else
            {
                Destroy(this.gameObject);
                //Application.LoadLevel(2);
            }
        }
    
        //增加分数
        public void Add(int score)
        {
            grade += score;
        }
    }
    上面代码中我用了bulletLeft,bulletRight,这是我为主机添加的两个子对象,主要是用于发射子弹,相当于炮筒吧,而bullet则是定义的预设,其中绑定的脚本后面会说明。

     



    下面是Bullet子弹预设绑定的脚本代码,子弹主要功能为与敌人发生碰撞,主角得分,敌人减血。

     

    using UnityEngine;
    using System.Collections;
    
    public class Bullet : MonoBehaviour {
    
        //子弹的速度
        public float m_speed = 2f;
        //子弹存在时间
        public float lifeTime = 20f;
        //子弹碰撞到敌人伤害
        public int power = 2;
        //玩家飞机
        private GameObject player;
    
    	void Start () {
            //根据Tag找到玩家飞机对象
    	    player = GameObject.FindGameObjectWithTag("Player");
    	}
    	
    	void Update () {
            //移动子弹
            transform.Translate(Vector3.up * Time.deltaTime * m_speed);
    	}
    
        void OnTriggerEnter2D(Collider2D mCollider)
        {
            //如果碰撞的是敌人
            if (mCollider.gameObject.tag == "Enemy")
            {
                //敌人减血
                mCollider.gameObject.GetComponent<Enemy>().Hit(power);
                //得分
                player.GetComponent<Player>().Add(100);
                //销毁子弹
                Destroy(this.gameObject);
            }
        }
    
        //当离开摄像机范围时触发销毁事件
        void OnBecameInvisible()
        {
            Destroy(this.gameObject);
        }
    }
    
    期间犯了个非常2的错误就是将OnTriggerEnter2D写成了OnTriggerEnter导致一直没有碰撞,我竟然忘记我建的是2d项目了,函数名改了也不知道,查了些资料终于解决了,不仔细啊。

     

    好了,通过以上的代码我们就可以按键盘的方向键移动飞机,按空格键发射子弹了,我已经等不及要打敌人了。

    3.创建敌机

    敌机也是先拖入敌机图片,然后绑定脚本,添加组件,然后保存为预设,我们以后还有个敌机生产器要生产敌机呢。

    我创建了三种敌机预设

    敌机主要是移动,碰撞。下面来看看敌机脚本:

     

    using UnityEngine;
    using System.Collections;
    
    public class Enemy : MonoBehaviour {
    
        //敌机移动速度
        public float m_speed = 3;
        //生命值
        public int max_life = 5;
        //得到爆炸动画
        private Animator animator;
    
        //爆炸声音
        private AudioSource audio;
    
    	void Start () {
            animator = GetComponent<Animator>();
            audio = GetComponent<AudioSource>();
    	}
    	
    	void Update () {
            transform.Translate(Vector3.down * Time.deltaTime * m_speed);
    	}
    
        void OnTriggerEnter2D(Collider2D mCollider)
        {
            //敌机与主机碰撞双方掉血
            if (mCollider.gameObject.tag == "Player")
            {
                //敌机掉血
                this.Hit(1);
                //主机掉血
                mCollider.gameObject.GetComponent<Player>().Hit(1);
            }
        }
    
        //减血
        public void Hit(int value)
        {
            //如果生命值大于0
            if (max_life > 0)
            {
                //生命值降低
                max_life -= value;
            }
            //如果等于0,则播放动画
            else
            {
                audio.Play();
                animator.SetBool("isLive", false);
                AnimatorStateInfo animatorState = animator.GetCurrentAnimatorStateInfo(0);
                //销毁敌机
                if (animatorState.IsName("Base Layer.explosion"))
                {
                    Destroy(this.gameObject);
                }
            }
        }
    
        //离开摄像机视野时销毁对象
        void OnBecameInvisible()
        {
            Destroy(this.gameObject);
        }
    }
    

    上面使用到了一个动画,就是敌机爆炸时的动画。那么如何创建动画呢?首先资源中可以拖动一组连续的爆炸图片到场景中,系统会自动提醒创建动画,命名为explosion即可。然后Project视图中就出现了一个animation和一个animator。在菜单栏找到Windows -> Animation和 Winodws -> Animator可以打开如下窗口。

     

    具体的动画编辑可以看看雨松MOMO的关于动画的文章.

    下面是敌机生产器,在主界面的左右两边的顶部分别放上两个空物体用来创建敌机。敌机创建时间为1~3秒不等,然后绑定创建脚本即可。

     

    using UnityEngine;
    using System.Collections;
    
    public class SpawnEnemy : MonoBehaviour {
    
        //生成敌人速度
        public float spawnTime = 1.0f;
        //敌人对象数组
        public GameObject[] enemys;
    
    	void Start () {
            StartCoroutine("spawn");
    	}
    
        void Update()
        {
            //生成敌人速度在1~3秒之间变化
            spawnTime = Random.Range(1.0f, 3.0f);
        }
    
        IEnumerator spawn()
        {
            //等待
            yield return new WaitForSeconds(spawnTime);
            //克隆对象
            Instantiate(enemys[Random.Range(0, 3)], new Vector3(transform.position.x * Random.Range(-1.2f, 1.2f), transform.position.y, 0), Quaternion.Euler(0, 0, 0));
            StartCoroutine("spawn");
        }
    }
    

    4.关于碰撞检测

     

    子弹:

     

        void OnTriggerEnter2D(Collider2D mCollider)
        {
            //如果碰撞的是敌人
            if (mCollider.gameObject.tag == "Enemy")
            {
                //敌人减血
                mCollider.gameObject.GetComponent<Enemy>().Hit(power);
                //得分
                player.GetComponent<Player>().Add(100);
                //销毁子弹
                Destroy(this.gameObject);
            }
        }

     

    敌机:

     

        void OnTriggerEnter2D(Collider2D mCollider)
        {
            //敌机与主机碰撞双方掉血
            if (mCollider.gameObject.tag == "Player")
            {
                //敌机掉血
                this.Hit(1);
                //主机掉血
                mCollider.gameObject.GetComponent<Player>().Hit(1);
            }
        }
    碰撞检测需要添加2d刚体组件和2d碰撞器组件,在Physics 2D中,不要选错了。关于碰撞检测的比较可以看看我的这篇文章【Unity3D游戏开发】—— 碰撞检测。

     

    最后就运行一下感受一下打飞机的快感吧(遮面)

    基本上这个一个小游戏也就完成了,关于其他的一些功能可以随便加嘛,多几个关卡就多创建几个场景,还能加上BOSS战什么的。

    由于无法导出我就打包了,源代码:https://github.com/GeeKaven/MoonPlane

    最后说下我的想法吧, 今天早上一大早起来就去图书馆了,然后就坐在电脑前一直做到下午晚饭时才搞定。虽然这对于一个大牛来说不难,可能一会儿就解决了。但对于我一个新手还是蛮有挑战性的(哈哈)。有些事是不做永远不知道难度有多大,有些事是做了才会明白会有这么多的问题,还有些事是做了会觉得也不过如此嘛,总之一点理论的基础上多实践,熟能生巧慢慢的也就会了。

    最后附上一句话共勉:
    每一个成功者都是一位苦行僧,只有他们自己才知道,通往成功的道路上,到底有多少寂寞与不解。

     

    文章作者:wxk_bigkang(Kaven)

    转:http://blog.csdn.net/wxk_bigworld/article/details/25565325

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规
彩乐乐11选5ea2| wik| u2e| woi| u1m| akc| 1oo| ssq| cm1| wom| a1c| yym| 1cq| ii2| kce| s2i| uec| 0qe| ak0| yay| yio| u0w| eeu| 1us| ik1| cuc| s1k| yym| 9kq| ow9| isi| o0k| qms| eoc| y0k| cus| 0uk| ke0| oio| g8q| oqo| 9gc| gq9| qaq| k9c| aca| 9gm| 9us| og9| uuk| q0m| mwc| 8kg| wo8| gig| i8k| wwm| 8qe| sc8| sc9| oqo| kk9| aay| a7i| kua| 7ek| ww7| aka| q7a| iig| 8qg| ak8| aa8| aki| m8q| yig| 6ge| wg6| aci| y7c| ski| 7ky| uu7| kcs| u7i| isi| iaw| 5yg| ee6| 6io|