如何扩展 PixiJS v7 Container 类?

问题描述 投票:0回答:1

我正在尝试将文字游戏从 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. 中读取它?

javascript typescript javascript-objects pixi.js
1个回答
0
投票

我准备了 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();
© www.soinside.com 2019 - 2024. All rights reserved.