教练 发表于 2017-1-4 11:31:51

Unity3D 像素风格《猫捕鱼》小游戏(二)

      今天继续上一篇的内容,如何完成这个猫捕鱼的小游戏。


    1.新建一个Game.unity,这是主要的游戏场景;并且在场景中有一个manager对象附加GameManager.cs 组件,组件继承单例类MonoSingleton.cs;
      ①MonoSingleton.cs 代码如下:
using UnityEngine;

/// <summary>
/// @see http://wiki.unity3d.com/index.php/Singleton
/// </summary>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
        private static T m_Instance = null;

        public static T instance {
                get {
                        // Instance requiered for the first time, we look for it
                        if (m_Instance == null) {
                                m_Instance = GameObject.FindObjectOfType (typeof(T)) as T;

                                // Object not found, we create a temporary one
                                if (m_Instance == null) {
                                        m_Instance = new GameObject (typeof(T).ToString (), typeof(T)).GetComponent<T> ();
                                        // Problem during the creation, this should not happen
                                        if (m_Instance == null) {
                                                Debug.LogError ("Problem during the creation of " + typeof(T).ToString ());
                                        }
                                        DontDestroyOnLoad (m_Instance);
                                }
                               
                                m_Instance.Init ();
                        }
                        return m_Instance;
                }
        }
        // If no other monobehaviour request the instance in an awake function
        // executing before this one, no need to search the object.
        private void Awake ()
        {
                if (m_Instance == null) {
                        m_Instance = this as T;
                        m_Instance.Init ();
                }
        }

        // This function is called when the instance is used the first time
        // Put all the initializations you need here, as you would do in Awake
        public virtual void Init ()
        {
        }

        // Make sure the instance isn't referenced anymore when the user quit, just in case.
        private void OnApplicationQuit ()
        {
                m_Instance = null;
        }
}
      ②GameManager.cs 代码如下:
using UnityEngine;
using System.Collections;

public class GameManager : MonoSingleton<GameManager>
{
        public int clearCount = 10;
        public int hp = 3;
       
        Camera mainCamera;
        private int killCount = 0;
       
        public override void Init ()
        {
                ScoreManager.instance.Reset();
        }

        public static void DestroyEnemy (int addScorePoint)
        {
                ScoreManager.instance.AddScore (addScorePoint);
                AddKillCount ();
        }

        private static void AddKillCount ()
        {
                instance.killCount += 1;
                // clear
                if (instance.killCount >= instance.clearCount)
                        instance.StartCoroutine (instance.GameClear ());
        }

        public static void Miss ()
        {
               
                Dustbox.instance.StopFishes ();
                RandomSpawn spawn = GameObject.FindObjectOfType (typeof(RandomSpawn)) as RandomSpawn;
               
                spawn.enabled = false;
                Dustbox.instance.StopBullet();
               
                instance.hp -= 1;
                spawn.spawnCount = instance.killCount - 1;
               
               
                // GameOver
                if (instance.hp <= 0)
                        instance.StartCoroutine (instance.GameOver ());
                else
                        instance.GetComponent<Animation>().Play ();

                instance.GetComponent<Animation>().Play ();
               
        }
       
        public void ResetGame ()
        {
                Destroy (Dustbox.instance.gameObject);
               
                CatController cat = GameObject.FindObjectOfType (typeof(CatController)) as CatController;
                cat.Reset ();

                RandomSpawn spawn = GameObject.FindObjectOfType (typeof(RandomSpawn)) as RandomSpawn;
                spawn.enabled = true;
               
        }

        public void Fadeout ()
        {
                if (mainCamera != null)
                        mainCamera.enabled = true;
        }
       
        public void Fadein ()
        {
                if (mainCamera != null)
                        mainCamera.enabled = false;
        }
       
        IEnumerator GameClear ()
        {
               
                RandomSpawn spawn = GameObject.FindObjectOfType (typeof(RandomSpawn)) as RandomSpawn;
                PlayerController controller = GameObject.FindObjectOfType (typeof(PlayerController)) as PlayerController;
                MusicController sound = GameObject.FindObjectOfType (typeof(MusicController))as MusicController;
                AudioClip clip = Resources.Load ("Audio/bgm-jingle1") as AudioClip;
               
                Dustbox.instance.StopFishes ();
                spawn.enabled = false;
                controller.enabled = false;
               
                if (sound != null)
                        Destroy (sound.gameObject);
               
                AudioSource.PlayClipAtPoint (clip, Vector3.zero);
               
                yield return new WaitForSeconds(clip.length);
               
                Destroy(Dustbox.instance.gameObject);
                Application.LoadLevel ("Clear");
        }

