首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >所需javascript帮助中的冲突脚本

所需javascript帮助中的冲突脚本
EN

Stack Overflow用户
提问于 2011-11-02 00:25:13
回答 2查看 187关注 0票数 0

好的,我只是想减少代码行,把所有的东西都手动写成数组。我的问题是他现在传送和重力不工作..。首先,我有一个单元格对象网格,它基本上是一个32x32网格"640X480“。这些对象都被传递到一个数组中,就像这样-

代码语言:javascript
复制
var gridcellarray = [750];
gridcellarray[0] = cell0;
gridcellarray[1] = cell1;
gridcellarray[2] = cell2;
and so on for 750 32x32 cells...

至于碰撞剧本我有这个..。

代码语言:javascript
复制
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值有很大帮助,但他仍然不能跳转,因为陆上变量不想在碰撞检测到时重置.哦,传送是由于我的向上的剧本-

代码语言:javascript
复制
  //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; 
         }
     }

有什么办法解决上面这个烂摊子吗?阻止他传送?它只用于检查防撞面罩(红色矩形)的顶部是否与街区接触,就好像试图跳过它一样,但它是为了阻止这种情况发生,所以你撞到了头,然后又跌倒了。提前谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-02 00:37:25

如果/ each实际上根本不属于循环中,则它们不会计算正在循环的单元格,但是每次调用冲突检查时都会被多次触发。

代码语言:javascript
复制
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;
     }
}

但是一种更好的方法是根据每个网格单元格的位置来存储,所以你只需要查找船附近的网格单元。

代码语言:javascript
复制
// 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个单元,我们只是观察我们所知道的相互重叠的单元。这比所有的位置计算要有效得多,而且容易读懂。

票数 3
EN

Stack Overflow用户

发布于 2011-11-02 00:43:59

对您的代码的一些评论:

代码语言:javascript
复制
var gridcellarray = [750];

它使用值为750的单个成员创建数组。我认为你认为这相当于:

代码语言:javascript
复制
var gridcellarray = new Array(750);

它创建一个长度为750的数组。不需要设置数组的大小,只需将其初始化为空数组并赋值即可。

代码语言:javascript
复制
var gridcellarray = [];
gridcellarray[0] = cell0;

这将第一个成员的值替换为cell0的值。

代码语言:javascript
复制
function collisioncheck(obj) {
    obj = obj;

第二行没有意义,它只是将obj的值分配给obj (所以它是多余的)。

代码语言:javascript
复制
  for(var i = 0; i < gridcellarray.length; i++){

在大多数浏览器中,保存gridcellarray.length值的效率要高得多,否则每次都必须查找它(编译器可能无法工作,无论它是否能够缓存它),因此:

代码语言:javascript
复制
  for (var i = 0, iLen = gridcellarray.length; i < iLen; i++) {

更有效的方法是存储一个关于网格的引用,而不是每次查找它。此外,您还可以使用一个短名称,因为它只在循环中使用,因此很容易找到它的用途:

代码语言:javascript
复制
    var c = gridcellarray[i];

因此,代码不仅运行得更快,而且if语句的字符更少(您可能更喜欢以不同的格式对其进行格式化):

代码语言:javascript
复制
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声明。你能把它分解成更简单、合乎逻辑的步骤吗?

啊,扎克也发了一个答案,所以我就把它留在这里。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7974513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档