我正在学习p5.js,我遇到了一个我无法解决的问题。 所以,我正在制作这个小游戏,你必须射击敌人并躲避他们的技能。这是看起来如何:
在右侧,我们有玩家,中间是子弹(用阵列处理),左侧是敌人(阵列)。敌人和子弹都有自己的对象。 这是产生敌人和子弹的代码:
对于子弹
function shoot() {
x = p.x + 6.5;
y = p.y + 12.5;
bullets.push(new Bullet(x, y));
}
对于敌人:
function spawnEnemies() {
let x = 650;
let y = 30;
for (let i = 0; i < 14; i++) {
enemies.push(new Enemy(x, y));
y += 40
}
}
我要做的是在子弹到达目标时检测碰撞。这是我尝试的方式:
// check hit
for (let i = 0; i < bullets.length; i++){
for (let j = 0; j < enemies.length; j++){
let d = dist(bullets[i].x, bullets[i].y, enemies[j].x, enemies[j].y)
if (d < 1){
console.log('hit');
}
}
}
check hit
代码位于p5的draw
函数内部,因此会连续执行。任何人都可以帮助我吗?
提前谢谢!
答案 0 :(得分:1)
您可以检查draw
循环内的碰撞。使用圆圈很简单,您可以检查距离是否小于两个元素半径DEMO
dist < circleOne.radius + circleTwo.radius
但是既然你有正方形,那么因为size != diagonal
会更加困难,所以代码可能看起来像这样。 DEMO
if (Math.abs(this.position.x - player.position.x) < this.size/2 + player.size/2 && Math.abs(this.position.y - player.position.y) < this.size/2 + player.size/2) collision = true;
此处我使用p5.Vector
作为职位,但您不必使用dist
代替p5.Vector.dist
const targets = [];
let player = null;
let canvas = null;
function setup() {
canvas = createCanvas(400, 400);
player = new Player(0, 0, 30, 'green');
for (var i = 0; i < 10; i++) {
const w = random(width);
const h = random(height);
const size = random(5, 40);
targets.push(new Target(w, h, size, 'blue'));
}
canvas.mouseMoved(function() {
player.position.x = mouseX;
player.position.y = mouseY;
})
}
function draw() {
background(220);
player.show()
targets.forEach(target => {
target.show();
target.hit(player)
})
}
class Element {
constructor(x, y, size, color) {
this.x = x;
this.y = y;
this.size = size;
this.color = color;
this.position = new p5.Vector(this.x, this.y);
}
show() {
fill(this.color);
rectMode(CENTER)
rect(this.position.x, this.position.y, this.size, this.size)
}
}
class Player extends Element {}
class Target extends Element {
hit(player) {
let collision = false;
if (Math.abs(this.position.x - player.position.x) < this.size / 2 + player.size / 2 && Math.abs(this.position.y - player.position.y) < this.size / 2 + player.size / 2) collision = true;
else collision = false;
if (collision) this.color = 'red';
else this.color = 'blue';
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>
要检测两个元素数组之间的冲突,可以使用嵌套的for
循环,因为您需要检查第一个数组中的任何元素是否与第二个数组中的任何元素冲突。
const targets = [];
const bullets = [];
let canvas = null;
function setup() {
canvas = createCanvas(400, 400);
for (var i = 0; i < 10; i++) {
const w = random(width);
const h = random(height);
const size = random(5, 50);
targets.push(new Target(w, h, size, 'blue'));
}
for (var j = 0; j < 30; j++) {
const w = random(width);
const h = random(height);
const size = random(5, 20);
bullets.push(new Bullet(w, h, size, 'green'));
}
}
function draw() {
background(220);
bullets.forEach(bullet => {
bullet.show();
bullet.move();
});
for (var i = 0; i < targets.length; i++) {
for (var j = 0; j < bullets.length; j++) {
const hit = targets[i].hit(bullets[j]);
if (hit) {
targets[i].color = 'red';
break;
} else targets[i].color = 'blue'
}
}
targets.forEach(target => target.show());
}
class Element {
constructor(x, y, size, color) {
this.x = x;
this.y = y;
this.size = size;
this.color = color;
this.position = new p5.Vector(this.x, this.y);
}
show() {
const c = color(this.color);
c.setAlpha(150);
fill(c);
rectMode(CENTER)
rect(this.position.x, this.position.y, this.size, this.size)
}
}
class Bullet extends Element {
move() {
this.position.add(p5.Vector.random2D())
}
}
class Target extends Element {
hit(player) {
if (Math.abs(this.position.x - player.position.x) < this.size / 2 + player.size / 2 && Math.abs(this.position.y - player.position.y) < this.size / 2 + player.size / 2) return true;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>