玩家名称
大家都知道,取个不俗的名字就是展示自我,区分于他人!就好比武侠小说里那些厉害角色,一个牛逼的名字就能吓到人。因此,我们的HTML5Canvas五子棋游戏当然也得给玩儿家取个炫酷的名字!
玩家棋子
玩家棋子,关系到谁输谁赢!一般我们都选黑白色的,就跟太极图似的,有阴必有阳。你想的话,还能换其他喜欢的颜色,比如嫩萌的粉色、冷艳的蓝色啥的。关键就是要容易区分出来就好。
当前由谁下棋背景定位
这小玩意儿主要就是提示你该干嘛。玩五子棋,当你上场时屏幕色调会变或听得见提示音,这样才能避免乱套。想想要是在下棋时犯迷糊,那可是会被别人打败的
玩家比分
别忘了,玩家比分直接决定结果!所以得多留意比分变化才行,看看到底是咱们胜利还是失败。还有,加点儿特色元素也是挺有趣的,比如说搞个排行榜,弄个成就能让大家更兴奋。
功能菜单区域(重新开始和无限悔棋)
你知道功能菜单区里咱们可以找到好多救援工具吗?重新开始和无限悔棋就像是“后悔药”,嗑下去就能把悲剧变喜剧!要是下错了步咋办?别担心,用悔棋功能,赶紧回到从前选对路。而重新开始,那就是从头再来,洗牌重开呀。
棋盘区域
玩五子棋游戏,那棋盘可就像个大舞台了!每下一步,你都能感受到那份紧张和刺激。再说,用HTML5画出来的棋盘更是栩栩如生,让人有如亲临其境。
胜利后连环棋子连接
胜利之后,把所有棋子串起来真的太让人心跳加速了!当五个棋子连成一条直线的那刻,那自豪感瞬间MAX!而且用HTML5Canvas画出来的效果更是炫酷到不行!
最后下棋位置闪烁显示
哎呦妈最牛的就是最后那步棋,闪烁给几个提示,全盘都能看到,感觉这不是靠实力而是靠运气赢。不过,关键时候用这个还是挺管事儿的。
光标定位
选棋子时的光标定位可千万不能马虎!一不小心就会拿起竞败将军。紧张激烈的对战中,别小看这小小的失误,分分钟就能让你打起了退堂鼓。
返回主界面
别乱戳!不小心误触那个回到主界面的按钮可就尴尬。咱得想好怎么放这个回去主界面按钮最方便!
保存棋局和相关数据
var gb = null; var infoboj = document.getElementsByClassName("info")[0]; var pl1obj = document.getElementById("pl1"); var pl2obj = document.getElementById("pl2"); var plname1obj = document.getElementById("plname1"); var plname2obj = document.getElementById("plname2"); var chesstypeobj = document.getElementsByName("chesstype"); var chesscolorobj = document.getElementsByName("chesscolor"); var chessbgObj = document.getElementsByName("chessbg"); var winerpnl = document.getElementById("winer"); document.getElementById("startgame").addEventListener("click", function() { function initParams() { var chessTypeValue = 1; if (chesstypeobj.length > 0) { for (var i = 0; i 0) { for (var i = 0; i 0) { for (var i = 0; i < chessbgObj.length; i++) { if (chessbgObj[i].checked) { bcorimgvalue = chessbgObj[i].value; break; } } } return { lineColor: linevalue, chessType: chessTypeValue, //1 色彩棋子 2 仿真棋子 playAName: plname1Input.value, playBName: plname2Input.value, backColorORImg: bcorimgvalue, playAImg: "http://sandbox.runjs.cn/uploads/rs/62/nbqodq5i/playA.png", playBImg: "http://sandbox.runjs.cn/uploads/rs/62/nbqodq5i/playB.png", playerBIsComputer:openComputer.checked }; } document.getElementById("cc").style.display = "block"; gb = new gobang(initParams()); /** * 设置一些界面信息 * @param {Object} opt */ gb.info = function(opt) { infoboj.style.visibility = "visible"; document.getElementsByClassName("startpnl")[0].style.visibility = "hidden"; plname1obj.innerHTML = opt.playAName; plname2obj.innerHTML = opt.playBName; if (opt.chessType == 1) { var span1 = document.createElement("span"); pl1obj.insertBefore(span1, plname1obj); var span2 = document.createElement("span"); pl2obj.insertBefore(span2, plname2obj); } else { var img1 = document.createElement("img"); img1.src = opt.playAImg; pl1obj.insertBefore(img1, plname1obj); var img2 = document.createElement("img"); img2.src = opt.playBImg; pl2obj.insertBefore(img2, plname2obj); } } /** * 每次下棋后触发事件 * @param {Object} c2d */ gb.operate = function(opt, c2d) { if (!c2d.winer || c2d.winer <= 0) { pl1obj.removeAttribute("class", "curr"); pl2obj.removeAttribute("class", "curr"); if (c2d.player == 1) { pl2obj.setAttribute("class", "curr"); } else { pl1obj.setAttribute("class", "curr"); } document.getElementById("backChessman").innerHTML="悔棋("+c2d.canBackTimes+")"; } else { var winname = c2d.winer == 1 ? opt.playAName : opt.playBName; var str = "恭喜,【" + winname + "】赢了!" alert(str); winerpnl.style.display = "block"; document.getElementById("winerName").innerHTML = "恭喜,【" + winname + "】赢了!"; document.getElementById("pl" + c2d.winer).style.backgroundColor = "pink"; document.getElementById("scoreA").innerHTML = c2d.playScoreA; document.getElementById("scoreB").innerHTML = c2d.playScoreB; } } gb.start(); }); document.getElementById("openComputer").addEventListener("change", function() { if (this.checked) { plname2Input.value = "电脑"; plname2Input.disabled = "disabled"; } else { plname2Input.value = "玩家二"; plname2Input.disabled = ""; } }); //document.getElementById("openComputer").checked="checked"; //重新开始 function restartgui() { if (gb) { winerpnl.style.display = "none"; pl1obj.removeAttribute("class", "curr"); pl2obj.removeAttribute("class", "curr"); document.getElementById("pl1").style.backgroundColor = ""; document.getElementById("pl2").style.backgroundColor = ""; gb.restart(); } };
保存棋谱和相关数据真的特别重要,可以留个纪念比如以后要是想炫耀以前下过的那盘棋或者想分享给朋友看看有多牛就方便!所以数据得保护好。
读取棋局和相关数据
// ========== // =name:gobang 游戏 // =anthor:jasnature // =last modify date:2016-04-13 // ========== (function(win) { var gb = function(option) { var self = this, canObj = document.getElementById("cc"), can = canObj.getContext("2d"); self.contextObj = canObj; self.context = can; if (!self.context) { alert("浏览器不支持html5"); return; }; self.Opt = { lineColor: "green", chessType: 1, //1 色彩棋子 2 仿真棋子 playAName: "play1", playBName: "play2", playAColor: "red", playBColor: "blue", playAImg: "img/playA.png", playBImg: "img/playB.png", backColorORImg: "default", playerBIsComputer: false }; self.operate; //合并属性 for (var a in option) { //console.log(opt[a]); self.Opt[a] = option[a]; }; //私有变量 var my = {}; my.enableCalcWeightNum = false; //显示AI分数 my.gameover = false; //棋盘相关 my.baseWidth = 30; my.lastFocusPoint = {}; //鼠标最后移动到的坐标点,计算后的 my.cw = self.contextObj.offsetWidth; //棋盘宽 my.ch = self.contextObj.offsetHeight; //高 my.xlen = Math.ceil(my.cw / my.baseWidth); //行数 my.ylen = Math.ceil(my.ch / my.baseWidth); //列 my.chessRadius = 14; //棋子半径 my.playerBIsComputer = false; //棋手B是否是电脑 my.ComputerThinking = false; //电脑是否在下棋 my.goBackC2dIsComputer = false; //最后下棋是否为电脑 my.switcher = 1; //由谁下棋了 1-a 2-b or computer my.winer = -1; //赢家,值参考my.switcher my.playScoreA = 0; my.playScoreB = 0; //x,y 正方形数量(20*20) my.rectNum = my.xlen; //存储已下的点 my.rectMap = []; my.NO_CHESS = -1; //没有棋子标识 my.goBackC2d = {}; //最后下的数组转换坐标 my.downChessmanStackC2d = []; // 记录已下棋子的顺序和位置,堆栈 my.focusFlashInterval = null; //焦点闪烁线程 my.focusChangeColors = ["red", "fuchsia", "#ADFF2F", "yellow", "purple", "blue"]; my.eventBinded = false; my.currChessBackImg = null; my.currChessAImg = null; my.currChessBImg = null; my.currDrawChessImg = null; my.ChessDownNum = 0; //2个玩家 下棋总数 /** * 开始游戏 */ self.start = function() { }; /** * 重新开始游戏 */ self.restart = function() { }; /** * 悔棋一步 ,清棋子,并返回上一次参数 */ self.back = function() { } /** * 初始化一些数据 */ function init() { } // self.paint = function() { // // //window.requestAnimationFrame(drawChessboard); // }; /** * 游戏逻辑 */ function logic(loc, iscomputer) { }; /** * 判断是否有玩家胜出 * @param {Object} c2d */ function isWin(c2d) { return false; } /** * 连接赢家棋子线 * @param {Object} points */ function joinWinLine(points) { } /** * 画棋盘 */ function drawChessboard() { }; /** * 画棋子 * @param {Object} loc 鼠标点击位置 */ function drawChessman(c2d) { } function drawRect(lastRecord, defColor) { } /** * 闪烁最后下棋点 */ function flashFocusChessman() { } /** * 清棋子 * @param {Object} c2d */ function clearChessman() { } /** * @param {Object} loc * @return {Object} I 二维数组横点(),J二维数组纵点,IX 横点起始坐标,JY纵点起始坐标,player 最后下棋玩, winer 赢家 */ function calc2dPoint(loc) { var txp = Math.floor(loc.x / my.baseWidth), typ = Math.floor(loc.y / my.baseWidth) dxp = txp * my.baseWidth, dyp = typ * my.baseWidth; loc.I = txp; loc.J = typ; loc.IX = dxp; loc.JY = dyp; return loc; } my.isChangeDraw = true; /** * 位置移动光标 * @param {Object} loc */ function moveFocus(loc) { } /** * 绑定事件 */ function bindEvent() { if (!my.eventBinded) { self.contextObj.addEventListener("touchstart", function(event) { //console.log(event); var touchObj = event.touches[0]; eventHandle({ s: "touch", x: touchObj.clientX - this.offsetLeft, y: touchObj.clientY - this.offsetTop }) }); self.contextObj.addEventListener("click", function(event) { //console.log("click event"); eventHandle({ s: "click", x: event.offsetX, y: event.offsetY }) }); self.contextObj.addEventListener("mousemove", function(event) { //console.log("mousemove event"); moveFocus({ x: event.offsetX, y: event.offsetY }); }); my.eventBinded = true; } function eventHandle(ps) { if (!my.gameover && !my.ComputerThinking) { logic(ps); if (my.playerBIsComputer && my.switcher == 2) { my.ComputerThinking = true; var pp = AI.analysis(my.goBackC2d.I, my.goBackC2d.J); logic({ I: pp.x, J: pp.y }, true); my.ComputerThinking = false; } } event.preventDefault(); event.stopPropagation(); return false; } } }; win.gobang = gb; })(window);
记住,读取棋局和数据也同样重要!如果想要复习之前的对局或者学学高手们的招数,只要找到保存好的数据就省事儿多!
交换角色
换个角色玩也挺好玩儿的,能让游戏更有趣且刺激点~毕竟每个角色都有自己的特色和优点缺点咯。
/** * 判断是否有玩家胜出 * @param {Object} c2d */ function isWin(c2d) { //四个放心计数 竖 横 左斜 右斜 var hcount = 0, vcount = 0, lbhcount = 0, rbhcount = 0, temp = 0; var countArray = []; //左-1 for (var i = c2d.I; i >= 0; i--) { temp = my.rectMap[i][c2d.J]; if (temp < 0 || temp !== c2d.player) { break; } hcount++; countArray.push({ I: i, J: c2d.J }); } //右-1 for (var i = c2d.I + 1; i < my.rectMap.length; i++) { temp = my.rectMap[i][c2d.J]; if (temp < 0 || temp !== c2d.player) { break; } hcount++; countArray.push({ I: i, J: c2d.J }); } if (countArray.length = 0; j--) { temp = my.rectMap[c2d.I][j]; if (temp < 0 || temp !== c2d.player) { break; } vcount++; countArray.push({ I: c2d.I, J: j }); } //下-2 for (var j = c2d.J + 1; j < my.rectMap[c2d.I].length; j++) { temp = my.rectMap[c2d.I][j]; if (temp < 0 || temp !== c2d.player) { break; } vcount++; countArray.push({ I: c2d.I, J: j }); } } if (countArray.length = 0, j >= 0; i--, j--) { if (i < 0 || j < 0) break; temp = my.rectMap[i][j]; if (temp < 0 || temp !== c2d.player) { break; } lbhcount++; countArray.push({ I: i, J: j }); } //右下 if (c2d.I < my.rectMap.length - 1 && c2d.I < my.rectMap[0].length - 1) { for (var i = c2d.I + 1, j = c2d.J + 1; i < my.rectMap.length, j = my.rectMap.length || j >= my.rectMap.length) break; temp = my.rectMap[i][j]; if (temp < 0 || temp !== c2d.player) { break; } lbhcount++; countArray.push({ I: i, J: j }); } } } if (countArray.length < 5) { countArray = []; //右上 for (var i = c2d.I, j = c2d.J; i = 0; i++, j--) { if (i >= my.rectMap.length || j < 0) break; temp = my.rectMap[i][j]; if (temp = 1 && c2d.J 0, j = my.rectMap.length || i < 0) break; temp = my.rectMap[i][j]; if (temp = 5 || vcount >= 5 || lbhcount >= 5 || rbhcount >= 5) { my.winer = c2d.player; my.gameover = true; joinWinLine(countArray); return true; } return false; }
网络对战(2台机器)
网络对战嗨到爆!和全世界的玩家切磋真过瘾得很!两个家伙在机器上打得火热,哪个会是赢家?
双方思考总时间记录
要知道,记录两人一共花的时间也挺重要滴!这样可以让大家看看自己下棋玩儿了多久,或者是不是策略合不合适。你想,厉害的人当然用时就短啦!
/** * 连接赢家棋子线 * @param {Object} points */ function joinWinLine(points) { points.sort(function(left, right) { return (left.I + left.J) > (right.I + right.J); }); var startP = points.shift(); var endP = points.pop(); var poffset = my.baseWidth / 2; can.strokeStyle = "#FF0000"; can.lineWidth = 2; can.beginPath(); var spx = startP.I * my.baseWidth + poffset, spy = startP.J * my.baseWidth + poffset; can.arc(spx, spy, my.baseWidth / 4, 0, 2 * Math.PI, false); can.moveTo(spx, spy); var epx = endP.I * my.baseWidth + poffset, epy = endP.J * my.baseWidth + poffset; can.lineTo(epx, epy); can.moveTo(epx + my.baseWidth / 4, epy); can.arc(epx, epy, my.baseWidth / 4, 0, 2 * Math.PI, false); can.closePath(); can.stroke(); }
评论0