之前因为实训忙成狗没有时间写博客,趁着清明有点小空来写下博客
有点懒,就直接贴代码了,这是第一次用代码块来贴代码。后面有效果图
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);
}
}
}