问题描述
所以,我尝试创建一个平台游戏,但是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;
}
}
Character 类和 Obstacle 类包含这些 BoundingBox 实例类 (bbx),它继承了这些类的 x,height 位置。
class Player {
constructor(x,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.height);
this.color = "rgba(255,0)";
}
draw() {
ctx.beginPath();
ctx.save();
ctx.fillStyle = this.color;
ctx.strokeStyle = "red";
ctx.stroke();
ctx.fillRect(this.x,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.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.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.height);
Block.blocks.push(this);
}
draw() {
ctx.beginPath();
ctx.save();
ctx.fillStyle = "red";
ctx.fillRect(this.x,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;
};
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)