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

Phaser实现Chebyshev Distance时移动后出现origin.x空指针错误

问题解决:Phaser中Cannot read properties of null (reading 'x')错误

问题描述

复现Phaser的切比雪夫距离示例时,解决了gameState变量识别问题后,触发Cannot read properties of null (reading 'x')错误,该错误在玩家从x=0位置移动几个tile后出现。

错误原因

错误出现在updateMap方法中:this.gameState.map.getTileAtWorldXY(this.player.x, this.player.y)返回了null,此时访问origin.x自然会报错。导致返回null的核心原因有两个:

  1. 玩家移动到了tilemap范围之外,当前位置没有对应的tile
  2. 代码中down方向的速度设置错误(写成了-50),导致玩家移动逻辑异常,更容易意外移出地图边界

修复方案

1. 增加空值判断,避免访问空对象属性

修改updateMap方法,先检查origin是否有效,再执行后续切比雪夫距离计算:

updateMap() {
  var origin = this.gameState.map.getTileAtWorldXY(this.player.x, this.player.y);
  // 先判断origin是否存在,不存在则直接返回
  if (!origin) return;
  
  this.gameState.map.forEachTile(function (tile) {
    var dist = Phaser.Math.Distance.Chebyshev(
      origin.x,
      origin.y,
      tile.x,
      tile.y
    );

    tile.setAlpha(1 - 0.1 * dist);
  }, this);
}

2. 修正方向速度错误

在update方法中,down方向的velocityY应设置为正数值,否则会和up方向一样向上移动:

else if (this.gameState.cursors.down.isDown) {
  this.player.setVelocityY(50); // 将-50改为50
}

3. 限制玩家在tilemap范围内移动(可选)

如果不想让玩家移出地图,可以在update方法中添加边界限制,避免玩家跑到没有tile的区域:

// 在update方法末尾、调用updateMap之前添加
const mapWidth = this.gameState.map.widthInPixels;
const mapHeight = this.gameState.map.heightInPixels;
// 考虑玩家精灵的锚点和尺寸,避免半移出地图
this.player.x = Phaser.Math.Clamp(this.player.x, this.player.width/2, mapWidth - this.player.width/2);
this.player.y = Phaser.Math.Clamp(this.player.y, this.player.height/2, mapHeight - this.player.height/2);

完整修正后的代码

import Phaser from "../lib/phaser.js";

export default class Game extends Phaser.Scene {
  constructor() {
    super("game1");
  }

  preload() {
    this.load.image(
      "Tileset",
      "https://cdn.glitch.global/cc90578e-c3d0-47c5-bb0d-f5a81263b5b6/pixil-frame-0%20(17).png?v=1675985219390"
    );
    this.load.tilemapTiledJSON(
      "map",
      "https://cdn.glitch.global/cc90578e-c3d0-47c5-bb0d-f5a81263b5b6/Map.tmj?v=1675985261369"
    );
    this.load.spritesheet(
      "player",
      "https://cdn.glitch.global/cc90578e-c3d0-47c5-bb0d-f5a81263b5b6/pixil-frame-0%20(13).png?v=1675904194091",
      { frameWidth: 32, frameHeight: 32 }
    );
  }

  create() {
    this.gameState = {
      map: "",
      cursors: "",
    };

    this.gameState.map = this.make.tilemap({ key: "map" });
    this.tiles = this.gameState.map.addTilesetImage("tileSet", "Tileset");
    this.worldLayer = this.gameState.map.createLayer(
      "Block Layer",
      this.tiles,
      0,
      0
    );

    this.player = this.physics.add.sprite(0, 1600, "player", 1);

    this.cameras.main.setBounds(
      0,
      0,
      this.gameState.map.widthInPixels,
      this.gameState.map.heightInPixels
    );
    this.cameras.main.startFollow(this.player);

    this.gameState.cursors = this.input.keyboard.createCursorKeys();
    this.physics.add.collider(this.player, this.worldLayer);
  }

  update() {
    if (this.gameState.cursors.left.isDown) {
      this.player.setVelocityX(-50);
    } else if (this.gameState.cursors.right.isDown) {
      this.player.setVelocityX(50);
    } else if (this.gameState.cursors.up.isDown) {
      this.player.setVelocityY(-50);
    } else if (this.gameState.cursors.down.isDown) {
      this.player.setVelocityY(50); // 修正方向速度
    } else {
      this.player.setVelocityX(0);
      this.player.setVelocityY(0); // 补充停止Y方向速度
    }

    // 限制玩家在地图范围内移动
    const mapWidth = this.gameState.map.widthInPixels;
    const mapHeight = this.gameState.map.heightInPixels;
    this.player.x = Phaser.Math.Clamp(this.player.x, this.player.width/2, mapWidth - this.player.width/2);
    this.player.y = Phaser.Math.Clamp(this.player.y, this.player.height/2, mapHeight - this.player.height/2);

    this.updateMap();
  }
  
  updateMap() {
    var origin = this.gameState.map.getTileAtWorldXY(
      this.player.x,
      this.player.y
    );
    
    // 检查origin有效性
    if (!origin) return;

    this.gameState.map.forEachTile(function (tile) {
      var dist = Phaser.Math.Distance.Chebyshev(
        origin.x,
        origin.y,
        tile.x,
        tile.y
      );

      tile.setAlpha(1 - 0.1 * dist);
    }, this);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:27:25