如何在Phaser 3中实现基于递增计时器的事件触发?
Phaser 3 计时触发逻辑实现方案
Phaser 3内置的Time系统完全能搞定你要的需求,下面是几个对应场景的完整可运行示例,直接复制到VSCode就能测试:
场景1:延迟显示文本/图片/可点击按钮
用time.delayedCall实现单次延迟触发,适合“多久后显示元素”的需求:
import Phaser from 'phaser'; const gameConfig = { type: Phaser.AUTO, width: 800, height: 600, scene: { preload: preloadAssets, create: setupScene } }; new Phaser.Game(gameConfig); // 预加载资源(替换成你自己的资源路径) function preloadAssets() { this.load.image('gameLogo', 'assets/phaser-logo.png'); this.load.spritesheet('uiButton', 'assets/button-sprite.png', { frameWidth: 220, frameHeight: 60 }); } function setupScene() { // 初始隐藏所有要延迟显示的元素 const delayedText = this.add.text(400, 200, '3秒后出现的提示', { fontSize: '28px', fill: '#ffffff' }) .setOrigin(0.5) .setVisible(false); const delayedImage = this.add.image(400, 320, 'gameLogo') .setScale(0.6) .setVisible(false); const delayedButton = this.add.sprite(400, 450, 'uiButton') .setInteractive() .setVisible(false); // 3秒后显示文本 this.time.delayedCall(3000, () => { delayedText.setVisible(true); }, [], this); // 5秒后显示图片 this.time.delayedCall(5000, () => { delayedImage.setVisible(true); }, [], this); // 7秒后显示按钮并绑定点击事件 this.time.delayedCall(7000, () => { delayedButton.setVisible(true); delayedButton.on('pointerdown', () => { this.add.text(400, 550, '按钮被点击啦!', { fontSize: '22px', fill: '#00ff00' }) .setOrigin(0.5); }); }, [], this); }
场景2:特定时间点触发元素闪烁
用time.addEvent指定触发时间,配合Tween动画实现闪烁效果:
// 可以直接替换上面的setupScene函数 function setupScene() { const targetImage = this.add.image(400, 300, 'gameLogo').setScale(0.6); // 计时到第8秒时触发闪烁 this.time.addEvent({ delay: 8000, // 延迟8秒执行 callback: () => { // Tween实现交替透明/不透明的闪烁效果,持续2秒 this.tweens.add({ targets: targetImage, alpha: 0, duration: 250, yoyo: true, // 往返动画 repeat: 3, // 重复3次,总共闪4次 onComplete: () => { targetImage.setAlpha(1); // 闪烁结束后恢复正常显示 } }); }, callbackScope: this }); }
场景3:实时跟踪计时器(Update循环中监控)
如果需要持续监控计时数值,在update函数中累计时间并判断:
// 修改scene配置,加入update函数 const gameConfig = { type: Phaser.AUTO, width: 800, height: 600, scene: { preload: preloadAssets, create: setupScene, update: trackTimer } }; function setupScene() { this.totalElapsedTime = 0; // 累计时间(毫秒) this.hasTriggered10s = false; // 标记是否已触发10秒事件 this.timerText = this.add.text(20, 20, '已计时:0秒', { fontSize: '20px', fill: '#fff' }); this.triggeredImage = this.add.image(400, 300, 'gameLogo').setScale(0.6).setVisible(false); } function trackTimer(time, delta) { this.totalElapsedTime += delta; const currentSeconds = Math.floor(this.totalElapsedTime / 1000); this.timerText.setText(`已计时:${currentSeconds}秒`); // 当计时到第6秒时显示图片 if (currentSeconds === 6 && !this.triggeredImage.visible) { this.triggeredImage.setVisible(true); } // 当计时到第10秒时执行一次性动作 if (currentSeconds === 10 && !this.hasTriggered10s) { this.add.text(400, 450, '10秒计时完成!', { fontSize: '30px', fill: '#ffff00' }) .setOrigin(0.5); this.hasTriggered10s = true; // 避免重复触发 } }
方法选择建议
delayedCall:适合单次延迟执行的场景(比如多久后显示元素)addEvent:支持重复触发、循环执行,适合定时重复任务- Update循环跟踪:适合需要实时监控时间数值,或者复杂的多条件触发逻辑
内容的提问来源于stack exchange,提问作者EmptyStone
相关产品推荐
相关产品推荐

