Unity游戏开发之2048游戏的实现

作者:恬静的小魔龙 时间:2023-04-19 00:11:33 

一、前言

写今天这篇文章的缘由,其实是来自于前段时间和粉丝的一个聊天,最近他打算参加游戏创作大赛,问我需要准备学习什么知识,以及参加比赛的注意事项一类:

Unity游戏开发之2048游戏的实现

我相信因为热爱游戏而前来投身于U3D学习的粉丝想来不是少数,兴趣可以驱动学习,在完善自己心爱游戏的过程中,要不断的去学习,不断的提高自己。

而参与游戏设计比赛,更是提高自身技术实力、增长眼界见识的优秀途径,在此途中也能遇见不少志同道合的好朋友。

那今天就借此简单的聊一下,制作一个简单游戏需要具备哪些技术栈,以及参加这类比赛需要的知识基础。

并且,还有休闲类游戏《2048》的实战开发内容。

二、游戏开发知识储备

接下来就聊一下做一个游戏需要具备哪些技术栈, 因为只是面对“做出游戏”这个特定需求,所以有些技术没有列举出来,在开发中遇到可以再学习。

2-1技术栈

Unity3D安装

首先,学习Unity3D你要安装Unity3D编辑器吧,激活Unity Hub许可证。

分享 几个下载链接:

Unity3D中国版官网

Unity3D国际版官网

Unity3D下载链接

当然,比较推荐是用Unity Hub下载安装:

Unity游戏开发之2048游戏的实现

安装后激活许可证,这个网上教程比较多,这里就不赘述了:

Unity游戏开发之2048游戏的实现

Unity3D编辑器布局学习

学习Unity3D编辑器,要先熟悉Unity编辑器的布局,比如菜单栏,工具栏在什么位置:

Unity入门组件学习

Unity的特色就是面向组件编程,所以对于组件的熟悉是基本的要求。

比较常用的组件有:

Audio组

  • AudioSource

  • AudioListener

Effects组

  • ParticleSystem

  • LineRenderer

  • TrailRenderer

Event组

  • EventSystem

  • EventTrigger

  • GraphicRaycaster

Layout组

  • RectTransform

  • Canvas

  • CanvasGroup

  • CanvasScaler

  • AspectRatioFitter

  • ContentSizeFitter

  • GridLayoutGroup

  • HorizontalLayoutGroup

  • VerticleLayoutGroup

  • LayoutElement

Mesh组

  • MeshFilter

  • MeshRenderer

  • SkinnedMeshRenderer

  • TextMeshPro-Text

Miscellaneous组

  • Animator

  • Animation

Nevigation组

  • NavMeshAgent

  • NavMeshObstacle

Physics2D组

  • Rigidbody2D

  • BoxCollider2D

  • CapsuleCollider2D

  • CircleCollider2D

  • CompositeCollider2D

  • EdgeCollider2D

Physics组

  • Rigidbody

  • BoxCollider

  • CapsuleCollider

  • SphereCollider

  • CharacterController

  • TerrainCollider

Rendering组

  • Camera

  • CanvasRenderer

  • SpriteRenderer

  • Skybox

  • SortingGroup

  • Light

组件比较多,但是不需要全部学习,只需要在用到的时候查看一下Unity3D手册即可:

Unity3D中文手册https://docs.unity.cn/cn/current/Manual/index.html

C#语言基础

Unity3D的脚本语言是C#,随意要做好Unity3D开发,C#编程语言肯定要学的。

最基本的面向对象思想,数据类型、流程控制、数组、函数都要有一定的了解。

Unity3D-UGUI

UGUI是Unity3D的UI系统,可以用UGUi搭建界面,然后很多的用户交互逻辑都是在UI上完成的,所以学好UGUI是很有必要的,下面就来看一下UGUI的基本组件:

  • Text

  • Image

  • RawImage

  • Button

  • Toggle

  • Slider

  • Scrollbar

  • Dropdown

  • InputField

  • Canvas

  • Panel

  • ScrollView

数据结构

数据结构是一种具有一定逻辑关系,在计算机中应用某种存储结构,并且封装了相应操作的数据元素的集合。

简单点说就是专门用于数据存储和检索的类。

因为做游戏开发或者其他项目都会用到对数据的操作,而数据结构就是专门用于数据存储和检索的类。

常见的数据结构有:

  • 列表List

  • 数组Array

  • 字典Dictionary

  • 栈Stack

  • 队列Queue

总结的技术栈看着字没有那么多,但是内容还是很多的,比如说Unity3D的组件、C#脚本语言、UGUI系统,每一块拿出来都是很多的内容。

三、休闲类游戏《2048》开发实战

3-1玩法概述

开局是一个4X4棋盘,棋盘中随机出现两个数字,出现的数字为2或4。

玩家通过选择上下左右四个反向,若玩家选择的方向上有相同的数字则合并,若选择的反向上没有相同的数字但是有空位则移动,可以移动的同时合并,但是不可以连续合并。

若棋盘被数字填满,无法进行移动或合并,则游戏失败。

如果棋盘出现2048,则游戏胜利:

Unity游戏开发之2048游戏的实现

3-2实现分析

根据规则,来分析一下游戏的实现。

以向左移动为例:

Unity游戏开发之2048游戏的实现

可以看到移动后的规则:

相邻的元素值相同则合并,然后末尾补上空元素

开头或中间有空元素就移动到末尾

只合并一次,不会多次合并

3-3搭建场景

(1)新建项目我用的Unity 2019.4.7f1版本,模板选择2D,设置项目名称和位置:

Unity游戏开发之2048游戏的实现

(2)将图片另存为,然后导入到项目中:

Unity游戏开发之2048游戏的实现

(3)在Inspector视图中导入设置:

Unity游戏开发之2048游戏的实现

(4)分割图片,点击Sprite Editor后,会出现分割窗口,然后点击Slice,选择Grid By Cell Count,点击Apply:

Unity游戏开发之2048游戏的实现

分割后:

Unity游戏开发之2048游戏的实现

(5)切完后,把图集放到Resources文件夹中,没有就新建一个,Resources文件夹在Unity中有特殊作用,可以通过脚本Resources类进行访问。

Unity游戏开发之2048游戏的实现

PS:注意图集的名字2048,稍后代码会用到。

接着将2048_0拖入场景中,重命名为BG,设置排序层Order inLayer为-1,这样背景就总是显示在最下面了:

Unity游戏开发之2048游戏的实现

将BG拖入Project视图,做成预制体:

Unity游戏开发之2048游戏的实现

同样的操作,将2048_1拖入场景,然后重命名为Card,设置排序层为0,然后做成预制体:

Unity游戏开发之2048游戏的实现

将场景中的BG和Card对象删除,我们将在后面使用实例化新建出来。

至此,我们的场景就搭建完成了,下面进行代码的编写。

3-4实现代码

(1)首先,我们需要创建16个小方格作为背景,新建脚本GameManager.cs,双击打开脚本,编写代码:

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

public class GameManager : MonoBehaviour
{
   public GameObject bgSprite;//背景卡片
   private Vector2 BeginPos = new Vector2(-1.5f, 1.5f);//差不多在屏幕中间
   private float OffsetX = 1.1f;//xy 加个0.1 有个间隙
   private float OffsetY = 1.1f;

void Start()
   {
       CreateBG();
   }

void CreateBG()
   {
       GameObject BG = new GameObject("BG");//创建空游戏对象作为背景预制体
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               Vector2 newPos = new Vector2(BeginPos.x + j * OffsetX, BeginPos.y - i * OffsetY);
               Instantiate(bgSprite, newPos, Quaternion.identity, BG.transform);
           }
       }
   }
}

将脚本附给Main Camera对象,然后将预制体BG拖到Card脚本组件的BgSprite卡槽中:

Unity游戏开发之2048游戏的实现

运行程序:

Unity游戏开发之2048游戏的实现

(2)接下来创建一个Card.cs脚本,主要用来管理创建的Card对象,找到Project视图中的Card对象,将Card.cs脚本附加上去:

Unity游戏开发之2048游戏的实现

修改Card.cs脚本:

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

public class Card : MonoBehaviour
{
   public Sprite[] CardSprites;//读取图集中所有切片
   private string fileName = "2048";//图集的名字
   public int _currentIndex = 0;//当前卡片的显示编号

void Awake()
   {
       CardSprites = Resources.LoadAll<Sprite>(fileName);
   }

//根据卡片编号修改SpriteRendere,从而改变卡片的数值
   public void Generate(int index)
   {
       _currentIndex = index;
       GetComponent<SpriteRenderer>().sprite = CardSprites[_currentIndex];
   }

//合并卡片的逻辑
   public void Merge()
   {
       _currentIndex++;
       GetComponent<SpriteRenderer>().sprite = CardSprites[_currentIndex];
   }
}

