本节的主要工作是给棋子添加鼠标事件,实现选中棋子、走子以及吃子等功能,同时将服务器端的基础搭建好。

棋盘初始化完成之后,棋盘背景、棋子位置都已经绘制完毕。这时候就需要给上层的Canvas添加鼠标事件的侦听:

me.piecesCanvas.addEventListener("click",me.onClick,false);

当鼠标在棋盘区域进行单击事件的时候,就会触发me.onClick函数的执行,下面就看一下me.onClick的定义

me.onClick = function(e) {
    var x = e.clientX - me.startX - me.piecesCanvas.offsetLeft;
    var y = e.clientY - me.startY - me.piecesCanvas.offsetTop;
    var lineX = x / me.xStep;
    var lineY = y / me.yStep;
    lineX = parseInt(lineX + 1.5);
    lineY = parseInt(lineY + 1.5);
    var pX = (lineX - 1) * me.xStep;
    var pY = (lineY - 1) * me.yStep;
    var dist = Math.sqrt((x - pX) * (x - pX) + (y - pY) * (y - pY));
    var r = me.getPiecesR();
    if (dist < r) {
        if (me.status == "idle") {
            var selectPoint = me.board[lineY][lineX];
            if (selectPoint == "") {
                return;
            } else {
                var selectArr = selectPoint.split("-");
                var position = selectArr[0];
                var pieceStr = selectArr[1];
                if (position == "our") {
                    me.activePiece = pieceStr;
                    me.piecesList["our"][pieceStr].active = true;
                    me.status = "active";
                    me.reDrawPieces();
                }
            }
        } else if (me.status == "active") {
            var selectPoint = me.board[lineY][lineX];

            if (selectPoint == "") {
                me.pieceMoveTo("our", me.activePiece, lineX, lineY);
                me.piecesList["our"][me.activePiece].active = false;
                me.activePiece = "";
                me.status = "idle";
                me.reDrawPieces();
            } else {
                var selectArr = selectPoint.split("-");
                var position = selectArr[0];
                var pieceStr = selectArr[1];
                if (position == "opposite") {
                    me.pieceMoveTo("our", me.activePiece, lineX, lineY);
                    me.piecesList["our"][me.activePiece].active = false;
                    me.activePiece = "";
                    me.status = "wait";
                    me.reDrawPieces();
                } else if (position == "our") {
                    me.piecesList["our"][me.activePiece].active = false;
                    me.piecesList["our"][pieceStr].active = true;
                    me.activePiece = pieceStr;
                    me.reDrawPieces();
                }
            }

        }
    }
};

这里主要将棋局分成三个状态,idle、active和wait。在idle状态,我方可以选子,一旦选定一个棋子,状态就变成active状态,被选中棋子的active属性就变成true。active状态下,继续侦听鼠标事件,当鼠标选再次单击时判断单击的位置。如果仍然选中了我方棋子,那么就更改被选中的棋子,就是换一个棋子走。如果选中了空白棋子,就走到该位置,棋局状态变为wait状态。如果选中的是对方棋子,那么吃掉对方棋子,棋局状态变成wait状态。这里注意两点:一是还没有考虑不同棋子的走子规则,马走日字象走田嘛,这个以后添加。二是wait状态之后就需要和服务器通讯了,现在也还没有实现。

另外,服务器端使用express来处理web请求,同时使用socket.io来进行websocket通讯。服务端代码大致如下:

var express = require('express')
  , routes = require('./routes');

var app = module.exports = express.createServer();
var io = require('socket.io').listen(app);
// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.set('view options',{layout:false});
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

// Routes

app.get('/', routes.index);
var conns={};
io.sockets.on('connection',function(socket){
	//do something
});
app.listen(3000, function(){
  console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});

最近时间太紧,以后慢慢写。