unity3d简单游戏教程_3D推荐

unity3d简单游戏教程_3D推荐经过前面《Unity3D入门教程》系列讲解,再加上我们自己的探索,相信大家已经掌握了Unity3D的相关知识和基本方法。本文将使用前面学到的知识,开发一款简单的五子棋程序。本文用到的东西其实不多,非常简单。在最后我们会把完整工程的源代码发布出来,以供初学者参考。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

经过前面《Unity3D入门教程》系列讲解,再加上我们自己的探索,相信大家已经掌握了Unity3D的相关知识和基本方法。本文将使用前面学到的知识,开发一款简单的五子棋程序。本文用到的东西其实不多,非常简单。在最后我们会把完整工程的源代码发布出来,以供初学者参考。先展示一下最后的运行效果吧。

unity3d简单游戏教程_3D推荐

1 准备工作

(1)开发环境:Win10 + Unity5.4.1

(2)图片素材准备:

黑棋子和白棋子

unity3d简单游戏教程_3D推荐   unity3d简单游戏教程_3D推荐

棋盘

unity3d简单游戏教程_3D推荐

获胜提示图片

unity3d简单游戏教程_3D推荐

unity3d简单游戏教程_3D推荐

2 开发流程

上文提到的素材可以直接下载我们给出的这些图,也可以自己制作。注意黑白棋子要做成PNG格式,以保证显示的时候棋子四个角是透明的。将用到的图片素材导入到工程当中。新建一个场景,创建一个Plane,作为MainCamera的子物体。将棋盘贴图拖动到Plane上,并且将Plane正面面向摄像机。

unity3d简单游戏教程_3D推荐

再创建四个sphere,作为Plane的子物体,分别命名为LeftTop、RightTop、LeftBottom、RightBottom。然后把他们的MeshRenderer勾选掉。这些球是为了计算棋子落点所设置的,所以需要把它们与棋盘的四个角点对准。

unity3d简单游戏教程_3D推荐

然后我们创建一个chess.cs脚本,绑定到MainCamera上。脚本中包含了所有的功能。需要绑定的一些物体如图所示。

unity3d简单游戏教程_3D推荐

chess.cs脚本如下:

using UnityEngine;
using System.Collections;

public class chess : MonoBehaviour {

	//四个锚点位置,用于计算棋子落点
	public GameObject LeftTop;
	public GameObject RightTop;
	public GameObject LeftBottom;
	public GameObject RightBottom;
	//主摄像机
	public Camera cam;
	//锚点在屏幕上的映射位置
	Vector3 LTPos;
	Vector3 RTPos;
	Vector3 LBPos;
	Vector3 RBPos;

	Vector3 PointPos;//当前点选的位置
	float gridWidth =1; //棋盘网格宽度
	float gridHeight=1; //棋盘网格高度
	float minGridDis;  //网格宽和高中较小的一个
	Vector2[,] chessPos; //存储棋盘上所有可以落子的位置
	int[,] chessState; //存储棋盘位置上的落子状态
	enum turn {black, white } ;
	turn chessTurn; //落子顺序
	public Texture2D white; //白棋子
	public Texture2D black; //黑棋子
	public Texture2D blackWin; //白子获胜提示图
	public Texture2D whiteWin; //黑子获胜提示图
	int winner = 0; //获胜方,1为黑子,-1为白子
	bool isPlaying = true; //是否处于对弈状态
	void Start () {
		chessPos = new Vector2[15, 15];
		chessState =new int[15,15];
		chessTurn = turn.black;

	}

