JS实现五子棋(二)外观分析及绘制

上期内容:

JS实现五子棋(一)目标分析

一、外观分析

还记得最开始我们进行目标分析之前画了一个草图,就按照这个草图描绘的外观进行分析

棋盘是N*N正方形,通常是15*15,那么棋盘就是由横向16条,纵向16条的线段组合而成。

为了方便实现,不考虑页面尺寸兼容,这里使用固定的棋盘边长a,棋盘单元格边长使用c=a/N

棋子是可以落在棋盘格子的边缘上,所以棋盘的边缘与边线需要加一段边距。

落子规则是落在横纵线交叉点上,棋子是黑白两色的正圆形,为了美观一点,棋子直径要小于棋盘单元格边长,这样相邻的棋子之间就能够留出一些空隙,显得不那么拥挤。

根据分析内容画出棋盘原型图

根据操作制作玩家信息展示区域的原型,总共分为两块,每一块显示4个信息,分别是玩家名称,落子步数,玩家阵营(黑子、白子),玩家类型(人类、机器)

根据分析内容画出用户信息区域原型图

分析到这里也画出了原型,可以开始照此实现了。

二、外观绘制

棋盘绘制

首先创建一个棋盘的类并定义基础变量,比如棋盘canvas的对象变量、棋盘边长、单元格数量等等。

<canvas id="canvas"></canvas>
function Plate(){   // 这个名字起坏了,别在意
let cxt2d = canvas = null;  // canvas上下文对象
  let canvasSideLen = 780;  // px canvas画布大小
  let plateSideLen = 0;  // 棋盘边长 需要进行初始化计算
  let plateLineWidth = 1;  // px 棋盘线条宽度
  let cellNumOneSide = 15;  // 棋盘单边单元格数量
  let cellSideLen = 0;    // px 单元格边长 需要计算初始化
  let initCxt = function(){
    // 初始化棋盘画布
  }
  let initPlateAttr = function(){
    // 初始化并计算棋盘相关变量,棋盘边长、单元格边长
  }
  let renderPlate = function() {
    // 使用矩形绘制边框并填充颜色或图片 
    // 循环绘制出横纵格线   
  }
  // 分别按顺序进行调用
  initCxt();
  initPlateAttr();
  renderPlate();
}
<script>
var plate = new Plate();  // 初始化棋盘对象
</script>

棋盘的初步样子就可以显示出来了

棋子绘制

因为棋盘是固定样式基本不会变化,而棋子是可以添加、清除,所以考虑将棋子使用单独的一个canvas透明层,叠加在棋盘层之上,使绘制出的棋子对齐到格线交点上,落子的外观就做好了。

在上期内容里假设了棋盘具有绘制棋子和清除棋盘的功能,所以初始化变量、绘制棋子及清除棋盘的方法就可以添加到Plate对象中。

棋子是圆形,canvas绘制圆形需要原点坐标,以及半径,所以要在对象中定义这些变量并根据棋盘尺寸计算。

<!--定义棋子层-->
<canvas id="chess"></canvas>
/* canvas使用定位,将各层叠加起来 */
canvas {
position: absolute;
top: 0;
left: 0;
margin: 0 auto;
cursor: pointer;
}
function Plate(){
  ... 
  let cxtChess2d = null;   //棋子画布
  let plateOriginPosX = 0;  //棋盘原点坐标X
  let plateOriginPosY = 0;  //棋盘远点坐标Y
  let drawChessBasePosX = 0;  //棋子坐标基准X
  let drawChessBasePosY = 0;  //棋子坐标基准Y
  let singleChessRadius = 0;  //棋子半径
  let initPlateAttr = function(){
    ...
    //初始化和计算棋盘原点和棋子坐标基准
  }
  //绘制一个棋子,传入绘制位置 v:垂直位置,h:横向位置 以及颜色
  let drawOneChess = function (y, x, color) {
    // 通过v和h,单元格边长,棋子坐标基准,计算当前棋子坐标,
    // currentX=drawChessBasePosX + x * cellSideLen
    // currentY=drawChessBasePosY + y * cellSideLen
    // 使用cxtChess2d绘制圆形,并填充color
  }
  
  //测试在[0,0]位置绘制一颗黑色棋子
  drawOneChess(0,0,'#000');
}

对于棋盘对象,需要开放绘制棋子和清空棋盘内棋子的方法,后期在控制器落子动作需要使用到开放出来的绘制功能,重新开始游戏时需要使用到清空棋盘的功能。

function Plate(){
  ...
  this.renderOneChess = function(v,h,color){
    drawOneChess(v,h,color);
  };
  
  let clearAllChessDraw = function () {
    //清除cxtChess2d整个画布矩形区域
  };
  this.clearAll = function(){
    clearAllChessDraw();
  };
}
<script>
var plate = new Plate();  // 初始化棋盘层和棋子层
plate.renderOneChess(0,0,'#000');  //在0,0绘制一个黑色棋子
plate.renderOneChess(1,1,'#fff');  //在1,1绘制一个白色棋子

//清除棋子
//plate.clearAll();
</script>

此时以及棋盘和棋子的绘制工作就基本完成了,至于玩家信息,先直接用html+css实现一下,就像下面图里的样子

右侧暂时写死

到这里外观的绘制就算基本完成了,可以提供棋盘、棋子的绘制,以及玩家信息显示的面板。

下一期要开始让游戏可以玩起来,引入棋子对象、玩家对象、控制器、棋子运行时对象、事件绑定、棋盘矩阵、棋子渲染等。

原文发布于微信公众号 - 可回收BUG(way-of-full-stack)

原文发表时间:2019-07-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券