所以,我试着创建一个平台游戏,但5天来我遇到了一个碰撞问题,如果我的重力太大(角色从远距离坠落),即使有条件存在,我的物体也会在障碍物(地面)内卡住,当我向左或向右移动时,我可以穿过障碍物,尝试解决这个问题,但它不起作用。
所以,我创建了boundingbox类,它类似于每个障碍物和玩家的阴影(第二个透明对象),用于检查玩家阴影是否与障碍物阴影发生碰撞。
class BoundingBox {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.x2 = this.x + this.width;
this.y2 = this.y + this.height;
}
draw() {
ctx.beginPath();
ctx.save();
ctx.globalAlpha = 0;
ctx.fillRect(this.x, this.y, this.width, this.height);
ctx.restore();
}
update(x, y) {
this.x = x;
this.y = y;
this.x2 = x + this.width;
this.y2 = y + this.height;
}
checkCollision(ob) {
return this.x2 > ob.x && this.x < ob.x2 && this.y2 >= ob.y && this.y < ob.y2;
}
}
角色类和障碍物类包含这些边界框示例类(bbx),它继承这些类的x、y、宽度、高度位置。
class Player {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedX = 1;
this.speedY = 1;
this.leftArrowPressed = false;
this.rightArrowPressed = false;
this.bbx = new BoundingBox(this.x, this.y, this.width, this.height);
this.color = "rgba(255,0,0)";
}
draw() {
ctx.beginPath();
ctx.save();
ctx.fillStyle = this.color;
ctx.strokeStyle = "red";
ctx.stroke();
ctx.fillRect(this.x, this.y, this.width, this.height);
ctx.restore();
this.bbx.draw();
}
update() {
this.handleController();
this.gravity();
this.draw();
this.bbx.update(this.x, this.y);
if (blockCollision(this.bbx, this.x, this.y + this.speedY)) {
while (!blockCollision(this.bbx, this.x, this.y + Math.sign(this.speedY))) this.y -= Math.sign(this.speedY);
this.speedY = 0;
}
if (blockCollision(this.bbx, this.x + this.speedX, this.y)) {
while (!blockCollision(this.bbx, this.x, this.y + Math.sign(this.speedX))) this.y -= Math.sign(this.speedX);
this.speedX = 0;
}
}
gravity() {
this.y += this.speedY;
this.speedY += 0.09; //it's too high and my player can stuck inside an obstacle
}
controll() {
addEventListener("keydown", e => {
if (e.code === "Space") {
this.speedY = -5;
} else if (e.code === "ArrowRight") {
this.speedX = -5;
this.rightArrowPressed = true;
} else if (e.code === "ArrowLeft") {
this.speedX = 5;
this.leftArrowPressed = true;
}
});
addEventListener("keyup", e => {
if (e.code === "ArrowRight") {
this.rightArrowPressed = false;
} else if (e.code === "ArrowLeft") {
this.leftArrowPressed = false;
}
});
}
handleController() {
this.controll();
if (this.leftArrowPressed) {
this.x -= this.speedX;
} else if (this.rightArrowPressed) {
this.x -= this.speedX;
}
}
}
class Block {
constructor(x, y) {
this.x = x;
this.y = y;
this.width = 32;
this.height = 32;
this.bbx = new BoundingBox(this.x, this.y, this.width, this.height);
Block.blocks.push(this);
}
draw() {
ctx.beginPath();
ctx.save();
ctx.fillStyle = "red";
ctx.fillRect(this.x, this.y, this.width, this.height);
this.bbx.draw();
ctx.restore();
}
static blocks = [];
}
有一个函数,它通过每个障碍物形成一个循环,并检查条件:
// check if any block collisions with character
const blockCollision = (bbx, x, y) => {
const lastX = bbx.x;
const lastY = bbx.y;
const collision = Block.blocks.some(block => {
if (block.bbx.checkCollision(bbx)) return true;
});
return collision;
};
暂无答案!
目前还没有任何答案,快来回答吧!