3Dgame_homework3

简答并用程序验证

1. 游戏对象运动的本质是什么?

游戏世界的构建就是游戏对象的状态在游戏循环驱动下进行的演变,也就是研究物体的变化与运动;而游戏对象运动的本质就是使用矩阵变换(平移、旋转、缩放)来改变游戏对象的空间属性,即对象在空间中每一帧不同位置的链接。

如下文2.中实现游戏对象的抛物线运动,可以采用Transform属性、向量Vector3等多种方法达成。

2. 请用三种方法以上方法,实现物体的抛物线运动(如修改Transform属性,使用向量Vector3的方法等)。

将游戏部件添加到游戏对象上,就可以产生组合行为。而游戏中每个对象的行为都由少数几个基本动作组合而成,这样提升了程序的灵活性,减少了应对游戏规则变化带来的编码量。

(1)TransForm部件:

Unity使用TransForm部件来操作物体的位置、旋转和缩放。场景中的每个对象都有一个变换,用于存储和操作对象的位置、旋转和缩放,其中每个变换都可以有一个父级,让您能够分层应用位置、旋转和缩放;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour{
    public float speed_y;
    void Start(){
        speed_y = 0.98f;
    }    
    void Update(){
        this.transform.position += Vector3.right * Time.deltaTime * 0.98f;
        speed_y -= 0.98f * Time.deltaTime;
        this.transform.position += Vector3.up * Time.deltaTime * speed_y;
    }
}

通过修改y方向移动的速度而固定x方向的速度来实现抛物线运动,即x轴初始速度为0.98,y初始速度为0.98,而y轴有负向加速度0.98,这些都是通过修改position实现。

(2)使用平移Translate:

TransForm部件还提供了其他的方法编写运动程序,直接修改游戏对象的属性,例如平移(Translate)等;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
    public float speed_y;
    void Start(){
        speed_y = 0.98f;
    }
  void Update(){
        speed_y -= 0.98f * Time.deltaTime;
        this.transform.Translate(0.98f * Time.deltaTime, speed_y * Time.deltaTime, 0);
    }
}

通过平移函数Translate直接修改x,y的坐标。

(3)使用向量Vector3:

向量控制运动是万能且高效的方法;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
    public float speed_y;
    void Start() {
        speed_y = 0.98f;
    }
  void Update() {
        speed_y -= 0.98f * Time.deltaTime;
        Vector3 v = new Vector3(0.98f * Time.deltaTime,speed_y*Time.deltaTime,0);
        this.transform.position += v;
    }
}

其原理与TransForm部件方法类似,Vector3为中间介质。

3. 写一个程序,实现一个完整的太阳系,其中其他星球围绕太阳的转速必须不一样,且不在一个法平面上。

参考图片:

太阳系
(Pluto冥王星于2006年被国际天文联合会降级为矮行星,因此不考虑)

需要大概模拟出各个行星的位置和转速,并考虑公转RotateAround与自转Rotate两个过程;

代码:

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

public class Solarsystem : MonoBehaviour {
    public Transform Sun;  //太阳
    public Transform Mercury;  //水星
    public Transform Venus;  //金星
    public Transform Earth;  //地球
    public Transform Mars;  //火星
    public Transform Jupiter;  //木星
    public Transform Saturn;  //土星
    public Transform Uranus;  //天王星
    public Transform Neptune;  //海王星

    void Start() {
        Sun.position = new Vector3(0, 0, 0);
        Mercury.position = new Vector3(2, 0, 0);
        Venus.position = new Vector3(33, 0, 0);
        Earth.position = new Vector3(4, 0, 0);
        Mars.position = new Vector3(5, 0, 0);
        Jupiter.position = new Vector3(6, 0, 0);
        Saturn.position = new Vector3(7, 0, 0);
        Uranus.position = new Vector3(8, 0, 0);
        Neptune.position = new Vector3(9, 0, 0);
    }

