作者:老葛 亚艾元软件
这是我开发好的效果:
图8-2-3-1
代码可以在github上面下载。
前面我们已经熟悉了微信小程序的基本结构,我打算先写一个微信小程序下面的象棋播放器,作为练手。我花了整整一个周末的时间,终于搞定了。现在我介绍一下大致的流程:
首先,需要熟悉微信小程序有关canvas的文档
https://mp.weixin.qq.com/debug/wxadoc/dev/component/canvas.html#canvas
图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
|
采用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,在有的手机上显示有问题。