3D游戏编程与设计_HW2

1、简答题【建议做】

  1. 解释 游戏对象(GameObjects) 和 资源(Assets)的区别与联系。
    1. 游戏对象表示某些资源的具体实例化,出现在游戏的场景中,游戏对象一般有敌人,场景,摄像机等非实体虚拟父类,子类一般为游戏内的实体

    2. 资源表示硬盘中的文件,存储在Unity工程的Assets文件中,资源可以被多个对象使用,也可以作为模板实例化成游戏内的实体,一般划分为材质,对象,场景,预设,声音,脚本,贴图等子文件夹中。

 

  • 下载几个游戏案例,分别总结资源、对象组织的结构(指资源的目录组织结构与游戏对象树的层次结构)
    • GameObject的组织结构
    • Assets的组织结构

 

  • 编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件
    • 基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()
    • 常用事件包括 OnGUI() OnDisable() OnEnable()
    • Awake()          :当一个脚本实例被载入时被调用

    • Start()             :   在所有update()函数被调用之前调用

    • Update()         :   当行为启用时其Update()在每一帧被调用

    • FixedUpdate():   当行为启动时其Update()在每一时间片被调用

    • LateUpdate() :    当行为启用时,在所有Update()执行完后执行

    • Onable()         :    当对象变为可用或激活状态时此函数被调用,OnEnable不能用于协同程序(物体启动时被调用)

    • Ondisable()    :    当对象变为不可用或非激活状态时此函数被调用。当物体被销毁时他被调用,并且可用于任意清理代码 。当脚本编译完成之后重新加载时,该函数被调用,OnEnable()在脚本被载入后被调用。(物体被禁用时调用)

    • OnGUI()          : 绘制GUI时触发。一般在这个函数里绘制GUI菜单(GUI显示函数只能在OnGUI中被调用) 

  • 查找脚本手册,了解 GameObject,Transform,Component 对象
    • 分别翻译官方对三个对象的描述(Description)
    • GameObeject:Base class for all entities in Unity Scenes.

    • 翻译:Unity场景中所有实体的基类

    • Transform:Position, rotation and scale of an object.Every object in a Scene has a Transform. It's used to store and manipulate the position, rotation and scale of the object. Every Transform can have a parent, which allows you to apply position, rotation and scale hierarchically. 

    • 翻译:对象的位置旋转和比例。场景中每个对象都有一个变换。他用于操作对象的位置,缩放和旋转。每个转换都可以拥有一个父类,允许分层应用位置。

    • Component:Base class for everything attached to GameObjects.

    • 翻译:所有附加到GameObject的东西的基类。

    • 描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件
      • 本题目要求是把可视化图形编程界面与 Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。
      • 例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。
      • table:第一个选择框时便签Tag:当前选择的是未加标签。第二个选择框是层,当前是默认属性。第三个属性是预设。

      • Transform:有三个属性:Position,Rotation,Scale:表示位置,旋转,比例

      • 组件:Mesh Filter,Box Collider,Mesh Renderer

    • 用 UML 图描述 三者的关系(请使用 UMLet 14.1.1 stand-alone版本出图)
    • 资源预设(Prefabs)与 对象克隆 (clone)
      • 预设(Prefabs)有什么好处?
      • 使游戏对象可重复使用,这个游戏对象已经配置完成,可以直接加入到游戏中去,提高了工作效率。

      • 预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?
      • 预设与克隆都可以由一个对象生成大量相同的对象,但是预设出的对象在本体改变时回随着本体进行改变,而克隆出的对象之间没有联系,可以随意更改。

      • 制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象
      • 先绘制出桌子,然后拖入Assets框中,做成预制资源

      • 之后写一个脚本,如图:

      • 之后应用脚本,然后把预制好的table资源拖入框中如图:

 

2、 编程实践,小游戏

  • 游戏内容: 井字棋 或 贷款计算器 或 简单计算器 等等
  • 技术限制: 仅允许使用 IMGUI 构建 UI
  • 作业目的:
    • 了解 OnGUI() 事件,提升 debug 能力
    • 提升阅读 API 文档能力

项目链接

主要代码如下:

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

public class NewBehaviourScript : MonoBehaviour
{
    private int[,] chessBoard = new int[3, 3];
    private int turn = 1;//决定到哪一方

