You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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,当变量达到所有元素完全移出画布的帧数(动画周期)时重置:

  1. 声明全局变量animationStep并初始化为0;
  2. 在draw()中用animationStep替换所有frameCount;
  3. 每帧结束后递增animationStep;
  4. 当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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:30:46