You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将DOM事件赋值给变量或数组:卡牌配对游戏开发问题

解决卡牌配对游戏的翻牌匹配逻辑问题

我来帮你梳理下当前代码的问题,然后一步步实现靠谱的卡牌匹配逻辑~

首先,你当前的代码存在几个关键问题:

  • openedCards()函数里直接使用event会报错,因为event是cardFlip的局部参数,你没把它传递到openedCards里
  • card1、card2是在if/else块里定义的局部变量,后续代码根本访问不到,所以cardFlip(card1)会提示变量未定义
  • openedCardsList.push(i)里的i没有明确的来源,你应该存储的是当前翻牌的DOM元素,而不是一个不明的参数

下面是修正后的完整思路和代码,完全贴合你的需求:

核心逻辑梳理

  1. 维护三个状态变量:
    • 存储已翻开卡牌的数组
    • 翻牌计数器(记录当前轮次的翻牌次数)
    • 一个锁变量(防止在翻牌动画/匹配判断期间重复点击)
  2. 翻牌时先做拦截:如果正在处理匹配、当前牌已翻开/已匹配,直接返回
  3. 每翻一张牌,更新计数器并加入数组
  4. 当数组里有两张牌时,判断是否匹配:
    • 匹配:标记为已匹配状态,不再响应点击
    • 不匹配:延迟一段时间后翻回两张牌
  5. 处理完成后重置状态,进入下一轮

修正后的代码示例

// 全局/闭包内维护状态变量
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:06:06