You are here

Drupal8+微信小程序:3,实现象棋棋谱播放器

作者:老葛 亚艾元软件

这是我开发好的效果:

8-2-3-1.png 

8-2-3-1

   代码可以在github上面下载。

   前面我们已经熟悉了微信小程序的基本结构,我打算先写一个微信小程序下面的象棋播放器,作为练手。我花了整整一个周末的时间,终于搞定了。现在我介绍一下大致的流程:

   首先,需要熟悉微信小程序有关canvas的文档

https://mp.weixin.qq.com/debug/wxadoc/dev/component/canvas.html#canvas

8-2-3-2.png 

8-2-3-2

 

   微信文档里面给出了例子,我们可以让它的代码跑起来。

 

画一个象棋棋盘:

让你画一个象棋棋盘,你一定开始觉得无从下手。如果让你在canvas上面画一条直线,这应该不会是一个难的问题。实际上,一个棋盘,就是由这样的一条一条的线构成,我们把它一条一条的画出来,最终就会画成我们的棋盘。

我开发小程序棋谱播放器的时候,就是按照这样的思路,我在小程序的canvas上面画了一条线,成功了。Github上面,有多个象棋棋谱播放器的程序,我也下载了很多,作为参考。

画一条直线:

function lineDrawing(context, mx, my, lx, ly) {

context.beginPath()

context.moveTo(mx, my)

context.lineTo(lx, ly)

context.stroke()

}

  开始的时候,没有对代码进行封装,后来改造为了一个函数。

 

  画一个棋盘:

function qipanDrawing(context, offsetX, offsetY, cellSize) {

    context.setStrokeStyle("brown")

    context.setLineWidth(2)

    //context.rect(3, 3, 320, 360)

    //context.stroke()

for(var i= 1; i< 8; i++){

lineDrawing(context,cellSize * i + offsetX, offsetY, cellSize * i + offsetX, cellSize * 4 + offsetY)

lineDrawing(context,cellSize * i + offsetX, cellSize * 5 + offsetY, cellSize * i + offsetX, cellSize * 9 + offsetY)

}

 

//棋盘行

for(var i= 0; i<10; i++){

lineDrawing(context,offsetX, i * cellSize + offsetY, cellSize * 8 + offsetX, i * cellSize + offsetY)

}


lineDrawing(context,offsetX, offsetY, offsetX, cellSize * 9 + offsetY)

lineDrawing(context,cellSize * 8 + offsetX, offsetY, cellSize * 8 + offsetX, cellSize * 9 + offsetY)

 

lineDrawing(context, cellSize * 3 + offsetX, offsetY, cellSize * 5 + offsetX, cellSize * 2 + offsetY)

//lineDrawing(context, cellSize * 3 + offsetX, offsetY, cellSize * 5 + offsetX, cellSize * 2 + offsetY)

lineDrawing(context, cellSize * 5 + offsetX, offsetY, cellSize * 3 + offsetX, cellSize * 2 + offsetY)

lineDrawing(context, cellSize * 3 + offsetX, cellSize * 9 + offsetY, cellSize * 5 + offsetX, cellSize * 7 + offsetY)

lineDrawing(context, cellSize * 5 + offsetX, cellSize * 9 + offsetY, cellSize * 3 + offsetX, cellSize * 7 + offsetY)


var unit = 4;

//var centers = [];

    centerDrawing(context,cellSize * 1 + offsetX, cellSize * 2 + offsetY, unit)

centerDrawing(context,cellSize * 7 + offsetX, cellSize * 2 + offsetY, unit)

centerDrawing(context,cellSize * 0 + offsetX, cellSize * 3 + offsetY, unit)

centerDrawing(context,cellSize * 2 + offsetX, cellSize * 3 + offsetY, unit)

centerDrawing(context,cellSize * 4 + offsetX, cellSize * 3 + offsetY, unit)

centerDrawing(context,cellSize * 6 + offsetX, cellSize * 3 + offsetY, unit)

centerDrawing(context,cellSize * 8 + offsetX, cellSize * 3 + offsetY, unit)

centerDrawing(context,cellSize * 0 + offsetX, cellSize * 6 + offsetY, unit)

centerDrawing(context,cellSize * 2 + offsetX, cellSize * 6 + offsetY, unit)

centerDrawing(context,cellSize * 4 + offsetX, cellSize * 6 + offsetY, unit)

centerDrawing(context,cellSize * 4 + offsetX, cellSize * 6 + offsetY, unit)

centerDrawing(context,cellSize * 8 + offsetX, cellSize * 6 + offsetY, unit)

    centerDrawing(context,cellSize * 1 + offsetX, cellSize * 7 + offsetY, unit)

centerDrawing(context,cellSize * 7 + offsetX, cellSize * 7 + offsetY, unit)



context.setFillStyle("#000000");

context.setFontSize(cellSize * 0.75)

//console.log(cellSize *1 + 5 + offsetX)

//console.log( cellSize *5 - 10  + offsetY)

offsetX = offsetX +15

context.fillText("", cellSize *1 + 5 + offsetX, cellSize *5 - 10  + offsetY);

//context.fillText("", 65, 210);

context.fillText("", cellSize *2 + 5 + offsetX, cellSize *5 - 10 + offsetY);

context.fillText("", cellSize *5 + 5 + offsetX, cellSize *5 - 10 + offsetY);

context.fillText("", cellSize *6 + 5 + offsetX, cellSize *5 - 10 + offsetY);

offsetX = offsetX -10

context.setFontSize(cellSize * 0.3)

context.fillText("", cellSize * 3 + 5 + offsetX, cellSize * 4.5 -5 + offsetY);

context.fillText("", cellSize * 4 - 5 + offsetX, cellSize * 4.5 -5 + offsetY);

    context.fillText("", cellSize * 4.5 +5 + offsetX, cellSize * 4.5 -5 + offsetY);

    context.fillText("", cellSize * 3 + 5 + offsetX, cellSize *5 - 5 + offsetY);

context.fillText("", cellSize * 4 - 5 + offsetX, cellSize *5 - 5 + offsetY);

    context.fillText("", cellSize * 4.5 +5 + offsetX, cellSize *5 - 5 + offsetY);  

}

  其中centerDrawing用来画象棋棋盘里面的中心点,对应函数:

