3D游戏设计 homework2

1、简单题

1.1 解释游戏对象(GameObjects) 和 资源(Assets)的区别与联系。

区别:
游戏对象是出现在场景中的各种物体或场景。 即游戏中的每个对象都是一个游戏对象。游戏对象自己不做任何事。他们需要专有属性,才可以成为一个角色,一个环境,或一种特殊效果。游戏对象更像是一种容器。
资源是项目中的素材,包括图像、音乐文件、脚本文件、预制文件等。

联系:
游戏对象可保存为资源(以便重复利用),资源可以作为组件或游戏对象创建游戏对象实例。

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

资源的目录组织结构: 资源文件夹将作用相似的资源放在同一个文件夹中。

游戏对象树的层次结构: 游戏对象树类似于树,一个游戏对象往往是包括了多个子对象。子对象又包括了它的子对象

1.3 编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件

基本行为包括 Awake() Start() Update() FixedUpdate() LateUpdate()
常用事件包括 OnGUI() OnDisable() OnEnable()

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

public class init : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("It is in Start");
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log("It is in Update");
    }

    private void Awake()
    {
        Debug.Log("It is in Awake");
    }

    private void FixedUpdate()
    {
        Debug.Log("It is in FixedUpdate");
    }

    private void LateUpdate()
    {
        Debug.Log("It is in LateUpdate");
    }

    private void OnGUI()
    {
        Debug.Log("It is in OnGUI");
    }

    private void OnDisable()
    {
        Debug.Log("It is in OnDisable");
    }

    private void OnEnable()
    {
        Debug.Log("It is in OnEnable");
    }
}

执行效果:
执行效果
解释:
awake:当一个脚本实例被载入时被调用
start:在所有update函数之前被调用一次,用于初始化
update:当行为启用时,其update在每一帧被调用
fixedupdate:当行为启用时,其fixedupdate在每一时间片被调用
LateUpdate:在每帧执行完毕调用,在所有update结束后才执行,比较适合用于命令脚本的执行。
OnGUI:渲染和处理GUI事件时调用,一般在这个函数里绘制GUI菜单
OnEnable:当对象变为可用或激活状态时被调用
OnDisable:当对象变为不可用或非激活状态时被调用

1.4 查找脚本手册,了解 GameObject,Transform,Component 对象

分别翻译官方对三个对象的描述(Description)
描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件
本题目要求是把可视化图形编程界面与 Unity API 对应起来,当你在 Inspector 面板上每一个内容,应该知道对应 API。
例如:table 的对象是 GameObject,第一个选择框是 activeSelf 属性。
用 UML 图描述 三者的关系(请使用 UMLet 14.1.1 stand-alone版本出图)
table
翻译:
GameObject:游戏对象是Unity中表示游戏角色,游戏道具和游戏场景的基本对象。他们自身无法完成许多功能,但是他们构成了那些给予他们实体功能的组件的容器。
Transform:转换组件决定了游戏场景中每个游戏对象的位置,旋转和缩放比例。每个游戏对象都有转换组件。
Component:组件是游戏中对象和行为的细节。它是每个游戏对象的功能部分。

table对象属性:
table 的对象是 GameObject,第一个选择框是activeSelf:可以定义对象的名称,动静态等属性;第二个选择框是Transform:可以定义对象的位置、面向方向、大小;第三个选择框是Box Collider:可以调整坐标系的位置、大小;第四个选择框是Component:可以给对象增加行为

table 的 Transform 的属性:
Position为(0,0,0);Rotation为(0,0,0)、Scale为(1,1,1)。

table 的部件:
Tranform、Mesh Filter、Box Collider、Mesh Renderer

UML图:
UMl

1.5 整理相关学习资料,编写简单代码验证以下技术的实现:

查找对象

public static GameObject Find(string name); 
//通过名字查找
public static GameObject FindWithTag(string tag);
//通过标签查找单个对象
public static GameObject[] FindGameObjectsWithTag(string tag);
//通过标签查找多个对象

添加子对象

public static GameObect CreatePrimitive(PrimitiveTypetype)

遍历对象树

foreach (Transform child in transform) {
 
         Debug.Log(child.gameObject.name);
 
}

清除所有子对象

foreach (Transform child in transform) {  
    Destroy(child.gameObject);  
} 

1.6 资源预设(Prefabs)与 对象克隆 (clone)

预设(Prefabs)有什么好处?
预设像一个类模板,可以迅速方便创建大量相同属性的对象、操作简单,代码量少,减少出错概率。修改的复杂度降低,一旦需要修改所有相同属性的对象,只需要修改预设即可,所有通过预设实例化的对象都会做出相应变化。
预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?
修改预设后,所有通过预设实例化的对象都会做出相应变化。但是克隆只是复制它,这个对象独立于原来的对象,在修改克隆体不会影响原有的。这类似于C++值复制和引用的差别。
制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象

public GameObject table;
 void Start () {
        Debug.Log("ITStart");
        GameObject newTable = (GameObject)Instantiate(table.gameObject);
}

2、编程实践,小游戏

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

在阅读IMGUI的API后实现,具体代码如下:

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

