好的,我只是想减少代码行,把所有的东西都手动写成数组。我的问题是他现在传送和重力不工作..。首先,我有一个单元格对象网格,它基本上是一个32x32网格"640X480“。这些对象都被传递到一个数组中,就像这样-
var gridcellarray = [750];
gridcellarray[0] = cell0;
gridcellarray[1] = cell1;
gridcellarray[2] = cell2;
and so on for 750 32x32 cells...至于碰撞剧本我有这个..。
function collisioncheck(obj) {
obj = obj;
for(var i = 0; i < gridcellarray.length; i++){
//really long if statement// sorry...
if ((gridcellarray[i].solid == true) && ((obj.PosY >= gridcellarray[i].y - obj.maskImg.height) && !(obj.PosY >= gridcellarray[i].y ) && !((obj.PosX > gridcellarray[i].x + solidOriginX + solidImg.width/2-5) || (obj.PosX < gridcellarray[i].x - solidOriginX - solidImg.width/2)))){
if(obj.onground == 0){
obj.PosY = gridcellarray[i].y - obj.maskImg.height;
obj.VelY = 0;
obj.onground = 1;
obj.jump = 0;
}
}
else if (obj.PosY >= canvas.height - obj.maskImg.height){
if(obj.onground == 0){
obj.VelY = 0;
obj.onground = 1;
obj.jump = 0;
obj.PosY = canvas.height - obj.maskImg.height;
}
}
else {
obj.VelY += 1;
obj.onground = 0;
}
}
}现在,这段代码运行良好,如果我手动复制了每个单元格750次,问题是,现在有一次循环循环,将它们作为数组循环,它会混淆并将我传送到底部,如果我试图跳转,即使不是在块下面或块上,它也会将我传送回底部。
//编辑
我认为所有的变量都应该用名字来解释它们的目的,但是如果你有任何问题,请问。
//编辑
所有变量都应用您检查碰撞的对象,例如冲突检查(Player),这里有一个指向正在运行的代码演示的链接。Zack Bloom的代码就在其中,它的工作原理很好地应用于未发布的水平碰撞脚本,但是垂直地,它不会重置并确认您在块上的位置-- in = true;演示链接
//编辑
好的,现在Zack指出,重新设置y to和x值有很大帮助,但他仍然不能跳转,因为陆上变量不想在碰撞检测到时重置.哦,传送是由于我的向上的剧本-
//Upwards Collision//
if ((cell.solid == true) && ((obj.PosY >= cell.y - 32) && !(obj.PosY > cell.y+32) && !((obj.PosX > cell.x + solidOriginX + solidImg.width/2-5) || (obj.PosX < cell.x - solidOriginX - solidImg.width/2)))){
if (obj.onground == 0){
obj.VelY += 1;
obj.onground = 0;
obj.PosY = cell.y + obj.maskImg.height-13;
}
}有什么办法解决上面这个烂摊子吗?阻止他传送?它只用于检查防撞面罩(红色矩形)的顶部是否与街区接触,就好像试图跳过它一样,但它是为了阻止这种情况发生,所以你撞到了头,然后又跌倒了。提前谢谢!
发布于 2011-11-02 00:37:25
如果/ each实际上根本不属于循环中,则它们不会计算正在循环的单元格,但是每次调用冲突检查时都会被多次触发。
function collisioncheck(obj) {
for(var i = 0; i < gridcellarray.length; i++){
var cell = gridcellarray[i];
if (cell.solid && ((obj.PosY >= cell.y - obj.maskImg.height) && !(obj.PosY >= cell.y ) && !((obj.PosX > cell.x + solidOriginX + solidImg.width/2-5) || (obj.PosX < cell.x - solidOriginX - solidImg.width/2)))){
if(!obj.onground){
obj.PosY = cell.x - obj.maskImg.height;
obj.VelY = 0;
obj.onground = 1;
obj.jump = 0;
break;
}
}
}
if (obj.PosY >= canvas.height - obj.maskImg.height){
if(!obj.onground){
obj.VelY = 0;
obj.onground = 1;
obj.jump = 0;
obj.PosY = canvas.height - obj.maskImg.height;
}
} else {
obj.VelY += 1;
obj.onground = 0;
}
}但是一种更好的方法是根据每个网格单元格的位置来存储,所以你只需要查找船附近的网格单元。
// You only have to do this once to build the structure, don't do it every time you
// need to check a collision.
var gridcells = {};
for (var i=0; i < gridcellarray.length; i++){
var cell = gridcellarray[i];
var row_num = Math.floor(cell.PosX / 32);
var col_num = Math.floor(cell.PosY / 32);
if (!gridcells[row_num])
gridcells[row_num] = {};
gridcells[row_num][col_num] = cell;
}
// Then to check a collision:
function collisioncheck(obj){
// I'm not sure exactly what your variables mean, so confirm that this will equal
// the width of the object:
var obj_width = solidImg.width;
var obj_height = obj.maskImg.height;
var collided = false;
var left_col = Math.floor(obj.PosX / 32),
right_col = Math.floor((obj.PosX + obj_width) / 32),
top_row = Math.floor(obj.PosY / 32),
bottom_row = Math.floor((obj.PosY + obj_height) / 32);
for (var row=top_row; row <= bottom_row; row++){
for (var col=left_col; col <= right_col; col++){
var cell = gridcells[row][col];
if (cell.solid){
collided = true;
if (row == top_row){
// We collided into something above us
obj.VelY = 0;
obj.PosY = cell.PosY + 32;
} else if (row == bottom_row && !obj.onground){
// We collided into the ground
obj.PosY = cell.x - obj_height;
obj.VelY = 0;
obj.onground = 1;
obj.jump = 0;
}
if (col == left_col){
// We collided left
obj.VelX = 0;
obj.PosX = cell.PosX + 32;
} else if (col == right_col){
// We collided right
obj.VelX = 0;
obj.PosX = cell.PosX - obj_width;
}
}
}
}
if (obj.PosY >= canvas.height - obj_height){
if (!obj.onground){
obj.VelY = 0;
obj.onground = 1;
obj.jump = 0;
obj.PosY = canvas.height - obj_height;
}
}
if (!collided){
obj.VelY += 1;
obj.onground = 0;
}
}与其在每个帧中循环720个单元,我们只是观察我们所知道的相互重叠的单元。这比所有的位置计算要有效得多,而且容易读懂。
发布于 2011-11-02 00:43:59
对您的代码的一些评论:
var gridcellarray = [750];它使用值为750的单个成员创建数组。我认为你认为这相当于:
var gridcellarray = new Array(750);它创建一个长度为750的数组。不需要设置数组的大小,只需将其初始化为空数组并赋值即可。
var gridcellarray = [];
gridcellarray[0] = cell0;这将第一个成员的值替换为cell0的值。
function collisioncheck(obj) {
obj = obj;第二行没有意义,它只是将obj的值分配给obj (所以它是多余的)。
for(var i = 0; i < gridcellarray.length; i++){在大多数浏览器中,保存gridcellarray.length值的效率要高得多,否则每次都必须查找它(编译器可能无法工作,无论它是否能够缓存它),因此:
for (var i = 0, iLen = gridcellarray.length; i < iLen; i++) {更有效的方法是存储一个关于网格的引用,而不是每次查找它。此外,您还可以使用一个短名称,因为它只在循环中使用,因此很容易找到它的用途:
var c = gridcellarray[i];因此,代码不仅运行得更快,而且if语句的字符更少(您可能更喜欢以不同的格式对其进行格式化):
if ((c.solid == true) &&
((obj.PosY >= c.y - obj.maskImg.height) && !(obj.PosY >= c.y ) &&
!((obj.PosX > c.x + solidOriginX + solidImg.width/2-5) ||
(obj.PosX < c.x - solidOriginX - solidImg.width/2)))) {哇,这真的是一些if声明。你能把它分解成更简单、合乎逻辑的步骤吗?
啊,扎克也发了一个答案,所以我就把它留在这里。
https://stackoverflow.com/questions/7974513
复制相似问题