3D游戏设计 homework4

1、基本操作演练

1.1 下载 Fantasy Skybox FREE, 构建自己的游戏场景

1)下载 Fantasy Skybox FREE:在Unity的Asset Store中找到Fantasy Skybox FREE的材料包,然后下载并且导入自己的项目中。
在这里插入图片描述
导入成功后多了很多材料:
在这里插入图片描述
2) 构建自己的游戏场景:
在Camera中添加Component,然后添加Skybox,再将相应的Skybox图案添加上去,就能够完成天空盒的创建了,得到自己喜欢的背景了。
在这里插入图片描述
然后创建地形,需要添加Terrain,然后可以在Terrain中创造一些自己的场景,具体方法查看下图:
在这里插入图片描述
在这里插入图片描述

1.2 写一个简单的总结,总结游戏对象的使用

游戏对象主要包括:空对象,摄像机,光线,3D物体,声音,UI基于事件的new UI系统和粒子系统与特效,预制的材料

  • 空对象(Empty):不显示却是最常用的对象之一
  • 摄像机(Camara):观察游戏世界的窗口
  • 光线(Light):游戏世界的光源,让游戏世界富有魅力
  • 3D物体 :游戏中的重要组成部分,可以改变其网格和材质,也是很多复杂对象的初始材料
  • 声音(Audio):游戏中的音乐或者声音来源
  • 预制材料:方便复杂对象的重复使用

2、编程实践:牧师与魔鬼动作分离版

1)本次作业需要在上次作业的基础上,将游戏场景的动作分离出来:
即依然是采用MVC结构实现,与上一次无动作分离版的区别在于,之前对于动作的管理是实现了一个动作类,当鼠标点击船或是人物时,相当于是控制器让船或人物的实例调用动作类来实现运动。这次实践中将船或人物与动作分离开来,单独实现了一个动作管理器,鼠标点击船或是人物时,相当于是控制器发送请求给动作管理器,动作管理器来实现船或人物的运动。
2)主要思路:按照下图将上次的代码进行分解:
在这里插入图片描述

3)接下来是动作基类的实现(课程中有):
设计要点:

  • ScriptableObject是不需要绑定GameObject对象的可编程基类。这些对象受Unity引擎场景管理
  • protected SSAction()是防止用户自己new对象
  • 使用virtual申明虚方法,通过重写实现多态。这样继承者就能明确使用Start和Update编程游戏对象行为
  • 利用接口实现消息通知,避免与动作管理者直接依赖
public class SSAction : ScriptableObject
{
    public bool enable = true;
    public bool destroy = false;
 
    public GameObject gameobject { get; set; }
    public Transform transform { get; set; }
    public ISSActionCallback callback { get; set; }
 
    protected SSAction() {}
 
    public virtual void Start() {
        throw new System.NotImplementedException();
    }
 
    public virtual void Update() {
        throw new System.NotImplementedException();
    }
}

4)简单动作实现:
设计目的:游戏中移动的动作,通过传入游戏对象的位置和设置好的动作,就能够使游戏对象移动起来

public class CCMoveToAction : SSAction {
	public Vector3 target;
	public float speed;
 
	public static CCMoveToAction GetSSAction(Vector3 target, float speed) {
		CCMoveToAction action = ScriptableObject.CreateInstance<CCMoveToAction>();
		action.target = target;
		action.speed = speed;
		return action;
	}
 
	public override void Update () {
		this.transform.position = Vector3.MoveTowards(this.transform.position,target,speed);
		if(this.transform.position == target) {
			this.destroy = true;
			this.callback.SSActionEvent(this);
		}
	}
 
	public override void Start() {}
}

5)顺序动作组合类实现:
代码重点:

  • repeat的值为-1表示动作无限循环,而start则表示动作开始
  • Update的重写则是表示执行当前的动作
  • SSActionEvent则是一个回调通知的动作,当收到当前动作执行完成后,则推下一个动作,如果完成一次循环,则减少它的次数。如果当所有动作完成,就通知动作的管理者,将其销毁。
  • Start的重写则是表示,在执行动作前,为每个动作注入当前动作的游戏对象,并将自己作为动作事件的接收者。