(3)接下来修改GameManager.cs脚本,双击打开脚本,修改代码:

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

public class GameManager : MonoBehaviour
{
   public GameObject card;//卡片对象
   private GameObject[,] cardList = new GameObject[4, 4];//卡片游戏对象对应的棋盘格子
   private int CardNum = 0;//棋盘格子的卡片计数,用于满格后重新开始游戏

void Start()
   {
       CreateBG();
       CreateCard();
   }

void Update()
   {
       if (Input.GetKeyDown(KeyCode.W))//上
       {
           MoveUp();
           CreateCard();
       }
       if (Input.GetKeyDown(KeyCode.S))//下
       {
           MoveUp();
           MoveDown();
       }
       if (Input.GetKeyDown(KeyCode.A))//左
       {
           MoveLeft();
           CreateCard();
       }
       if (Input.GetKeyDown(KeyCode.D))//右
       {
           MoveRight();
           CreateCard();
       }
   }

void CreateBG()
   {
       GameObject BG = new GameObject("BG");//创建空游戏对象作为背景预制体
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               Vector2 newPos = new Vector2(BeginPos.x + j * OffsetX, BeginPos.y - i * OffsetY);
               Instantiate(bgSprite, newPos, Quaternion.identity, BG.transform);
           }
       }
   }

void CreateCard()
   {

}

void MoveUp()
   {

}

void MoveDown()
   {

}

void MoveLeft()
   {

}

void MoveRight()
   {

}
}

CreateCard函数的主要实现思路是:

  • 每次申城一个卡片时计算当前数组中的卡牌数,如果大于16则游戏重置

  • 否则随机生成坐标点,判断当前当前坐标是否有卡片,直到找到空余位置,实例化卡片

  • 生成对应数字的卡片

void CreateCard()
   {
       CardNum = 0;
       foreach (var item in cardList)
       {
           if (item)
           {
               CardNum++;
           }
       }
       if (CardNum >= 16)
       {
           ResetGame();
           return;
       }

int X_index, Y_index = 0;
       do
       {
           X_index = Random.Range(0, 4);
           Y_index = Random.Range(0, 4);
       } while (cardList[X_index, Y_index]);
       Vector2 newPos = GetPosVector2(X_index, Y_index);

cardList[X_index, Y_index] = Instantiate(_card, newPos, Quaternion.identity);
       if (Random.Range(0.0f,1.0f)>0.5f)
       {
           cardList[X_index, Y_index].GetComponent<Card>().Generate(1);
       }
       else
       {
           cardList[X_index, Y_index].GetComponent<Card>().Generate(2);
       }
   }

public Vector2 GetPosVector2(int x, int y)
   {
       return new Vector2(BeginPos.x + y * OffsetX, BeginPos.y - x * OffsetY);
   }

void ResetGame()
   {
       foreach (var card in cardList)
       {
           if (card != null)
           {
               Destroy(card);
           }
           cardList = new GameObject[4, 4];
       }
   }

(4)接下来就是响应鼠标输入,然后移动卡片了,以向上移动为例,主要逻辑思路如下:

遍历卡片数组,寻找存在的卡片

寻找到一个存在的卡片,沿着移动方向上每一个格子做判断,看前面是否有卡片,找到离自己最近的卡片做判断

如果与本身卡片数值一直,则进行Card类中的Merge方法进行合并

否则,将卡片移动到该格子的临近格子

向上移动代码实现如下:

void MoveUp()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       x--;//根据方向的不同  x--是向上 x++是向下
                       if (x < 0 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (x >= 0 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x + 1, y] = temp;
                               cardList[x + 1, y].transform.position = GetPosVector2(x + 1, y);
                           }
                       }
                   }
               }
           }
       }
   }

向下移动:

void MoveDown()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       x++;//根据方向的不同  x--是向上 x++是向下
                       if (x > 3 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (x <= 3 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x - 1, y] = temp;
                               cardList[x - 1, y].transform.position = GetPosVector2(x - 1, y);
                           }
                       }
                   }
               }
           }
       }
   }

向左移动:

void MoveLeft()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       y--;//根据方向的不同  x--是向上 x++是向下
                       if (y < 0 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (y >= 0 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x, y + 1] = temp;
                               cardList[x, y + 1].transform.position = GetPosVector2(x, y + 1);
                           }
                       }
                   }
               }
           }
       }
   }

向右移动:

