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

一个 ECharts 做的猜数小游戏

作者头像
ZXand618
发布2022-04-10 09:56:54
5070
发布2022-04-10 09:56:54
举报
文章被收录于专栏:ZXand618的ECharts之旅

大概 1 年多之前,一位老同学找到我,问能不能帮他做一个非常简单的猜数字游戏,需求是这样的:

  1. 在 1 到 100 的整数里,随机选一个数字,让小朋友们猜;
  2. 如果猜错了,告知小朋友猜大了还是猜小了;
  3. 如果猜中了,游戏结束。

正好那段时间,我一直在用ECharts做统计图表。一听到这个需求,马上想到用ECharts的交互效果就能做,而且比直接写程序要省事得多。于是答应他中午午休给他做,1小时左右交差。

结果ECharts果然好用,1小时内实现功能 + 调了调细节交付,1 个 HTML 文件 + 2 个 JS 文件(自己写的 JS + echarts.min.js)就搞定了。思路大致是这样的:

  1. 用了基于直角坐标系的热力图(heatmap)和仪表盘图(gauge),去掉直角坐标系的坐标轴(xAxis.show = false, yAxis.show = false),去掉仪表盘指针和刻度值(axisLabel.show = false)等;
  1. 点击热力图猜数,仪表盘显示结果(监听 click 事件,设置回调函数更新图表),同时把用不到的数字按钮去掉。

关键代码部分

代码水平可能比较低…因为我是工作之余凭兴趣偶尔写写,请大家多多包涵

1、准备热力图数据

我需要准备 1 到 100 个数,填满热力图。为了偷懒,我弄了 0 到 100 共 101 个数,这样坐标(0, 1)对应的数字正好是 1,(1, 0)对应 10 ,看起来比较直观,省脑子…哈哈!

代码语言:javascript
复制
 data: [
        // X坐标, Y坐标, 数值 
        [  0,    0,   0],
        [  0,    1,   1],
        [  0,    2,   2]
    ]

这是生成数据的代码,循环嵌套:

代码语言:javascript
复制
var data = (function() {
    var res = [];
    for (i = 0; i < 11; i++) {
        for (j = 0; j < 10; j++) {
            if (i * 10 + j < 101) {
                res.push([i, j, '' + (i * 10 + j)]);
            }
        }
    }
    return res;
})();

结果大致是这样的

代码语言:javascript
复制
[[ 0, 0, 0], [ 0, 1, 1], ..., [ 0, 9, 9],
 [ 1, 0, 10],[ 1, 1, 11], ..., [ 1, 9, 19],
 ...,
 [ 9, 0, 90],[ 9, 1, 91], ..., [ 9, 9, 99],
 [ 10, 0, 100]]
 

然后发现犯二了,x 坐标和 y 坐标位置弄反了,数字竖向排列了,赶紧交换下位置

(或者把 res.push() 里面的 i, j 顺序换下)

代码语言:javascript
复制
guessNumData = data.map(function(item) {
    return [item[1], item[0], item[2] || '-'];
});

2、点击事件的监听处理

使用 myChart.on() 监听点击事件。

代码语言:javascript
复制
// 设置一个变量,如果猜对了将其赋值为 1
var flag = 0;

//监听点击事件,在猜中之前进行响应,params.data[2]就是所猜的数字
myChart.on('click', function(params) {
    if (params.seriesId === 'guessPanel' && flag == 0) {
        guess(parseInt(params.data[2]));
    }
});

guess 函数做了什么?与预先生成的随机数比对,根据比对结果提供刷新图表的参数:

  1. 是否猜中,1 代表猜中,0 代表没猜中;
  2. 提示信息;
  3. 新的猜数范围最小值;
  4. 新的猜数范围最大值。
代码语言:javascript
复制
function guess(num) {
    var info;
    if (num == secretNum) {
        info = '猜中了!!!';
        flag = 1;
        renewEcharts(1, info, min, max);
    } else if (num < min || num > max) {
        info = '请猜' + min + '到' + max + '之间的数';
        renewEcharts(0, info, min, max);
    } else if (num < secretNum) {
        min = num + 1;
        info = '猜小了,答案在' + min + '与' + max + '之间';
        renewEcharts(0, info, min, max);
    } else {
        max = num - 1;
        info = '猜大了,答案在' + min + '与' + max + '之间';
        renewEcharts(0, info, min, max);
    }
}

renewEcharts 函数又做了什么?根据 guess 函数提供的参数更新图表。

代码语言:javascript
复制
function renewEcharts(isGet, msg, min, max) {
    var opt;
    
    // 根据新的猜数范围,修改仪表盘颜色
    var color = '#5BC49F';
    if (max - min < 8) {
        color = '#B5495B';
    } else if (max - min < 15) {
        color = '#FF7C7C';
    } else if (max - min < 30) {
        color = '#FFDA43';
    }
    
    // 如果猜中,只更新仪表盘中心的提示信息
    if (isGet == 1) {
        opt = {
            series: {
                detail: {
                    formatter: msg
                }
            }
        };
        myChart.setOption(opt);
        
    // 如没猜中,更新仪表盘和热力图,提示用户继续猜
    } else {
        opt = {
            series: [{
                id: 'guess',
                axisLine: {
                    lineStyle: {
                    
                        // 更新仪表盘中,除灰色之外部分的长度和颜色
                        color: [
                            [0, '#BEBEBE'],
                            [min / 100, '#BEBEBE'],
                            [max / 100, color],
                            [1, '#BEBEBE']
                        ]
                    }
                },
                
                // 更新仪表盘中心的提示信息及文字颜色
                detail: {
                    formatter: msg,
                    color: color
                }
            }, {
                id: 'guessPanel',
                
                // 将新的猜数范围之外的按钮去掉(直接更换热力图的数据)
                data: (function() {
                    var res = [];
                    for (var item in guessNumData) {
                        if (parseInt(guessNumData[item][2]) >= min && parseInt(guessNumData[item][2]) <= max) {
                            res.push(guessNumData[item]);
                        }
                    }
                    return res;
                })()
            }]
        };
        myChart.setOption(opt);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档