TilemapGPULayer is drawn at twice its x/y (position applied twice)

Abierto Apto para principiantes
#7,422 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 3 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
80/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
javascript

Línea de trabajo

Abre src/renderer/webgl/renderNodes/submitter/SubmitterTilemapGPULayer.js y lee run: la matriz del sprite aplica la posición de la capa mediante applyITRS, luego calcMatrix.setQuad(x, y, x + width, y + height, quad) la traslada una segunda vez. Compara con la ruta de TilemapLayer de Canvas/WebGL para confirmar que el origen debería venir solo de la matriz, luego cambia el quad para que empiece en 0,0. Verifica con la demo del issue, donde la capa GPU en (100,160) debería quedar sobre su marcador blanco exactamente igual que la capa no GPU; comprueba también el escalado y un tilemap con origen distinto de cero.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Version

  • Phaser Version: 4.2.1 (also on master today)
  • Operating system: Linux
  • Browser: Chrome 149 (WebGL 2 via ANGLE)

Description

A TilemapGPULayer placed anywhere but 0,0 is drawn in the wrong place: its x/y are applied twice. Unscaled, a layer created at (100, 160) is drawn at (200, 320); with a scale it lands at x + scaleX * x, e.g. a layer at (300, 120) with scale 0.25 is drawn at (375, 150).

In SubmitterTilemapGPULayer.run (src/renderer/webgl/renderNodes/submitter/SubmitterTilemapGPULayer.js), the sprite matrix already translates by the layer's position:

spriteMatrix.applyITRS(x, y, 0, tilemapLayer.scaleX, tilemapLayer.scaleY);
calcMatrix.multiply(spriteMatrix);

and then the quad is built from the position again:

calcMatrix.setQuad(x, y, x + width, y + height, quad);

Expected: a TilemapGPULayer at (x, y) is drawn where a TilemapLayer at (x, y) is.
Actual: it's drawn at (x + scaleX·x, y + scaleY·y).

Fix (tested against the example below with a patched dist/phaser.js; the layer then lands on its marker):

calcMatrix.setQuad(0, 0, width, height, quad);

Example Test Code

A plain two-tile tileset (no margin or spacing). The white squares mark where each layer's top-left should be. The TilemapLayer (top) sits on its marker; the TilemapGPULayer (created at 100,160) is drawn at 200,320.

<!doctype html>
<html><body style="margin:0">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script>
<script>
class Demo extends Phaser.Scene {
  create() {
    const tex = this.textures.createCanvas('tiles', 64, 32);
    const ctx = tex.getContext();
    ctx.fillStyle = '#e33'; ctx.fillRect(0, 0, 32, 32);
    ctx.fillStyle = '#36f'; ctx.fillRect(32, 0, 32, 32);
    tex.refresh();
    const data = [[0, 1, 0, 1]];
    for (const [gpu, x, y] of [[false, 100, 60], [true, 100, 160]]) {
      const map = this.make.tilemap({ data, tileWidth: 32, tileHeight: 32 });
      map.createLayer(0, map.addTilesetImage('tiles'), x, y, gpu);
      this.add.rectangle(x, y, 8, 8, 0xffffff);
    }
  }
}
new Phaser.Game({ type: Phaser.WEBGL, width: 600, height: 400, backgroundColor: '#222', scene: Demo });
</script>
</body></html>

Additional Information

Workaround: keep TilemapGPULayers at 0,0 (scaling about the origin is then fine).

Lenguaje dominante
JavaScript
Estrellas
40.7k
Forks
7.2k
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de phaserjs/phaser

Todos los issues de phaserjs/phaser

Issues similares

Más issues de JavaScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.