3D游戏编程与设计 Week6

之前因为实训忙成狗没有时间写博客,趁着清明有点小空来写下博客

有点懒,就直接贴代码了,这是第一次用代码块来贴代码。后面有效果图


SceneContoller.cs

using System;  
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
  
namespace Com.Shoot {  
    public interface IUserAction { //设置接口 IUserAction
        void createArrow();  
        void arrowFollowMouse(Vector3 mousePos);  
        void shootTheArrow(Vector3 mousePos);  
    }  
  
    public interface IGameStatusOp {  //设置接口 IGameStatusOp
        bool haveArrowOnPort();  
        void addScore(int point);  
        void showTipsText(int point);  
        void modifyWind();  
        int getWindDir();  
        int getWindStrength();  
    }  
  
    public class SceneController : System.Object, IUserAction, IGameStatusOp {  
        private static SceneController instance;  
        private GameModel myGameModel;  
        private GameStatus myGameStatus;  
  
        public static SceneController getInstance() {  //创建单实例
            if (instance == null)  
                instance = new SceneController();  
            return instance;  
        }  
          
        internal void setGameModel(GameModel _myGameModel) {  //两个set方法
            if (myGameModel == null) {  
                myGameModel = _myGameModel;  
            }  
        }  
  
        internal void setGameStatus(GameStatus _myGameStatus) {  
            if (myGameStatus == null) {  
                myGameStatus = _myGameStatus;  
            }  
        }  
  
  
        //实现IUserAction接口 
        public void createArrow() {  //造箭-_-
            myGameModel.createArrow();  
        }  
  
        public void arrowFollowMouse(Vector3 mousePos) { //让箭跟着鼠标动 
            myGameModel.arrowFollowMouse(mousePos);  
        }  
  
        public void shootTheArrow(Vector3 mousePos) {  //射!
            myGameModel.shootTheArrow(mousePos);  
        }  
  
  
        // 实现IGameStatusOp接口 
        public bool haveArrowOnPort() {  
            return myGameModel.haveArrowOnPort();  
        }  
  
        public void addScore(int point) {  
            myGameStatus.addScore(point);  
        }  
  
        public void showTipsText(int point) {  
            myGameStatus.showTipsText(point);  
        }  
  
        public void modifyWind() {  
            myGameStatus.modifyWind();  
        }  
  
        public int getWindDir() {  
            return myGameStatus.getWindDir();  
        }  
  
        public int getWindStrength() {  //风强
            return myGameStatus.getWindStrength();  
        }  
    }  
}  

GameModel.cs

using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using Com.Shoot;  
  
public class GameModel : MonoBehaviour {  
    public GameObject TargetItem, ArrowItem;  
  
    private GameObject holdingArrow = null, target;  
    private const int ARROW_SPEED = 30;  
  
    private SceneController scene;  
  
    void Awake() {  
        ArrowFactory.getInstance().initItem(ArrowItem);  
    }  
  
    void Start () {  
        scene = SceneController.getInstance();  
        scene.setGameModel(this);  
  
        target = Instantiate(TargetItem);  
    }  
      
    void Update () {  
        ArrowFactory.getInstance().detectReuseArrows();  
  
    }  
  
    //是否握住箭  
    public bool haveArrowOnPort() {  
        return (holdingArrow != null);  
    }  
  
    //造箭  
    public void createArrow() {  
        if (holdingArrow == null) {  
            holdingArrow = ArrowFactory.getInstance().getArrow();  
        }  
    }  
  
    //使箭跟着鼠标移动  
    public void arrowFollowMouse(Vector3 mousePos) {  
        holdingArrow.transform.LookAt(mousePos * 30);  
    }  
  
    //射箭  
    public void shootTheArrow(Vector3 mousePos) {  
        holdingArrow.transform.LookAt(mousePos * 30);  
        holdingArrow.GetComponent<Rigidbody>().isKinematic = false;  
  
          
        addWindForce();  
  
        holdingArrow.GetComponent<Rigidbody>().AddForce(mousePos * 30, ForceMode.Impulse);  
        holdingArrow = null;  
    }  
	
