JavaScript类间访问问题:p5js打砖块游戏碰撞报错排查
解决p5.js打砖块游戏中Ball与Brick碰撞的
Cannot read properties of undefined错误 错误根源
报错TypeError: Cannot read properties of undefined (reading 'brickX')明确说明:调用Ball.collide(brick)时,传入的brick参数是undefined,导致代码试图访问不存在对象的brickX属性。
常见触发场景及修复步骤
- 缺少砖块数组及初始化
你当前代码里没有定义存储砖块的数组,也没有创建Brick实例。首先添加全局数组并在setup()中生成砖块:
let allBricks = []; // 新增全局变量 function setup() { createCanvas(600, 400); // 生成一行示例砖块 for (let i = 0; i < 6; i++) { allBricks.push(new Brick(i * 100, 40, 90, 30)); } new Ball(300, 300, 12, 2, -2); // 创建初始球 }
- 调用collide时未确保brick有效
在draw()中遍历球和砖块时,要跳过已销毁的砖块,且确保遍历的是有效的Brick实例:
function draw() { background(220); // 绘制 paddle rect(paddlex, 360, 100, 20); // 处理球的移动、绘制及碰撞检测 for (let ball of allBalls) { if (!ball.alive) continue; ball.move(); ball.show(); // 遍历存活砖块检测碰撞 for (let brick of allBricks) { if (brick.brickAlive) { ball.collide(brick); } } } // 绘制所有砖块 for (let brick of allBricks) { brick.display(); } // 控制 paddle 移动 if (keyIsDown(LEFT_ARROW)) paddlex = max(0, paddlex - paddlespeed); if (keyIsDown(RIGHT_ARROW)) paddlex = min(width - 100, paddlex + paddlespeed); }
- 完善collide方法的安全性与碰撞逻辑
原碰撞逻辑仅判断了部分边界,容易出现误判,且未做参数有效性校验。修改collide方法:
collide(brick){ // 先校验brick是否有效,直接返回避免错误 if (!brick || !brick.brickAlive) return; // 更准确的圆形-矩形碰撞检测 // 计算球心到砖块矩形的最近点 const closestX = constrain(this.x, brick.brickX, brick.brickX + brick.brickW); const closestY = constrain(this.y, brick.brickY, brick.brickY + brick.brickH); // 计算距离平方(避免开根号提升性能) const distX = this.x - closestX; const distY = this.y - closestY; const distSq = distX * distX + distY * distY; if (distSq < (this.w / 2) ** 2) { brick.brickAlive = false; // 碰撞后球反弹(可根据碰撞方向调整,这里先简单反转Y方向) this.ydir *= -1; } }
额外注意点
- 确保
allBalls和allBricks数组中不会混入undefined元素,创建实例时直接push到数组即可 - 当球销毁后(
alive=false),可以考虑从allBalls数组中移除,避免无效遍历
内容的提问来源于stack exchange,提问作者Cole Bechtel
相关产品推荐
相关产品推荐