void MoveRight()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       y++;//根据方向的不同  x--是向上 x++是向下
                       if (y > 3 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (y <= 3 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x, y - 1] = temp;
                               cardList[x, y - 1].transform.position = GetPosVector2(x, y - 1);
                           }
                       }
                   }
               }
           }
       }
   }

运行游戏,就可以愉快的玩耍了:

Unity游戏开发之2048游戏的实现

到这一步,我们就完成了《2048》游戏的核心代码实现,但是我们的代码只有满格后重新开始游戏的判断,没有游戏完成的判断,下面加一个游戏成功的代码,继续修改GameManager.cs脚本:

void CreateCard()
   {
       CardNum = 0;
       foreach (var item in cardList)
       {
           if (item)
           {
               CardNum++;
           }
       }
       if (CardNum >= 16)
       {
           ResetGame();
           return;
       }

int X_index, Y_index = 0;
       do
       {
           X_index = Random.Range(0, 4);
           Y_index = Random.Range(0, 4);
       } while (cardList[X_index, Y_index]);
       Vector2 newPos = GetPosVector2(X_index, Y_index);

cardList[X_index, Y_index] = Instantiate(_card, newPos, Quaternion.identity);
       if (Random.Range(0.0f,1.0f)>0.5f)
       {
           cardList[X_index, Y_index].GetComponent<Card>().Generate(1);
       }
       else
       {
           cardList[X_index, Y_index].GetComponent<Card>().Generate(2);
       }
       SucceedGame();
   }
void SucceedGame()
   {
       foreach (var item in cardList)
       {
           if (item.GetComponent<Card>()._currentIndex >= 11)
           {
               Debug.Log("游戏成功");
               break;
           }
       }
       ResetGame();
   }

整体GameManager.cs脚本代码:

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

public class GameManager : MonoBehaviour
{
   public GameObject bgSprite;//背景卡片
   private Vector2 BeginPos = new Vector2(-1.5f, 1.5f);//差不多在屏幕中间
   private float OffsetX = 1.1f;//xy 加个0.1 有个间隙
   private float OffsetY = 1.1f;

public GameObject _card;//卡片对象
   private GameObject[,] cardList = new GameObject[4, 4];//卡片游戏对象对应的棋盘格子
   private int CardNum = 0;//棋盘格子的卡片计数,用于满格后重新开始游戏

void Start()
   {
       CreateBG();
       CreateCard();
       CreateCard();
   }

void Update()
   {
       if (Input.GetKeyDown(KeyCode.W))//上
       {
           MoveUp();
           CreateCard();
       }
       if (Input.GetKeyDown(KeyCode.S))//下
       {
           MoveDown();
           CreateCard();
       }
       if (Input.GetKeyDown(KeyCode.A))//左
       {
           MoveLeft();
           CreateCard();
       }
       if (Input.GetKeyDown(KeyCode.D))//右
       {
           MoveRight();
           CreateCard();
       }
   }

void CreateBG()
   {
       GameObject BG = new GameObject("BG");//创建空游戏对象作为背景预制体
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               Vector2 newPos = new Vector2(BeginPos.x + j * OffsetX, BeginPos.y - i * OffsetY);
               Instantiate(bgSprite, newPos, Quaternion.identity, BG.transform);
           }
       }
   }

void CreateCard()
   {
       CardNum = 0;
       foreach (var item in cardList)
       {
           if (item)
           {
               CardNum++;
           }
       }
       if (CardNum >= 16)
       {
           ResetGame();
           return;
       }

int X_index, Y_index = 0;
       do
       {
           X_index = Random.Range(0, 4);
           Y_index = Random.Range(0, 4);
       } while (cardList[X_index, Y_index]);
       Vector2 newPos = GetPosVector2(X_index, Y_index);

cardList[X_index, Y_index] = Instantiate(_card, newPos, Quaternion.identity);
       if (Random.Range(0.0f,1.0f)>0.5f)
       {
           cardList[X_index, Y_index].GetComponent<Card>().Generate(1);
       }
       else
       {
           cardList[X_index, Y_index].GetComponent<Card>().Generate(2);
       }
       SucceedGame();
   }

public Vector2 GetPosVector2(int x, int y)
   {
       return new Vector2(BeginPos.x + y * OffsetX, BeginPos.y - x * OffsetY);
   }

void ResetGame()
   {
       foreach (var item in cardList)
       {
           if (item != null)
           {
               Destroy(item);
           }
           cardList = new GameObject[4, 4];
       }
   }

void SucceedGame()
   {
       foreach (var item in cardList)
       {
           if (item.GetComponent<Card>()._currentIndex >= 11)
           {
               Debug.Log("游戏成功");
               break;
           }
       }
       ResetGame();
   }

void MoveUp()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       x--;//根据方向的不同  x--是向上 x++是向下
                       if (x < 0 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (x >= 0 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x + 1, y] = temp;
                               cardList[x + 1, y].transform.position = GetPosVector2(x + 1, y);
                           }
                       }
                   }
               }
           }
       }
   }

void MoveDown()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       x++;//根据方向的不同  x--是向上 x++是向下
                       if (x > 3 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (x <= 3 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x - 1, y] = temp;
                               cardList[x - 1, y].transform.position = GetPosVector2(x - 1, y);
                           }
                       }
                   }
               }
           }
       }
   }

void MoveLeft()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       y--;//根据方向的不同  x--是向上 x++是向下
                       if (y < 0 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (y >= 0 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x, y + 1] = temp;
                               cardList[x, y + 1].transform.position = GetPosVector2(x, y + 1);
                           }
                       }
                   }
               }
           }
       }
   }

void MoveRight()
   {
       for (int i = 0; i < 4; i++)
       {
           for (int j = 0; j < 4; j++)
           {
               if (cardList[i, j] != null)//当找到其中的卡片后
               {
                   GameObject temp = cardList[i, j];//保留该卡片的引用
                   int x = i;
                   int y = j;
                   bool isFind = false;//设置查找标识
                   while (!isFind)
                   {
                       y++;//根据方向的不同  x--是向上 x++是向下
                       if (y > 3 || cardList[x, y])//达到边界或找到卡片后
                       {
                           isFind = true;
                           //判断值是否相同,相同的话合并操作
                           if (y <= 3 && cardList[x, y].GetComponent<Card>()._currentIndex == cardList[i, j].GetComponent<Card>()._currentIndex)
                           {
                               cardList[x, y].GetComponent<Card>().Merge();
                               Destroy(cardList[i, j]);
                               cardList[i, j] = null;
                           }
                           else//否则移动即可
                           {
                               cardList[i, j] = null;
                               cardList[x, y - 1] = temp;
                               cardList[x, y - 1].transform.position = GetPosVector2(x, y - 1);
                           }
                       }
                   }
               }
           }
       }
   }
}

至此,我们的《2048》游戏就已经完成了,愉快的玩耍吧。

来源:https://blog.csdn.net/q764424567/article/details/123626745

标签:Unity,2048,游戏
0
投稿

猜你喜欢

  • JavaBean和SpringBean的区别及创建SpringBean方式

    2022-05-23 03:32:14
  • Java 数据结构与算法系列精讲之环形链表

    2023-04-27 22:37:07
  • java并发高的情况下用ThreadLocalRandom来生成随机数

    2022-10-30 12:42:03
  • Java实现将png格式图片转换成jpg格式图片的方法【测试可用】

    2023-09-30 08:00:22
  • android上的一个网络接口和图片缓存框架enif简析

    2022-10-06 07:37:56
  • C#用户定义类型转换详解

    2022-06-07 11:44:32
  • Android系统永不锁屏永不休眠的方法

    2023-03-11 00:06:21
  • Maven安装与配置及Idea配置Maven的全过程

    2023-05-20 01:37:59
  • android自定义View实现简单五子棋游戏

    2022-09-16 14:52:30
  • 两种java实现二分查找的方式

    2023-09-04 05:25:00
  • Java中Thread类详解及常用的方法

    2022-09-29 11:35:44
  • Java基本数据类型(动力节点java学院整理)

    2022-09-26 12:14:13
  • 模拟打印机排队打印效果

    2023-12-13 13:26:22
  • java对象转换String类型的三种方法

    2023-11-09 15:50:59
  • SpringCloud中的Consul详解

    2023-05-26 04:56:41
  • C# 表达式目录树Expression的实现

    2023-04-03 22:57:32
  • Spring AOP实现权限检查的功能

    2023-08-10 06:51:14
  • RocketMQ特性Broker存储事务消息实现

    2022-07-10 20:42:13
  • Maven聚合开发实例详解

    2023-07-14 11:18:12
  • Java中对象的比较操作实例分析

    2023-03-05 03:58:09
  • asp之家 软件编程 m.aspxhome.com