如何在pixi.js中创建具有良好性能的动画tile ?

How do I create an animated tile in pixi.js with good performance?

本文关键字:性能 动画 tile pixi js 创建      更新时间:2023-09-26

我如何使用PIXI js从精灵表动画使用TiledSprites?我需要从精灵表中添加一个平铺精灵背景。

目前有API调用动画平铺精灵在PIXI.js API。我创建了下面的类来帮助我加载和动画平铺背景。

/////////////////////////////////////////////////////////////////////////////
/// Tiling Sprite Animation
/////////////////////////////////////////////////////////////////////////////
(function() {
    PIXI.TilingSpriteAnimation = function(texture, frames, rows, frametime, loop)  {
          PIXI.TilingSprite.call(
            this, texture,
            VIEWPORTWIDTH,
            this._texture.baseTexture.height);
        this._stop = true;
        this._texture = new PIXI.Texture(texture);
        this.frameTime = frametime;
        this.loop = loop || true;
        this.curX = 0;
        this.curY = 0;
        this.fh = this._texture.height / rows;
        this.fw = this._texture.width / frames;
        this.ticks = 0;
        this.maxFrames = frames;
        this.maxRows = rows;
        this.done = false;
        this.calculateFrame();
    };
    PIXI.TilingSpriteAnimation.prototype = Object.create( PIXI.TilingSprite.prototype );
    PIXI.TilingSpriteAnimation.prototype.constructor = PIXI.TilingSpriteAnimation;
    Object.defineProperty(PIXI.TilingSpriteAnimation.prototype, 'texture', {
        get: function() {
            return this._texture;
        }
    });
    PIXI.TilingSpriteAnimation.prototype.update = function() {
        console.log(this.ticks);
        if(!this._stop) {
          this.ticks += 1;
        }
        if (this.done == false) {
            if (this.ticks >= this.frameTime) {
                this.curX++;
                this.ticks = 0;
                if (this.curX == this.maxFrames) {
                    this.curX = 0;
                    this.curY++;
                    if (this.curY == this.maxRows) {
                        this.curY = 0;
                        if (!this.loop)
                            this.done = true;
                    }
                }
                this.calculateFrame();
            }
        }
    };
    PIXI.TilingSpriteAnimation.prototype.goto = function(frame, row) {
        this.curX = frame;
        this.curY = row || 0;
    };
    PIXI.TilingSpriteAnimation.prototype.stop = function() {
        this._stop = true;
    };
    PIXI.TilingSpriteAnimation.prototype.play = function() {
        this._stop = false;
    };
    PIXI.TilingSpriteAnimation.prototype.calculateFrame = function() {
        this.texture.frame.x = this.curX * this.fw;
        this.texture.frame.y = this.curY * this.fh;
        this.texture.frame.width = this.fw;
        this.texture.frame.height = this.fh;
        this.texture.setFrame(this.texture.frame);
        this.generateTilingTexture(this.texture);
    };
}).call(this);
然而,这段代码效率非常低,因为每次进入一个新帧时,它都会计算一个新的TiledTexture。我该如何优化呢?

我为此挣扎了一段时间,但得出了以下结论。我希望这对你有帮助。

/////////////////////////////////////////////////////////////////////////////
/// Tiling Sprite Animation
/////////////////////////////////////////////////////////////////////////////
(function() {
    PIXI.TilingSpriteAnimation = function(texture, frames, frametime, loop)  {
          PIXI.TilingSprite.call(
            this, texture,
            VIEWPORTWIDTH,
            VIEWPORTHEIGHT);
        this._stop = true;
        this._texture = new PIXI.Texture(texture);
        this.frameTime = frametime;
        this.loop = loop || true;
        this.curX = 0;
        this.fh = this._texture.height;
        this.fw = this._texture.width / frames;
        this.ticks = 0;
        this.maxFrames = frames;
        for (var i=0;i<frames;i++){
          this.preLoadFrame(i);
        }
        this.calculateFrame();
    };
    PIXI.TilingSpriteAnimation.prototype = Object.create( PIXI.TilingSprite.prototype );
    PIXI.TilingSpriteAnimation.prototype.constructor = PIXI.TilingSpriteAnimation;
    Object.defineProperty(PIXI.TilingSpriteAnimation.prototype, 'texture', {
        get: function() {
            return this._texture;
        }
    });
    PIXI.TilingSpriteAnimation.prototype.update = function() {
        if (this._stop == false) {
            this.ticks += 1;
            if (this.ticks >= this.frameTime) {
                this.curX++;
                this.ticks = 0;
                if (this.curX == this.maxFrames) {
                    this.curX = 0;
                    if (!this.loop) {
                        this._stop = true;
                    }
                }
                this.calculateFrame();
            }
        }
    };
    PIXI.TilingSpriteAnimation.prototype.goto = function(frame) {
        this.curX = frame;
    };
    PIXI.TilingSpriteAnimation.prototype.stop = function() {
        this._stop = true;
    };
    PIXI.TilingSpriteAnimation.prototype.play = function() {
        this._stop = false;
    };
    PIXI.TilingSpriteAnimation.prototype.calculateFrame = function() {
      this.tilingTexture = PIXI.Texture.fromFrame("texture" + this.curX);
    };
    PIXI.TilingSpriteAnimation.prototype.preLoadFrame = function(frame) {
        var text = new PIXI.TilingSprite(this.texture);
        text.texture.frame.x = frame * this.fw;
        text.texture.frame.y = 0;
        text.texture.frame.width = this.fw;
        text.texture.frame.height = this.fh;
        text.texture.setFrame(text.texture.frame);  
        text.generateTilingTexture(text);
        PIXI.Texture.addTextureToCache(text.tilingTexture, "texture" + frame)
    };
}).call(this);