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

如何在Phaser3中缩放TiledMap以填充Canvas可用空间

Tiled地图适配Canvas全屏的Phaser响应式解决方案

要让Tiled导出的地图占满Canvas全部空间并适配所有屏幕尺寸,你需要通过计算缩放比例并动态调整地图容器/相机缩放来实现,替代不存在的groundLayer.resizeWorld()方法。以下是具体修改方案:

关键修改步骤

1. 补充resize处理方法

在Scene1类中添加resize方法,用于窗口尺寸变化时重新计算缩放比例并更新:

resize(gameSize) {
  const { width, height } = gameSize;
  const mapWidth = this.map.widthInPixels;
  const mapHeight = this.map.heightInPixels;

  // 计算宽高缩放比例,取最大值保证填满屏幕
  const scaleX = width / mapWidth;
  const scaleY = height / mapHeight;
  const scale = Math.max(scaleX, scaleY);

  // 统一缩放游戏容器(包含地图和所有元素)
  this.gameContainer.setScale(scale);

  // 更新物理世界和相机边界
  this.physics.world.setBounds(0, 0, mapWidth * scale, mapHeight * scale);
  this.cameras.main.setBounds(0, 0, mapWidth * scale, mapHeight * scale);

  // 保持相机跟随玩家
  if (this.player) {
    this.cameras.main.startFollow(this.player);
  }
}

2. 初始化时设置全屏适配逻辑

修改create方法,缓存地图实例到类属性,创建统一容器管理所有游戏元素,并计算初始缩放:

create() {
  // 缓存地图实例,方便resize时调用
  this.map = this.make.tilemap({ key: 'map' });
  const tileset1 = this.map.addTilesetImage('objects', 'objects');
  const tileset2 = this.map.addTilesetImage('img_3500', 'img_3500');
  const groundLayer = this.map.createLayer('groundLayer', tileset2, 0, 0);
  const worldLayer = this.map.createLayer('worldLayer_1', tileset1);

  // 创建统一容器,管理地图和所有游戏元素
  this.gameContainer = this.add.container(0, 0);
  this.gameContainer.add([groundLayer, worldLayer]);

  // 添加玩家元素到容器
  this.player = this.add
    .sprite(32, 64, 'playerDown')
    .setScale(0.5)
    .setDepth(10);
  this.gameContainer.add(this.player);

  // 添加障碍物和目标点到容器(基于原始地图坐标)
  this.obst = this.add.sprite(
    this.map.widthInPixels / 2,
    64 * 2,
    'pond'
  ).setScale(0.5);
  this.gameContainer.add(this.obst);

  this.goal = this.add.sprite(
    this.map.widthInPixels - 64 * 2,
    64 * 3,
    'goal'
  ).setScale(2);
  this.gameContainer.add(this.goal);

  // 计算初始缩放比例并应用
  const gameWidth = this.sys.game.config.width;
  const gameHeight = this.sys.game.config.height;
  const mapWidth = this.map.widthInPixels;
  const mapHeight = this.map.heightInPixels;
  const scaleX = gameWidth / mapWidth;
  const scaleY = gameHeight / mapHeight;
  const scale = Math.max(scaleX, scaleY);
  this.gameContainer.setScale(scale);

  // 设置相机和物理世界边界
  const camera = this.cameras.main;
  camera.setBounds(0, 0, mapWidth * scale, mapHeight * scale);
  camera.startFollow(this.player);
  this.physics.world.setBounds(0, 0, mapWidth * scale, mapHeight * scale);

  // 监听窗口resize事件
  this.scale.on('resize', this.resize, this);
}

3. 优化Phaser配置

调整scale配置,确保Canvas自动适配父容器并居中显示:

const config = {
  type: Phaser.AUTO,
  parent: 'phaser-test',
  pixelArt: true,
  preserveDrawingBuffer: true,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 0 },
      debug: false,
    },
  },
  scene: [Scene1],
  audio: {
    disableWebAudio: true,
  },
  scale: {
    mode: Phaser.Scale.RESIZE,
    parent: 'phaser-test',
    width: '100%',
    height: '100%',
    autoCenter: Phaser.Scale.CENTER_BOTH,
  },
};

核心逻辑说明

  • 统一容器缩放:将地图图层和所有游戏元素放入同一个容器,通过缩放容器实现整体适配,避免单独调整每个元素的繁琐操作。
  • 比例适配:取窗口与地图宽高比值的最大值,确保地图填满屏幕的同时保持原始宽高比,避免拉伸变形。
  • 动态响应:监听窗口resize事件,实时更新缩放比例和边界,保证窗口尺寸变化时仍保持全屏适配效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:40:34