做一个简单的射靶游戏

来源:互联网 发布:年度十大精品网络剧 编辑:程序博客网 时间:2024/06/05 07:24

简介

就是。。一个简单的射靶游戏, 有随机的风向,越接近靶心分数越高。

对象处理

我们。。需要一支箭和一个靶。。
靶由5个圆柱体拼接而成,然后在父对象那里挂载刚体主件,5个子对象分别挂载mesh collider组件
这里写图片描述
箭由箭头(圆柱体),箭身(圆柱体),箭尾(两个相交的平面)构建而成
这里写图片描述
同样,父对象挂刚体,子对象挂碰撞器,然后。。我们就可以写代码啦。。

UML

其实这个UML图跟上次的打飞碟的 UML图大同小异,就把Disk改为Arrow就行啦
这里写图片描述

代码

这里就只展示跟之前不同的部分
DiskData对应ArrowScript

using System.Collections;using System.Collections.Generic;using UnityEngine;public class ArrowScript : MonoBehaviour {    public string shootring;    private ScoreRecorder recorder;    void OnTriggerEnter(Collider other) {        shootring = other.gameObject.tag;        Destroy(GetComponent<Rigidbody>());        recorder.Record(shootring);    }    void Awake() {        recorder = (ScoreRecorder)FindObjectOfType(typeof(ScoreRecorder));    }}

记分系统稍微改改

using System.Collections;using System.Collections.Generic;using UnityEngine;public class ScoreRecorder : MonoBehaviour {    private float score;    public float getScore() {        return score;    }    public void Record(string target_ring) {        switch (target_ring) {        case "Ring10": score += 10; break;        case "Ring8": score += 8; break;        case "Ring6": score += 6; break;        case "Ring4": score += 4; break;        case "Ring2": score += 2; break;        }    }    public void Reset() {        score = 0;    }}

UI加入风速

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public interface IUserAction {    void shoot();}public class UserGUI : MonoBehaviour {    private IUserAction action;    private float width, height;    private string countDownTitle;    public RoundActionManager actionmanager;    void Start() {        countDownTitle = "Start";        action = Director.getInstance().currentSceneController as IUserAction;    }    float castw(float scale) {        return (Screen.width - width) / scale;    }    float casth(float scale) {        return (Screen.height - height) / scale;    }    void OnGUI() {        width = Screen.width / 12;        height = Screen.height / 12;        GUI.Label(new Rect(castw(2f)+20, casth(6f) - 20, 50, 50), ((RoundController)Director.getInstance().currentSceneController).leaveSeconds.ToString());        GUI.Button(new Rect(580, 10, 80, 30), ((RoundController)Director.getInstance().currentSceneController).scoreRecorder.getScore().ToString());        if (Director.getInstance().currentSceneController.state != State.WIN && Director.getInstance().currentSceneController.state != State.LOSE            && GUI.Button(new Rect(10, 10, 80, 30), countDownTitle)) {            if (countDownTitle == "Start") {                countDownTitle = "Pause";                Director.getInstance().currentSceneController.Resume();            } else {                countDownTitle = "Start";                Director.getInstance().currentSceneController.Pause();            }        }        if (Director.getInstance().currentSceneController.state == State.WIN) {            if (GUI.Button(new Rect(castw(2f), casth(6f), width, height), "Win!")) Director.getInstance().currentSceneController.Restart();        } else if (Director.getInstance().currentSceneController.state == State.LOSE) {            if (GUI.Button(new Rect(castw(2f), casth(6f), width, height), "Lose!")) Director.getInstance().currentSceneController.Restart();        }    }    public Text windforce;    public Text winddirection;    void Update() {        action.shoot();        float force = actionmanager.getWindForce();        if (force < 0)            winddirection.text = "风向 : 左";        else if (force > 0)            winddirection.text = "风向 : 右";        else            winddirection.text = "风向 : 无";        windforce.text = "风力 : " + actionmanager.getWindForce();        action.shoot();    }}

动作管理器

