花5个小时撸了一个“码了个码”,源码文档开源

最近羊了个羊爆火网络,其实这个程序本来不难,但是怎么火起来的,可能研究人性方面更多吧。

作为程序员,三天也撸了一个程序,号称"码了个码"!

一、演示地址

https://www.coderutil.com/game/mlgm

二、源代码下载

点赞转发本文后私信【929】即可下载代码和操作文

三、技术栈

只是为了实现那么要效果,不涉及服务端交互,纯前段实现:H5、CSS3、JS、Jquery、layui

四、游戏逻辑

根本逻辑:本质上跟以前的大家玩的消消乐逻辑是比较相似的,有一些元素,选中3个可以抵消,直到游戏面板所有元素全部消除可通关;

羊了个羊:他的通过难点在于是有多层叠加、只有上面压着的元素被拿掉下面的才可以点击。其他的也都是比较常规的设计;

五、实现整体思路

我准备单从比较核心的这几个问题来进行分享:多层叠加面板设计与实现、随机元素分布、元素点击事件、操作结果校验!

5.1 多层面板的实现

这里我选用了一种简单的叠加效果:固定5层叠加,示意图:


5.2 随机元素分布

游戏元素对象创建

首选我需要定义一个游戏元素对象,GameItem: id、name、icon、color

游戏元素个数以及初始化创建

OK,有了元素对象我准备先创建一个Array容器用来保存本局游戏初始化生成的所有元素:

这里遇到一个问题:需要生成多少个元素?需要几种元素?因为我们看到羊了个羊游戏元素对象并不是填充满的,有很多空位。于是乎为了简单,我自己固定定义了一种规则:

按照我现在个字的设计:8 * 8,7 * 7,6 * 6,5 * 5, 4 * 4,下来全部填满有 190个位置;然后我需要空出来一些位置,怎么空这里就有点玄幻了,我设计了这样的规则:

(8*8 - 12) + (7*7 - 10) + (6*6 - 8) + (5*5 - 6) + (4*4 - 4)共 150个元素,每三个一组的话有50队可消除的元素;

我这里一共设计了10种元素icon,在简单一点即,没中元素生成15个即150个;

好了,规则清晰了,可以去初始化游戏元素了,定义了一个items数组、initGameData()方法:

/***
 * 游戏网格
 * 1、每层格子抽象为一个矩阵/数组, 共 4 层: [8, 8], [7, 7], [6, 6], [5, 5], [4, 4]
 * 2、每层初始化规则:(64 - 12) + (49 - 10) + (36 - 8) + (25 - 6) + (16 - 4)共 150个元素 50队
 * 3、一共设置了10中图标元素,目前是写死的,固定规则:分别5组 10 * 5 * 3 = 150个
 */
function GameGrid() {
  
   /***
 * 实际元素个数
 * @type {number}
 */
var size = 0;

/** 初始化所有元素 **/
var items = new Array();

/***
 * 初始化游戏数据
 * @returns {any[]}
 */
this.initGameData = function() {
    var idx = 0;
    for (var i = 0; i < this.initSize(); i++) {
        idx = Math.floor(i / 15);
        var id = i;
        var name = idx;
        var icon = "/game/icon/"+(idx + 1)+".png";
        var color = colors[idx];
        // 加入游戏元素容器
        items.add(new GameItem(id, name, icon, color));
    }
    console.log("完成游戏元素初始化.")
    return items;
}
}

游戏元素分布

目前为止,我已经拿到了一个items里面有150个游戏元素的数组对象、还有页面上1 5 层p面板;现在需要考虑怎么把游戏元素放进去,并且随机、随机位置、随机空位置。

这里先对5个p从数据角度做个抽象:我们把每个p落点抽象为一个矩阵(二维数组),矩阵的值由0,1组成,1代表这个位置有元素、0代表是空位。

我们已最上层为例子来看:

创建5个矩阵、且需要按照我们的上述的规则随机生成5个0 1 矩阵,大小分别为 8 * 8,7 * 7,6 *6, 5*5,4*4:

/***
 * 初始化游戏网格
 */
