昨天看了别人写的一个中国象棋,自己也仿照着写了一下基本上效果实现了,不过还是有一些需要改进,?,不断完善吧。
代码如下:
1 DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>中国象棋title> 6 <style type="text/css"> 7 body{ 8 background: #eee; 9 } 10 #canvas,#canvas1{ 11 position: absolute; 12 left: 50%; 13 top: 50%; 14 /*宽度是250px,高度是250px*/ 15 margin-left: -250px; 16 margin-top: -250px; 17 } 18 /*层级较高*/ 19 #canvas{ 20 z-index: 10; 21 } 22 /*层级低但是有背景颜色*/ 23 #canvas1{ 24 z-index: 1; 25 background: #b3b37d; 26 } 27 #title{ 28 width: 100px; 29 height: 50px; 30 position: absolute; 31 left: 50%; 32 top: 50%; 33 margin-left: -50px; 34 margin-top: -280px; 35 text-align: center; 36 } 37 style> 38 head> 39 <body onselectstart="return false;"> 40 <h2 id="title">h2> 41 <canvas id="canvas" width="" height="">canvas> 42 <canvas id="canvas1" width="" height="">canvas> 43 body> 44 html> 45 <script type="text/javascript"> 46 //开始画象棋布局 47 //定义一个棋盘所有的棋子,这是一个二维数组 48 var chess = [ 49 //['名称(txt)','横坐标x','纵坐标y','哪边下子','判断是红棋还是黑棋','判断是什么棋'] 50 //chess.length = 32,一共32颗棋子 51 ['车',50,50,1,1,1],['车',450,50,1,1,1], 52 ['馬',100,50,1,1,2],['馬',400,50,1,1,2], 53 ['象',150,50,1,1,3],['象',350,50,1,1,3],//3 54 ['士',200,50,1,1,4],['士',300,50,1,1,4],//4 55 ['帅',250,50,1,1,5],//5 56 ['炮',100,150,1,1,6],['炮',400,150,1,1,6],//6 57 ['兵',50,200,1,1,7],['兵',150,200,1,1,7],['兵',250,200,1,1,7],['兵',350,200,1,1,7],['兵',450,200,1,1,1,7],//7 58 ['车',50,500,1,0,1],['车',450,500,1,0,1], 59 ['馬',100,500,1,0,2],['馬',400,500,1,0,2], 60 ['象',150,500,1,0,3],['象',350,500,1,0,3], 61 ['士',200,500,1,0,4],['士',300,500,1,0,4], 62 ['将',250,500,1,0,5], 63 ['炮',100,400,1,0,6],['炮',400,400,1,0,6], 64 ['卒',50,350,1,0,7],['卒',150,350,1,0,7],['卒',250,350,1,0,7],['卒',350,350,1,0,7],['卒',450,350,1,0,7] 65 ]; 66 67 //建一个数组来存放我们点击的那个棋子的所有参数 68 //参数:x坐标,y坐标,哪边下子,判断是红棋还是黑棋,判断是什么棋 69 var desc_click = [0,0,0,-1,0]; 70 //判断当前是哪边出手1表示"汉方"0表示"楚方" 71 var whose = 1; 72 73 window.onload = function (){ 74 var canvas = document.getElementById("canvas"); 75 var canvas1 = document.getElementById("canvas1"); 76 77 canvas.width = 500; 78 canvas.height = 550; 79 80 canvas1.width = 500; 81 canvas1.height = 550; 82 83 var context = canvas.getContext("2d"); 84 var context1 = canvas1.getContext("2d"); 85 86 draw_ChessBoard(context1);//画棋盘 87 draw_Chess_All(context);//画棋子 88 update_h2();//更换当前的出手的人 89 90 canvas.onclick = function(e){ 91 //三个参数 第一个是当前的context,第二个是点击的棋子到画板左边的距离,第三个是当前点击的棋子到画板上边的距离 92 get_Chess(context,e.clientX - canvas.offsetLeft,e.clientY - canvas.offsetTop); 93 update_h2(); 94 }; 95 } 96 97 //获取棋子 三个参数 第一个是在canvas上画 第二个是坐标x第三个是坐标y 98 function get_Chess(context,x,y){ 99 //定义俩个变量 100 var sub_x = 0,sub_y = 0; 101 if (x<30||y<30||x>470||y>570) {return false}; 102 //这里就是一个四舍五入和向下取整,以便棋子能在棋盘上按格走 103 if (x%100>80||x%100<20) {sub_x = 100*Math.round(x/100)}; 104 if (x%100>30&&x%100<70) {sub_x = x>100?(Math.floor(x/100)*100 + 50):50}; 105 if (y%100>80||y%100<20) {sub_y = 100*Math.round(y/100)}; 106 if (y%100>30&&y%100<70) {sub_y = y>100?(Math.floor(y/100)*100 + 50):50}; 107 108 if(sub_x > 0 && sub_y > 0){ 109 for (var i = 0;i < chess.length; i++) { 110 if (chess[i][1] == sub_x && chess[i][2] == sub_y && chess[i][3] > 0) { 111 if (chess[i][4] == whose) {//可见第5个参数是判断当前该哪边出手的数 112 draw_check(context,sub_x,sub_y);//画棋子 113 //参数:x坐标,y坐标,数组里的第几个,数组的第五个参数即该哪边下,第六个参数 114 desc_click = [sub_x,sub_y,i,chess[i][4],chess[i][5]]; 115 return false; 116 } 117 if(desc_click[3] == whose&&chess[i][4]!=whose){ 118 //这一步判断是否成功换人下子 119 if(go(sub_x,sub_y,desc_click[4],true)){ 120 chess[desc_click[2]][1] = sub_x;// 121 chess[desc_click[2]][2] = sub_y;// 122 chess[i][3] = 0;//棋子第三个参数赋值为0 123 whose = whose == 0?1:0;//是不是"楚"如果是就换,如果不是就是"楚" 124 repaint(context);//调用函数重新画整个棋盘 125 if(chess[i][5] == 5) {document.getElementById("canvas").onclick = null;}// 126 } 127 } 128 return false; 129 } 130 } 131 } 132 if(sub_x >= 50&&sub_x<=450&&sub_y>=50&&sub_y<=550&&desc_click[3] == whose){ 133 if(go(sub_x,sub_y,desc_click[4])){ 134 chess[desc_click[2]][1] = sub_x; 135 chess[desc_click[2]][2] = sub_y; 136 repaint(context); 137 desc_click = [0,0,0,-1,0]; 138 whose = whose ==0?1:0; 139 } 140 } 141 } 142 143 function repaint(context){ 144 context.clearRect(0,0,500,550); 145 draw_Chess_All(context); 146 } 147 //画棋盘 148 function draw_ChessBoard(context){ 149 //定义线宽 150 context.lineWidth = 2; 151 //开始画线 152 context.beginPath(); 153 //画横线 154 for (var i = 1; i <= 10; i++) { 155 context.moveTo(50,50*i); 156 context.lineTo(450,50*i); 157 } 158 //画竖线 159 for (var i = 1; i <= 9; i++) { 160 context.moveTo(50*i,50); 161 context.lineTo(50*i,500); 162 } 163 context.stroke(); 164 165 //画中心的斜线 166 context.beginPath(); 167 context.moveTo(200,50); 168 context.lineTo(300,150); 169 context.moveTo(300,50); 170 context.lineTo(200,150); 171 172 context.moveTo(200,400); 173 context.lineTo(300,500); 174 context.moveTo(300,400); 175 context.lineTo(200,500); 176 context.stroke(); 177 178 context.beginPath(); 179 180 for (var i = 0; i < 2; i++) { 181 for (var j = 0; j < 2; j++) { 182 //绘制炮的位置的四个标记 183 //绘制左上角的 184 context.moveTo(85 + 300*i,145 + 250*j); 185 context.lineTo(95 + 300*i,145 + 250*j); 186 context.lineTo(95 + 300*i,135 + 250*j); 187 //绘制右上角的 188 context.moveTo(105 + 300*i,135 + 250*j); 189 context.lineTo(105 + 300*i,145 + 250*j); 190 context.lineTo(115 + 300*i,145 + 250*j); 191 //绘制左下角 192 context.moveTo(85 + 300*i,155 + 250*j); 193 context.lineTo(95 + 300*i,155 + 250*j); 194 context.lineTo(95 + 300*i,165 + 250*j); 195 //绘制右下角 196 context.moveTo(105 + 300*i,165 + 250*j); 197 context.lineTo(105 + 300*i,155 + 250*j); 198 context.lineTo(115 + 300*i,155 + 250*j); 199 } 200 } 201 202 context.stroke(); 203 //临时存储一下 204 context.save(); 205 //画最外层的粗线条边框 206 context.beginPath(); 207 context.lineWidth = 3; 208 context.strokeRect(46,46,408,458); 209 context.fillStyle = "#b3b37d"; 210 context.fillRect(51,251,398,48); 211 context.restore(); 212 213 context.save(); 214 context.font = "bold 40px KaiTi_GB2312"; 215 context.translate(100,295); 216 context.rotate(-90*Math.PI/180); 217 context.fillText("楚",0,40); 218 context.restore(); 219 220 context.save(); 221 context.font = "bold 40px KaiTi_GB2312"; 222 context.translate(150,295); 223 context.rotate(-90*Math.PI/180); 224 context.fillText("河",0,40); 225 context.restore(); 226 227 context.save(); 228 context.font = "bold 40px KaiTi_GB2312"; 229 context.translate(400,255); 230 context.rotate(90*Math.PI/180); 231 context.fillText("汉",0,40); 232 context.restore(); 233 234 context.save(); 235 context.font = "bold 40px KaiTi_GB2312"; 236 context.translate(350,255); 237 context.rotate(90*Math.PI/180); 238 context.fillText("界",0,40); 239 context.restore(); 240 } 241 // 242 function draw_Chess_All(context){ 243 for (var i = 0;i < chess.length; i++) { 244 if (chess[i][3]>0) { 245 draw_Chess_One(context,chess[i][1],chess[i][2],chess[i][0],chess[i][4]); 246 } 247 } 248 } 249 250 //绘制棋子 参数:context即当前的画板 x坐标 y坐标 填充的文字 判断是红棋还是黑棋 251 function draw_Chess_One(context,x,y,txt,p){ 252 //p值是判断是黑棋还是红棋 253 var color = p>0?"#ff0000":"#000000"; 254 context.save(); 255 context.beginPath(); 256 //棋子颜色填充用的是渐变 257 var b_Color = context.createLinearGradient(x+15,y-15,x-15,y+15); 258 b_Color.addColorStop(0,"#f3f5d5"); 259 b_Color.addColorStop(1,"#8c834d"); 260 //棋子的样式 261 context.arc(x,y,22,0,2*Math.PI); 262 context.fillStyle = b_Color; 263 context.fill(); 264 //开始画棋子 265 context.beginPath(); 266 context.arc(x,y,17,0,2*Math.PI); 267 context.fillStyle = "#f5da94"; 268 context.strokeStyle = "#c9c876"; 269 context.stroke(); 270 context.fill(); 271 272 context.beginPath(); 273 context.fillStyle = color; 274 context.font = "900 24px KaiTi_GB2312"; 275 context.fillText(txt,x-12,y+8); 276 context.restore(); 277 278 } 279 //绘制选中某个棋子的那个框 280 function draw_check(context,x,y){ 281 //重新画整个棋盘 282 repaint(context); 283 //开始画左上角 284 context.beginPath(); 285 context.moveTo(x-23,y-10); 286 context.lineTo(x-23,y-23); 287 context.lineTo(x-10,y-23); 288 //开始画右上角 289 context.moveTo(x+10,y-23); 290 context.lineTo(x+23,y-23); 291 context.lineTo(x+23,y-10); 292 //开始画左下角 293 context.moveTo(x-23,y+10); 294 context.lineTo(x-23,y+23); 295 context.lineTo(x-10,y+23); 296 //开始画右下角 297 context.moveTo(x+23,y+10); 298 context.lineTo(x+23,y+23); 299 context.lineTo(x+10,y+23); 300 context.stroke(); 301 } 302 //吃子 303 function go(x2,y2,txt,eat){ 304 //定义x1是点击的那个对象数组的第一个值 y1是第二个值 305 var x1 = desc_click[0]; 306 var y1 = desc_click[1]; 307 //定义最大值和最小值 308 var min_x = x1 > x2?x2:x1; 309 var max_x = x1 > x2?x1:x2; 310 var min_y = y1 > y2?y2:y1; 311 var max_y = y1 > y2?y1:y2; 312 //定义是否可以吃子 313 var can_go = true; 314 var num = 0; 315 //判断是不是俩个将帅面对面 316 if (is_face_to_face(x2)) { 317 return false; 318 } 319 //下棋 320 switch (txt){ 321 case 1: 322 // 如果俩车不在同一条直线上 323 if(x1!=x2&&y1!=y2){ 324 //不能吃子 325 can_go = false; 326 break; 327 } 328 //开始遍历 329 for(var i = 0;i < chess.length; i++){ 330 // 331 if(chess[i][1] == x1 && chess[i][2] > min_y && chess[i][2] < max_y && chess[i][3] != 0){ 332 can_go = false; 333 } 334 // 335 if(chess[i][2] == y1 && chess[i][1] > min_x && chess[i][1] < max_x && chess[i][3] != 0){ 336 can_go = false; 337 } 338 } 339 break; 340 case 2://如果是马怎么走 341 can_go = false; 342 if(x1-50==x2&&y1-100==y2&&!is_chess(x1,y1-50)){can_go = true}; 343 if(x1+50==x2&&y1-100==y2&&!is_chess(x1,y1-50)){can_go = true}; 344 if(x1-50==x2&&y1+100==y2&&!is_chess(x1,y1+50)){can_go = true}; 345 if(x1+50==x2&&y1+100==y2&&!is_chess(x1,y1+50)){can_go = true}; 346 if(x1-100==x2&&y1-50==y2&&!is_chess(x1-50,y1)){can_go = true}; 347 if(x1-100==x2&&y1+50==y2&&!is_chess(x1-50,y1)){can_go = true}; 348 if(x1+100==x2&&y1-50==y2&&!is_chess(x1+50,y1)){can_go = true}; 349 if(x1+100==x2&&y1+50==y2&&!is_chess(x1+50,y1)){can_go = true}; 350 break; 351 case 3://象怎么走 352 can_go = false; 353 if(whose == 1 && y2 > 250) {break}; 354 if(whose == 0 && y2 < 300) {break}; 355 if(x1-100==x2&&y1-100==y2&&!is_chess(x1-50,y1-50)) {can_go=true}; 356 if(x1+100==x2&&y1-100==y2&&!is_chess(x1+50,y1-50)) {can_go=true}; 357 if(x1-100==x2&&y1+100==y2&&!is_chess(x1-50,y1+50)) {can_go=true}; 358 if(x1+100==x2&&y1+100==y2&&!is_chess(x1+50,y1+50)) {can_go=true}; 359 break; 360 case 4://士怎么走 361 can_go= false; 362 if(x2<200||x2>300){break}; 363 if(whose == 1&&y2>150){break}; 364 if(x1+50==x2&&y1+50==y2){can_go = true}; 365 if(x1+50==x2&&y1-50==y2){can_go = true}; 366 if(x1-50==x2&&y1+50==y2){can_go = true}; 367 if(x1-50==x2&&y1-50==y2){can_go = true}; 368 break; 369 case 5://帅怎么走 370 can_go = false; 371 if(x2<200||x2>300){break}; 372 //红棋的帅 373 if(whose == 1&&y2>150){break}; 374 //黑棋的将 375 if(whose==0&&y2<400){break}; 376 //判断怎么能走 377 if(x1+50==x2&&y1==y2){can_go=true}; 378 if(x1-50==x2&&y1==y2){can_go=true}; 379 if(x1==x2&&y1+50==y2){can_go=true}; 380 if(x1==x2&&y1-50==y2){can_go=true}; 381 break; 382 case 6://炮怎么走 383 //不能原地走 384 if(x1!=x2&&y1!=y2){ 385 can_go = false; 386 break; 387 } 388 //如果吃子 389 if(eat){ 390 for(var i = 0;i < chess.length; i++){ 391 if(chess[i][1]==x1&&chess[i][2]>min_y&&chess[i][2]<max_y&&chess[i][3]!=0){num++}; 392 if(chess[i][2]==y1&&chess[i][1]>min_x&&chess[i][1]<max_x&&chess[i][3]!=0){num++}; 393 } 394 if(num!=1){can_go = false}; 395 break; 396 } 397 // 398 for(var i=0;i<chess.length;i++){ 399 if(chess[i][1]==x1&&chess[i][2]>min_y&&chess[i][2]<max_y&&chess[i][3]!=0){can_go = false}; 400 if(chess[i][2]==y1&&chess[i][1]>min_x&&chess[i][1]<max_x&&chess[i][3]!=0){can_go = false}; 401 } 402 break; 403 case 7://兵怎么走 404 if(whose==1&&y1>y2){can_go = false}; 405 if(whose==0&&y1<y2){can_go = false}; 406 if(whose==1&&y1<=250&&x1!=x2){can_go = false}; 407 if(whose==0&&y1>=300&&x1!=x2){can_go = false}; 408 if(max_x-min_x+max_y-min_y>50){can_go = false}; 409 break; 410 } 411 return can_go; 412 } 413 //判断这颗棋子是否存在 414 function is_chess(x,y){ 415 //定义existe判断是否这颗棋子还活着默认是死了 416 var existe = false; 417 for(var i = 0;i<chess.length;i++){ 418 //如果某颗棋子的横纵坐标都有并且chess[i][3]任然等于1这个参数是true表示活着 419 if(chess[i][1]==x && chess[i][2]==y && chess[i][3]==1){existe = true;}; 420 } 421 return existe; 422 } 423 //这是一个判断俩个帅是否是面对面(有bug) 424 function is_face_to_face(x){ 425 //定义四个参数红色的和黑色的x,y坐标 426 var r_x = 0,r_y=0,b_x=0,b_y=0,num=0; 427 //定义一个状态 428 var state = false; 429 // 430 for(var i=0;i<chess.length;i++){ 431 //chess[i][5]值就是从1到7分别代表不同的棋子,例如1表示军7表示兵卒 432 //5表示将帅 433 if(chess[i][5]==5 && chess[i][4]==1){//如果将帅活着并且1表示红棋 434 //获取到这个棋子的横纵坐标 435 r_x=chess[i][1]; 436 r_y=chess[i][2]; 437 } 438 if(chess[i][5]==5 && chess[i][4]==0){//如果将帅活着并且1表示黑棋 439 //获取到当前棋子的横纵坐标 440 b_x=chess[i][1]; 441 b_y=chess[i][2]; 442 } 443 } 444 //如果红色和黑色的横坐标相同时 445 if(r_x == b_x){ 446 //遍历一遍chess数组 447 for(var i = 0;i<chess.length;i++){ 448 //如果当前棋子的位置没变并且是红棋落子时 449 if(chess[i][1] == r_x && chess[i][3] > 0){num++;} 450 } 451 //??有问题 452 if(num - 2 == 1 && x != r_x){state = true;} 453 } 454 return state; 455 } 456 457 function update_h2(){ 458 var h2 = document.getElementById("title"); 459 h2.innerHTML = whose == 1?"汉":"楚"; 460 h2.style.color = whose == 1?"#ff0000":"#000"; 461 } 462 463 464 script>