我已经为这个坦克游戏工作了一段时间了,我已经达到了我想办法让我的坦克与周围环境,主要是地形相互作用的程度。我创建地形的方法是使用一个点列表,由我最喜欢的新地形创建器:噪波贴图生成。但是坦克和地形的相互作用不起作用。
为了让坦克的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);
}
如果有人能帮忙的话,我会非常感激,如果我没有提供足够的信息(代码)来解决这个问题,请告诉我,我会补充更多。
暂无答案!
目前还没有任何答案,快来回答吧!