	void Update () {

		//计算锚点位置
		LTPos = cam.WorldToScreenPoint(LeftTop.transform.position);
		RTPos = cam.WorldToScreenPoint(RightTop.transform.position);
		LBPos = cam.WorldToScreenPoint(LeftBottom.transform.position);
		RBPos = cam.WorldToScreenPoint(RightBottom.transform.position);
		//计算网格宽度
		gridWidth = (RTPos.x - LTPos.x) / 14;
		gridHeight = (LTPos.y - LBPos.y) / 14;
		minGridDis = gridWidth < gridHeight ? gridWidth : gridHeight;
		//计算落子点位置
		for (int i = 0; i < 15; i++)
		{
			for (int j = 0; j < 15; j++)
			{
				chessPos[i, j] = new Vector2(LBPos.x + gridWidth * i, LBPos.y + gridHeight * j);
			}
		}
		//检测鼠标输入并确定落子状态
		if (isPlaying && Input.GetMouseButtonDown(0))
		{
			PointPos = Input.mousePosition;
			for (int i = 0; i < 15; i++)
			{
				for (int j = 0; j < 15; j++)
				{   
					//找到最接近鼠标点击位置的落子点,如果空则落子
					if (Dis(PointPos, chessPos[i, j]) < minGridDis / 2 && chessState[i,j]==0)
					{
						//根据下棋顺序确定落子颜色
						chessState[i, j] = chessTurn == turn.black ? 1 : -1;
						//落子成功,更换下棋顺序
						chessTurn = chessTurn == turn.black ? turn.white : turn.black;                        
					}
				}
			}
			//调用判断函数,确定是否有获胜方
			int re = result();
			if (re == 1)
			{
				Debug.Log("黑棋胜");
				winner = 1;
				isPlaying = false;
			}
			else if(re==-1)
			{
				Debug.Log("白棋胜");
				winner = -1;
				isPlaying = false;
			}            
		}
		//按下空格重新开始游戏
		if (Input.GetKeyDown(KeyCode.Space))
		{
			for (int i = 0; i < 15; i++)
			{
				for (int j = 0; j < 15; j++)
				{
					chessState[i, j] = 0;
				}
			}
			isPlaying = true;
			chessTurn = turn.black;
			winner = 0;
		}     
	}
	//计算平面距离函数
	float Dis(Vector3 mPos, Vector2 gridPos)
	{
		return Mathf.Sqrt(Mathf.Pow(mPos.x - gridPos.x, 2)+ Mathf.Pow(mPos.y - gridPos.y, 2));
	}

