3D游戏编程与设计-井字棋

3D游戏编程与设计-井字棋

A. 简答题

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

① 游戏对象

游戏对象是在游戏中真实存在一个物体

是可以进行选中操作的对象

一个能够容纳实现实际功能的组件

② 资源

是对游戏对象的一个修饰

指的是在游戏中可能用到的各种东西

比如模型、声音文件、贴图文件等等

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

资源的目录组织结构基本包括

Prefabs预设,resources动态加载的资源文件

Scenes场景文件,Scenes场景文件

Scripts脚本代码文件,Sounds音效文件,Textures所有的贴图等等

而游戏对象树类似于多个父子继承关系,一个游戏对象往往是包括了多个子对象

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

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

public class NewBehaviourScript1 : MonoBehaviour {

    void Awake()
    {
        Debug.Log("Awake!");
    }
    void Start()
    {
        Debug.Log("Start!");
    }

    void Update()
    {
        Debug.Log("Update!");
    }
    void FixedUpdate()
    {
        Debug.Log("FixedUpdate!");
    }
    void LateUpdate()
    {
        Debug.Log("LateUpdate!");
    }
    void Reset()
    {
        Debug.Log("Reset!");
    }
    void OnGUI()
    {
        Debug.Log("onGUI!");
    }
    void OnDisable()
    {
        Debug.Log("onDisable!");
    }
    void OnDestroy()
    {
        Debug.Log("onDestroy!");
    }
}

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

① 分别翻译官方对三个对象的描述(Description)

GameObject: 游戏中的每个对象都是一个游戏对象(GameObject)。然而,游戏对象(GameObjects)本身不做任何事情。它们需要特殊属性(special properties)才能成为一个角色、一种环境或者一种特殊效果。

Transform:变换(Transforms)是每个游戏对象(GameObject)的关键组件(Component)。它们决定游戏对象 (GameObject)的位置、旋转方式及缩放。

Reset:在游戏中,组件(Components)就是对象和行为的螺栓与螺母,它们是每个游戏对象 (GameObject)的功能零件。

② 描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件

table 的对象是GameObject

第一个选择框是 activeSelf属性

第二个选择框是Transform属性

第三个选择框是Mesh Filter筛网过滤器属性

第四个选择框是Box Collider属性

第五个选择框是Mesh Renderer筛网渲染器属性

第六个选择框是Default-Material属性。

③ 用 UML 图描述三者的关系

在这里插入图片描述


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

① 预设(Prefabs)有什么好处?

预设是一个非常容易复用的类模板

可以迅速方便创建大量相同属性的对象

好处是操作简单,代码量少,减少出错概率

② 预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?

预设可以使修改的复杂度降低

一旦需要修改所有相同属性的对象,只需要修改预设即可

所有通过预设实例化的对象都会做出相应变化

而克隆只是复制一个一模一样的对象

这个对象独立于原来的对象

在修改的过程中不会影响原有的对象

这样不方便整体改动

③ 制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象
void Start()
{
    Debug.Log("Start!");
    GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    cube.name = "a cube";
    cube.transform.position = new Vector3(0, 1, 2);
    cube.transform.parent = this.transform;
}


B. 井字棋的设计

1. 核心脚本

变量

public Texture2D img1;//棋子图片
public Texture2D img2;//同上
public Texture2D imgBack;//背景图片
private int player;//用奇偶决定当前是哪个玩家下棋
private int result;//胜负结果
private int [,] matrix2D;//棋盘
private int [] repent;//记录上一步棋子,用来悔棋



Start函数:调用Reset函数

void Start()
{
	Reset();
}



Reset函数:重启

void Reset()
{
	player = 0;
	result = 0;
	matrix2D = new int [3,3]
	{
		{0,0,0},
		{0,0,0},
		{0,0,0}
	};
	repent = new int [2] {0,0};
}



Repent函数:悔棋操作

void Repent()
{
	player ++;//+1和-1都一样
	matrix2D[repent[0],repent[1]] = 0;
}



check函数:检测是否有玩家胜出

int check()
{
	for(int i = 0;i < 3;i ++)
	{
		if(matrix2D[i,0] == matrix2D[i,1] && matrix2D[i,1]== matrix2D[i,2] && matrix2D[i,0] != 0)
			return matrix2D[i,0];
		if(matrix2D[0,i] == matrix2D[1,i] && matrix2D[1,i]== matrix2D[2,i] && matrix2D[0,i] != 0)
			return matrix2D[0,i];
	}
	if(matrix2D[0,0] == matrix2D[1,1] && matrix2D[1,1] ==matrix2D[2,2]) 
		return matrix2D[1,1];
	if(matrix2D[0,2] == matrix2D[1,1] && matrix2D[1,1] ==matrix2D[2,0]) 
		return matrix2D[1,1];
	return 0;
}



OnGUI函数:UI界面

