背景信息:我正在使用HTML5画布制作一个非常基本的2D平台游戏。 在我的主游戏循环中,我遍历所有对象以检查玩家是否站在一个物体上。如果是这样,我结束函数的执行直到下一个循环。
如果对象和玩家发生碰撞,在使用return
退出该功能之前(因为我们知道玩家正站在该对象上),我在Y轴上设置了玩家的速度为0,稍微调整他的Y位置只是为了正确对齐他和对象,并将玩家的属性player.grounded
设置为true。这是主要问题所在。它是与player.isFalling
属性绑定的必需布尔值。更新功能检查玩家的Y速度是否高于0并检查他是否未接地。在那种情况下player.isFalling
是真的。仅当isFalling
为真时,才会执行standingCheck辅助函数。
const standingCheckHandler = (player) => {
for(let i = 0; i < objects.length; i ++){
if(standingCheck(player, objects[i])){
player.pos.y = objects[i].pos.y - player.height;
player.velocity.y = 0;
player.grounded = true;
return;
}else{
player.grounded = false;
}
}
}
现在出现问题:即使我退出函数,或使用break
,循环仍然继续迭代其他对象。我会记录player.grounded
,甚至在设置为true
之后(这意味着函数应该自行退出,对吗?),它将继续循环其他对象并设置{{ 1}}到player.grounded
,这导致游戏本身的狡猾的运动。 (从理论上讲它是有效的,但是玩家继续上下浮动,这并不是一个很好的景象)。
我尝试过各种各样的事情。使用新属性,计算玩家可以站立的对象数量,似乎没有任何效果。我觉得我忽略了某些东西,但我不确定那可能是什么。
(抱歉文字墙!)
更新:这是standCheck方法:
false
答案 0 :(得分:1)
我想我找到了答案。虽然它没有直接修复bug,但我设法通过引入一个新的帮助函数来解决这个问题:
groundedCheck
与standingCheck
大致相同。它基本上只检查玩家是否有效地仍然接地(如果player.y + player.height等于object.y)。
可能 肯定是一种更快捷的方式,但现在可以使用。
我是如何解决的:
const standingCheckHandler = (player) => {
for(let i = 0; i < objects.length; i ++){
if(standingCheck(player, objects[i])){
player.pos.y = objects[i].pos.y - player.height;
player.velocity.y = 0;
player.grounded = true;
break;
}
}
// this is new
if(player.grounded){
let len = objects.length;
for(let j = 0; j < objects.length; j ++){
if(!groundedCheck(player, objects[j])){
len --;
}
}
if(len <= 0){
player.grounded = false;
}
}
}
// so is this
const groundedCheck = (a, b) => {
// a = player, b = object
if(!(a.pos.x > b.pos.x + b.width || a.pos.x + a.width < b.pos.x)){
if(a.pos.y + a.height === b.pos.y){
return true;
}
}
}