从随机起始位置沿直线绘制点

时间:2016-05-26 20:01:09

标签: java

我正在寻找一些我从飞行模拟中继承的游戏代码的帮助。下面的代码模拟炸弹在地面爆炸,它工作正常但我正在努力改进它。

此刻,它将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;
    }
}

Image

2 个答案:

答案 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;
        }
    }
}