【Unity3D入门教程】Unity3D开发实战之五子棋
前言
經過前面《Unity3D入門教程》系列講解,再加上我們自己的探索,相信大家已經掌握了Unity3D的相關知識和基本方法。本文將使用前面學到的知識,開發一款簡單的五子棋程序。本文用到的東西其實不多,非常簡單。在最后我們會把完整工程的源代碼發布出來,以供初學者參考。先展示一下最后的運行效果吧。
1 準備工作
(1)開發環境:Win10 + Unity5.4.1
(2)圖片素材準備:
黑棋子和白棋子
? ?
棋盤
獲勝提示圖片
2 開發流程
上文提到的素材可以直接下載我們給出的這些圖,也可以自己制作。注意黑白棋子要做成PNG格式,以保證顯示的時候棋子四個角是透明的。將用到的圖片素材導入到工程當中。新建一個場景,創建一個Plane,作為MainCamera的子物體。將棋盤貼圖拖動到Plane上,并且將Plane正面面向攝像機。
再創建四個sphere,作為Plane的子物體,分別命名為LeftTop、RightTop、LeftBottom、RightBottom。然后把他們的MeshRenderer勾選掉。這些球是為了計算棋子落點所設置的,所以需要把它們與棋盤的四個角點對準。
然后我們創建一個chess.cs腳本,綁定到MainCamera上。腳本中包含了所有的功能。需要綁定的一些物體如圖所示。
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;} }運行效果截圖:
小結
本程序實現了五子棋的基本功能,純屬娛樂而作。暫時沒有加入各種UI、網絡模塊等。本程序經過了簡單的測試,沒有什么問題,如果大家在使用的時候發現有什么Bug,請聯系我改正,謝謝。
*************************************************************************************
下面是工程源碼下載地址:
GitHub - zzlyw/Gobang_Tutorial
總結
以上是生活随笔為你收集整理的【Unity3D入门教程】Unity3D开发实战之五子棋的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何让带AV接口的复古老彩电活在当下
- 下一篇: html5ppt介绍,html5介绍.p