《3D游戏编程与设计》第四次作业

一、基本操作演练【建议做】

  • 下载 Fantasy Skybox FREE, 构建自己的游戏场景
  1. 上Assest Store下载资源Fantasy Skybox FREE 和 Realistic Tree 9,下载后Assest出现如下文件

2.新建mysky,并将对应纹理拖入

3.设置场景天空盒,并加入摄像机

4.新建Terrian,并绘制地形

5.在周边添加几块地形,并使用terrian自带brush种草种树

6.效果
  • 写一个简单的总结,总结游戏对象的使用
在实际游戏生产中我们依赖的模型、预制,是由最基础的游戏对象构成的:
Empty:作用是创建一个新的对象空间,也可作为子对象的容器,不显示,但最常用对象之一。
3D物体:
  基础 3D 物体:立方体、球体、胶囊体、圆柱体、平面、四边形
  构造 3D 物体:由三角形网格构建的物体:如地形等
Camera :观察游戏世界的窗口
Light:游戏世界的光源,分为平行光(类似太阳光)、聚光灯(spot)、点光源(point)、区域光(area)
Audio:游戏世界的声音

通过对基础的游戏对象的使用,可以构建出复杂、完整、各种各样的游戏。


二、编程实践(二选一)

1.裁判类

将原始版本FirstController类中的check_game_over方法单独作为裁判类,原来的场景控制器FirstController需要在Awake和初始化函数中初始化一个裁判类。

public class JudgeController
{
    FirstController firstCtrl;

    public JudgeController(){
        firstCtrl = Director.getInstance().currentSceneController as FirstController;
    }

    //判断游戏状态
    public int UpdadeGameState(){
        int from_priest = 0;
        int from_devil = 0;
        int to_priest = 0;
        int to_devil = 0;

        int[] fromCount = firstCtrl.fromCoast.getCharacterNum ();
        from_priest += fromCount[0];
        from_devil += fromCount[1];

        int[] toCount = firstCtrl.toCoast.getCharacterNum ();
        to_priest += toCount[0];
        to_devil += toCount[1];

        if (to_priest + to_devil == 6)      // win
            return 2;

        int[] boatCount = firstCtrl.boat.getCharacterNum ();
        if (firstCtrl.boat.get_to_or_from () == -1) {   // boat at toCoast
            to_priest += boatCount[0];
            to_devil += boatCount[1];
        } else {    // boat at fromCoast
            from_priest += boatCount[0];
            from_devil += boatCount[1];
        }
        if (from_priest < from_devil && from_priest > 0) {      // lose
            return 1;
        }
        if (to_priest < to_devil && to_priest > 0) {
            return 1;
        }
        return 0;           // not finish
    }

2.动作分离

在原始代码中,游戏对象的移动由FirstController、MyCharacterController和BoatController类共同管理。在动作分离版的代码中,管理动作的代码被分解成以下三部分:CCActionManager用于管理所有移动动作,CCMoveAction用于管理“移动”这种动作,Move则是移动动作的实体。

CCActionManager类代码如下:

public class CCActionManager : UserAction {
    
    public FirstController controller;
    public CCMoveAction moveAction;

    public CCActionManager(){
        controller = Director.getInstance().currentSceneController as FirstController;
        moveAction = new CCMoveAction();
    }

    public void moveBoat() {
        if (controller.boat.isEmpty ())
            return;
        moveAction.MoveBoat(controller.boat);
        controller.userGUI.status = controller.judgeController.UpdadeGameState ();
    }

    public void characterIsClicked(MyCharacterController characterCtrl) {
        if (characterCtrl.isOnBoat ()) {
            CoastController whichCoast;
            if (controller.boat.get_to_or_from () == -1) { // to->-1; from->1
                whichCoast = controller.toCoast;
            } else {
                whichCoast = controller.fromCoast;
            }

            controller.boat.GetOffBoat (characterCtrl.getName());
            moveAction.MoveMyCharacter(characterCtrl,whichCoast.getEmptyPosition());
            characterCtrl.getOnCoast (whichCoast);
            whichCoast.getOnCoast (characterCtrl);

        } else {                                    // character on coast
            CoastController whichCoast = characterCtrl.getCoastController ();

            if (controller.boat.getEmptyIndex () == -1) {       // boat is full
                return;
            }

            if (whichCoast.get_to_or_from () != controller.boat.get_to_or_from ())  // boat is not on the side of character
                return;

            whichCoast.getOffCoast(characterCtrl.getName());
            moveAction.MoveMyCharacter(characterCtrl,controller.boat.getEmptyPosition());
            characterCtrl.getOnBoat (controller.boat);
            controller.boat.GetOnBoat (characterCtrl);
        }
        controller.userGUI.status = controller.judgeController.UpdadeGameState ();
    }

    public void restart() {
        controller.boat.reset ();
        controller.fromCoast.reset ();
        controller.toCoast.reset ();
        for (int i = 0; i < controller.characters.Length; i++) {
            controller.characters [i].reset ();
        }
    }
}

CCMoveAction类代码如下:

public class CCMoveAction
{
    public void MoveMyCharacter(MyCharacterController characterCtrl,Vector3 destination){
        characterCtrl.moveScript.setDestination(destination);
    }

    public void MoveBoat(BoatController bostCtrl) {
        if (bostCtrl.to_or_from == -1) {
            bostCtrl.moveScript.setDestination(bostCtrl.fromPosition);
            bostCtrl.to_or_from = 1;
        } else {
            bostCtrl.moveScript.setDestination(bostCtrl.toPosition);
            bostCtrl.to_or_from = -1;
        }
    }
}

CCMoveAction类代码如下:

public class Move: MonoBehaviour
{
    readonly float move_speed = 20;

    int moving_status;  // 0->not moving, 1->moving to middle, 2->moving to dest
    Vector3 dest;
    Vector3 middle;
    void Update() {
        if (moving_status == 1) {
            transform.position = Vector3.MoveTowards (transform.position, middle, move_speed * Time.deltaTime);
            if (transform.position == middle) {
                moving_status = 2;
            }
        } else if (moving_status == 2) {
            transform.position = Vector3.MoveTowards (transform.position, dest, move_speed * Time.deltaTime);
            if (transform.position == dest) {
                moving_status = 0;
            }
        }
    }
        
    public void setDestination(Vector3 _dest) {
        dest = _dest;
        middle = _dest;
        if (_dest.y == transform.position.y) {  // boat moving
            moving_status = 2;
        }
        else if (_dest.y < transform.position.y) {  // character from coast to boat
            middle.y = transform.position.y;
        } else {                                // character from boat to coast
            middle.x = transform.position.x;
        }
        moving_status = 1;
    }

    public void reset() {
        moving_status = 0;
    }

}

运行效果与原版相同
具体代码请见

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容