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
JavaScript
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
};
};