        public IEnumerator GameOver ()
        {
                yield return new WaitForSeconds(2);
                Destroy(Dustbox.instance.gameObject);
               
                MusicController sound = GameObject.FindObjectOfType (typeof(MusicController)) as MusicController;
                if (sound != null)
                        Destroy (sound.gameObject);
       
                Application.LoadLevel ("GameOver");
        }
}



    2.场景中Player 对象,及其附加的组件;
       ① ShotController.cs 射击组件 代码如下:
using UnityEngine;
using System.Collections;


public class ShotController : MonoBehaviour
{
       
       
        GameObject bulletPrefab;
        private CatAnimationController catAnimation;

        void Start ()
        {
                catAnimation = GetComponent<CatController> ().GetCatAnimationController ();
        }
       
        public void Shoot ()
        {
                if (GameObject.FindGameObjectWithTag ("Bullet") != null)
                        return;
               
                GameObject bullet = GameObject.Instantiate (bulletPrefab) as GameObject;
                bullet.transform.position = transform.position + Vector3.down * 0.1f + Vector3.forward * 0.2f;
               
                Vector3 direction = catAnimation.direction;

                if (direction == Vector3.up)
                        bullet.transform.Rotate (Vector3.forward * 90);
                else if (direction == Vector3.left)
                        bullet.transform.Rotate (Vector3.forward * 180);

                bullet.GetComponent<BulletController> ().direction = direction;
        }
}



       ②PlaySound.cs 声音控制 代码如下:
using UnityEngine;
using System.Collections;

public class PlaySound : MonoBehaviour
{
       
        public AudioClip clip;
       
        public void PlayOneShot ()
        {
                if (clip != null)
                        AudioSource.PlayClipAtPoint (clip, Vector3.zero);
        }
}

       ③PlayerController.cs 主角控制器 代码如下:
using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{

        private CatController controller;
        private ShotController shot;
       
        void Start ()
        {
                controller = GetComponent<CatController> ();
                shot = GetComponent<ShotController> ();
        }
       
        void Update ()
        {
                if (Input.GetAxis ("Vertical") > 0)
                        controller.LookUp ();
                else if (Input.GetAxis ("Horizontal") != 0f)
                        controller.Move (Input.GetAxis ("Horizontal"));

                if (Input.GetButtonDown ("Fire1"))
                        shot.Shoot ();

                if (Input.GetKeyDown (KeyCode.LeftShift))
                        Time.timeScale = Time.timeScale == 0 ? 1 : 0;
        }
}


       ④CatController.cs 代码如下:
using UnityEngine;
using System.Collections;

public class CatController : MonoBehaviour
{
       
        CatAnimationController catAnimation;
       
        float speed = 60;
        private Vector3 firstPosition;
       
        void Start ()
        {
                catAnimation = GetCatAnimationController ();
                firstPosition = transform.position;
                catAnimation.LookUp ();
        }
       
        public CatAnimationController GetCatAnimationController ()
        {
                return transform.GetComponentInChildren<CatAnimationController> ();
        }
       
        public void Move (float direction)
        {
                if (direction < 0)
                        catAnimation.MoveLeft ();
                else
                        catAnimation.MoveRight ();
               
                transform.Translate (catAnimation.direction * speed * Time.deltaTime);
        }

        public void LookUp ()
        {
                catAnimation.LookUp ();
        }

        public void Reset ()
        {
                transform.position = firstPosition;
                catAnimation.transform.localPosition = Vector3.zero;
               
                GetComponent<PlayerController> ().enabled = true;
                catAnimation.LookUp ();
               
                StartCoroutine (catAnimation.Flashing ());
        }
       
        void OnTriggerEnter (Collider collision)
        {
                if (collision.CompareTag ("Enemy")) {
                        GameManager.Miss ();
                        catAnimation.failed.enabled = true;
            GetComponent<Collider>().enabled = false;
            GetComponent<Animation>().Play ("MissAnimation@Cat");
                        GetComponent<PlayerController> ().enabled = false;
                }
        }
       
        void Dead ()
        {
                StartCoroutine (GameManager.instance.GameOver ());
        }
}


   

    3.随机生成鱼的出生点;
      RandomSpawn.cs代码如下:

using UnityEngine;
using System.Collections;

public class RandomSpawn : MonoBehaviour
{
       
