赞
踩
开发一个第一人称射箭游戏,应满足以下要求:
- 基础分(2分):有博客;
- 1-3分钟视频(2分):视频呈现游戏主要游玩过程;
- 地形(2分):使用地形组件,上面有草、树;
- 天空盒(2分):使用天空盒,天空可随玩家位置 或 时间变化 或 按特定按键切换天空盒;
- 固定靶(2分):有一个以上固定的靶标;
- 运动靶(2分):有一个以上运动靶标,运动轨迹,速度使用动画控制;
- 射击位(2分):地图上应标记若干射击位,仅在射击位附近可以拉弓射击,每个位置有 n 次机会;
- 驽弓动画(2分):支持蓄力半拉弓,然后 hold,择机 shoot;
- 游走(2分):玩家的驽弓可在地图上游走,不能碰上树和靶标等障碍;
- 碰撞与计分(2分):在射击位,射中靶标的相应分数,规则自定;
具体设计为:
-设置静止靶单倍区和运动靶双倍区两个区域可以射击,其他区域没有靶子无法射击得分。
-靶子分为白、黑、红自外向里为3、4、5分,集中运动靶分数则翻倍
-一共有10支箭矢,全部用完则游戏结束
-长按空格可以为弓弩蓄力,再次按下空格则发射
视频展示:
负责游戏一开始的初始化,和游戏进行中将信息传递到不同的脚本中,如为视图View传递分数、当前位置等信息。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- /* 游戏状态,0为准备进行,1为正在进行游戏,2为结束 */
- enum GameState {
- Ready = 0, Playing = 1, GameOver = 2
- };
-
- public class MainController : MonoBehaviour
- { private View view; // 游戏视图
- private CrossController crossController;//十字弩控制器
- private int gameState;//游戏状态
- public GUISkin gameSkin; //按键皮肤
- public Material[] skyboxMaterials;//存储天空盒数组
- private int index;//天空盒数组下标
- private int lessnum;//剩余箭矢数
- public GameObject cross; //十字弩
- // Start is called before the first frame update
- void Start()//在start中进行初始化
- {Director.GetInstance().mainController = this;
- crossController= gameObject.AddComponent<CrossController>();
- gameState = (int)GameState.Ready;
- view = gameObject.AddComponent<View>();
- view.gameSkin = gameSkin;
- // 隐藏十字弩
- cross.SetActive(false);
- //携程切换天空盒
- index=-1;
- StartCoroutine(ChangeSkybox());
- }
-
- public void SetGameState(int state) {//设置游戏状态
- gameState = state;
- }
-
- public void Restart() {//重启游戏函数
- view.Init();
- lessnum=10;
- roundController.Reset();
- CrossC crossComponent = cross.GetComponent<CrossC>();
- crossComponent.Init();
- }
-
- public void ShowPage() {//控制视图view的页面
- switch(gameState) {
- case 0:
- view.ShowHomePage();
- break;
- case 1:
- view.ShowGamePage();
- break;
- case 2:
- view.ShowRestart();
- break;
- }
- }
- public void SetViewScore(int score) {//将十字弩的计分传给视图
- view.SetScore(score);
- }
-
- public void SetViewNum(int num) {//将十字弩的剩余箭矢数传给视图
- lessnum=num;
- view.SetNum(num);
- }
-
- public void SetViewX(float x){//将十字弩的位置传给视图
- view.GetX(x);
- }
-
- public void Update(){//实时传递游戏状态给视图
- CrossC crossComponent = cross.GetComponent<CrossC>();
- SetViewScore(crossComponent.getScore());
- SetViewNum(crossComponent.getNum());
- SetViewX(crossComponent.getX());
- if(lessnum==0) SetGameState(2);//剩余箭为0时结束游戏
- }
-
- IEnumerator ChangeSkybox()
- {
- while (true)
- {
- // 循环选择一个天空盒子材质
- index = (index+1)%3;
- RenderSettings.skybox = skyboxMaterials[index];
-
- // 等待一段时间后再切换天空盒子
- yield return new WaitForSeconds(20);
- }
- }
-
- }
负责控制游戏的页面提示,向玩家展示游戏的进行状态
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- public class View : MonoBehaviour
- {
- private MainController mainController;
- private int score;//当前得分
- private int arrownum;//当前剩余箭矢数
- private float x;//当前位置
- public GUISkin gameSkin;
-
- // Start is called before the first frame update
- void Start()//初始化
- { score = 0;
- mainController = Director.GetInstance().mainController;
- }
-
- // 分别获取分数、剩余箭矢数和位置的函数
- public void SetScore(int score) {
- this.score = this.score+score;
- }
-
- public void SetNum(int num){
- arrownum=num;
- }
-
- public void GetX(float a){
- x=a;
- }
-
- public void Init(){//开始游戏的初始化
- score=0;
- arrownum=10;
- }
- public void ShowHomePage() {
- AddStartButton();
- }
-
- public void ShowGamePage(){
- AddGameLabel();
- }
-
- public void ShowRestart() {
- AddRestartlabel();
- }
- public void AddStartButton(){//GameState=0时,展示初始界面
- GUI.skin = gameSkin;
- if(GUI.Button(new Rect(340,200,160,80),"点击开始")){
- mainController.Restart();
- mainController.SetGameState((int)GameState.Playing);//按下开始按钮则进入游戏状态
- }
- }
-
- public void AddGameLabel() {//GameState=1时,展示游戏界面
- GUIStyle labelStyle = new GUIStyle();
- labelStyle.normal.textColor = Color.black;
- labelStyle.fontSize = 30;
- mainController.cross.SetActive(true);
- mainController.cross.transform.rotation=Quaternion.Euler(-10f, 0f, 0f);
- GUI.Label(new Rect(570, 10, 100, 50), "得分: " + score, labelStyle);//展示得分、剩余箭矢数及提示当前区域
- GUI.Label(new Rect(570, 45, 100, 50), "剩余箭数: " + arrownum, labelStyle);
- if(x<-9.96||(x>10.05&&x<19.00)||x>40.00) GUI.Label(new Rect(10,10,100,50),"当前区域:无箭靶",labelStyle);
- else if(x>=-9.96&&x<10.05) GUI.Label(new Rect(10,10,100,50),"当前区域:静止靶单倍区",labelStyle);
- else GUI.Label(new Rect(10,10,100,50),"当前区域:移动靶双倍区",labelStyle);
- }
-
- public void AddRestartlabel(){//GameState=2时,展示结束界面
- GUI.skin = gameSkin;
- GUIStyle labelStyle = new GUIStyle();
- labelStyle.normal.textColor = Color.red;
- labelStyle.fontSize = 30;
- GUI.Label(new Rect(340,100,100,50),"最终得分:"+score,labelStyle);//展示最终得分
- if(GUI.Button(new Rect(340,200,160,80),"再来一次")){
- mainController.Restart();
- mainController.SetGameState((int)GameState.Playing);//按下再来一次按钮则再次进入游戏状态
- }
-
- }
-
- void OnGUI() {
- mainController.ShowPage();
- }
- }
挂载在十字弩物体上,控制十字弩的射击、蓄力等动画呈现,以及控制十字弩可以上下左右移动。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- public class CrossC : MonoBehaviour
- {
- private Animator ani;
- public float horizontalinput;//水平参数
- public float Verticalinput;//垂直参数
- float speed=1.6f;//速度参数
- public float power;//蓄力系数
- public Arrow _arrow;//箭矢对象
- private Arrow arrow;
- private bool flag=false;
- private int num;
- private bool hold;//记录按下空格应该是拉弓蓄力还是发射
- private bool wait;
- public Text hintText;
- public Text powerText;
-
- void Start()//初始化
- { ani=GetComponent<Animator>();
- hintText.gameObject.SetActive(false);
- powerText.gameObject.SetActive(false);
- num=10;
- hold=true; wait=true;
- }
-
- public void Init(){
- num=10;
- }
-
- // Update is called once per frame
- void Update()
- { horizontalinput = Input.GetAxis("Horizontal");
- //AD方向控制
- Verticalinput = Input.GetAxis("Vertical");
-
- if (horizontalinput!=0&&Verticalinput!=0)
- {
- horizontalinput = horizontalinput * 1.4f;
- Verticalinput = Verticalinput * 1.4f;
- }
- //WS方向控制
-
- this.transform.Translate(Vector3.right * horizontalinput * Time.deltaTime * speed);
- //控制该物体向侧方移动
- this.transform.Translate(Vector3.up* Verticalinput * Time.deltaTime * speed);
- if(iflegalarea()) {ShowHint("您已超出射击区域,该区域无射击靶"); flag=true;}
- else if(flag&&!iflegalarea()) {HideHint(); flag=false;}
- if(power!=0f) {
- int ppower=(int)(power*100);
- powerText.text="蓄力"+ppower+"%";
- powerText.gameObject.SetActive(true);
- }
- else{
- powerText.gameObject.SetActive(false);
- }
- //控制该物体向上下移动
- if(Input.GetKey(KeyCode.Space))//按下空格
- { if(hold){//蓄力
- Transform childTransform = transform.Find("箭");
- childTransform.gameObject.SetActive(true);
- ani.SetBool("pull",true);
- ani.SetBool("shoot",false);
- if (power < 1)
- {
- power += Time.deltaTime * 0.5f;
- }
- else
- {
- power = 1;
- }
- ani.SetFloat("pullpower",power);
- wait=true;
- }
- else{//发射
- if(wait){ani.SetBool("shoot",true);
- ani.SetBool("pull",false);
- ani.SetBool("hold",false);
- initArrow();
- RunArrow();
- wait=false;
- Transform childTransform = transform.Find("箭");
- childTransform.gameObject.SetActive(false);
- power=0f;
- ani.SetFloat("pullpower",power);
- Invoke("SetHoldTrue", 1f);}
- }
-
- }
-
- if (Input.GetKeyUp(KeyCode.Space)){//抬起空格,保持
- ani.SetBool("pull",false);
- hold=false;//预备射击}
- }
-
- public void initArrow()//创建箭矢对象
- {
- Vector3 np=this.transform.position;
- arrow = Instantiate(_arrow,np,Quaternion.identity);
- arrow.gameObject.SetActive(true);
-
- }
-
- public void RunArrow()//发射箭矢对象
- {
- if(arrow != null)
- {
- Rigidbody rb = arrow.GetComponent<Rigidbody>();
- if (rb)
- {
- rb.drag = 0.5f;
- Vector3 shootingDirection = this.transform.forward;
- rb.AddForce(shootingDirection * (power*20f+5), ForceMode.Impulse);
- num--;
- }
- }
- }
-
- //向其他脚本传递数据
- public int getScore()//若箭矢命中,传回分数并提示
- {
- if(arrow != null && arrow.attacked&&!arrow.isRecord){
- arrow.isRecord=true;
- if(arrow.score==5) ShowHint("正中红心!",0);
- else ShowHint("命中!",0);
- float x=this.transform.position.x;
- if(x>=19.00&&x<=40.00) return arrow.score*2;
- else return arrow.score;
- }
- return 0;
- }
- public int getNum(){
- return num;
- }
-
- public float getX(){
- return this.transform.position.x;
- }
-
- public void ShowHint(string message,int state=1)//提示标签控制
- {
- // 显示提示文字
- hintText.text = message;
- hintText.gameObject.SetActive(true);
-
- // 延迟几秒后隐藏提示文字
- if(state==0) Invoke("HideHint", 1f);
- }
-
- void HideHint()
- {
- hintText.gameObject.SetActive(false);
- }
-
- void SetHoldTrue(){
- hold=true;
- }
-
- private bool iflegalarea(){//判断是否在射击区域,不在则提示
- float x=this.transform.position.x;
- return (x<-9.96||(x>10.05&&x<19.00)||x>40.00);
- }
- }
挂载在箭矢物体上,主要负责响应碰撞事件并传回击中的分数:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- public class CrossC : MonoBehaviour
- {
- private Animator ani;
- public float horizontalinput;//水平参数
- public float Verticalinput;//垂直参数
- float speed=1.6f;//速度参数
- public float power;//蓄力系数
- public Arrow _arrow;//箭矢对象
- private Arrow arrow;
- private bool flag=false;
- private int num;
- private bool hold;//记录按下空格应该是拉弓蓄力还是发射
- private bool wait;
- public Text hintText;
- public Text powerText;
-
- void Start()//初始化
- { ani=GetComponent<Animator>();
- hintText.gameObject.SetActive(false);
- powerText.gameObject.SetActive(false);
- num=10;
- hold=true; wait=true;
- }
-
- public void Init(){
- num=10;
- }
-
- // Update is called once per frame
- void Update()
- { horizontalinput = Input.GetAxis("Horizontal");
- //AD方向控制
- Verticalinput = Input.GetAxis("Vertical");
-
- if (horizontalinput!=0&&Verticalinput!=0)
- {
- horizontalinput = horizontalinput * 1.4f;
- Verticalinput = Verticalinput * 1.4f;
- }
- //WS方向控制
-
- this.transform.Translate(Vector3.right * horizontalinput * Time.deltaTime * speed);
- //控制该物体向侧方移动
- this.transform.Translate(Vector3.up* Verticalinput * Time.deltaTime * speed);
- if(iflegalarea()) {ShowHint("您已超出射击区域,该区域无射击靶"); flag=true;}
- else if(flag&&!iflegalarea()) {HideHint(); flag=false;}
- if(power!=0f) {
- int ppower=(int)(power*100);
- powerText.text="蓄力"+ppower+"%";
- powerText.gameObject.SetActive(true);
- }
- else{
- powerText.gameObject.SetActive(false);
- }
- //控制该物体向上下移动
- if(Input.GetKey(KeyCode.Space))//按下空格
- { if(hold){//蓄力
- Transform childTransform = transform.Find("箭");
- childTransform.gameObject.SetActive(true);
- ani.SetBool("pull",true);
- ani.SetBool("shoot",false);
- if (power < 1)
- {
- power += Time.deltaTime * 0.5f;
- }
- else
- {
- power = 1;
- }
- ani.SetFloat("pullpower",power);
- wait=true;
- }
- else{//发射
- if(wait){ani.SetBool("shoot",true);
- ani.SetBool("pull",false);
- ani.SetBool("hold",false);
- initArrow();
- RunArrow();
- wait=false;
- Transform childTransform = transform.Find("箭");
- childTransform.gameObject.SetActive(false);
- power=0f;
- ani.SetFloat("pullpower",power);
- Invoke("SetHoldTrue", 1f);}
- }
-
- }
-
- if (Input.GetKeyUp(KeyCode.Space)){//抬起空格,保持
- ani.SetBool("pull",false);
- hold=false;//预备射击}
- }
-
- public void initArrow()//创建箭矢对象
- {
- Vector3 np=this.transform.position;
- arrow = Instantiate(_arrow,np,Quaternion.identity);
- arrow.gameObject.SetActive(true);
-
- }
-
- public void RunArrow()//发射箭矢对象
- {
- if(arrow != null)
- {
- Rigidbody rb = arrow.GetComponent<Rigidbody>();
- if (rb)
- {
- rb.drag = 0.5f;
- Vector3 shootingDirection = this.transform.forward;
- rb.AddForce(shootingDirection * (power*20f+5), ForceMode.Impulse);
- num--;
- }
- }
- }
-
- //向其他脚本传递数据
- public int getScore()//若箭矢命中,传回分数并提示
- {
- if(arrow != null && arrow.attacked&&!arrow.isRecord){
- arrow.isRecord=true;
- if(arrow.score==5) ShowHint("正中红心!",0);
- else ShowHint("命中!",0);
- float x=this.transform.position.x;
- if(x>=19.00&&x<=40.00) return arrow.score*2;
- else return arrow.score;
- }
- return 0;
- }
- public int getNum(){
- return num;
- }
-
- public float getX(){
- return this.transform.position.x;
- }
-
- public void ShowHint(string message,int state=1)//提示标签控制
- {
- // 显示提示文字
- hintText.text = message;
- hintText.gameObject.SetActive(true);
-
- // 延迟几秒后隐藏提示文字
- if(state==0) Invoke("HideHint", 1f);
- }
-
- void HideHint()
- {
- hintText.gameObject.SetActive(false);
- }
-
- void SetHoldTrue(){
- hold=true;
- }
-
- private bool iflegalarea(){//判断是否在射击区域,不在则提示
- float x=this.transform.position.x;
- return (x<-9.96||(x>10.05&&x<19.00)||x>40.00);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。