如何使用mouseX和mouseY移除p5.play中的移动Sprite
解决p5.play中点击移动Sprite的问题
问题分析
你当前代码的核心问题:
- 全局变量
enemy被反复覆盖,导致点击操作永远只作用于最后创建的那个敌人,而非你点击到的目标 spriteClicked里的坐标判断语法完全错误,逗号运算符和逻辑与的混用没有实现“鼠标在Sprite范围内”的判断- 在
draw()里检测mouseIsPressed会导致每帧重复执行,容易出现误触发
修正方案
1. 移除全局enemy变量,改用遍历Sprite组检测点击
p5.play的Sprite对象自带位置属性(position.x/position.y)和碰撞检测方法,直接利用这些特性更可靠:
let spawnTimer = 0; let spritegroup; // 提前声明组变量 function setup() { createCanvas(900, 900); spritegroup = new Group(); // clickedgroup如果没用到可以暂时注释 // clickedgroup = new Group(); } function draw() { background(255); spritegroup.cull(20); // clickedgroup.cull(20); spawnSprites(); drawSprites(); } function spawnSprites() { if (spawnTimer === 60) { for (let i = 0; i < 2; i++) { const x = random(50, 850); // 修正y轴初始位置,之前的sin计算会导致y值过小,敌人从顶部外缓慢进入 const y = -100; createEnemy(3, x, y); } spawnTimer = 0; } spawnTimer++; } function createEnemy(type, x, y) { // 用局部变量存储新创建的敌人,不再覆盖全局变量 const enemy = createSprite(x, y); // 原代码中enemy[floor(random(0,4))]是无效操作,删除 enemy.setSpeed(3.5 - type / 2, 90); spritegroup.add(enemy); enemy.setCollider("rectangle", 0, 0, 100, 100); enemy.debug = true; // 可以给敌人设置颜色方便区分 enemy.shapeColor = color(random(255), random(255), random(255)); return enemy; } // 改用p5.js的mousePressed函数,只在点击瞬间触发一次 function mousePressed() { // 遍历所有敌人Sprite,检查鼠标是否在其碰撞范围内 for (const enemy of spritegroup) { // 用Sprite的overlapPoint方法检测鼠标是否在Sprite上 if (enemy.overlapPoint(mouseX, mouseY)) { enemy.remove(); // 找到点击的敌人后跳出循环,避免一次点击删除多个 break; } } }
关键修正点说明
- 移除全局
enemy变量:每次创建敌人用局部变量存储,避免后续创建的敌人覆盖之前的引用 - 使用
mousePressed()替代draw()内的检测:确保点击操作只在鼠标按下的瞬间触发一次,而非每帧重复检测 - 利用
overlapPoint()方法:p5.play内置的碰撞检测方法,直接判断鼠标坐标是否在Sprite的碰撞范围内,比手动计算坐标更准确 - 修正敌人初始位置:原代码的y轴计算会导致敌人从屏幕外极慢进入,改为
-100让敌人从顶部外快速进入视野
额外提示
- 如果需要获取任意Sprite的坐标,直接访问
sprite.position.x和sprite.position.y即可,比如遍历组时可以打印每个敌人的位置:for (const enemy of spritegroup) { console.log("敌人位置:", enemy.position.x, enemy.position.y); } debug模式开启后,你可以看到Sprite的碰撞范围,方便调试点击是否命中
内容的提问来源于stack exchange,提问作者TheBigStivz
相关产品推荐
相关产品推荐

