Phaser 3:初始重力设0后玩家无法跳跃的解决方法
解决Phaser 3中玩家无法跳跃的问题
问题根源
- Update函数未正确暴露:你的
update函数嵌套在create函数内部,Phaser无法全局调用它,导致键盘输入逻辑完全不执行。 - 未初始化键盘输入对象:没有创建
cursors对象来检测方向键按下状态,跳跃判断条件永远不成立。 - 修改配置文件重力无效:
config仅用于初始化游戏,运行时修改config.physics.arcade.gravity不会影响当前物理世界的状态。
修复步骤
- 将
update函数移到create函数外部,与preload、create同级,确保Phaser能正确调用。 - 在
create函数中初始化键盘输入对象:cursors = this.input.keyboard.createCursorKeys();。 - 给玩家精灵单独设置重力(而非全局重力),避免影响其他物理体:
- 初始时设置玩家重力为0,防止下落;
- 跳跃时设置玩家重力为300,使其能下落;
- 玩家落地后重置重力为0,保持静止。
修改后的完整代码
let config = { type: Phaser.AUTO, width: 800, height: 500, physics: { default: 'arcade', arcade: { gravity: { y: 0 }, debug: false } }, scene: { preload: preload, create: create, update: update }, scale: { mode: Phaser.Scale.FIT, parent: 'root', autoCenter: Phaser.Scale.CENTER_BOTH, width: 800, height: 600 }, }; new Phaser.Game(config) function preload() { this.load.image('sky', require('../assets/backgrounds/sky.png')); this.load.image('jungle', require('../assets/backgrounds/jungle.png')); this.load.image('ground', require('../assets/tiles/ground-transp.png')) this.load.image('small-platform', require("../assets/tiles/small-platform-removebg-preview.png")) this.load.image('jungle-platform', require("../assets/tiles/jungle-platform.png")) this.load.image('large-platform', require("../assets/tiles/large-platform-removebg-preview.png")) this.load.image('tree', require("../assets/backgrounds/treetrunk.png")) this.load.image('plant', require("../assets/backgrounds/plant.png")) this.load.image('plant2', require("../assets/backgrounds/plants2.png")) this.load.image('rock', require("../assets/backgrounds/rock.png")) this.load.atlas('sacred', require('../assets/spritesheets/sacredRock.png'), require('../assets/spritesheets/sacredRock.json')) this.load.atlas('player', require('../assets/spritesheets/dilopodon.png'), require('../assets/spritesheets/dilopodon.json')) this.load.tilemapTiledJSON('Ground', require('../assets/maps/simple-tutorial.json')); } function create () { this.bg = this.add.image(-41, -41, 'sky'); this.bg = this.add.image('jungle'); this.add.image(67, 370, 'tree') this.add.image(167, 429, 'plant') this.add.image(700, 405, 'plant2') this.add.image(300, 440, 'rock') const map = this.make.tilemap({ key: 'Ground' }) // 创建 tilesets const groundTileSet = map.addTilesetImage('Ground', 'ground') const platformTileset = map.addTilesetImage('small-platform', 'small-platform') const junglePlatformTileset = map.addTilesetImage('jungle-platform', 'jungle-platform') const largePlatformTileset = map.addTilesetImage('large-platform', 'large-platform') let groundLayer = map.createLayer('Ground', [groundTileSet, platformTileset, junglePlatformTileset, largePlatformTileset]) groundLayer.setCollisionByExclusion([-1]); // 创建玩家 player = this.physics.add.sprite(100, 420, 'player') player.setBounce(0.2); player.setCollideWorldBounds(true) player.setGravityY(0); // 初始玩家重力为0,防止下落 player.body.width = 60 player.body.height = 60 player.body.offset.x = 10 player.body.offset.x = 10 // 创建圣石 sacredStone = this.physics.add.sprite(400, 270, 'sacred') sacredStone.setCollideWorldBounds(true) sacredStone.setGravityY(0); // 固定圣石,不受重力影响 sacredStone.body.width = 60 sacredStone.body.height = 230 // 物理碰撞 this.physics.add.collider(groundLayer, player ) this.physics.add.collider(groundLayer, sacredStone ) // 初始化键盘输入 cursors = this.input.keyboard.createCursorKeys(); } function update() { sacredStone.anims.play('glow', true) if (cursors.left.isDown) { player.setVelocityX(-160); player.anims.play('walkLeft', true); } else if (cursors.right.isDown) { player.setVelocityX(160); player.anims.play('walkRight', true); } else { player.setVelocityX(0); player.anims.play('idle', true); } // 跳跃逻辑 if (cursors.up.isDown && player.body.blocked.down) { player.setGravityY(300); // 设置玩家重力,使其下落 player.setVelocityY(-330); } // 玩家落地后重置重力为0,保持静止 if (player.body.blocked.down) { player.setGravityY(0); } }
额外说明
- 如果需要全局重力生效,可改用
this.physics.world.gravity.y = 300修改全局重力,但需给不需要下落的物体(如圣石)单独设置setGravityY(0)。 - 确保你的动画(如
walkLeft、glow)已正确定义,否则会出现报错。
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