    void Start()
    {
        Reset();//初始化界面
    }
    int checkWin()//判断胜负
    {
        for (int i = 0; i < 3; i++)
        {
            if (chessBoard[i, 0] == chessBoard[i, 1] && chessBoard[i, 0] == chessBoard[i, 2] && chessBoard[i, 0] != 0)
                return chessBoard[i, 0];//]

        }//竖着赢
        for (int i = 0; i < 3; i++)
        {
            if (chessBoard[0, i] == chessBoard[1, i] && chessBoard[0, i] == chessBoard[2, i] && chessBoard[0, i] != 0)
                return chessBoard[0, i];
        }//横着赢

        if (chessBoard[0, 0] == chessBoard[1, 1] && chessBoard[0, 0] == chessBoard[2, 2] && chessBoard[0, 0] != 0)
            return chessBoard[0, 0];//斜着赢

        if (chessBoard[2, 0] == chessBoard[1, 1] && chessBoard[2, 0] == chessBoard[0, 2] && chessBoard[2, 0] != 0)
            return chessBoard[2, 0];//斜着赢
        int count = 0;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (chessBoard[i, j] != 0)
                {
                    count++;
                }
            }
        }

        if (count == 9)//被填满仍无人胜利,平局
            return 0;
        return 3;
    }
    void OnGUI()
    {
        if (GUI.Button(new Rect(300, 50, 150, 50), "Start Game"))
        {
            Reset();//点击Start Game按钮重置游戏
        }
        GUISkin skin = GUI.skin;
        skin.button.normal.textColor = Color.green;
        skin.button.hover.textColor = Color.blue;//设置按钮样式
        int State = checkWin();//判断当前状态2:x赢1:O赢0:平局
        if (State == 2)
        {

            skin.button.normal.textColor = Color.red;
            GUI.Label(new Rect(300, 105, 50, 50), "X Win!");
        }
        else if (State == 1)
        {
            skin.button.normal.textColor = Color.red;
            GUI.Label(new Rect(300, 105, 50, 50), "O Win");
        }
        else if (State == 0)
        {
            skin.button.normal.textColor = Color.red;
            GUI.Label(new Rect(300, 105, 50, 50), "Tied");
        }
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (chessBoard[i, j] == 1)
                {
                    // GUI.Label(new Rect(400, 105, 50, 50), "X's turn.");
                    GUI.Button(new Rect(300 + 50 * i, 130 + j * 50, 50, 50), "O");
                }
                else if (chessBoard[i, j] == 2)
                {
                    //GUI.Label(new Rect(400, 105, 50, 50), "O's turn.");
                    GUI.Button(new Rect(300 + 50 * i, 130 + j * 50, 50, 50), "X");
                }

                if (GUI.Button(new Rect(300 + 50 * i, 130 + j * 50, 50, 50), ""))
                {//按钮没被点击时,被点击后改变棋盘状态,然后根据棋盘状态改变按钮显示
                    if (State == 3)
                    {
                        if (turn == 1)
                            chessBoard[i, j] = 1;
                        else if (turn == -1)
                            chessBoard[i, j] = 2;
                        turn = -turn;
                    }
                }
            }
        }



    }

    void Reset()
    {//重置棋盘
        turn = 1;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                chessBoard[i, j] = 0;
            }
        }
    }

    void Update()
    {

    }
}

3、思考题【选做】

  • 微软 XNA 引擎的 Game 对象屏蔽了游戏循环的细节,并使用一组虚方法让继承者完成它们,我们称这种设计为“模板方法模式”。
    • 为什么是“模板方法”模式而不是“策略模式”呢?
      • Game对象看作一个类,它使用一组虚方法来声明出该对象的细节功能,然后由子类将剩余的逻辑实现,当游戏对象遇到不同的环境,只有其中一个或几个方法需要不同的实现方法时,但是其他方法并不全部需要改变时,这样就可以只替换其中一个方法,也就是说使用不同的子类来提供不同的实现,这样就大大提高了代码的可复用性。而策略模式是,把不同的算法包装成统一的接口,在不影响客户端的情况下选择不同的算法来进行实现。

        ​​​​​​总得来说,模板方法可以通过不同的实现来达到不同的效果,而策略模式以不同的实现方法来达到相同的效果。

  • 将游戏对象组成树型结构,每个节点都是游戏对象(或数)。
    • 尝试解释组合模式(Composite Pattern / 一种设计模式)。
    • 组合模式可以把一组对象按照树型结构组合成一种层次结构,这种层次结构可以把一组对象表现为一个整体,通过对这个整体进行处理来完成对一个对象和对象的组合的处理。组合模式实现的最关键的地方是简单对象和复合对象必须实现相同的接口

    • 使用 BroadcastMessage() 方法,向子对象发送消息。你能写出 BroadcastMessage() 的伪代码吗?
    • foreach childObject

      • sendMessage();

  • 一个游戏对象用许多部件描述不同方面的特征。我们设计坦克(Tank)游戏对象不是继承于GameObject对象,而是 GameObject 添加一组行为部件(Component)。
    • 这是什么设计模式?
    • Decorator模式

    • 为什么不用继承设计特殊的游戏对象?
      • 因为需要对对象动态的添加功能,采用继承需要修改的代码过多,采用Decorate模式,可以在不修改原来代码的情况下增加新的功能核模块。

 

