【p5.js】模拟烟花效果-交互媒体设计作业

这篇博客介绍了一个基于p5.js库创建烟花放射效果的项目。通过定义Firework、FireworkString和FireworkParticle类,实现了烟花从起点绽放、烟花串的生成以及粒子的运动和消失。在主函数中,利用鼠标点击事件触发烟花生成,并在每一帧中更新和绘制烟花串。项目展示了绚丽多彩的烟花动画效果,为读者提供了互动式的视觉体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【项目介绍】

基于p5.js,模拟烟花的放射效果
参考文章
源码项目

【代码展示】

一、类介绍

  1. 烟花类 包含烟花串对象数组(同时向数组中添加10~50个烟花串对象,每个烟花串起始点相同)、色调(每簇烟花的色相是相同的)
class Firework
{
    constructor(x,y){
        this.H = random(0,239); //色调

        this.stringarray=new Array();
        for(var i=0; i<random(10,50); i++)
            this.stringarray.push(new FireworkString(x,y));
    }
    drawFireworkString(){
        this.stringarray.forEach((tmp)=>{   //遍历粒子串数组并绘制
            tmp.drawFireworkParticle(this.H);
        })
    }
}
  1. 烟花串类 包含一个起始点 FireworkParticle(每串粒子的饱和度和亮度相同,不同串则不同)、可见的烟花粒子队列 Visible(同时压起始点入队)
class FireworkString
{
    constructor(firstX,firstY){
        this.S = random(0,240); //饱和度
        this.B = random(0,240); //亮度
        this.len=random(5,15);  //控制烟花串长度
        //烟花粒子初始化
        this.fireworkparticle=new FireworkParticle(firstX,firstY,random(5,15),
            50,10);
        this.Visible=new Array();
        this.Visible.push(this.fireworkparticle);
    }
    drawFireworkParticle(H){
        this.fireworkparticle.update(); //更新粒子
        tmp=this.fireworkparticle;
        this.Visible.push(new FireworkParticle(tmp.x, tmp.y, tmp.radius,
            tmp.alphaSpeed, tmp.initSpeed));  //入队
        this.Visible.forEach((tmp)=>{   //遍历绘制
            if(!tmp.deleteCheck()){
                //tmp.blinking();
                tmp.draw(H,this.S,this.B);
            }
        })
        if(this.Visible.length>this.len) this.Visible.shift(); //判断出队
    }
}
  1. 烟花粒子类 包含坐标、半径、透明度递减速度、初始速度。颜色模式为HSB,初始化moveXY、alpha。
    update() 用于更新每串烟花粒子下一个粒子的位置并变形外观
    draw() 用于先示该粒子(在alpha或radius降为0该粒子不在粒子队列的情况下,是不会显示的)
//烟花粒子
class FireworkParticle
{
    constructor(x, y,           //坐标
                radius,         //半径
                alphaSpeed,     //透明速度
                initSpeed) {    //初始速度
        colorMode(HSB, 255);
        noStroke(); //取消描边
        this.x = x; this.y = y;
        this.radius = radius;
        this.alpha = 200;
        this.alphaSpeed = alphaSpeed;
        //一开始即确定水平与垂直方向初速度
        this.moveX = random(-initSpeed, initSpeed);
        this.moveY = random(-initSpeed, initSpeed);
    }

    update() {
        //移动
        this.moveX = this.moveX * AirF;
        this.moveY = this.moveY * AirF + Gravity;
        this.x = this.x + this.moveX; 
        this.y = this.y + this.moveY;
        //变形
        this.alpha = this.alpha - this.alphaSpeed;
        this.radius = this.radius - 0.3;
    }

    draw(H,S,B) {
        fill(H, S, B, this.alpha);
        ellipse(this.x, this.y, this.radius, this.radius);
    }

    deleteCheck() {
        if (this.x < 0 || this.x > width || this.y > height || this.radius < 0) {
            return true;
        }
    }
}

二、主函数

画板大小为1000*1000,背景为黑色,鼠标每点击一次,创建一个烟花对象并压入烟花对象数组中。每帧运行时清空画板填充黑色背景,并遍历烟花对象数组,为每一簇烟花绘制其烟花串。

const Gravity=0.5; //重力
const AirF=1;      //空气阻率
var FireworkArray = new Array();
var tmp;

function setup(){ createCanvas(1000, 1000); }
function draw(){
    background(0);
    FireworkArray.forEach((tmp)=>{  //遍历烟花数组并绘制
        tmp.drawFireworkString();
    })
}
//鼠标点击时,在点击处创建烟花
function mouseClicked(){
    var firework=new Firework(mouseX,mouseY);
    FireworkArray.push(firework);
}

每一个烟花串又会绘制其烟花粒子

	drawFireworkString(){
        this.stringarray.forEach((tmp)=>{   //遍历粒子串数组并绘制
            tmp.drawFireworkParticle(this.H);
        })
	}

绘制烟花粒子时,先更新粒子并压入队列,遍历队列绘制每一个粒子(半径为0以及不在画板的粒子不画),最后判断队列是否过长(过长就弹出队首粒子)

drawFireworkParticle(H){
        this.fireworkparticle.update(); //更新粒子
        tmp=this.fireworkparticle;
        this.Visible.push(new FireworkParticle(tmp.x, tmp.y, tmp.radius,
            tmp.blinkingSpeed, tmp.initSpeed));  //入队
        this.Visible.forEach((tmp)=>{   //遍历绘制
            if(!tmp.deleteCheck()){
                //tmp.blinking();
                tmp.draw(H,this.S,this.B);
            }
        })
        if(this.Visible.length>this.len) this.Visible.shift(); //判断出队
    }

三、效果展示

鼠标点击发射烟花

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值