function centerDrawing(context, x, y, unit) {

//中心点

x =x;

y = y;

//左上

if(x - unit > 20){

  lineDrawing(context, x - unit, y - 3 * unit, x - unit, y - unit);

  lineDrawing(context, x - unit, y - unit, x - 3 * unit, y - unit);

    }

//右上

if(x + unit < unit * 80){

lineDrawing(context, x + unit, y - 3 * unit, x + unit, y - unit);

lineDrawing(context, x + unit, y - unit, x + 3 * unit, y - unit);

}

//左下

if(x - unit > 20){

  lineDrawing(context, x - unit, y + 3 * unit, x - unit, y + unit);

  lineDrawing(context, x - unit, y + unit, x - 3 * unit, y + unit);

}

//右下

if(x + unit < unit * 80){

lineDrawing(context, x + unit, y + 3 * unit, x + unit, y + unit);

lineDrawing(context, x + unit, y + unit, x + 3 * unit, y + unit);

}

}

  context.fillText用来在棋盘上面写字,我们知道棋盘上面通常有楚河汉界四个字。

context.fillText("", cellSize *1 + 5 + offsetX, cellSize *5 - 10  + offsetY);

  在这四个字之间,我增加了“亚艾元象棋网”6个小字。

 

画一个棋子:

   棋盘画出来以后,在棋盘上面加个棋子,其实就是在指定位置画一个圈,加个背景色,然后再写个字。先画一个棋子,然后将它总结成为函数:

function qiziDrawing(context, x, y, qizi_text, isred) {

context.setLineWidth(2)


context.beginPath()

    context.arc(x+1, y+1, 18, 0, 2 * Math.PI)

context.setFillStyle("rgba(250, 240, 240,1)")

    context.fill();

var stroke_style = isred ? "red" : "#000000";

    context.setStrokeStyle(stroke_style)

    context.stroke()

    //context.stroke();

context.setFillStyle(stroke_style);

    context.setTextAlign('center')

context.setFontSize(30)

    context.fillText(qizi_text, x+1, y+11);  

}

 

画一个局面:

   在象棋里面,通常使用一个fen字符串来表示象棋的当前局面,有关fen字符串的更详细的内容,可以参考象棋百科全书里面的介绍。这里简单加以介绍。

为方便表示,中国象棋的棋子名称除了用汉字以外,还可以用字母,字母可从国际象棋中稍加改动得到,而数字是为了方便棋谱的输入(以便用在数字小键盘上)(见表一)

红方黑方字母相当于国际象棋中的棋子数字帅将KKing(王)1仕士AAdvisor(没有可比较的棋子)2相象B[1]Bishop(象)3马马N[2]Knight(马)4车车RRook(车)5炮炮CCannon(没有可比较的棋子)6兵卒PPawn(兵)7

 

表一 中国象棋棋子代号[1] 世界象棋联合会推荐的字母代号为E(Elephant)[2] 世界象棋联合会推荐的字母代号为H(Horse)

 

     其中红方用大写,黑方用小写。

 

另外,对于棋谱招法,我们采用ICCS格式:

  ICCS是中国象棋互联网服务器(Internet Chinese Chess Server)的缩写。在网络对弈服务器处理着法时,把着法表示成起点和终点的坐标是最方便的

,因此这种格式最早在计算机上使用。

 

1. H2-E2(炮二平五) H7-E7(炮8平5)2. E2-E6(炮五进四) D9-E8(士4进5)3. H0-G2(马二进三) H9-G7(马8进7)4. B2-E2(炮八平五) B9-C7(马2进3)5. E6-E4(前炮退二) I9-H9(车9平8)6. ……(如右图)   

 

  在中国象棋通用引擎协议(UCCI协议)中,坐标格式得到进一步简化,例如H2-E2记作h2e2,把符号限制在一个32位数据中,处理起来速度更快。

8-2-3-3.png

图8-2-3-3

 

采用ICCS简写的形式。

 

"rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w"

局面分两部分:"rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR, w"。第一部分,表示每个位置上面的棋子,第二部分表示当前该有哪方走棋。

对于第一部分,这就是一个字符串。里面的字母用来表示对应的棋子。数字表示棋盘这一行,连续多少个位置上面没有棋子。从上面到下面共有10行,9表示这一行一个棋子也没有。

 

从这里,我们可以看出,一个局面包含了多个棋子,并且包含了这些棋子的位置信息。我们将局面的fen字符串,循环处理,分别画出单个棋子。最终就组成了一个当前局面。

function fenDrawing(context, fen, offsetX, offsetY, cellSize) {

  if(fen == ''){

    fen = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w";

  }

  var fen_array =new Array();

  var qiju = new Array();

  fen_array = fen.split("/");

  //console.log(fen_array);

  //console.log(fen);

  //var length = arr.length;

  for (var i = 0; i < 10; i++) {

    var fen_item = fen_array[i] || '';

var k = 0;

    if(fen_item == '' || fen_item == '9'){

  continue;

    }else{

  for(var j=0;j<fen_item.length; j++){

if(k >8){

   break;

}  

 var qizi_name = fen_item.charAt(j);

if(/^\d+$/.test(qizi_name)){

  k = parseInt(qizi_name) + k;

          //console.log(k);

          //console.log(qizi_name);    

}else{

  var qizi_text = convertMachineToReadName(qizi_name);

  var isred = (qizi_name === qizi_name.toUpperCase());

  

  qiziDrawing(context, cellSize * k + offsetX, cellSize * i + offsetY, qizi_text, isred);

  k++;

}


 

  }    


}  

  }

  context.draw()

}

  同样我将一个局面分装成了一个函数。先手动的一个一个画出一个局面,最后再做的封装。

 

  招法与局面的转换

    一个棋谱,有一个初始局面,还有一个招法列表。每走一步,就是一个新的局面,为了方便,我根据初始局面,还有招法,生成一个局面数组。这个数组里面包含了这个棋谱的所有局面,每一步的局面。前面我们能够画出,一个局面的canvas表示,每到一个局面,我们都给它重新画一遍。 这些代码,写好以后,对齐做以下封装,这样方便调用。

function getFenList(fen, moves) {

  var fen_list = new Array();

  fen_list[0] = fen;

  var total_steps = Math.floor(moves.length / 4);

  var current_fen = fen;

  for(var i = 1; i<= total_steps ; i++){

var move = moves.substring((i-1) * 4, i * 4);

    fen_list[i] = nextFen(current_fen, move);

    current_fen = fen_list[i];    

  }

  return fen_list;

}

