如何为 p5js 创建动画 class 库

How to create animation class library for p5js

我正在开发一个应用程序,我想使用 p5js 将不同动画叠加到一系列视频上。我希望组织我的 classes 动画类型,以便每个动画都有类似的结构来在每个循环中更新和销毁对象。我的计划是让一组当前 "active" 的动画在循环的每次迭代中更新它们,然后在它们完成时销毁它们。我构建了一个 class 来以这种方式淡化文本,但我得到了一些奇怪的华而不实的行为,每次在另一个动画中间触发一个新动画时似乎都会发生这种行为。我一直在尝试调试它,但没有成功。你有什么建议: (1) 如果这是由于我的代码结构造成的? (也许你有更好的建议), 要么 (2) 我做错了什么?

代码如下:

// create an array of currently executing animations to update 
// each animation class needs to have one function and one attribute: 
//      (1) update() -- function to move the objects where ever they need to be moved
//      (2) done -- attribute to determine if they should be spliced out of the array 
var animations = []; 

//////////////////////////////////////////
// Global Variables for Animations      //
//////////////////////////////////////////


let start = false; 
let count = 0; 

function setup(){
    let canv = createCanvas(1920, 1080); 
    canv.id = "myP5canvas"; 
    background(0);  
}

function draw(){

    background(0); 
    // Check things to see if we should be adding any animations to the picture 
    var drawText = random(100); 
    if (drawText > 98) { 
    //if (start == false) {
        let r = 255; 
        let g = 204; 
        let b = 0; 
        let x = random(width-10); 
        let y = random(height-10); 
        animations.push(new TextFader("Wowwwzers!", 100, 'Georgia', r, g, b, x, y, count)); 
        start = true; 
        count += 1; 
    }



    // Update animations that exist! 
    for (var i=0; i < animations.length; i++) { 
        // update the position/attributes of the animation
        animations[i].update(); 
        // check if the animation is done and should be removed from the array 
        if (animations[i].done) { 
            console.log("SPLICE: " + animations[i].id); 
            animations.splice(i, 1); 
        } 

    }
}


// EXAMPLE ANIMATION 
// TEXT FADE 
let TextFader = function(words, size, font, red, green, blue, xloc, yloc, id) {
    this.id = id; 
    console.log("create fader: " + this.id); 
    // translating inputs to variables 
    this.text = words; 
    this.size = size; 
    this.font = font; 
    // To Do: separating out each of the values until I figure out how to fade separately from the color constructor
    this.red = red; 
    this.green = green; 
    this.blue = blue; 

    this.xloc = xloc; 
    this.yloc = yloc; 

    // Maybe add customization in the future for fading... 
    this.fade = 255; 
    this.fadeTime = 3; // in seconds 
    this.fadeIncrement = 5; 
    // Variables to use for destruction
    this.createTime = millis(); 
    this.done = false; 
}

TextFader.prototype.update = function() { 
    // Update the fade 
    // If the fade is below zero don't update and set to be destroyed 
    this.fade -= this.fadeIncrement; 
    if (this.fade <= 0) { 
        this.done = true; 
    } else { 
        this.show(); 
    }
}

TextFader.prototype.show = function() { 
    textFont(this.font); 
    textSize(this.size); 
    fill(this.red, this.green, this.blue, this.fade); 
    text(this.text, this.xloc, this.yloc);
    console.log("Drawing: " + this.id + " fade: " + this.fade + " done: " + this.done); 
}

耶,我给你答案了!当您反转循环遍历动画的 for 循环时,它会像预期的那样工作。

因为你在循环内拼接了同一个数组的元素,一些元素被跳过了。例如; animations[0].done = true 并被移除。这意味着 animations[1] 现在位于 animations[0] 的位置,而 animations[2] 现在位于 animations[1] 的位置。
i 变量递增到 1,因此在下一个循环中,您更新动画 [1](并跳过现在位于动画 [0] 中的动画)。

当你反转循环时,你拼接的元素之前的所有内容都保持不变,没有任何内容被跳过。
例如; animations[2].done = true 并被移除。这意味着 animations[1] 仍然在 animations[1].
的位置 i 变量递减为 1,因此在下一个循环中,您更新动画 [1] 并且不跳过任何元素。

// Update animations that exist! 
for (var i = animations.length - 1; i >= 0; i--) { 
    // update the position/attributes of the animation
    animations[i].update(); 
    // check if the animation is done and should be removed from the array 
    if (animations[i].done) { 
        //console.log("SPLICE: " + animations[i].id); 
        animations.splice(i, 1); 
    } 

}