P5.js图像冲突



我最近发现p5.js中的图像冲突与常规矩形冲突有很大不同。如果您希望在不设置image()函数中的手动高度和宽度参数的情况下保持图像的纵横比,则可以使用scale()函数缩放图像。然而,这不会改变图像的面积,因此为了检测碰撞,我必须将图像乘以我设置的图像比例。例如,如果在构造函数中设置,则获取播放器宽度将为playerImage.width * player.scale

所以我已经完成了所有这些,甚至制作了一个函数来显示图像的区域/点击框。然后,当我用碰撞功能设置这个时,底部和右侧可以很好地检测到碰撞,但顶部和左侧的行为似乎很奇怪。

你可以在这里看到发生了什么:https://image-colliding.stcollier.repl.co/

有人知道为什么左边缘和上边缘的碰撞停止了吗?

这是我的问题代码:

let debug = true;
function preload() {
playerImg = loadImage("https://image-colliding.stcollier.repl.co/Player.png")
brickImg = loadImage("https://image-colliding.stcollier.repl.co/brick.jpeg")
}
function setup() {
createCanvas(windowWidth, windowHeight)
player = new Player(windowWidth/2, windowHeight/2, 0.5)
brick = new Brick(windowWidth/10, windowHeight/3, 0.1)
speed = 3;
}
function draw() {
background(200, 200, 200)
push();
brick.display();
pop();
push();
player.display();
pop();
if (debug) {
showRectCollider(player.x, player.y, playerImg.width * player.s, playerImg.height * player.s)
showRectCollider(brick.x, brick.y, brickImg.width * brick.s, brickImg.height * brick.s)
if (player.collidesImg(brick.x, brick.y, brickImg.width, brickImg.height, brick.s)) {
collidingColor = 'green';
} else {
collidingColor = 'red'
}
}
if (keyIsPressed && keyCode === UP_ARROW) {
moveY(player, -speed)
}
if (keyIsPressed && keyCode === DOWN_ARROW) {
moveY(player, speed)
}
if (keyIsPressed && keyCode === LEFT_ARROW) {
moveX(player, -speed)
}
if (keyIsPressed && keyCode === RIGHT_ARROW) {
moveX(player, speed)
}
}
class Player {
constructor(x, y, s) {
this.x = x;
this.y = y;
this.s = s;
}
display() {
translate(this.x, this.y)
scale(this.s)
image(playerImg, 0, 0)
}
collidesFunc1(x, y, w, h) {
if (
this.x - w/2 <= x + w/2 &&
this.x + w/2 >= x - w/2 && 
this.y - h/2 <= y + h/2 && 
this.y + h/2 >= y - h/2) {
return true;
}
else {
return false;
}
}
collidesFunc2(x, y, w, h) {
if (
this.x >= x - w &&
this.x <= x + w &&
this.y >= y - h &&
this.y <= y + h) {
return true;
}
else {
return false;
}
}
collidesImg(x, y, w, h, s) {
if (
this.x >= x - (w * s) &&
this.x <= x + (w * s) &&
this.y >= y - (h * s) &&
this.y <= y + (h * s)) {
return true;
}
else {
return false;
}
}
}
class Brick {
constructor(x, y, s) {
this.x = x;
this.y = y;
this.s = s;
}
display() {
translate(this.x, this.y)
scale(this.s)
image(brickImg, 0, 0)
}
}
//Other functions
var collidingColor = 'red';
function showRectCollider(x, y, w, h) {
noFill();
stroke(collidingColor);
strokeWeight(3);
rect(x, y, w, h)
}
function moveX(object, speed) {
object.x += speed;
}
function moveY(object, speed) {
object.y += speed;
}
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>
</head>
<body>
<script src="script.js"></script>
</body>
</html>

我有三个用于检测碰撞的函数,目前我正在使用我制作的collidesImg()函数。这三个函数都可以在第71-106行找到。

谢谢你的帮助。我真的很感激。

您的冲突逻辑有点偏离,下面是解释性注释:

collidesImg(x, y, w, h, s) {
if (
// right edge of player to the right of left edge of brick
this.x + playerImg.width * this.s >= x &&
// left edge of player to the left of right edge of brick
this.x <= x + (w * s) &&
// bottom edge of player below top edge of brick
this.y + playerImg.height * this.s >= y &&
// top edge of player above bottom edge of brick
this.y <= y + (h * s)) {
return true;
} else {
return false;
}
}

let debug = true;
function preload() {
playerImg = loadImage("https://image-colliding.stcollier.repl.co/Player.png")
brickImg = loadImage("https://image-colliding.stcollier.repl.co/brick.jpeg")
}
function setup() {
createCanvas(windowWidth, windowHeight)
player = new Player(windowWidth / 2, windowHeight / 2, 0.5)
brick = new Brick(windowWidth / 10, windowHeight / 3, 0.1)
speed = 3;
}
function draw() {
background(200, 200, 200)
push();
brick.display();
pop();
push();
player.display();
pop();
if (debug) {
if (player.collidesImg(brick.x, brick.y, brickImg.width, brickImg.height, brick.s)) {
collidingColor = 'green';
} else {
collidingColor = 'red'
}
showRectCollider(player.x, player.y, playerImg.width * player.s, playerImg.height * player.s)
showRectCollider(brick.x, brick.y, brickImg.width * brick.s, brickImg.height * brick.s)
}
if (keyIsPressed && keyCode === UP_ARROW) {
moveY(player, -speed)
}
if (keyIsPressed && keyCode === DOWN_ARROW) {
moveY(player, speed)
}
if (keyIsPressed && keyCode === LEFT_ARROW) {
moveX(player, -speed)
}
if (keyIsPressed && keyCode === RIGHT_ARROW) {
moveX(player, speed)
}
}
class Player {
constructor(x, y, s) {
this.x = x;
this.y = y;
this.s = s;
}
display() {
translate(this.x, this.y)
scale(this.s)
image(playerImg, 0, 0)
}
collidesFunc1(x, y, w, h) {
if (
this.x - w / 2 <= x + w / 2 &&
this.x + w / 2 >= x - w / 2 &&
this.y - h / 2 <= y + h / 2 &&
this.y + h / 2 >= y - h / 2) {
return true;
} else {
return false;
}
}
collidesFunc2(x, y, w, h) {
if (
this.x >= x - w &&
this.x <= x + w &&
this.y >= y - h &&
this.y <= y + h) {
return true;
} else {
return false;
}
}
collidesImg(x, y, w, h, s) {
if (
// right edge of player to the right of left edge of brick
this.x + playerImg.width * this.s >= x &&
// left edge of player to the left of right edge of brick
this.x <= x + (w * s) &&
// bottom edge of player below top edge of brick
this.y + playerImg.height * this.s >= y &&
// top edge of player above bottom edge of brick
this.y <= y + (h * s)) {
return true;
} else {
return false;
}
}
}
class Brick {
constructor(x, y, s) {
this.x = x;
this.y = y;
this.s = s;
}
display() {
translate(this.x, this.y)
scale(this.s)
image(brickImg, 0, 0)
}
}
//Other functions
var collidingColor = 'red';
function showRectCollider(x, y, w, h) {
noFill();
stroke(collidingColor);
strokeWeight(3);
rect(x, y, w, h)
}
function moveX(object, speed) {
object.x += speed;
}
function moveY(object, speed) {
object.y += speed;
}
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>
</head>
<body>
</body>
</html>

最新更新