	//加风力
    void addWindForce() {  
        int windDir = scene.getWindDir();  //由箭的方向来决定风力
        int windStrength = scene.getWindStrength();  
  
        Vector3 windForce;  
        switch (windDir) {  
            case 0:  
                windForce = new Vector3(0, 1, 0);  
                break;  
            case 1:  
                windForce = new Vector3(1, 1, 0);  
                break;  
            case 2:  
                windForce = new Vector3(1, 0, 0);  
                break;  
            case 3:  
                windForce = new Vector3(1, -1, 0);  
                break;  
            case 4:  
                windForce = new Vector3(0, -1, 0);  
                break;  
            case 5:  
                windForce = new Vector3(-1, -1, 0);  
                break;  
            case 6:  
                windForce = new Vector3(-1, 0, 0);  
                break;  
            case 7:  
                windForce = new Vector3(-1, 1, 0);  
                break;  
            default:  
                windForce = Vector3.zero;  
                break;  
        }  
        holdingArrow.GetComponent<Rigidbody>().AddForce(windForce * windStrength * 20, ForceMode.Force);  
    }  
} 

ArrowFactory.cs

using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
  
namespace Com.Shoot {  
    public class ArrowFactory : System.Object {  
        private static ArrowFactory instance;  
        private List<GameObject> usingArrowList = new List<GameObject>();  
        private List<GameObject> unusedArrowList = new List<GameObject>();  
  
        private GameObject ArrowItem;  
        private Vector3 ARROW_INIT_POS = new Vector3(0, 0, -8);  
  
        public static ArrowFactory getInstance() {  
            if (instance == null)  
                instance = new ArrowFactory();  
            return instance;  
        }  
  
        public void initItem(GameObject _ArrowItem) {  
            ArrowItem = _ArrowItem;  
        }  
  
        //提供箭  
        public GameObject getArrow() {  
            if (unusedArrowList.Count == 0) {    //没有箭  
                GameObject newArrow = Camera.Instantiate(ArrowItem);  
                usingArrowList.Add(newArrow);  
                return newArrow;  
            }  
            else {                      //有箭  
                GameObject oldArrow = unusedArrowList[0];  
                unusedArrowList.RemoveAt(0);  
                oldArrow.SetActive(true);  
                usingArrowList.Add(oldArrow);  
                return oldArrow;  
            }  
        }  
  
        //检测箭落地,回收。此方法由GameModel的update()方法触发  
        public void detectReuseArrows() {  
            for (int i = 0; i < usingArrowList.Count; i++) {  
                if (usingArrowList[i].transform.position.y <= -8) {  
                    usingArrowList[i].GetComponent<Rigidbody>().isKinematic = true;  
                    usingArrowList[i].SetActive(false);  
                    usingArrowList[i].transform.position = ARROW_INIT_POS;  
                    unusedArrowList.Add(usingArrowList[i]);  
                    usingArrowList.Remove(usingArrowList[i]);  
                    i--;  
  
                    SceneController.getInstance().modifyWind();  
                }  
            }  
        }  
    }  
}  

GameStatus.cs

using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using Com.Shoot;  
using UnityEngine.UI;  
  
public class GameStatus : MonoBehaviour {  
    public GameObject canvasItem, scoreTextItem, TipsTextItem, windTextItem;  
  
    private int score = 0;  
    private int windDir = 0;  
    private int windStrength = 0;  
    private string[] windTextSet;  
  
    private const float TIPS_TEXT_SHOW_TIME = 0.6f;  
  
    private GameObject canvas, scoreText, TipsText, windText;  
    private SceneController scene;  
  
