2)初始化游戏界面
游戏开始时,init()对保存棋盘上的棋子信息的qizi数组初始化,同时在棋盘上显示初始的4个棋子。
function init(){ initLevel();// 棋盘上初始4个棋子 showMoveInfo();//当前走棋方信息 mycanvas.addEventListener("mousedown",doMouseDown,false); } function initLevel(){//初始化界面var i,j;for (i=0; i<8; i++) {qizi[i]=new Array();for (j=0; j<8; j++) {qizi[i][j]=KONG;}}// 棋盘上初始4个棋子// 1为黑,2为白,0为无棋子qizi[3][3] = WHITE;qizi[4][4] = WHITE;qizi[3][4] = BLACK;qizi[4][3] = BLACK;DrawMap(); //画棋盘和所有棋子message_txt.innerHTML = "该黑棋走子";} //画棋盘和所有棋子 function DrawMap(){ context.clearRect ( 0 , 0 ,720 , 720); context.drawImage(qipan,0,0,qipan.width,qipan.height); for(i=0;i
showMoveInfo()显示轮到那方走棋。
function showMoveInfo(){ if (curQizi== BLACK)// 当前走棋方是黑棋 message_txt.innerHTML="该黑棋走子"; else message_txt.innerHTML="该白棋走子"; }
init()函数同时对canvas添加鼠标单击事件的侦听。如果canvas被单击则执行doMouseDown函数完成走棋功能。
3)走棋过程
如果是棋盘被单击,则此位置像素信息(event.pageX,event.pageY)可以转换成棋盘坐标 (x1,y1),然后判断当前位置(x1, y1)是否可以放棋子(符合夹角之势),如果可以则此位置显示自己棋子图形,调用FanALLQi(i, j)从左,左上,上,右上等八个方向翻转对方的棋。最后判断对方是否有棋可走,如果对方可以走棋则交换走棋方。如果对方不可以走棋,则自己可以继续走棋,直到双方都不能走棋,显示输赢信息。
function doMouseDown(event){ var x = event.pageX; var y = event.pageY; var canvas = event.target; var loc = getPointOnCanvas(canvas, x, y); console.log("mouse down at point( x:" + loc.x + ", y:" + loc.y + ")"); clickQi(loc); } function getPointOnCanvas(canvas, x, y){ var bbox = canvas.getBoundingClientRect(); return { x: x - bbox.left * (canvas.width / bbox.width), y: y - bbox.top * (canvas.height / bbox.height)}; } function clickQi(thisQi){var x1, y1;x1 = Math.round((thisQi.y - 40) / 80); y1 = Math.round((thisQi.x - 40) / 80); //Math.round()四舍五入if (Can_go(x1, y1)) {// 判断当前位置是否可以放棋子//trace("can");qizi[x1][y1] = curQizi;FanALLQi(x1, y1);//从左,左上,上,右上,右,右下,下,左下方向翻转对方的棋DrawMap();//判断对方是否有棋可走,如有交换走棋方if (curQizi==WHITE &&checkNext(BLACK) ||curQizi==BLACK &&checkNext(WHITE)) {if (curQizi==WHITE) {curQizi=BLACK;message_txt.innerHTML = "该黑棋走子";} else {curQizi=WHITE;message_txt.innerHTML = "该白棋走子";}} else if (checkNext(curQizi)) { //判断自己是否有棋可走,如有,给出提示 message_txt.innerHTML = "对方无棋可走,请继续";} else {//双方都无棋可走,游戏结束,显示输赢信息isLoseWin();}//统计双方的棋子数量,显示输赢信息。} else { message_txt.innerHTML = "不能落子!";}}
4)可否落子判断
Can_go(x1,y1)从左,左上,上,右上,右,右下,下,左下八个方向判断(x1,y1)处可否落子。
function Can_go(x1, y1){//从左,左上,上,右上,右,右下,下,左下八个方向判断if (CheckDirect(x1, y1, -1, 0) == true) {return true;}if (CheckDirect(x1, y1, -1, -1) == true) {return true;}if (CheckDirect(x1, y1, 0, -1) == true) {return true;}if (CheckDirect(x1, y1, 1, -1) == true) {return true;}if (CheckDirect(x1, y1, 1, 0) == true) {return true;}if (CheckDirect(x1, y1, 1, 1) == true) {return true;}if (CheckDirect(x1, y1, 0, 1) == true) {return true;}if (CheckDirect(x1, y1, -1, 1) == true) {return true;}return false;}
CheckDirect()判断某方向上是否形成夹击之势,如果形成且中间无空子则返回True。
function CheckDirect(x1, y1, dx, dy){ var x,y; var flag= false; x = x1 + dx; y = y1 + dy; while (InBoard(x, y) && !Ismychess(x, y) && qizi[x][y] != 0) { x += dx; y += dy; flag = true;//构成夹击之势 } if (InBoard(x, y) && Ismychess(x, y) && flag == true) { return true;//该方向落子有效 } return false; }
checkNext(i)验证参数代表的走棋方是否还有棋可走。
/** * 验证参数代表的走棋方是否还有棋可走 * @param i 代表走棋方,1为黑方,2为白方 * @return true/false */function checkNext(i){ old=curQizi; curQizi=i;if ( Can_Num()>0) { curQizi=old;return true;} else { curQizi=old;return false;}}
Can_Num()统计可以落子的位置数。
function Can_Num(){//统计可以落子的位置数 var i, j, n = 0; for (i = 1; i <= 8; i++) { for (j = 1; j <= 8; j++) { if (Can_go(i, j)) { n = n + 1; } } } return n;//可以落子的位置个数 }
5)翻转对方的棋子
FanALLQi(int x1, int y1) 从左,左上,上,右上,右,右下,下,左下八个方向翻转对方的棋子。
function FanALLQi(x1, y1){//从左,左上,上,右上,右,右下,下,左下八个方向翻转if (CheckDirect(x1, y1, -1, 0) == true) {DirectReverse(x1, y1, -1, 0);}if (CheckDirect(x1, y1, -1, -1) == true) {DirectReverse(x1, y1, -1, -1);}if (CheckDirect(x1, y1, 0, -1) == true) {DirectReverse(x1, y1, 0, -1);}if (CheckDirect(x1, y1, 1, -1) == true) {DirectReverse(x1, y1, 1, -1);}if (CheckDirect(x1, y1, 1, 0) == true) {DirectReverse(x1, y1, 1, 0);}if (CheckDirect(x1, y1, 1, 1) == true) {DirectReverse(x1, y1, 1, 1);}if (CheckDirect(x1, y1, 0, 1) == true) {DirectReverse(x1, y1, 0, 1);}if (CheckDirect(x1, y1, -1, 1) == true) {DirectReverse(x1, y1, -1, 1);}}
DirectReverse()针对已形成夹击之势某方向上的对方棋子进行翻转。
function DirectReverse(x1, y1, dx, dy){var x, y;var flag= false;x = x1 + dx;y = y1 + dy;while (InBoard(x, y) && !Ismychess(x, y) && qizi[x][y] != 0) {x += dx;y += dy;flag = true;//构成夹击之势}if (InBoard(x, y) && Ismychess(x, y) && flag == true) {do {x -= dx;y -= dy;if ((x != x1 || y != y1)) {FanQi(x, y);}} while ((x != x1 || y != y1));}}
FanQi(int x, int y)将存储(x, y)处棋子信息qizi[x][y]的反色处理。
function FanQi(x, y){if (qizi[x][y] == BLACK) {qizi[x][y] = WHITE;} else {qizi[x][y] = BLACK;}}
InBoard()判断(x,y)是否在棋盘界内,如果在界内则返回真,否则返回假。
//InBoard()判断(x,y)是否在棋盘界内,如果在界内则返回真,否则返回假。 function InBoard(x,y){if (x >= 0 && x <= 7 && y >= 0 && y <= 7) {return true;} else {return false;}}
6)显示执棋方可落子位置
“走棋提示”按钮单击事件函数是DoHelp(),它显示可以落子的位置提示。Show_Can_Position()用图片i显示可以落子的位置。
function DoHelp(){ showCanPosition();//显示可以落子的位置 } function showCanPosition(){ //显示可以落子的位置 var i,j; var n = 0;//可以落子的位置统计 for (i = 0; i <= 7; i++) { for (j = 0; j <= 7; j++) { if (qizi[i][j] == 0 && Can_go(i, j)) { n = n + 1; pic=info; context.drawImage(pic,w*j+20,h*i+20,pic.width,pic.height);;//显示提示图形 } } } }
7)判断胜负功能
isLoseWin()统计双方的棋子数量,显示输赢信息。
// 显示输赢信息 function isLoseWin(){ var whitenum = 0; var blacknum = 0; var n = 0,x,y; for (x = 0; x <= 8; x++) { for (y = 0; y <= 8; y++) { if (qizi[x][y] != 0) { n = n + 1; if (qizi[x][y] == 2) { whitenum += 1; } if (qizi[x][y] == 1) { blacknum += 1; } } } } if (blacknum > whitenum) { message_txt.innerHTML = "游戏结束黑方胜利,黑方:" + String(blacknum) + "白方:" + String(whitenum); } else { message_txt.innerHTML = "游戏结束白方胜利, 黑方:" + String(blacknum) + "白方:" + String(whitenum); } }
至此就完成黑白棋游戏设计了。