如果你玩“游戏”我已经设置了一会儿,你会发现当你跳到它上面时,化身会从第二个平台上掉下来。我简直无法理解为什么会这样。我知道这可能比应该发布的代码更多,但是我的智慧结束了,也许有人可以很快看到我做错了什么。 有问题的“游戏”。只需使用箭头键进行跑步和跳跃即可。
//RequestAnimationFrame shim.
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
//Initializing canvas and world
var canvas = document.getElementById('viewport');
var ctx = canvas.getContext('2d');
var keysDown = [];
var currentPlatform = 0;
//some helpful variables
var canvasHeight = $('#viewport').height();
var canvasWidth = $('#viewport').width();
//Add keycodes to 'keysDown' array
$(document).keydown(function (e) {
if ($.inArray(e.which, keysDown) === -1) {
keysDown.push(e.keyCode);
}
});
//Remove keycodes from 'keysDown' array
$(document).keyup(function (e) {
if ($.inArray(e.which, keysDown) > -1) {
keysDown = $.grep(keysDown, function (n, i) {
return n !== e.which;
});
}
});
//Avatar object, lots of attributes, great import!
var avatar = {};
avatar.xPos = 50;
avatar.yPos = 50;
avatar.accl = 0.55;
avatar.decel = 0.85;
avatar.jReduction = 1.25;
avatar.direction = null;
avatar.stopping = false;
avatar.avatarHeight = 50;
avatar.avatarWidth = 25;
avatar.fallTime = 0;
avatar.isGrounded = false;
avatar.isJumping = false;
avatar.endJump = false;
avatar.jump = 18;
avatar.j = avatar.jump;
avatar.jStrength = 0.55;
avatar.speed = 13;
avatar.prevXPos = 0;
avatar.xDelta = 0;
avatar.xVelocity = 0;
avatar.yVelocity = 0;
avatar.yBottom = 0;
avatar.xAlignment = 0;
avatar.collDetect = function (args) {
avatar.yBottom = avatar.yPos + avatar.avatarHeight;
avatar.xPosRight = avatar.xPos + avatar.avatarWidth;
for (i = 0; i < arguments.length; i++) {
if (avatar.yBottom > arguments[i].boxTop) {
if (avatar.xPos > arguments[i].xPos) {
if (avatar.direction === 'left' && avatar.xDelta > avatar.xPos - arguments[i].xPosRight) {
avatar.xPos = arguments[i].xPosRight;
avatar.xStop();
} else if (avatar.direction === 'left' && avatar.xPos <= arguments[i].xPosRight) {
avatar.xPos = arguments[i].xPosRight;
avatar.xStop();
}
} else if (avatar.xPos < arguments[i].xPos) {
if (avatar.direction === 'right' && avatar.xDelta > arguments[i].xPos - avatar.xPosRight) {
avatar.xPos = arguments[i].xPos - avatar.avatarWidth;
avatar.xStop();
} else if (avatar.direction === 'right' && avatar.xPos >= arguments[i].xPos) {
avatar.xPos = arguments[i].xPos - avatar.avatarWidth;
avatar.xStop();
}
}
}
if (avatar.xPos > arguments[i].xPos - avatar.avatarWidth && avatar.xPos < arguments[i].xPos + arguments[i].boxWidth) {
currentPlatform = arguments[i].boxHeight;
} else {
currentPlatform = 0;
}
}
};
avatar.xStop = function () {
avatar.xVelocity = 0;
avatar.xDelta = 0;
avatar.stopping = false;
avatar.direction = null;
};
//First obstacle. Good luck gettin' over this one, avatar!
function Box(xPos, boxWidth, boxHeight, boxColor) {
this.xPos = xPos;
this.boxWidth = boxWidth;
this.boxHeight = boxHeight;
this.boxColor = boxColor;
this.xPosRight = xPos + boxWidth;
this.boxTop = canvasHeight - boxHeight;
}
function renderBoxes(n) {
for (i = 0; i < arguments.length; i++) {
ctx.fillStyle = arguments[i].boxColor;
ctx.fillRect(arguments[i].xPos,
canvasHeight - arguments[i].boxHeight,
arguments[i].boxWidth,
arguments[i].boxHeight);
}
}
var box1 = new Box(100, 50, 100, 'gray');
var box2 = new Box(300, 50, 125, 'green');
//physics object. Properties of the world
var physx = {};
physx.gravity = 1;
physx.colliding = false;
physx.fallTimeModifier = 0.5;
//Big movement function. The action's in here!
function moveIt() {
//Jump!
if ($.inArray(38, keysDown) > -1) {
if (avatar.j > 0) {
avatar.isGrounded = false;
avatar.isJumping = true;
avatar.yPos -= avatar.j;
avatar.yVelocity = avatar.j;
avatar.j -= avatar.jStrength;
} else if (avatar.j <= 0) {
avatar.isJumping = false;
}
}
//End Jump, initiated when the user lets off the jump key mid-jump.
if (avatar.endJump === true) {
if (avatar.j > 0) {
avatar.j -= avatar.jReduction;
avatar.yPos -= avatar.j;
} else if (avatar.j <= 0) {
avatar.isJumping = false;
avatar.endJump = false;
}
}
$(document).keyup(function (e) {
if (e.which === 38 && avatar.isJumping === true) {
avatar.endJump = true;
}
});
//Accounting for deceleration when avatar stops.
if (avatar.stopping === true) {
if ((avatar.xVelocity - avatar.decel) <= 0) {
avatar.xStop();
return;
}
if (avatar.direction === 'right') {
avatar.xPos += avatar.xVelocity;
avatar.xVelocity -= avatar.decel;
avatar.xDelta = avatar.xVelocity;
}
if (avatar.direction === 'left') {
avatar.xPos -= avatar.xVelocity;
avatar.xVelocity -= avatar.decel;
avatar.xDelta = avatar.xVelocity
}
}
//Correcting glitchy stopping behavior when conflicting left/right keycodes present in 'keysDown' array
if ($.inArray(37, keysDown) > -1 && $.inArray(39, keysDown) > -1) {
avatar.stopping = true;
}
//right
if ($.inArray(39, keysDown) > -1) {
if (avatar.stopping === false) {
avatar.direction = 'right';
if (avatar.xVelocity >= avatar.speed) {
avatar.xPos += avatar.speed;
avatar.xDelta = avatar.speed;
} else {
avatar.xPos += avatar.xVelocity;
avatar.xVelocity += avatar.accl;
avatar.xDelta = avatar.xVelocity;
}
}
}
//left
if ($.inArray(37, keysDown) > -1) {
if (avatar.stopping === false) {
avatar.direction = 'left';
if (avatar.xVelocity >= avatar.speed) {
avatar.xPos -= avatar.speed;
avatar.xDelta = avatar.speed;
} else {
avatar.xPos -= avatar.xVelocity;
avatar.xVelocity += avatar.accl;
avatar.xDeta = avatar.xVelocity;
}
}
}
//Set avatar.isStopping to true when
$(document).keyup(function (e) {
if (e.which === 39 || e.which === 37) {
avatar.stopping = true;
}
});
}
//Gravity function. Keep him on the dang ground!
function grav() {
if (avatar.isJumping) {
return;
}
if (avatar.yPos >= (canvasHeight - currentPlatform) - avatar.avatarHeight) {
avatar.isGrounded = true;
avatar.fallTime = 0;
} else {
if ((avatar.fallTime * physx.gravity) > (((canvasHeight - currentPlatform) - avatar.avatarHeight) - avatar.yPos)) {
avatar.yPos = (canvasHeight - currentPlatform) - avatar.avatarHeight;
avatar.isGrounded = true;
avatar.j = avatar.jump;
avatar.fallTime = 0;
} else {
avatar.yPos += avatar.fallTime * physx.gravity;
avatar.fallTime += physx.fallTimeModifier;
}
}
}
//Render the dang thing, ya dingus!
function render() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
renderBoxes(box1, box2);
avatar.collDetect(box2, box1);
grav();
ctx.fillStyle = 'red';
ctx.fillRect(avatar.xPos,
avatar.yPos,
avatar.avatarWidth,
avatar.avatarHeight);
moveIt();
谢谢!
答案 0 :(得分:0)
看起来你几乎想通了这个,因为我注意到你已经颠倒了碰撞检测调用中的方框顺序。不过,我会继续告诉你它在哪里。
if (avatar.xPos > arguments[i].xPos - avatar.avatarWidth && avatar.xPos < arguments[i].xPos + arguments[i].boxWidth) {
currentPlatform = arguments[i].boxHeight;
} else {
currentPlatform = 0;
}
所以这里的这个位于循环内部。因为你使用if / else,所以它总是只适用于第二个框。意思是,即使第一次通过循环设置currentPlatform = X,第二次传递也会设置currentPlatform = 0.。
对于此特定问题,请尝试
if (avatar.xPos > arguments[i].xPos - avatar.avatarWidth && avatar.xPos < arguments[i].xPos + arguments[i].boxWidth) {
currentPlatform = arguments[i].boxHeight;
break; // <-- here
} else {
currentPlatform = 0;
}