【问题标题】:Color program from Khanacademy with ProcessingJS来自 Khanacademy 的带有 ProcessingJS 的颜色程序
【发布时间】:2022-10-17 14:48:51
【问题描述】:

最近我偶然发现了大约七年前的这个彩弹射击动画:

https://www.khanacademy.org/computer-programming/paintball-painter/5316001292353536

似乎这是使用 ProcessingJS 构建的,目前已不再维护。 因此,为什么我想再次尝试在 vanilla javascript 中运行它。

当我查看链接中的代码时 - 也发布在此处,我认为我需要自己更改或编码的唯一想法是一开始的 framerate(30)?当我寻找帧速率的内置 API 时,我在 SO answer 中找到了 requestAnimationFrame()。这是要走的路吗?我希望在documenentation 中找到它的实现,但事实并非如此。

//Select your color on the bottom.
//click anywhere to shoot paintballs!

//This program works with modified canvas size. Just make sure you set this variable to the height
var canvasHeight = 400;

//https://www.khanacademy.org/computer-programming/paintball-painter/5316001292353536?width=800&height=600


//0pink, 1red, 2orange, 3yellow, 4green, 5cyan, 6blue, 7purple, 8magenta, 9grey, 10black, 11random
frameRate(30);
var splatDiameter = 40;
var numSpots = 6;
var pcolor = 11;
var pballFrames = [1234, 1234];
var pballXs = [1234, 1234];
var pballYs = [1234, 1234];
var pballColors = [1234, 1234];
var i = 0;
var j = 0;
var k = 0;
var spotXs = [1234, 1234];
var spotYs = [1234, 1234];
var spotColors = [1234, 1234];
var spotTrans = [1234, 1234];
var spotDiameters = [1234, 1234];
canvasHeight -=20;

var drawColorSelector = function(){
noStroke();
fill(255, 100, 130);
rect(0, canvasHeight, 33, 20);
fill(255, 0, 0);
rect(33, canvasHeight, 33, 20);
rect(363, canvasHeight, 37, 3);
fill(255, 140, 0);
rect(66, canvasHeight, 33, 20);
rect(363, canvasHeight + 3, 37, 3);
fill(255, 255, 0);
rect(99, canvasHeight, 33, 20);
rect(363, canvasHeight + 6, 37, 3);
fill(0, 200, 0);
rect(132, canvasHeight, 33, 20);
rect(363, canvasHeight + 9, 37, 3);
fill(0, 150, 150);
rect(165, canvasHeight, 33, 20);
fill(0, 0, 255);
rect(198, canvasHeight, 33, 20);
rect(363, canvasHeight + 12, 37, 3);
fill(150, 0, 150);
rect(231, canvasHeight, 33, 20);
rect(363, canvasHeight + 15, 37, 3);
fill(255, 0, 255);
rect(264, canvasHeight, 33, 20);
fill(150, 150, 150);
rect(297, canvasHeight, 33, 20);
rect(363, canvasHeight + 18, 37, 3);
fill(0, 0, 0);
rect(330, canvasHeight, 33, 20);
textSize(18);
text("?", 377, canvasHeight + 15);
noFill();
stroke(255, 255, 255);
strokeWeight(4);
if(pcolor < 11){
    rect(33 * pcolor, canvasHeight, 33, 20);
}else{
    rect(364, canvasHeight, 35, 20);
} 

};
var selectColor = function(){
    if(mouseIsPressed){
    if(mouseY > canvasHeight){
        if(mouseX < 33){
            pcolor = 0;
        }else if(mouseX < 66){
            pcolor = 1;
        }else if(mouseX < 99){
            pcolor = 2;
        }else if(mouseX < 132){
            pcolor = 3;
        }else if(mouseX < 165){
            pcolor = 4;
        }else if(mouseX < 198){
            pcolor = 5;
        }else if(mouseX < 231){
            pcolor = 6;
        }else if(mouseX < 264){
            pcolor = 7;
        }else if(mouseX < 297){
            pcolor = 8;
        }else if(mouseX < 330){
            pcolor = 9;
        }else if(mouseX < 363){
            pcolor = 10;
        }else{
            pcolor = 11;
        }
    }
}
};

var setFill = function(clr, trans){
    if(clr === 0){
        fill(255, 100, 130, trans);
    }else if(clr === 1){
        fill(255, 0, 0, trans);
    }else if(clr === 2){
        fill(255, 140, 0, trans);
    }else if(clr === 3){
        fill(255, 255, 0, trans);
    }else if(clr === 4){
        fill(0, 200, 0, trans);
    }else if(clr === 5){
        fill(0, 150, 150, trans);
    }else if(clr === 6){
        fill(0, 0, 255, trans);
    }else if(clr === 7){
        fill(150, 0, 150, trans);
    }else if(clr === 8){
        fill(255, 0, 255, trans);
    }else if(clr === 9){
        fill(150, 150, 150, trans);
    }else if(clr === 10){
        fill(0, 0, 0, trans);
    }else{
        fill(random(0, 255), random(0, 255), random(0, 255), trans);
    }
};

var drawPaintball = function(x, y, frames){
    if(frames !== 1234){
        noStroke();
        ellipse(x, y, (11 - frames) * 3, (11 - frames) * 3);
    }
};