function nextFen(fen, move) {

  var x_array = new Array();

    x_array["a"] = "0";

    x_array["b"] = "1";

x_array["c"] = "2";

x_array["d"] = "3";

x_array["e"] = "4";

x_array["f"] = "5";

x_array["g"] = "6";

x_array["h"] = "7";

x_array["i"] = "8";


  if(fen == ''){

    fen = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w";

 

  }

  var fen_twoparts = fen.split(" ");

  var fen_first = fen_twoparts[0];

  var fen_second = fen_twoparts[1] || 'w';

  var fen_array =new Array();

  fen_array = fen_first.split("/");

  

  var from_x = move.charAt(0);

  var from_y = move.charAt(1);

  var from_fen_item = fen_array[9-from_y];

  var to_x = move.charAt(2);

  var to_y = move.charAt(3);

  var to_fen_item = fen_array[9-to_y];

  if(from_y == to_y){

var from_row_array = fenItemToRowArray(from_fen_item);

//todo

var from_x_index = x_array[from_x];

var qizi_name = from_row_array[from_x_index];

    from_row_array[from_x_index] = '';

//from_fen_item = rowArrayToFenItem(from_row_array);

var to_x_index = x_array[to_x];

    from_row_array[to_x_index] = qizi_name;


fen_array[9-from_y] = rowArrayToFenItem(from_row_array);

  

  }else{

var from_row_array = fenItemToRowArray(from_fen_item);

//todo

var from_x_index = x_array[from_x];

var qizi_name = from_row_array[from_x_index];

    from_row_array[from_x_index] = '';

//from_fen_item = rowArrayToFenItem(from_row_array);

fen_array[9-from_y] = rowArrayToFenItem(from_row_array);


var to_row_array = fenItemToRowArray(to_fen_item);

//todo

var to_x_index = x_array[to_x];

    to_row_array[to_x_index] = qizi_name;

//from_fen_item = rowArrayToFenItem(from_row_array);

fen_array[9-to_y] = rowArrayToFenItem(to_row_array);

  

  }

  

  fen_first = fen_array.join("/");

  if(fen_second == 'w'){

fen_second = 'b';  

  }else{

fen_second = 'w';  

  }

  var next_fen = fen_first + ' ' + fen_second;

  return next_fen;

  

  

}

 

function fenItemToRowArray(fen_item) {

  var row_array = new Array();

  var k = 0;  

  for(var j=0;j<fen_item.length; j++){

if(k >8){

  break;

}

var qizi_name = fen_item.charAt(j);

if(/^\d+$/.test(qizi_name)){

var g = 0;

while(g < qizi_name){

row_array[k] = '';

k++;

g++;

if(k >8){

  break;

}  

}

}else{

row_array[k] = qizi_name;

    k++;  

}

  }

  return row_array;

}

 

function rowArrayToFenItem(row_array) {

var fen_item ="";

var k = 0;

for(var i = 0; i < row_array.length; i++){

if(row_array[i] != ''){

  if(k == 0){

fen_item = fen_item + row_array[i];  

  }else{

fen_item = fen_item + k + row_array[i];

k = 0;

  }

  

}else{

  k++;

}

}

if(k > 0){

  fen_item = fen_item + k;

}

return fen_item;

}

这样,当一个棋谱加载的时候,初始局面的canvas表示,我们就可以轻松实现了。

var util = require('../../utils/util.js')