传说中的龙书是也。。。 最好最新的DirectX游戏开发入门书籍 英文版+中文版+源代码 打包 非常适合初学者 内容提要 -------------------------------------------------------------------------------- 本书主要介绍如何使用DirectX 9.0开发交互式3D图形程序,重点是游戏开发。全书首先介绍了必要的数学工具,然后讲解了相关的3D概念。其他主题几乎涵盖了Direct3D中的所有基本运算,例如图元的绘制、光照、纹理、Alpha融合、模板,以及如何使用Direct3D实现游戏中所需的技术。介绍顶定点着色器和像素着色器的章节(包含了效果框架和新的高级着色语言的内容)对这些关键运算进行了较为集中的讨论。 本书内容深入浅出,内容广泛,可供从事3D游戏程序设计、可视化系统设计或其他图形应用程序开发的开发人员和大中专院校学生参考,也极适合各种游戏开发培训机构作为Direct3D编程的培训教程。 目录 -------------------------------------------------------------------------------- 第Ⅰ部分 基础知识 必备的数学知识\t 3D空间中的向量\t 矩阵\t\t 基本变换\t 平面(选读)\t 射线(选读)\t 小结\t\t 第Ⅱ部分 Direct3D基础 第1章 初始化Direct3D 1.1 Direct3D概述\t 1.2 COM(组件对象模型)\t 1.3 预备知识\t 1.4 Direct3D的初始化\t 1.5 例程:Direct3D的初始化 1.6 小结\t 第2章 绘制流水线\t 2.1 模型表示\t 2.2 虚拟摄像机 2.3 绘制流水线 2.4 小结\t 第3章 Direct3D中的绘制\t 3.1 顶点缓存与索引缓存 3.2 绘制状态\t 3.3 绘制的准备工作\t 3.4 使用顶点缓存和索引缓存进行绘制\t 3.5 D3DX几何体 3.6 例程:三角形、立方体、茶壶、D3DXCreate* 3.7 小结\t 第4章 颜色\t 4.1 颜色表示 4.2 顶点颜色 4.3 着色\t 4.4 例程:具有颜色的三角形\t 4.5 小结\t 第5章 光照\t 5.1 光照的组成\t 5.2 材质\t 5.3 顶点法线\t 5.4 光源\t 5.5 例程:光照 5.6 一些附加例程\t 5.7 小结\t 第6章 纹理映射 6.1 纹理坐标\t 6.2 创建并启用纹理\t 6.3 纹理过滤器 6.4 多级渐进纹理 6.5 寻址模式 6.6 例程:纹理四边形 6.7 小结\t 第7章 融合技术\t 7.1 融合方程\t 7.2 融合因子 7.3 透明度 7.4 用DirectX Texture Tool创建Alpha通道\t 7.5 例程:透明效果\t 7.6 小结\t 第8章 模板\t 8.1 模板缓存的使用\t 8.2 例程:镜面效果\t 8.3 例程:Planer Shadows\t 8.4 小结\t 第Ⅲ部分 Direct3D的应用 第9章 字体\t 第10章 网格(一)\t 第11章 网格(二)\t 第12章 设计一个灵活的Camera类 第13章 地形绘制基础\t 第14章 粒子系统\t 第15章 拾取\t 第Ⅳ部分 着色器和效果 第16章 高级着色语言(HLSL)入门\t 第17章 顶点着色器入门\t 第18章 像素着色器入门\t 第19章 效果框架\t 附录 Windows编程入门\t 参考文献 作者介绍 -------------------------------------------------------------------------------- Prank Luna是Hero lnteractive的程序员,从事交互式3D图形编程已有八年多。他最早接触DirectX可以追溯到DirectX5发布之时,目前居住在加州的洛杉矶市。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值