坦克地形交互在我的坦克游戏中不能正常工作

3j86kqsm  于 2021-07-12  发布在  Java
关注(0)|答案(0)|浏览(231)

我已经为这个坦克游戏工作了一段时间了,我已经达到了我想办法让我的坦克与周围环境,主要是地形相互作用的程度。我创建地形的方法是使用一个点列表,由我最喜欢的新地形创建器:噪波贴图生成。但是坦克和地形的相互作用不起作用。
为了让坦克的Angular 本身根据地形,我想尝试使用一个矩形2D来象征我的坦克的踏板,和一个多边形来象征地形(我只使用一块足够大的地形,以适应坦克顶部)。我从坦克当前x位置的地面上的踏板矩形的中心开始。然后,我把这个矩形旋转,让我的程序给我任何可能的位置,踏板可以放置(使用Angular 和y位置)。如果找不到,它会向上移动矩形,然后一次又一次地尝试,直到找到一个打开的位置。
不过,我的问题是,我从程序中得到的只是一个y值,它离地形太远,并且旋转了0度。有什么想法吗?
我的坦克的油漆和运动:

public void paintSelf(Graphics g) {
    // never change for each object, so final
    final int w1 = (int)mapRange(size, 0, 10, 0, barrel.getWidth());  //80
    final int h1 = (int)mapRange(size, 0, 10, 0, barrel.getHeight()); //10
    final int w2 = (int)mapRange(size, 0, 10, 0, base.getWidth());    //80
    final int h2 = (int)mapRange(size, 0, 10, 0, base.getHeight());   //20

    double barAngleRad = Math.toRadians(this.anglePointing);
    double basAngleRad = Math.toRadians(this.rotation);

    Graphics2D g2d = (Graphics2D)g;
    AffineTransform backup = g2d.getTransform();
    AffineTransform transBar = new AffineTransform();
    AffineTransform transBas = new AffineTransform();
    // x, y: the points to rotate around

    // this is for the barrel: ignore it
    transBar.rotate( barAngleRad, x, y - h2 );
    g2d.transform( transBar );
    g2d.drawImage(barrel, x - (int)mapRange(size, 0, 10, 0, 21), y - (int)mapRange(size, 0, 10, 0, 4) - h2, w1, h1, null);

    g2d.setTransform( backup );

    transBas.rotate( basAngleRad, x, y);
    g2d.transform( transBas );
    g2d.drawImage(base, x - (int)mapRange(size, 0, 10, 0, 34), y - h2, w2, h2, null);

    g2d.setTransform( backup ); // restore previous transform

    g.setColor(Color.red);
    g.drawOval(x, y, 1, 1);
    g.drawOval(x, y - h2, 1, 1);
}

public void repositionTankCenter(TerrainFour terrain) {
    //this finds the Y on the terrain at the X of the tank,
    // creates a rectangle at that Y in the shape of the treads
    // on the tank, tests rotations for no intersection with the
    // terrain, and once it finds one (or more) it sets the tank's
    // Y value to that height and it's angle to that angle -----

    // creating variables to use--
    final int c_x = this.getX();
    int c_y = terrain.getpList(c_x).y + terrain.getY();
    final int s_x = (int)(c_x - this.getWidth()/2 - 1);
    final int e_x = (int)(c_x + this.getWidth()/2 + 1);
    final int tw = (int)(this.getTreadWidth());
    final int th = (int)(this.getTreadHeight());
    ArrayList<Point2D.Double> angle_heightList = new ArrayList<Point2D.Double>();
    final AffineTransform at = new AffineTransform();
    Rectangle2D.Double sTreads;
    Rectangle2D boundRect;
    boolean found = false;
    double angle;
    int deg;

    // terrain polygon
    final Polygon T = new Polygon();
    for (int i = 0; i < e_x - s_x; i++)
        T.addPoint( terrain.getpList(i + s_x).x + terrain.getX(), terrain.getpList(i + s_x).y + terrain.getY());
    T.addPoint(e_x, 800);
    T.addPoint(s_x, 800);

    do {
        // treads (of tank) Rectangle
        sTreads = new Rectangle2D.Double(c_x - tw/2, c_y - th, tw, th);
        System.out.println(c_y);

        for (int j = 292; j < 428; j++) {//from 292deg moving right to 68deg
            deg = j % 360;
            angle = Math.toRadians(deg);

            // rotating the treads to a new angle
            at.rotate(angle, sTreads.getCenterX(), sTreads.getCenterY());
            Shape s = at.createTransformedShape(sTreads);
            // rotate back
            at.rotate(-angle, sTreads.getCenterX(), sTreads.getCenterY());

            // creating a rectangle with the new position
            boundRect = s.getBounds2D();

            //comparing the treads' new position to the polygon:
            // if it doesn't intercect, then a position is found
            // and added to a list
            if (!T.intersects(boundRect) ) {
                angle_heightList.add( new Point2D.Double(angle, boundRect.getCenterY()) );
                found = true;
            }
        }
        c_y--;

    } while (!found);

    //gets the correct position and sets the tank's
    // angle and Y value ------------------------
    int a = (int)(angle_heightList.size() / 2);
    this.setRotation( angle_heightList.get(a).x );
    this.setY( (int)angle_heightList.get(a).y );
}

这是我认为必要的地形

public class TerrainFour {

private int x, y, width, minHeight, maxHeight, variance;
private int numberOfPoints;
private double distBetweenPoints;
private ArrayList<Point> pList;
private FBM fbm;

public TerrainFour(int x, int y, int width, int minHeight, int maxHeight, double distBetweenPoints, int variance) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.minHeight = minHeight;
    this.maxHeight = maxHeight;
    this.numberOfPoints = width + 2;
    this.distBetweenPoints = distBetweenPoints - 1;
    this.variance = variance;
    createTerrain();
}

//how I learned about Noise Generation (and FBM)
// https://rtouti.github.io/graphics/perlin-noise-algorithm

private void createTerrain() {
    int a, b;

    //creates points and checks against variance because I
    // like to have a more interesting (height-wise) terrain
    // -- currently prefer 180 as the variance -----------
    do {
        a = minHeight;
        b = maxHeight;
        generatePoints();
        for (int i = 0; i < pList.size(); i++) {
            if (pList.get(i).y > a)
                a = pList.get(i).y;
            if (pList.get(i).y < b)
                b = pList.get(i).y;
        }
    } while (a - b < variance);
}

private void generatePoints() {
    pList = new ArrayList<Point>();

    //an FBM object represents fractial brownian motion - basically
    // means you layer incrementally advanced noisemaps on top of
    // each other to create a more realistic (natural) terrain 
    // I've been using 7 octaves ---------------------------
    fbm = new FBM(7, 21234998, 0.7);

    int s = (int)(Math.random() * 100000);
    for (double t = 0.01 + s; t < numberOfPoints * 0.01 + s; t += 0.01) {
        // fbm works with 2Dnoise.. I don't need 2D so I gave t twice
        double a = fbm.noise(t, t);
        a = mapRange(a, -0.1, 1.25, minHeight, maxHeight);

        pList.add(new Point((int)((t - s)/0.01 + distBetweenPoints), (int)a));
    }
}

private static double mapRange(double value, double low1, double high1, double low2, double high2) {
    return low2 + (high2 - low2) * (value - low1) / (high1 - low1);
}

如果有人能帮忙的话,我会非常感激,如果我没有提供足够的信息(代码)来解决这个问题,请告诉我,我会补充更多。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题