首頁>技術>

我們將保持程式碼短而簡單,因此我們的煙花看起來不會很花哨或不現實 - 實際上,它們將與您在二十年前在Geocities上看到的一樣。但它仍然是一個很好的編碼練習。

主程式[第5-31行]首先宣告變數,然後建立一個煙花物件的陣列。每個煙花都有自己的x和y座標,年齡(自爆炸以來經過的時間),階段(飛行/爆炸)和一系列火花。

每個火花依次具有自己的水平(vx)和垂直(vy)速度,重量決定了它的下降速度和顏色(由紅色,綠色和藍色成分決定)。

在[31]中,我們啟動了主要的動畫功能 - 爆炸[40-75]。此功能更新並繪製每個煙花的每個火花。

[44-62]是爆炸階段。在這個階段,每個火花都有10個矩形的蹤跡。我們根據煙花的座標,火花的速度,爆炸的“年齡”和矩形的索引來計算每個矩形[45-48]的位置。我沒有使用任何彈道公式,相反,我透過反覆試驗得出了這個古怪的[48]。

[49-52]計算每個矩形的顏色,考慮到衰減因子,它是從爆炸的“年齡”得出的 - 爆炸越老,顏色越深。

[53-56]繪製矩形

在[60-61]中,如果爆炸超過100幀,則有5%的機會重置煙花。

重置功能[33-37]將煙花放回螢幕底部的隨機位置,“飛行”階段再次開始。

在這個階段[64-71],煙花在螢幕上移動[64]並且繪製了極其基本的火花尾[65-69]。

在給定的框架中,煙花爆炸的可能性為0.001(相位變化)[71]。 一旦y座標達到200,它肯定會爆炸。

程式碼如下:

<html>

<body style='background-color:black'>

<canvas id='myCanvas' width='800' height='800'></canvas>

<script>

const max_fireworks = 5,

max_sparks = 50;

let canvas = document.getElementById('myCanvas');

let context = canvas.getContext('2d');

let fireworks = [];

for (let i = 0; i < max_fireworks; i++) {

let firework = {

sparks: []

};

for (let n = 0; n < max_sparks; n++) {

let spark = {

vx: Math.random() * 5 + .5,

vy: Math.random() * 5 + .5,

weight: Math.random() * .3 + .03,

red: Math.floor(Math.random() * 2),

green: Math.floor(Math.random() * 2),

blue: Math.floor(Math.random() * 2)

};

if (Math.random() > .5) spark.vx = -spark.vx;

if (Math.random() > .5) spark.vy = -spark.vy;

firework.sparks.push(spark);

}

fireworks.push(firework);

resetFirework(firework);

}

window.requestAnimationFrame(explode);

function resetFirework(firework) {

firework.x = Math.floor(Math.random() * canvas.width);

firework.y = canvas.height;

firework.age = 0;

firework.phase = 'fly';

}

function explode() {

context.clearRect(0, 0, canvas.width, canvas.height);

fireworks.forEach((firework,index) => {

if (firework.phase == 'explode') {

firework.sparks.forEach((spark) => {

for (let i = 0; i < 10; i++) {

let trailAge = firework.age + i;

let x = firework.x + spark.vx * trailAge;

let y = firework.y + spark.vy * trailAge + spark.weight * trailAge * spark.weight * trailAge;

let fade = i * 20 - firework.age * 2;

let r = Math.floor(spark.red * fade);

let g = Math.floor(spark.green * fade);

let b = Math.floor(spark.blue * fade);

context.beginPath();

context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',1)';

context.rect(x, y, 4, 4);

context.fill();

}

});

firework.age++;

if (firework.age > 100 && Math.random() < .05) {

resetFirework(firework);

}

} else {

firework.y = firework.y - 10;

for (let spark = 0; spark < 15; spark++) {

context.beginPath();

context.fillStyle = 'rgba(' + index * 50 + ',' + spark * 17 + ',0,1)';

context.rect(firework.x + Math.random() * spark - spark / 2, firework.y + spark * 4, 4, 4);

context.fill();

}

if (Math.random() < .001 || firework.y < 200) firework.phase = 'explode';

}

});

window.requestAnimationFrame(explode);

}

</script>

</body>

</html>

20
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • python