3D游戏作业四:牧师与魔鬼动作分离版

1:3D游戏作业四:牧师与魔鬼动作分离版:

1:要求:

在原来设计的基础上添加一个裁判类,当游戏达到结束条件时,通知场景控制器游戏结束。

2:编程:

本次编程依然是使用MVC编程,只是添加了一个定义裁判类的Judger.cs文件。:
在这里插入图片描述

2.创建预制:

在Resources文件夹下创建预制:
在这里插入图片描述

3.代码:

3.1 以下的代码都在文件 controller.cs中的同一个命名空间controller下:
0:主要改动:Judger:

添加了一个Judger类,为了方便引用,定义在一个命名空间里。它主要用来分析当前河岸和船上的角色信息,如果某个河岸的魔鬼比牧师的数量多,就判定游戏结束:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using controller;

namespace judger_controller{
public class Judger : System.Object {
    private static Judger _instance;
         public static Judger getInstance() {
             if(_instance == null) _instance = new Judger();
             return _instance;
         }
         
                     
     public int check_game_over(Bank_controller start_bank,Bank_controller dest_bank, Boat_controller boat) {
       int start_priest = 0;
       int start_devil = 0;
       int dest_priest = 0;
       int dest_devil  = 0;
       
       int[] start = start_bank.count_chara();
       int[] dest = dest_bank.count_chara();
       int[] boat_count = boat.count_chara();

       if(dest[0] +dest[1] == 6)  return 2;   //赢


       if(boat.get_status() == 0){
           start_priest = start[0] + boat_count[0];
           start_devil =  start[1] + boat_count[1];
           dest_priest = dest[0];
           dest_devil =  dest[1];
       }
       else{
           start_priest = start[0] ;
           start_devil =  start[1] ;
           dest_priest = dest[0]+ boat_count[0];
           dest_devil =  dest[1]+ boat_count[1];
       }
       Debug.Log("start:"+start[0]+start[1]);
       Debug.Log("dest:" +dest[0]+dest[1]);
       Debug.Log("boat:"+ boat_count[0]+boat_count[1]+boat_count[2]);
       Debug.Log("start_p"+start_priest+start_devil+dest_priest+dest_devil);

       if((start_priest < start_devil && start_priest !=0) || (dest_priest < dest_devil && dest_priest != 0))
         return 1;   //游戏结束

       return 0;  //游戏继续

    }
 }
}
1.Director:

我们需要一名导演来获取游戏场景;以及控制场景的切换,管理游戏状态:

    public class Director : System.Object{
        private static Director _instance;
        public  ISceneController currentSceneController {get ;set ;}

        public static Director getInstance() {
		    if (_instance == null) {
				_instance = new Director ();
			}
			return _instance;
		}
    }
2.接口:
	public interface ISceneController {
		void load_resource ();
	}

	public interface IUserAction {
		void S_Boating();
		void Click_char(chara_controller characterCtrl);
		void Restart();
	}
3.牧师以及魔鬼游戏对象的controller,以及它们的运动组件:

//charact_move 
//牧师和魔鬼的运动模块:
public class charact_move : MonoBehaviour{

