phaser icon indicating copy to clipboard operation
phaser copied to clipboard

Tiles disappear on camera move in isometric mode

Open 318h7 opened this issue 3 years ago • 5 comments

Version

  • Phaser Version: 3.51.0
  • Operating system: Linux
  • Browser: reproducible on Firefox and Chrome

Description

When moving camera to the right or downwards, tiles start to dissapear row by row in isometic mode. I don't get this behaviour when loading a map from json. Also, this issue disappears when switched to orthogonal mode. But I wanted to work on a game that would have random generated isometric map.

Example Test Code

(Used the png from the examples repo)

import Phaser from 'phaser';

var config = {
    type: Phaser.WEBGL,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    pixelArt: true,
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var controls;
var layer;
var game = new Phaser.Game(config);

function preload ()
{
    this.load.image('tiles', 'assets/iso/iso-64x64-outside.png');
}


function fillLayer() {
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 4; j++) {
        layer.putTileAt(0, i, j);
      }
    }
  }

function create ()
{
    var map = this.make.tilemap({ tileWidth: 64, tileHeight: 64  });
    map.orientation = 1;

    var tileset1 = map.addTilesetImage('iso-64x64-outside', 'tiles');

    layer = map.createBlankLayer('ground', tileset1);

    var cursors = this.input.keyboard.createCursorKeys();

    this.cameras.main.setScroll(-340, -100);

    fillLayer();

    var controlConfig = {
        camera: this.cameras.main,
        left: cursors.left,
        right: cursors.right,
        up: cursors.up,
        down: cursors.down,
        acceleration: 0.04,
        drag: 0.0005,
        maxSpeed: 0.7
    };

    controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
}

function update (time, delta)
{
    controls.update(delta);
}

Additional Information

2021-01-09-02-16-32

318h7 avatar Jan 09 '21 00:01 318h7

TL;DR: As a quick workaround, try using TilemapLayer.skipCull to see if it helps.

I'm running into a similar issue when adding a TileMap to a container and then moving the container. The current implementation of renderWebGL for Tilemap doesn't accept a parent transform matrix, so when it's in a container it just ignores any container transform. (You can see the call from container.renderWebGL to the child render call here).

I updated the Tilemap code to accept the matrix and pass it into the pipeline batch texture call here and that actually works, but then I start seeing problems with tiles being culled while still in view.

So, now we know that we have tiles being unexpectedly culled. So back to TileMapLayerWebGLRenderer and the very first thing that happens is this cull call which ALSO doesn't accept the parent transform matrix. At this point I'm beyond my depth :). I took a look at the IsometricCullTiles implementation, and I don't know what the easiest way to take into account the parent transform would be so I stopped there.

In your case, it's likely that the camera scroll that you're setting is what's causing the unexpected culling. As a workaround, you can probably use TilemapLayer.skipCull to avoid any culling altogether, but if you have a large map you might run into some performance issues. Worth a shot!

veleek avatar Jan 24 '21 02:01 veleek

This issue has been mentioned on Phaser. There might be relevant details there:

https://phaser.discourse.group/t/isometric-maps/10221/1

photonstorm avatar Sep 07 '21 21:09 photonstorm

I am encountering this problem as well.

https://user-images.githubusercontent.com/30558265/132597195-808921a5-2676-4871-9ea4-5fef510a7933.mov

When I try to set skipCull to true, then absolutely nothing renders on the screen:

floorLayer.setSkipCull(true)

stevesmit avatar Sep 08 '21 23:09 stevesmit

This issue has been mentioned on Phaser. There might be relevant details there:

https://phaser.discourse.group/t/isometric-maps/10221/2

photonstorm avatar Sep 08 '21 23:09 photonstorm

Turns out what solved the problem was setting the cullPadding property using the setCullPadding() property.

Per the docs:

When a Camera culls the tiles in this layer it does so using its view into the world, building up a rectangle inside which the tiles must exist or they will be culled. Sometimes you may need to expand the size of this ‘cull rectangle’, especially if you plan on rotating the Camera viewing the layer. Do so by providing the padding values. The values given are in tiles, not pixels. So if the tile width was 32px and you set paddingX to be 4, it would add 32px x 4 to the cull rectangle (adjusted for scale)

So you need to use this method on the TileMapLayer you create from your actual Tilemap. For example:

const map = this.add.tilemap('map')

const tileset = map.addTilesetImage('spritesheet', 'tiles')
const firstLayer = map.createLayer('LayerNameHere', [tileset])
firstLayer.setCullPadding(8, 8)

stevesmit avatar Sep 09 '21 20:09 stevesmit

Thank you for submitting this issue. We have fixed this and the fix has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that.

photonstorm avatar Mar 22 '23 18:03 photonstorm