使用Canvas绘制一个游戏人物属性图


Posted in Javascript onMarch 25, 2022

前言

身为一个程序员竟然沉迷游戏,wtf??? 都怪腾讯前几天出了一款叫做寻仙的手游,作为曾经的资深玩家,小V君犹豫再三还是忍不住入坑了。入坑了怎么不去打游戏,还在这里发文章? 不不不,小V君今天在这里可不是要跟大家讨论游戏,作为一个好好学习,天天向上的有位少年,游戏嘛,只是业余的,码代码才是王道!!!所以小V君今天给大家分享一下怎么使用Canvas来绘制一个游戏登录界面的人物属性图!

先上一波图片,怎么样? 人物是不是很帅,很中国风???小V君当年可是花了四年时间来玩这个人物哦。。。

使用Canvas绘制一个游戏人物属性图

一. 什么是Canvas?

canvas 元素用于在网页上绘制图形。HTML5 的 canvas 元素使用 JavaScript 在网页上绘制2D图像。 在矩形区域的画布上,控制其每一像素,JavaScript 来绘制 2D图形,逐像素进行渲染。可以通过多种方法使用canvas 元素绘制路径、矩形、圆形、字符以及添加图像。

注意!!!

canvas 标签本身是不具备绘图功能,只能使用 JavaScript 在网页上绘制图像哦。

二. 任务分析

为了简洁明了,小V君没有在页面上花什么时间,希望大家不要介意,毕竟JS才是今天的主角哦。
首先,我们来简单分析一下。这个人物的属性图是由六个内嵌的正六边形组成的,再由六根线从连接这个正六边形的中心,最后根据人物的属性进行颜色的填充。怎么样?是不是很简单,只要三步就可以绘制出这个游戏人物属性图哦。可能大家会觉得小V君说起来容易,实际又该怎么操作呢?各位看官大爷别着急,小的这就送上代码。

三. 代码部分

var mW = 400,
    mH = 400,
    mCtx = null,
    mCount = 6,
    mCenter = mW/2,
    mRadius = mCenter - 50,
    mAngle = Math.PI*2/mCount,
    mColorPolygon = '#000000',
    mData = [
      ['爆发', 100],
      ['防御', 60],
      ['治疗', 50],
      ['控制', 60],
      ['辅助', 30],
      ['机动', 70]
    ],
    mColorText = '#000000',
    canvas = document.createElement('canvas');
    document.body.appendChild(canvas);
    canvas.width = mW;
    canvas.height = mH;
    mCtx = canvas.getContext('2d');

首先,我们需要指定一个id属性 (脚本中经常引用), 再使用width 和 height 属性定义的画布的大小.在这里我将画布的宽和高都设置为400,六边形嘛,数量当然是6,图形的中心等于它自身宽度的一半,线条的颜色就使用黑色,在利用一个数组写上自定义的数据就可以开始绘画啦。

细心的朋友可能会问mRadius为什么等于mCenter减50呢?在这里,请允许小V君卖个关子,大家看完就自然知道结果啦~~~

绘制六个内嵌的六边形

function drawPolygon(ctx) {
    ctx.save();   // save the default state
    ctx.strokeStyle = mColorPolygon;
    var r = mRadius / mCount;
    for(var i = 0; i < mCount; i++) {
        ctx.beginPath();   //开始路径
        var currR = r * (i + 1);
        for(var j = 0; j < mCount; j++) {
            var x = mCenter + currR*Math.cos(mAngle*j);
            var y = mCenter + currR*Math.sin(mAngle*j);
            ctx.lineTo(x, y);  
        }
        ctx.closePath();  //闭合路径
        ctx.stroke()  // restore to the default state
    }
    ctx.restore();
}

为了代码整体的美观和复用性,我们定一个名为drawPolygon的函数,再使用一个for循环来完成六边形的绘制。看到这里,大家可能会问怎么还使用了sin和cos函数了,想当年学数学那可是一个受罪,怎么现在还要受它的折磨。。。小V君也深表无奈,代码跟数学本来就是一家,代码里面很多地方都要运用Math函数,所以在数学这个坑上小V君与大家同在(┬_┬)。(ps:js中需要用到的数学公式很多网上都有,不需要自己手写,只要增加点印象,一个复制就可以拉过来用了,啦啦啦,小V君也很会偷懒的,哈哈哈~~~)