public class CCSequenceAction : SSAction, ISSActionCallback {
    public List<SSAction> sequence;
    public int repeat = -1; //repeat forever
    public int start = 0;
 
    public static CCSequenceAction GetSSAction(int repeat, int start, List<SSAction> sequence) {
        CCSequenceAction action = ScriptableObject.CreateInstance<CCSequenceAction>();
        action.repeat = repeat;
        action.sequence = sequence;
        action.start = start;
        return action;
    }
 
    public override void Start() {
        foreach (SSAction action in sequence) {
            action.gameobject = this.gameobject;
            action.transform = this.transform;
            action.callback = this;
            action.Start();
        }
    }
 
    public override void Update() {
        if (sequence.Count == 0) return;
        if (start < sequence.Count)
            sequence[start].Update();
    }
 
    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Completed,
     int intParam = 0, string strParam = null, Object objectParam = null) {
        source.destroy = false;
        this.start++;
        if (this.start >= sequence.Count) {
            this.start = 0;
            if (repeat > 0) repeat--;
            if (repeat == 0) {
                this.destroy = true;
                this.callback.SSActionEvent(this);
            }
            else {
                sequence[start].Start();
            }
        }
    }
 
    private void OnDestroy() {
        //destory
    }
}

6)动作事件接口定义:在定义了时间处理接口以后,所有的事件管理者都必须实现这个接口来实现事件调度。所以,组合事件需要实现它,事件管理器也必须实现它。

public enum SSActionEventType : int { Started, Completed }
 
public interface ISSActionCallback
{
    void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Completed,
        int intParam = 0, string strParam = null, Object objectParam = null);
}

7)动作管理基类 – SSActionManager:实现了所有动作的基本管理

public class SSActionManager : MonoBehaviour, ISSActionCallback {                     //action管理器

    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();    //将执行的动作的字典集合,int为key,SSAction为value
    private List<SSAction> waitingAdd = new List<SSAction>();                       //等待去执行的动作列表
    private List<int> waitingDelete = new List<int>();                              //等待删除的动作的key                

    protected void Update(){
        foreach (SSAction ac in waitingAdd){
            actions[ac.GetInstanceID()] = ac;                                      //获取动作实例的ID作为key
        }
        waitingAdd.Clear();

        foreach (KeyValuePair<int, SSAction> kv in actions){
            SSAction ac = kv.Value;
            if (ac.destroy) waitingDelete.Add(ac.GetInstanceID());
            else if (ac.enable) ac.Update();
        }

        foreach (int key in waitingDelete){
            SSAction ac = actions[key];
            actions.Remove(key);
            Object.Destroy(ac);
        }
        waitingDelete.Clear();
    }

    public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager){
        action.gameobject = gameobject;
        action.transform = gameobject.transform;
        action.callback = manager;
        waitingAdd.Add(action);
        action.Start();
    }

    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null){
        //牧师与魔鬼的游戏对象移动完成后就没有下一个要做的动作了,所以回调函数为空
    }
}

8)裁判类的实现:对当前局面胜负关系的判断

public class Judger : System.Object {
    private static Judger _instance; 
    public static Judger getInstance() { //使用单例模式
        if (_instance == null) _instance = new Judger ();
        return _instance;
    }
    public int check(CoastCon fromCoast,CoastCon toCoast,BoatCon boat) {	// 0->not finish, 1->lose, 2->win
        int fromP = 0, fromD = 0, toP = 0, toD = 0;
        int[] fromCount = fromCoast.getCharacterNum();
        fromP += fromCount[0];
        fromD += fromCount[1];

        int[] toCount = toCoast.getCharacterNum ();
        toP += toCount[0];
        toD += toCount[1];

        if (toP + toD == 6) return 2; //win
        int[] boatCount = boat.getCharacterNum ();
        if (boat.getStatus () == -1) {
            toP += boatCount[0]; toD += boatCount[1];	// boat at toCoast
        }
        else {
            fromP += boatCount[0]; fromD += boatCount[1];	// boat at fromCoast	
        }
        if (fromP < fromD && fromP > 0) return 1; //lose		
        if (toP < toD && toP > 0) return 1; //lose
        return 0;			// not finish
    }
}

9)视频链接

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

余额充值