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

p5.js弹跳变色小球颜色被背景矩形覆盖问题求助

解决p5.js中小球撞边变色后被盒子fill覆盖的问题

你的问题根源在于p5.js的全局绘图状态:innerRect()函数里设置的fill(71, 71, 71)会覆盖之前changeColor()设置的填充色,而你当前的draw()顺序是先绘制背景(包含灰色盒子),再处理小球移动,最后画小球——此时绘图状态的fill还是盒子的灰色,所以小球会被画成灰色。

修复方案

  1. 用变量存储小球的颜色,而非直接通过fill()设置全局状态
  2. 每次绘制小球前,主动设置小球的颜色,避免被其他绘图操作的fill覆盖

修改后的完整代码

// Bounce1
// 完美弹跳的小球,不会减速

// 画布和内部盒子参数
let canvasW = 900;
let canvasH = 700;
let innerborder = 100;

// 小球的位置、大小、速度
let positionX = 300;
let positionY = 300;
let radius = 20;
let velocityX = 3;
let velocityY = 5;

// 存储小球颜色,初始设一个默认色
let ballColor = color(255, 0, 0);

function setup() {
  createCanvas(canvasW, canvasH);
}

function draw() {
  drawBackground();
  moveBall();
  drawBall();
}

function drawBackground(){
  background(220);
  innerRect();
}

function innerRect(){
  fill(71, 71, 71);
  rect(innerborder, 100, 700, 500);
}

function moveBall(){
  // 更新小球位置
  positionX += velocityX;
  positionY += velocityY;

  const rightEdge = width - 100;
  const leftEdge = 0 + 100;
  const topEdge = 0 + 100;
  const bottomEdge = height - 100;

  // 检测碰撞并反弹
  if (positionX + radius > rightEdge) {
    velocityX *= -1;
    positionX = rightEdge - radius;
    changeColor();
  }
  else if (positionX - radius < leftEdge) {
    velocityX *= -1;
    positionX = leftEdge + radius;
    changeColor();
  }

  if (positionY + radius > bottomEdge) {
    velocityY *= -1;
    positionY = bottomEdge - radius;
    changeColor();
  }
  else if (positionY - radius < topEdge) {
    velocityY *= -1;
    positionY = topEdge + radius;
    changeColor();
  }
}

function drawBall(){
  // 绘制小球前主动设置颜色
  fill(ballColor);
  ellipse(positionX, positionY, radius * 2, radius * 2);
}

function changeColor(){
  // 生成随机颜色并赋值给ballColor变量
  let r = random(0, 255);
  let g = random(0, 255);
  let b = random(0, 255);
  ballColor = color(r, g, b);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>

关键改动说明

  • 新增ballColor变量专门存储小球的颜色,避免全局fill状态被其他绘图操作干扰
  • changeColor()不再直接调用fill(),而是更新ballColor的值
  • drawBall()每次绘制前都会设置fill(ballColor),确保小球用自己的颜色绘制
  • 移除了原代码中多余的change变量和noFill()逻辑,简化了碰撞处理流程

内容的提问来源于stack exchange,提问作者Hbomb02

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:39:38