    void Update() {
        Mercury.RotateAround(Sun.position, new Vector3(0, 3, 1), 23 * Time.deltaTime);
        Venus.RotateAround(Sun.position, new Vector3(0, 2, 1), 17 * Time.deltaTime);
        Earth.RotateAround(Sun.position, new Vector3(0, 1, 0), 10 * Time.deltaTime);
        Mars.RotateAround(Sun.position, new Vector3(0, 13, 5), 9 * Time.deltaTime);
        Jupiter.RotateAround(Sun.position, new Vector3(0, 8, 3), 8 * Time.deltaTime);
        Saturn.RotateAround(Sun.position, new Vector3(0, 2, 1), 7 * Time.deltaTime);
        Uranus.RotateAround(Sun.position, new Vector3(0, 9, 1), 4 * Time.deltaTime);
        Neptune.RotateAround(Sun.position, new Vector3(0, 7, 1), 3 * Time.deltaTime);

        Venus.Rotate(new Vector3(0, 3, 1) * 25 * Time.deltaTime);
        Mercury.Rotate(new Vector3(0, 2, 1) * 20 * Time.deltaTime);
        Earth.Rotate(new Vector3(0, 1, 0) * 30 * Time.deltaTime);
        Mars.Rotate(new Vector3(0, 3, 2) * 20 * Time.deltaTime);
        Jupiter.Rotate(new Vector3(0, 2, 1) * 30 * Time.deltaTime);
        Saturn.Rotate(new Vector3(0, 4, 1) * 20 * Time.deltaTime);
        Uranus.Rotate(new Vector3(0, 7, 1) * 20 * Time.deltaTime);
        Neptune.Rotate(new Vector3(0, 3, 1) * 30 * Time.deltaTime);
    }
}

建立对象,关联代码;

运行结果:

编程实践

阅读以下游戏脚本:

牧师和恶魔
帮助牧师和恶魔在时限内过河;
河的一边有三个牧师和三个恶魔,他们都想到河的对岸去;
只有一艘船,这艘船每次只能载两个人,而且必须要有一个人才能把船从一边转到另一边;
在flash游戏中,你可以点击它们来移动它们,然后点击go按钮将船移动到另一个方向;
如果在河的任意一边牧师的人数小于恶魔,他们就会被杀,使游戏结束;
尝试使所有的牧师都活下来而通过游戏。

参考游戏:play the game


需要满足的要求:

1)列出游戏中提及的事物(Objects)

Priests(牧师)*3,Devil(恶魔)*3,Boat(船),River(河),Bank(河岸)。

2)用表格列出玩家动作表(规则表)

动作描述
点击牧师/恶魔牧师/恶魔上船/下船
点击船若船上有牧师/恶魔,则船从河岸的一侧移动到另一侧

3)将游戏中对象做成预制

4)在场景控制器 LoadResources 方法中加载并初始化长方形、正方形、球及其色彩代表游戏中的对象

5)使用 C# 集合类型有效地组织对象

6)整个游戏仅主摄像机和一个 Empty 对象, 其他对象必须代码动态生成,不许出现 Find 游戏对象, SendMessage 这类突破程序结构的通讯耦合语句

7)请使用课件架构图编程,不接受非 MVC 结构程序

8)注意细节,例如:船未靠岸,牧师与恶魔上下船运动中,均不能接受用户事件

【步骤】

  1. MVC架构:
    MVC是界面人机交互程序设计的一种架构模式,把程序分为了三个部分:
    模型(Model):数据对象及关系;
         游戏对象、空间关系;
    控制器(Controller):接受用户事件,控制模型的变化;
         一个场景一个主控制器;
         至少实现与玩家交互的接口(IPlayerAction);
         实现或管理运动;
    界面(View):显示模型,将人机交互事件交给控制器处理;
         处收 Input 事件;
         渲染 GUI,接收事件;
  2. 划分目录,创建对象并制作预制:


  1. 编写代码:
    (1)Controller:
    1)SSDirector:
    创建导演(使用单例模式实现);
public static SSDirector GetInstance() {
        if (_instance == null) {
            _instance = new SSDirector();
        }
        return _instance;
}

2)ISceneControllor:
场景控制器的接口,导演使用这个接口与场景控制器沟通,只需加载资源;

public interface ISceneController
{
    void LoadResources(); 
}

3)FirstController:
控制器,对场景中的具体对象进行操作,挂载到一个空的游戏对象中;

public LandModel land1;
public LandModel land2;
public BoatModel boat;
private RoleModel[] roles;
UserGUI user_gui;
void Start() {
        SSDirector director = SSDirector.GetInstance();
        director.CurrentScenceController = this;
        user_gui = gameObject.AddComponent<UserGUI>() as UserGUI;
        LoadResources();
}

(2)UserGUI:
用于控制GUI的各种信息的展示,用户交互结构;

(3)Model:
控制各个对象的参数和属性和行为;

  1. 运行结果:

思考题(选做)

使用向量与变换,实现并扩展 Tranform 提供的方法,如 Rotate、RotateAround 等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值