使用Canvas绘制一个游戏人物属性图

绘制直线

function drawLines(ctx) {
  ctx.save();
  ctx.beginPath();
  ctx.strokeStyle = mColorPolygon;
  for( var i = 0; i< mCount; i++){
    var x = mCenter + mRadius * Math.cos(mAngle*i);
    var y = mCenter + mRadius * Math.sin(mAngle*i);
    ctx.moveTo(mCenter, mCenter);
    ctx.lineTo(x, y);
  }
  ctx.stroke();
  ctx.restore();
}

同理,定义一个名为drawLines的函数来实现这部分功能。Canvas画线相对来说比较简单,比较难理解的估计还是在这个for循环的函数里面,对于六边形的绘制大家可以参考一下这篇博文 ? 如何绘制六边形

使用Canvas绘制一个游戏人物属性图

绘制覆盖区域

function drawRegion(ctx) {
  ctx.save();
  ctx.beginPath();
  for(var i = 0; i< mCount; i++){
    var x = mCenter + mRadius*Math.cos(mAngle*i)*mData[i][5]/100;
    var y = mCenter + mRadius*Math.sin(mAngle*i)*mData[i][6]/100;
    ctx.lineTo(x, y);
  }
  ctx.closePath();
  ctx.fillStyle = 'rgba(255,0,0,.5)';
  ctx.fill();
  ctx.store();
}

写到这里,我们的属性图差不多就绘制完成了。但是,图形内的颜色具体是怎么进行填充的呢?在这里我们使用了fill语法进行填充,在代码中只需要使用ctx.fill()就可以实现了。

解释:填充,是将闭合的路径的内容填充具体的颜色,在这里我设置了透明度为0.5的红色,默认颜色黑色。如果所有的描点没有构成封闭结构,也会自动构成一个封闭图形。

使用Canvas绘制一个游戏人物属性图

绘制文本

function drawText(ctx) {
  ctx.save();
  var fontSize = mCenter/12;
  ctx.font = fontSize + 'px Microsoft Yahei';
  ctx.fillStyle = mColorText;
  for(var i = 0; i< mCount; i++){
    var x = mCenter + mRadius*Math.cos(mAngle*i);
    var y = mCenter + mRadius*Math.sin(mAngle*i);
    //通过不同的位置,调整文本的显示位置
    if( mAngle * i >= 0 && mAngle * i <= Math.PI / 2 ){
            ctx.fillText(mData[i][0], x, y + fontSize);
        }else if(mAngle * i > Math.PI / 2 && mAngle * i <= Math.PI){
            ctx.fillText(mData[i][0], x - ctx.measureText(mData[i][0]).width, y + fontSize);
        }else if(mAngle * i > Math.PI && mAngle * i <= Math.PI * 3 / 2){
            ctx.fillText(mData[i][0], x - ctx.measureText(mData[i][0]).width, y);
        }else{
            ctx.fillText(mData[i][0], x, y);
        }
  }
  ctx.restore();
}

至此,我们的人物属性图就绘制好了。不知道各位看完之后有没有想明白前面小V君埋下的问题呢?50px,对的,mRadius等于mCenter减50中的那50px就是给我们的文本留出来的位置,代码中的if语句就是通过不同的位置来调整文本的显示位置。

使用Canvas绘制一个游戏人物属性图

四. 小结

综上所述,简单说明了如何使用Canvas来绘制一个人物属性图,以上内容属个人理解和网上学习总结,如有错误,欢迎指正共勉。关于Canvas这个元素,它应用的领域可是非常的广阔哦。比如在游戏方面,canvas在基于Web的图像显示方面比Flash更加立体、更加精巧,canvas游戏在流畅度和跨平台方面更牛。在可视化数据方面,百度的echart、d3.js、three.js等等用运用到了canvas。如果你以为Canvas的运用只有这些,那就打错特错了,在现在以及未来的智能机时代,HTML5技术能够在banner广告上发挥巨大作用,而使用Canvas来实现动态的广告效果再合适不过。