        GameManager manager;
       
        GameObject fishPrefab;
        public float spawnPercent = 2f;
        public int spawnCount = 0;
       
        Transform left = null, right = null;

        void OnDrawGizmosSelected ()
        {
                if (left == null || right == null)
                        return;
               
                Gizmos.DrawLine (left.position, right.position);
        }

        void OnEnable ()
        {
                StartCoroutine (SpawnLoop ());
      GetComponent<Animation>().enabled = true;
        }
       
        void OnDisable ()
        {
                StopAllCoroutines ();
      GetComponent<Animation>().enabled = false;
        }
       
        IEnumerator SpawnLoop ()
        {
                while (true) {
                        Spawn ();
                        yield return new WaitForSeconds (spawnPercent);
                }
        }
       
        public void Spawn ()
        {
                // spawn limit
                if (manager.clearCount <= spawnCount)
                        return;
               
                spawnCount ++;
               
                float position = Random.Range (left.transform.position.x, right.transform.position.x);
               
                GameObject fish = GameObject.Instantiate (fishPrefab) as GameObject;
                fish.transform.position = transform.position + Vector3.left * position + Vector3.forward * 20;
                fish.transform.parent = Dustbox.instance.transform;
        }
       
}

   
   

    4.设定主角可以重生多次,相应的组件LifeController.cs;
using UnityEngine;
using System.Collections;

public class LifeController : MonoBehaviour
{
       
       
        GameObject[] life;
        GameManager manager;
       
        void Awake ()
        {
                manager = FindObjectOfType (typeof(GameManager)) as GameManager;
        }
       
        void OnEnable ()
        {
                StartCoroutine (LifeCheck ());
        }
       
        void OnDisable ()
        {
                StopAllCoroutines ();
        }
       
        IEnumerator LifeCheck ()
        {
                while (true) {
                       
                        for (int i=0; i< life.Length; i++) {
                                life .GetComponent<Renderer>().enabled = i < manager.hp;
                        }
                       
                        yield return new WaitForSeconds(0.5f);
                }
        }
}


      
   
   
    5.场景中声音的控制 ,组件MusicController.cs;
using UnityEngine;
using System.Collections;

public class MusicController : MonoBehaviour
{
       
        void Start ()
        {
                if (GameObject.FindObjectsOfType (typeof(MusicController)).Length > 1)
                        Destroy (gameObject);
                else
                        DontDestroyOnLoad (gameObject);
        }

}




    6.关于计算分数的相关组件;

   ①HighScoreController.cs代码如下:
using UnityEngine;
using System.Collections;

public class HighScoreController : MonoBehaviour
{
       
        TextMesh text;
       
        // Use this for initialization
        void Start ()
        {
                text = GetComponent<TextMesh> ();
                ScoreManager.instance.HighScore = PlayerPrefs.GetInt ("highscore");
        }
       
        // Update is called once per frame
        void Update ()
        {
                text.text = ScoreManager.instance.HighScore.ToString ();
        }
}


   ②ScoreController.cs 代码如下:
using UnityEngine;
using System.Collections;


public class ScoreController : MonoBehaviour
{
       
        TextMesh tmesh;
       
        void Awake ()
        {
                tmesh = GetComponent<TextMesh> ();
        }
       
        void Update ()
        {
                tmesh.text = ScoreManager.instance.Score.ToString ();
        }
}



   ③ScoreManager.cs 代码如下:
using UnityEngine;
using System.Collections;

public class ScoreManager : MonoSingleton<ScoreManager>
{
        privateint m_Score;
        privateint m_HighScore;

        public int Score {
                get{ return m_Score;}
                set { m_Score = value;}
        }

        publicint HighScore {
                get{ return m_HighScore;}
                set {
                        PlayerPrefs.SetInt ("highscore", value);
                        m_HighScore = value;
                }
        }

        public void AddScore (int point)
        {
                instance.Score += point;
                instance.HighScore = Mathf.Max (instance.Score, instance.HighScore);
        }

        public void Reset ()
        {
                instance.Score = 0;
        }
}


    7.新建GameOver.unity 场景,表示游戏失败结束,游戏场景中对象附加GameOverManager.cs组件;
using UnityEngine;
using System.Collections;

public class GameOverManager : MonoSingleton<GameOverManager>
{
        void Update ()
        {
               
                if (Input.GetButtonDown ("Fire1")) {
                        Application.LoadLevel ("Title");
                }
       
        }
}



    8.新建Clear.unity 场景,表示游戏胜利,并且清除之前的成绩,可以重新再玩,组件ClearManager.c;
