我正在寻找一些我从飞行模拟中继承的游戏代码的帮助。下面的代码模拟炸弹在地面爆炸,它工作正常但我正在努力改进它。
此刻,它将x和y的随机值作为起点,然后在-20和20之间添加另一个随机值。它运作正常,但不能模拟炸弹掉落得很好,因为图案不是沿直线放置/
我想要实现的是在第一个随机值之后的所有x和y点,沿着一条直线放置,以便所有呼叫的效果看起来都在一条线上。线的方向无关紧要。
感谢您的帮助
拖鞋
public static class BombUnit extends CandCGeneric
{
public boolean danger()
{
Point3d point3d = new Point3d();
pos.getAbs(point3d);
Vector3d vector3d = new Vector3d();
Random random = new Random();
Aircraft aircraft = War.GetNearestEnemyAircraft(this, 10000F, 9);
if(counter > 10)
{
counter = 0;
startpoint.set(point3d.x + (double)(random.nextInt(1000) - 500), point3d.y + (double)(random.nextInt(1000) - 500), point3d.z);
}
if(aircraft != null && (aircraft instanceof TypeBomber) && aircraft.getArmy() != myArmy)
{
World.MaxVisualDistance = 50000F;
counter++;
String s = "weapon.bomb_std";
startpoint.x += random.nextInt(40) - 20;
startpoint.y += random.nextInt(40) - 20;
Explosions.generate(this, startpoint, 7F, 0, 30F, !Mission.isNet());
startpoint.z = World.land().HQ(startpoint.x, startpoint.y);
MsgExplosion.send(this, s, startpoint, getOwner(), 0.0F, 7F, 0, 30F);
Engine.land();
int i = Landscape.getPixelMapT(Engine.land().WORLD2PIXX(startpoint.x), Engine.land().WORLD2PIXY(startpoint.y));
if(firecounter < 100 && i >= 16 && i < 20)
{
Eff3DActor.New(null, null, new Loc(startpoint.x, startpoint.y, startpoint.z + 5D, 0.0F, 90F, 0.0F), 1.0F, "Effects/Smokes/CityFire3.eff", 300F);
firecounter++;
}
super.setTimer(15);
}
return true;
}
private static Point3d startpoint = new Point3d();
private int counter;
private int firecounter;
public BombUnit()
{
counter = 11;
firecounter = 0;
Timer1 = Timer2 = 0.05F;
}
}
答案 0 :(得分:0)
我假设你的startpoint是一个StartPoint类,其中x,y,z坐标为整数。
我希望我能正确理解你的问题。看起来你要么想要制造垂直爆炸,要么想要水平爆炸。由于爆炸总是发生在地面上,因此z坐标将为零。现在,您可以改变x或y坐标中的一个,以便沿直线随机爆炸。您是选择x还是y可以修复,也可以随机化。下面是一个潜在的随机解决方案:
public boolean danger() {
// stuff
int orientation = Random.nextInt(2);
if(aircraft != null && (aircraft instanceof TypeBomber) && aircraft.getArmy() != myArmy)
{
// stuff
startPoint = randomizeStartPoint(orientation, startPoint);
// stuff
}
}
StartPoint randomizeStartPoint(int orientation, StartPoint startPoint) {
if(orientation == 0) {
startPoint.x += random.nextInt(40) - 20;
}
else {
startPoint.y += random.nextInt(40) - 20;
}
return startPoint;
}
对于您上传的图像,爆炸的方向似乎不一定是水平或垂直的。所以我上面发布的代码为您的问题提供了有限的解决方案。
由于您需要任何随机直线,因此您的问题归结为两个子部分: 1.生成随机直线方程。 2.沿着这条线生成随机点。
现在,坐标几何中的直线方程是y = mx + c
,其中m
是斜率,c
是线与y轴交叉的常量。 c
的问题在于它会产生不合理的坐标。我假设您正在寻找整数坐标,因为这将确保您的点被准确地绘制。 (你可以使用有理分数,但是像1/3这样的分数仍然会导致准确度的降低)。摆脱这种非理性问题的最好方法是摆脱c
。所以现在你的直线总是看起来像y = mx
。因此,对于第一步,您必须生成随机m
。
然后,对于第2步,您可以生成随机x
或随机y
。它并不重要,因为任何一个都会产生随机坐标。
以下是解决方案的可能代码:
int generateRandomSlope() {
return Random.nextInt(100); // arbitrarily chose 100.
}
int randomizeStartPoint(int m, StartPoint startPoint) { // takes the slope we generated earlier. without the slope, your points will never be on a straight line!
startPoint.x += random.nextInt(40) - 20;
startPoint.y += x * m; // because a line equation is y = mx
return startPoint;
}
public boolean danger() {
// stuff
int m = generateRandomSlope(); // you may want to generate this elsewhere so that it doesn't change each time danger() is called.
if(aircraft != null && (aircraft instanceof TypeBomber) && aircraft.getArmy() != myArmy)
{
// stuff
startPoint = randomizeStartPoint(m, startPoint);
// stuff
}
}
同样,这不是一个完整的或最好的解决方案。
答案 1 :(得分:0)
问题中的代码是一团糟,但忽略了这一点并试图关注相关部分:您可以为第一个点和随机方向生成随机位置,然后分几步沿着这个方向行走。
(这仍然提出了一个问题,即方向是否真的并不重要。如果只有第一枚炸弹落入&#34;有效的&#34;区域,那不重要吗,以及屏幕外的其余部分?)
但是,相关代码可能大致如下:
class Bombs
{
private final Random random = new Random(0);
int getScreenSizeX() { ... }
int getScreenSizeY() { ... }
// Method to drop a single bomb at the given position
void dropBombAt(double x, double y) { ... }
void dropBombs(int numberOfBombs, double distanceBetweenBombs)
{
// Create a random position in the screen
double currentX = random.nextDouble() * getScreenSizeX();
double currentY = random.nextDouble() * getScreenSizeY();
// Create a random step size
double directionX = random.nextDouble();
double directionY = random.nextDouble();
double invLength = 1.0 / Math.hypot(directionX, directionY);
double stepX = directionX * invLength * distanceBetweenBombs;
double stepY = directionY * invLength * distanceBetweenBombs;
// Drop the bombs
for (int i=0; i<numberOfBombs; i++)
{
dropBombAt(currentX, currentY);
currentX += stepX;
currentY += stepY;
}
}
}