var spawnPaintball = function(){
    if(mouseIsPressed && (mouseY < canvasHeight || mouseX > 400)){
        for(i = 0; i < pballXs.length + 1; i += 1){
            if(pballXs[i] === 1234 || ! pballXs[i]){
                pballXs[i] = mouseX;
                pballYs[i] = mouseY;
                if(pcolor === 11){
                    pballColors[i] = floor(random(0, 10));
                }else{
                    pballColors[i] = pcolor;
                }
            pballFrames[i] = 1;
            i = pballXs.length + 2;
    }
}

}
};

var spawnSplat = function(x, y, dia, num, pclrid){
    for(k = 0; k < num; k += 1){
            j = spotXs.length;
            if( ! spotXs[j] || spotXs[j] === 1234){
               if(k === 0){
                   spotXs[j] = x;
                   spotYs[j] = y;
                   spotDiameters[j] = 30;
                   spotColors[j] = pclrid;
                   spotTrans[j] = 255;
               }else{
                   spotXs[j] = x + random(-dia/2, dia/2);
                   spotYs[j] = y + random(-dia/2, dia/2);
                   spotDiameters[j] = random(5, 40);
                   spotColors[j] = pclrid;
                   spotTrans[j] = 255;
               } 
            j = spotXs.length + 2;
            
            }
        
    }
};

var updatePaintball = function(){
    for(i = 0; i < pballXs.length; i += 1){
    if(pballXs[i] !== 1234 && pballXs[i]){
        setFill(pballColors[i], 1000);
        drawPaintball(pballXs[i], pballYs[i], pballFrames[i]);
        pballFrames[i] += 0.4;
        
        if(pballFrames[i] > 11){
            spawnSplat(pballXs[i], pballYs[i], splatDiameter, numSpots, pballColors[i]);
            pballFrames[i] = 1234;
            pballXs[i] = 1234;
            pballYs[i] = 1234;
            pballColors[i] = 1234;
        }
    }
}
};

var updateSpots = function(){
    for(i = 0; i < spotXs.length; i += 1){
    if(spotXs[i] !== 1234 && spotXs[i]){
        noStroke();
        setFill(spotColors[i], spotTrans[i]);
        spotTrans[i] -= 0.75;
        ellipse(spotXs[i], spotYs[i], spotDiameters[i], spotDiameters[i]);
        if(spotTrans[i] < 0){
            spotXs[i] = 1234;
            spotYs[i] = 1234;
            spotTrans[i] = 1234;
            spotDiameters[i] = 1234;
        }
    }
}
};


var draw = function() {
background(255, 255, 255);
selectColor();
spawnPaintball();
updateSpots();
updatePaintball();
drawColorSelector();
};

现在看来,经过一些研究,我可能只需要用自己的实现替换 frameRate(30) 就可以不依赖于 npm 包。我查看了旧的 processingJS 文档,但我找不到他们是如何实现 framerate() 的,所以我可以看到他们的实现,因为我不确定如何实现这个函数,以便彩弹效果可以工作。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    我会推荐p5.js

    p5.j​​s 是对当今网络处理的解释。

    (editor, creative community)

    它还包括frameRate 函数。

    如果您对内部结构感兴趣或想在 vanilla js 中复制它们:frameRate 位于environment.js。它会影响main animation loop(由requestAnimationFrame 驱动)触发绘图的频率。

    编辑:这是一个著名的例子(很多赞成)how to throttle requestAnimationFrame to a specific frame rate

    编辑:您的代码works pretty much out of the box with p5.js。您需要做的就是添加一个初始化画布的setup 函数,并且对frameRate 的调用也需要位于那里:

    function setup() {
      createCanvas(400, 400);
      frameRate(30);
    }
    
    //insert your code
    

    编辑:要开始使用 p5.js,请将您的代码放入文件 sketch.js 并使用以下 HTML:

    <html>
      <head>
        <script src="https://cdn.jsdelivr.net/npm/p5@1.4.2/lib/p5.js"></script>
        <script src="sketch.js"></script>
      </head>
      <body>
        <main>
        </main>
      </body>
    </html>
    

    p5.j​​s Get Started 页面上提供了更多说明。

    【讨论】:

    • 嘿,对不起,我想我在 p5.js 中遗漏了一些东西,但是当我添加初始化画布的设置函数和帧速率调用时,它不能开箱即用? codesandbox.io/s/dreamy-grass-qeb0if?file=/src/index.js感谢frameRate所在的提示,我会深入研究的!
    • 添加了有关入门的信息。看到你的代码工作here
    【解决方案2】:

    我认为当你想使用 Vanilla Javascript 时,你需要实现更多的东西。当我查看代码时,似乎fillrecttextSizetextnoFillstrokenoStrokestrokeWeightcanvasHeight、@98765430 987654331@、mouseXellipsefloorrandom 用于处理.js图书馆。

    【讨论】:

      【解决方案3】:

      将此 ProcessingJS 脚本移植到 p5.js 非常简单:

      https://editor.p5js.org/leftium/sketches/dKt3QEGFJ

      基本上,将framerate(30) 替换为以下代码:

      function setup() {
        createCanvas(400, 400);
        frameRate(30);
      }
      

      为了帮助您在没有 p5.js 的情况下用 vanilla JS 重写:

      【讨论】:

        猜你喜欢
        • 2015-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-16
        • 2020-11-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多