我正在学习 Vue 3 做一个记忆游戏。我有一个对象(卡片)代理数组,对象具有以下格式:
{
"id": "01",
"image": "01.jpg",
"isFlipped": false
}
{
"id": "07",
"image": "01.jpg",
"isFlipped": false
}
我的 flipCard méthodes turns card.isFlipped:true 显示图像。当显示 2 张牌时,将调用比较方法。如果有匹配卡,请不要打开。如果没有匹配卡,则在 setTimeOut 1.5 秒后再次取消翻转。 如果在 setTimeOut 的 1.5 秒之前翻转了另一辆车,我需要清除此超时以在打开下一张之前(在 1.5 秒之前)打开显示的 2 张卡片。我已经尝试了 2 个月。 谁能帮帮我,谢谢
我的组件
// flip 2 cards and compare them
function flipCard(card) {
clearTimeout(timeoutId.value);
card.isFlipped = true;
clicksNumber.value += 1;
comparedCards.value.push(card);
if (comparedCards.value.length === 2) {
compare(comparedCards.value[0], comparedCards.value[1]);
}
}
let timeoutId = ref();
function unflip(card) {
// Set a timeout and assign the ID to the timeoutId variable
timeoutId.value = setTimeout(() => {
card.isFlipped = false;
}, 1500);
}
// compares 2 flipped cards
function compare(a, b) {
if (a.image == b.image) {
found.value.push(a, b);
// remove found values from not found array
notFound.value = notFound.value.filter(
(item) => !found.value.includes(item)
);
} else {
comparedCards.value.forEach((card) => {
unflip(card); //unflips cards agter 1.5 secs
});
}
comparedCards.value = [];
}
我尝试初始化总点击次数 以及每次我们有 2 张卡片进行比较时的点击次数 (stopClick)
let clicksNumber = ref(0);
let stopClick = ref();
然后当达到 2 张卡片进行比较时,获得发生这种情况时的点击次数 并观察它与 totalClicks 的比较 如果这些不同,请调用 clearTimeout(timeoutId)
function flipCard(card) {
clearTimeout(timeoutId.value);
card.isFlipped = true;
clicksNumber.value += 1;
comparedCards.value.push(card);
if (comparedCards.value.length === 2) {
stopClick.value = clicksNumber.value;
compare(comparedCards.value[0], comparedCards.value[1]);
}
}
watch(clicksNumber, (stopClick) => {
if (clicksNumber.value != stopClick) {
clearTimeout(timeoutId)
}
});
还尝试了大约 20 种不同的东西,但都不起作用......:-(
我没有任何错误,只是在1.5秒之前点击我可以同时翻转3 4或5张牌
因为
comparedCards
包含两个项目,你在这里设置两个超时:
comparedCards.value.forEach((card) => {
unflip(card);
});
所以
timeoutId
将只包含最后一个超时ID。
要解决此问题,您可以将
timeoutId
设为数组,或更改 unflip()
以处理两张牌:
function unflip(cards){
timeoutId.value = setTimeout(() => {
cards.forEach(card.isFlipped = false);
}, 1500);
}
顺便说一句。我不认为让
timeoutId
成为 ref 对你有多大帮助——你永远不会在模板中使用它。
第二个问题是你实际上不只是想取消超时。如果显示了两张不匹配的牌并且玩家翻转了另一张牌,您不只是想取消等待再次翻转前两张牌,而是想立即翻转它们:
let timeoutId = null; // <--- doesn't have to be a ref
function compare(a, b) {
if (a.image == b.image) {
...
comparedCards.value = []; // <--- cards match, remove right away
} else {
timeoutId = setTimeout(unflip, 1500); // <--- wait to unflip
}
// <--- do not clear compared cards here
}
function flipCard(card) {
if(timeoutId){
unflip() //<--- abort timeout, unflip right away
}
card.isFlipped = true;
comparedCards.value.push(card);
if (comparedCards.value.length === 2) {
compare(...comparedCards.value);
}
}
function unflip() {
if(timeoutId){
clearTimeout(timeoutId);
timeoutId = null;
}
comparedCards.value.forEach(card => card.isFlipped = false); // unflip all opened cards
comparedCards.value = [] // no more open cards
}
我可能会将
comparedCards
重命名为 unflippedCards
或其他名称。