	void OnGUI()
	{ 
		//绘制棋子
		for(int i=0;i<15;i++)
		{
			for (int j = 0; j < 15; j++)
			{
				if (chessState[i, j] == 1)
				{
					GUI.DrawTexture(new Rect(chessPos[i,j].x-gridWidth/2, Screen.height-chessPos[i,j].y-gridHeight/2, gridWidth,gridHeight),black);
				}
				if (chessState[i, j] == -1)
				{
					GUI.DrawTexture(new Rect(chessPos[i, j].x - gridWidth / 2, Screen.height - chessPos[i, j].y - gridHeight / 2, gridWidth, gridHeight), white);
				}               
			}
		}
		//根据获胜状态,弹出相应的胜利图片
		if (winner ==  1)
			GUI.DrawTexture(new Rect(Screen.width * 0.25f, Screen.height * 0.25f, Screen.width * 0.5f, Screen.height * 0.25f), blackWin);
		if (winner == -1)
			GUI.DrawTexture(new Rect(Screen.width * 0.25f, Screen.height * 0.25f, Screen.width * 0.5f, Screen.height * 0.25f), whiteWin);

	}
	//检测是够获胜的函数,不含黑棋禁手检测
	int result()
	{
		int flag = 0;
		//如果当前该白棋落子,标定黑棋刚刚下完一步,此时应该判断黑棋是否获胜
		if(chessTurn == turn.white)
		{
			for (int i = 0; i < 11; i++)
			{
				for (int j = 0; j < 15; j++)
				{
					if (j < 4)
					{
						//横向
						if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == 1 && chessState[i + 1, j] == 1 && chessState[i + 2, j] == 1 && chessState[i + 3, j] == 1 && chessState[i + 4, j] == 1)
						{
							flag = 1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j + 1] == 1 && chessState[i + 2, j + 2] == 1 && chessState[i + 3, j + 3] == 1 && chessState[i + 4, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//左斜线
						//if (chessState[i, j] == 1 && chessState[i + 1, j - 1] == 1 && chessState[i + 2, j - 2] == 1 && chessState[i + 3, j - 3] == 1 && chessState[i + 4, j - 4] == 1)
						//{
						//    flag = 1;
						//    return flag;
						//}
					}
					else if (j >= 4 && j < 11)
					{
						//横向
						if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == 1 && chessState[i + 1, j] == 1 && chessState[i + 2, j] == 1 && chessState[i + 3, j] == 1 && chessState[i + 4, j] == 1)
						{
							flag = 1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j + 1] == 1 && chessState[i + 2, j + 2] == 1 && chessState[i + 3, j + 3] == 1 && chessState[i + 4, j + 4] == 1)
						{
							flag = 1;
							return flag;
						}
						//左斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j - 1] == 1 && chessState[i + 2, j - 2] == 1 && chessState[i + 3, j - 3] == 1 && chessState[i + 4, j - 4] == 1)
						{
							flag = 1;
							return flag;
						}
					}
					else
					{
						//横向
						//if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)
						//{
						//    flag = 1;
						//    return flag;
						//}
						//纵向
						if (chessState[i, j] == 1 && chessState[i + 1, j] == 1 && chessState[i + 2, j] == 1 && chessState[i + 3, j] == 1 && chessState[i + 4, j] == 1)
						{
							flag = 1;
							return flag;
						}
						//右斜线
						//if (chessState[i, j] == 1 && chessState[i + 1, j + 1] == 1 && chessState[i + 2, j + 2] == 1 && chessState[i + 3, j + 3] == 1 && chessState[i + 4, j + 4] == 1)
						//{
						//    flag = 1;
						//    return flag;
						//}
						//左斜线
						if (chessState[i, j] == 1 && chessState[i + 1, j - 1] == 1 && chessState[i + 2, j - 2] == 1 && chessState[i + 3, j - 3] == 1 && chessState[i + 4, j - 4] == 1)
						{
							flag = 1;
							return flag;
						}
					}

				}
			}
			for (int i = 11; i < 15; i++) 
			{
				for (int j = 0; j < 11; j++) 
				{
					//只需要判断横向  
					if (chessState[i, j] == 1 && chessState[i, j + 1] == 1 && chessState[i, j + 2] == 1 && chessState[i, j + 3] == 1 && chessState[i, j + 4] == 1)  
					{  
						flag = 1;  
						return flag;  
					}  
				}
			}
		}
		//如果当前该黑棋落子,标定白棋刚刚下完一步,此时应该判断白棋是否获胜
		else if(chessTurn == turn.black)
		{
			for (int i = 0; i < 11; i++)
			{
				for (int j = 0; j < 15; j++)
				{
					if (j < 4)
					{
						//横向
						if (chessState[i, j] == -1 && chessState[i, j + 1] == -1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] == -1)
						{
							flag = -1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == -1 && chessState[i + 1, j] == -1 && chessState[i + 2, j] == -1 && chessState[i + 3, j] == -1 && chessState[i + 4, j] == -1)
						{
							flag = -1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j + 1] == -1 && chessState[i + 2, j + 2] == -1 && chessState[i + 3, j + 3] == -1 && chessState[i + 4, j + 4] == -1)
						{
							flag = -1;
							return flag;
						}
						//左斜线
						//if (chessState[i, j] == -1 && chessState[i + 1, j - 1] == -1 && chessState[i + 2, j - 2] == -1 && chessState[i + 3, j - 3] == -1 && chessState[i + 4, j - 4] == -1)
						//{
						//    flag = -1;
						//    return flag;
						//}
					}
					else if (j >= 4 && j < 11)
					{
						//横向
						if (chessState[i, j] == -1 && chessState[i, j + 1] == -1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] ==- 1)
						{
							flag = -1;
							return flag;
						}
						//纵向
						if (chessState[i, j] == -1 && chessState[i + 1, j] == -1 && chessState[i + 2, j] == -1 && chessState[i + 3, j] == -1 && chessState[i + 4, j] == -1)
						{
							flag = -1;
							return flag;
						}
						//右斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j + 1] == -1 && chessState[i + 2, j + 2] == -1 && chessState[i + 3, j + 3] == -1 && chessState[i + 4, j + 4] == -1)
						{
							flag = -1;
							return flag;
						}
						//左斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j - 1] == -1 && chessState[i + 2, j - 2] == -1 && chessState[i + 3, j - 3] == -1 && chessState[i + 4, j - 4] == -1)
						{
							flag = -1;
							return flag;
						}
					}
					else
					{
						//横向
						//if (chessState[i, j] == -1 && chessState[i, j + 1] ==- 1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] == -1)
						//{
						//    flag = -1;
						//    return flag;
						//}
						//纵向
						if (chessState[i, j] == -1 && chessState[i + 1, j] ==- 1 && chessState[i + 2, j] ==- 1 && chessState[i + 3, j] ==- 1 && chessState[i + 4, j] == -1)
						{
							flag = -1;
							return flag;
						}
						//右斜线
						//if (chessState[i, j] == -1 && chessState[i + 1, j + 1] == -1 && chessState[i + 2, j + 2] == -1 && chessState[i + 3, j + 3] == -1 && chessState[i + 4, j + 4] == -1)
						//{
						//    flag = -1;
						//    return flag;
						//}
						//左斜线
						if (chessState[i, j] == -1 && chessState[i + 1, j - 1] == -1 && chessState[i + 2, j - 2] == -1 && chessState[i + 3, j - 3] == -1 && chessState[i + 4, j - 4] == -1)
						{
							flag = -1;
							return flag;
						}
					}
				}
			}
			for (int i = 11; i < 15; i++) 
			{
				for (int j = 0; j < 11; j++) 
				{
					//只需要判断横向  
					if (chessState[i, j] == -1 && chessState[i, j + 1] == -1 && chessState[i, j + 2] == -1 && chessState[i, j + 3] == -1 && chessState[i, j + 4] == -1)  
					{  
						flag = -1;  
						return flag;  
					}  
				}
			}
		}       
		return flag;
	}    
}

运行效果截图:

unity3d简单游戏教程_3D推荐

unity3d简单游戏教程_3D推荐

小结

本程序实现了五子棋的基本功能,纯属娱乐而作。暂时没有加入各种UI、网络模块等。本程序经过了简单的测试,没有什么问题,如果大家在使用的时候发现有什么Bug,请联系我改正,谢谢。

*************************************************************************************

下面是工程源码下载地址:

GitHub – zzlyw/Gobang_Tutorial

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/169321.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月10日 下午2:36
下一篇 2022年8月10日 下午2:36


相关推荐

  • 面试题总结 —— JAVA高级工程师[通俗易懂]

    面试题总结 —— JAVA高级工程师[通俗易懂]面试题总结——JAVA高级工程师近期考虑换工作的问题,于是投简历面试,面试5家公司的高级Java工程师,有4家给了我offer,想着总结一下面试经验,方便最近正在寻求机会的你们一、无笔试题不知道是不是职位原因还是没遇到,面试时,都不需要做笔试题,而是填张个人信息表格,或者直接面试二、三大框架方面问题1、Spring事务的隔离性,并说说每个隔离性的…

    2022年6月14日
    29
  • SIP服务器介绍

    SIP服务器介绍摘要介绍了 SIP 服务器设备的主要内容 包括 SIP 服务器在网络中的具体位置 SIP 服务器的功能要求 业务要求 协议要求 操作维护与网管 性能和可靠性要求以及电源和环境等通用的技术要求 cs Phontol comprog Phontol com nbsp nbsp nbsp 关键词 SIP 服务器 SIP 网络用户代理 prog Phontol com nbsp nbsp nbsp 1 引言 prog Phontol com nbsp nbsp nbsp 随着近年来 SI

    2026年2月22日
    1
  • Ubuntu 24.04.4 LTS安装千问大模型,应该选择哪个版本?

    Ubuntu 24.04.4 LTS安装千问大模型,应该选择哪个版本?

    2026年3月15日
    2
  • 奈氏曲线的绘制步骤_qpcr扩增曲线是直线

    奈氏曲线的绘制步骤_qpcr扩增曲线是直线本文由@浅墨_毛星云出品,首发于知乎专栏,转载请注明出处文章链接:https://zhuanlan.zhihu.com/p/69380665作为基于物理的渲染(PBR)技术中材质高光质感的决定因素,更先进的法线分布函数(NormalDistributionFunction,NDF)的问世和发展,是PBR能够在游戏和电影工业日益普及的重要…

    2022年8月11日
    8
  • Sobel 边缘检测算子「建议收藏」

    Sobel 边缘检测算子「建议收藏」转自:http://blog.csdn.net/xiaqunfeng123/article/details/17302003Sobel算子是一个离散微分算子(discretedifferent

    2022年7月1日
    29
  • linux单引号双引号反引号_unix和linux的区别

    linux单引号双引号反引号_unix和linux的区别特殊的赋值Shell中可以将数字或字符直接赋予变量,也可以将Linux命令的执行结果赋予变量,如下:(1)$count=9#将数字赋予变量count(2)$name=”ming”#将字符赋予变量name(3)$listc=`ls-la`#将Linux命令赋予listc,listc的值就是该命令的执行结果反引号的作用反引号的作用就是将反引号内的Lin…

    2025年7月27日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号