代码说明:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DiskFactory : MonoBehaviour
{
private List<DiskData> used = new List<DiskData>();
private List<DiskData> free = new List<DiskData>();
private List<Color> c = new List<Color>();
private void Awake()
{
c.Add(Color.black);
c.Add(Color.blue);
c.Add(Color.cyan);
c.Add(Color.gray);
c.Add(Color.green);
c.Add(Color.magenta);
c.Add(Color.red);
c.Add(Color.white);
c.Add(Color.yellow);
}
public GameObject GetDisk(int round)
{
GameObject newDisk = null;
if (free.Count > 0)
{
newDisk = free[0].gameObject;
free.Remove(free[0]);
}
else
{
newDisk = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("prefabs/disk"), Vector3.zero, Quaternion.identity);
newDisk.AddComponent<DiskData>();
}
int flag;
flag = UnityEngine.Random.Range(0, 5);
newDisk.GetComponent<DiskData>().color = c[(round + flag) % 9];
newDisk.GetComponent<Renderer>().material.color = c[(round + flag) % 9];
newDisk.GetComponent<DiskData>().speed = round * 5;
newDisk.GetComponent<DiskData>().size = getSize(round);
newDisk.transform.localScale = getSize(round);
float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1;
newDisk.GetComponent<DiskData>().direction = new Vector3(RanX, 1, 0);
used.Add(newDisk.GetComponent<DiskData>());
newDisk.name = newDisk.GetInstanceID().ToString();
return newDisk;
}
public void FreeDisk(GameObject disk)
{
disk.SetActive(false);
free.Add(disk.GetComponent<DiskData>());
used.Remove(disk.GetComponent<DiskData>());
}
private Vector3 getSize(int r)
{
if (r == 0)
{
return new Vector3(5, 0.1f, 5);
}
else if (r == 1)
{
return new Vector3(4, 0.1f, 4);
}
else if (r == 2)
{
return new Vector3(3, 0.1f, 3);
}
else if (r == 3)
{
return new Vector3(2, 0.1f, 2);
}
else
{
return new Vector3(1, 0.1f, 1);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DiskData : MonoBehaviour
{
public Vector3 size;
public Color color;
public float speed;
public Vector3 direction;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface ISceneControl
{
void LoadResources();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Director : System.Object
{
// singlton instance
private static Director _instance;
public ISceneControl currentSceneController { get; set; }
public bool running { get; set; }
//get instance anytime anywhere!
public static Director getInstance()
{
if (_instance == null)
{
_instance = new Director();
}
return _instance;
}
public int getFPS()
{
return Application.targetFrameRate;
}
public void setFPS(int fps)
{
Application.targetFrameRate = fps;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FirstController : MonoBehaviour, ISceneControl, IUserAction
{
public ActionMode mode { get; set; }
public IActionManager actionManager { get; set; }
public ScoreRecorder scoreRecorder { get; set; }
private int trial;
private GameState gameState;
public int round = 1;
void Awake()
{
Director director = Director.getInstance();
director.setFPS(60);
director.currentSceneController = this;
this.gameObject.AddComponent<ScoreRecorder>();
this.gameObject.AddComponent<DiskFactory>();
this.gameObject.AddComponent<CCActionManager>();
gameState = GameState.START;
scoreRecorder = Singleton<ScoreRecorder>.Instance;
//actionManager = Singleton.Instance;
setMode(ActionMode.KINEMATIC);
LoadResources();
}
private void Update()
{
if (gameState == GameState.START)
{
scoreRecorder.Reset();
trial = 10;
round = 1;
ThrowDisk();
gameState = GameState.RUNNING;
}
if (gameState == GameState.NEXT_ROUND)
{
round++;
gameState = GameState.RUNNING;
trial = 10;
ThrowDisk();
}
if (gameState == GameState.DROP)
{
gameState = GameState.RUNNING;
trial--;
if (trial == 0)
{
gameState = GameState.GAME_OVER;
}
else
{
ThrowDisk();
}
}
}
void ThrowDisk()
{
DiskFactory df = Singleton<DiskFactory>.Instance;
GameObject disk = df.GetDisk(round);
float y = UnityEngine.Random.Range(0f, 4f);
Vector3 position = new Vector3(-disk.GetComponent<DiskData>().direction.x * 7, y, 0);
disk.transform.position = position;
disk.SetActive(true);
actionManager.StartThrow(disk);
}
public void LoadResources()
{
GameObject greensward = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("prefabs/greensward"));
}
public void hit(Vector3 pos)
{
Ray ray = Camera.main.ScreenPointToRay(pos);
//Return the ray's hit
RaycastHit[] hits;
hits = Physics.RaycastAll(ray);
for (int i = 0; i < hits.Length; i++)
{
RaycastHit hit = hits[i];
if (hit.collider.gameObject.GetComponent<DiskData>() != null)
{
scoreRecorder.AddRecord(round);
DiskFactory df = Singleton<DiskFactory>.Instance;
df.FreeDisk(hit.collider.gameObject);
setGameState(GameState.ROUND_END);
}
}
}
public void setGameState(GameState gs)
{
gameState = gs;
}
public int getRound()
{
return round;
}
public int getScore()
{
return scoreRecorder.score;
}
public int getTrial()
{
return trial;
}
public GameState getGameState()
{
return gameState;
}
public ActionMode getMode()
{
return mode;
}
public void setMode(ActionMode m)
{
if (m == ActionMode.KINEMATIC)
{
this.gameObject.AddComponent<CCActionManager>();
}
else
{
this.gameObject.AddComponent<PhysicActionManager>();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SSActionManager : MonoBehaviour
{
private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();
private List<SSAction> waitingAdd = new List<SSAction>();
private List<int> waitingDelete = new List<int>();
// Use this for initialization
protected void Start()
{
}
// Update is called once per frame
protected void Update()
{
foreach (SSAction ac in waitingAdd) actions[ac.GetInstanceID()] = ac;
waitingAdd.Clear();
foreach (KeyValuePair<int, SSAction> kv in actions)
{
SSAction ac = kv.Value;
if (ac.destroy)
{
waitingDelete.Add(ac.GetInstanceID());
}
else if (ac.enable)
{
ac.Update();// update action
}
}
foreach (int key in waitingDelete)
{
SSAction ac = actions[key];
actions.Remove(key);
DestroyObject(ac);
}
waitingDelete.Clear();
}
public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager)
{
action.gameobject = gameobject;
action.transform = gameobject.transform;
action.callback = manager;
waitingAdd.Add(action);
action.Start();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IActionManager
{
void StartThrow(GameObject disk);
/*int getDiskNumber();
void setDiskNumber(int num);*/
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CCActionManager : SSActionManager, ISSActionCallback, IActionManager
{
public FirstController sceneController;
public List<CCFlyAction> Fly;
public int DiskNumber = 0;
protected new void Start()
{
sceneController = (FirstController)Director.getInstance().currentSceneController;
sceneController.actionManager = this;
}
protected new void Update()
{
base.Update();
}
public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted, int intParam = 0, string strParam = null, UnityEngine.Object objectParam = null)
{
if (source is CCFlyAction)
{
sceneController.setGameState(GameState.DROP);
DiskFactory df = Singleton<DiskFactory>.Instance;
df.FreeDisk(source.gameobject);
}
}
public void StartThrow(GameObject disk)
{
RunAction(disk, CCFlyAction.GetSSAction(disk.GetComponent<DiskData>().speed, disk.GetComponent<DiskData>().direction), (ISSActionCallback)this);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicActionManager : MonoBehaviour, IActionManager, ISSActionCallback
{
public FirstController sceneController;
private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();
private List<SSAction> waitingAdd = new List<SSAction>();
private List<int> waitingDelete = new List<int>();
protected void Start()
{
sceneController = (FirstController)Director.getInstance().currentSceneController;
sceneController.actionManager = this;
}
// Update is called once per frame
protected void FixedUpdate()
{
foreach (SSAction ac in waitingAdd) actions[ac.GetInstanceID()] = ac;
waitingAdd.Clear();
foreach (KeyValuePair<int, SSAction> kv in actions)
{
SSAction ac = kv.Value;
if (ac.destroy)
{
waitingDelete.Add(ac.GetInstanceID());
}
else if (ac.enable)
{
ac.FixedUpdate();
}
}
foreach (int key in waitingDelete)
{
SSAction ac = actions[key];
actions.Remove(key);
DestroyObject(ac);
}
waitingDelete.Clear();
}
public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager)
{
action.gameobject = gameobject;
action.transform = gameobject.transform;
action.callback = manager;
waitingAdd.Add(action);
action.Start();
}
public void SSActionEvent(SSAction source,
SSActionEventType events = SSActionEventType.Competeted,
int intParam = 0,
string strParam = null,
UnityEngine.Object objectParam = null)
{
if (source is CCFlyAction)
{
sceneController.setGameState(GameState.DROP);
DiskFactory df = Singleton<DiskFactory>.Instance;
df.FreeDisk(source.gameobject);
}
}
public void StartThrow(GameObject disk)
{
/*CCFlyActionFactory cf = Singleton.Instance;
foreach (GameObject tmp in diskQueue)
{
RunAction(tmp, cf.GetSSAction(), (ISSActionCallback)this);
}*/
RunAction(disk, CCFlyAction.GetSSAction(disk.GetComponent<DiskData>().speed, disk.GetComponent<DiskData>().direction), (ISSActionCallback)this);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SSAction : ScriptableObject
{
public bool enable = false;
public bool destroy = false;
public GameObject gameobject { get; set; }
public Transform transform { get; set; }
public ISSActionCallback callback { get; set; }
protected SSAction() { }
public virtual void Start()
{
throw new System.NotImplementedException();
}
// Update is called once per frame
public virtual void Update()
{
throw new System.NotImplementedException();
}
public virtual void FixedUpdate()
{
throw new System.NotImplementedException();
}
public void reset()
{
enable = false;
destroy = false;
gameobject = null;
transform = null;
callback = null;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CCFlyAction : SSAction
{
public float acceleration;
public float horizontalSpeed;
public Vector3 direction;
public float time;
public static CCFlyAction GetSSAction(float speed, Vector3 d)
{
CCFlyAction action = ScriptableObject.CreateInstance<CCFlyAction>();
action.acceleration = 9.8f;
action.horizontalSpeed = speed;
action.time = 0;
action.direction = d;
action.enable = true;
return action;
}
public override void Start()
{
}
// Update is called once per frame
public override void Update()
{
if (gameobject.activeSelf)
{
time += Time.deltaTime;
//Debug.Log(time);
transform.Translate(Vector3.down * acceleration * time * Time.deltaTime);
transform.Translate(direction * horizontalSpeed * Time.deltaTime);
if (this.transform.position.y < -4)
{
this.destroy = true;
this.enable = false;
this.callback.SSActionEvent(this);
}
}
}
public override void FixedUpdate()
{
if (gameobject.activeSelf)
{
time += Time.deltaTime;
//Debug.Log(time);
transform.Translate(Vector3.down * acceleration * time * Time.deltaTime);
transform.Translate(direction * horizontalSpeed * Time.deltaTime);
if (this.transform.position.y < -4)
{
this.destroy = true;
this.enable = false;
this.callback.SSActionEvent(this);
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum SSActionEventType : int { Started, Competeted }
public interface ISSActionCallback
{
void SSActionEvent(SSAction source,
SSActionEventType events = SSActionEventType.Competeted,
int intParam = 0,
string strParam = null,
Object objectParam = null);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum GameState { START, NEXT_ROUND, GAME_OVER, RUNNING, ROUND_END, DROP }
public enum ActionMode { PHYSIC, KINEMATIC, NOTSET }
public interface IUserAction
{
int getRound();
int getScore();
int getTrial();
GameState getGameState();
void setGameState(GameState gs);
void hit(Vector3 pos);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UserGUI : MonoBehaviour
{
private IUserAction action;
private int score;
private int trial;
private int round;
// Use this for initialization
void Start()
{
action = Director.getInstance().currentSceneController as IUserAction;
//Debug.Log(action.getTrial());
}
private void Update()
{
Debug.Log("hi");
score = action.getScore();
trial = action.getTrial();
round = action.getRound();
}
void OnGUI()
{
//Debug.Log(action == null);
//Debug.Log(action.getTrial());
GUI.Box(new Rect(Screen.width / 2 - 75, 10, 150, 55), "Round " + (round) + "\nYour score: " + score + "\nYour trial left: " + (trial));
if (action.getGameState() == GameState.ROUND_END)
{
GUI.Window(0, new Rect(Screen.width / 2 - Screen.width / 12, Screen.height / 2 - Screen.height / 12, Screen.width / 6, Screen.height / 6), next_round_window, "Success !");
}
if (action.getGameState() == GameState.GAME_OVER)
{
GUI.Window(0, new Rect(Screen.width / 2 - Screen.width / 12, Screen.height / 2 - Screen.height / 12, Screen.width / 6, Screen.height / 6), game_over_window, "Game Orver!");
}
if (Input.GetButtonDown("Fire1"))
{
Vector3 pos = Input.mousePosition;
action.hit(pos);
}
}
void next_round_window(int id)
{
if (GUI.Button(new Rect(Screen.width / 24, Screen.height / 24 + 5, Screen.width / 12, Screen.height / 12), "Next"))
{
action.setGameState(GameState.NEXT_ROUND);
}
}
void game_over_window(int id)
{
if (GUI.Button(new Rect(Screen.width / 24, Screen.height / 24 + 5, Screen.width / 12, Screen.height / 12), "Restart"))
{
Debug.Log("Restart");
action.setGameState(GameState.START);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScoreRecorder : MonoBehaviour
{
public int score;
// Use this for initialization
void Start()
{
score = 0;
}
public void AddRecord(int round)
{
score += round;
}
public void Reset()
{
score = 0;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
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;
}
}
}