|
本节对游戏游玩时的互动部分进行开发,主要包括宝石选中、宝石移动、宝石消除、互动音效等。
一、游玩触摸事件
在touchEventHandlerPlaying触摸事件里:
(1)当用户点击左上角“返回”按钮时,则播放点击声音,删除当前监听器,游戏状态变为return,添加touchEventHandlerReturn监听器(游戏正在进行中,是否真的要结束游戏并返回);
(2)当用户点击左上角“帮助”按钮时,则播放点击声音,删除当前监听器,弹出窗口help,画面添加touchEventHandlerHelp触摸事件(此时不暂停游戏)。
(3)当用户点击下方“放弃”按钮时,则播放点击声音,删除当前监听器,游戏状态变为giveup,添加touchEventHandlerGiveup监听器(游戏正在进行中,是否真的要放弃并结束游戏);
(4)当用户点击下方“保存”按钮时,则播放点击声音,删除当前监听器,游戏状态变为pause,游戏暂停,弹出窗口saveGame,添加touchEventHandlerSaveGame监听器。
(5)当用户点击中间位置时,首先确定点击的格子位置,如果格子上有宝石,则播放选中宝石的声音,设置curSelectedIndex为当前格子(在myRender里面会隔若干帧使选中的宝石的偏移一点点位置,实现选中动画);如果格子上没有宝石且curSelectedIndex不为-1(有选中的宝石),则创建一条由curSelectedIndex到点击位置的路径,如果该路径存在则替换随机列表中的curSelectedIndex和点击位置,curSelectedIndex设为-1,myRender开始渲染pathIndexs实现移动宝石动画;如果该路径不存在则播放无法移动的音效。
touchEventHandlerPlaying(e) {
e.preventDefault();
const x = e.touches[0].clientX;
const y = e.touches[0].clientY;
if (y > myRender.btnAreaStartUpY && y <= myRender.btnAreaEndUpY) {
if (x > myRender.btnAreaStartUpX1 && x <= myRender.btnAreaEndUpX1) {
myMusic.playPressButtonU();
canvas.removeEventListener(&#34;touchstart&#34;, this.touchHandler);
this.gamePopup = &#34;return&#34;;
this.touchHandler = this.touchEventHandlerReturn.bind(this);
canvas.addEventListener(&#34;touchstart&#34;, this.touchHandler);
} else if (x > myRender.btnAreaStartUpX2 && x <= myRender.btnAreaEndUpX2) {
myMusic.playPressButtonU();
canvas.removeEventListener(&#34;touchstart&#34;, this.touchHandler);
this.gamePopup = &#34;help&#34;;
this.touchHandler = this.touchEventHandlerHelp.bind(this);
canvas.addEventListener(&#34;touchstart&#34;, this.touchHandler);
}
} else if (y > myRender.btnAreaStartDownY && y <= myRender.btnAreaEndDownY) {
if (x > myRender.btnAreaStartDownX1 && x <= myRender.btnAreaEndDownX1) {
myMusic.playPressButtonU();
canvas.removeEventListener(&#34;touchstart&#34;, this.touchHandler);
this.gamePopup = &#34;giveup&#34;;
this.touchHandler = this.touchEventHandlerGiveup.bind(this);
canvas.addEventListener(&#34;touchstart&#34;, this.touchHandler);
} else if (x > myRender.btnAreaStartDownX2 && x <= myRender.btnAreaEndDownX2) {
if (myData.gameModel == 1) {
myMusic.playPressButtonU();
canvas.removeEventListener(&#34;touchstart&#34;, this.touchHandler);
this.gamePopup = &#34;saveGame&#34;;
myData.pauseBeginTime = new Date().getTime();
this.gameStatus = &#34;pause&#34;; //保存时游戏应该暂停
this.touchHandler = this.touchEventHandlerSaveGame.bind(this);
canvas.addEventListener(&#34;touchstart&#34;, this.touchHandler);
}
} else if (x > myRender.btnAreaStartDownX3 && x <= myRender.btnAreaEndDownX3) {
} else if (x > myRender.btnAreaStartDownX4 && x <= myRender.btnAreaEndDownX4) {
}
} else if (x > myRender.btnAreaStartCenterX && x <= myRender.btnAreaEndCenterX && y > myRender.btnAreaStartCenterY && y <= myRender.btnAreaEndCenterY) {
let blockWidth = (myRender.btnAreaEndCenterX-myRender.btnAreaStartCenterX)/9;
let touchColumnIndex = parseInt((x-myRender.btnAreaStartCenterX)/blockWidth);
let touchRowIndex = parseInt((y-myRender.btnAreaStartCenterY)/blockWidth);
if (myData.gemColors[touchRowIndex*9+touchColumnIndex] != 0) {
myMusic.playSelectGem();
myData.curSelectedIndex = touchRowIndex*9+touchColumnIndex;
} else if (myData.curSelectedIndex != -1) {
let index = touchRowIndex*9+touchColumnIndex;
myData.createNewPath(myData.curSelectedIndex,index,myData.playingSets[9]);
if (myData.pathIndexs.length == 0) {myMusic.playCannotMoveGem();return;} //播放禁止移动的音效
myData.randomIndexs[myData.randomIndexs.indexOf(index)] = myData.curSelectedIndex;
myData.curSelectedIndex = -1;
}
}
}
二、宝石移动
当选中一个宝石再点击黑白格子某一个空白格子时,游戏创建一条由新路径createNewPath,起点为curSelectedIndex,终点为当前点击格子。当游戏设置为穿越格子时,pathIndexs直接设置起点和终点,闪现过去。
在MyData.js里,增加createNewPath方法:
createNewPath(startIndex,endIndex) {
this.pathIndexs = new Array();
if (this.playingSets[9] == 1) { //穿越格子
this.pathIndexs.push(endIndex);
this.pathIndexs.push(startIndex);return;
}
let openlist = new Array();
let openlistG = new Array();
let openlistF = new Array();
let openlistParents = new Array();
let closelist = new Array();
let closelistParents = new Array();
let curIndex = startIndex;let curG = 0;
closelist.push(curIndex);closelistParents.push(-1);
nextPath(curIndex,endIndex,this.gemColors,openlist,openlistParents,openlistG,openlistF,closelist,curG);
let curOpenlistIndex = 0;let count = 0;
while (true) {
for (let i=1;i<openlist.length;i++) {
if (openlistF < openlistF[curOpenlistIndex]) curOpenlistIndex = i;
}
if (openlistF[curOpenlistIndex] > 1000) break;
curIndex = openlist[curOpenlistIndex];curG = openlistG[curOpenlistIndex];
closelist.push(curIndex);closelistParents.push(openlistParents[curOpenlistIndex]);
openlist.splice(curOpenlistIndex,1);openlistParents.splice(curOpenlistIndex,1);openlistG.splice(curOpenlistIndex,1);openlistF.splice(curOpenlistIndex,1);
nextPath(curIndex,endIndex,this.gemColors,openlist,openlistParents,openlistG,openlistF,closelist,curG);
if (curIndex == endIndex) break;
count++;if (count > 50) break;
curOpenlistIndex = 0;
}
curIndex = endIndex;
for (let i=closelist.length-1;i>=0;i--) {
if (closelist == curIndex) {
this.pathIndexs.push(curIndex);
curIndex = closelistParents;
}
}
}
该路径的生成算法nextPath使用A-star寻路算法,关于9×9格子的寻路算法部分见另一篇文章《A-star寻路算法实现(JavaScript)》,文章里有详细的讲解,在此不再赘述。
在MyData.js主体外部增加nextPath函数:
function nextPath(curIndex,endIndex,gemColors,openlist,openlistParents,openlistG,openlistF,closelist,curG) {
let topIndex = curIndex-9;
let bottomIndex = curIndex+9;
let leftIndex = curIndex-1;
let rightIndex = curIndex+1;
while (topIndex >= 0) {
let listIndex = -1;
for (let i=0;i<closelist.length;i++) {
if (closelist == topIndex) {listIndex = i;break;}
}
if (listIndex != -1) break;
for (let i=0;i<openlist.length;i++) {
if (openlist == topIndex) {listIndex = i;break;}
}
if (listIndex == -1) {
openlist.push(topIndex);openlistParents.push(curIndex);
let topIndexG = 10;let topIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(topIndex/9))+Math.abs(endIndex%9-topIndex%9))*10;let topIndexF = topIndexG+topIndexH;openlistG.push(topIndexG);openlistF.push(topIndexF+gemColors[topIndex]*1000);
} else if (curG+10 < openlistG[listIndex]) {
let topIndexG = curG+10;let topIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(topIndex/9))+Math.abs(endIndex%9-topIndex%9))*10;let topIndexF = topIndexG+topIndexH;openlistG[listIndex] = topIndexG;openlistF[listIndex] = topIndexF+gemColors[topIndex]*1000;openlistParents[listIndex] = curIndex;
}
break;
}
while (bottomIndex < 81) {
let listIndex = -1;
for (let i=0;i<closelist.length;i++) {
if (closelist == bottomIndex) {listIndex = i;break;}
}
if (listIndex != -1) break;
for (let i=0;i<openlist.length;i++) {
if (openlist == bottomIndex) {listIndex = i;break;}
}
if (listIndex == -1) {
openlist.push(bottomIndex);openlistParents.push(curIndex);
let bottomIndexG = 10;let bottomIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(bottomIndex/9))+Math.abs(endIndex%9-bottomIndex%9))*10;let bottomIndexF = bottomIndexG+bottomIndexH;openlistG.push(bottomIndexG);openlistF.push(bottomIndexF+gemColors[bottomIndex]*1000);
} else if (curG+10 < openlistG[listIndex]) {
let bottomIndexG = curG+10;let bottomIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(bottomIndex/9))+Math.abs(endIndex%9-bottomIndex%9))*10;let bottomIndexF = bottomIndexG+bottomIndexH;openlistG[listIndex] = bottomIndexG;openlistF[listIndex] = bottomIndexF+gemColors[bottomIndex]*1000;openlistParents[listIndex] = curIndex;
}
break;
}
while (leftIndex >= 0 && leftIndex%9 != 8) {
let listIndex = -1;
for (let i=0;i<closelist.length;i++) {
if (closelist == leftIndex) {listIndex = i;break;}
}
if (listIndex != -1) break;
for (let i=0;i<openlist.length;i++) {
if (openlist == leftIndex) {listIndex = i;break;}
}
if (listIndex == -1) {
openlist.push(leftIndex);openlistParents.push(curIndex);
let leftIndexG = 10;let leftIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(leftIndex/9))+Math.abs(endIndex%9-leftIndex%9))*10;let leftIndexF = leftIndexG+leftIndexH;openlistG.push(leftIndexG);openlistF.push(leftIndexF+gemColors[leftIndex]*1000);
} else if (curG+10 < openlistG[listIndex]) {
let leftIndexG = curG+10;let leftIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(leftIndex/9))+Math.abs(endIndex%9-leftIndex%9))*10;let leftIndexF = leftIndexG+leftIndexH;openlistG[listIndex] = leftIndexG;openlistF[listIndex] = leftIndexF+gemColors[leftIndex]*1000;openlistParents[listIndex] = curIndex;
}
break;
}
while (rightIndex < 81 && rightIndex%9 != 0) {
let listIndex = -1;
for (let i=0;i<closelist.length;i++) {
if (closelist == rightIndex) {listIndex = i;break;}
}
if (listIndex != -1) break;
for (let i=0;i<openlist.length;i++) {
if (openlist == rightIndex) {listIndex = i;break;}
}
if (listIndex == -1) {
openlist.push(rightIndex);openlistParents.push(curIndex);
let rightIndexG = 10;let rightIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(rightIndex/9))+Math.abs(endIndex%9-rightIndex%9))*10;let rightIndexF = rightIndexG+rightIndexH;openlistG.push(rightIndexG);openlistF.push(rightIndexF+gemColors[rightIndex]*1000);
} else if (curG+10 < openlistG[listIndex]) {
let rightIndexG = curG+10;let rightIndexH = (Math.abs(parseInt(endIndex/9)-parseInt(rightIndex/9))+Math.abs(endIndex%9-rightIndex%9))*10;let rightIndexF = rightIndexG+rightIndexH;openlistG[listIndex] = rightIndexG;openlistF[listIndex] = rightIndexF+gemColors[rightIndex]*1000;openlistParents[listIndex] = curIndex;
}
break;
}
}
三、宝石消除
宝石消除涉及的逻辑算法较为复杂,在”5消“的设定下,一次可能会只消除5颗宝石,也可能会出现消除33颗宝石的终极消除(一出即消),再加上魔法宝石的加成,消除算法变得更加复杂。在此只展示算法示例,有兴趣的可以自行研究,如果需要的话也可以另外写一篇文章进行讲解。
在MyData.js里修改clearGemsAndGetScore方法。
clearGemsAndGetScore(index,gemColorsOrIcons) {
if (gemColorsOrIcons == this.gemIcons && this.playingSets[2] == 0) {
if (this.clearIndexs == null) this.scorePower = 1;
return 0;
}
if (this.clearIndexs == null) this.clearIndexs = new Array();
//直线消除和斜线消除
let allClearNumber = 1;
let differentColorClear = false;
let upMagicNumber = 0;let downMagicNumber = 0;let leftMagicNumber = 0;let rightMagicNumber = 0;let upLeftMagicNumber = 0;let downRightMagicNumber = 0;let upRightMagicNumber = 0;let downLeftMagicNumber = 0;let upColor = 0;let downColor = 0;let leftColor = 0;let rightColor = 0;let upLeftColor = 0;let downRightColor = 0;let upRightColor = 0;let downLeftColor = 0;
let upClearNumber = 0;let leftClearNumber = 0;let upLeftClearNumber = 0;let upRightClearNumber = 0;
let addMagicNumber = 0;let subMagicNumber = 0;
let addMagicNumber_ = 0;let subMagicNumber_ = 0;
let curColor = gemColorsOrIcons[index];
let curRow = parseInt(index/9);
let curColumn = index%9;
let startRow = curRow;let endRow = curRow;let myColor = 0;let addMagicColor = gemColorsOrIcons==this.gemColors?9+1:9+1+100;
if (curColor < addMagicColor) { //非魔法宝石
if (curRow > 0) {
for (let i=curRow-1;i>=0;i--) {
myColor = gemColorsOrIcons[i*9+curColumn];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
startRow = i;
}
myColor = 0;
}
if (curRow+1 < 9) {
for (let i=curRow+1;i<9;i++) {
myColor = gemColorsOrIcons[i*9+curColumn];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
endRow = i;
}
myColor = 0;
}
if (endRow-startRow+1 >= this.playingSets[0]) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=startRow;i<=endRow;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+curColumn);
this.randomIndexs.push(i*9+curColumn);
}
allClearNumber += endRow-startRow;
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
let readyColumn = curColumn;let endColumn = curColumn;
if (curColumn > 0) {
for (let i=curColumn-1;i>=0;i--) {
myColor = gemColorsOrIcons[9*curRow+i];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
readyColumn = i;
}
myColor = 0;
}
if (curColumn+1 < 9) {
for (let i=curColumn+1;i<9;i++) {
myColor = gemColorsOrIcons[9*curRow+i];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
endColumn = i;
}
myColor = 0;
}
if (endColumn-readyColumn+1 >= this.playingSets[0]) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=readyColumn;i<=endColumn;i++) {
if (i == curColumn) continue;
this.clearIndexs.push(9*curRow+i);
this.randomIndexs.push(9*curRow+i);
}
allClearNumber += endColumn-readyColumn;
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
startRow = curRow;endRow = curRow;
readyColumn = curColumn;endColumn = curColumn;
if (curRow > 0 && curColumn > 0) {
if (curRow < curColumn) {
for (let i=curRow-1;i>=0;i--) {
myColor = gemColorsOrIcons[i*9+curColumn-(curRow-i)];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
startRow = i;readyColumn = curColumn-(curRow-i);
}
myColor = 0;
} else {
for (let i=curColumn-1;i>=0;i--) {
myColor = gemColorsOrIcons[(curRow-(curColumn-i))*9+i];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
startRow = curRow-(curColumn-i);readyColumn = i;
}
}
myColor = 0;
}
if (curRow+1 < 9 && curColumn+1 < 9) {
if (curRow > curColumn) {
for (let i=curRow+1;i<9;i++) {
myColor = gemColorsOrIcons[i*9+curColumn+(i-curRow)];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
endRow = i;endColumn = curColumn+(i-curRow);
}
myColor = 0;
} else {
for (let i=curColumn+1;i<9;i++) {
myColor = gemColorsOrIcons[(curRow+(i-curColumn))*9+i];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
endRow = curRow+(i-curColumn);endColumn = i;
}
myColor = 0;
}
}
if (endRow-startRow+1 >= this.playingSets[0]) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=startRow;i<=endRow;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+readyColumn+(i-startRow));
this.randomIndexs.push(i*9+readyColumn+(i-startRow));
}
allClearNumber += endRow-startRow;
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
startRow = curRow;endRow = curRow;
readyColumn = curColumn;endColumn = curColumn;
if (curRow > 0 && curColumn+1 < 9) {
if (curRow < 9-curColumn-1) {
for (let i=curRow-1;i>=0;i--) {
myColor = gemColorsOrIcons[i*9+curColumn+(curRow-i)];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
startRow = i;readyColumn = curColumn+(curRow-i);
}
myColor = 0;
} else {
for (let i=curColumn+1;i<9;i++) {
myColor = gemColorsOrIcons[(curRow-(i-curColumn))*9+i];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
startRow = curRow-(i-curColumn);readyColumn = i;
}
myColor = 0;
}
}
if (curRow+1 < 9 && curColumn > 0) {
if (9-curRow-1 < curColumn) {
for (let i=curRow+1;i<9;i++) {
myColor = gemColorsOrIcons[i*9+curColumn-(i-curRow)];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
endRow = i;endColumn = curColumn-(i-curRow);
}
myColor = 0;
} else {
for (let i=curColumn-1;i>=0;i--) {
myColor = gemColorsOrIcons[(curRow-(i-curColumn))*9+i];
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
else if (myColor != curColor) break;
endRow = curRow-(i-curColumn);endColumn = i;
}
myColor = 0;
}
}
if (endRow-startRow+1 >= this.playingSets[0]) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=startRow;i<=endRow;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+readyColumn-(i-startRow));
this.randomIndexs.push(i*9+readyColumn-(i-startRow));
}
allClearNumber += endRow-startRow;
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
} else { //魔法宝石
if (curColor == addMagicColor) addMagicNumber++;
else if (curColor == addMagicColor+1) subMagicNumber++;
let curIndex = curRow;let count = 1;myColor = 0;
while (curRow > 0) {
curIndex--;
if (curIndex == -1 || gemColorsOrIcons[curIndex*9+curColumn] == 0) break;
myColor = gemColorsOrIcons[curIndex*9+curColumn];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (upColor == 0) upColor = myColor;
else if (myColor != upColor) break;
startRow = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (upColor == 0) upMagicNumber++;
startRow = curIndex;
}
count++;if (count == this.playingSets[0]) break;
}
curIndex = curRow;count = 1;myColor = 0;
while (curRow+1 < 9) {
curIndex++;
if (curIndex == 9 || gemColorsOrIcons[curIndex*9+curColumn] == 0) break;
myColor = gemColorsOrIcons[curIndex*9+curColumn];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (downColor == 0) downColor = myColor;
else if (myColor != downColor) break;
endRow = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (downColor == 0) downMagicNumber++;
endRow = curIndex;
}
count++;if (count == this.playingSets[0]) break;
}
if (endRow-startRow+1 >= this.playingSets[0]) {
if (upColor == downColor) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=startRow;i<=endRow;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+curColumn);
this.randomIndexs.push(i*9+curColumn);
}
upClearNumber = endRow-startRow;
} else {
let isClear = false;
if (curRow+downMagicNumber-startRow+1 >= this.playingSets[0]) {
for (let i=startRow;i<curRow-upMagicNumber;i++) {
this.clearIndexs.push(i*9+curColumn);
this.randomIndexs.push(i*9+curColumn);
}
upClearNumber = curRow-upMagicNumber-startRow;
isClear = true;
} else upColor = 0;
if (endRow-(curRow-upMagicNumber)+1 >= this.playingSets[0]) {
for (let i=curRow+downMagicNumber+1;i<=endRow;i++) {
this.clearIndexs.push(i*9+curColumn);
this.randomIndexs.push(i*9+curColumn);
}
upClearNumber += endRow-downMagicNumber-curRow;
isClear = true;
} else downColor = 0;
if (isClear) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
if (upColor!=0 && downColor!=0) differentColorClear = true;
else upColor = upColor+downColor;
for (let i=curRow-upMagicNumber;i<=curRow+downMagicNumber;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+curColumn);
this.randomIndexs.push(i*9+curColumn);
}
upClearNumber += upMagicNumber+downMagicNumber;
}
}
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
let readyColumn = curColumn;let endColumn = curColumn;
curIndex = curColumn;count = 1;myColor = 0;
while (curColumn > 0) {
curIndex--;
if (curIndex == -1 || gemColorsOrIcons[9*curRow+curIndex] == 0) break;
myColor = gemColorsOrIcons[9*curRow+curIndex];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (leftColor == 0) leftColor = myColor;
else if (myColor != leftColor) break;
readyColumn = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (leftColor == 0) leftMagicNumber++;
readyColumn = curIndex;
}
count++;if (count == this.playingSets[0]) break;
}
curIndex = curColumn;count = 1;myColor = 0;
while (curColumn+1 < 9) {
curIndex++;
if (curIndex == 9 || gemColorsOrIcons[9*curRow+curIndex] == 0) break;
myColor = gemColorsOrIcons[9*curRow+curIndex];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (rightColor == 0) rightColor = myColor;
else if (myColor != rightColor) break;
endColumn = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (rightColor == 0) rightMagicNumber++;
endColumn = curIndex;
}
}
if (endColumn-readyColumn+1 >= this.playingSets[0]) {
if (leftColor == rightColor) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=readyColumn;i<=endColumn;i++) {
if (i == curColumn) continue;
this.clearIndexs.push(9*curRow+i);
this.randomIndexs.push(9*curRow+i);
}
leftClearNumber = endColumn-readyColumn;
} else {
let isClear = false;
if (curColumn+rightMagicNumber-readyColumn+1 >= this.playingSets[0]) {
for (let i=readyColumn;i<curColumn-leftMagicNumber;i++) {
this.clearIndexs.push(9*curRow+i);
this.randomIndexs.push(9*curRow+i);
}
leftClearNumber = curColumn-leftMagicNumber-readyColumn;
isClear = true;
} else leftColor = 0;
if (endColumn-(curColumn-leftMagicNumber)+1 >= this.playingSets[0]) {
for (let i=curColumn+rightMagicNumber+1;i<=endColumn;i++) {
this.clearIndexs.push(9*curRow+i);
this.randomIndexs.push(9*curRow+i);
}
leftClearNumber += endColumn-rightMagicNumber-curColumn;
isClear = true;
} else rightColor = 0;
if (isClear) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
if (leftColor!=0 && rightColor!=0) differentColorClear = true;
else leftColor = leftColor + rightColor;
for (let i=curColumn-leftMagicNumber;i<=curColumn+rightMagicNumber;i++) {
if (i == curColumn) continue;
this.clearIndexs.push(9*curRow+i);
this.randomIndexs.push(9*curRow+i);
}
leftClearNumber += leftMagicNumber+rightMagicNumber;
}
}
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
startRow = curRow;endRow = curRow;
readyColumn = curColumn;endColumn = curColumn;
if (curRow > 0 && curColumn > 0) {
curIndex = curRow;count = 1;myColor = 0;
while (curRow < curColumn) {
curIndex--;
if (curIndex == -1 || gemColorsOrIcons[curIndex*9+curColumn-(curRow-curIndex)] == 0) break;
myColor = gemColorsOrIcons[curIndex*9+curColumn-(curRow-curIndex)];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (upLeftColor == 0) upLeftColor = myColor;
else if (myColor != upLeftColor) break;
startRow = curIndex;readyColumn = curColumn-(curRow-curIndex);
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (upLeftColor == 0) upLeftMagicNumber++;
startRow = curIndex;readyColumn = curColumn-(curRow-curIndex);
}
count++;if (count == this.playingSets[0]) break;
}
curIndex = curColumn;count = 1;myColor = 0;
while (curRow >= curColumn) {
curIndex--;
if (curIndex == -1 || gemColorsOrIcons[(curRow-(curColumn-curIndex))*9+curIndex] == 0) break;
myColor = gemColorsOrIcons[(curRow-(curColumn-curIndex))*9+curIndex];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (upLeftColor == 0) upLeftColor = myColor;
else if (myColor != upLeftColor) break;
startRow = curRow-(curColumn-curIndex);readyColumn = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (upLeftColor == 0) upLeftMagicNumber++;
startRow = curRow-(curColumn-curIndex);readyColumn = curIndex;
}
count++;if (count == this.playingSets[0]) break;
}
}
if (curRow+1 < 9 && curColumn+1 < 9) {
curIndex = curRow;count = 1;myColor = 0;
while (curRow > curColumn) {
curIndex++;
if (curIndex == 9 || gemColorsOrIcons[curIndex*9+curColumn+(curIndex-curRow)] == 0) break;
myColor = gemColorsOrIcons[curIndex*9+curColumn+(curIndex-curRow)];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (downRightColor == 0) downRightColor = myColor;
else if (myColor != downRightColor) break;
endRow = curIndex;endColumn = curColumn+(curIndex-curRow);
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (downRightColor == 0) downRightMagicNumber++;
endRow = curIndex;endColumn = curColumn+(curIndex-curRow);
}
count++;if (count == this.playingSets[0]) break;
}
curIndex = curColumn;count = 1;myColor = 0;
while (curRow <= curColumn) {
curIndex++;
if (curIndex == 9 || gemColorsOrIcons[(curRow+(curIndex-curColumn))*9+curIndex] == 0) break;
myColor = gemColorsOrIcons[(curRow+(curIndex-curColumn))*9+curIndex];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (downRightColor == 0) downRightColor = myColor;
else if (myColor != downRightColor) break;
endRow = curRow+(curIndex-curColumn);endColumn = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (downRightColor == 0) downRightMagicNumber++;
endRow = curRow+(curIndex-curColumn);endColumn = curIndex;
}
count++;if (count == this.playingSets[0]) break;
}
}
if (endRow-startRow+1 >= this.playingSets[0]) {
if (upLeftColor == downRightColor) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=startRow;i<=endRow;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+readyColumn+(i-startRow));
this.randomIndexs.push(i*9+readyColumn+(i-startRow));
}
upLeftClearNumber += endRow-startRow;
} else {
let isClear = false;
if (curRow+downRightMagicNumber-startRow+1 >= this.playingSets[0]) {
for (let i=startRow;i<curRow-upLeftMagicNumber;i++) {
this.clearIndexs.push(i*9+readyColumn+(i-startRow));
this.randomIndexs.push(i*9+readyColumn+(i-startRow));
}
upLeftClearNumber = curRow-upLeftMagicNumber-startRow;
isClear = true;
} else upLeftColor = 0;
if (endRow-(curRow-upLeftMagicNumber)+1 >= this.playingSets[0]) {
for (let i=curRow+downRightMagicNumber+1;i<=endRow;i++) {
this.clearIndexs.push(i*9+readyColumn+(i-startRow));
this.randomIndexs.push(i*9+readyColumn+(i-startRow));
}
upLeftClearNumber += endRow-downRightMagicNumber-curRow;
isClear = true;
} else downRightColor = 0;
if (isClear) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
if (upLeftColor!=0 && downRightColor!=0) differentColorClear = true;
else upLeftColor = upLeftColor + downRightColor;
for (let i=curRow-upLeftMagicNumber;i<=curRow+downRightMagicNumber;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+readyColumn+(i-startRow));
this.randomIndexs.push(i*9+readyColumn+(i-startRow));
}
upLeftClearNumber += upLeftMagicNumber+downRightMagicNumber;
}
}
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
startRow = curRow;endRow = curRow;
readyColumn = curColumn;endColumn = curColumn;
if (curRow > 0 && curColumn+1 < 9) {
curIndex = curRow;count = 1;myColor = 0;
while (curRow < 9-curColumn-1) {
curIndex--;
if (curIndex == -1 || gemColorsOrIcons[curIndex*9+curColumn+(curRow-curIndex)] == 0) break;
myColor = gemColorsOrIcons[curIndex*9+curColumn+(curRow-curIndex)];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (upRightColor == 0) upRightColor = myColor;
else if (myColor != upRightColor) break;
startRow = curIndex;readyColumn = curColumn+(curRow-curIndex);
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (upRightColor == 0) upRightMagicNumber++;
startRow = curIndex;readyColumn = curColumn+(curRow-curIndex);
}
count++;if (count == this.playingSets[0]) break;
}
curIndex = curColumn;count = 1;myColor = 0;
while (curRow >= 9-curColumn-1) {
curIndex++;
if (curIndex == 9 || gemColorsOrIcons[(curRow-(curIndex-curColumn))*9+curIndex] == 0) break;
myColor = gemColorsOrIcons[(curRow-(curIndex-curColumn))*9+curIndex];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (upRightColor == 0) upRightColor = myColor;
else if (myColor != upRightColor) break;
startRow = curRow-(curIndex-curColumn);readyColumn = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (upRightColor == 0) upRightMagicNumber++;
startRow = curRow-(curIndex-curColumn);readyColumn = curIndex;
}
count++;if (count == this.playingSets[0]) break;
}
}
if (curRow+1 < 9 && curColumn > 0) {
curIndex = curRow;count = 1;myColor = 0;
while (9-curRow-1 < curColumn) {
curIndex++;
if (curIndex == 9 || gemColorsOrIcons[curIndex*9+curColumn-(curIndex-curRow)] == 0) break;
myColor = gemColorsOrIcons[curIndex*9+curColumn-(curIndex-curRow)];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (downLeftColor == 0) downLeftColor = myColor;
else if (myColor != downLeftColor) break;
endRow = curIndex;endColumn = curColumn-(curIndex-curRow);
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (downLeftColor == 0) downLeftMagicNumber++;
endRow = curIndex;endColumn = curColumn-(curIndex-curRow);
}
count++;if (count == this.playingSets[0]) break;
}
curIndex = curColumn;count = 1;myColor = 0;
while (9-curRow-1 >= curColumn) {
curIndex--;
if (curIndex == -1 || gemColorsOrIcons[(curRow-(curIndex-curColumn))*9+curIndex] == 0) break;
myColor = gemColorsOrIcons[(curRow-(curIndex-curColumn))*9+curIndex];
if (myColor < addMagicColor) { //如果不是魔法宝石
if (downLeftColor == 0) downLeftColor = myColor;
else if (myColor != downLeftColor) break;
endRow = curRow-(curIndex-curColumn);endColumn = curIndex;
} else {
if (myColor == addMagicColor) addMagicNumber_++;
else if (myColor == addMagicColor+1) subMagicNumber_++;
if (downLeftColor == 0) downLeftMagicNumber++;
endRow = curRow-(curIndex-curColumn);endColumn = curIndex;
}
count++;if (count == this.playingSets[0]) break;
}
}
if (endRow-startRow+1 >= this.playingSets[0]) {
if (upRightColor == downLeftColor) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
for (let i=startRow;i<=endRow;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+readyColumn-(i-startRow));
this.randomIndexs.push(i*9+readyColumn-(i-startRow));
}
upRightClearNumber += endRow-startRow;
} else {
let isClear = false;
if (curRow+downLeftMagicNumber-startRow+1 >= this.playingSets[0]) {
for (let i=startRow;i<curRow-upRightMagicNumber;i++) {
this.clearIndexs.push(i*9+readyColumn-(i-startRow));
this.randomIndexs.push(i*9+readyColumn-(i-startRow));
}
upRightClearNumber = curRow-upRightMagicNumber-startRow;
isClear = true;
} else upRightColor = 0;
if (endRow-(curRow-upRightMagicNumber)+1 >= this.playingSets[0]) {
for (let i=curRow+downLeftMagicNumber+1;i<=endRow;i++) {
this.clearIndexs.push(i*9+readyColumn-(i-startRow));
this.randomIndexs.push(i*9+readyColumn-(i-startRow));
}
upRightClearNumber += endRow-downLeftMagicNumber-curRow;
isClear = true;
} else downLeftColor = 0;
if (isClear) {
addMagicNumber += addMagicNumber_;subMagicNumber += subMagicNumber_;
if (upRightColor!=0 && downLeftColor!=0) differentColorClear = true;
else upRightColor = upRightColor + downLeftColor;
for (let i=curRow-upRightMagicNumber;i<=curRow+downLeftMagicNumber;i++) {
if (i == curRow) continue;
this.clearIndexs.push(i*9+readyColumn-(i-startRow));
this.randomIndexs.push(i*9+readyColumn-(i-startRow));
}
upRightClearNumber += upRightMagicNumber+downLeftMagicNumber;
}
}
}
addMagicNumber_ = 0;subMagicNumber_ = 0;
allClearNumber = 1+upClearNumber+leftClearNumber+upLeftClearNumber+upRightClearNumber;
}
if (this.clearIndexs.length == 0) {
if (gemColorsOrIcons == this.gemIcons) this.scorePower = 1;
this.clearIndexs = null;return 0;
}
if (allClearNumber == 1) return 0;
this.clearIndexs.push(9*curRow+curColumn);
this.randomIndexs.push(9*curRow+curColumn);
let myScore = Math.ceil(this.playingSets[0]+(allClearNumber-this.playingSets[0])*this.playingSets[0]*0.5);
if (curColor >= addMagicColor) {
if (allClearNumber == (1+upMagicNumber+downMagicNumber+leftMagicNumber+rightMagicNumber+upLeftMagicNumber+downRightMagicNumber+upRightMagicNumber+downLeftMagicNumber)) myScore = myScore*2; //全是魔法宝石,得分*2
else if (differentColorClear) myScore = myScore*2; //异色消除,得分*2
else if (upClearNumber!=0) {
if (leftClearNumber!=0 && upColor!=leftColor) myScore = myScore*2; //异色消除,得分*2
if (upLeftClearNumber!=0 && upColor!=upLeftColor) myScore = myScore*2; //异色消除,得分*2
if (upRightClearNumber!=0 && upColor!=upRightColor) myScore = myScore*2; //异色消除,得分*2
} else if (leftClearNumber!=0) {
if (upLeftClearNumber!=0 && leftColor!=upLeftColor) myScore = myScore*2; //异色消除,得分*2
if (upRightClearNumber!=0 && leftColor!=upRightColor) myScore = myScore*2; //异色消除,得分*2
} else if (upLeftClearNumber!=0 &&upLeftColor!=upRightColor) myScore = myScore*2; //异色消除,得分*2
}
myScore = myScore*this.scorePower;
this.scorePower = 2*this.scorePower; //多次连续消除会使得分一直翻倍
if (addMagicNumber > subMagicNumber) this.scoreModel = 1;
else if (addMagicNumber < subMagicNumber) this.scoreModel = -1;
return myScore*this.scoreModel;
}
通过clearGemsAndGetScore方法,会自动生成可消除的clearIndexs,这些即将消除掉的宝石位置会加到随机位置生成列表randomIndexs,用于将来随机放置位置的生成。在返回得分的时候,会根据某些设定出现得分翻倍的情况,比如魔法宝石同时消除2种以上颜色、多次连续消除、一出便消等,增加游戏的娱乐性和竞技性。
四、互动音效
互动音效包括选中音效、移动音效、无法移动音效、消除音效、游戏结束音效等,bengbeng.mp3、boob.mp3、dadoo.mp3、kin.mp3、money.mp3、opendoor.mp3、wuen.mp3、wuwu.mp3等音效文件可自定义,一般选择1秒左右短时音效。
let instance;
const bgm1 = &#34;audio/bgm1.mp3&#34;;
const bgm2 = &#34;audio/bgm2.mp3&#34;;
const boom = &#34;audio/boom.mp3&#34;;
const bullet = &#34;audio/bullet.mp3&#34;;
const bengbeng =&#34;audio/bengbeng.mp3&#34;;
const boob = &#34;audio/boob.mp3&#34;;
const dadoo = &#34;audio/dadoo.mp3&#34;;
const kin = &#34;audio/kin.mp3&#34;;
const money = &#34;audio/money.mp3&#34;;
const opendoor = &#34;audio/opendoor.mp3&#34;;
const wuen = &#34;audio/wuen.mp3&#34;;
const wuwu = &#34;audio/wuwu.mp3&#34;;
/**
* 统一的音乐音效管理器
*/
export default class MyMusic {
constructor() {
if (instance) return instance;
instance = this;
this.bgm = wx.createInnerAudioContext();
this.bgm.loop = true;
this.soundEffect = wx.createInnerAudioContext();
}
setBgm(index) {
this.bgm.stop();
let tempIndex = 0;
if (index == 2) {
tempIndex = parseInt(Math.random()*2);
} else tempIndex = index;
if (tempIndex == 0) {
this.bgm.src = bgm1;
} else {
this.bgm.src = bgm2;
}
}
playBgm() {
this.bgm.play();
}
stopBgm() {
this.bgm.stop();
}
setBgmVolume(volume) {
if (volume > 1) volume = volume/200; //背景音乐音量调低
this.bgm.volume = volume;
}
playPressButtonC() {
this.soundEffect.src = opendoor;
this.soundEffect.play();
}
playPressButtonU() {
this.soundEffect.src = kin;
this.soundEffect.play();
}
setSoundEffectVolume(volume) {
if (volume > 1) volume = volume/100;
this.soundEffect.volume = volume;
}
playSelectGem() {
this.soundEffect.src = boob;
this.soundEffect.play();
}
playCannotMoveGem() {
this.soundEffect.src = dadoo;
this.soundEffect.play();
}
playMoveGem() {
this.soundEffect.src = bengbeng;
this.soundEffect.play();
}
playClearGem() {
this.soundEffect.src = bullet;
this.soundEffect.play();
}
playGameOver() {
this.soundEffect.src = money;
this.soundEffect.play();
}
}
现在可以移动宝石、消除宝石、刷新得分了。 |
|