如何在p5.js中实现汽车消失后draw函数动画的循环重启?
在p5.js中实现汽车动画循环播放的解决方案
问题描述
我使用p5.js编写了一段通过draw函数绘制的汽车动画代码,希望当所有汽车从画布消失后自动重启动画。尝试用while循环实现但未成功,以下是原动画代码及尝试的错误代码,寻求解决方案。
原动画代码
JavaScript代码
function setup() { createCanvas(500, 400); frameRate (50) } function draw() { background(220); fill (250,250, 250); ellipse (frameCount, 200, 50); ellipse (frameCount, 220, 50); ellipse (frameCount + 180, 215, 50); ellipse (frameCount + 180, 230, 50); fill (250,0, 0); rect (frameCount, 140, 210, 70, 0, 100, 100, 100); fill(250, 250, 250) ellipse ( 470 - frameCount, 80, 50) fill(250, 250, 250) ellipse ( 290 - frameCount, 80, 50) fill (0, 0, 0); rect ( 280 - frameCount,10, 200, 70, 100, 0, 100, 100); fill(250, 250, 250) ellipse ( 290 - frameCount, 90, 50) fill(250, 250, 250) ellipse ( 450 - frameCount, 90, 50) fill (0, 0, 0) circle (210, 565 - frameCount, 50) fill (220, 220, 220) circle (210, 563 - frameCount, 15) fill (0, 0, 0) circle (270, 565 - frameCount, 50) fill (220, 220, 220) circle (270, 563 - frameCount, 15) fill (0, 0, 0) circle (200, 671 - frameCount, 50) fill (220, 220, 220) circle (200, 671 - frameCount, 15) fill (0, 0, 0) circle (280, 670 - frameCount, 50) fill (220, 220, 220) circle (280, 671 - frameCount, 15) fill (0, 0, 250) rect (200, 550 - frameCount, 80, 130, 100, 100, 0, 0); fill (0, 0, 0) circle (700,700, frameCount) }
CSS代码
html, body { margin: 0; padding: 0; } canvas { display: block; }
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/addons/p5.sound.min.js"></script>
错误尝试代码
function setup() { createCanvas(500, 400); frameRate (50) } function draw() { background(220); fill (250,250, 250); ellipse (frameCount, 200, 50); ellipse (frameCount, 2... } i = 0 while (i = 0) { setup(); draw(); }
解决方案
问题原因
p5.js的setup()仅需执行一次,用于初始化画布;draw()由引擎自动按设定帧率循环调用。手动用while循环调用这两个函数会阻塞浏览器主线程,无法正常渲染动画,同时重复执行setup()会多次创建画布引发异常。另外原代码直接使用持续递增的frameCount作为动画参数,导致动画无法循环。
修改方案
自定义动画进度变量替代frameCount,当变量达到所有元素完全移出画布的帧数(动画周期)时重置:
- 声明全局变量
animationStep并初始化为0; - 在
draw()中用animationStep替换所有frameCount; - 每帧结束后递增
animationStep; - 当
animationStep超过710(经计算的最大周期,确保所有汽车完全移出画布)时重置为0。
修改后的完整JavaScript代码
let animationStep = 0; // 自定义动画进度变量 function setup() { createCanvas(500, 400); frameRate(50); } function draw() { background(220); fill(250,250, 250); ellipse(animationStep, 200, 50); ellipse(animationStep, 220, 50); ellipse(animationStep + 180, 215, 50); ellipse(animationStep + 180, 230, 50); fill(250,0, 0); rect(animationStep, 140, 210, 70, 0, 100, 100, 100); fill(250, 250, 250); ellipse(470 - animationStep, 80, 50); ellipse(290 - animationStep, 80, 50); fill(0, 0, 0); rect(280 - animationStep,10, 200, 70, 100, 0, 100, 100); fill(250, 250, 250); ellipse(290 - animationStep, 90, 50); ellipse(450 - animationStep, 90, 50); fill(0, 0, 0); circle(210, 565 - animationStep, 50); fill(220, 220, 220); circle(210, 563 - animationStep, 15); fill(0, 0, 0); circle(270, 565 - animationStep, 50); fill(220, 220, 220); circle(270, 563 - animationStep, 15); fill(0, 0, 0); circle(200, 671 - animationStep, 50); fill(220, 220, 220); circle(200, 671 - animationStep, 15); fill(0, 0, 0); circle(280, 670 - animationStep, 50); fill(220, 220, 220); circle(280, 671 - animationStep, 15); fill(0, 0, 250); rect(200, 550 - animationStep, 80, 130, 100, 100, 0, 0); fill(0, 0, 0); circle(700,700, animationStep); // 递增进度,达到周期后重置 animationStep++; if (animationStep > 710) { animationStep = 0; } }
内容的提问来源于stack exchange,提问作者Mitko.Vtori
相关产品推荐
相关产品推荐