void OnGUI()
{

	GUI.Label(new Rect(600,300,150,150),"");
	if (GUI.Button(new Rect(600, 0, 150, 150), "restart"))
		Reset();
	if ( result == 0 && GUI.Button(new Rect(600, 150, 150, 150), "repent"))
		Repent();
	else 
	;
	GUIStyle fontStyle = new GUIStyle();  
    fontStyle.normal.background = null;   
    fontStyle.normal.textColor= new Color(1, 1, 1);    
    fontStyle.fontSize = 15;   
	
	for(int i = 0;i < 3;i ++ )
	{
		for(int j = 0;j < 3;++ j)
		{
			if(matrix2D[i,j] == 1)
				GUI.Button(new Rect(150*i, 150*j, 150, 150), img1);
			else if(matrix2D[i,j] == 2)
				GUI.Button(new Rect(150*i, 150*j, 150, 150), img2);
			else if(result != 0)
			{
				if(GUI.Button(new Rect(150*i, 150*j, 150, 150), imgBack))
					;
			}
			else
			{
				if(GUI.Button(new Rect(150*i, 150*j, 150, 150), imgBack))
				{
					matrix2D[i,j] = 1 + player % 2;
					repent[0] = i; 	repent[1] = j;
					result = check();
					player ++;
				}
			}
		}
	} 
	if (result == 1) 
	{    
		GUI.Label (new Rect (600, 300, 150, 150), "Player1 wins!", fontStyle);    
	} 
	else if (result == 2) 
	{    
		GUI.Label (new Rect (600, 300, 150, 150), "Player2 wins!", fontStyle);    
	} 
	else 
	{
		GUI.Label (new Rect (600, 300, 150, 150), "Playing...", fontStyle);
	} 
}



完整脚本代码:

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

public class UI : MonoBehaviour
{
	public Texture2D img1;
	public Texture2D img2;
	public Texture2D imgBack;
	private int player;
	private int result;
	private int [,] matrix2D;
	private int [] repent;
	
	void OnGUI()
    {
		
		GUI.Label(new Rect(600,300,150,150),"");
		if (GUI.Button(new Rect(600, 0, 150, 150), "restart"))
			Reset();
		if ( result == 0 && GUI.Button(new Rect(600, 150, 150, 150), "repent"))
			Repent();
		else 
			;
		GUIStyle fontStyle = new GUIStyle();  
        fontStyle.normal.background = null;   
        fontStyle.normal.textColor= new Color(1, 1, 1);    
        fontStyle.fontSize = 15;   

		for(int i = 0;i < 3;i ++ )
		{
			for(int j = 0;j < 3;++ j)
			{
				if(matrix2D[i,j] == 1)
					GUI.Button(new Rect(150*i, 150*j, 150, 150), img1);
				else if(matrix2D[i,j] == 2)
					GUI.Button(new Rect(150*i, 150*j, 150, 150), img2);
				else if(result != 0)
				{
					if(GUI.Button(new Rect(150*i, 150*j, 150, 150), imgBack))
						;
				}
				else
				{
					if(GUI.Button(new Rect(150*i, 150*j, 150, 150), imgBack))
					{
						
						matrix2D[i,j] = 1 + player % 2;
						repent[0] = i; 	repent[1] = j;
						result = check();
						player ++;
					}
				}
			}
		} 
		if (result == 1) 
		{    
			GUI.Label (new Rect (600, 300, 150, 150), "Player1 wins!", fontStyle);    
		} 
		else if (result == 2) 
		{    
			GUI.Label (new Rect (600, 300, 150, 150), "Player2 wins!", fontStyle);    
		} 
		else 
		{
			GUI.Label (new Rect (600, 300, 150, 150), "Playing...", fontStyle);
		} 
    }

    void Start()
    {
		Reset();
		
    }

	void Reset()
	{
		player = 0;
		result = 0;

		matrix2D = new int [3,3]
		{
			{0,0,0},
			{0,0,0},
			{0,0,0}
		};
		repent = new int [2] {0,0};
	
	}

	void Repent()
	{
		player ++;
		matrix2D[repent[0],repent[1]] = 0;
	}
	
	int check()
	{
		for(int i = 0;i < 3;i ++)
		{
			if(matrix2D[i,0] == matrix2D[i,1] && matrix2D[i,1]== matrix2D[i,2] && matrix2D[i,0] != 0)
				return matrix2D[i,0];
			if(matrix2D[0,i] == matrix2D[1,i] && matrix2D[1,i]== matrix2D[2,i] && matrix2D[0,i] != 0)
				return matrix2D[0,i];
		}
		if(matrix2D[0,0] == matrix2D[1,1] && matrix2D[1,1] ==matrix2D[2,2]) 
			return matrix2D[1,1];
		if(matrix2D[0,2] == matrix2D[1,1] && matrix2D[1,1] ==matrix2D[2,0]) 
			return matrix2D[1,1];
		return 0;
	}

    void Update(){
        
    }
}

脚本挂在创建的一个Empty游戏对象。

2. 棋子与背景图片

棋子1号
棋子1



棋子2号
棋子2



背景图片
背景


挂在脚本位置
描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值