    int char_moveable;  //运动使能,为1时才运动
    int status;    //0 ->移动到起始点,1->移动到船上,2-》移动到终点
    Vector3  free;  //要移动到的目标位置
    void Update() {
        if(char_moveable == 1){

        if(status == 1){

            if(transform.position.x > 0){  //从出发点移动到船上
                if(transform.position.x > 7)
                  transform.position = Vector3.MoveTowards (transform.position, new Vector3(7,3,0), 2 * Time.deltaTime);
                else
                {
                     transform.position = Vector3.MoveTowards (transform.position, free , 2 * Time.deltaTime);
                }

                if(transform.position == free){
                    char_moveable = 0;
                    
                }
            }

            else{  //从终点移动到船上
                if(transform.position.x < -7)
                  transform.position = Vector3.MoveTowards (transform.position, new Vector3(-7,3,0), 2 * Time.deltaTime);
                else
                {
                     transform.position = Vector3.MoveTowards (transform.position, free , 2 * Time.deltaTime);
                }
                if(transform.position == free){
                    char_moveable = 0;
                    
                }
            }
          }
          else{
            if(transform.position.x > 0){  //移动到起始岸边
                if(transform.position.x < 7)
                  transform.position = Vector3.MoveTowards (transform.position, new Vector3(7,3,0), 2 * Time.deltaTime);
                else
                {
                     transform.position = Vector3.MoveTowards (transform.position, free , 2 * Time.deltaTime);
                }

                if(transform.position == free){
                    char_moveable = 0;
                    
                }
            }

            else{   //移动到终点岸边
                if(transform.position.x > -7)
                  transform.position = Vector3.MoveTowards (transform.position, new Vector3(-7,3,0), 2 * Time.deltaTime);
                else
                {
                     transform.position = Vector3.MoveTowards (transform.position, free , 2 * Time.deltaTime);
                }
                if(transform.position == free){
                    char_moveable = 0;
                    
                }
            }
          }
        }
    }

    public void set_char_mov(int istatus,Vector3 t_free)   
    {
        char_moveable = 1 ;
        status = istatus;
        free = t_free ;
    }


    public void init()
    {
        char_moveable = 0;
    }
}




chara_controller
    public class chara_controller {
        GameObject character;
        int char_type;  //0-priest;1-devil
        int status; //0- start;1->on boat; 2->on dest
        int char_moveable;  //运动使能
        int rank ; //排位
        Vector3 position; //位置
        Vector3 free;  //移动的目标地址
		readonly Click_GUI click_GUI;
        Bank_controller bank_con;
        Boat_controller boat_con ;
        charact_move chara_movscr;  //运动模块
        public chara_controller(int irank,int itype)
        {
          if (itype == 0) {
                position = new Vector3(7+irank,2,0);
                rank = irank;
                status = 0;
                char_type = 0;
				character = Object.Instantiate (Resources.Load ("Perfabs/Priest", typeof(GameObject)), position, Quaternion.identity, null) as GameObject;
			} else {
                position = new Vector3(7+irank,2,0);
                rank = irank;
                status = 0;
                char_type = 1;
				character = Object.Instantiate (Resources.Load ("Perfabs/Devil", typeof(GameObject)), position, Quaternion.identity, null) as GameObject;
			}
            chara_movscr = character.AddComponent (typeof(charact_move)) as charact_move;
			click_GUI = character.AddComponent (typeof(Click_GUI)) as Click_GUI;
			click_GUI.setController (this);
        }
 //角色运动控制函数
        public void charac_action(int start_end,Vector3 ifree)
        {
            if(status == 0 || status == 2 )
            {
                chara_movscr.set_char_mov(start_end,ifree);
                status = 1;
            }
            else {
                chara_movscr.set_char_mov(start_end,ifree);
                status = start_end;
            }
        }





        public void set_position(Vector3 pos)
        {
            character.transform.position = pos;
            position = pos;
        }

		public void setName(string name) {
			character.name = name;
		}
        public Vector3 get_position()
        {
            return position;
        }

        public int get_type(){
            return char_type;
        }

        public int get_rank(){
            return rank ;
        }

        public int get_status(){
            return status;
        }
         
 
        public void set_free(Vector3 free_posi){
            free = free_posi;
        }


       public void get_on_boat(Boat_controller boat_c)
       {
           bank_con = null;
           boat_con = boat_c;
           character.transform.parent = boat_c.get_Object().transform;
       }

       public void get_on_bank(Bank_controller ban_c)
       {
           bank_con = ban_c;
           character.transform.parent = null;
           boat_con = null;
       }
      
      public Bank_controller get_bank(){
          return bank_con;
      }

      public  void init() {  //初始化
                position = new Vector3(7+rank,2,0);
                character.transform.position = position ;
                status = 0;
			    bank_con = (Director.getInstance ().currentSceneController as scen_controller).start_bank;
			    get_on_bank (bank_con);
                chara_movscr.init();
        }

    }