Page({

  data: {

    current_step: 0,

total_steps: 0,

fen_list: [],

    auto_play_text:'自动',

auto_play:false,

    qipu: {}

  },

     

  onReady: function (e) {

    // 使用 wx.createContext 获取绘图上下文 context

    var context = wx.createCanvasContext('qipuCanvas')

var offsetX = 20

    var offsetY = 20

var cellSize = 40;


var qipu = {

  //fen: "rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w",

  title:'王天一 先胜 赵国荣',

  event:'“腾讯棋牌”2017年全国象棋男子甲级联赛',

      fen:'',   

  //moves: 'h0g2i9h9i0h0c6c5g3g4b9c7b0a2a6a5b2c2c7b5a0a1c9e7h0h6d9e8a1d1b5a3d1b1h7i7h6g6b7c7c2c1i7i8g4g5i8g8g6f6g8g5g2f4c7c6f6f8a9d9b1b6c6c8f8f6h9h4f4e6g7e6e2e6a3c2g0e2h4d4f0e1c2e3f6f3e3d5e6e5c8c9e0f0d9d7b6b9e9d9c1c2d5c7b9a9d4e4c2d2d7d2e5e8d2d0e1d0f9e8d0e1d9e9f3f5a5a4c3c4c5c4a9a4e4e3i3i4e3e4a4a7g5g7a7a3e4i4a3g3c7e6f5f6i4e4g3g4e4g4e2g4e6c5f6i6c4d4'

      moves:'g0e2b7d7a0a1b9c7a1d1f9e8b0a2a9b9a3a4b9b5d1d4b5f5a2b4c6c5h2h1h7h5h1c1c7d5d4h4d5f4c1f1f4h3h4h3d7h7h3h5f5h5h0g2g9e7b4a6h5h1f1f4g6g5f4i4h9i7f0e1i6i5i4d4i7h5d4d3e6e5b2b5i9i6a6b4h1h2d3d2i6e6b4d3h5g3d3e5h7g7i0f0h2h6c3c4e6f6f0i0h6h2g2f0h2h6c4c5e7c5f0g2c5e7e5c4h6g6b5b6f6b6c4b6g6b6i0h0b6g6h0h4g5g4e2g4g7g4g2i1g4g5h4g4g3h1i1h3h1i3g4g0i5i4h3f4g6h6f4d5i4h4c0e2g5e5g0g3i3h5e3e4e5e2e1f2h6e6d5c3e6d6d2d5e2b2d5e5e9f9g3f3d6f6e5f5f9e9c3d5f6d6e4e5b2b5d5c3b5f5f3f5h5g7f5f4h4h3c3d5g7i6d0e1i6g5a4a5h3g3a5b5g5h3d5b6d6c6e0d0e8d7e5d5d9e8f4d4g3f3d5d6c6c0d0d1c0c1d1d0c1c0d0d1f3f2d4h4c0c1d1d0c1c3h4h9e8f9b6d7e9d9h9f9d9d8f9f8d8d9f8e8c3c0d0d1c0c1d1d0c1c0d0d1c0c1d1d0c1c7b5c5f2e2c5c6e2e1c6c7h3f2e8e9d9d8c7c8'

}

 

var init_fen= "rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w";

//fen = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w";

//fen = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR b";

//fen = "rnbakab1r/9/1c4nc1/p1p1p1p1p/9/9/P1P1P1P1P/1C2C4/9/RNBAKABNR w";

//h2e2 h9g7

var moves = 'h0g2i9h9i0h0c6c5g3g4b9c7b0a2a6a5b2c2c7b5a0a1c9e7h0h6d9e8a1d1b5a3d1b1h7i7h6g6b7c7c2c1i7i8g4g5i8g8g6f6g8g5g2f4c7c6f6f8a9d9b1b6c6c8f8f6h9h4f4e6g7e6e2e6a3c2g0e2h4d4f0e1c2e3f6f3e3d5e6e5c8c9e0f0d9d7b6b9e9d9c1c2d5c7b9a9d4e4c2d2d7d2e5e8d2d0e1d0f9e8d0e1d9e9f3f5a5a4c3c4c5c4a9a4e4e3i3i4e3e4a4a7g5g7a7a3e4i4a3g3c7e6f5f6i4e4g3g4e4g4e2g4e6c5f6i6c4d4';

    //var moves = 'h0g2i9h9i0h0c6c5';

 

var fen_list = util.getFenList(qipu.fen, qipu.moves)

//this.setData({

    //    fen_list:fen_list

    //})


var total_steps = Math.floor(qipu.moves.length / 4);

this.setData({

qipu:qipu,

fen_list:fen_list,

        total_steps:total_steps

    })

console.log(fen_list);


util.qipanDrawing(context,offsetX, offsetY, cellSize)

util.fenDrawing(context, fen_list[this.data.current_step], offsetX, offsetY, cellSize)


this.gotoInit()



  }

})

 

<button type="default" size="mini" plain="true" bindtap="gotoPrevious" hover-class="qipu-button-hover"> 后退 </button>

 

实现控制按钮:

在模板文件里面添加:

<view>

<!-- canvas.wxml -->

<canvas style="width: 360px; height: 400px;" canvas-id="qipuCanvas"></canvas>

<!-- 当使用绝对定位时,文档流后边的 canvas 的显示层级高于前边的 canvas -->

<view>

<button type="default" size="mini" plain="true" disabled="true" hover-class="qipu-button-hover">{{current_step}}/{{total_steps}}</button>

 

<button type="default" size="mini" plain="true" bindtap="gotoPrevious" hover-class="qipu-button-hover"> 后退 </button>

<button type="default" size="mini" plain="true" bindtap="gotoNext" hover-class="qipu-button-hover"> 前进 </button>

</view>

 

<view>

