您现在的位置是:首页 > 文章详情

【JavaScript游戏开发】JavaScript+HTML5封装的苏拉卡尔塔游戏(包含源码)

日期:2018-08-22点击:310
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81978903
/** 苏拉克尔塔游戏 * 思路: * 1.棋盘设置:使用HTML5的canvas标签绘制整个棋盘 * 2.点击事件:当页面被点击时,获取点击的x,y像素点,根据此像素点进行判断,再在合适位置绘制黑红棋子,棋子均是使用canvas绘制的 * 3.保存落子记录:将数据存入一个二维数组,x和y表是落子坐标,1为白棋,2为黑棋,0代表此处无棋子,只有没有棋子的才能落子 * 4.判断输赢:每次落子后以此坐标分别向左右,上下,右下,右上进行判断,设参数count,遇到同色棋子+1,遇到空格或不同色棋子终止,当count=5时,游戏结束 * 20180823 */

完整项目源码已经开源:https://github.com/xiugangzhang/SularaGame

项目在线预览地址:

http://htmlpreview.github.io/?https://github.com/xiugangzhang/SularaGame/blob/master/SularaGame.html

主要功能:

1.棋盘棋子的初始化

2.走棋规则的实现

3.输赢的判定

4.自动走棋的实现

 

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SuraKarta Game</title> </head> <body onload="startLoad()" style="padding:0px;margin:0px"> <canvas width="700" id="canvas" onmousedown="play(event)" height="600"> </canvas> <div style=" border: solid 2px purple; display: block; position:absolute; left:750px; top:50px; width: 100px; height: 500px; text-align: center; margin:auto; line-height: 45px;"> <input type="button" value="START" id="begin" onclick="isNewGame()"/> <input type="button" value="STOP" id="replay" onclick="isExitGame()"/> </div> </body> <script type="text/javascript"> /** 苏拉克尔塔游戏 * 思路: * 1.棋盘设置:使用HTML5的canvas标签绘制整个棋盘 * 2.点击事件:当页面被点击时,获取点击的x,y像素点,根据此像素点进行判断,再在合适位置绘制黑红棋子,棋子均是使用canvas绘制的 * 3.保存落子记录:将数据存入一个二维数组,x和y表是落子坐标,1为白棋,2为黑棋,0代表此处无棋子,只有没有棋子的才能落子 * 4.判断输赢:每次落子后以此坐标分别向左右,上下,右下,右上进行判断,设参数count,遇到同色棋子+1,遇到空格或不同色棋子终止,当count=5时,游戏结束 * 20180823 */ /**全局参数初始化 * */ var canvas; //html5画布 var context; var isRed = false; //设置是否该轮到白棋,黑棋先手 var winner = ''; //赢家初始化为空 var step = 225;//总步数 // 记录棋盘的位置坐标 var chessData = new Array(6); //二维数组存储棋盘落子信息,初始化数组chessData值为0即此处没有棋子,1为红棋,2为黑棋 for (var x = 0; x < 6; x++) { chessData[x] = new Array(6); for (var y = 0; y < 6; y++) { chessData[x][y] = 0; } } /**每次打开网页加载棋盘和相关游戏信息 * */ function startLoad() { drawRect(); // 会加载游戏上一局保存的记录 //loadGame(); } /**棋盘样式信息 * */ function drawRect() { /*//创建棋盘背景 canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); context.fillStyle = '#FFFFFF'; context.fillRect(0, 0, 1024, 768); //标题 context.fillStyle = '#00f'; context.font = '20px Consols'; context.strokeText('SuraKarta Game Board', 750, 150); context.strokeRect(745, 120, 230, 250);*/ //新游戏 context.strokeRect(790, 180, 120, 30); context.fillStyle = '#00f'; context.font = '25px Consols'; context.strokeText('START', 809, 205); //结束游戏 context.strokeRect(790, 250, 120, 30); context.fillStyle = '#00f'; context.font = '25px Consols'; context.strokeText('STOP', 812, 275); //游戏说明 /*context.fillStyle = '#00f'; context.font = '15px Arial'; context.strokeText('游戏规则:玩家执黑色', 780, 200); context.strokeText('棋子先手,电脑执白色棋子', 750, 220); context.strokeText('后手,任何一方形成五子连', 750, 240); context.strokeText('珠,游戏终止。', 750, 260);*/ //棋盘纵横线 for (var i = 1; i < 7; i++) { if (i == 1 || i == 6) { context.lineWidth = 8; context.strokeStyle = '#FEFE02'; } else if (i == 2 || i == 5) { context.lineWidth = 8; context.strokeStyle = '#02CFFF'; } else { context.lineWidth = 8; context.strokeStyle = '#028202'; } context.beginPath(); context.moveTo(57 * i + 160, 150); context.lineTo(57 * i + 160, 437); context.closePath(); context.stroke(); context.beginPath(); context.moveTo(216, 57 * i + 94); context.lineTo(501, 57 * i + 94); context.closePath(); context.stroke(); } // 圆弧的绘制 //弧度是以x轴正方向为基准、进行顺时针旋转的角度来计算 // true 表示逆时针, false表示顺时针 var x = 0; var y = 0; context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#02CFFF'; context.arc(217, 151, 57, 0, getRads(90), true); context.stroke(); context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#028202'; context.arc(217, 151, 57 * 2, 0, getRads(90), true); context.stroke(); context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#02CFFF'; context.arc(502, 150, 57, getRads(90), getRads(180), true); context.stroke(); context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#028202'; context.arc(502, 150, 57 * 2, getRads(90), getRads(180), true); context.stroke(); context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#02CFFF'; context.arc(217, 436, 57, getRads(0), getRads(270), false); context.stroke(); context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#028202'; context.arc(217, 436, 57 * 2, getRads(0), getRads(270), false); context.stroke(); context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#02CFFF'; context.arc(503, 436, 57, getRads(-90), getRads(180), false); context.stroke(); context.beginPath(); context.lineWidth = 8; context.strokeStyle = '#028202'; context.arc(503, 436, 57 * 2, getRads(-90), getRads(180), false); context.stroke(); } // 重绘棋盘 function update() { context.clearRect(0, 0, 700, 600); drawRect(); } /**加载游戏记录 * 通过cookie查询是否存在游戏记录,有则加载 */ function loadGame() { var we = getCookie("red"); console.log("获取白色棋子的cookie" + we); loadChessByCookie("white", we); var bk = getCookie("black"); console.log("获取黑色棋子的cookie" + bk); loadChessByCookie("black", bk); winner = getCookie("winner"); //如果没有winner的cookie存在的话此处winner的值会被设为null //判断是否该电脑走 // var temp=getCookie("isRed"); // if(temp!=null){ // if(temp=="true"){ // AIplay(); // } // } } /**分割cookie中获取的字符串,从而加载棋子 * @param {[type]} color [description] * @param {[type]} record [description] * @return {[type]} [description] */ function loadChessByCookie(color, record) { if (record == null) { console.log(color + "棋子没有游戏记录"); } else { var a = record.split(";"); console.log(color + "第一次分割字符串:" + a) for (var i = 0; i < a.length; i++) { var b = a[i].split(","); console.log("第" + (i + 1) + "个" + color + "棋子坐标:" + parseInt(b[0]) + "," + parseInt(b[1])); chess(color, b[0], b[1]); } } } /** 落子 * @param {[type]} turn [description] * @param {[type]} x [description] * @param {[type]} y [description] * @return {[type]} [description] */ function drawChess(color, x, y) { //参数为,棋(1为白棋,2为黑棋),数组位置 if (x >= 0 && x < 6 && y >= 0 && y < 6) { if (color == "red") { chess("red", x, y); } else if (color == "black") { chess("black", x, y); } else if (color == "blue" && isSelected) { chess("blue", x, y); } } /*if (--step == 0) { winner = "和局"; setCookie("winner", winner); alert(winner); }*/ } /**绘制棋子,每次绘制棋子的时候刷新cookie信息 * */ function chess(color, x, y) { if (x > 6 || y > 6 || x < 0 || y < 0 || x == 6 || y == 6){ return; } context.fillStyle = color; context.beginPath(); // 绘制棋子(注意要把棋子的初始位置复位) context.arc(x * 56 + 217, y * 56 + 150, 20, 0, Math.PI * 2, true); context.closePath(); context.fill(); if (color == "red") { console.log("电脑在" + x + "," + y + "画了个红棋"); // 1为红棋子 chessData[x][y] = 1; } else if (color == "black") { // 2为黑棋子 console.log("电脑在" + x + "," + y + "画了个黑棋"); chessData[x][y] = 2; } /*var a = getCookie(color); if (a != null) { delCookie(color); setCookie(color, a + ";" + x + "," + y, 30); } else { setCookie(color, x + "," + y, 30); }*/ } /**鼠标点击事件 * 在这里开始完成棋子的博弈操作 * @param {[type]} e [description] * @return {[type]} [description] */ function play(e) { //鼠标点击时发生 var color; var e = e || event; console.log("(e.x, e.y) = " + "(" + e.clientX + ", " + e.clientY + ")"); // 用这个棋盘的初始位置为坐标的原点(217, 150) var px = e.clientX - 217; var py = e.clientY - 150; console.log("(px, py) = " + "(" + px + ", " + py + ")"); // 棋子的大小 var x = parseInt(px / 57); var y = parseInt(py / 57); console.log("(x, y) = " + "(" + x + ", " + y + ")"); //isNewGame(e.clientX, e.clientY); //是否点击了newgame //isExitGame(e.clientX, e.clientY); //是否点击了exitGame // 划定棋盘的位置范围 if (px < 0 || py < 0 || x > 5 || y > 5) { //鼠标点击棋盘外的区域不响应 return; } //chess('red', 2, 3); doCheck(x, y); } // 检查鼠标当前点击的位置上有没有棋子 var isSelected = false; var selectedX = -1; var selectedY = -1; var movetoX =-1; var movetoY =-1; // 选中的棋子ID //var selectedChess; var chessId = 1; var col; var row; for (var i=0; i<24; i++){ drawChessById(i); } var stone = new Array(24); function drawChessById(id, x, y) { /* // 黑色 if (id == "00"){ chess("red", 0, 0); }if (id == "10"){ }if (id == "20"){ }if (id == "30"){ }if (id == "40"){ }if (id == "50"){ }if (id == "01"){ }if (id == "11"){ }if (id == "21"){ }if (id == "31"){ }if (id == "41"){ }if (id == "51"){ } // 红色 if (id == "04"){ }if (id == "14"){ }if (id == "24"){ }if (id == "34"){ }if (id == "44"){ }if (id == "54"){ }if (id == "05"){ }if (id == "15"){ }if (id == "25"){ }if (id == "35"){ }if (id == "45"){ }if (id == "55"){ }*/ // //chess(stone[id], x, y); } // 记录选中的棋子的ID function doCheck(x, y) { if (winner != '' && winner != null) { //已经结束的游戏只能点击new game //alert(winner); //return; } // 判断是黑棋子还是红棋子(注意在判断的时候要使用双等号, 不要使用一个等号哈) var chessColor; // 红色棋子被选中 // 每次点击一次, 都要把键盘的所有棋子重新绘制一次, 而不是去覆盖 // 判断点击的位置有没有棋子被选中 if (chessData[x][y] != 0) { //alert("有棋子"); isSelected = true; } else { alert("没有棋子"); isSelected = false; } //chess("blue", 1, 2); // 如果有棋子被选中了 if (isSelected) { // 开始绘制棋子 chessColor = "blue"; // 把选中的棋子的坐标记录下来 selectedX = x; selectedY = y; if (chessData[x][y] == 1) { /*alert("你选择的是红色棋子" + "这个棋子的ID是" + selectedX + selectedY);*/ chessId = selectedX+","+selectedY; alert("chessId="+chessId); } else { /*alert("你选择的是黑色棋子" + "这个棋子的ID是" + selectedX + selectedY);*/ chessId = selectedX+","+selectedY; alert("chessId="+chessId); } // 重新绘制 //drawRedAndBlackChess(chessColor, selectedX, selectedY); // 棋盘上面任意位置有棋子被选中就变颜色 update(); // 棋子选中的位置变颜色 if (chessData[selectedX][selectedY] != 0) { chess("blue", selectedX, selectedY); // 记录这个选中的棋子的id var id = selectedX + "" + selectedY; alert("ID" + id); // 只要这个棋子选中了 drawRedAndBlackChess("blue", selectedX, selectedY); } } // 第一次选择了棋子, 第二次点击其他位置 if (!isSelected){ alert("开始移动"); // 记录鼠标将要移动到的位置 movetoX = x; movetoY = y; //移动棋子到新的位置 //alert("movetoX, movetoY"+x+", "+y); // 强制加载当前的文档 //location.reload(); // 移动当前的棋子(开始重绘) //update(); // 移动棋子 chessMove(selectedX, selectedY, movetoX, movetoY); //drawRedAndBlackChess(chessColor, selectedX, selectedY); } } // 根据棋子的ID来绘制棋子 /*var row; var col; var type; var arr = new Array(24); function drawChessById(id) { var chess = arr[id]; // 根据行列号来 }*/ // 对绘制好的棋子赋值id var arr = new Array(24); function getChessidByRowCol(row, col) { for(var i=0; i<6; i++){ for (var j=0; j<6; j++){ //alert(); arr.push(); } } } // 移动棋子(源位置移动到目标位置) function chessMove(selectedX, selectedY, movetoX, movetoY) { //alert(selectedX+" "+selectedY+","+movetoX+" "+movetoY); // 从源位置移动到目标位置 // 红色棋子在移动 // 原来的位置不画 //update(); if (chessData[selectedX][selectedY] == 1) { alert("SeID"+selectedX+selectedY+"选择的"+chessId); update(); //location.reload(); //alert("红色"); // 红色棋子移动到的位置 chess("red", movetoX, movetoY); // 绘制红色棋子(移动的位置不用画, 其他的位置都要画出来) // 这个是在最下面两行绘制的红色棋子的方式 for (var j = 0; j < 6; j++) { for (var i = 4; i < 6; i++) { // 开始绘制更新后的红色棋子 if (j == selectedX && i == selectedY) { // 这个位置就是那个之前移动棋子的位置 continue; } else { chess("red", j, i); } } } /*for (var i=0; i<6; i++){ for (var j=0; j<6; j++){ if (j == selectedX && i == selectedY){ //chess("red", selectedX, selectedY); continue; } chess("red", selectedX, selectedY); } }*/ for (var j = 0; j < 6; j++) { for (var i = 0; i < 2; i++) { chess("black", j, i); } } } // 黑色棋子在移动 if (chessData[selectedX][selectedY] == 2) { // 绘制红色棋子(移动的位置不用画, 其他的位置都要画出来) for (var j = 0; j < 6; j++) { for (var i = 4; i < 6; i++) { chess("red", j, i); } } //alert("黑色"); // 绘制黑色棋子 //alert("chess move"); chess("black", movetoX, movetoY); for (var j = 0; j < 6; j++) { for (var i = 0; i < 2; i++) { // 把选中的棋子设为蓝色 // 除了原来的位置不画出来,其他位置都要画 if (selectedX == j && selectedY == i) { // 原来的这个位置不画出来 continue; } chess("black", j, i); } } } } /**新游戏按钮 * */ function isNewGame(x, y) { if (confirm("Arr you sure to play new game now?")) { update(); // 从新摆棋子 drawRedAndBlackChess(); //chess("red", 1, 2); //chess("black", 2, 2); // 创建24个棋子对象 /*for (var i=0; i<24; i++){ drawChessById(i, x, y); }*/ } } // 主要用于绘制24个棋子 function drawRedAndBlackChess(chesscolor, x, y) { // 绘制黑色棋子12 个 for (var j = 0; j < 6; j++) { for (var i = 0; i < 2; i++) { // 把选中的棋子设为蓝色 if (isSelected && j == x && i == y) { //alert("isSelected && j==x && i==y"); //chess(chesscolor, j, i); } else { chess("black", j, i); } } } // 绘制红色棋子 12个 for (var j = 0; j < 6; j++) { for (var i = 4; i < 6; i++) { if (isSelected && j == x && i == y) { //alert("isSelected && j==x && i==y"); //chess(chesscolor, j, i); } else { chess("red", j, i); } } } } // 退出游戏 function isExitGame(x, y) { if (confirm("Are you sure to exit game now?")) { //退出游戏 window.close(); } } /**判断此局游戏是否已有结果 * 每次落子判断游戏是否胜利 * */ function isWin(color, x, y) { console.log("判断" + color + "(" + x + "," + y + ")是否胜利"); var temp = 2; //默认为黑色 if (color == "white") { temp = 1; } //白色 console.log("temp=" + temp); lrCount(temp, x, y); tbCount(temp, x, y); rtCount(temp, x, y); rbCount(temp, x, y); } function lrCount(temp, x, y) { var line = new Array(4); var count = 0; for (var i = x; i >= 0; i--) { line[0] = i; line[1] = y; if (chessData[i][y] == temp) { ++count; } else { i = -1; } } for (var i = x; i <= 6; i++) { line[2] = i; line[3] = y; if (chessData[i][y] == temp) { ++count; } else { i = 100; } } success(line[0], line[1], line[2], line[3], temp, --count); } function tbCount(temp, x, y) { var line = new Array(4); var count = 0; for (var i = y; i >= 0; i--) { line[0] = x; line[1] = i; if (chessData[x][i] == temp) { ++count; } else { i = -1; } } for (var i = y; i <= 14; i++) { line[2] = x; line[3] = i; if (chessData[x][i] == temp) { ++count; } else { i = 100; } } success(line[0], line[1], line[2], line[3], temp, --count); } function rtCount(temp, x, y) { var line = new Array(4); var count = 0; for (var i = x, j = y; i <= 14 && j >= 0;) { line[0] = i; line[1] = j; if (chessData[i][j] == temp) { ++count; } else { i = 100; } i++; j--; } for (var i = x, j = y; i >= 0 && j <= 14;) { line[2] = i; line[3] = j; if (chessData[i][j] == temp) { ++count; } else { i = -1; } i--; j++; } success(line[0], line[1], line[2], line[3], temp, --count); } function rbCount(temp, x, y) { //右下斜判断 var line = new Array(4); var count = 0; for (var i = x, j = y; i >= 0 && j >= 0;) { line[0] = i; line[1] = j; if (chessData[i][j] == temp) { ++count; } else { i = -1; } i--; j--; } for (var i = x, j = y; i <= 14 && j <= 14;) { line[2] = i; line[3] = j; if (chessData[i][j] == temp) { ++count; } else { i = 100; } i++; j++; } success(line[0], line[1], line[2], line[3], temp, --count); } /**判断是否胜利及胜利之后的操作 * @param {[type]} turn [description] * @param {[type]} count [description] * @return {[type]} [description] */ function success(a, b, c, d, temp, count) { if (count == 5) { //因为落子点重复计算了一次 console.log("此局游戏结束啦"); console.log("(" + a + "," + b + ")" + "到" + "(" + c + "," + d + ")"); context.beginPath(); context.lineWidth = 5; context.strokeStyle = 'purple'; context.moveTo(40 * a + 180, 40 * b + 80); context.lineTo(40 * c + 180, 40 * d + 80); context.closePath(); context.stroke(); winner = "黑棋胜利!"; if (temp == 1) { winner = "白棋胜利!"; } setCookie("winner", winner); alert(winner); } } /**使用cookie保存棋盘信息,防止不小心关闭网页 * @param {[type]} name [description] * @param {[type]} value [description] * @param {[type]} time [description] */ function setCookie(name, value, time) { var exp = new Date(); exp.setTime(exp.getTime() + time * 24 * 60 * 60 * 1000); document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString(); } /**获取cookie,初始化棋盘 *cookie */ function getCookie(name) { var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); if (arr = document.cookie.match(reg)) return unescape(arr[2]); else return null; } /**删除cookie * */ function delCookie(name) { var exp = new Date(); exp.setTime(exp.getTime() - 1); var cval = getCookie(name); if (cval != null) document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString(); } /** * 禁止页面滚动事件 * @return {[type]} [description] */ var pageScroll = 0; window.onscroll = function () { pageScroll++; scrollTo(0, 0); if (pageScroll > 100) { //每当玩家滚动页面滚动条100次提醒 pageScroll = 0; } } /** * 工具函数 */ function getRads(degrees) { return (Math.PI * degrees) / 180; } function getDegrees(rads) { return (rads * 180) / Math.PI; } </script> </html> 

 

原文链接:https://yq.aliyun.com/articles/647670
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章