我正在尝试将文字游戏从 Pixi.js 版本 6.5.9 移植到 7.2.3:
在游戏中我使用自定义类
Tile.js
来表示黄色可拖动字母方块:
'use strict';
function Tile(letter, value) {
PIXI.Container.call(this); // Uncaught TypeError: Class constructor _Container cannot be invoked without 'new'
this.col = NaN;
this.row = NaN;
this.letter = letter;
this.value = value;
// is this tile being dragged?
this.drag = false;
this.graph = new PIXI.Graphics();
this.addChild(this.graph);
this.letterText = new PIXI.Text('', {fontFamily: 'Arial', fontSize: 40, fill: 0x000000});
this.letterText.anchor.set(0.5);
this.addChild(this.letterText);
this.indexText = new PIXI.Text('', {fontFamily: 'Arial', fontSize: 20, fill: 0x000000});
this.indexText.anchor.set(1);
this.addChild(this.indexText);
this.setLetter(letter);
this.setValue(value);
}
该类使用以下代码扩展了
PIXI.Container
类:
Tile.prototype = Object.create(PIXI.Container.prototype);
Tile.prototype.constructor = Tile;
然后为了实现拖动我添加了方法:
Tile.prototype.setIteractive = function(onDragStart, onDragMove, onDragEnd) {
this.eventMode = 'static'; // previously: this.interactive = true;
this.buttonMode = true;
// it is important to set hitArea, otherwise pointerdown will be called on wrong tiles
this.hitArea = new PIXI.Rectangle(0, 0, Tile.WIDTH, Tile.HEIGHT);
this.on('pointerdown', onDragStart)
.on('pointermove', onDragMove)
.on('pointerup', onDragEnd);
};
Tile.prototype.startDragging = function() {
this.drag = true;
this.scale.x = 1.4;
this.scale.y = 1.4;
this.alpha = 0.9;
};
Tile.prototype.stopDragging = function() {
this.drag = false;
this.scale.x = 1;
this.scale.y = 1;
this.alpha = 1;
};
从 Pixi.js 版本 6.5.9 升级到 7.2.3 后,我在 Edge 浏览器控制台中收到以下错误:
Uncaught TypeError: Class constructor _Container cannot be invoked without 'new'
我扩展
Container
类的方式是否已被弃用?
我在 Github 上搜索了 试图理解如何正确扩展 PixiJS v7 中的类...我试图理解
Container
是如何扩展DisplayObject
的,但它的语法非常不同(也许是因为它是打字稿?)...
更新:
我已经尝试了@domis86 的建议并重写了我的自定义
Tile.js
类以拥有一个PIXI.Container 成员:
function Tile(letter, value) {
var _col = NaN;
var _row = NaN;
var _letter = letter;
var _value = value;
// is this tile being dragged?
var _drag = false;
var _cont = new PIXI.Container();
_cont.eventMode = 'static';
_cont.buttonMode = true;
// the following line does not work, is undefined
_cont.tile = this;
var _graph = new PIXI.Graphics();
_cont.addChild(_graph);
var _letterText = new PIXI.Text('', {fontFamily: 'Arial', fontSize: 40, fill: 0x000000});
_letterText.anchor.set(0.5);
_cont.addChild(_letterText);
var _indexText = new PIXI.Text('', {fontFamily: 'Arial', fontSize: 20, fill: 0x000000});
_indexText.anchor.set(1);
_cont.addChild(_indexText);
setLetter(letter);
setValue(value);
function getContainer() {
return _cont;
}
function setIteractive(onDragStart, onDragMove, onDragEnd) {
_cont.eventMode = 'static';
_cont.buttonMode = true;
setDrawSides(true, true, true, true);
// it is important to set hitArea, otherwise pointerdown will be called on wrong tiles
_cont.hitArea = new PIXI.Rectangle(0, 0, WIDTH, HEIGHT);
_cont.on('pointerdown', onDragStart)
.on('pointermove', onDragMove)
.on('pointerup', onDragEnd);
}
function startDragging() {
_drag = true;
_cont.scale.x = 1.4;
_cont.scale.y = 1.4;
_cont.alpha = 0.9;
redraw();
}
function stopDragging() {
_drag = false;
_cont.scale.x = 1;
_cont.scale.y = 1;
_cont.alpha = 1;
redraw();
}
...more methods here...
// return the public methods
return {
getContainer: getContainer,
setIteractive: setIteractive,
startDragging: startDragging,
stopDragging: stopDragging,
...
redraw: redraw
};
}
问题是,当拖动
Tile
实例时,现在会在pointerdown
上调用_cont
和其他事件,而不是在Tile
实例本身上调用 - 然后我不知道如何访问字母拼贴的附加属性(如_letter
、_value
、_col
、_row
):
function onDragStart(ev) {
this.data = ev.data;
var pos = this.data.getLocalPosition(this.parent);
this.x = pos.x - this.width / 2;
this.y = pos.y - this.height / 2;
// put the tile on top
app.stage.removeChild(this);
app.stage.addChild(this);
// the following line gives error because PIXI.Container does not have the method
this.startDragging();
// here I only have access to the _cont through "this"
// but how to access the _letter, _value of the tile?
}
我尝试通过以下方式将
.tile
属性添加到 _cont
:
_cont.tile = this;
但是当我尝试在
undefined
中访问
this.tile
时,它给了我
onDragStart
更新 2:
PixiJS Elementals 教程提到有一种方法可以将自定义对象(在我的例子中是
Tile
实例)传递给鼠标事件:
向输入添加事件侦听器的基本结构是: yourObject.on("stringOfWhatYouWantToKnow", functionToBeCalled, contextForTheFunction)
但是如何将它添加到我的代码中,因为
this
似乎未定义以及如何在 onStartDrag()
etc. 中读取它?
我准备了 jsfiddle :
https://jsfiddle.net/k1qr5m8g/
(来自用户 bigtimebuddy 的修改示例来自问题“在 v7 中实现拖动的建议方式是什么?”-https://github.com/pixijs/pixijs/discussions/8813#discussioncomment-4038065)
请运行它并观察浏览器控制台。单击矩形(精灵)后,您应该会看到类似的内容:
called Tile.getMyValue() - value: 123
dumping "this":
Object { iAmTile: true }
PixiJS Elementals 教程提到有一种方法可以将自定义对象(在我的例子中是 Tile 实例)传递给鼠标事件:
注意这个代码片段:
// Here we are passing the "that" (aka: original "this" of Tile object instance) as third argument.
// It will cause "this" inside getMyValue function to point to the Tile instance.
sprite.on('pointerdown', getMyValue, that);
如您在 https://www.pixijselementals.com/#getting-interactive 中看到的那样,要将它与直接“这个”(没有“那个”)一起使用,您需要将代码转换为 ES6 类,我认为 -我推荐。
顺便说一句:在您的代码中,您是否使用“new”关键字创建了 Tile 对象的实例?请参阅 jsfiddle 末尾:
var tileInstance = new Tile('A', 123, app);
tileInstance.initializeInteractiveListeners();