4.boat对象的控制函数和运动模块:

public class boat_move : MonoBehaviour{    //船的运动模块;

    int status;  //0-> 在起始位置  1-> 在终点位置
    int boat_movable;   //运动使能

    Vector3 start_pos = new Vector3(5.2F,1,0);  //船的起始位置
    Vector3 desti_pos = new Vector3(-5.2F,1,0); //船的的终点位置
    void Update() {

        if(boat_movable == 1)
           {
                if(status == 0 && boat_movable == 1)  //从起点移动到终点
                {
                    transform.position = Vector3.MoveTowards (transform.position,desti_pos,5*Time.deltaTime);
                    if(transform.position == desti_pos)
                    {
                        status = 1;//
                        boat_movable = 0;
                    }
                        
                }
                else if(status == 1 && boat_movable == 1){  //从终点移动到起始点
                    transform.position = Vector3.MoveTowards (transform.position,start_pos,5*Time.deltaTime);
                    if(transform.position == desti_pos)
                    {
                        status = 0;//
                        boat_movable = 0;
                    }
                }
           }
    }


    public void set_boat_action(int stat,int moveable) //设置状态和运动时能
    {
        status =stat;
         boat_movable  = moveable; 
    }
    public void init()  //初始化
    {
        status = 0;
        boat_movable = 0;
    }
}


public class Boat_controller{
    GameObject boat;
    Vector3 start_pos = new Vector3(5.2F,1,0);
    Vector3 desti_pos = new Vector3(-5.2F,1,0);
    boat_move  boat_moscri;
    int status ;  //0->at_start,1->at_dest; 2->boating

    int boat_movable;//0->不移动  1-->移动
    chara_controller [] passenger = new chara_controller [2];  //船上的乘客

    public Boat_controller() {
        status = 0;
        boat_movable = 0;
        boat = Object.Instantiate(Resources.Load ("Perfabs/Boat",typeof(GameObject)),start_pos,Quaternion.identity,null) as GameObject;
        boat.name = "boat";
        boat.AddComponent(typeof(Click_GUI));
        boat_moscri = boat.AddComponent (typeof(boat_move)) as boat_move;
    }
    

public void boating()
{
    if(status == 0)
    {
        boat_moscri.set_boat_action(0,1);
        status = 1;
    }
    else if(status == 1)
    {
        boat_moscri.set_boat_action(1,1);
        status = 0;       
    }
}
    public int get_free() {//获取船上的空闲位置
        if(passenger[0] == null)  return 0;
        if(passenger[1] == null)  return 1;
        return -1;
    }


    public void get_on_boat(chara_controller chara_c) { //将角色加入船的乘客队列
       int free_i = get_free ();
       passenger [free_i] = chara_c;
    }


    public chara_controller get_off_boat(int rank_i) {//将角色从队列中除去;
        for(int i = 0; i < 2; ++i){
           if(passenger[i]!= null && passenger[i].get_rank() == rank_i) {
            chara_controller chara_c = passenger [i];
            passenger [i] = null;
            return chara_c ;
        }
      }   
      return null;       
    }

    public GameObject get_Object() {
        return boat;
    }

     public int get_status() {
         return status ;
     }
     public void set_boat_move(int t)
     {
          boat_movable = t;
     }
    public int [] count_chara() {  //统计乘客的数量和类型
        int [] count = {0,0,0};
        for(int i = 0; i< 2; i++)
        {
            if(passenger[i] == null)
              continue;
              else if(passenger[i].get_type() == 0)
              count[0] ++;
               else{
                   count[1] ++;
               }
        }
        count[2] = count[0] +count[1];
        return count;
    }

