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

目录
  • 一、前言
  • 二、游戏开发知识储备
    • 2-1技术栈
  • 三、休闲类游戏《2048》开发实战
    • 3-1玩法概述
    • 3-2实现分析
    • 3-3搭建场景
    • 3-4实现代码

一、前言

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

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

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

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

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

二、游戏开发知识储备

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

2-1技术栈

Unity3D安装

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

分享 几个下载链接:

Unity3D中国版官网

Unity3D国际版官网

Unity3D下载链接

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

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

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,则游戏胜利:

3-2实现分析

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

以向左移动为例:

可以看到移动后的规则:

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

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

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

3-3搭建场景

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

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

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

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

分割后:

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

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

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

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

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

将场景中的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卡槽中:

运行程序:

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

修改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);
                            }
                        }
                    }
                }
            }
        }
    }

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

到这一步,我们就完成了《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》游戏就已经完成了,愉快的玩耍吧。

以上就是Unity游戏开发之2048游戏的实现的详细内容,更多关于Unity2048游戏的资料请关注我们其它相关文章!

(0)

相关推荐

  • Unity游戏开发之射击小游戏的实现

    目录 前言 游戏画面展示 游戏代码解析 游戏打包 总结 前言 人们一直都说学习和玩游戏不能兼顾,那我们就来边学习怎样制作游戏,边玩游戏 不就兼得了嘛~ 我可真是一个小天才呢~ 所以本篇文章为大家带来一个 横版2D射击小游戏,游戏制作超级简单,玩法一学就会, 一起来看看吧! 游戏画面展示 这款小游戏只用了两个UI界面,一个是菜单界面,另一个是战斗界面 菜单界面有三种模式,分别是一般.困难和地狱 战斗界面就是很简单的从两边刷野怪,然后主角开枪打死他们 UI搭建很简单,只有一张背景图使用Image,加

  • Unity2D实现游戏回旋镖

    本文实例为大家分享了Unity2D游戏回旋镖实现的具体代码,供大家参考,具体内容如下 以下我举出2种同使用情况的回旋镖 那么回旋镖需要怎么做呢? 任务清单如下 回旋镖会自我旋转 回旋镖达到一定距离会飞回来 回旋镖对敌人造成伤害 回旋镖会飞回玩家手里 带着这些任务我们来依次实现这两种情况的回旋镖吧 1.在2D平面游戏上的回旋镖 实现一个丢出回旋镖后,会缓慢减速,然后再直接收回手里,碰到怪马上返回的效果 先创建一个回旋镖实体,并在上面添加如下脚本 public float Speedrotate;

  • Unity3D实现甜品消消乐游戏

    目录 前言 项目效果展示 项目概况 素材展示 场景展示 场景元素 玩法介绍 版本说明 项目源码 前言 解释: 之前用的ScreenToGif录屏,因为上传的.gif最大不超过5MB,所以做了不少删帧和色彩弱化等处理,这才导致色彩看上去不是很舒服,不要盯着它看太久,不然会有点难受... 由于使用的素材是现成的,没有花时间精力去扒,所以细节方面可能不是做的很好. 说明: 这次的甜品消消乐虽然看上去好像挺简单普通的,但是相对于之前的坦克大战,某种程度上已然提升难度了,归类到了算法类层的游戏. 拉到最后

  • 用Python手把手教你实现2048小游戏

    一.开发环境 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块. 二.环境搭建 安装Python并添加到环境变量,pip安装需要的相关模块即可. 三.原理介绍 "使用方向键移动方块,两个数字相同的方块撞在一起后,将会合并为一个数字是原来两倍的新方块.游戏的时候尽可能多地合并这些数字方块就行了." 大概了解了游戏规则之后,我们就可以开始写这个游戏啦~首先,进行一下游戏初始化操作并播放一首自己喜欢的游戏背景音乐: # 游戏初始化 pygame.i

  • java实现2048小游戏(含注释)

    本文实例为大家分享了java实现2048小游戏的具体代码,供大家参考,具体内容如下 实现文件 APP.java import javax.swing.*; public class APP { public static void main(String[] args) { new MyFrame(); } } 类文件 import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionList

  • 基于Unity3D实现3D迷宫小游戏的示例代码

    目录 一.前言 二.构思 三.正式开发 3-1.搭建场景 3-2.设置出入口 3-3.添加角色 3-4.实现角色移动 3-5.出入口逻辑 四.总结 一.前言 闲来无事,从零开始整个<3D迷宫>小游戏. 本篇文章会详细介绍构思.实现思路,希望可以帮助到有缘人. 二.构思 首先,要实现一个小游戏,心里肯定要有一个大概的想法,然后就是将想法完善起来. 我的想法就是一个用立体的墙搭建的迷宫,然后控制人物在迷宫中移动,最后找到出口,就这么简单. 当然,这是一个雏形,比如可以加点音效.背景.关卡.解密等.

  • 用C语言实现2048游戏

    本文实例为大家分享了用C语言实现2048游戏的具体代码,供大家参考,具体内容如下 我遇到的几个问题: 问题1:如何显示? system("clear");//清屏 每次发生变化就清屏一次,再把内容打印出来 问题2:怎么用键盘控制? w,s,a,d-->上下左右 system("stty -icanon");//关闭缓冲区,输入字符无需回车直接接受 问题3:随机位置? 用srand()与rand()产生随机数(x,y),再判断位置(x,y)是否为空格,不是空格就

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

    目录 一.前言 二.游戏开发知识储备 2-1技术栈 三.休闲类游戏<2048>开发实战 3-1玩法概述 3-2实现分析 3-3搭建场景 3-4实现代码 一.前言 写今天这篇文章的缘由,其实是来自于前段时间和粉丝的一个聊天,最近他打算参加游戏创作大赛,问我需要准备学习什么知识,以及参加比赛的注意事项一类: 我相信因为热爱游戏而前来投身于U3D学习的粉丝想来不是少数,兴趣可以驱动学习,在完善自己心爱游戏的过程中,要不断的去学习,不断的提高自己. 而参与游戏设计比赛,更是提高自身技术实力.增长眼界见

  • Android 游戏开发之Canvas画布的介绍及方法

    Canvas,在英语中,这个单词的意思是帆布.在Android中,则把Canvas当做画布,只要我们借助设置好的画笔(Paint类)就可以在画布上绘制我们想要的任何东西:另外它也是显示位图(Bitmap类)的核心类.随用户的喜好,Canvas还可设置一些关于画布的属性,比如,画布的颜色.尺寸等.Canvas提供了如下一些方法:    Canvas(): 创建一个空的画布,可以使用setBitmap()方法来设置绘制具体的画布.    Canvas(Bitmap bitmap): 以bitmap对

  • 用C语言完整实现2048游戏

    目录 前言 一.游戏思路 二.游戏框架 1.菜单界面 2.游戏主体 1.初始化界面: 2.随机生成初始数字 3.实现移动 4.增加新数字 5.判定胜负 6.游戏函数 三.游戏运行 四.所有代码 总结 前言 游戏规则:游戏开始,在4x4的棋盘上随机两个方块出现数字2,通过方向键控制所有方块向同一个方向移动,两个相同数字方块撞在一起之后合并成为他们的和.每次移动,棋盘上还会在一个随机位置增加一个数字2或者数字4,当最终得到一个"2048"的方块就算胜利了. 简单吧?简单--个鬼啊,我以前玩

  • javascript实现2048游戏示例

    原生javascript代码写的2048游戏.建议在谷歌浏览器下跑. 2048.html 复制代码 代码如下: <!DOCTYPE><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>2048

  • 微信公众平台开发实现2048游戏的方法

    本文实例讲述了微信公众平台开发实现2048游戏的方法.分享给大家供大家参考.具体如下: 一.2048游戏概述 <2048>是比较流行的一款数字游戏.原版2048首先在github上发布,原作者是Gabriele Cirulli.它是基于<1024>和<小3传奇>的玩法开发而成的新型数字游戏 . 随后2048便出现各种版本,走各大平台.由Ketchapp公司移植到IOS的版本最为火热,现在约有1000万下载,其名字跟原版一模一样.衍生版中最出名的是<2048六边形&

  • win32 api实现2048游戏示例

    自学的win32编程,写了一个win32 API版2048,自己摸索着写的,按上下左右箭头开始游戏 复制代码 代码如下: #include <windows.h>#include <stdlib.h>#include <stdio.h>#include <ctime>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//全局操作数组int arr[4][4] = { { 0, 0, 0, 0 }, {

  • lua+love2d制作的2048游戏

    使用lua和love2d编写的pc版2048游戏,适用于linux和windows平台.依赖love2d游戏引擎,love2d需0.9及以上版本. core.lua 复制代码 代码如下: core = {} core.block = {} core.score = 0 core.best = 0 love.filesystem.setIdentity("2048") local function get_best()     if not love.filesystem.exists(

  • java实现的2048游戏完整实例

    本文实例讲述了java实现的2048游戏.分享给大家供大家参考,具体如下: 先来看看运行效果: 具体代码如下: package awtDemo; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; @SuppressWarnings("serial") public class Game2048 extends JApplet{ @

  • 简单实现C语言2048游戏

    本文实例为大家分享了C语言2048游戏的具体代码,供大家参考,具体内容如下 /*2048*/ #include<stdio.h> #include<conio.h> #include<stdlib.h> #include<time.h> //全局变量 int x[4][4]={0}; int score=0; int can_move; int empty() { int i,j; int n=0; for(i=0;i<4;i++) { for(j=0

  • 200行python代码实现2048游戏

    Python实战系列用于记录实战项目中的思路,代码实现,出现的问题与解决方案以及可行的改进方向 本文为第2篇–200行Python代码实现2048 一.分析与函数设计 1.1 游戏玩法 2048这款游戏的玩法很简单,每次可以选择上下左右滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢.相撞时会相加.(介绍来自百度百科) 1.2 函数设计 _init _() 初始化4*4游戏地图,分数等游戏基本数据 is_gameover() 判

随机推荐