p5.js实现物体向移动目标移动/引力吸附及射击系统开发技巧
僵尸游戏功能实现思路与代码优化
僵尸自动追踪玩家实现
- 核心逻辑通过方向向量计算实现,不需要手动写复杂三角函数,适配p5.js运行环境
- 具体实现步骤:
- 每一帧先计算玩家和僵尸的坐标差:
let dx = player.x - zombie.x; let dy = player.y - zombie.y; - 计算两者间距,转换为单位向量保证移动速度恒定:
let distance = dist(player.x, player.y, zombie.x, zombie.y); let vx = dx / distance * zombie.speed; let vy = dy / distance * zombie.speed; - 把计算出的速度分量加到僵尸坐标上完成移动:
zombie.x += vx; zombie.y += vy;
- 每一帧先计算玩家和僵尸的坐标差:
- 注意事项:要先判断间距大于1再执行移动逻辑,避免距离为0时出现除以0的报错
射击系统实现
- 首先全局定义子弹数组存储所有飞行中的子弹:
let bullets = []; - 每个子弹设置三个核心属性:坐标、飞行速度分量、伤害值
- 监听鼠标点击触发射击,子弹方向指向点击位置:
function mousePressed() { let dx = mouseX - player.x; let dy = mouseY - player.y; let distance = dist(mouseX, mouseY, player.x, player.y); let bulletSpeed = 10; // 新增子弹存入数组 bullets.push({ x: player.x, y: player.y, vx: dx / distance * bulletSpeed, vy: dy / distance * bulletSpeed, damage: 25 }) }
- 把子弹更新和碰撞检测逻辑写在
draw函数中,注意从后往前遍历数组避免删除元素时出现索引错位:
for (let i = bullets.length - 1; i >= 0; i--) { let b = bullets[i]; // 更新子弹位置 b.x += b.vx; b.y += b.vy; // 绘制子弹 fill('yellow'); ellipse(b.x, b.y, 5, 5); // 检测子弹和僵尸碰撞 if (dist(b.x, b.y, zombie.x, zombie.y) < 15) { zombie.health -= b.damage; bullets.splice(i, 1); // 僵尸死亡逻辑:轮数+1,刷新僵尸属性 if (zombie.health <= 0) { round++; zombie.x = random(width); zombie.y = random(height); zombie.health = 150 + 100 * Math.min(round - 1, 8); } continue; } // 删除超出画布的子弹避免内存占用过高 if (b.x < 0 || b.x > width || b.y < 0 || b.y > height) { bullets.splice(i, 1); } }
现有代码问题修复
- 当前代码绘制僵尸时y坐标减了200,会导致显示位置和碰撞检测位置不一致,直接修改为
rect(zombie.x, zombie.y, 20, 20);即可 - 现有死亡判定阈值设置过大,建议改为距离小于20(玩家和僵尸的碰撞半径之和)才触发扣血,避免玩家还没碰到僵尸就判定死亡:
let touchDistance = dist(player.x, player.y, zombie.x, zombie.y); if (touchDistance <= 20) { // 按时间扣血避免帧率影响扣血速度 player.health -= zombie.damage * (deltaTime / 1000); if (player.health <= 0) { background(0); textSize(20); text('You died \n Round '+round,165,200); noLoop(); // 停止游戏运行 } }
内容的提问来源于stack exchange,提问作者yesimaperson55665
相关产品推荐
相关产品推荐