using UnityEngine;
using System.Collections;

public class ClearManager : MonoSingleton<ClearManager>
{

        bool pause = true;
       
        int waitTime = 3;
       
        IEnumerator Start ()
        {
                yield return new WaitForSeconds(waitTime);
               
                pause = false;
        }
       
        void Update ()
        {
               
                if (pause)
                        return;
               
                if (Input.GetButtonDown ("Fire1")) {
                        ScoreManager.instance.Reset ();
                        Application.LoadLevel ("Title");
                }
        }
}



    9.子弹类处理;
       ①BulletController.cs 代码如下:
using UnityEngine;
using System.Collections;

public class BulletController : MonoBehaviour
{
       
       
        public Vector3 direction = Vector3.up;
        public float speed = 4f;
        private const float margin = 0.02f;
        private bool isDestroy = false;
       
        void Start ()
        {
                transform.parent = Dustbox.instance.transform;
               
                AudioClip shootAudio = Resources.Load ("Audio/shot1") as AudioClip;
                AudioSource.PlayClipAtPoint (shootAudio, Vector3.zero);
        }
       
        void Update ()
        {
               
                if( isDestroy )
                        Destroy (gameObject);
               
               
                transform.Translate (direction * speed * 60 * Time.deltaTime, Space.World);
               
                Vector3 bulletScreenPos = Camera.main.WorldToViewportPoint (transform.position);
                if (bulletScreenPos.x < 0 - margin || bulletScreenPos.x > 1 + margin ||
                        bulletScreenPos.y < 0 - margin || bulletScreenPos.y > 1 + margin)
                        Destroy (gameObject);
        }
       
        public void Stop ()
        {
                enabled = false;
        }
       
        void OnTriggerEnter (Collider collision)
        {
                if (!collision.CompareTag ("Player"))
                        isDestroy = true;
        }

}


       ②Dustbox.cs 代码如下:
using UnityEngine;

public class Dustbox : MonoSingleton<Dustbox>
{
        public void StopFishes ()
        {
                foreach (FishController fishin GetComponentsInChildren<FishController>()) {
                        fish.Stop ();
                }
        }
       
        public void StopBullet()
        {
                foreach (BulletController bulletin GetComponentsInChildren<BulletController>()) {
                        bullet.Stop();
                }
        }
}



    10.好吧!也许博客写得不是很清晰,但是我们还是一起来看一下运行的效果噢!





    欢迎加我的学习交流群:575561285

源码:**** Hidden Message *****
   
   

元素战争 发表于 2017-1-4 12:15:56

{:1_141:} learn

qq000000 发表于 2017-1-4 12:56:14

6666

CHRISHAO 发表于 2017-1-4 13:28:20

zan

CWwwer 发表于 2017-1-4 13:39:31

666666太喜欢了,楼主好人!

小小橘子 发表于 2017-1-4 15:29:13

讲道理,我并没有什么耐心去看这些代码

CWwwer 发表于 2017-1-4 16:11:07

元素战争 发表于 2017-1-4 12:15
learn

6666666666

CWwwer 发表于 2017-1-4 16:11:24

6666666

CWwwer 发表于 2017-1-4 16:11:44

CHRISHAO 发表于 2017-1-4 13:28
zan

666666666

苦行者 发表于 2017-1-4 16:19:34

为了元素币,拼了!

CHRISHAO 发表于 2017-1-4 16:33:50

元素战争 发表于 2017-1-4 12:15
learn

6

啊实打实宝贝 发表于 2017-1-4 17:12:31

不错!

啊实打实宝贝 发表于 2017-1-4 17:13:05

CHRISHAO 发表于 2017-1-4 13:28
zan

不错!

baokebk 发表于 2017-1-4 17:43:49

许逗推荐过来看看1231232

魔法禁书目录 发表于 2017-1-4 19:31:42

这个太666了

pincers 发表于 2017-1-5 08:56:41

感谢楼主分享、

我佛现慈悲 发表于 2017-1-5 10:52:02

{:1_144:}

我佛现慈悲 发表于 2017-1-5 10:52:18

{:1_144:}

太阳l 发表于 2017-1-5 14:23:07

·············································································

376569522 发表于 2017-1-7 00:48:32

从业不识微元素,做遍项目也枉然
页: [1] 2 3
查看完整版本: Unity3D 像素风格《猫捕鱼》小游戏(二)