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

Phaser平台游戏运行5秒后卡顿:主平台消失或生成机制异常?

问题分析与解决方案

核心卡顿原因

  1. 每帧高频更新分数文本:update函数中每秒执行60次分数递增与文本刷新,这是性能消耗的首要来源。
  2. 重复触发平台生成:同时通过定时器和update条件判断调用生成函数,导致平台生成频率远超预期,物理对象数量激增。
  3. 碰撞回调逻辑错误:玩家与平台的任何碰撞都会重置跳跃次数,包括侧面碰撞,引发跳跃逻辑异常。
  4. 动态纹理加载方式不当:在preload中使用Canvas生成的Data URL加载纹理,可能导致Phaser纹理管理异常。

针对性修复建议

  • 分数更新优化:改用定时器每秒更新分数,大幅减少文本渲染次数。
  • 移除重复生成逻辑:删除update中调用生成函数的代码,仅保留定时器触发。
  • 修正碰撞回调:仅当玩家踩在平台底部时重置跳跃次数。
  • 正确生成动态纹理:使用Phaser内置的textures.generate方法创建纯色平台纹理,避免Data URL的潜在问题。
  • 优化平台销毁判断:确保平台完全移出屏幕后再销毁,避免误删。

修复后的完整代码

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 300 },
            debug: false
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var game = new Phaser.Game(config);
var player;
var cursors;
var platforms;
var obstacles;
var jumpCount = 0;
var maxJumps = 2;
var gapWidth = 400;
var score = 0;
var scoreText;

function preload() {
    this.load.image('background', 'assets/images/realistic-spring-landscape_23-2148852143.avif');
    this.load.image('player', 'assets/do-your-cat-in-pixel-art.jpg');
    this.load.image('obstacle', 'assets/images/enemy.png');
}

function create() {
    this.add.image(400, 300, 'background');

    // 生成纯色平台纹理
    this.textures.generate('platform', {
        width: 800,
        height: 20,
        data: function () {
            return Array(800 * 20).fill(0xffff00);
        }
    });

    // 创建玩家
    player = this.physics.add.sprite(200, 491, 'player');
    player.setOrigin(0.5, 0.5);
    player.setCollideWorldBounds(true);
    player.setScale(0.1);
    player.setBounce(0.2);
    player.setGravityY(300);

    cursors = this.input.keyboard.createCursorKeys();

    // 平台组
    platforms = this.physics.add.group({
        allowGravity: false,
        immovable: true
    });

    // 障碍物组
    obstacles = this.physics.add.group({
        allowGravity: false,
        immovable: true
    });

    // 初始长平台
    var initialPlatform = platforms.create(400, 550, 'platform');
    initialPlatform.displayWidth = 1600;
    initialPlatform.setVelocityX(-200);

    // 碰撞处理:仅当玩家踩在平台上时重置跳跃次数
    this.physics.add.collider(player, platforms, function (player, platform) {
        if (player.body.touching.down && platform.body.touching.up) {
            jumpCount = 0;
        }
    });

    // 分数文本
    scoreText = this.add.text(16, 16, 'Score: 0', { fontSize: '32px', fill: '#FFF' });

    // 每秒更新分数
    this.time.addEvent({
        delay: 1000,
        callback: function () {
            score += 10; // 调整分数增量更合理
            scoreText.setText('Score: ' + score);
        },
        loop: true
    });

    // 平台生成定时器
    this.time.addEvent({
        delay: 1500,
        callback: generateObstaclesAndPlatforms,
        callbackScope: this,
        loop: true
    });
}

var lastPlatformX = 800;

function update() {
    player.setVelocityX(0);

    if (cursors.left.isDown) {
        player.setVelocityX(-160);
    } else if (cursors.right.isDown) {
        player.setVelocityX(160);
    }

    // 跳跃逻辑:仅在按键按下瞬间触发,避免持续按住连跳
    if (Phaser.Input.Keyboard.JustDown(cursors.up) && (player.body.touching.down || jumpCount < maxJumps)) {
        player.setVelocityY(-400);
        jumpCount++;
    }

    // 销毁移出屏幕的平台
    platforms.children.iterate(function (child) {
        // 平台完全移出左侧屏幕后销毁
        if (child.x + child.displayWidth / 2 < 0) {
            child.destroy();
        }
    });

    // 销毁移出屏幕的障碍物
    obstacles.children.iterate(function (child) {
        if (child.x + child.width < 0) {
            child.destroy();
        }
    });
}

function generateObstaclesAndPlatforms() {
    var platformGap = Phaser.Math.Between(gapWidth, gapWidth + 200);
    var platformWidth = (800 - platformGap) / 2;

    // 确保平台宽度至少为100,避免过窄
    platformWidth = Math.max(platformWidth, 100);

    var platform1 = platforms.create(lastPlatformX + platformGap, 550, 'platform');
    platform1.displayWidth = platformWidth;
    platform1.setVelocityX(-200);
    platform1.setImmovable(true);

    var platform2 = platforms.create(lastPlatformX + platformGap + platformWidth, 550, 'platform');
    platform2.displayWidth = platformWidth;
    platform2.setVelocityX(-200);
    platform2.setImmovable(true);

    lastPlatformX += platformGap + platformWidth;
}

额外优化建议

  • 限制平台数量:可在平台组中设置最大对象数,避免过多物理对象占用资源。
  • 对象池复用:对于频繁创建销毁的平台/障碍物,使用Phaser对象池机制替代每次创建新对象,进一步提升性能。
  • 调试模式:开启physics.arcade.debug=true,查看物理碰撞体状态,确认平台生成与销毁逻辑是否正常。

内容的提问来源于stack exchange,提问作者Matevz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:51:09