<button type="default" size="mini" plain="true" bindtap="gotoInit" hover-class="qipu-button-hover"> 初始 </button>

<button type="default" size="mini" plain="true" bindtap="gotoEnd" hover-class="qipu-button-hover"> 终局 </button>

<button type="default" size="mini" plain="true" bindtap="autoPlay" hover-class="qipu-button-hover"> {{auto_play_text}} </button>

</view>

<text>{{qipu.title}}</text>

<text>{{qipu.event}}</text>

</view>

   为为初始、中局、前进、后退,添加对应的代码:

gotoEnd: function (e) {

this.setData({

        current_step:this.data.total_steps

    })

var fen_list = this.data.fen_list

    var context = wx.createCanvasContext('qipuCanvas')

var offsetX = 20

    var offsetY = 20

var cellSize = 40;

util.qipanDrawing(context,offsetX, offsetY, cellSize)

util.fenDrawing(context, fen_list[this.data.current_step], offsetX, offsetY, cellSize)

  },

  gotoInit: function (e) {

this.setData({

        current_step:0

    })

var fen_list = this.data.fen_list

    var context = wx.createCanvasContext('qipuCanvas')

var offsetX = 20

    var offsetY = 20

var cellSize = 40;

util.qipanDrawing(context,offsetX, offsetY, cellSize)

util.fenDrawing(context, fen_list[this.data.current_step], offsetX, offsetY, cellSize)

  },  

  gotoNext: function (e) {

var next_step = this.data.current_step +1

if(next_step <= this.data.total_steps){

this.setData({

        current_step:next_step

    })

var fen_list = this.data.fen_list

    var context = wx.createCanvasContext('qipuCanvas')

var offsetX = 20

    var offsetY = 20

var cellSize = 40;

util.qipanDrawing(context,offsetX, offsetY, cellSize)

util.fenDrawing(context, fen_list[this.data.current_step], offsetX, offsetY, cellSize)

}

  },

  gotoPrevious: function (e) {

var previous_step = this.data.current_step - 1

if(previous_step >= 0){

this.setData({

        current_step:previous_step

    })

var fen_list = this.data.fen_list

    var context = wx.createCanvasContext('qipuCanvas')

var offsetX = 20

    var offsetY = 20

var cellSize = 40;

util.qipanDrawing(context,offsetX, offsetY, cellSize)

util.fenDrawing(context, fen_list[this.data.current_step], offsetX, offsetY, cellSize)

}

  },

 

自动播放

  我们需要使用setInterval, 以前我用过这个函数,但是第一个参数都一个一个完整的函数,而这次则是使用this.interval = setInterval(this.autoMove,2000);有所区别,试了一下,正常。注意播放完了以后,使用clearInterval清除这个定时器。对应代码:

   

autoMove: function (e) {

    this.gotoNext();

if(this.data.current_step == this.data.total_steps){

      clearInterval(this.interval);

  this.setData({

        auto_play_text:'自动',

auto_play:false

     })  

}

  },  

  autoPlay: function (e) {

    if(this.data.auto_play == false){

  this.setData({

        auto_play_text:'暂停',

auto_play:true

     })

      this.interval = setInterval(this.autoMove,2000);

    }else{

      clearInterval(this.interval);

  this.setData({

        auto_play_text:'自动',

auto_play:false

     })    

 

    }   

  

var previous_step = this.data.current_step - 1

if(previous_step >= 0){

this.setData({

        current_step:previous_step

    })

var fen_list = this.data.fen_list

    var context = wx.createCanvasContext('qipuCanvas')

var offsetX = 20

    var offsetY = 20

var cellSize = 40;

util.qipanDrawing(context,offsetX, offsetY, cellSize)

util.fenDrawing(context, fen_list[this.data.current_step], offsetX, offsetY, cellSize)

}

  },   

当前局面所在的步数,这个小功能,是后来加的。代码都分散在前面几个函数里面。

实际上,在这个棋谱播放器里面,我犯了一个错误,就是红方用的是“兵”,不是“卒”,结果我弄了一个红“卒”出来,有时候眼花,过了好长一段时间,我才发现这个问题。这是因为我在网页版的棋谱播放器里面也是用的红“卒”,我使用程序为每个棋谱动态的生成gif文件的时候,中间检查文件,偶然发现的。

还有就是棋谱默认宽度360px,算上两边的边框400px,在有的手机上显示有问题。

 



Drupal版本: