您的位置:首页 > 移动开发 > Unity3D

Unity3D作业六项目一——优化打飞碟游戏

2017-04-05 16:59 211 查看
这次作业,主要使用了单实例的工厂类,从而可以让各个类之间的访问通过Singleton<T>来进行访问。

其次,这次的优化在于将Rule类分开来,把游戏的分数,胜利条件放在Rule类中,从而便于日后管理

而涉及到飞碟的颜色等等属性则放在UFO管理之中,从而实现了分离原则。

UI没有太多的改动,主要是显示内容和控制发射。

这次的场景控制器只有分数,关卡和游戏状态,大大简化了场景控制器所需要知道的东西。

UFO管理是整个游戏的核心之一,因为涉及到UFO的各个状态,所以包括资源的加载,回收和发射飞碟,都是在这个类之中实现的。

动作管理器很简单,写了两个函数用来调用UFO管理的函数。

加载在UFO实例上的两个Compent,一个实现了物理引擎,一个没有实现

这次单数关卡是物理,双数不是。可以继续优化的点在于可以创建一个按钮来实现切换,不过这次就没实现了。

爆炸效果和子弹也都是在UFO管理之中。下面上代码,UML图和效果图






using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyGame;
using UnityEngine.UI;
using rule;

public class UserControl : MonoBehaviour
{

public Text Main_Text; // 显示主提示
public Text Score_Text; // 显示得分
public Text Level_Text; // 显示回合
public Camera cam;
public bool IsFinish = false;
SceneController SC;
GameControl GC;
Rule RC;
UFOControl UF;
private void Awake()
{
SC = Singleton<SceneController>.Instance;
GC = Singleton<GameControl>.Instance;
RC = Singleton<Rule>.Instance;
UF = Singleton<UFOControl>.Instance;
}

void Start()
{
Score_Text.text = "Score: "+SC.getScore();
Level_Text.text = "Level: " + SC.getNowLevel();
Main_Text.text = "Gaming";
}

// Update is called once per frame
void Update()
{
if (IsFinish == true)
{
if (RC.CheckStatus() == 1)
Main_Text.text= "Win";
else
Main_Text.text = "False";
}
if (Input.GetKeyDown("space") && IsFinish == false)
{
GC.Launch_UFO();
}
else if (Input.GetMouseButtonDown(0))
{
Vector3 mp = Input.mousePosition;
Ray ray = Camera.main.ScreenPointToRay(mp); // 摄像机到鼠标射线
UF.bullet.GetComponent<Rigidbody>().velocity = Vector3.zero; // 子弹刚体速度重置
UF.bullet.GetComponent<Transform>().position = transform.position; // 子弹从摄像机位置射出
UF.bullet.GetComponent<Rigidbody>().AddForce(ray.direction*50, ForceMode.Impulse);

RaycastHit hit;
if (Physics.Raycast(ray, out hit) && hit.collider.gameObject.tag == "UFO")
{
// 播放爆炸粒子特效
UF.explosion.transform.position = hit.collider.gameObject.transform.position;
//UF.explosion.GetComponent<Renderer>().material.color = hit.collider.gameObject.GetComponent<Renderer>().material.color;
UF.explosion.Play();
GC.Hit_UFO(hit.collider.gameObject);
}

}

Level_Text.text = "Level: "+ SC.getNowLevel();
Score_Text.text = "Score: "+SC.getScore();
}

}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyGame;
using rule;

public class GameControl : MonoBehaviour
{

UFOControl UC;
private void Awake()
{
UC= Singleton<UFOControl>.Instance;
}

public void Launch_UFO()
{
UC.Launch_UFO();
}

public void Hit_UFO(GameObject temp)
{
UC.Hit_UFO(temp);
}

}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyGame;
using rule;

namespace MyGame
{

public class UFOControl : MonoBehaviour
{
private List<GameObject> UFO_Ready_List = new List<GameObject>();
private List<GameObject> UFO_Active_List = new List<GameObject>();
private List<GameObject> UFO_UnActive_List = new List<GameObject>();
public GameObject UFO_Pre;  //  UFO预制
public GameObject bullet; //子弹预制
public ParticleSystem explosion; //爆炸预制
private Vector3 UnusedPlace = new Vector3(1000f, 1000f, 1000f);

private Color UFO_Color;                //颜色
private int UFO_Number = 10;         // 飞碟一共的数量
private int UFO_Speed;               //飞碟的速度

Rule Crule;
private void Awake()
{
Crule = Singleton<Rule>.Instance;
}

public Color getColor()
{
return UFO_Color;
}
public int getSpeed()
{
return UFO_Speed;
}

public void Start()
{

for(int i=0; i<10;i++)
{
GameObject Temp = GameObject.Instantiate(UFO_Pre, UnusedPlace, Quaternion.identity) as GameObject;
UFO_Ready_List.Add(Temp);
}

}

//资源加载
public void Load_Reources(Level level)
{
if (level == Level.Ready)
{
UFO_Color = Color.blue;
UFO_Speed = 1;
Launch_Ready_UFO();
}
else if (level == Level.First)
{
UFO_Color = Color.green;
UFO_Speed = 3;
Launch_Ready_UFO();
}
else if (level == Level.Second)
{
UFO_Color = Color.red;
UFO_Speed = 5;
Launch_Ready_UFO();
}
}
//发射准备
public void Launch_Ready_UFO()
{
Debug.Log("SSS");
for (int i = 0; i < 10; i++)
{
if (UFO_Active_List.Count != 0)
{
GameObject temp = UFO_Active_List[0];
temp.transform.position = UnusedPlace;
UFO_Ready_List.Add(temp);
UFO_Active_List.Remove(temp);
}
else if (UFO_UnActive_List.Count != 0)
{
GameObject temp = UFO_UnActive_List[0];
temp.transform.position = UnusedPlace;
UFO_Ready_List.Add(temp);
UFO_UnActive_List.Remove(temp);
}
}
}

public void Launch_UFO()
{
if (UFO_Ready_List.Count == 0)
{
isFlaseStatus();
}
else
{
GameObject Temp =UFO_Ready_List[0];
UFO_Ready_List.Remove(Temp);
Temp.GetComponent<Renderer>().material.color = UFO_Color;

if(Crule.getNowLevel() == Level.First || Crule.getNowLevel() == Level.Tird)
{
UFOCompent ac = Temp.AddComponent<UFOCompent>();
Temp.transform.position = new Vector3(0 + Random.Range(-10, 10), 8 + Random.Range(-4, 5), 0);
ac.setting(UFO_Speed);
}
else
{
UFOCompentP ac = Temp.AddComponent<UFOCompentP>();
Temp.transform.position = new Vector3(0 + Random.Range(-10, 10), 8 + Random.Range(-4, 5), 0);
ac.setting(UFO_Speed);
}

UFO_Active_List.Add(Temp);

}

}

public void Hit_UFO(GameObject temp)
{
UFO_Active_List.Remove(temp);
UFO_UnActive_List.Add(temp);
temp.transform.position = new Vector3(1000f, 1000f, 1000f);
Crule.HitUFO();

}

public void Miss_UFO(GameObject temp)
{
UFO_Active_List.Remove(temp);
UFO_UnActive_List.Add(temp);
}
//游戏结束判断
public void isFlaseStatus()
{
Crule.IsFalseStatus();
}

}
}

using MyGame;
using rule;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UFOCompent : MonoBehaviour
{

private float time;
public float UFO_Speed;
public float UFO_Speed_y;
public float UFO_Speed_x;
// Use this for initialization
Rule Srule;
UFOControl UC;

private void Awake()
{
Srule = Singleton<Rule>.Instance;
UC = Singleton<UFOControl>.Instance;
}
public void setting(float Speed)
{
time = Time.time;
UFO_Speed = Speed;
}

// Update is called once per frame
void Update()
{

UFO_Speed_y = UnityEngine.Random.Range(0, 3) + UFO_Speed;
UFO_Speed_x = UnityEngine.Random.Range(-10, 10) + UFO_Speed;
transform.Translate(Vector3.down * Time.deltaTime * UFO_Speed_y, Space.World);
transform.Translate(Vector3.left * Time.deltaTime * UFO_Speed_x);

if (this.gameObject.transform.position.y < -3)
{

bb9c
this.gameObject.transform.position = new Vector3(1000f, 1000f, 1000f);
UC.explosion.GetComponent<Transform>().position = new Vector3(1000f, 1000f, 1000f);
}
if (Time.time - time > 8 || this.gameObject.transform.position.y < -3)
{
UC.Miss_UFO(this.gameObject);
this.gameObject.transform.position = new Vector3(1000f, 1000f, 1000f);
UC.explosion.GetComponent<Transform>().position = new Vector3(1000f, 1000f, 1000f);
Destroy(this);
}
}
}