using System.Collections;using System.Collections.Generic;using UnityEngine;public class RoundActionManager : SSActionManager, ISSActionCallback {    public RoundController scene;    private float speed = 20.0f;    private float force = 0f;    public void shootArrowAction(GameObject arrow, Vector3 dir) {        arrow.transform.position = new Vector3(0, 0, -9);        arrow.transform.up = dir;        arrow.GetComponent<Rigidbody>().velocity = dir * speed;    }    public void wind(GameObject arrow, float time) {           if(time % 2 == 0) force = UnityEngine.Random.Range(-30, 30);        if(arrow != null && arrow.GetComponent<Rigidbody>() != null) {            arrow.GetComponent<Rigidbody>().AddForce(new Vector3(force, 0, 0), ForceMode.Force);        }    }    public float getWindForce() {        return force;    }    protected void Start() {        scene = (RoundController)Director.getInstance().currentSceneController;        scene.actionManager = this;    }    protected new void Update() {        base.Update();    }    public void SSActionEvent(SSAction source,SSActionEventType events = SSActionEventType.Completed,        int intParam = 0,        string strParam = null,        Object objectParam = null) {    }}

控制器

using System;using System.Collections;using System.Collections.Generic;using UnityEngine;public enum State { WIN, LOSE, PAUSE, CONTINUE, START };public class RoundController : MonoBehaviour, IUserAction, ISceneController {    public ArrowFactory arrowFactory;    public RoundActionManager actionManager;    public ScoreRecorder scoreRecorder;    public List<GameObject> arrow;    public GameObject new_arrow;    public GameObject target;    public State state { get; set; }    public int leaveSeconds;    IEnumerator DoCountDown() {        while (leaveSeconds >= 0) {            yield return new WaitForSeconds(1);            leaveSeconds--;        }    }    void Awake() {        Director director = Director.getInstance();        director.setFPS(60);        director.currentSceneController = this;        Director.getInstance().currentSceneController.state = State.PAUSE;        arrowFactory = Singleton<ArrowFactory>.Instance;        scoreRecorder = Singleton<ScoreRecorder>.Instance;        state = State.PAUSE;        leaveSeconds = 60;    }    void Start () {        actionManager = GetComponent<RoundActionManager>() as RoundActionManager;        LoadResources();    }    void Update() {        RecycleArrow ();        Judge();     }    private void FixedUpdate() {        actionManager.wind(new_arrow, leaveSeconds);    }    public void LoadResources() {        Camera.main.transform.position = new Vector3(0, 0, -10);        target =  GameObject.Instantiate(Resources.Load("Prefabs/Target")) as GameObject;        target.transform.position = new Vector3(0, 0, 3);    }    public void shoot() {        if (Input.GetMouseButtonDown(0) && (state == State.START || state == State.CONTINUE)) {            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);            new_arrow = arrowFactory.GetArrow();            arrow.Add(new_arrow);            actionManager.shootArrowAction(new_arrow, ray.direction);        }    }    public void RecycleArrow() {        for(int i = 0; i < arrow.Count; i++) {            if(arrow[i].transform.position.y < -10 || arrow[i].transform.position.z > 15) {                arrowFactory.FreeArrow(arrow[i]);                arrow.Remove(arrow[i]);            }        }    }    public void Judge() {        if (leaveSeconds == 0 && scoreRecorder.getScore() < 100) {            StopAllCoroutines();            state = State.LOSE;        }        else if ((leaveSeconds > 0 && scoreRecorder.getScore() >= 100)) {            StopAllCoroutines();            state = State.WIN;        }    }    public void Pause() {        state = State.PAUSE;        StopAllCoroutines();        for (int i = 0; i < arrow.Count; i++) {            arrow [i].SetActive (false);        }    }    public void Resume() {        StartCoroutine(DoCountDown());          state = State.CONTINUE;        for (int i = 0; i < arrow.Count; i++) {            arrow[i].SetActive(true);        }    }    public void Restart() {        scoreRecorder.Reset();        Application.LoadLevel(Application.loadedLevelName);        Director.getInstance().currentSceneController.state = State.START;    }}

工厂模式

using System.Collections;using System.Collections.Generic;using UnityEngine;public class ArrowFactory : MonoBehaviour {    private List<GameObject> used = new List<GameObject>();    private List<GameObject> free = new List<GameObject>();    public GameObject GetArrow() {        GameObject a_arrow;        if (free.Count > 0) {            a_arrow = free[0];            free.Remove(free[0]);        } else {            a_arrow = GameObject.Instantiate(Resources.Load("prefabs/Arrow")) as GameObject;        }        a_arrow.SetActive(true);        used.Add(a_arrow);        return a_arrow;    }    public void FreeArrow(GameObject disk) {        for(int i = 0; i < used.Count; i++) {            if(used[i] == disk) {                disk.SetActive(false);                used.Remove(used[i]);                free.Add(disk);            }        }    }}

大概就这么多啦,还是得说一句。。这个框架实在是好用。