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 *****
{:1_141:} learn 6666 zan 666666太喜欢了,楼主好人! 讲道理,我并没有什么耐心去看这些代码 元素战争 发表于 2017-1-4 12:15
learn
6666666666 6666666 CHRISHAO 发表于 2017-1-4 13:28
zan
666666666 为了元素币,拼了! 元素战争 发表于 2017-1-4 12:15
learn
6 不错! CHRISHAO 发表于 2017-1-4 13:28
zan
不错! 许逗推荐过来看看1231232 这个太666了 感谢楼主分享、 {:1_144:} {:1_144:} ············································································· 从业不识微元素,做遍项目也枉然