我正在 p5.js 中制作一个游戏,您必须在一组随机放置的圆圈中找到较暗的圆圈。当您单击正确的选项时,它会重新随机化所有内容,然后您可以再次进行。圆圈的位置被放置在一个数组中,该数组在每个“回合”开始时随机化。我需要一种方法来查看玩家是否点击了错误的圆圈,从而删除了一条生命(尚未实现)
这是代码:
function setup() {
createCanvas(600, 450);
background(255);
circles = [];
circleNum = 50
r = random(0, 240)
g = random(0, 240)
b = random(0, 240)
while (circles.length != circleNum+1) {
noStroke();
fill(70, 150, 200, 200)
var overlapping = false;
var circle = {
x: random(width),
y: random(height),
r: 20
}
for (var j = 0; j < circles.length; j++) {
var prev = circles[j];
var circlesDist = dist(circle.x, circle.y, prev.x, prev.y);
if (circlesDist < circle.r + prev.r) {
overlapping = true;
} else if (circle.x < circle.r || circle.x > width-circle.r) {
overlapping = true;
} else if (circle.y < circle.r || circle.y > height-circle.r) {
overlapping = true;
}
}
if (!overlapping) {
circles.push(circle);
}
}
for (var i = 0; i < circles.length; i++) {
fill(r, g, b, 200);
ellipse(circles[i].x, circles[i].y, circles[i].r*2, circles[i].r*2);
}
fill(r, g, b, 200);
ellipse(circles[circleNum].x, circles[circleNum].y, circles[circleNum].r*2, circles[circleNum].r*2);
}
function mousePressed() {
if (dist(mouseX, mouseY, circles[circleNum].x, circles[circleNum].y) < circles[circleNum].r) {
setup();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
我真的不知道如何解决这个问题,所以如果有人可以提供帮助,我会洗耳恭听。
在我看来,你已经具备了所有必要的逻辑——只需在距离检查上添加一个生命计数器和一个
else {}
即可:
let lives;
function setup() {
// ...
lives = 3;
}
function mousePressed() {
if (dist(mouseX, mouseY, circles[circleNum].x, circles[circleNum].y) < circles[circleNum].r) {
setup();
} else {
// the user has clicked elsewhere than the target circle; remove a life
lives--;
if (lives === 0) {
// the user has lost all lives; do something special
}
}
}
顺便说一句,请始终使用
let
或 const
声明变量,以避免与 window
变量发生冲突。如果您在任何地方都没有 foo = 42
或 let
的情况下执行 const
,则会将其添加到全局范围中。
另外,一般不要调用
setup()
——这是由 p5 为你调用的,应该是一次性的画布创建等等。我编写了自定义函数,添加了生命并删除了一些多余的测试:
const circlesToMake = 50;
let circles, r, g, b, lives;
function setup() {
createCanvas(600, 450);
background(255);
noStroke();
setupCircles();
drawCircles();
}
function setupCircles() {
circles = []
lives = 3;
r = random(0, 240)
g = random(0, 240)
b = random(0, 240)
while (circles.length < circlesToMake) {
const circle = {
x: random(width),
y: random(height),
r: 20
};
let overlapping = false;
for (let j = 0; j < circles.length; j++) {
const other = circles[j];
const d = dist(circle.x, circle.y, other.x, other.y);
if (d < circle.r + other.r) {
overlapping = true;
break;
}
}
if (!overlapping) {
circles.push(circle);
}
}
}
function drawCircles() {
clear();
circles.forEach(c => {
fill(r, g, b, 200); ellipse(c.x, c.y, c.r * 2, c.r * 2);
});
fill(0, 0, 0, 200); // make the target easy to identify for development purposes
const target = circles[0];
ellipse(target.x, target.y, target.r * 2, target.r * 2);
text(`lives: ${lives}`, 20, 20);
}
function mousePressed() {
if (dist(mouseX, mouseY, circles[0].x, circles[0].y) < circles[0].r) {
setupCircles();
drawCircles();
} else {
if (--lives === 0) {
setupCircles();
}
drawCircles();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>
为了简单起见,我将
circles[0]
视为目标/深色圆圈。
如果您只想在用户单击有效点而不是空白时减少生命,则可以循环遍历所有圆圈以确保至少有一个圆圈被触摸到
mousePressed
else
块中。
其他游戏重置行为也是可能的,例如将生命从一轮转移到另一轮,显示“游戏结束”屏幕等,但这些超出了当前问题的范围。