PhaserJS:旋转相机后拖动 Sprite 会产生奇怪的坐标
PhaserJS: After Rotation of camera dragging a Sprite gives strange coords
基本上问题是在旋转相机后,在拖动回调中作为参数给出的点不是我所期望的。我猜我也必须旋转给定的点,但我做不到。
谁能解释一下这是怎么回事,这是某种错误还是我应该怎么做才能让精灵跟随鼠标光标?
解释问题的最简单方法是重现它:
1) 转到 Phaser Example Runner
2) 复制-粘贴此代码:
var config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
scene: {
preload: preload,
create: create
}
};
var game = new Phaser.Game(config);
function preload ()
{
this.load.image('eye', 'assets/pics/lance-overdose-loader-eye.png');
}
function create ()
{
var image = this.add.sprite(200, 300, 'eye').setInteractive();
this.cameras.main.setRotation(Math.PI);
image.on('pointerover', function () {
this.setTint(0x00ff00);
});
image.on('pointerout', function () {
this.clearTint();
});
this.input.setDraggable(image);
this.input.on('dragstart', function (pointer, gameObject) {
gameObject.setTint(0xff0000);
});
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
console.log(`x: ${dragX}, y: ${dragY}`);
gameObject.x = dragX;
gameObject.y = dragY;
});
this.input.on('dragend', function (pointer, gameObject) {
gameObject.clearTint();
});
}
3)打开控制台,在Eye周围拖拽,看看给出的坐标是什么。
4) 如果删除第 24 行(相机的旋转),一切都会按预期进行。
(示例取自Phaser 3官方示例,针对BUG做了一点修改)
根据 setRotation()
方法中的 Phaser's API Documentation,以弧度表示的旋转适用于相机渲染的所有内容。不幸的是,您的指针不是由相机渲染的,因此它不会获得相同的旋转坐标。不确定这是库的错误还是只是记录不完整的异常,但我相信有解决方法。
创建 2 个变量来保存初始位置和最终位置:
var image = this.add.sprite(200, 300, 'eye').setInteractive();
var initial = [];
var final = [];
在您的 .on('dragstart')
方法中填充初始位置:
this.input.on('dragstart', function (pointer, gameObject) {
initial = [
gameObject.x,
gameObject.y,
pointer.x,
pointer.y
];
gameObject.setTint(0xff0000);
});
然后,在您的 .on('drag')
方法中填充最终变量:
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
final = [
gameObject.x, // not necessary but keeping for variable shape consistency
gameObject.y, // not necessary but keeping for variable shape consistency
pointer.x,
pointer.y
];
gameObject.x = initial[0] + (initial[2] - final[2]);
gameObject.y = initial[1] + (initial[3] - final[3]);
});
我们在这里所做的就是跟踪 pointer
位置的变化并模仿我们 gameObject
的变化。
基本上问题是在旋转相机后,在拖动回调中作为参数给出的点不是我所期望的。我猜我也必须旋转给定的点,但我做不到。
谁能解释一下这是怎么回事,这是某种错误还是我应该怎么做才能让精灵跟随鼠标光标?
解释问题的最简单方法是重现它:
1) 转到 Phaser Example Runner
2) 复制-粘贴此代码:
var config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
scene: {
preload: preload,
create: create
}
};
var game = new Phaser.Game(config);
function preload ()
{
this.load.image('eye', 'assets/pics/lance-overdose-loader-eye.png');
}
function create ()
{
var image = this.add.sprite(200, 300, 'eye').setInteractive();
this.cameras.main.setRotation(Math.PI);
image.on('pointerover', function () {
this.setTint(0x00ff00);
});
image.on('pointerout', function () {
this.clearTint();
});
this.input.setDraggable(image);
this.input.on('dragstart', function (pointer, gameObject) {
gameObject.setTint(0xff0000);
});
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
console.log(`x: ${dragX}, y: ${dragY}`);
gameObject.x = dragX;
gameObject.y = dragY;
});
this.input.on('dragend', function (pointer, gameObject) {
gameObject.clearTint();
});
}
3)打开控制台,在Eye周围拖拽,看看给出的坐标是什么。
4) 如果删除第 24 行(相机的旋转),一切都会按预期进行。
(示例取自Phaser 3官方示例,针对BUG做了一点修改)
根据 setRotation()
方法中的 Phaser's API Documentation,以弧度表示的旋转适用于相机渲染的所有内容。不幸的是,您的指针不是由相机渲染的,因此它不会获得相同的旋转坐标。不确定这是库的错误还是只是记录不完整的异常,但我相信有解决方法。
创建 2 个变量来保存初始位置和最终位置:
var image = this.add.sprite(200, 300, 'eye').setInteractive();
var initial = [];
var final = [];
在您的 .on('dragstart')
方法中填充初始位置:
this.input.on('dragstart', function (pointer, gameObject) {
initial = [
gameObject.x,
gameObject.y,
pointer.x,
pointer.y
];
gameObject.setTint(0xff0000);
});
然后,在您的 .on('drag')
方法中填充最终变量:
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
final = [
gameObject.x, // not necessary but keeping for variable shape consistency
gameObject.y, // not necessary but keeping for variable shape consistency
pointer.x,
pointer.y
];
gameObject.x = initial[0] + (initial[2] - final[2]);
gameObject.y = initial[1] + (initial[3] - final[3]);
});
我们在这里所做的就是跟踪 pointer
位置的变化并模仿我们 gameObject
的变化。