教你用ECharts轻松做一个FlappyBird小游戏
本文分享自华为云社区《没想到吧!这个可可爱爱的游戏居然是用ECharts实现的!云社区华为云》,作者:DevUI。前言
echarts是一个很强大的图表库,除了我们常见的图表功能,echarts有一个自定义图形的功能,这个功能可以让我们很简单地在画布上绘制一些非常规的图形,基于此,我们来玩一些花哨的。
FlappyBird小游戏体验地址(看看你能玩几分):
foolmadao。github。ioechartflap
下面我们来一步步实现他。1在坐标系中画一只会动的小鸟
首先实例化一个echart容器,再从网上找一个像素小鸟的图片,将散点图的散点形状,用自定义图片的方式改为小鸟。constmyChartecharts。init(document。getElementById(main));option{series:〔{name:bird,type:scatter,symbolSize:50,symbol:image:bird。png,data:〔〔50,80〕〕,animation:false},〕};myChart。setOption(option);
要让小鸟动起来,就需要给一个向右的速度和向下的加速度,并在每一帧的场景中刷新小鸟的位置。而小鸟向上飞的动作,则可以靠角度的旋转来实现,向上飞的触发条件设置为空格事件。option{series:〔{xAxis:{show:false,type:value,min:0,max:200,},yAxis:{show:false,min:0,max:100},name:bird,type:scatter,symbolSize:50,symbol:image:bird。png,data:〔〔50,80〕〕,animation:false},〕};设置速度和加速度leta0。05;letvh0;letvw0。5timersetInterval((){小鸟位置和仰角调整vhvha;option。series〔0〕。data〔0〕〔1〕vh;option。series〔0〕。data〔0〕〔0〕vw;option。series〔0〕。symbolRotateoption。series〔0〕。symbolRotate?option。series〔0〕。symbolRotate5:0;坐标系范围调整option。xAxis。minvw;option。xAxis。maxvw;myChart。setOption(option);},25);
效果如下
2用自定义图形绘制障碍物
echarts自定义系列,渲染逻辑由开发者通过renderItem函数实现。该函数接收两个参数params和api,params包含了当前数据信息和坐标系的信息,api是一些开发者可调用的方法集合,常用的方法有:api。value(),意思是取出dataItem中的数值。例如api。value(0)表示取出当前dataItem中第一个维度的数值。api。coord(),意思是进行坐标转换计算。例如varpointapi。coord(〔api。value(0),api。value(1)〕)表示dataItem中的数值转换成坐标系上的点。api。size(),可以得到坐标系上一段数值范围对应的长度。api。style(),可以获取到series。itemStyle中定义的样式信息。
灵活使用上述api,就可以将用户传入的Data数据转换为自己想要的坐标系上的像素位置。
renderItem函数返回一个echarts中的graphic类,可以多种图形组合成你需要的形状,graphic类型。对于我们游戏中的障碍物只需要使用矩形即可绘制出来,我们使用到下面两个类。type:group,组合类,可以将多个图形类组合成一个图形,子类放在children中。type:rect,矩形类,通过定义矩形左上角坐标点,和矩形宽高确定图形。数据项定义为〔x坐标,下方水管上侧y坐标,上方水管下侧y坐标〕data:〔〔150,50,80〕,。。。〕renderItem:function(params,api){获取每个水管主体矩形的起始坐标点letstart1api。coord(〔api。value(0)10,api。value(1)〕);letstart2api。coord(〔api。value(0)10,100〕);获取两个水管头矩形的起始坐标点letstartHead1api。coord(〔api。value(0)12,api。value(1)〕);letstartHead2api。coord(〔api。value(0)12,api。value(2)8〕)水管头矩形的宽高letheadSizeapi。size(〔24,8〕)水管头矩形的宽高letrectapi。size(〔20,api。value(1)〕);letrect2api。size(〔20,100api。value(2)〕);坐标系配置constcommon{x:params。coordSys。x,y:params。coordSys。y,width:params。coordSys。width,height:params。coordSys。height}水管形状constrectShapeecharts。graphic。clipRectByRect({x:start1〔0〕,y:start1〔1〕,width:rect〔0〕,height:rect〔1〕},common);constrectShape2echarts。graphic。clipRectByRect({x:start2〔0〕,y:start2〔1〕,width:rect2〔0〕,height:rect2〔1〕},common)水管头形状constrectHeadShapeecharts。graphic。clipRectByRect({x:startHead1〔0〕,y:startHead1〔1〕,width:headSize〔0〕,height:headSize〔1〕},common);constrectHeadShape2echarts。graphic。clipRectByRect({x:startHead2〔0〕,y:startHead2〔1〕,width:headSize〔0〕,height:headSize〔1〕},common);返回一个group类,由四个矩形组成return{type:group,children:〔{type:rect,shape:rectShape,style:{。。。api。style(),lineWidth:1,stroke:000}},{type:rect,shape:rectShape2,style:{。。。api。style(),lineWidth:1,stroke:000}},{type:rect,shape:rectHeadShape,style:{。。。api。style(),lineWidth:1,stroke:000}},{type:rect,shape:rectHeadShape2,style:{。。。api。style(),lineWidth:1,stroke:000}}〕};},
颜色定义,我们为了让水管具有光泽使用了echarts的线性渐变色对象。itemStyle:{渐变色对象color:{type:linear,x:0,y:0,x2:1,y2:0,colorStops:〔{offset:0,color:ddf38c0处的颜色},{offset:1,color:587d2a100处的颜色}〕,global:false缺省为false},borderWidth:3},
另外,用一个for循环一次性随机出多个柱子的数据functioninitObstacleData(){添加minHeight防止空隙太小letminHeight20;letstart150;obstacleData〔〕;for(letindex0;index50;index){constheightMath。random()30minHeight;constobstacleStartMath。random()(90minHeight);obstacleData。push(〔start50index,obstacleStart,obstacleStartheight100?100:obstacleStartheight〕)}}
再将背景用游戏图片填充,我们就将整个游戏场景,绘制完成:
3进行碰撞检测
由于飞行轨迹和障碍物数据都很简单,所以我们可以将碰撞逻辑简化为小鸟图片的正方形中,我们判断右上和右下角是否进入了自定义图形的范围内。
对于特定坐标下的碰撞范围,因为柱子固定每格50坐标值一个,宽度也是固定的,所以,可碰撞的横坐标范围就可以简化为(x501)0。6
在特定范围内,依据Math。floor(x50)获取到对应的数据,即可判断出两个边角坐标是否和柱子区域有重叠了。在动画帧中判断,如果重叠了,就停止动画播放,游戏结束。centerCoord为散点坐标点functionjudgeCollision(centerCoord){if(centerCoord〔1〕0centerCoord〔1〕100){returnfalse;}letcoordList〔〔centerCoord〔0〕15,centerCoord〔1〕1〕,〔centerCoord〔0〕15,centerCoord〔1〕1〕,〕for(leti0;i2;i){constcoordcoordList〔i〕;constindexcoord〔0〕50;if(index10。6obstacleData〔Math。floor(index)3〕){if(obstacleData〔Math。floor(index)3〕〔1〕coord〔1〕obstacleData〔Math。floor(index)3〕〔2〕coord〔1〕){returnfalse;}}}returnfalse}functioninitAnimation(){动画设置timersetInterval((){小鸟速度和仰角调整vhvha;option。series〔0〕。data〔0〕〔1〕vh;option。series〔0〕。data〔0〕〔0〕vw;option。series〔0〕。symbolRotateoption。series〔0〕。symbolRotate?option。series〔0〕。symbolRotate5:0;坐标系范围调整option。xAxis。minvw;option。xAxis。maxvw;碰撞判断constresultjudgeCollision(option。series〔0〕。data〔0〕)if(result){产生碰撞后结束动画endAnimation();}myChart。setOption(option);},25);}总结
echarts提供了强大的图形绘制自定义能力,要使用好这种能力,一定要理解好数据坐标点和像素坐标点之间的转换逻辑,这是将数据具象到画布上的重要一步。
运用好这个功能,再也不怕产品提出奇奇怪怪的图表需求。
源码地址:github。comfoolmadaoe
点击下方,第一时间了解华为云新鲜技术
华为云博客大数据博客AI博客云计算博客开发者中心华为云
破圈和破题宁波县域经济成绩单观察近期,宁波各区县(市)2022年GDP数据浮出水面。鄞州以2734。78亿元的GDP,首次坐上浙江县域经济头把交椅,让不少宁波人骄傲了一把。实际上除了鄞州外,宁波各区县(市)全年表
孟晚舟将首次当值华为轮值董事长,这意味着什么?任正非之女华为副董事长轮值董事长CFO孟晚舟将于2023年4月1日首次当值华为轮值董事长,将成为华为的最高领袖,也是史上首个女掌舵人。消息传出后,再次引起了人们的关注。什么叫当值?
盐城房价两连涨,盐城楼市利好越来越多,盐城楼市分析第2期2月财经新势力盐城为了帮助盐城楼市稳住,也是出台了不少利好政策。在前段时间里面,盐城楼市已经把盐城的公积金贷款额度,从原来的60万,增加到了100万,并且公积金的贷款年限,从原来的
准东千万吨级露天煤矿获得核准!1月29日,国家发展改革委核准新疆兖矿其能煤业有限公司准东五彩湾矿区四号露天矿一期工程及选煤厂1000万吨年项目。这是十四五期间准东开发区获得核准的首个千万吨级露天煤矿。该项目总投
大北农放量大跌9。03,深股通净卖出4。34亿元大北农今日跌9。03,报8。36元,成交额28。72亿元,换手率10。27。盘后龙虎榜数据显示,深股通专用席位买入5667。77万元并卖出4。91亿元,2家机构专用席位净卖出856
狂飙中的疯子与坏官狂飙中不容小觑的配角演员王宏演活了疯子,能够把精神失控和痴傻的样子表演出来,而且一点也不夸张和违和,演员王宏真是实力不容小觑。剧中的李青,从小就患有精神病,是在白眼和谩骂声中长大的
伊布必须享受欧冠之夜同时保持专注,我们要心存信念直播吧2月15日讯在没能入选球队欧冠大名单的情况下,米兰老将伊布将会为球队加油助威。在对阵热刺之前,伊布对本场比赛发表了自己的看法。伊布说道这样的夜晚实在太棒了,因为米兰在欧冠赛场
识破洗澡蟹,不能只靠新技术郭元鹏不法商贩用洗澡蟹冒充知名湖区产品卖高价,损害消费者利益,侵害农产品品牌。近期,中国科学技术大学黄方教授团队副研究员于慧敏博士生殷皓铭等人基于一方水土养一方蟹的地理特点,运用激
2月15日早上,中国传来了3个新消息,建议您了解一下让我们花几分钟时间来看看最近传来的新消息,文章可能有点长,请耐心阅读。第一个新消息我国多地生育登记取消结婚限制。最近,四川省卫生和计划生育委员会发布了一项新规定,叫做四川省生育登记
图集情人节,动物也来秀恩爱动物出双入对,卿卿我我,大秀恩爱2月14日,早春二月,深圳野生动物园里的小动物们春意萌动,大胆追求爱情,享受着属于它们的亲密时刻。小动物们各种各样的求偶方式,十分可爱,给春季里的动
五问医保个人账户改革缩水的钱去哪儿了?谁将从中获益?(健康时报记者谭琪欣)个人账户里少的钱去哪儿了?个人医保账户的钱越改越少,是不是国家医保基金池子没钱了?近日,江苏黑龙江江西等多地陆续启动职工医保个人账户改革,引发热议。医院医保业