我在Android中编写一个游戏,其中一艘敌舰需要以自己的星形模式射击。基本上,对于任何X次射击我都会将敌舰射击,我希望它能够通过射击次数在自身周围360度分割并以正好等边角度射击。因此,第一次射击360度,第二次射击120度,第三次射击240度,射击3次。 4次射击将是360,90,180,270等等。然后每个镜头将以对角线向外移动,直到它到达屏幕边缘(或路上的其他东西)。到现在为止还挺好。这是我的代码 - 我显然做错了,因为虽然四次射击将在四个相同的方向(北,南,东和西)射击,但是3次射击或6次射击或8次射击(等)将朝错误的方向射击。角度不正确。我很感激任何有关这方面的帮助,因为我已经挣扎了很长一段时间了。在下面的示例中,iShotNumber是齐射中发射的镜头数。距离是镜头在一个'刻度'中行进的距离(以像素为单位)。这些镜头以一个阵列的形式添加在船的周围,然后通过每个“滴答”将镜头向前推进一步。
围绕船只周围拍摄的逻辑:
public void addShot(Context ctx, int iShotNumber, float distance) {
for (int iShot=1; iShot<=iShotNumber; iShot++) {
double
dAngle =0, //angle of the shot
dCosFactor=0, //factor on the x-axis
dSinFactor=0; //factor on the y-axis
float
fNewX = 0, //new position on the x-axis
fNewY =0; //new position on the y-axis
dAngle = 360/iShotNumber;
dAngle = dAngle*iShot;
if (iShotNumber == 1) {dAngle=180;} //if there's only one shot then fire straight down
if (dAngle!=360 && dAngle!=180) //if its 360 or 180 then fire straight up or straight down - no need for X
{
fNewX = (float) (getShipRadius()*Math.cos(Math.toRadians(dAngle)));
if (dAngle<=180) {fNewX=fNewX+distance;} else {fNewX=fNewX-distance;}
fNewX=fNewX+getXLocation();
}
else {fNewX=getXLocation();}
if (dAngle!=90 && dAngle !=270) //if its 90 or 270 then fire straight right or straight left - no need for Y
{
fNewY = (float) (getShipRadius()*Math.sin(Math.toRadians(dAngle)));
if (dAngle<=90||dAngle>=270) {fNewY=fNewY+distance;} else {fNewY=fNewY-distance;}
fNewY=fNewY+getYLocation();
}
else {fNewY=getYLocation();}
if (dAngle>=90&&dAngle<=180) {dSinFactor = Math.sin(Math.toRadians(dAngle)-90); dCosFactor = Math.cos(Math.toRadians(dAngle)-90);}
else if (dAngle>=181&&dAngle<=270) {dSinFactor = Math.sin(Math.toRadians(dAngle)-180); dCosFactor = Math.cos(Math.toRadians(dAngle)-180);}
else if (dAngle>=271&&dAngle<360) {dSinFactor = Math.sin(Math.toRadians(dAngle)-270); dCosFactor = Math.cos(Math.toRadians(dAngle)-270);}
else if (dAngle==360) {dSinFactor = Math.sin(Math.toRadians(dAngle)-271); dCosFactor = Math.cos(Math.toRadians(dAngle)-271);}
else {dSinFactor = Math.sin(Math.toRadians(dAngle)); dCosFactor = Math.cos(Math.toRadians(dAngle));}
//dSinFactor = Math.sin(Math.toRadians(dAngle)); dCosFactor = Math.cos(Math.toRadians(dAngle));
//if (dSinFactor<=0){dSinFactor = dSinFactor*-1;} //neutralize negative angles on upshots
//if (dCosFactor<=0){dCosFactor = dCosFactor*-1;} //neutralize negative angles on rightshots
if ( MainActivity.iDebugLevel >= 1) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot)
+ " with dAngle " +String.valueOf(dAngle) +" cosan was " +String.valueOf(dCosFactor) +" sinan was " +String.valueOf(dSinFactor));}
if ( MainActivity.iDebugLevel >= 2) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with fNewX " +String.valueOf(fNewX));}
if ( MainActivity.iDebugLevel >= 2) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with fNewY " +String.valueOf(fNewY));}
if (dAngle==90||dAngle==270) {newShot = new ShotClass(ctx, fNewX, fNewY, dCosFactor /*x-angle*/, 0 /*y-angle*/);} //fire straight to the right or left
else if (dAngle==360||dAngle==180) {newShot = new ShotClass(ctx, fNewX, fNewY, 0 /*x-angle*/, dSinFactor /*y-angle*/);} //fire straight up or down
else {newShot = new ShotClass(ctx, fNewX, fNewY, dCosFactor /*x-angle*/, dSinFactor /*y-angle*/);} //fire at an angle
if ( dAngle <= 90 || dAngle >= 270) {
newShot.setShotGoingUp(true);
}
else
{
newShot.setShotGoingUp(false);
}
if ( dAngle <= 180 ) {
newShot.setShotGoingRight(true);
}
else
{
newShot.setShotGoingRight(false);
}
if ( MainActivity.iDebugLevel >= 1) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with goingup " +String.valueOf(newShot.getShotGoingUp()) +" with goingright " +String.valueOf(newShot.getShotGoingRight()));}
arShots.add(newShot);
if ( MainActivity.iDebugLevel >= 2) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with position " +String.valueOf(getXLocation()) +" " +String.valueOf(getYLocation()) +" firing params: " +String.valueOf(dCosFactor) +" " +String.valueOf(dSinFactor) +" angle was " +String.valueOf(dAngle));}
}
以对角线发射镜头的逻辑:
inpDistance = inpDistance * .2f; //slow down the shot to one fifth speed
for (int iShotInTheSequence=1;iShotInTheSequence<=inpNumberShots;iShotInTheSequence++) {
fFactor = (float) (inpDistance * getYFiringAngle());
if ( getShotGoingUp() ) { //shot is going up
fYLocation = fYLocation - fFactor;
} //shot is going up
else {//shot is going down
fYLocation = fYLocation + fFactor;
} //shot is going down
fFactor = (float) (inpDistance * getXFiringAngle());
if ( getShotGoingRight() ) { //shot is going right
fXLocation = fXLocation + fFactor;
} //shot is going right
else {//shot is going left
fXLocation = fXLocation - fFactor;
} //shot is going left
}
答案 0 :(得分:3)
大多数编程语言中的三角函数(包括Java)以弧度而非度数来度量参数。有一个辅助函数可以进行转换,因此无论您拨打sin
还是cos
,都可以添加对toRadians
的调用:
Math.cos(Math.toRadians(dAngle))
答案 1 :(得分:1)
第一个错误:
dAngle = 360/iShotNumber;
你想要一个双重作为除法的结果,那么你不能简单地进行整数除法。你应该这样做:
dAngle = 360.0/(double)iShotNumber;
我正在检查其他错误。