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

Phaser 3最新版 Graphics生成纹理后Sprite尺寸异常如何正确设置

问题根因

核心问题出在graphics.generateTexture('hex')的调用逻辑:

  • 该方法如果不手动传入纹理宽度、高度参数,Phaser 3会默认使用当前游戏的全画布尺寸(即你配置的1920*1080)作为生成纹理的大小。你绘制的六边形仅占这张全屏大纹理的极小部分,其余区域全是透明像素,因此创建Sprite后读取到的displayWidth、displayHeight就是全屏尺寸。
  • 额外偏差来自绘制坐标:你传入Graphics的六边形顶点是叠加了世界坐标偏移的数值,没有做局部坐标转换,六边形在大纹理中的位置本身就是偏移的,缩放时就会出现只显示一角、图形几乎不可见的问题。
修复方案

1. 修正纹理生成逻辑

生成纹理前先计算六边形的实际边界,将顶点转换为相对于纹理原点的局部坐标,同时给generateTexture传入准确的宽高参数,预留描边宽度避免内容被裁切:

function GraphicsCreator(scene, hexShape, hex) {
  // 计算六边形几何边界,预留和线宽一致的内边距防止描边裁切
  const bounds = hexShape.getBounds()
  const padding = 3
  const texWidth = Math.ceil(bounds.width) + padding * 2
  const texHeight = Math.ceil(bounds.height) + padding * 2

  const graphics = scene.add.graphics({ x: 0, y: 0, add: false });
  graphics.lineStyle(3, hex.outlineColour)
  graphics.fillStyle(hex.colour);

  // 所有顶点转换为纹理局部坐标:减去边界偏移,加上内边距
  graphics.beginPath();
  const firstPoint = hexShape.points[0]
  graphics.moveTo(firstPoint.x - bounds.x + padding, firstPoint.y - bounds.y + padding);
  for (let i = 1; i < hexShape.points.length; i++) {
    const p = hexShape.points[i]
    graphics.lineTo(p.x - bounds.x + padding, p.y - bounds.y + padding);
  }

  graphics.closePath();
  graphics.strokePath();
  graphics.fillPath();
  // 传入准确宽高生成纹理,禁止使用默认全屏尺寸
  graphics.generateTexture('hex', texWidth, texHeight)
  graphics.destroy();

  // 存储纹理对应的定位偏移量,供后续创建Sprite使用
  hex.texWidth = texWidth
  hex.texHeight = texHeight
  hex.spritePosX = bounds.x - padding
  hex.spritePosY = bounds.y - padding
}

2. 修正Sprite创建逻辑

不要硬写Sprite的display宽高或缩放值,直接使用纹理自带的尺寸,坐标对齐纹理对应的世界位置:

function TextureGetter(scene, hex) {
  // 原点设为左上角,坐标对齐纹理实际对应的世界位置
  const sprite = scene.add.sprite(hex.spritePosX, hex.spritePosY, 'hex')
  sprite.setDisplayOrigin(0)
  return sprite
}
Phaser 3 Sprite尺寸设置注意事项
  • displayWidth、displayHeight是引擎自动计算的属性,不建议手动赋值,它的取值 = 纹理原始尺寸 * Sprite缩放值,手动硬写会打乱渲染比例。
  • 需要调整Sprite大小时,统一使用sprite.setScale(scaleValue)方法,引擎会自动更新display宽高和碰撞边界。
  • 用Graphics生成纹理时必须显式传入宽高,永远不要依赖默认的全屏尺寸参数。
  • 你项目中的scale适配配置(FIT模式+居中)和本次问题无关,不需要修改。
  • 现有逻辑中仅在id为1的六边形上生成一次纹理是合理的,相同样式的六边形复用同一张纹理即可,不需要重复生成浪费性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:27:17