到此这篇关于使用Canvas绘制一个游戏人物属性图的文章就介绍到这了,更多相关Canvas游戏人物属性图内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

 
Javascript 相关文章推荐
JS网络游戏-(模拟城市webgame)提供的一些例子下载
Oct 14 Javascript
通过Jquery遍历Json的两种数据结构的实现代码
Jan 19 Javascript
JavaScript可否多线程? 深入理解JavaScript定时机制
May 23 Javascript
解析JavaScript中instanceof对于不同的构造器或许都返回true
Dec 03 Javascript
jquery如何通过name名称获取当前name的value值
Dec 20 Javascript
推荐4个原生javascript常用的函数
Jan 12 Javascript
jquery模拟多级复选框效果的简单实例
Jun 08 Javascript
JS实现页面跳转参数不丢失的方法
Nov 28 Javascript
iscroll动态加载数据完美解决方法
Jul 18 Javascript
JS实现问卷星自动填问卷脚本并在两秒自动提交功能
Jun 17 Javascript
基于Vue实现拖拽效果
Apr 27 Javascript
element vue Array数组和Map对象的添加与删除操作
Nov 14 Javascript
【js设计模式】SOLID五大设计原则
什么是SOLID
Vue3中toRef与toRefs的区别
Mar 24 #Vue.js
Javascript的promise,async和await的区别详解
Mar 24 #Javascript
一起来看看Vue的核心原理剖析
Mar 24 #Vue.js
手写Spirit防抖函数underscore和节流函数lodash
Mar 22 #Javascript
深入讲解Vue中父子组件通信与事件触发
Mar 22 #Vue.js
You might like
怎么使 Mysql 数据同步
2006/10/09 PHP
PHP警告Cannot use a scalar value as an array的解决方法
2012/01/11 PHP
几个优化WordPress中JavaScript加载体验的插件介绍
2015/12/17 PHP
PHP定时任务获取微信access_token的方法
2016/10/10 PHP
Laravel框架自定义分页样式操作示例
2020/01/26 PHP
JQuery扩展插件Validate—6 radio、checkbox、select的验证
2011/09/05 Javascript
javascript实现促销倒计时+fixed固定在底部
2013/09/18 Javascript
js中哈希表的几种用法总结
2014/01/28 Javascript
基于javascript实现精确到毫秒的倒计时限时抢购
2016/04/17 Javascript
Vue.js实现无限加载与分页功能开发
2016/11/03 Javascript
简单学习vue指令directive
2016/11/03 Javascript
Angular中的$watch方法详解
2017/09/18 Javascript
vue语法之拼接字符串的示例代码
2017/10/25 Javascript
详解vue通过NGINX部署在子目录或者二级目录实践
2018/09/03 Javascript
详解vue中使用vue-quill-editor富文本小结(图片上传)
2019/04/24 Javascript
vue项目中引入Sass实例方法
2019/08/27 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
vue项目中微信登录的实现操作
2020/09/08 Javascript
基于python requests库中的代理实例讲解
2018/05/07 Python
python 实时得到cpu和内存的使用情况方法
2018/06/11 Python
python批量下载网站马拉松照片的完整步骤
2018/12/05 Python
Django 多环境配置详解
2019/05/14 Python
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
2020/01/02 Python
flask利用flask-wtf验证上传的文件的方法
2020/01/17 Python
jupyter notebook 调用环境中的Keras或者pytorch教程
2020/04/14 Python
call在Python中改进数列的实例讲解
2020/12/09 Python
使用HTML5里的classList操作CSS类
2016/06/28 HTML / CSS
意大利奢侈品网站:Italist
2016/08/23 全球购物
英语教学随笔感言
2014/02/20 职场文书
新年爱情寄语
2014/04/08 职场文书
省级优秀班集体申报材料
2014/05/25 职场文书
卫生厅领导班子党的群众路线教育实践活动整改措施
2014/09/20 职场文书
储备店长岗位职责
2015/04/14 职场文书
离婚代理词范文
2015/05/23 职场文书
自从在 IDEA 中用了热部署神器 JRebel 之后,开发效率提升了 10(真棒)
2021/06/26 Java/Android
PHP中多字节字符串操作实例详解
2021/08/23 PHP