【发布时间】:2013-12-31 12:55:27
【问题描述】:
我正在用 android 编写一个游戏,其中一艘敌舰需要在其周围以星形图案开火。基本上,对于我让敌舰开火的任何 X 次射击,我希望它围绕自身 360 度除以射击次数,并以完全等边的角度射击。因此,将发射 3 枪,第一枪在 360 度,第二枪在 120 度,第三枪在 240 度。 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
}
【问题讨论】:
-
在堆栈交换数学中发布这个,您可能会得到与数学计算相关的更好的解决方案
-
当你大量编辑原始问题的代码时,你应该总是写一个评论。 @Joni 的解决方案是否解决了您的问题?
-
哦,对不起 - 我在编辑屏幕上写了一条评论(不知道它没有出现在任何地方)。他添加的内容确实帮助了我,但镜头仍然没有出现在船周围的正确位置
标签: java android space trigonometry