3D 游戏编程与设计:第3次作业

3D 游戏编程与设计:第3次作业

姓名:韩宝欣 学号:20331013

代码仓库:https://gitee.com/sse_20331013/3d-game.git


1、简答并用程序验证【建议做】

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

    本质是游戏对象在游戏每一帧的渲染过程中Transform属性在发生变化。这里物体的Transform属性是指Position与Rotation两个属性。


  • 请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
    • 第一种方法
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class parabola : MonoBehaviour {
        public float speed1 = 4;
        public float speed2 = 0;
        public float speed = 3;
    	// Use this for initialization
    	void Start () {
            Debug.Log("Init start");
    	}
    	
    	// Update is called once per frame
    	void Update () {
            if(speed1 >= 0){
                speed1 = speed1 - 10 * Time.deltaTime;
                this.transform.position += Vector3.up * Time.deltaTime * speed1 / 2;
            }
            //此处为实现物体先上抛在竖直方向上位置的变化。
            else{
                speed2 = speed2 + 10 * Time.deltaTime;
                this.transform.position += Vector3.down * Time.deltaTime * speed2 / 2;
            }
            //此处为实现物体竖直方向速度减为0后
            //平抛运动在竖直方向上位置的变化。
            
            this.transform.position += Vector3.left * Time.deltaTime * speed;
            //此处为物体在水平上位置的变化。
    	}
    }
    

- 第二种方法,使用transform中的translate方法改变对象的位置。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class parabola : MonoBehaviour {
    public float speed1 = 4;
    public float speed2 = 0;
    public float speed = 3;
	// Use this for initialization
	void Start () {
        Debug.Log("Init start");
	}
	
	// Update is called once per frame
	void Update () {
        if(speed1 >= 0)
        {
            speed1 = speed1 - 10 * Time.deltaTime;
            transform.Translate(Vector3.up * Time.deltaTime * speed1 / 2, Space.World);
        }
        //此处为实现物体先上抛在竖直方向上位置的变化。
        else
        {
            speed2 = speed2 + 10 * Time.deltaTime;
            transform.Translate(Vector3.down * Time.deltaTime * speed2 / 2, Space.World);
        }
        //此处为实现物体竖直方向速度减为0后
        //平抛运动在竖直方向上位置的变化。
        transform.Translate(Vector3.left * Time.deltaTime * speed);
		//此处为物体在水平上位置的变化。
	}
}

  • 第三种方法,新建一个vector3对象,改变这个对象的值,然后直接赋给物体。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class parabola : MonoBehaviour {
    public float speed1 = 4;
    public float speed2 = 0;
    public float speed = 3;
	// Use this for initialization
	void Start () {
        Debug.Log("Init start");
	}
	
	// Update is called once per frame
	void Update () {
        if(speed1 >= 0)
        {
            speed1 = speed1 - 10 * Time.deltaTime;
            Vector3 newOne = new Vector3(Time.deltaTime * speed, Time.deltaTime * speed1 / 2, 0);
            this.transform.position += newOne;
        }
        //此处为实现物体先上抛在竖直方向上位置的变化。
        else
        {
            speed2 = speed2 + 10 * Time.deltaTime;
            Vector3 newOne = new Vector3(Time.deltaTime * speed, -Time.deltaTime * speed2 / 2, 0);
            this.transform.position += newOne;
        }
        //此处为实现物体竖直方向速度减为0后
        //平抛运动在竖直方向上位置的变化。
		
	}
}



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

介绍框架和核心代码,源代码放在gitee上(省略了月球)

  • 首先,在游戏Scene中设置太阳、水星、金星、地球、火星、木星、土星、天王星和海王星。将图片放置在球体上,如下:
    在这里插入图片描述

  • 设置各个行星的公转与自转速度,以及各自的法平面。

    • 运动中心参考物体:太阳;
    • Vector3变量axis:由两个float型的随机数组成:rx与ry,作为各行星运动的轴,代表行星运动的法平面;
    • 设置除了Sun外所有行星的中心体为Sun:
      在这里插入图片描述
      • 将脚本 plantMove.cs 挂载到各个行星上,核心代码如下:

        void Update()
        {
        GameObject.Find(“Sun”).transform.Rotate(Vector3.up * Time.deltaTime * 5 );
        GameObject.Find(“Mercury”).transform.RotateAround(Vector3.zero, new Vector3(0.1f, 1, 0), 60 * Time.deltaTime);
        GameObject.Find(“Mercury”).transform.Rotate(Vector3.up * Time.deltaTime * 1 / 58);

          GameObject.Find("Venus").transform.RotateAround(Vector3.zero, new Vector3(0, 1, -0.1f), 55 * Time.deltaTime);
          GameObject.Find("Venus").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 243);
        
          GameObject.Find("Earth").transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0), 50 * Time.deltaTime);
          GameObject.Find("Earth").transform.Rotate(Vector3.up * Time.deltaTime * 10);
          
          GameObject.Find("Mars").transform.RotateAround(Vector3.zero, new Vector3(0.2f, 1, 0), 45 * Time.deltaTime);
          GameObject.Find("Mars").transform.Rotate(Vector3.up * Time.deltaTime * 10);
        
          GameObject.Find("Jupiter").transform.RotateAround(Vector3.zero, new Vector3(-0.1f, 2, 0), 35 * Time.deltaTime);
          GameObject.Find("Jupiter").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.3f);
        
          GameObject.Find("Saturn").transform.RotateAround(Vector3.zero, new Vector3(0, 1, 0.2f), 20 * Time.deltaTime);
          GameObject.Find("Saturn").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.4f);
        
          GameObject.Find("Uranus").transform.RotateAround(Vector3.zero, new Vector3(0, 2, 0.1f), 15 * Time.deltaTime);
          GameObject.Find("Uranus").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.6f);
        
          GameObject.Find("Neptune").transform.RotateAround(Vector3.zero, new Vector3(-0.1f, 1, -0.1f), 10 * Time.deltaTime);
          GameObject.Find("Neptune").transform.Rotate(Vector3.up * Time.deltaTime * 10 / 0.7f); 	}
        




