前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ECharts 做的另一种猜数小游戏

ECharts 做的另一种猜数小游戏

作者头像
ZXand618
发布2022-04-10 10:00:17
3920
发布2022-04-10 10:00:17
举报

昨天突然想起上学时玩的文曲星(电子词典),里面有个猜数字的小游戏,于是拿 ECharts 试着做了一下,大体思路如下:

  1. 用基于直角坐标系上的 heatmap 做虚拟按键
  2. 用 graphic.elements[i]-text 和 graphic.elements[i]-rect 做文本框、提示框
  3. 监听 heatmap 的点击事件,输入数字、猜数

heatmap 虚拟按键实现

heatmap 数据准备

代码语言:javascript
复制
// 准备 heatmap 的按钮数据,用 '-1' 作为退格按钮、'-2'作为猜数按钮 
var btnData = (function() {
    var res = [];
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 4; j++) {
            if (j > 0) {
                res.push([i, j, '' + (j * 3 + i - 2)]);
            } else {
                res.push([i, j, '' + (0 - i)]);
            }
        }
    }
    return res;
})();

heatmap 所在 x、y 坐标轴数据

代码语言:javascript
复制
var categoryX = ['0', '1', '2'];
var categoryY = ['0', '1', '2', '3'];

heatmap 部分配置项

代码语言:javascript
复制
option = {
    title: {
        text: '文曲星词典猜数字游戏'
    },
    tooltip: {
        show: false
    },
    grid: {
        width: '30%',
        height: '60%',
        left: '10px',
        top: '30%'
    },
    xAxis: {
        show: false,
        type: 'category',
        data: categoryX,
        splitArea: {
            show: true
        }
    },
    yAxis: {
        show: false,
        type: 'category',
        data: categoryY,
        splitArea: {
            show: true
        }
    },
    series: [{
        id: 'btnPanel',
        type: 'heatmap',
        label: {
            normal: {
                show: true,
                formatter: function(params) {
                    if (params.data[2] < 0) {
                        return params.data[2] == -1 ? '⬅' : '猜';
                    }
                    return params.data[2];
                }
            }
        },
        data: btnData
    }]
};
  • grid:直角坐标系位置等配置
  • tooltip:隐藏提示框
  • xAxis 和 yAxis:x 轴和 y 轴配置
  • series[i]-heatmap:热力图配置,其中 label.formatter 使用回调函数把 '-1' 和 '-2' 分别换成 '←' 和 '猜',data 绑定之前准备好的heatmap 数据

graphic 输入框、提示框实现

输入框、提示框生成函数( 4个方块数字框 + 提示框),这个函数返回的 JSON 对象用于 option.graphic 配置

代码语言:javascript
复制
// 输入框、提示框生成函数( 4个方块数字框 + 提示框)
function graphicObj(arr, msg) {
    var res = [];
    for (var i = 0; i < 4; i++) {
        res.push({
            type: 'group',
            id: 'textGroup' + i,
            left: 50 + i * 60,
            top: 50,
            children: [{
                    type: 'rect',
                    z: 100,
                    left: 'center',
                    top: 'center',
                    shape: {
                        width: 40,
                        height: 50
                    },
                    style: {
                        fill: '#fff',
                        stroke: '#999',
                        lineWidth: 2,
                        shadowBlur: 8,
                        shadowOffsetX: 3,
                        shadowOffsetY: 3,
                        shadowColor: 'rgba(0,0,0,0.3)'
                    }
                },
                {
                    type: 'text',
                    z: 100,
                    top: 'middle',
                    left: 'center',
                    style: {
                        text: typeof(arr[arr.length - 4 + i]) === 'undefined' ? '' : arr[arr.length - 4 + i],
                        font: '20px "STHeiti", sans-serif'
                    }
                }
            ]
        });
    }
    res.push({
        type: 'text',
        z: 100,
        top: '50',
        left: '400',
        style: {
            text: msg,
            font: '20px "STHeiti", sans-serif'
        }
    });
    return res;
}
  • graphic.elements[i]-group:可以有子节点的容器
  • graphic.elements[i]-text:文本块
  • graphic.elements[i]-rect:矩形块
  • 一个文本块和一个矩形块组成一个数字显示框,一起放到容器内部,通过容器整体定位
  • 循环 4 次,生成 4 个包含文本块的容器,排成一行显示
  • 单独添加一个文本块用于显示提示信息
  • 偷懒没有按百分比定位

交互部分实现

监听 heatmap 上的点击事件

代码语言:javascript
复制
// 点击热力图时调用 btnClick 函数
myChart.on('click', function(params) {
    if (params.seriesId === 'btnPanel' && times > 0) {
        btnClick(params.data[2]);
    }
});
  • params:用于传入图表的点击事件的基本参数
    • params.seriesId:对应 option.series[i]-id
    • params.data:对应 option.series[i]-data,此处 params.data[0] 对应 xAxis坐标,params.data[1] 对应 yAxis 坐标,params.data[2] 是该坐标对应的数值(也就是此前生成的按钮数据)
  • times:用于记录还剩下几次猜数字机会

btnClick 函数定义

代码语言:javascript
复制
// 按钮点击响应函数
function btnClick(btnID) {
    if (btnID === '-1') {
        inputList.pop();
    } else if (btnID === '-2') {
        return inputList.length === 4 ? guess(inputList) : alert('请先填入 4 个数字再猜!');
    } else {
        inputList.length === 4 ? inputList[3] = btnID : inputList.push(btnID);
    }
    myChart.setOption({
        graphic: graphicObj(inputList, msgList.join('\n'))
    });
}
  • inputList:预先定义好的,用于存放猜数列表的数组变量
  • <表达式1> ? <表达式2> : <表达式3> 三元表达式,如果<表达式1> 为真,则执行<表达式2>,否则执行<表达式3>
  • btnID:传入的按钮数据
    • 当 btnID 等于 '-1' 时,删除 inputList 最后一个数字
    • 当 btnID 等于 '-2' 时,猜数字或提示不足 4 位数字
    • 当 btnID 等于其他值时(0 到 9),在 inputList 末尾插入或替换一个数字
  • myChart.setOption(option):更新图表,默认将 option 与之前的图标配置项合并
  • myChart.setOption(option, false):更新图表,用此 option 替换原配置项

guess 函数定义

代码语言:javascript
复制
猜数函数
function guess(arr) {
    if (arr.length != 4) {
        return alert('请猜4位数字');
    }
    var info;
    var A = 0;
    var B = 0;
    times--;
    for (var i = 0; i < 4; i++) {
        if (secretNumList.indexOf(arr[i]) === i) {
            A++;
        } else if (secretNumList.indexOf(arr[i]) != -1) {
            B++;
        }
    }
    if (A === 4) {
        info = arr.join('') + '  猜中了!!!';
        times = 0;
    } else {
        info = arr.join('') + '  ' + A + 'A' + B + 'B , 你还有' + times + '次机会...';
    }
    msgList.push(info);
    inputList = [];
    myChart.setOption({
        graphic: graphicObj(inputList, msgList.join('\n'))
    });
}
  • 变量 A:数字和位置都猜对的数量
  • 变量 B:仅数字猜对但位置猜错的数量
  • 通过 for 循环分别匹配每一位所猜数字,根据匹配结果 A++ 或者 B++
    • Array.indexOf(item) 方法,从 array 里查找 item ,如果存在则返回匹配的 Index ,否则 返回 -1
  • 匹配完成后,如果 A === 4 则猜对了,否则通过类似 0A1B 的方式提示猜数的结果,通过 myChart.setOtion() 更新图表的提示区
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ZXand618的ECharts之旅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档