phaserjs / phaser-ce

Phaser CE is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
http://phaser.io
MIT License
1.35k stars 491 forks source link

Invalid pointer world position when camera/world scale is not 1 or world rotation is not 0 #87

Open sebas86 opened 7 years ago

sebas86 commented 7 years ago

If world scale is not 1 or rotation is not 0 pointer world position will be invalid.

Sample code:

var sprite;

function preload() {
    game.load.baseURL = 'http://examples.phaser.io/assets/';
    game.load.crossOrigin = 'anonymous';
    game.load.image('phaser', 'sprites/phaser-dude.png');
}

function create() {
    game.world.position.set(100,100);
    if (1)
    {
        game.world.scale.set(0.5,0.5);
    }
    if (1)
    {
        game.world.rotation = Math.PI * 45 / 180;
    }
    sprite = game.add.sprite(0, 0, 'phaser');
    sprite.anchor.set(0.5, 0.5);
}

function update() {
    var pointer = game.input.mousePointer;
    sprite.x = pointer.worldX;
    sprite.y = pointer.worldY;
}

Temporary workaround:

var sprite;

function preload() {
    game.load.baseURL = 'http://examples.phaser.io/assets/';
    game.load.crossOrigin = 'anonymous';
    game.load.image('phaser', 'sprites/phaser-dude.png');
}

function create() {
    game.world.position.set(1000,1000);
    if (1)
    {
        game.world.scale.set(0.5,0.5);
    }
    if (1)
    {
        game.world.rotation = Math.PI * 15 / 180;
    }
    sprite = game.add.sprite(0, 0, 'phaser');
    sprite.anchor.set(0.5, 0.5);
}

function update() {
    var pointer = game.input.mousePointer;
    var camera = game.camera;
    var world = game.world;
    var rotation = -world.rotation;
    var sin = Math.sin(rotation);
    var cos = Math.cos(rotation);
    var tmpX = (pointer.x + camera.position.x) / camera.scale.x;
    var tmpY = (pointer.y + camera.position.y) / camera.scale.y;
    var worldX = tmpX * cos - tmpY * sin;
    var worldY = tmpX * sin + tmpY * cos;
    sprite.x = worldX;
    sprite.y = worldY;
}
samme commented 7 years ago

Did you try setting game.input.scale?

sebas86 commented 7 years ago

No, I did not. I suppose setting this property will break something in other places. For example button handles clicks and touches correctly without setting this property. Similar problem occurs in few other places, for example box2d debug render. I suppose it's problem with duplicated code - in many places transformation is performed by hand instead using shared code (matrix transformations).

I also checked source code and pointer.worldX use only camera position to transform pointer from camera to world space.