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

Angular项目足球小游戏开发求助:定时显隐与点击失效问题

解决方案

问题根源

你当前的代码用单个setInterval每10秒切换显隐,导致显示时长是10秒而非需求的5秒;同时直接用jQuery操作DOM不符合Angular的响应式理念,还会和手动点击的逻辑冲突。

修复步骤

  1. 用Angular变量控制显隐:放弃jQuery的fadeIn/fadeOut,改用组件变量绑定控制元素显示状态,同时用Angular的方式处理位置和样式。
  2. 拆分定时器逻辑:用一个setInterval负责每10秒触发足球出现,每次出现后用setTimeout控制5秒后自动隐藏;点击时立即清除自动隐藏的定时器并隐藏足球。
  3. 清理定时器避免内存泄漏:在组件销毁时清除所有定时器。

完整代码示例

组件类代码

import { Component, OnInit, OnDestroy, ElementRef, ViewChild } from '@angular/core';

@Component({
  selector: 'app-football-minigame',
  templateUrl: './football-minigame.component.html',
  styleUrls: ['./football-minigame.component.css']
})
export class FootballMinigameComponent implements OnInit, OnDestroy {
  isFootballVisible = false;
  footballPosition = { left: '0px', top: '0px' };
  balance = 0;
  userId = 1; // 替换为实际用户ID
  private hideTimeout: any;
  private showInterval: any;
  @ViewChild('minigameWindow') minigameWindow!: ElementRef;

  ngOnInit(): void {
    // 每10秒触发一次足球出现
    this.showInterval = setInterval(() => {
      this.showFootball();
    }, 10000);
  }

  ngOnDestroy(): void {
    // 清理定时器,避免内存泄漏
    if (this.hideTimeout) clearTimeout(this.hideTimeout);
    if (this.showInterval) clearInterval(this.showInterval);
  }

  showFootball(): void {
    // 计算随机位置
    this.placeRandomPosition();
    // 显示足球
    this.isFootballVisible = true;
    // 设置5秒后自动隐藏
    this.hideTimeout = setTimeout(() => {
      this.hideFootball();
    }, 5000);
  }

  hideFootball(): void {
    this.isFootballVisible = false;
    if (this.hideTimeout) {
      clearTimeout(this.hideTimeout);
      this.hideTimeout = null;
    }
  }

  onFootballClick(): void {
    // 立即隐藏足球
    this.hideFootball();
    // 添加5金币
    this.addCredits(this.userId, 5);
  }

  addCredits(userId: number, amount: number): void {
    // 这里实现添加金币的逻辑,比如更新余额或调用API
    this.balance += amount;
    console.log(`用户${userId}余额增加${amount},当前余额:${this.balance}`);
  }

  private placeRandomPosition(): void {
    const windowElement = this.minigameWindow.nativeElement;
    const windowWidth = windowElement.offsetWidth;
    const windowHeight = windowElement.offsetHeight;
    const footballSize = 80; // 足球宽高都是80px

    // 计算随机位置,确保足球不会超出容器
    const randomLeft = Math.floor(Math.random() * (windowWidth - footballSize));
    const randomTop = Math.floor(Math.random() * (windowHeight - footballSize));

    this.footballPosition = {
      left: `${randomLeft}px`,
      top: `${randomTop}px`
    };
  }
}

HTML模板代码

<div #minigameWindow id="minigame-window" class="card-body" style="height: 65vh; position: relative;">
  <!-- 足球元素,用*ngIf控制显隐,绑定随机位置 -->
  <div 
    *ngIf="isFootballVisible"
    class="football rotate90"
    [style.left]="footballPosition.left"
    [style.top]="footballPosition.top"
    (click)="onFootballClick()"
    style="position: absolute; cursor: pointer;"
  >
    <img src="assets/football-157930_640.png" class="rotate90" height="80px" width="80px">
  </div>

  <!-- 可选:显示当前余额 -->
  <div>当前余额:{{ balance }}金币</div>
</div>

关键说明

  • 用@ViewChild获取容器元素,避免直接用jQuery选择器,符合Angular规范。
  • 每次显示足球时重新计算随机位置,确保每次出现的位置都不一样。
  • 点击足球时会立即清除自动隐藏的定时器,避免后续自动隐藏逻辑触发。
  • 组件销毁时清理所有定时器,防止内存泄漏。

内容的提问来源于stack exchange,提问作者mooney-jjang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:25:57