2、编程实践

  • 阅读以下游戏脚本

Priests and Devils

Priests and Devils is a puzzle game in which you will help the Priests and Devils to cross the river within the time limit. There are 3 priests and 3 devils at one side of the river. They all want to get to the other side of this river, but there is only one boat and this boat can only carry two persons each time. And there must be one person steering the boat from one side to the other side. In the flash game, you can click on them to move them and click the go button to move the boat to the other direction. If the priests are out numbered by the devils on either side of the river, they get killed and the game is over. You can try it in many > ways. Keep all priests alive! Good luck!

  • 代码要求
    • 游戏效果:http://www.flash-game.net/game/2535/priests-and-devils.html
    • 请将游戏中对象做成预制 (Prefab)
    • 在场景控制器 LoadResources 方法中加载并初始化长方形、正方形、球及其色彩代表游戏中的对象
    • 使用 C# 集合类型 有效组织对象
    • 整个游戏仅主摄像机 和一个 Empty 对象, 其他对象必须代码动态生成!!!整个游戏不许出现Find 游戏对象, SendMessage 这类突破程序结构的通讯耦合语句
    • 请使用课件架构图编程,不接受非 MVC 结构程序
    • 注意细节,例如:船未靠岸,牧师与魔鬼上下船运动中,均不能接受用户事件
游戏实现

只介绍框架,源代码放在gitee上

  • 代码:3d-game/作业三/牧师和恶魔

  • 运行视频

  • 游戏获胜截图:
    在这里插入图片描述

  • 游戏中提及的事物
    • Priest
    • Devil
    • Boat
    • Other environmental objects —— WaterRiverbank
  • 玩家动作表(规则表)
    动作参数结果
    启动游戏切换至初始界面
    开始游戏(初始界面)切换至游戏界面
    重新开始(游戏界面重新加载游戏界面资源
    点击对象(游戏界面)对象对象根据当前位置移动
    返回(游戏界面)初始界面
  • MVC 架构

在这里插入图片描述

  • M (Model):代表游戏中所有的游戏对象,它们受各自的Controller控制。Model是游戏中存在的实体。

  • V (View):代表游戏呈现出的界面。主要包括GUI和Click两部分,GUI负责展示游戏结果,Click负责处理用户点击事件。

  • C (Controller):代表游戏中的控制器,分为FitstController(场景控制器)和SSDirector(导演)。由于本游戏只有一个场景,所以导演只用负责退出和暂停;场景控制器需要控制场景中的所有物体。

  • 本游戏中,一共创建7个C#脚本来支持MVC架构。

  1. 游戏对象内部逻辑的实现(ModelController.cs):
  • 陆地 (LandModel)
    • 变量landSign:区分出发点和目的地;
    • Vector3数组:存储角色的位置,共6个位置;
    • RoleMode数组:存储角色的信息,共6个角色;
    • 成员函数:更改成员变量,实现角色的上船和上岸动作。
  • 船(BoatModel)
    • Move对象和Click对象:被点击和移动;
    • 变量boatSign:记录移动方向;
    • Vector3数组startPos和endPos:保存角色的位置;
    • RoleModel数组roles:保存角色的信息;
    • 成员函数:移动和支持角色上船以及上岸动作。
  • 角色/牧师和魔鬼(RoleMode)
    • 变量roleSign,onBoat,landSign:标记身份,是否在船上,在哪块陆地上;
    • Move和Click:角色的移动和被点击事件处理;
    • 其他成员函数:例如状态设置set,移动move等。
  1. 控制类的实现
    (SSDirect.cs/Interfaces.cs/FirstController.cs/MoveController.cs/ClickController.cs):
  • SSDirect.cs 使用单例模式,掌控全局;

    • 写一个单例模式即可。
  • FirstController.cs 用于控制场景Scene;

    • 其中具有之前的模型;
      也要包含Interface中所有的成员函数
  • Interfaces.cs 给FirstController.cs提供接口的,规范FirstController.cs的内容;

    • ISceneController提供场景接口;
    • IUserAction提供用户动作接口。
  • MoveController.cs 是用来控制物体的移动功能;

  • ClickController.cs 是用来控制物体被点击的动作。

  1. GUI 类
  • 实现UserGUI.cs:
    主要绘制文本框和按钮即可,游戏对象不通过GUI展现。
    变量sign:标记游戏的胜负;
    按钮 restart :实现重新开始;
    文本框 gametext :公布游戏结果。

参考:
Assets中其他的部分是直接copy师兄师的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值