this.initGameGrid = function () {
    /***
     * 初始化 1 - 5 层矩阵, 每次初始化元素位置都是随机的
     * *^* 这里X、Y、矩阵0数量直接写死吧,懒得定义了
     */
    matrix1 = this.initMatrix(8, 8, 12);
    matrix2 = this.initMatrix(7, 7, 10);
    matrix3 = this.initMatrix( 6, 6, 8);
    matrix4 = this.initMatrix(5, 5, 6);
    matrix5 = this.initMatrix(4, 4, 4);
}

/***
 * 初始化一个 X * Y 的 0、1 矩阵:1代表有元素,0 无元素,
 * @param x x轴个数
 * @param y y轴个数
 * @param emptySize 空个数,即位置0的个数
 */
this.initMatrix = function (x, y, emptySize) {
    // 初始化一个 X * Y 的值为1的矩阵
    var matrix = new Array();
    for (var i = 0; i < x; i++) {
        matrix[i] = new Array();
        for (var j = 0; j < y; j++) {
            matrix[i][j] = 1;
        }
    }
    // 随机生成emptySize个随机位置,设置值为0,代表没有元素
    var validateArr = new Array(); // 娇艳重复的
    for (var i = 0; i < emptySize; i++) {
        var randomArr = getRandom(x, y, validateArr);
        matrix[randomArr[0]][randomArr[1]] = 0;
    }
    return matrix;
}

元素矩阵落位

ok, 矩阵有了,元素也有了,可以做元素填充了:其实就是把items:Array中的150个元素依次顺序的分布到这5个矩阵当中即可。

这里有个小问题:现在的items:Array元素顺序每次还是固定的,即使矩阵0 1落位是随机的,但是玩两把下来还是会发现规律,解决办法也很简单,在落位之前我们先对items顺序做一次打乱:

/***
 * 打乱arr顺序
 */
this.sort = function () {
    var length = this.size(),
        randomIndex,
        temp;
    while (length) {
        randomIndex = Math.floor(Math.random() * (length--));
        temp = items[randomIndex];
        items[randomIndex] = items[length];
        items[length] = temp;
    }
}

/**。打乱元素随机位置 **/
this.sort(); 

到目前为止我们已经完成了面板叠加、随机游戏元素以及游戏元素的落位展示:


5.3 点击事件

这个操作的核心所在,我们需要实现:

1、点击元素将元素移动到底部选中区

2、元素消失后,需要判断被它压着的元素是否暴露出来了,及是否可以点击

3、也就是下一步的校验:判断是否有可以消除的,以及是否Game Over

点击事件这里不展开写了,我们只关心这里的一个难点问题:点击上层后需要校验下层是否暴露出来:

思路,需要两步:第一步获取需要校验的底层元素、娇艳底层元素是否完全暴露。

点击上层元素(x,y),获取可能被它盖住的底层元素:

在不考虑特殊情况的前提下点击上层(x, y),我们需要校验直接(注意:每次我们只需要关心直接下层即可)下层的(x,y)(x+1,y) (x, y+1), (x+1, y+1)

判断下层的四个元素是否完全暴露:

需要注意的是每个元素又可能被上层的4个元素盖住(最大情况下)

到这里基本上就ok了,可能有人会好奇你的点击不可点击是怎么实现的:

我就是给每个元素家里一个span蒙层,每次在点击元素的时候判断这个元素是否有span这个子元素


.disable-click {
    position: absolute;
    left: 0px;
    top: 0px;
    width: 100%;
    height: 100%;
    background-color: black;
    opacity: 0.6;
}
$(".grid-game-item").on('click', function () {
    var disableClick = $(this).children(".disable-click").length > 0;
    if (disableClick) {
        // 不能点击
        return;
    }

    /** 点击后的处理 **/
}

因为点击后的处理,包括上述的底层是否暴露可以点击的代码逻辑比较多,所以就不贴了,感兴趣的兄弟可以自己下载源代码查看:

https://www.coderutil.com/resource/view?resid=RESOURCE_1f801b03cbdd445795ce3c6800fe9002

5.4 操作校验

操作校验主要有三个校验:

1、是否可以消除:校验选中的元素是否可以消除:根据元素的name属性来判断

2、校验GameOver:满足7个 & 不满足消除条件

3、游戏通关:面板内所有元素都消除干净

展开阅读全文

页面更新:2024-04-29

标签:初始化   多层   源码   面板   逻辑   元素   定义   对象   规则   小时   操作   文档   游戏

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top