赞
踩
一.游戏简介:
这是一个简单的打靶游戏,总共有五环,从外到里依次是一到五环,打到一环得一分,二环得二分,依此类推
玩家可以通过方向键或asdw键来控制发射的位置,还有,在游戏当中,还会有风来影响箭的飞行方向
二.游戏效果图:
三.UML图:
四.游戏主要代码和设置说明:
1.游戏中是用了虚拟轴来控制箭的位置,不过移动箭的代码是挂在一个空对象上的,而箭是它的子对象,当箭射出的时候,就把它的parent置为null,这样在
箭射出后就不能控制箭了,移动的代码如下:
- void Update () {
- float translationY = Input.GetAxis("Vertical") * speed;
- float translationX = Input.GetAxis("Horizontal") * speed;
- translationY *= Time.deltaTime;
- translationX *= Time.deltaTime;
- this.gameObject.transform.Translate(0, translationY, 0);
- this.gameObject.transform.Translate(-translationX, 0, 0);
- }
- horizontalSpeed = gameobject.GetComponent<ArrowData>().speed;
- direction = Vector3.back;
- rigid = this.gameobject.GetComponent<Rigidbody>();
- rigid.velocity = direction * horizontalSpeed;
3.游戏中靶是有五个圆柱体和一个空对象组成的,圆柱体是空对象的子对象,通过圆柱体细微的高度差异,就可以显示各个环的颜色,
通过mesh触发器,就可以和箭产生出发事件,各个圆柱的设置差不多,只是其中一个:
4.但各个圆柱的触发区域有重叠的地方,我这里是用一个数组来记录有哪些环出发了,然后选得分最大的那个环
hitedTarget = new bool[5] { false, false, false, false, false };
- public void setHitedTarget(int ring)
- {
- hitedTarget[ring - 1] = true;
- }
- private void OnTriggerEnter(Collider other)
- {
- if (other.gameObject.GetComponent<Rigidbody>())
- {
- other.gameObject.transform.FindChild("head").gameObject.SetActive(false);
- other.gameObject.GetComponent<Rigidbody>().isKinematic = true;
- sceneController.setHitedTarget((int)this.gameObject.name[0] - (int)'0'); //环的名字是对应第几环
- }
-
- }
- void FixedUpdate() {
- if (rigid.useGravity) //当箭射出时,刚体的useGravity属性才会置为true
-
- {
- rigid.AddForce(force);
- }
- }
1.ArrowData.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ArrowData : MonoBehaviour {
-
- public Vector3 size;
- public Color color;
- public float speed;
- public Vector3 direction;
- public bool destroy;
- public bool used;
- }
- /**
- * 这个文件是用来生产飞碟的工厂
- */
-
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ArrowFactory : MonoBehaviour
- {
-
-
-
- public GameObject ArrowPrefab;
- public GameObject person;
-
- float time = 0;
-
- /**
- * used是用来保存正在使用的箭
- * free是用来保存未激活的箭
- */
-
- private Dictionary<int, ArrowData> used = new Dictionary<int, ArrowData>();
- private List<ArrowData> free = new List<ArrowData>();
- private List<int> wait = new List<int>();
-
- private void Awake()
- {
- ArrowPrefab = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/arrow"), Vector3.zero, Quaternion.identity);
- person = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/person"), new Vector3(0,0,3), Quaternion.identity);
- ArrowPrefab.SetActive(false);
- }
-
-
- public GameObject GetArrow()
- {
- GameObject newArrow = null;
- if (free.Count > 0)
- {
- newArrow = free[0].gameObject;
- free.Remove(free[0]);
- }
- else
- {
- newArrow = GameObject.Instantiate<GameObject>(ArrowPrefab, Vector3.zero, Quaternion.identity);
- }
-
- ArrowData data = newArrow.GetComponent<ArrowData>();
- data.destroy = false;
- data.speed = 15f;
- data.used = false;
- data.transform.rotation = Quaternion.identity;
- newArrow.transform.position = new Vector3(0, 0, 3);
-
- Rigidbody rigid = newArrow.GetComponent<Rigidbody>();
- rigid.isKinematic = false;
- rigid.useGravity = false;
- rigid.velocity = Vector3.zero;
-
- used.Add(data.GetInstanceID(), data);
- newArrow.transform.parent = person.transform;
- newArrow.SetActive(true);
- return newArrow;
- }
-
- public void FreeArrow(GameObject Arrow)
- {
- ArrowData tmp = null;
- int key = Arrow.GetComponent<ArrowData>().GetInstanceID();
- if (used.ContainsKey(key))
- {
- tmp = used[key];
- }
-
- if (tmp != null)
- {
- tmp.gameObject.SetActive(false);
- free.Add(tmp);
- used.Remove(key);
- }
- }
-
- private void Update()
- {
- time += Time.deltaTime;
- if (time > 10f)
- {
- clear();
- time = 0;
- }
-
- foreach (var tmp in used.Values)
- {
-
- if (tmp.destroy)
- {
- wait.Add(tmp.GetInstanceID());
- }
- }
-
- foreach (int tmp in wait)
- {
- FreeArrow(used[tmp].gameObject);
- }
- wait.Clear();
- }
-
- public void clear()
- {
- foreach (var tmp in used.Values)
- {
- if (tmp.GetComponent<ArrowData>().used)
- {
- tmp.gameObject.SetActive(false);
- tmp.destroy = true;
- }
-
- }
- }
- }
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class CCActionManager : SSActionManager, ISSActionCallback {
-
- public FirstSceneControl sceneController;
-
- protected void Start()
- {
- sceneController = (FirstSceneControl)Director.getInstance().currentSceneControl;
- sceneController.actionManager = this;
-
- }
-
- public void SSActionEvent(SSAction source,
- SSActionEventType events = SSActionEventType.Competeted,
- int intParam = 0,
- string strParam = null,
- UnityEngine.Object objectParam = null)
- {
-
- if (!source.gameobject.activeSelf)
- {
- source.gameobject.GetComponent<ArrowData>().destroy = true;
- }
-
- if (source is CCFlyAction)
- {
- source.gameobject.GetComponent<ArrowData>().used = true;
- sceneController.setGameState(GameState.DART_FINISH);
- source.reset();
- }
-
-
- }
-
- public void StartThrow(GameObject Arrow)
- {
- CCFlyActionFactory cf = Singleton<CCFlyActionFactory>.Instance;
- RunAction(Arrow, cf.GetSSAction(), (ISSActionCallback)this);
- Arrow.transform.parent = null;
- Arrow.GetComponent<Rigidbody>().useGravity = true;
- }
- }
- /**
- * 这个文件是实现飞碟的飞行动作
- */
-
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class CCFlyAction : SSAction {
-
-
- float horizontalSpeed;
-
- Vector3 direction;
-
- Rigidbody rigid;
-
- public override void Start () {
- enable = true;
- horizontalSpeed = gameobject.GetComponent<ArrowData>().speed;
- direction = Vector3.back;
- rigid = this.gameobject.GetComponent<Rigidbody>();
- rigid.velocity = direction * horizontalSpeed;
- rigid.useGravity = false;
- }
-
- // Update is called once per frame
-
-
- public override void FixedUpdate () {
-
- if (gameobject.activeSelf && rigid)
- {
-
-
- if (this.transform.position.y < -4)
- {
- this.destroy = true;
- this.enable = false;
- this.gameobject.SetActive(false);
- this.callback.SSActionEvent(this);
- }
-
- if (rigid.isKinematic)
- {
- this.enable = false;
- this.callback.SSActionEvent(this);
- }
-
- }
-
- }
-
- public static CCFlyAction GetCCFlyAction()
- {
- CCFlyAction action = ScriptableObject.CreateInstance<CCFlyAction>();
- return action;
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class CCFlyActionFactory : MonoBehaviour {
-
- private Dictionary<int, SSAction> used = new Dictionary<int, SSAction>();
- private List<SSAction> free = new List<SSAction>();
- private List<int> wait = new List<int>();
-
- public CCFlyAction Fly;
-
- // Use this for initialization
- void Start () {
- Fly = CCFlyAction.GetCCFlyAction();
- }
-
-
- private void Update()
- {
- foreach (var tmp in used.Values)
- {
- if (tmp.destroy)
- {
- wait.Add(tmp.GetInstanceID());
- }
- }
-
- foreach (int tmp in wait)
- {
- FreeSSAction(used[tmp]);
- }
- wait.Clear();
- }
-
- public SSAction GetSSAction()
- {
- SSAction action = null;
- if (free.Count > 0)
- {
- action = free[0];
- free.Remove(free[0]);
- }
- else
- {
- action = ScriptableObject.Instantiate<CCFlyAction>(Fly);
- }
-
- used.Add(action.GetInstanceID(), action);
- return action;
- }
-
- public void FreeSSAction(SSAction action)
- {
- SSAction tmp = null;
- int key = action.GetInstanceID();
- if (used.ContainsKey(key))
- {
- tmp = used[key];
- }
-
- if (tmp != null)
- {
- tmp.reset();
- free.Add(tmp);
- used.Remove(key);
- }
- }
-
- public void clear()
- {
- foreach (var tmp in used.Values)
- {
- tmp.enable = false;
- tmp.destroy = true;
-
- }
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class CCMoveDartAction : MonoBehaviour {
-
- // Use this for initialization
- void Start () {
-
- }
- float speed = 4f;
- // Update is called once per frame
- void Update () {
- float translationY = Input.GetAxis("Vertical") * speed;
- float translationX = Input.GetAxis("Horizontal") * speed;
- translationY *= Time.deltaTime;
- translationX *= Time.deltaTime;
- this.gameObject.transform.Translate(0, translationY, 0);
- this.gameObject.transform.Translate(-translationX, 0, 0);
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class collision : MonoBehaviour {
-
- public FirstSceneControl sceneController;
-
- // Use this for initialization
- void Start() {
- sceneController = (FirstSceneControl)Director.getInstance().currentSceneControl;
- }
-
- private void OnTriggerEnter(Collider other)
- {
- if (other.gameObject.GetComponent<Rigidbody>())
- {
- other.gameObject.transform.FindChild("head").gameObject.SetActive(false);
- other.gameObject.GetComponent<Rigidbody>().isKinematic = true;
- sceneController.setHitedTarget((int)this.gameObject.name[0] - (int)'0');
- }
-
- }
- }
- /**
- * 这个文件是用来场景控制的,负责各个场景的切换,
- * 虽然目前只有一个场景
- */
-
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Director : System.Object {
-
- /**
- * currentSceneControl标志目前正在使用的场景
- */
-
- public ISceneControl currentSceneControl { get; set; }
-
- /**
- * Director这个类是采用单例模式
- */
-
- private static Director director;
-
- private Director()
- {
-
- }
-
- public static Director getInstance()
- {
- if (director == null)
- {
- director = new Director();
- }
- return director;
- }
- }
- /**
- * 这个文件是用来控制主游戏场景的
- */
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class FirstSceneControl : MonoBehaviour, ISceneControl, IUserAction {
-
- /**
- * actionManager是用来指定当前的动作管理器
- */
-
- public CCActionManager actionManager { get; set; }
-
- /**
- * scoreRecorder是用来指定当前的记分管理对象的
- */
-
- public ScoreRecorder scoreRecorder { get; set; }
-
-
- public bool[] hitedTarget = null;
-
- /**
- * gameState是用来保存当前的游戏状态
- */
-
- private GameState gameState;
- private GameObject currentArrow;
-
- void Awake () {
- Director director = Director.getInstance();
- director.currentSceneControl = this;
- gameState = GameState.DART_START;
- hitedTarget = new bool[5] { false, false, false, false, false };
- this.gameObject.AddComponent<ScoreRecorder>();
- this.gameObject.AddComponent<ArrowFactory>();
- this.gameObject.AddComponent<CCFlyActionFactory>();
- scoreRecorder = Singleton<ScoreRecorder>.Instance;
- director.currentSceneControl.LoadResources();
- }
-
- private void Update()
- {
- /**
- * 以下代码用来管理游戏的状态
- */
-
-
- if (gameState == GameState.DART_FINISH)
- {
- int ring = check();
- scoreRecorder.Record(ring);
- gameState = GameState.DART_START;
- }
-
- if (gameState == GameState.DART_START)
- {
- ArrowFactory df = Singleton<ArrowFactory>.Instance;
- currentArrow = df.GetArrow();
- gameState = GameState.WAIT;
- }
-
- if (gameState == GameState.SHOOT)
- {
- actionManager.StartThrow(currentArrow);
- gameState = GameState.RUNNING;
- }
-
- }
-
- public void LoadResources()
- {
- GameObject DartsBoard = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/dartsboard"));
- GameObject plane = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/plane"));
-
- }
-
- public string GetWindInfo()
- {
- float wind = currentArrow.GetComponent<wind>().GetForce();
- if (wind < 0)
- {
- return "Right " + (-wind).ToString();
- }
- else
- {
- return "Left " + wind.ToString();
- }
-
- }
-
- public int GetScore()
- {
- return scoreRecorder.score;
- }
-
- public GameState getGameState()
- {
- return gameState;
- }
-
- public void setGameState(GameState gs)
- {
- gameState = gs;
- }
-
- public void setHitedTarget(int ring)
- {
- hitedTarget[ring - 1] = true;
- }
-
- public int check()
- {
- int result = -1;
- for (int i = 4; i >= 0; i--)
- {
- if (hitedTarget[i])
- {
- result = i;
- break;
- }
- }
-
- for (int i = 4; i >= 0; i--)
- {
- hitedTarget[i] = false;
- }
- return result + 1;
- }
- }
- /*
- * 场景控制的必须实现的接口
- */
-
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public interface ISceneControl {
- void LoadResources();
- }
- /**
- * 这个接口负责动作与动作管理器间的通信
- */
-
- 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);
-
- }
- /**
- * UI界面与场景管理器通信的接口
- */
-
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public enum GameState { RUNNING, DART_START, DART_FINISH, WAIT, SHOOT}
-
- public interface IUserAction {
- GameState getGameState();
- void setGameState(GameState gs);
- int GetScore();
- string GetWindInfo();
- }
- /**
- * 这个类是用来记录玩家得分的
- */
-
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ScoreRecorder : MonoBehaviour {
-
- /**
- * score是玩家得到的总分
- */
-
- public int score;
-
- /**
- * scoreTable是一个得分的规则表,每种飞碟的颜色对应着一个分数
- */
-
- private Dictionary<int, int> scoreTable = new Dictionary<int, int>();
-
- // Use this for initialization
- void Start () {
- score = 0;
- scoreTable.Add(0, 0);
- scoreTable.Add(1, 1);
- scoreTable.Add(2, 2);
- scoreTable.Add(3, 3);
- scoreTable.Add(4, 4);
- scoreTable.Add(5, 5);
- }
-
- public void Record(int ring)
- {
- score += scoreTable[ring];
- }
-
- public void Reset()
- {
- score = 0;
- }
- }
- /**
- * 这是一个实现单例模式的模板,所有的MonoBehaviour对象都用这个模板来实现单实例
- */
-
- 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;
- }
- }
- }
- /**
- * 所有动作的基类
- */
-
- 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 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 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>(); //动作的删除队列,在这个对象保存的动作会稍后删除
-
-
- // Update is called once per frame
- protected void FixedUpdate()
- {
- //把等待队列里所有的动作注册到动作管理器里
- foreach (SSAction ac in waitingAdd) actions[ac.GetInstanceID()] = ac;
- waitingAdd.Clear();
-
- //管理所有的动作,如果动作被标志为删除,则把它加入删除队列,被标志为激活,则调用其对应的Update函数
- 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();
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class UserGUI : MonoBehaviour
- {
- private IUserAction action;
-
- void Start () {
- action = Director.getInstance().currentSceneControl as IUserAction;
- }
-
- private void OnGUI()
- {
- if (GUI.Button(new Rect(900, 500, 90, 90), "shoot") && (action.getGameState() == GameState.WAIT))
- {
- action.setGameState(GameState.SHOOT);
- }
-
- GUI.Label(new Rect(500, 90, 90, 90), "Force: " + action.GetWindInfo());
- GUI.Label(new Rect(900, 90, 90, 90), "Score: " + action.GetScore().ToString());
-
- }
-
-
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class wind : MonoBehaviour {
-
- Vector3 force;
- Rigidbody rigid;
-
- void Start() {
- float xforce = Random.Range(-0.5f, 0.5f);
- force = new Vector3(xforce, 0, 0);
- rigid = this.gameObject.GetComponent<Rigidbody>();
- }
-
-
- void FixedUpdate() {
- if (rigid.useGravity)
- {
- rigid.AddForce(force);
- }
-
- }
-
- public float GetForce()
- {
- return force.x;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。