    public void init() {
        if(status == 1)
          {
              boating();
          }

        passenger = new chara_controller[2];
    }


  }
5.河岸的控制函数:
    public class Bank_controller{
        GameObject bank;
        Vector3 position;
        int type ; //1->start  -1->destination

        chara_controller [] characters ;

        public  Bank_controller(int itype)
        {
            position = new Vector3(10*itype,1,0);
            bank = Object.Instantiate (Resources.Load("Perfabs/bank",typeof(GameObject)),position ,Quaternion.identity,null) as GameObject;
            type = itype;
            characters = new chara_controller [6];
        }
       
        public void get_on_bank(chara_controller chara_c) {
           int irank = chara_c.get_rank();
           characters[irank] = chara_c ;
        }
        public chara_controller get_off_bank(int irank){
            chara_controller ichara = characters[irank];
            characters[irank]  = null;
            return ichara ;
        }


        public int get_type() {
            return type;
        }

        public int [] count_chara() {
            int [] count = { 0 , 0};
            for(int i = 0; i< 6; ++i)
            {
                if(characters[i] == null)
                  continue ;
                if(characters[i].get_type() == 0)
                  count[0] ++;
                else if(characters[i].get_type() == 1)
                   count[1] ++;
            }
            return count ;
        }

        public void init() {
            characters = new chara_controller[6];
        }
    }

3.2 User_GUI负责处理玩家动作;在游戏结束时点击按键重新游戏:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using controller;

public class User_GUI : MonoBehaviour {
	private IUserAction action;
	public int status = 0;
	GUIStyle style;
	GUIStyle buttonStyle;


    void Start() {//
    	action = Director.getInstance ().currentSceneController as IUserAction;
        style = new GUIStyle();
		style.fontSize = 40;
        style.normal.textColor = new Color(100, 155, 255);
		style.alignment = TextAnchor.MiddleCenter;

		buttonStyle = new GUIStyle("button");
		buttonStyle.fontSize = 30;
		buttonStyle.normal.textColor = new Color(100, 155, 255);


    }
	void OnGUI() {
		if (status == 1) {
			GUI.Label(new Rect(Screen.width/2-50, Screen.height/2-85, 100, 50), "Gameover!", style);
			if (GUI.Button(new Rect(Screen.width/2-70, Screen.height/2, 140, 70), "Restart", buttonStyle)) {
				status = 0;
				action.Restart ();
			}
		} else if(status == 2) {
			GUI.Label(new Rect(Screen.width/2-50, Screen.height/2-85, 100, 50), "You win!", style);
			if (GUI.Button(new Rect(Screen.width/2-70, Screen.height/2, 140, 70), "Restart", buttonStyle)) {
				status = 0;
				action.Restart ();
			}
		}
	}
}
3.3scen_controller

场记:创建初始化游戏对象,切换各游戏对象以及游戏的状态,负责管理各游戏对象的交换动作。在这个版本中,将游戏状态判断的部分转移到了Judger类中,通过调用Judger判断游戏是否结束:

using System.Collections.Generic;
using UnityEngine;
using controller;
using judger_controller;
public class scen_controller : MonoBehaviour, ISceneController, IUserAction {

    User_GUI user_GUI;
    public Bank_controller start_bank;
    public Bank_controller dest_bank;
    public Boat_controller boat;
    public chara_controller [] characters ;
    public Judger judger;  
    void Awake() {
        Director director = Director.getInstance ();
        director.currentSceneController = this;
        user_GUI = gameObject.AddComponent <User_GUI>() as User_GUI;
		characters = new chara_controller[6];
        load_resource();
    }
   
