将DOM事件赋值给变量或数组:卡牌配对游戏开发问题
解决卡牌配对游戏的翻牌匹配逻辑问题
我来帮你梳理下当前代码的问题,然后一步步实现靠谱的卡牌匹配逻辑~
首先,你当前的代码存在几个关键问题:
openedCards()函数里直接使用event会报错,因为event是cardFlip的局部参数,你没把它传递到openedCards里card1、card2是在if/else块里定义的局部变量,后续代码根本访问不到,所以cardFlip(card1)会提示变量未定义openedCardsList.push(i)里的i没有明确的来源,你应该存储的是当前翻牌的DOM元素,而不是一个不明的参数
下面是修正后的完整思路和代码,完全贴合你的需求:
核心逻辑梳理
- 维护三个状态变量:
- 存储已翻开卡牌的数组
- 翻牌计数器(记录当前轮次的翻牌次数)
- 一个锁变量(防止在翻牌动画/匹配判断期间重复点击)
- 翻牌时先做拦截:如果正在处理匹配、当前牌已翻开/已匹配,直接返回
- 每翻一张牌,更新计数器并加入数组
- 当数组里有两张牌时,判断是否匹配:
- 匹配:标记为已匹配状态,不再响应点击
- 不匹配:延迟一段时间后翻回两张牌
- 处理完成后重置状态,进入下一轮
修正后的代码示例
// 全局/闭包内维护状态变量 let openedCards = []; let flipCount = 0; let isProcessing = false; function cardFlip(event) { // 拦截无效点击:正在处理中、卡牌已翻开/已匹配 if (isProcessing || $(event.target).hasClass('open') || $(event.target).hasClass('matched')) { return; } const $currentCard = $(event.target); $currentCard.addClass('open show'); // 这里用addClass,避免重复切换 flipCount++; handleCardMatch($currentCard); } function handleCardMatch($card) { openedCards.push($card); // 当翻开了第二张牌时 if (openedCards.length === 2) { isProcessing = true; // 上锁,禁止连续点击 const [$card1, $card2] = openedCards; // 这里替换成你的卡牌匹配判断逻辑,比如根据卡牌的图标类/自定义属性 // 示例:假设卡牌内部的图标类是匹配依据,比如fa-diamond、fa-paper-plane-o const card1IconClass = $card1.find('.fa').attr('class').split(' ').find(cls => cls.startsWith('fa-')); const card2IconClass = $card2.find('.fa').attr('class').split(' ').find(cls => cls.startsWith('fa-')); const isMatched = card1IconClass === card2IconClass; if (isMatched) { // 匹配成功:标记为已匹配,移除翻牌状态 $card1.addClass('matched').removeClass('open show'); $card2.addClass('matched').removeClass('open show'); console.log('卡牌匹配成功!'); } else { // 匹配失败:延迟1秒后翻回卡牌 setTimeout(() => { $card1.removeClass('open show'); $card2.removeClass('open show'); console.log('卡牌不匹配,翻回!'); }, 1000); } // 重置状态,解锁点击 setTimeout(() => { openedCards = []; isProcessing = false; flipCount = 0; // 每轮结束重置计数器 }, 1000); } // 可以在这里打印计数器状态,测试逻辑 console.log(`当前翻牌次数:${flipCount}`); }
关键细节说明
- 点击锁
isProcessing:避免在翻牌动画期间重复点击,防止数组里塞入超过两张牌,导致逻辑混乱 - 匹配判断逻辑:你可以根据自己的卡牌结构调整,比如如果给每个卡牌加了
data-card-type属性,就用$card.data('card-type')来比较,比用图标类更可靠 - 计数器逻辑:每次翻牌
flipCount递增,两轮结束后重置为0,完全符合你“第一次到1,第二次到2,不匹配则重置”的需求 - 变量作用域:把卡牌的jQuery对象直接传递给处理函数,避免依赖
event跨函数访问,减少错误
内容的提问来源于stack exchange,提问作者3noki
相关产品推荐
相关产品推荐