public class newGame : MonoBehaviour
{   
    //引入图片
    public Texture letterX;
    public Texture circle;
    public Texture2D backGround;

    private int[,] board = new int[3, 3];           //储存棋盘信息,0为X,1为O,
    private int turn = 1;               //标记轮到谁,1为O,0为X
    private int count = 0;              //统计棋盘棋子数量
    private bool finished = false;      //标记游戏是否结束
    // Start is called before the first frame update
    void Start()
    {
        Reset();
    }

    void OnGUI()
    {
        GUI.Label(new Rect(100, 50, 210, 50), "Tic - Tac - Toe");   //游戏标题
        if (GUI.Button(new Rect(400, 50, 100, 50), "RESET")) {   //重置游戏按钮
            Reset();
        }

        //游戏过程
        for (int i = 0; i < 3; ++ i) {
            for (int j = 0; j < 3; ++ j) {
                //模拟轮次点击过程
                if (board[i, j] == 1) {
                    GUI.Button(new Rect(400 + 50 * i, 150 + 50 * j, 50, 50), circle);
                }
                else if (board[i, j] == 0) {
                    GUI.Button(new Rect(400 + 50 * i, 150 + 50 * j, 50, 50), letterX);
                }
                else {
                    if (GUI.Button(new Rect(400 + 50 * i, 150 + 50 * j, 50, 50), backGround)) {
                        if (finished == true)       //游戏结束便保持现状
                            continue;
                        count++;
                        if (turn == 1) {
                            board[i, j] = 1;
                            turn = 0;
                        }
                        else if (turn == 0) {
                            board[i, j] = 0;
                            turn = 1;
                        }
                    }
                }
            }
        }

        //得到结果并输出
        if (count >= 5)
        {
            int State = getResult();        //-2表示游戏未结束,-1表示平局,0表示X胜利,1表示O胜利
            if (State == 0) {
                GUI.Label(new Rect(400, 100, 100, 50), "X WIN!");
                finished = true;
            }
            else if (State == 1) {
                GUI.Label(new Rect(400, 100, 100, 50), "O WIN!");
                finished = true;
            }
            else if (State == -1 && count == 9) {
                GUI.Label(new Rect(400, 100, 210, 50), "NO ONE WIN");
            }
        }
    }

    int getResult()
    {
        //检验行是否存在满足胜利的条件
        for (int i = 0; i < 3; ++ i) {
            if (board[i, 0] == board[i, 1] && board[i, 0] == board[i, 2] && board[i, 0] != -1) {
                return board[i, 0]; 
            }
        }
        //检验列是否存在满足胜利的条件
        for (int j = 0; j < 3; ++ j) {
            if (board[0, j] == board[1, j] && board[0, j] == board[2, j] && board[0, j] != -1) {
                return board[0, j]; 
            }
        }

        //检验对角线是否存在满足胜利的条件
        if (board[0, 0] == board[1, 1] && board[0, 0] == board[2, 2] && board[0, 0] != -1)
            return board[0, 0];

        if (board[0, 2] == board[1, 1] && board[0, 2] == board[2, 0] && board[0, 2] != -1)
            return board[0, 2];

        //判断是否平局
        int counts = 0;
        for (int i = 0; i < 3; ++ i) {
            for (int j = 0; j < 3; ++ j) {
                if (board[i, j] != -1) {
                    counts++;
                }
                else
                    return -2;
            }
        }
        if (counts == 9) {
            return -1;
        }
        return -2;
    }

    // Update is called once per frame
    void Update()
    {

    }
    //重置游戏
    void Reset()
    {
        turn = 1;
        count = 0;
        finished = false;
        for (int i = 0; i < 3; ++ i) {
            for (int j = 0; j < 3; ++ j) {
                board[i, j] = -1;
            }
        }
    }
}

视频链接

3 思考题【选做】

3.1

微软 XNA 引擎的 Game 对象屏蔽了游戏循环的细节,并使用一组虚方法让继承者完成它们,我们称这种设计为“模板方法模式”。为什么是“模板方法”模式而不是“策略模式”呢?
模板方法模式定义了一个算法的步骤或者骨架,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。而策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。从二者的定义来分析,微软 XNA 引擎的 Game 对象的游戏循环的步骤一直都是一样的,故更符合模板方法模式。

3.2

将游戏对象组成树型结构,每个节点都是游戏对象(或数)。尝试解释组合模式(Composite Pattern / 一种设计模式)。
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。组合模式是将对象组合成树形结构以表示“部分-整体”的层次结构,它使得用户对单个对象和组合对象的使用具有一致性。
使用 BroadcastMessage() 方法,向子对象发送消息。你能写出 BroadcastMessage() 的伪代码吗?
父对象代码:

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

public class father : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("It is in fatherStart");
        this.BroadcastMessage("testBroad", "hello sons!");
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

子对象代码:

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

public class son : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("It is in sonStart");
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void testBroad(string str)
    {
        print("son receive message: " + str);
    }
}

结果:结果

传说中的龙书是也。。。 最好最新的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、付费专栏及课程。

余额充值