草庐IT

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

半岛tie盒 2023-10-10 原文

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

  • 下载 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;
    }

}

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

有关《3D游戏编程与设计》第四次作业的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  7. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

  8. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  9. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  10. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

随机推荐