UNPKG

jellybubbleeffect-santoso

Version:

This repository demonstrates a simple implementation of a jelly bubble effect using JavaScript. It creates a canvas element and draws multiple bubbles with a jelly-like animation.

1,189 lines (1,124 loc) 34.8 kB
const canvas = document.createElement('canvas'); document.body.appendChild(canvas); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; class Star { constructor(x, y, radius, color, velocity) { this.x = x; this.y = y; this.radius = radius; this.color = color; this.velocity = velocity; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = this.color; ctx.fill(); ctx.closePath(); } update() { this.draw(); this.x += this.velocity.x; this.y += this.velocity.y; } } const stars = []; function createGalaxy() { for (let i = 0; i < 200; i++) { const x = Math.random() * canvas.width; const y = Math.random() * canvas.height; const radius = Math.random() * 3; const color = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, ${Math.random()})`; const velocity = { x: (Math.random() - 0.5) * 0.5, y: (Math.random() - 0.5) * 0.5 }; stars.push(new Star(x, y, radius, color, velocity)); } } function animate() { requestAnimationFrame(animate); ctx.clearRect(0, 0, canvas.width, canvas.height); stars.forEach(star => { star.update(); if (star.x + star.radius < 0) { star.x = canvas.width + star.radius; } if (star.x - star.radius > canvas.width) { star.x = -star.radius; } if (star.y + star.radius < 0) { star.y = canvas.height + star.radius; } if (star.y - star.radius > canvas.height) { star.y = -star.radius; } }); } createGalaxy(); animate(); ('use strict'); let doc = document; let sys = {}; sys.mySave = { save: function(key, value) { localStorage.setItem(key, JSON.stringify(value)); }, getsave: function(key) { return JSON.parse(localStorage.getItem(key)) || []; } }; sys.getel = function(o) { return doc.querySelectorAll(o); }; let map = document.getElementById('map'); let box = document.getElementById('box'); let audioClick = document.getElementById('audioClick'); let audioGo = document.getElementById('audioGo'); let audioKill = document.getElementById('audioKill'); let audioEat = document.getElementById('audioEat'); let Root = { fontSize: parseFloat(getComputedStyle(document.documentElement, false)['fontSize']), chessR: null, funReDraw: null, arrReDraw: [], funRules: null, arrDead: [], arrMap: [ { n: '車', xy: [0, 0], t: 'b' }, { n: '馬', xy: [1, 0], t: 'b' }, { n: '象', xy: [2, 0], t: 'b' }, { n: '仕', xy: [3, 0], t: 'b' }, { n: '將', xy: [4, 0], t: 'b' }, { n: '仕', xy: [5, 0], t: 'b' }, { n: '象', xy: [6, 0], t: 'b' }, { n: '馬', xy: [7, 0], t: 'b' }, { n: '車', xy: [8, 0], t: 'b' }, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { n: '砲', xy: [1, 2], t: 'b' }, {}, {}, {}, {}, {}, { n: '砲', xy: [7, 2], t: 'b' }, {}, { n: '卒', xy: [0, 3], t: 'b' }, {}, { n: '卒', xy: [2, 3], t: 'b' }, {}, { n: '卒', xy: [4, 3], t: 'b' }, {}, { n: '卒', xy: [6, 3], t: 'b' }, {}, { n: '卒', xy: [8, 3], t: 'b' }, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { n: '兵', xy: [0, 6], t: 'r' }, {}, { n: '兵', xy: [2, 6], t: 'r' }, {}, { n: '兵', xy: [4, 6], t: 'r' }, {}, { n: '兵', xy: [6, 6], t: 'r' }, {}, { n: '兵', xy: [8, 6], t: 'r' }, {}, { n: '炮', xy: [1, 7], t: 'r' }, {}, {}, {}, {}, {}, { n: '炮', xy: [7, 7], t: 'r' }, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { n: '車', xy: [0, 9], t: 'r' }, { n: '馬', xy: [1, 9], t: 'r' }, { n: '相', xy: [2, 9], t: 'r' }, { n: '士', xy: [3, 9], t: 'r' }, { n: '帥', xy: [4, 9], t: 'r' }, { n: '士', xy: [5, 9], t: 'r' }, { n: '相', xy: [6, 9], t: 'r' }, { n: '馬', xy: [7, 9], t: 'r' }, { n: '車', xy: [8, 9], t: 'r' } ] }; let mapSize = innerWidth >= innerHeight ? { width: Math.floor(innerHeight * 0.81 * 2), height: Math.floor(innerHeight * 0.9 * 2) } : { width: Math.floor(innerWidth * 0.98 * 2), height: Math.floor(innerWidth * 1.1111 * 2) }; mapSize.width = mapSize.width % 8 == 0 ? mapSize.width : mapSize.width - (mapSize.width % 8); mapSize.height = mapSize.height % 9 == 0 ? mapSize.height : mapSize.height - (mapSize.height % 9); console.table(mapSize); map.width = mapSize.width * 1.15; map.height = mapSize.height * 1.15; //map.height = map.width * window.devicePixelRatio; //map.width = map.height * window.devicePixelRatio; let w = Math.floor(mapSize.width / 8); let h = Math.floor(mapSize.height / 9); let p = map.getContext('2d'); if (innerWidth <= 700 && innerHeight > innerWidth) { map.style.cssText = 'width: ' + mapSize.width / 2 + 'px;height:' + mapSize.height / 2 + 'px;border: 0.16rem solid darkgoldenrod;'; p.lineWidth = 3; } else { p.lineWidth = 2; map.style.cssText = 'width: ' + mapSize.width / 2 + 'px;height:' + mapSize.height / 2 + 'px;'; } map.style.marginLeft = -parseFloat(map.style.width) / 2 - parseFloat(getComputedStyle(map, null).borderWidth) + 'px'; if (!getComputedStyle(map, null).borderWidth) { map.style.marginLeft = -parseFloat(map.style.width) / 2 - parseFloat(getComputedStyle(map, null).borderLeftWidth) + 'px'; } map.style.marginTop = -parseFloat(map.style.height) / 2 + 'px'; Root.canvasAndScreenRatioWidth = map.width / parseFloat(map.style.width); Root.canvasAndScreenRatioHeight = map.height / parseFloat(map.style.height); function viewInteractive() { let oBtnChangeForm = document.querySelectorAll('#regBtn,#youkeBtn,#forgetBtn'); let oFormView = document.querySelectorAll('.form'); let gameMenu = document.querySelectorAll('#gameMenu')[0]; let chessboard = document.querySelectorAll('#Chessboard')[0]; chessboard.style.marginLeft = -parseFloat(map.style.marginLeft) + 20 + 'px'; chessboard.style.marginTop = parseFloat(map.style.marginTop) + 20 + 'px'; chessboard.style.width = parseFloat(map.style.width) / 3 + 'px'; gameMenu.style.marginLeft = -parseFloat(map.style.marginLeft) + 20 + 'px'; gameMenu.style.marginTop = -parseFloat(map.style.marginTop) - 40 + 'px'; let oFormView3 = [...oFormView].slice(1, oFormView.length); for (let i = 0; i < oBtnChangeForm.length; i++) { oBtnChangeForm[i].addEventListener( 'click', function() { for (let all = 0; all < oBtnChangeForm.length; all++) { oFormView3[all].style.transform = 'translateX(-100vw)'; } oFormView3[i].style.transform = 'translateX(0vw)'; }, false ); } } viewInteractive(); function funCoordinateX(x) { return (mapSize.width / 8) * x + w / 8 + 0.5; } function funCoordinateY(y) { return (mapSize.height / 9) * y + h / 9 + 0.5; } p.translate(mapSize.width * (0.12 / 2), mapSize.height * (0.12 / 2)); function funDrawMap() { p.beginPath(); p.fillStyle = 'rgba(249,216,162,1)'; p.fillRect(-mapSize.width * (0.12 / 2), -mapSize.height * (0.12 / 2), map.width, map.height); p.closePath(); p.beginPath(); p.strokeStyle = '#000'; //console.log(mapSize.width); for (let i = 0; i < 9; i++) { p.moveTo(w * i + w / 8 + 0.5, h / 9 + 0.5); p.lineTo(w * i + w / 8 + 0.5, (mapSize.height / 9) * 4 + h / 9 + 0.5); p.moveTo(w * i + w / 8 + 0.5, (mapSize.height / 9) * 5 + h / 9 + 0.5); p.lineTo(w * i + w / 8 + 0.5, (mapSize.height / 9) * 9 + h / 9 + 0.5); if (i == 0 || i == 8) { p.moveTo(w * i + w / 8 + 0.5, (mapSize.height / 9) * 4 + h / 9 + 0.5); p.lineTo(w * i + w / 8 + 0.5, (mapSize.height / 9) * 5 + h / 9 + 0.5); } } p.stroke(); p.closePath(); p.beginPath(); for (let i = 0; i < 10; i++) { p.moveTo(w / 8 + 0.5, h * i + h / 9 + 0.5); p.lineTo(mapSize.width + w / 8 + 0.5, h * i + h / 9 + 0.5); } p.stroke(); p.closePath(); function DrawPost(x, y) { p.beginPath(); p.strokeStyle = '#000'; if (innerWidth <= 700 && innerHeight > innerWidth) { p.lineWidth = 3; //map.style.marginTop = -(map.height)/2 + 'px'; } else { p.lineWidth = 2; } if (x != 8) { p.moveTo(w * x + w / 8 + w * 0.08 + 0.5, (mapSize.height / 9) * y + h / 9 + 0.5 - w * 0.2); p.lineTo(w * x + w / 8 + w * 0.08 + 0.5, (mapSize.height / 9) * y + h / 9 + 0.5 - w * 0.08); p.lineTo(w * x + w / 8 + w * 0.25, (mapSize.height / 9) * y + h / 9 + 0.5 - w * 0.08); p.moveTo(w * x + w / 8 + w * 0.08 + 0.5, (mapSize.height / 9) * y + h / 9 + 0.5 + w * 0.2); p.lineTo(w * x + w / 8 + w * 0.08 + 0.5, (mapSize.height / 9) * y + h / 9 + 0.5 + w * 0.08); p.lineTo(w * x + w / 8 + w * 0.25 + 0.5, (mapSize.height / 9) * y + h / 9 + 0.5 + w * 0.08); } else { } if (x == 0) { } else { p.moveTo(w * x + w / 8 - w * 0.08, (mapSize.height / 9) * y + h / 9 + 0.5 + w * 0.2); p.lineTo(w * x + w / 8 - w * 0.08, (mapSize.height / 9) * y + h / 9 + 0.5 + w * 0.08); p.lineTo(w * x + w / 8 - w * 0.25, (mapSize.height / 9) * y + h / 9 + 0.5 + w * 0.08); p.moveTo(w * x + w / 8 - w * 0.08, (mapSize.height / 9) * y + h / 9 + 0.5 - w * 0.2); p.lineTo(w * x + w / 8 - w * 0.08, (mapSize.height / 9) * y + h / 9 + 0.5 - w * 0.08); p.lineTo(w * x + w / 8 - w * 0.25, (mapSize.height / 9) * y + h / 9 + 0.5 - w * 0.08); } p.stroke(); p.closePath(); } for (let i = 0; i < 9; i++) { if (i % 2 == 0) { DrawPost(i, 6); DrawPost(i, 3); } else if (i == 1 || i == 7) { DrawPost(i, 2); DrawPost(i, 7); } else { //空 } } p.beginPath(); p.moveTo(funCoordinateX(3), funCoordinateY(7)); p.lineTo(funCoordinateX(5), funCoordinateY(9)); p.moveTo(funCoordinateX(5), funCoordinateY(7)); p.lineTo(funCoordinateX(3), funCoordinateY(9)); p.moveTo(funCoordinateX(3), funCoordinateY(2)); p.lineTo(funCoordinateX(5), funCoordinateY(0)); p.moveTo(funCoordinateX(5), funCoordinateY(2)); p.lineTo(funCoordinateX(3), funCoordinateY(0)); p.stroke(); p.closePath(); p.beginPath(); //恢复p.save()保存的样式,否则棋子的文字样式会叠加到楚河汉界文字上 p.restore(); p.fillStyle = '#000'; //宽度小于700px 且竖屏 if (innerWidth <= 700 && innerHeight > innerWidth) { // map.style.top = '45%'; p.font = `${(w / 2.5) * 1.5}px STxingkai`; // map.style.marginTop = -(map.height) / 8 + 'px'; } else { p.font = `${(w / 2.5) * 1.6}px STxingkai`; } p.fillText('楚河', funCoordinateX(1), funCoordinateY(4.7)); p.fillText('汉界', funCoordinateX(6), funCoordinateY(4.7)); p.save(); p.closePath(); } function funPutChess() { if (innerWidth <= 700 && innerHeight > innerWidth) { p.font = `bold ${(w / 2.5) * 1.5}px 楷体`; //map.style.marginTop = -(map.height)/2 + 'px'; } else { p.font = `bold ${(w / 2.5) * 1.3}px 楷体`; } function drawChess() { //console.table(Root) for (let i = 0; i < Root.arrMap.length; i++) { if (Object.keys(Root.arrMap[i]).length !== 0) { p.beginPath(); // if(innerWidth<750){ // // // }else{ // p.shadowColor = 'rgba(0, 0, 0, 1)'; // p.shadowOffsetX = 4; // p.shadowOffsetY = 3; // p.shadowBlur = 10; // } if (Root.arrMap[i].t === 'b') { p.fillStyle = 'rgba(226,171,84,1)'; } else if (Root.arrMap[i].t === 'r') { p.fillStyle = 'rgba(255,160,122,1)'; } else { } p.arc( funCoordinateX(Root.arrMap[i].xy[0]), funCoordinateY(Root.arrMap[i].xy[1]), (w / 2.5) * 1.1, 0, (360 * Math.PI) / 180 ); p.fill(); p.closePath(); p.beginPath(); //p.rotate(Math.PI*2); if (Root.arrMap[i].t === 'b') { p.fillStyle = '#000'; } else if (Root.arrMap[i].t === 'r') { p.fillStyle = '#f00'; } else { } p.textAlign = 'center'; p.textBaseline = 'middle'; // if(innerWidth<750){ // // // }else{ // p.shadowColor = 'rgba(255, 255, 255, 0.8)'; // p.shadowOffsetX = -10; // p.shadowOffsetY = -10; // p.shadowBlur = 40; // } p.fillText( Root.arrMap[i].n, funCoordinateX(Root.arrMap[i].xy[0]), funCoordinateY(Root.arrMap[i].xy[1]) ); p.closePath(); } else { } } } drawChess(); } Root.arrReDraw.push(funDrawMap, funPutChess); Root.funReDraw = function() { p.clearRect(-mapSize.width * (0.12 / 2), -mapSize.height * (0.12 / 2), map.width, map.height); for (let i = 0; i < Root.arrReDraw.length; i++) { Root.arrReDraw[i](); } }; Root.oChessRecor = { title: null, win: null, lose: null, arr: [] }; Root.funChessRecor = function(nowChess, target) { let ChineseNum = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九']; let name, nowX, action, targetPosition; name = nowChess.n; nowX = nowChess.t == 'r' ? ChineseNum[10 - (nowChess.xy[0] + 1)] : nowChess.xy[0] + 1; if (nowChess.xy[1] == target.xy[1]) { action = '平'; targetPosition = nowChess.t == 'r' ? ChineseNum[10 - (target.xy[0] + 1)] : target.xy[0] + 1; } else if (nowChess.xy[0] == target.xy[0]) { if (nowChess.t == 'r') { action = target.xy[1] < nowChess.xy[1] ? '进' : '退'; targetPosition = ChineseNum[Math.abs(target.xy[1] - nowChess.xy[1])]; } else { action = target.xy[1] > nowChess.xy[1] ? '进' : '退'; targetPosition = Math.abs(target.xy[1] - nowChess.xy[1]); } } else { if (nowChess.t == 'r') { action = target.xy[1] < nowChess.xy[1] ? '进' : '退'; } else { action = target.xy[1] > nowChess.xy[1] ? '进' : '退'; } targetPosition = nowChess.t == 'r' ? ChineseNum[10 - (target.xy[0] + 1)] : target.xy[0] + 1; } console.log(name + nowX + action + targetPosition); Root.oChessRecor.arr.push(name + nowX + action + targetPosition); return name + nowX + action + targetPosition; }; Root.funRules = function(oNowSelectChess, oTager) { //合并棋子兵种 (部分棋子走法相同 ). let oChess = oNowSelectChess; //验证(布尔值) let bVerification = false; let chessType = ''; //可行坐标 let arrPracticable = []; //棋子兵种判断 统一改为红棋名字,具体判断oNowSelectChess时 再判断其属于红方或黑方 if (oChess.n == '相' || oChess.n == '象') { chessType = '相'; } else if (oChess.n == '士' || oChess.n == '仕') { chessType = '士'; } else if (oChess.n == '帥' || oChess.n == '將') { chessType = '帥'; } else if (oChess.n == '炮' || oChess.n == '砲') { chessType = '炮'; } else if (oChess.n == '兵' || oChess.n == '卒') { chessType = '兵'; } else if (oChess.n == '車') { chessType = '車'; } else if (oChess.n == '馬') { chessType = '馬'; } /*验证目标是否包含在可行范围*/ function funComprise(practicable, tager) { if (oTager) { practicable.forEach(function(item, index) { if (item[0] == tager.xy[0] && item[1] == tager.xy[1]) { bVerification = true; } else { //没找到 } }); } else { //未传入目标 } } switch (chessType) { case '車': (function() { //横向与纵向 循环棋盘最大跨度 //x+方向 y不变 for (let x = 1; x < 9; x++) { if (oChess.xy[0] + x <= 8 && oChess.xy[0] + x >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] + x + oChess.xy[1] * 9].xy) { //类型不同 允许该坐标添加 if (Root.arrMap[oChess.xy[0] + x + oChess.xy[1] * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0] + x, oChess.xy[1]]); //有棋子 停止后续添加 break; } else { break; } } else { //空位置 arrPracticable.push([oChess.xy[0] + x, oChess.xy[1]]); } } } //x-方向 for (let x = 1; x < 9; x++) { if (oChess.xy[0] - x <= 8 && oChess.xy[0] - x >= 0) { if (Root.arrMap[oChess.xy[0] - x + oChess.xy[1] * 9].xy) { //类型不同 允许该坐标添加 //alert(Root.arrMap[oChess.xy[0]-x+oChess.xy[1]*9].t+','+oChess.t) if (Root.arrMap[oChess.xy[0] - x + oChess.xy[1] * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0] - x, oChess.xy[1]]); //有棋子 停止后续添加 break; } else { break; } } else { //空位置 arrPracticable.push([oChess.xy[0] - x, oChess.xy[1]]); } } } //y+方向 , x轴不变 for (let y = 1; y <= 9; y++) { if (oChess.xy[1] + y <= 9 && oChess.xy[1] + y >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + y) * 9].xy) { //类型不同 允许该坐标添加 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + y) * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0], oChess.xy[1] + y]); //不同阵营棋子 添加该位置后停止后续添加(可吃该棋子) break; //同阵营棋子,直接终止 } else { break; } } else { //空位置 arrPracticable.push([oChess.xy[0], oChess.xy[1] + y]); } } } //y-方向 , x轴不变 for (let y = 1; y <= 9; y++) { if (oChess.xy[1] - y <= 9 && oChess.xy[1] - y >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - y) * 9].xy) { //类型不同 允许该坐标添加 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - y) * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0], oChess.xy[1] - y]); //不同阵营棋子 停止后续添加 break; //同阵营棋子,直接终止 } else { break; } } else { //空位置 //console.log(arrPracticable) arrPracticable.push([oChess.xy[0], oChess.xy[1] - y]); } } } //检测目标位置是否在可行坐标中,判断数组相等 funComprise(arrPracticable, oTager); })(); break; case '馬': //验证马蹩脚,传入主方向的x或y,存入撇脚位置; let arrPoor = []; function funPoor(x, y) { //马的朝向,大的那一个 //x轴右移进一格或左移一格,y不变 //+1 -1超范围判断必须分开... 否则影响另一组坐标的push if (x == -2 && oChess.xy[0] - 2 >= 0) { //转换为数组下标 验证该点是否有棋子阻挡,加入可行数组arrPracticable时 直接加x和y(两种) if (Root.arrMap[oChess.xy[0] - 1 + oChess.xy[1] * 9].xy) { arrPoor.push(Root.arrMap[oChess.xy[0] - 1 + oChess.xy[1] * 9]); } else { //x-2方向 有y+1 y-1两种可能 oChess.xy[1] - 1 >= 0 ? arrPracticable.push([oChess.xy[0] - 2, oChess.xy[1] - 1]) : null; oChess.xy[1] + 1 <= 9 ? arrPracticable.push([oChess.xy[0] - 2, oChess.xy[1] + 1]) : null; } } else if (x == 2 && oChess.xy[0] + 2 <= 8) { if (Root.arrMap[oChess.xy[0] + 1 + oChess.xy[1] * 9].xy) { arrPoor.push(Root.arrMap[oChess.xy[0] + 1 + oChess.xy[1] * 9]); } else { oChess.xy[1] - 1 >= 0 ? arrPracticable.push([oChess.xy[0] + 2, oChess.xy[1] - 1]) : null; oChess.xy[1] + 1 <= 9 ? arrPracticable.push([oChess.xy[0] + 2, oChess.xy[1] + 1]) : null; } } else if (y == -2 && oChess.xy[1] - 2 >= 0) { if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - 1) * 9].xy) { arrPoor.push(Root.arrMap[oChess.xy[0] + (oChess.xy[1] - 1) * 9]); } else { oChess.xy[0] - 1 >= 0 ? arrPracticable.push([oChess.xy[0] - 1, oChess.xy[1] - 2]) : null; oChess.xy[0] + 1 <= 8 ? arrPracticable.push([oChess.xy[0] + 1, oChess.xy[1] - 2]) : null; } } else if (y == 2 && oChess.xy[1] + 2 <= 9) { if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + 1) * 9].xy) { arrPoor.push(Root.arrMap[oChess.xy[0] + (oChess.xy[1] + 1) * 9]); } else { oChess.xy[0] - 1 >= 0 ? arrPracticable.push([oChess.xy[0] - 1, oChess.xy[1] + 2]) : null; oChess.xy[0] + 1 <= 8 ? arrPracticable.push([oChess.xy[0] + 1, oChess.xy[1] + 2]) : null; } } } //(function(){ //x或y只能有一个加2或减2,另一个加1或减1 ,共8个方向 跨度为2的方向验证蹩脚 //let arrTowards = [-2,2] //四个主方向 (0仅为了占位) funPoor(2, 0); funPoor(-2, 0); funPoor(0, 2); funPoor(0, -2); //arrPracticable可行坐标中范围可能超出棋盘 ,将超出的和同阵营棋子过滤 //console.log(arrPracticable); arrPracticable = arrPracticable.filter(function(item, index, arr) { return ( item[0] >= 0 && item[0] <= 8 && item[1] >= 0 && item[1] <= 9 && Root.arrMap[item[0] + item[1] * 9].t != oChess.t ); }); funComprise(arrPracticable, oTager); if (arrPoor.length == 0) { } else { console.error('马被以下位置撇脚:'); console.log(arrPoor); } //})(); break; case '相': (function() { let arrPoor = []; let arr = [[2, 2], [2, -2], [-2, -2], [-2, 2]]; for (let i = 0; i < arr.length; i++) { // 当前棋子与可行位差值x y相加不得超出棋盘 if ( oChess.xy[0] + arr[i][0] <= 8 && oChess.xy[0] + arr[i][0] >= 0 && oChess.xy[1] + arr[i][1] <= 9 && oChess.xy[1] + arr[i][1] >= 0 ) { //塞象眼 if (Root.arrMap[oChess.xy[0] + arr[i][0] / 2 + (oChess.xy[1] + arr[i][1] / 2) * 9].xy) { arrPoor.push([ parseInt(arr[i][0] / 2) + oChess.xy[0], parseInt(arr[i][1] / 2) + oChess.xy[1] ]); } else { //可行位置,原棋子位置+arr偏差(!!!下面数组数字类型怎么被转字符串了?) arrPracticable.push([oChess.xy[0] + arr[i][0], oChess.xy[1] + arr[i][1]]); } } else { //超出棋盘 } } //过滤同阵营棋子位置/判断Y(item[1])不允许过河 arrPracticable = arrPracticable.filter(function(item, index, arr) { if (oChess.t == 'r') { return item[1] <= 9 && item[1] >= 5 && Root.arrMap[item[0] + item[1] * 9].t != oChess.t; } else if (oChess.t == 'b') { return item[1] <= 4 && item[1] >= 0 && Root.arrMap[item[0] + item[1] * 9].t != oChess.t; } else { //未知数据 } }); funComprise(arrPracticable, oTager); if (arrPoor.length == 0) { } else { console.error('象被以下位置撇脚:'); console.log(arrPoor); } })(); break; case '士': (function() { let arr = [[1, 1], [1, -1], [-1, -1], [-1, 1]]; for (let i = 0; i < arr.length; i++) { if (oChess.xy[0] + arr[i][0] <= 5 && oChess.xy[0] + arr[i][0] >= 3) { if (oChess.t == 'r') { oChess.xy[1] + arr[i][1] <= 9 && oChess.xy[1] + arr[i][1] >= 7 ? arrPracticable.push([oChess.xy[0] + arr[i][0], oChess.xy[1] + arr[i][1]]) : null; } else if (oChess.t == 'b') { oChess.xy[1] + arr[i][1] <= 2 && oChess.xy[1] + arr[i][1] >= 0 ? arrPracticable.push([oChess.xy[0] + arr[i][0], oChess.xy[1] + arr[i][1]]) : null; } else { //未知数据 } } else { //x方向超出 } } //移除同阵营棋子位置 arrPracticable = arrPracticable.filter(function(item, index, arr) { return Root.arrMap[item[0] + item[1] * 9].t != oChess.t; }); funComprise(arrPracticable, oTager); })(); break; case '帥': //统一验证x范围,再验证y (function() { oChess.xy[0] + 1 <= 5 ? arrPracticable.push([oChess.xy[0] + 1, oChess.xy[1]]) : null; oChess.xy[0] - 1 >= 3 ? arrPracticable.push([oChess.xy[0] - 1, oChess.xy[1]]) : null; //if(oTager.xy[0]==oNowSelectChess.xy[0]){ if (oNowSelectChess.t == 'r') { for (let y = 1; y <= 9; y++) { if (oChess.xy[1] - y <= 9 && oChess.xy[1] - y >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - y) * 9].n == '將') { //类型不同 允许该坐标添加到可行 arrPracticable.push([oChess.xy[0], oChess.xy[1] - y]); //不同阵营棋子 停止后续添加 break; //同阵营棋子,直接终止 } else { if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - y) * 9].xy) { break; } //非將位置 //console.log(arrPracticable) //arrPracticable.push([oChess.xy[0],oChess.xy[1]-y]); } } } } else if (oNowSelectChess.t == 'b') { for (let y = 1; y <= 9; y++) { if (oChess.xy[1] + y <= 9 && oChess.xy[1] + y >= 0) { if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + y) * 9].n == '帥') { //类型不同 允许该坐标添加到可行 arrPracticable.push([oChess.xy[0], oChess.xy[1] + y]); //不同阵营棋子 停止后续添加 break; //同阵营棋子,直接终止 } else { //有棋子才终止循环,没棋子继续循环找到 对方将帥 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + y) * 9].xy) { break; } //非將位置 //console.log(arrPracticable) //arrPracticable.push([oChess.xy[0],oChess.xy[1]-y]); } } } } else { //未知阵营 } //}; if (oChess.t == 'r') { oChess.xy[1] + 1 <= 9 ? arrPracticable.push([oChess.xy[0], oChess.xy[1] + 1]) : null; oChess.xy[1] - 1 >= 7 ? arrPracticable.push([oChess.xy[0], oChess.xy[1] - 1]) : null; } else if (oChess.t == 'b') { oChess.xy[1] - 1 >= 0 ? arrPracticable.push([oChess.xy[0], oChess.xy[1] - 1]) : null; oChess.xy[1] + 1 <= 2 ? arrPracticable.push([oChess.xy[0], oChess.xy[1] + 1]) : null; } else { //未知数据 } arrPracticable = arrPracticable.filter(function(item, index, arr) { if (Root.arrMap[item[0] + item[1] * 9]) { return Root.arrMap[item[0] + item[1] * 9].t != oChess.t; } }); funComprise(arrPracticable, oTager); })(); break; case '炮': (function() { //横向与纵向 循环棋盘最大跨度 //x+方向 y不变,bEat 可以吃子了 跳过越子这一次循环 //各方向是否越子 let bEat = { XPlush: false, XReduce: false, YPlush: false, YReduce: false }; for (let x = 1; x < 9; x++) { if (oChess.xy[0] + x <= 8 && oChess.xy[0] + x >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] + x + oChess.xy[1] * 9].xy) { //arrPracticable.push([oChess.xy[0]+x,oChess.xy[1]]); //仅在有棋子 且已越过子停止这一次后续添加,没越子设置为越子 if (!bEat.XPlush) { bEat.XPlush = true; continue; } } else { //空位置 , 未越子时才添加到可行,越子后不能添加空位置 if (!bEat.XPlush) { arrPracticable.push([oChess.xy[0] + x, oChess.xy[1]]); } else { //越子了 不能再走空位 } } //如果 越子,可以开始吃子了 if (bEat.XPlush) { //不是空的位置(发现棋子): if (Root.arrMap[oChess.xy[0] + x + oChess.xy[1] * 9].xy) { //不是同阵营 添加到可行位置数组 if (Root.arrMap[oChess.xy[0] + x + oChess.xy[1] * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0] + x, oChess.xy[1]]); break; } else { //同阵营 } //不管是不是同阵营棋子 都停止搜索 break; } } else { //未越子 不能开始吃子 } } } //x-方向 for (let x = 1; x < 9; x++) { if (oChess.xy[0] - x <= 8 && oChess.xy[0] - x >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] - x + oChess.xy[1] * 9].xy) { //arrPracticable.push([oChess.xy[0]+x,oChess.xy[1]]); //仅在有棋子 且已越过子停止这一次后续添加,没越子设置为越子 if (!bEat.XReduce) { bEat.XReduce = true; continue; } } else { //空位置 , 未越子时才添加到可行,越子后不能添加空位置 if (!bEat.XReduce) { arrPracticable.push([oChess.xy[0] - x, oChess.xy[1]]); } else { //越子了 不能再走空位 } } //如果 越子,可以开始吃子了 if (bEat.XReduce) { //不是空的位置(发现棋子): if (Root.arrMap[oChess.xy[0] - x + oChess.xy[1] * 9].xy) { //不是同阵营 添加到可行位置数组 if (Root.arrMap[oChess.xy[0] - x + oChess.xy[1] * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0] - x, oChess.xy[1]]); break; } else { //同阵营 } //不管是不是同阵营棋子 都停止搜索 break; } } else { //未越子 不能开始吃子 } } } //y+方向 , x轴不变 for (let y = 1; y <= 9; y++) { if (oChess.xy[1] + y <= 9 && oChess.xy[1] + y >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + y) * 9].xy) { //arrPracticable.push([oChess.xy[0]+x,oChess.xy[1]]); //仅在有棋子 且已越过子停止这一次后续添加,没越子设置为越子 if (!bEat.YPlush) { bEat.YPlush = true; continue; } } else { //空位置 , 未越子时才添加到可行,越子后不能添加空位置 if (!bEat.YPlush) { arrPracticable.push([oChess.xy[0], oChess.xy[1] + y]); } else { //越子了 不能再走空位 } } //如果 越子,可以开始吃子了 if (bEat.YPlush) { //不是空的位置(发现棋子): if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + y) * 9].xy) { //不是同阵营 添加到可行位置数组 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] + y) * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0], oChess.xy[1] + y]); break; } else { //同阵营 } //不管是不是同阵营棋子 都停止搜索 break; } } else { //未越子 不能开始吃子 } } } //y-方向 , x轴不变 for (let y = 1; y <= 9; y++) { if (oChess.xy[1] - y <= 9 && oChess.xy[1] - y >= 0) { //计算出可行位置(数组xy)在arrMap中的下标 找出该下标的信息 //有棋子 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - y) * 9].xy) { //arrPracticable.push([oChess.xy[0]+x,oChess.xy[1]]); //仅在有棋子 且已越过子停止这一次后续添加,没越子设置为越子 if (!bEat.YReduce) { bEat.YReduce = true; continue; } } else { //空位置 , 未越子时才添加到可行,越子后不能添加空位置 if (!bEat.YReduce) { arrPracticable.push([oChess.xy[0], oChess.xy[1] - y]); } else { //越子了 不能再走空位 } } //如果 越子,可以开始吃子了 if (bEat.YReduce) { //不是空的位置(发现棋子): if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - y) * 9].xy) { //不是同阵营 添加到可行位置数组 if (Root.arrMap[oChess.xy[0] + (oChess.xy[1] - y) * 9].t != oChess.t) { arrPracticable.push([oChess.xy[0], oChess.xy[1] - y]); break; } else { //同阵营 } //不管是不是同阵营棋子 越子后遇到棋子都停止搜索,且不能添加空位和同阵营 break; } } else { //未越子 不能开始吃子 } } } //检测目标位置是否在可行坐标中,判断数组相等 funComprise(arrPracticable, oTager); })(); break; case '兵': (function() { if (oChess.t == 'r') { //前进方向(不管是否过河,都可以前进) oChess.xy[1] - 1 >= 0 ? arrPracticable.push([oChess.xy[0], oChess.xy[1] - 1]) : null; //过河 if (oChess.xy[1] >= 0 && oChess.xy[1] <= 4) { oChess.xy[0] - 1 >= 0 ? arrPracticable.push([oChess.xy[0] - 1, oChess.xy[1]]) : null; oChess.xy[0] + 1 <= 8 ? arrPracticable.push([oChess.xy[0] + 1, oChess.xy[1]]) : null; } else { //未过河 不能左右 } } else if (oChess.t == 'b') { //前进方向(不管是否过河,都可以前进) oChess.xy[1] + 1 <= 9 ? arrPracticable.push([oChess.xy[0], oChess.xy[1] + 1]) : null; //过河 if (oChess.xy[1] >= 5 && oChess.xy[1] <= 9) { oChess.xy[0] - 1 >= 0 ? arrPracticable.push([oChess.xy[0] - 1, oChess.xy[1]]) : null; oChess.xy[0] + 1 <= 8 ? arrPracticable.push([oChess.xy[0] + 1, oChess.xy[1]]) : null; } else { //未过河 不能左右 } } else { //未知阵营 } funComprise(arrPracticable, oTager); })(); break; default: console.error('棋子兵种异常'); break; } console.log('可行位置:'); console.log(arrPracticable); console.log('验证通过?:' + bVerification); console.log('全局信息:'); console.log(Root.arrMap); return { bVerification: bVerification, arrPracticable: arrPracticable }; };