我正在製作一個簡單的記憶遊戲,並且在將兩張牌面朝上並在他們檢查比賽之前,我已經放了一個短暫的延遲。如果他們無法匹敵,他們會將臉朝下翻轉。我遇到的問題是延遲發生在第二張牌面朝上之前,即使它後來在代碼中出現,導致第二張牌不能正面顯示。我使用帶有預加載圖像的drawImage函數,因此調用不需要等待圖像加載。我已經在下面添加了我的代碼,並在繪製平面和延遲函數之後發表評論。如何在HTML5 canvas遊戲中的drawImage函數後正確引入延遲?
的在線版本:http://dtc-wsuv.org/mscoggins/hiragana/seindex.html
var ROWS = 2;
var COLS = 3;
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.width = COLS * 80 + (COLS - 1) * 10 + 40;
canvas.height = ROWS * 100 + (ROWS - 1) * 10 + 40;
var Card = function(x, y, img) {
this.x = x;
this.y = y;
this.w = 80;
this.h = 100;
this.r = 10;
this.img = img;
this.match = false;
};
Card.prototype.drawFaceDown = function() {
this.drawCardBG();
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(this.w/2 + this.x, this.h/2 + this.y, 15, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
this.isFaceUp = false;
};
Card.prototype.drawFaceUp = function() {
this.drawCardBG();
var imgW = 57;
var imgH = 70;
var imgX = this.x + (this.w - imgW)/2;
var imgY = this.y + (this.h - imgH)/2;
ctx.drawImage(this.img, imgX, imgY, imgW, imgH);
this.isFaceUp = true;
};
Card.prototype.drawCardBG = function() {
ctx.beginPath();
ctx.fillStyle = "white";
ctx.fillRect(this.x, this.y, this.w, this.h);
ctx.closePath();
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
ctx.moveTo(this.x + this.r, this.y);
ctx.lineTo(this.w + this.x - this.r * 2, this.y);
ctx.arcTo(this.w + this.x, this.y, this.w + this.x, this.y + this.r, this.r);
ctx.lineTo(this.w + this.x, this.h + this.y - this.r * 2);
ctx.arcTo(this.w + this.x, this.h + this.y, this.w + this.x - this.r, this.h + this.y, this.r);
ctx.lineTo(this.x + this.r, this.h + this.y);
ctx.arcTo(this.x, this.h + this.y, this.x, this.h + this.y - this.r, this.r);
ctx.lineTo(this.x, this.y + this.r);
ctx.arcTo(this.x, this.y, this.x + this.r, this.y, this.r);
ctx.stroke();
ctx.closePath();
};
Card.prototype.mouseOverCard = function(x, y) {
return x >= this.x && x <= this.x + this.w && y >= this.y && y <= this.y + this.h;
};
var imgLib = [
'img/a.png', 'img/ka.png', 'img/sa.png', 'img/ta.png', 'img/na.png', 'img/ha.png',
'img/ma.png', 'img/ya.png', 'img/ra.png', 'img/wa.png', 'img/i.png', 'img/ki.png',
'img/shi.png', 'img/chi.png', 'img/ni.png', 'img/hi.png', 'img/mi.png', 'img/ri.png',
'img/u.png', 'img/ku.png', 'img/su.png', 'img/tsu.png', 'img/nu.png', 'img/hu.png',
'img/mu.png', 'img/yu.png', 'img/ru.png', 'img/n.png', 'img/e.png', 'img/ke.png',
'img/se.png', 'img/te.png', 'img/ne.png', 'img/he.png', 'img/me.png', 'img/re.png',
'img/o.png', 'img/ko.png', 'img/so.png', 'img/to.png', 'img/no.png', 'img/ho.png',
'img/mo.png', 'img/yo.png', 'img/ro.png', 'img/wo.png'
];
var imgArray = [];
imgArray = imgLib.slice();
var flippedCards = [];
var numTries = 0;
var doneLoading = function() {};
canvas.addEventListener("click", function(e) {
for(var i = 0;i < cards.length;i++) {
var mouseX = e.clientX - e.currentTarget.offsetLeft;
var mouseY = e.clientY - e.currentTarget.offsetTop;
if(cards[i].mouseOverCard(mouseX, mouseY)) {
if(flippedCards.length < 2 && !this.isFaceUp) {
cards[i].drawFaceUp(); //draw card face up
flippedCards.push(cards[i]);
if(flippedCards.length === 2) {
numTries++;
if(flippedCards[0].img.src === flippedCards[1].img.src) {
flippedCards[0].match = true;
flippedCards[1].match = true;
}
delay(600); //delay after image has been drawn
checkMatches();
}
}
}
}
var foundAllMatches = true;
for(var i = 0;i < cards.length;i++) {
foundAllMatches = foundAllMatches && cards[i].match;
}
if(foundAllMatches) {
var winText = "You Win!";
var textWidth = ctx.measureText(winText).width;
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "red";
ctx.font = "40px Arial";
ctx.fillText(winText, canvas.width/2 - textWidth, canvas.height/2);
}
}, false);
var gameImages = [];
for(var i = 0;i < ROWS * COLS/2;i++) {
var imgId = Math.floor(Math.random() * imgArray.length);
var match = imgArray[imgId];
gameImages.push(match);
gameImages.push(match);
imgArray.splice(imgId, 1);
}
gameImages.sort(function() {
return 0.5 - Math.random();
});
var cards = [];
var loadedImages = [];
var index = 0;
var imgLoader = function(imgsToLoad, callback) {
for(var i = 0;i < imgsToLoad.length;i++) {
var img = new Image();
img.src = imgsToLoad[i];
loadedImages.push(img);
cards.push(new Card(0, 0, img));
img.onload = function() {
if(loadedImages.length >= imgsToLoad.length) {
callback();
}
};
}
for(var i = 0;i < COLS;i++) {
for(var j = 0;j < ROWS;j++) {
cards[index].x = i * 80 + i * 10 + 20;
cards[index].y = j * 100 + j * 10 + 20;
index++;
}
}
for(var i = 0;i < cards.length;i++) {
cards[i].drawFaceDown();
}
};
imgLoader(gameImages, doneLoading);
var checkMatches = function() {
for(var i = 0;i < cards.length;i++) {
if(!cards[i].match) {
cards[i].drawFaceDown();
}
}
flippedCards = [];
};
var delay = function(ms) {
var start = new Date().getTime();
var timer = false;
while(!timer) {
var now = new Date().getTime();
if(now - start > ms) {
timer = true;
}
}
};
屏幕不會被刷新,直到你的函數退出。 通常的處理方法是使用[setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout)。 將延遲後要運行的代碼放入單獨的函數中,並在所需的延遲後使用setTimeout調用該函數。請注意,setTimeout將立即返回;回調將在稍後執行。 – Jon
@Jon你可以在此擴展嗎?我嘗試將checkMatches函數移動到'window.setTimeout(checkMatches,600)'中,並且延遲消失,但卡片沒有翻轉過來 – mscoggins