爱上乐消消
一.引擎
游戏工程地址在文末
开发: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",
};
}
}