    void Start () {  
        scene = SceneController.getInstance();  
        scene.setGameStatus(this);  
  
        canvas = Instantiate(canvasItem);  
        scoreText = Instantiate(scoreTextItem, canvas.transform);  
        scoreText.transform.Translate(canvas.transform.position);  
        scoreText.GetComponent<Text>().text = "Score: " + score;  
  
        TipsText = Instantiate(TipsTextItem, canvas.transform);  
        TipsText.transform.Translate(canvas.transform.position);  
        TipsText.SetActive(false);  
  
        windTextSet = new string[8] { "↑", "↗", "→", "↘", "↓", "↙", "←", "↖" };  
        windText = Instantiate(windTextItem, canvas.transform);  
        windText.transform.Translate(canvas.transform.position);  //设置一个提示风力信息的部分
        modifyWind();  
    }  
      
    void Update () {  
          
    }  
  
    //得分 
    public void addScore(int point) {  
        score += point;  
        scoreText.GetComponent<Text>().text = "Score:  " + score;  
  
        modifyWind();  
    }  
  
    //环数  
    public void showTipsText(int point) {  
        TipsText.GetComponent<Text>().text = point + " points!";  
        TipsText.SetActive(true);  
        StartCoroutine(waitForSomeAndDisappearTipsText());  
    }  
     
    IEnumerator waitForSomeAndDisappearTipsText() {  
        yield return new WaitForSeconds(TIPS_TEXT_SHOW_TIME);  
  
        TipsText.SetActive(false);  
    }  
  
    //调整风向、强度  
    public void modifyWind() {  
        windDir = Random.Range(0, 8);  
        windStrength = Random.Range(0, 8);  
        windText.GetComponent<Text>().text = "Wind: " + windTextSet[windDir] + "  x" + windStrength;  
    }  
    public int getWindDir() {  
        return windDir;  
    }  
    public int getWindStrength() {  
        return windStrength;  
    }  
}  

UserInterface.cs

using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using Com.Shoot;  
  
public class UserInterface : MonoBehaviour {  
    private IUserAction action;  
    private IGameStatusOp gameStatusOp;  
  
    void Start () {  
        action = SceneController.getInstance() as IUserAction;  
        gameStatusOp = SceneController.getInstance() as IGameStatusOp;  
    }  
      
    void Update () {  
        detectMouseInput();  
        detectKeyInput();  
    }  
  
    void detectMouseInput() {  
        if (gameStatusOp.haveArrowOnPort()) {  
            if (Input.GetMouseButton(0)) {    //箭跟鼠标移动  
                Vector3 mousePos = Camera.main.ScreenPointToRay(Input.mousePosition).direction;  
                action.arrowFollowMouse(mousePos);  
            }  
  
            if (Input.GetMouseButtonUp(0)) {    //发射  
                Vector3 mousePos = Camera.main.ScreenPointToRay(Input.mousePosition).direction;  
                action.shootTheArrow(mousePos);  
            }  
        }  
    }  
  
    void detectKeyInput() {  
        if (Input.GetKeyDown(KeyCode.Space)) {    //按下空格键造箭  
            action.createArrow();  
        }  
    }  
}  



ArrowCollider.cs

using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using Com.Shoot;  
   
  
public class ArrowCollider : MonoBehaviour {  
    private IGameStatusOp gameStatusOp;  
  
    void Start () {  
        gameStatusOp = SceneController.getInstance() as IGameStatusOp;  
    }  
      
    void Update () {  
          
    }  
  
    void OnTriggerEnter(Collider c) {  
        if (c.gameObject.tag == "target") {  
            //Debug.Log(this.gameObject.name + ": " + c.gameObject.name);  
            gameObject.transform.parent.gameObject.GetComponent<Rigidbody>().isKinematic = true;  
            gameObject.SetActive(false);     
  
            int point = c.gameObject.name[c.gameObject.name.Length - 1] - '0';  //score!  
            gameStatusOp.showTipsText(point);  
            gameStatusOp.addScore(point * 10);  
  
        }  
    }  
}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值