【爱上乐消消】点消

本文介绍了使用Unity3D 2020.1.1开发的休闲消除游戏《爱上乐消消》。游戏采用自封装的DLFramwork框架,管理音频、UI、数据存储和游戏系统。游戏流程涉及方块生成区和UI部分,UI部分基于DLFramwork。在研发阶段,详细讲解了框架导入、游戏入口、游戏管理类和场景管理类的设计与实现。
摘要由CSDN通过智能技术生成

一.引擎

游戏工程地址在文末

开发:unity3d 2020.1.1
音乐:au
美术:ps

二.游戏流程

游戏

主要分为两个大的部分:
游戏部分:
市面上的方块消除游戏主要分为:
1.方块生成区
UI部分我们统一使用我们自己封装的DLFramwork框架管理!

三.研发阶段

1.导入框架DLFramwork

这个是自己封装的框架!主要作用是封装了一些通用的内容,比如音频系统,ui系统,数据存储系统,游戏系统等等

2.Game游戏入口

在这里插入图片描述
这里我强调一点,我们写代码尽量拥有自己的名称空间,不然多人开发的时候容易乱!我的是DLAM什么意思呢,你们猜猜??(文末有注解)

Game脚本是整个游戏的唯一入口:
Init函数:初始化框架
Onstart函数:通过框架创建游戏

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

namespace DLAM
{
    public class Game : GameBase
    {
        private GameMgr _game;
        public override void _Init()
        {
            SysManager.InitSys();
            SysManager.LoadSys<GameSys>();
            SysManager.LoadSys<FairyGUISys>();
            SysManager.LoadSys<AudioSys>();
            SysManager.LoadSys<EventSys>();
            SysManager.LoadSys<PoolSys>();
        }

        public override void _OnStart()
        {
            _game = SysManager.GetSys<GameSys>().CreatGame<GameMgr>();
        }
    }
}

3.GameMgr游戏管理类

这个类是通过游戏系统创建出来的,所以我继承了GameSys基类和IMgr接口
主要用来管理游戏进程,管理其他的管理器!

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

namespace DLAM
{
    public class GameMgr : IGame
    {
        public SceneMgr SceneMgr;
        public override void _InitGame()
        {
            SceneMgr = new SceneMgr();
            SceneMgr._InitMgr();
        }

        public override void _StartGame()
        {
            SceneMgr._StartMgr();
        }

        public override void _UpdateGame()
        {
           
        }

        public override void _EndGame()
        {
            
        }
    }
}


4.SceneMgr管理所有游戏对象

提供所有游戏对象的生成和访问

using System.Collections;
using System.Collections.Generic;
using DLBASE;
using FairyGUI;
using UnityEngine;

namespace DLAM
{
    public class SceneMgr : IMgr
    {
        private BlockPool _blockPool;
        private GComponent _parent;
        private Block[,] _blocks;
        private Vector3[,] _posarray;

        /// <summary>
        /// 寻路四个方向
        /// </summary>
        private Vector2Int[] _path = new Vector2Int[4]
        {
            new Vector2Int(-1, 0),
            new Vector2Int(1, 0),
            new Vector2Int(0, 1),
            new Vector2Int(0, -1)
        };

        /// <summary>
        /// 下方向寻路
        /// </summary>
        private Vector2Int _downpath = new Vector2Int(0, 1);
        /// <summary>
        /// 左方向寻路
        /// </summary>
        private Vector2Int _leftpath = new Vector2Int(-1, 0);

        public void _InitMgr()
        {
            _blockPool = SysManager.GetSys<PoolSys>().CreatPool<BlockPool>();
            _parent = SysManager.GetSys<GameSys>().GROOT;
            _blocks = new Block[GameConfig.ROW, GameConfig.COLLOW];
            _posarray = new Vector3[GameConfig.ROW, GameConfig.COLLOW];
        }

        public void _StartMgr()
        {
            InitBoard();
        }

        private void InitBoard()
        {
            for (int i = 0; i < GameConfig.ROW; i++)
            {
                for (int j = 0; j < GameConfig.COLLOW; j++)
                {
                    Block block = new Block(_blockPool,_parent,_blocks);
                    Vector3 pos = new Vector3(i * GameConfig.heightdis, j * GameConfig.weidthdis, 0)+GetStartPos();
                    block.Position = pos;
                    block.ID = new Vector2Int(i, j);
                    int type = Random.Range(0, 5);
                    block.Type = type;
                    block.GUID = GameUtlis.GetGUID();
                    block.AddClick(ClickHundler);
                    _blocks[i, j] = block;
                    _posarray[i, j] = pos;
                }
            }
        }

        private void ClickHundler(Block obj)
        {
            List<Block> blocks = new List<Block>();
            blocks.Add(obj);
            DepthFristSearch(obj,ref blocks);
            for (int i = 0; i < blocks.Count; i++)
            {
                blocks[i].DistorySelf();
            }

            DownBoard();
            GameUtlis.Waits(0.5f, () =>
            {
                LeftBoard();
            });
        }

        private void LeftBoard()
        {
            for (int i = 0; i < GameConfig.ROW; i++)
            {
                for (int j = 0; j <GameConfig.COLLOW ; j++)
                {
                    Block block = _blocks[i, j];
                    if (block != null)
                    {
                        Vector2Int path = block.ID;
                        SearchLeftPath(block.ID,ref path);
                        if (block.ID != path)
                        {
                            Vector3 pos = _posarray[path.x,path.y];
                            block.TweenMove(pos);
                            block.ID = path;
                            _blocks[path.x, path.y] = block;
                            _blocks[i, j] = null;
                        }
                    }
                }
            }
        }
        
        /// <summary>
        /// 布局下落
        /// </summary>
        private void DownBoard()
        {
            for (int i = 0; i < GameConfig.ROW; i++)
            {
                for (int j = GameConfig.COLLOW - 1; j >= 0 ; j--)
                {
                    Block block = _blocks[i, j];
                    if (block != null)
                    {
                        Vector2Int path = block.ID;
                        SearchDownPath(block.ID,ref path);
                        if (block.ID != path)
                        {
                            Vector3 pos = _posarray[path.x,path.y];
                            block.TweenMove(pos);
                            block.ID = path;
                            _blocks[path.x, path.y] = block;
                            _blocks[i, j] = null;
                        }
                    }
                }
            }
        }
        
        /// <summary>
        /// 单向深度搜索
        /// </summary>
        private void SearchLeftPath(Vector2Int target,ref Vector2Int path)
        {
            Vector2Int pos = _leftpath + target;
            if (pos.x > GameConfig.ROW - 1 || pos.x < 0 )
            {
                Debug.Log("越界");
                path = target;
                return;
            }

            Block block = _blocks[pos.x, pos.y];
            if (block == null)
            {
                path = pos;
                SearchLeftPath(pos,ref path);
            }
        }

        /// <summary>
        /// 单向深度搜索
        /// </summary>
        private void SearchDownPath(Vector2Int target,ref Vector2Int path)
        {
            Vector2Int pos = _downpath + target;
            if (pos.y > GameConfig.COLLOW - 1 || pos.y < 0 )
            {
                Debug.Log("越界");
                path = target;
                return;
            }

            Block block = _blocks[pos.x, pos.y];
            if (block == null)
            {
                path = pos;
                SearchDownPath(pos,ref path);
            }
        }

        /// <summary>
        /// 深度优先搜索
        /// </summary>
        private void DepthFristSearch(Block target,ref List<Block> blocks)
        {
            int count = 0;
            for (int i = 0; i < _path.Length; i++)
            {
                count++;
                Vector2Int pos = _path[i] + target.ID;
                if (pos.x > GameConfig.ROW - 1 || pos.y > GameConfig.COLLOW - 1
                   ||pos.x < 0 || pos.y < 0)
                {
                    Debug.Log("越界");
                }
                else
                {
                    Block block = _blocks[pos.x, pos.y];
                    if (block != null && block.Type == target.Type && !ListIsHaveBlock(blocks, block))
                    {
                        blocks.Add(_blocks[pos.x, pos.y]);
                        DepthFristSearch(block, ref blocks);
                    }
                    else if (count == 4)
                    {
                        return;
                    }
                }
            }
        }

        /// <summary>
        /// 是否包含了方块
        /// </summary>
        private bool ListIsHaveBlock(List<Block> list,Block block)
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].GUID == block.GUID)
                {
                    return true;
                }
            }

            return false;
        }

        private Vector3 GetStartPos()
        {
            float x = GRoot.inst.width;
            float y = GRoot.inst.height;

            float startx = GameConfig.weidthdis * GameConfig.ROW;
            float starty = GameConfig.heightdis * GameConfig.COLLOW;
            startx = (x-startx) / 2.0f;
            starty = (y-starty) / 2.0f;
            return new Vector3(startx,starty,0);
        }

        public void _EndMgr()
        {
            
        }

        public void _UpdateMgr()
        {
            
        }
    }
}

Block方块类

基础类,主要是修改方块的基础类型,包括类型,颜色,等等

using System;
using System.Collections;
using System.Collections.Generic;
using DLBASE;
using FairyGUI;
using UnityEngine;

namespace DLAM
{
    public class Block 
    {
        private string _url = "ui://GameView/block";
        private Vector3 _position;
        private GButton _obj;
        private Vector2Int _sizeint;
        private int _type;
        private Action<Block> _click;
        private string _guid;
        private BlockPool _pool;
        private Block[,] _blocks;

        public Block(BlockPool pool,GComponent parent,Block[,] blocks)
        {
            _blocks = blocks;
            _pool = pool;
            _obj = pool.GetFGobj(_url).asButton;
            parent.AddChild(_obj);
            _obj.onClick.Add(ClickHundler);
        }

        public void DistorySelf()
        {
            _pool.RecycleGObj(_obj);
            _blocks[_sizeint.x, _sizeint.y] = null;
        }

        public void TweenMove(Vector3 pos)
        {
            _obj.TweenMove(pos,0.2f);
        }

        private void ClickHundler(EventContext context)
        {
            _click?.Invoke(this);
        }

        public void AddClick(Action<Block> click)
        {
            _click = click;
        }

        public Vector3 Position
        {
            get => _position;
            set
            {
                _obj.position = value;
                _position = value;
            }
        }

        public Vector2Int ID
        {
            get => _sizeint;
            set
            {
                _sizeint = value;
                _obj.title = _sizeint.ToString();
            }
        }

        public int Type
        {
            get => _type;
            set
            {
                _type = value;
                _obj.GetChild("bg").asGraph.color = GameUtlis.ChangeColor(ColorConfig.BlockColor[_type]);
            }
        }

        public string GUID
        {
            get => _guid;
            set
            {
                _guid = value;
            }
        }
    }
}

ColorConfig颜色配置类

方块背景类,主要修改方块背景的虚线框,是否填充,数组位置等等

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

namespace DLAM
{
    public class ColorConfig
    {
        public static string[] BlockColor = new string[10]
        {
            "#FFFFFF",
            "#EEEEEE",
            "#DADADA",
            "#C2C1C1",
            "#A4A3A3",
            "#7C7C7C",
            "#5C5C5C",
            "#434343",
            "#2A2929",
            "#111111",
        };
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值