using MyGame;
using rule;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UFOCompentP : MonoBehaviour
{

private float time;
public float UFO_Speed;
// Use this for initialization
Rule Srule;
UFOControl UC;

private void Awake()
{
Srule = Singleton<Rule>.Instance;
UC = Singleton<UFOControl>.Instance;
}
public void setting(float Speed)
{
time = Time.time;
UFO_Speed = Speed;
}

// Update is called once per frame
void FixedUpdate()
{
this.gameObject.AddComponent<Rigidbody>();
Rigidbody rigid = this.gameObject.GetComponent<Rigidbody>();
if (rigid)
{
rigid.AddForce(Vector3.down * 3.3f);
if (Random.Range(-1, 1) < 0)
rigid.AddForce(Vector3.left * 1.0f);
else
rigid.AddForce(Vector3.right * 1.0f);
}

if (this.gameObject.transform.position.y < -3)
{
this.gameObject.transform.position = new Vector3(1000f, 1000f, 1000f);
UC.explosion.GetComponent<Transform>().position = new Vector3(1000f, 1000f, 1000f);
}
if (Time.time - time > 8 || this.gameObject.transform.position.y < -3)
{
UC.Miss_UFO(this.gameObject);
this.gameObject.transform.position = new Vector3(1000f, 1000f, 1000f);
UC.explosion.GetComponent<Transform>().position = new Vector3(1000f, 1000f, 1000f);
Destroy(this);
}
}
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyGame;

//Rule类负责这个游戏的核心规则
//游戏的胜负,游戏的关卡变化,游戏的分数变化

namespace rule
{
public enum Level { Ready, First, Second, Tird }; //关卡信息
public class Rule : MonoBehaviour
{

private int Score = 0; //游戏的分数
private int GoalScore = 5; // 目标分数
private Level NowLevel = Level.Ready; // 游戏的关卡
private bool isWin = false;
private bool isFalse = false;
UFOControl RUFOControl;
public int getScore()
{
return Score;
}

public Level getNowLevel()
{
return NowLevel;
}

// 得分
public void HitUFO()
{
Score++;
Debug.Log("Good! Now Score: " + Score);
}

//关卡判断
public void IsNextLevel()
{
if (NowLevel == Level.Ready)
{
RUFOControl.Load_Reources(NowLevel);
NowLevel = Level.First;
}
else if (NowLevel == Level.First && Score >= GoalScore)
{
RUFOControl.Load_Reources(NowLevel);
Score = 0;
NowLevel = Level.Second;
}
else if (NowLevel == Level.Second && Score >= GoalScore)
{
RUFOControl.Load_Reources(NowLevel);
Score = 0;
NowLevel = Level.Tird;
}
else if (NowLevel == Level.Tird && Score >= GoalScore)
isWin = true;
else
{
if (Score < 0)
isFalse = true;
}
}

//检查游戏是否结束
public int CheckStatus()
{
if (isWin == true)
return 1;
else if (isFalse == true)
return -1;
else
return 0;
}

public void IsFalseStatus()
{
if (Score < GoalScore)
{
isFalse = true;
}
}

private void Awake()
{
RUFOControl = Singleton<UFOControl>.Instance;
}

public void Start()
{
IsNextLevel();
}

}

}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyGame;
using rule;

namespace MyGame
{

//场景单实例
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{

protected static T instance;

public static T Instance
{
get
{
if (instance == null)
{
instance = (T)FindObjectOfType(typeof(T));
if (instance == null)
{
Debug.LogError("An instance of " + typeof(T)
+ " is needed in the scene, but there is none.");
}
}
return instance;
}
}
}

public class SceneController : MonoBehaviour
{

private int Now_Score;   //当前分数
private Level Now_Level;//当前关卡
private int IsStatus = 0;//游戏状态

Rule Srule;
UserControl USC;
private void Awake()
{
Srule = Singleton<Rule>.Instance;
USC = Singleton<UserControl>.Instance;
}

public int getScore()
{
return Now_Score;
}

public Level getNowLevel()
{
return Now_Level;
}

public void Start()
{
Now_Score = Srule.getScore();
Now_Level = Srule.getNowLevel();
}

public void Update()
{
Srule.IsNextLevel();
Now_Score = Srule.getScore();
Now_Level  = Srule.getNowLevel();
IsStatus =  Srule.CheckStatus();
if (IsStatus == -1)
USC.IsFinish = true;
else if (IsStatus == 1)
USC.IsFinish = true;

}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: