|
本节对游戏游玩界面进行开发,主要涉及宝石生成、宝石选中、宝石移动、宝石消除、得分计算 、得分展示、游玩音效等内容。
一、游玩前的数据初始化(MyData.js)
gamePlayingInit() {
this.beginTime = new Date().getTime(); //游戏开始时间
this.deltaTime = 0; //游戏跳过时间(用于载入)
this.pauseTime = 0; //游戏暂停时间(用于保存等时机暂停游戏)
this.gameOver = 0; //游戏结束:1无路可走 2游戏时间到 3主动放弃
this.scorePower = 1; //多次连续消除会使得分一直翻倍
this.scoreModel = 1; //当得分模式为-1时会变成扣分
this.scoreAdd = 0; //需要增加的得分
this.playingSets = new Array();
if (this.gameModel == 1) {
for (let i=0;i<this.model1PlaySets.length;i++) {
this.playingSets = PLAY_SET_SELECTS[this.model1PlaySets];
}
}
this.gemColors = DEFAULT_GEM_COLORS.slice(); //宝石颜色列表
this.gemIcons = DEFAULT_GEM_ICONS.slice(); //宝石图案列表
this.curSelectedIndex = -1; //当前选中的宝石
this.pathIndexs = new Array(); //宝石移动的路径列表
this.clearIndexs = new Array(); //需要消除的宝石列表
this.magicGemPercent = this.playingSets[3]/(this.playingSets[1]+this.playingSets[3])*this.playingSets[11]; //魔法宝石生成百分比
this.newGemColors = new Array(); //新宝石颜色列表
this.newGemIcons = new Array(); //新宝石图案列表
this.generateNewGems(5); //随机生成5个宝石
this.randomIndexs = DEFAULT_ALL_INDEXS.slice(); //宝石生成的随机位置列表
this.newGemIndexs = new Array(); //随机生成位置列表
this.putGenerateGems(5); //将生成的宝石置于方格位置内
this.generateNewGems(); //随机生成新的宝石(提示栏的预告宝石)
this.propIcons = new Array();
this.generateNewProps(); //随机生成新的道具(提示栏的可用道具)
}
generateNewGems(number) {
if (number == null) number = this.playingSets[10];
for (let i=0;i<number;i++) {
let random1 = Math.random();let random2 = Math.random();
let randomColor = random1 < this.magicGemPercent?9+parseInt(this.playingSets[3]*random2):parseInt(this.playingSets[1]*random2);
this.newGemColors = DEFAULT_ALL_COLORS[randomColor];
if (this.playingSets[2] == 0) {
this.newGemIcons = DEFAULT_ALL_ICONS[randomColor];
} else {
let random3 = Math.random();
let randomIcon = parseInt(this.playingSets[2]*random3);
this.newGemIcons = DEFAULT_ALL_ICONS[randomIcon];
}
}
}
putGenerateGems(number) {
if (number == null) number = this.playingSets[10];
if (this.randomIndexs.length < number) {this.gameOver = 1;return 0;}
for (let i=0;i<number;i++) {
let random = parseInt(this.randomIndexs.length*Math.random());
this.gemColors[this.randomIndexs[random]] = this.newGemColors;
this.gemIcons[this.randomIndexs[random]] = this.newGemIcons;
this.randomIndexs.splice(random,1);
}
}
generateNewProps(number) {
if (number == null) number = this.playingSets[6];
for (let i=0;i<number;i++) {
let random = parseInt(number*Math.random());
this.propIcons = DEFAULT_ALL_PROPS[random];
}
}
二、游玩前的渲染初始化(MyRender.js)
(一)渲染时的信息
//渲染时的信息
let background = null;let buttonUpWidth = 48;
let fontSize = 14;let text = &#34;&#34;;let texts = new Array();
let splitWidth = 64;let splitHeight = 64;
let renderGemColors = null;
let renderGemIcons = null;
let renderPropIcons = null;
let clearHideShowTimes = 8; //清除时隐显次数
let curClearHideShowTimes = 0; //myData.frame%6
let oldGemPutIndex = -1; //依次放置,间隔myData.frame%7
let scoreAddShowTime = 50; //绘制得分所需帧数
let curAddScoreShowTime = 0;
let curAddScore = 0;
(二)宝石和道具渲染
主要包括宝石颜色渲染、宝石图标渲染、道具图标渲染,该初始化操作在MyRender的构造函数的doMainSets里面进行,当操作者更改了mainSets,这时也会同步更新渲染结果。
doMainSets(index) {
if (index == null) {
this.setBackground();
myMusic.setBgm(myData.mainSets[1]);
this.setRenderGemColors();
this.setRenderGemIcons();
myMusic.setBgmVolume(myData.MAIN_SET_SELECTS()[6][myData.mainSets[6]]);
myMusic.setSoundEffectVolume(myData.MAIN_SET_SELECTS()[7][myData.mainSets[7]]);
} else if (index == 0) {
this.setBackground();
} else if (index == 1) {
myMusic.setBgm(myData.mainSets[1]);
} else if (index == 2) {
this.setRenderGemColors();
} else if (index == 3) {
this.setRenderGemIcons();
} else if (index == 4) {
this.setRenderGemColors();
} else if (index == 5) {
this.setRenderGemIcons();
} else if (index == 6) {
myMusic.setBgmVolume(myData.MAIN_SET_SELECTS()[myData.mainSets]);
} else if (index == 7) {
myMusic.setSoundEffectVolume(myData.MAIN_SET_SELECTS()[myData.mainSets]);
}
}
setBackground() {
background = myData.mainSets[0]==0?background1:background2;
}
setRenderGemColors() {
renderGemColors = new Array();
renderGemColors.push(0); //0表示渲染空白图像
let tempSet = 0;let tempSets;let tempMagicGemSets;
if (myData.mainSets[2] == 3) {
tempSet = parseInt(Math.random()*3);
} else tempSet = myData.mainSets[2];
if (tempSet == 0) {
tempSets = [1,2,3,4,5,6,7,8,9];
tempMagicGemSets = [10,11,12];
} else if (tempSet == 1) {
tempSets = [13,14,15,16,17,18,19,20,21];
tempMagicGemSets = [22,23,24];
} else {
tempSets = [25,26,27,28,29,30,31,32,33];
tempMagicGemSets = [34,35,36];
}
if (myData.mainSets[4] == 2) { //随机排序
for (let i=0;i<9;i++) {
let tempRandom = parseInt(Math.random()*tempSets.length);
renderGemColors.push(tempSets[tempRandom]);
tempSets.splice(tempRandom,1);
}
renderGemColors.push(tempMagicGemSets[0]);
renderGemColors.push(tempMagicGemSets[1]);
renderGemColors.push(tempMagicGemSets[2]);
} else if (myData.mainSets[4] == 1) { //倒序
for (let i=0;i<9;i++) {
renderGemColors.push(tempSets[8-i]);
}
renderGemColors.push(tempMagicGemSets[0]);
renderGemColors.push(tempMagicGemSets[1]);
renderGemColors.push(tempMagicGemSets[2]);
} else { //顺序
for (let i=0;i<9;i++) {
renderGemColors.push(tempSets);
}
renderGemColors.push(tempMagicGemSets[0]);
renderGemColors.push(tempMagicGemSets[1]);
renderGemColors.push(tempMagicGemSets[2]);
}
}
setRenderGemIcons() {
renderGemIcons = new Array();
renderGemIcons.push(0); //0表示渲染空白图像
let tempSet = 0;let tempSets;
if (myData.mainSets[3] == 3) {
tempSet = parseInt(Math.random()*3);
} else tempSet = myData.mainSets[3];
if (tempSet == 0) {
tempSets = [1,2,3,4,5,6,7,8,9,10,11,12];
} else if (tempSet == 1) {
tempSets = [13,14,15,16,17,18,19,20,21,22,23,24];
} else if (tempSet == 2) {
tempSets = [25,26,27,28,29,30,31,32,33,34,35,36];
} else {
tempSets = [37,38,39,40,41,42,43,44,45,46,47,48];
}
if (myData.mainSets[5] == 2) { //随机排序
for (let i=0;i<12;i++) {
let tempRandom = parseInt(Math.random()*tempSets.length);
renderGemIcons.push(tempSets[tempRandom]);
tempSets.splice(tempRandom,1);
}
} else if (myData.mainSets[5] == 1) { //倒序
for (let i=0;i<12;i++) {
renderGemIcons.push(tempSets[11-i]);
}
} else { //顺序
for (let i=0;i<12;i++) {
renderGemIcons.push(tempSets);
}
}
}
setRenderPropIcons() {
renderPropIcons = new Array();
renderPropIcons.push(0); //0表示渲染空白图像
let tempSets = [1,2,3,4,5];
for (let i=0;i<5;i++) {
renderPropIcons.push(tempSets);
}
}
三、游玩界面渲染
中间部分主要包括提示栏、黑白方格,有时也需要渲染得分提示。
renderGamePlaying(gameStatus) {
ctx.globalAlpha = &#34;1&#34;;
//绘制左上角按钮
this.btnAreaStartUpX1 = widthL;
this.btnAreaEndUpX1 = this.btnAreaStartUpX1+buttonUpWidth;
this.btnAreaStartUpX2 = this.btnAreaEndUpX1+2;
this.btnAreaEndUpX2 = this.btnAreaStartUpX2+buttonUpWidth;
this.btnAreaStartUpY = widthL;
this.btnAreaEndUpY = this.btnAreaStartUpY+buttonUpWidth;
splitWidth = 64;splitHeight = 64;
ctx.drawImage(buttonUs,2*splitWidth,0*splitHeight,splitWidth,splitHeight,this.btnAreaStartUpX1,this.btnAreaStartUpY,buttonUpWidth,buttonUpWidth);
ctx.drawImage(buttonUs,3*splitWidth,0*splitHeight,splitWidth,splitHeight,this.btnAreaStartUpX2,this.btnAreaStartUpY,buttonUpWidth,buttonUpWidth);
//绘制得分
fontSize = parseInt(blockWidth*0.9);ctx.fillStyle = myData.mainSets[0]==0?&#39;#000&#39;:&#39;#fff&#39;;ctx.font = fontSize+&#39;px&#39;+fontFamily;
text = myData.score+&#34;&#34;;
ctx.fillText(text,screenWidth/2-ctx.measureText(text).width/2,heightU);
//绘制提示栏
ctx.drawImage(backgroundCU,widthL,heightU+heightCUU,widthCUC,heightCUC);
let gemsWidth = 128;let gemsHeight = 128;
let iconsWidth = 64;let iconsHeight = 64;
for (let i=0;i<myData.playingSets[4];i++) {
ctx.drawImage(gems,((renderGemColors[myData.newGemColors]-1)%6)*gemsWidth,parseInt((renderGemColors[myData.newGemColors]-1)/6)*gemsHeight,gemsWidth,gemsHeight,widthL+blockWidth*i,heightU+heightCUU,blockWidth,blockWidth);
ctx.drawImage(icons,((renderGemIcons[myData.newGemIcons]-1)%6)*iconsWidth,parseInt((renderGemIcons[myData.newGemIcons]-1)/6)*iconsHeight,iconsWidth,iconsHeight,widthL+blockWidth*i,heightU+heightCUU,blockWidth,blockWidth);
}
fontSize = parseInt(blockWidth*0.8);ctx.fillStyle = &#39;#fff&#39;;ctx.font = fontSize+&#39;px&#39;+fontFamily;
let curTime = &#34;∞&#34;;
if (myData.playingSets[5] > 0) {
if (gameStatus == &#34;pause&#34;) myData.pauseTime = new Date().getTime()-myData.pauseBeginTime;
else if (myData.pauseTime != 0) {
myData.beginTime += myData.pauseTime;myData.pauseTime = 0;
} else myData.deltaTime = new Date().getTime()-myData.beginTime+myData.deltaTime;
let myTime = myData.playingSets[5] - parseInt(myData.deltaTime/1000);
if (myTime <= 0) {
myData.gameOver = true;
myData.endTime = new Date().getTime();
return;
}
let curTime1 = parseInt(myTime/60);let curTime2 = myTime%60;
if (curTime1<10) curTime1 = &#34;0&#34;+curTime1;if (curTime2<10) curTime2 = &#34;0&#34;+curTime2;
curTime = curTime1+&#34;:&#34;+curTime2;
}
ctx.fillText(curTime,screenWidth/2-ctx.measureText(curTime).width/2,heightU+heightCUU+heightCUC/2);
splitWidth = 128;splitHeight = 128;
for (let i=0;i<myData.playingSets[6];i++) {
let w = myData.propIcons%6;let h = (myData.propIcons-w)/6%1;
ctx.drawImage(props,w*splitWidth,h*splitHeight,splitWidth,splitHeight,widthL+blockWidth*(6+i),heightU+heightCUU,blockWidth,blockWidth);
}
//绘制中间格子和宝石
ctx.drawImage(backgroundC2,widthL,heightU+heightCU,widthCC,heightCC);
if (myData.frame%3 == 0) {
if (myData.pathIndexs.length > 2) {
myData.gemColors[myData.pathIndexs[myData.pathIndexs.length-2]] = myData.gemColors[myData.pathIndexs[myData.pathIndexs.length-1]];
myData.gemColors[myData.pathIndexs[myData.pathIndexs.length-1]] = 0;
myData.pathIndexs.splice(myData.pathIndexs.length-1,1);
} else if (myData.pathIndexs.length == 2) {
myMusic.playMoveGem();
myData.gemColors[myData.pathIndexs[0]] = myData.gemColors[myData.pathIndexs[1]];
myData.gemColors[myData.pathIndexs[1]] = 0;
myData.scoreAdd = myData.clearGemsAndSetScore(myData.pathIndexs[0]);
if (myData.scoreAdd == 0) {
myData.putGenerateGems();
oldGemPutIndex = myData.oldGemNextIndexs.length==0?-1:myData.oldGemNextIndexs.length;
} else {
curClearHideShowTimes = clearHideShowTimes;
}
myData.pathIndexs = new Array();
}
}
if (curClearHideShowTimes != 0) {
if (myData.frame%6 == 0) {
for (let i=0;i<myData.allClearIndexs.length;i++) {
myData.gemColors[myData.allClearIndexs] *= -1;
}
curClearHideShowTimes--;
if (curClearHideShowTimes == 0) {
for (let i=0;i<myData.allClearIndexs.length;i++) {
myData.gemColors[myData.allClearIndexs] = 0;
}
myMusic.playClearGem();
myData.allClearIndexs = new Array();
myData.score += myData.scoreAdd;
curAddScoreShowTime = scoreAddShowTime;
curAddScore = myData.scoreAdd;
myData.scoreAdd = 0;
}
}
} else if (myData.frame%7 == 0 && oldGemPutIndex != -1) {
myData.gemColors[myData.oldGemNextIndexs[oldGemPutIndex]] = myData.newGemColors[oldGemPutIndex];
myData.scoreAdd = myData.clearGemsAndSetScore(myData.oldGemNextIndexs[oldGemPutIndex])*2; //一出便消得分*2
if (myData.scoreAdd != 0) curClearHideShowTimes = clearHideShowTimes;
oldGemPutIndex--;
if (oldGemPutIndex == -1) {
myData.oldGemNextIndexs = new Array();
myData.newGemColors = new Array();
myData.generateNewGems();
}
}
this.btnAreaStartCenterX = widthL;
this.btnAreaEndCenterX = this.btnAreaStartCenterX+widthCC;
this.btnAreaStartCenterY = heightU+heightCU;
this.btnAreaEndCenterY = this.btnAreaStartCenterY+heightCC;
for (let i=0;i<9;i++) {
for (let j=0;j<9;j++) {
if (myData.curSelectedIndex == i*9+j && myData.frame%20 > 10) {
ctx.drawImage(gems,((renderGemColors[myData.gemColors[i*9+j]<0?0:myData.gemColors[i*9+j]]-1)%6)*gemsWidth,parseInt((renderGemColors[myData.gemColors[i*9+j]<0?0:myData.gemColors[i*9+j]]-1)/6)*gemsHeight,gemsWidth,gemsHeight,this.btnAreaStartCenterX+blockWidth*j,this.btnAreaStartCenterY+blockWidth*i-3,blockWidth,blockWidth);
ctx.drawImage(icons,((renderGemIcons[myData.gemIcons[i*9+j]<0?0:myData.gemIcons[i*9+j]]-1)%6)*iconsWidth,parseInt((renderGemIcons[myData.gemIcons[i*9+j]<0?0:myData.gemIcons[i*9+j]]-1)/6)*iconsHeight,iconsWidth,iconsHeight,this.btnAreaStartCenterX+blockWidth*j,this.btnAreaStartCenterY+blockWidth*i-3,blockWidth,blockWidth);
} else {
ctx.drawImage(gems,((renderGemColors[myData.gemColors[i*9+j]<0?0:myData.gemColors[i*9+j]]-1)%6)*gemsWidth,parseInt((renderGemColors[myData.gemColors[i*9+j]<0?0:myData.gemColors[i*9+j]]-1)/6)*gemsHeight,gemsWidth,gemsHeight,this.btnAreaStartCenterX+blockWidth*j,this.btnAreaStartCenterY+blockWidth*i,blockWidth,blockWidth);
ctx.drawImage(icons,((renderGemIcons[myData.gemIcons[i*9+j]<0?0:myData.gemIcons[i*9+j]]-1)%6)*iconsWidth,parseInt((renderGemIcons[myData.gemIcons[i*9+j]<0?0:myData.gemIcons[i*9+j]]-1)/6)*iconsHeight,iconsWidth,iconsHeight,this.btnAreaStartCenterX+blockWidth*j,this.btnAreaStartCenterY+blockWidth*i,blockWidth,blockWidth);
}
}
}
//绘制得分提示
if (curAddScoreShowTime != 0) {
ctx.globalAlpha = &#34;0.2&#34;;
let tempWidth = 40*4;let tempHeight = 30*4;
let scoreIndex = parseInt(Math.abs(curAddScore)/myData.playingSets[0]);
splitWidth = 256;splitHeight = 192;
let w = scoreIndex%3;let h = (scoreIndex-w)/3%2;
ctx.drawImage(scores,w*splitWidth,h*splitHeight,splitWidth,splitHeight,screenWidth/2-tempWidth/2,screenHeight/2-tempHeight/2,tempWidth,tempHeight);
ctx.globalAlpha = &#34;1&#34;;
let numberWidth = 512/4;let numberHeight = 576/3;
tempWidth = 40;tempHeight = 60;
let curAddScoreText = Math.abs(curAddScore)+&#34;&#34;;
let readyWidth = screenWidth/2-(curAddScoreText.length+1)/2*tempWidth;
let temp = curAddScore>0?10:11;
ctx.drawImage(numbers,(temp%4)*numberWidth,parseInt(temp/4)*numberHeight,numberWidth,numberHeight,readyWidth,screenHeight/2-tempHeight/2,tempWidth,tempHeight);
for (let i=0;i<curAddScoreText.length;i++) {
let temp = curAddScoreText.substring(i,i+1);
ctx.drawImage(numbers,(temp%4)*numberWidth,parseInt(temp/4)*numberHeight,numberWidth,numberHeight,readyWidth+(i+1)*tempWidth,screenHeight/2-tempHeight/2,tempWidth,tempHeight);
}
curAddScoreShowTime--;
}
//绘制下方的功能按钮
let deltaButton = (widthCDC - heightCDC*4)/3;
let widthButton = heightCDC;
if (deltaButton <= 0) {
deltaButton = 8;widthButton = (widthCDC - deltaButton*3)/4;
}
this.btnAreaStartDownX1 = widthL;
this.btnAreaEndDownX1 = this.btnAreaStartDownX1+widthButton;
this.btnAreaStartDownX2 = this.btnAreaEndDownX1+deltaButton;
this.btnAreaEndDownX2 = this.btnAreaStartDownX2+widthButton;
this.btnAreaStartDownX3 = this.btnAreaEndDownX2+deltaButton;
this.btnAreaEndDownX3 = this.btnAreaStartDownX3+widthButton;
this.btnAreaStartDownX4 = this.btnAreaEndDownX3+deltaButton;
this.btnAreaEndDownX4 = this.btnAreaStartDownX4+widthButton;
this.btnAreaStartDownY = heightU+heightCU+heightCC+heightCDU;
this.btnAreaEndDownY = this.btnAreaStartDownY+widthButton;
let buttonDownIndexs = new Array();
if (myData.gameModel == 1) {
if (myData.userInfo == null) {
buttonDownIndexs = [11,0,0,0];
this.btnAreaEndDownX2 = this.btnAreareadyDownX2;
this.btnAreaEndDownX3 = this.btnAreareadyDownX3;
this.btnAreaEndDownX4 = this.btnAreareadyDownX4;
} else {
buttonDownIndexs = [11,2,0,0];
this.btnAreaEndDownX3 = this.btnAreareadyDownX3;
this.btnAreaEndDownX4 = this.btnAreareadyDownX4;
}
}
splitWidth = 128;splitHeight = 128;
for (let i=0;i<buttonDownIndexs.length;i++) {
let w = (buttonDownIndexs-1)%6;let h = (buttonDownIndexs-1-w)/6;
ctx.drawImage(buttonDs,w*splitWidth,h*splitHeight,splitWidth,splitHeight,widthL+widthButton*i+deltaButton*i,this.btnAreaStartDownY,widthButton,widthButton);
}
}
四、移动、消除与得分 |
|