javascript中奇怪的碰撞检测行为;游戏引擎'
strange collision detection behavior in javascript 'game engine.'
如果你玩我设置的"游戏"一段时间,你会发现化身在跳到第二个平台上时正好掉到了第二个。我简直无法理解为什么会这样。我知道这可能比应该发布的代码多,但我束手无策,也许有人会很快发现我做错了什么。有问题的"游戏"。只需使用箭头键即可进行跑步和跳跃。
http://jsfiddle.net/QGB69/
//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();
谢谢!
我注意到您在冲突检测调用中颠倒了方框的顺序,看起来您几乎已经明白了这一点。不过,我会继续告诉你它在哪里。
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;
}
相关文章:
- 你知道使用javascript游戏引擎的简单方法吗
- JavaScript游戏引擎——编辑器中的代码运行:)检查器中的错误
- UNITY游戏引擎的Javascript帮助
- 用于游戏引擎的C++或v8
- Javascript开源移动游戏引擎与音频和粒子
- 如何将Javascript游戏引擎与NAPA O365一起使用
- 理解游戏引擎中的顶点缓冲和索引缓冲
- 游戏2D最佳HTML5/Javascript引擎
- 在three.js游戏引擎中拆分javascript文件
- 除了Impact,还有哪些JavaScript游戏引擎
- 寻找引擎去开发带有贴图的2d或3d等角html5游戏
- 使用模块化游戏引擎的需求
- 尝试着创造一个基本的游戏引擎
- 对于Javascript游戏引擎,重用全局变量是否比使用局部变量更有效?
- 整合jQuery插件与LimeJS游戏引擎
- JavaScript(HTML5)游戏引擎
- javascript中奇怪的碰撞检测行为;游戏引擎'
- 我应该在我的Javascript游戏引擎中使用DOM片段作为Shadow DOM吗
- 基于 Web 的游戏引擎 - 请求输入
- 什么是最简单/最简单的浏览器游戏引擎