    public void load_resource() {

        start_bank = new Bank_controller(1) ;
        dest_bank = new Bank_controller (-1);
        GameObject water = Instantiate (Resources.Load ("Perfabs/Water", typeof(GameObject)), new Vector3(0,0.5F,0), Quaternion.identity, null) as GameObject;
        boat = new Boat_controller ();
        judger =  Judger.getInstance();
        for(int i = 0; i < 6; ++i){
            if(i < 3)
            {
                chara_controller chara_t = new chara_controller (i,0);
                chara_t.setName("priest" + i);
                chara_t.get_on_bank(start_bank);
                start_bank.get_on_bank(chara_t);
                characters[i] = chara_t;
            }
            else{
                chara_controller chara_t = new chara_controller (i,1);
                int t = i - 3;
                chara_t.setName("devil" +t);
                chara_t.get_on_bank(start_bank);
                start_bank.get_on_bank(chara_t);
                characters[i] = chara_t;
            }
        }

    }



	public void S_Boating() {
		int [] count_i = boat.count_chara();
        if(count_i[2] == 0)
        {
            Debug.Log("boat_empty");
	       	return;
        }

		boat.boating();
        Debug.Log("set_boat");
		user_GUI.status = judger.check_game_over (start_bank, dest_bank,boat);/
	}


    public void Click_char(chara_controller char_i) {
        if(char_i.get_status() == 1){  //在船上
             if(boat.get_status() == 0)//在开始地方
             {
                 
                 char_i.get_on_bank(start_bank);
                 start_bank.get_on_bank(char_i);
                 int t_rank = char_i.get_rank();
                 boat.get_off_boat(t_rank);
                 Vector3 free_pos = new Vector3(7+t_rank ,2,0);
                 char_i.charac_action(0,free_pos);
             }

            if(boat.get_status() == 1) //上终点河岸
                {
                    char_i.get_on_bank(dest_bank);
                    dest_bank.get_on_bank(char_i);
                    int t_rank = char_i.get_rank();
                    boat.get_off_boat(t_rank);
                    Vector3 free_pos = new Vector3(-7-t_rank ,2,0);
                    char_i.charac_action(2,free_pos);
                }
        }

        else{//在岸上
            Bank_controller bank_i = char_i.get_bank();

            if(boat.get_free() == -1)  
                 return ;

            if((bank_i.get_type() == 1 && boat.get_status() == 0)) ///在起点河岸上船
            {
                   bank_i.get_off_bank(char_i.get_rank());
                   int index = (boat.get_free())*2-1;           
                   Vector3 free_pos = new Vector3(5+index,1.5F,0);
                   char_i.charac_action(1,free_pos);
                   char_i.get_on_boat (boat);
                   boat.get_on_boat(char_i);
            }//在终点河岸上船:
             else if ((bank_i.get_type() == -1 && boat.get_status() == 1))
               {
                   bank_i.get_off_bank(char_i.get_rank());
                   int index = (boat.get_free())*2-1;           
                   Vector3 free_pos = new Vector3(-5+index,1.5F,0);
                   char_i.charac_action(1,free_pos);
                   char_i.get_on_boat (boat);
                   boat.get_on_boat(char_i);
               }
            else  {return ;}
        }

      user_GUI.status = judger.check_game_over (start_bank, dest_bank,boat);///
    }

public void Restart(){
    start_bank.init();
    dest_bank.init();
    boat.init();
    for(int i = 0; i < 6; ++i)
    {
        characters[i].init();
        start_bank.get_on_bank(characters[i]);
    }
} 

}

3.4 处理游戏对象点击的类 Click_GUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using controller;

public class Click_GUI : MonoBehaviour {
	IUserAction action;
	chara_controller characterController;

	public void setController(chara_controller characterCtrl) {
		characterController = characterCtrl;
	}

	void Start() {
		action = Director.getInstance ().currentSceneController as IUserAction;
	}

	void OnMouseDown() {
		if (gameObject.name == "boat") {
			action.S_Boating();
		} else {
			action.Click_char(characterController);
		}
	}
}

4.游戏运行:

1:运行截图:

在这里插入图片描述
在这里插入图片描述

2:演示视频:

priest and devil

5:项目源码地址

gitee仓库地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值