Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improper sizing on single-row/single-column SpriteSheets created from trimmed Texture Atlas frames #4096

Closed
Cirras opened this issue Oct 6, 2018 · 1 comment

Comments

@Cirras
Copy link
Contributor

Cirras commented Oct 6, 2018

Version

  • Phaser Version: v3.14.0-FB
  • Operating system: Windows 10
  • Browser: Not applicable

Description

In SpriteSheets created from a (trimmed) texture atlas frame with TextureManager.addFromTextureAtlas(), if the resulting spritesheet is single-row or single-column then the spritesheet frame sizes will be calculated improperly and show parts of the surrounding textures in the texture atlas when used.

Example Test Code

In the following example, we will meet Priestly the Slime. Unfortunately, we'll also meet portions of the texture(s) below Priestly in the texture atlas due to this bug. Have a look.

import 'phaser';

// NOTE: Below is a patch to fix issue #4088 for the purposes of this example.
// It can be commented out without issue, but the first frame of the animation will be skipped.
{
    var Texture = require('phaser/src/textures/Texture');
    var Frame = require('phaser/src/textures/Frame');

    Texture.prototype.add = function (name, sourceIndex, x, y, width, height)
    {
        var frame = new Frame(this, name, sourceIndex, x, y, width, height);

        this.frames[name] = frame;

        //  Set the first frame of the Texture (other than __BASE)
        //  This is used to ensure we don't spam the display with entire
        //  atlases of sprite sheets, but instead just the first frame of them
        //  should the dev incorrectly specify the frame index
        if (this.firstFrame === '__BASE')
        {
            console.log('firstName', this.firstFrame);
            this.firstFrame = name;
        }

        this.frameTotal++;

        return frame;
    }
}

const config = {
    type: Phaser.AUTO,
    width: 500,
    height: 500,
    pixelArt: true,
    roundPixels: true,
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);

function preload()
{
    this.load.path = 'https://game.bones-underground.org/';
    this.load.multiatlas('trimmedMultiAtlas', 'gfx/6/all.json');
}

function create()
{
    this.cameras.main.setZoom(3);

    this.textures.addSpriteSheetFromAtlas(
        'Priestly', 
        {
            atlas: 'trimmedMultiAtlas',
            frame: '1818',
            frameWidth: 45,
            frameHeight: 52
        });

    this.anims.create({
        key: 'PriestlyAnimation',
        frames: this.game.anims.generateFrameNumbers('Priestly'),
        frameRate: 2,
        repeat: -1
    });

    this.add.sprite(250, 250).play('PriestlyAnimation');
}

Additional Information

Have a look at the page of the multi-atlas where Priestly the Slime can be found here. Note the textures immediately under the first 2 frames of the animation. These are what we're seeing portions of in the example test code.

I have found the cause of the problem. In Parser.SpriteSheetFromAtlas, there is a portion of the code that looks like this:

                        if (leftRow)
                        {
                            destWidth = leftWidth;
                        }
                        else if (rightRow)
                        {
                            destWidth = rightWidth;
                        }

                        if (topRow)
                        {
                            destHeight = topHeight;
                        }
                        else if (bottomRow)
                        {
                            destHeight = bottomHeight;
                        }

As you can see, these checks adjust the size of the frame depending on whether the frame is in the left column or right column, and whether the frame is in the top row or bottom row. What it does not handle is the case where the frame is both top and bottom, or both left and right.

This is the cause of the bug. I will submit a pull request to resolve the problem shortly.

@photonstorm
Copy link
Collaborator

Thanks for opening this issue, and for submitting a PR to fix it. We have merged your PR into the master branch and attributed the work to you in the Change Log. If you need to tweak the code for whatever reason please submit a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants