2010-11-12 67 views
1

我正在研究一个程序,它模拟在一个字段中移动的对象。该领域具有1024x1024的界限。该对象不能在x,y坐标下低于0,并且它不能超过1024.我为每个对象创建一个名为“move()”的方法,以当前速度将对象移动到当前方向。如果物体接近边界,它会以新的方向和相同的速度转向。移动的物体卡在角落

我遇到的问题是,当我的一个对象接近x和y边界(字段的角落)时,它会卡在角落里。就好像它试图远离角落,但随后又转回来。它必须喜欢那个角落。我查看了我的代码和我,我的逻辑似乎是正确的。我检查以确保新的方向不是负的或超过359.我检查以确保新的x,y与新方向的坐标也在范围内。我甚至有办法设定一个新的方向。

我试过用不同的逻辑重新实现这个方法,但没有运气。如果有人可能在我的编程中发现缺陷或指出可能导致它的原因,那么将非常感激。

我试图调试并逐步通过我的程序,我发现当它到达角落时,它会改变方向转向,移动大约3个空格,然后回到角落。必须是一个美妙的角落。

代码移动方法如下:

public void move(){ 

    localX = super.getX(); 
    localY = super.getY(); 

    float newX=0, newY=0; 
    float testX, testY; 
    boolean acceptX = false, acceptY = false; 

    testX = (float) (Math.cos(direction)*10) + localX; 
    testY = (float) (Math.sin(direction)*10) + localY; 
    int testDirection; 

    while(!acceptX){ 
    if(testX >= 0 && testX <= bound){ 
    newX = testX; 
    acceptX = true; 
    }//end if statement 
    else{ 
    if(direction+180 > 359){ 
    setDirection(direction-180); 
    testX = (float) (Math.cos(Math.toRadians(direction))*speed) + localX; 
    } 
    else{ 
    setDirection(direction+180); 
    testX = (float) (Math.cos(Math.toRadians(direction))*speed) + localX; 
    } 
    }//end else 
    }//end while that checks for X value 

    while(!acceptY){ 
    if(testY >= 0 && testY <= bound){ 
    newY = testY; 
    acceptY = true; 
    }//end if statement 
    else{ 
    if(direction+180 > 359){ 
    setDirection(direction-180); 
    testY = (float) (Math.sin(Math.toRadians(direction))*speed) + localY; 
    } 
    else{ 
    setDirection(direction+180); 
    testY = (float) (Math.sin(Math.toRadians(direction))*speed) + localY; 
    } 
    }//end else 
    }//end while that checks for Y value 

    super.setX(newX); 
    super.setY(newY); 

} 

这里是setDirection代码

public void setDirection(int d) { 
     direction = d; 
    } 
+0

我们还需要设置'direction'的代码。可能它出于某种原因偏向于朝着角落移动。 – Donnie 2010-11-12 00:50:54

+0

没问题,上面加了。 – Seephor 2010-11-12 00:54:08

+1

setDirection((direction + 180)%360)。摆脱那些如果。 – 2010-11-12 00:54:54

回答

2

假设你在左上角有一个物体,正在上升。你的第一个测试将它转换成所以它下降。然后你的第二次检查,再次变成了一次又一次。

您的代码也可以使用更多的可读性。我注意到的第一件事是,您正在使用>359检查来规范新的方向。但是,所有情况都包括移动代码。我会这样做:

setDirection(direction + 180);   //turn around 
if (direction >= 360) direction -= 360; //normalize 
testY = ...;       //move 

将移动代码移出方向检查if/else块。 360也是一个更好的魔术数字使用; 359度毫无意义。如前所述,您最终应该使用矢量库,因此会丢掉大部分数学运算。

+0

好的,谢谢。我决定使用上面提到的参数进行清理。传入((方向+ 180)%360)。我实际上使用Java矢量库来存储在场中移动的对象,但是如何将它用于坐标? – Seephor 2010-11-12 01:16:47

+0

我的意思是数学向量。这些东西:http://download.java.net/media/java3d/javadoc/1.5.2/javax/vecmath/package-summary.html – aib 2010-11-12 08:25:12

1

我真的建议你存储方向矢量(X,Y),而不是从标量中计算该向量;我认为这对你的代码非常有帮助。

+0

我从来没有用过矢量来存储方向。我会将x和y分量存储在向量中吗? – Seephor 2010-11-12 01:14:40

+0

@Seephor:是的,这就是主意。关键是那些trig函数是昂贵的;当以直线移动时,实际矢量将保持一致(或由另一个矢量修改),并且节省这些trig函数的计算开销是非常有用的。当你需要方向时,你可以从反三角函数(弧函数)中得到它。 – 2010-11-12 05:13:01

1

问题:当物体碰到边缘时,将其转动180度。如果碰到两边,它会旋转到位,测试坐标将始终位于错误的位置。

当你的一个物体碰到一个边缘时,它需要反弹,而不是关于面部!入射角度==折射角度等。换句话说,如果您检查x坐标并弹跳,则取x轴速度,不能同时x & y。