Hello其他程序员,
我目前正在为我的研究编写一个小型图形应用程序,它应该在一个小型2D游戏中展示AI。我现在有点卡住了。 我在顶部创建了一个具有Entity的类层次结构,基本上代表任何实体,如播放器,敌人和障碍物,它有一个Node属性,用于以图形方式表示实体。实体还有两个受保护的SimpleIntegerProperty对象x和y,我绑定了Node属性的layout-properties,这样每当我更改x和y的值时,图形表示也会移动。
到目前为止,我可以做任何不依赖实体对象坐标的事情。碰撞等工作 然而,当我试图在玩家角色所在的位置(x和y属性的值)实现一个产生子弹(小圆圈对象)的系统时,玩家与鞋帮的距离有两倍的奇怪偏移。左角(右下角)。我做了一点实验,看到当我通过localToScene方法检查坐标时,使用两个属性的值或直接使用Node的layoutX和layoutY方法,它会给我坐标TWICE AS BIG作为实际坐标。 我的窗格是600x600 px大,当我将我的播放器(另一个扩展到Entity的对象)放在300,300时,一切看起来都很好,但是localToScene方法显然告诉我它是它的两倍,所以600,600。当我使用我的播放器到右下角并通过localToScene打印坐标时,它告诉我它是在1200,1200。
public void addProjectile(Projectile p)
{
Projectile p2 = new PlayerProjectile(100, 100, 0.5);
projectiles.add(p2);
System.out.println(p2.getSkin().localToScene(p2.getX(), p2.getY()));
System.out.println(p2.getSkin().getLayoutX() + " " + p2.getSkin().getLayoutY());
this.getChildren().add(p2.getSkin());
System.out.println(p2.getSkin().getLayoutX() + " " + p2.getSkin().getLayoutY());
// p.setPosition(p.getSkin().localToScreen(p.getX(), p.getY()));
}
此方法创建一个100,100的弹丸(layoutX和Y也确认了这一点)。然后,我将Projectile p2添加到ArrayList(不重要)。 第一次打印给我两个坐标,200和200。 第二次打印给我100和100。 第三个印刷品给了我100和100(加上这个,这是一个Pane,并没有明显地改变任何东西而不是原因)。
有没有人知道为什么它会把所有东西都加倍?这是每个相关的课程。
PlayerProjectile类:
public class PlayerProjectile extends Projectile
{
public static final int FIRE_RATE = 5; // Higher is slower
public PlayerProjectile(int x, int y, double dir)
{
super(x, y, dir);
range = 150;
speed = 4;
damage = 20;
nx = (int) (speed * Math.cos(angle));
ny = (int) (speed * Math.sin(angle));
}
@Override
public void update()
{
move();
}
@Override
protected void move()
{
x.setValue(x.getValue() + nx);
y.setValue(y.getValue() + ny);
// if (distance() > range)
// {
// remove();
// }
}
}
弹丸类:
public abstract class Projectile extends Entity
{
final protected int xOrigin, yOrigin;
protected double angle;
protected int nx, ny;
protected double distance;
protected double speed, range, damage;
public Projectile(int x, int y, double dir)
{
super(x, y);
skin = new Circle(x, y, 3);
((Circle) skin).setFill(new Color(0, 1, 0, 1));
xOrigin = x;
yOrigin = y;
angle = dir;
// this.getVisual().translateXProperty().bind(this.x);
// this.getVisual().translateYProperty().bind(this.y);
this.getSkin().layoutXProperty().bind(this.x);
this.getSkin().layoutYProperty().bind(this.y);
// this.getVisual().getChildren().add(skin);
}
protected void move()
{
}
public int getX()
{
return x.getValue().intValue();
}
public int getY()
{
return y.getValue().intValue();
}
public int getOriginX()
{
return xOrigin;
}
public int getOriginY()
{
return yOrigin;
}
}
实体类:
public class Entity
{
private boolean removed = false;
protected Level level;
protected Node skin;
// PROPERTIES FÜR X UND Y KOORDINATEN DES SKINS DES SPIELERS
protected SimpleIntegerProperty x, y;
// VISUELLE REPRÄSENTATION DER ENTITY
// protected Pane visual = new Pane();
public Entity()
{
}
public Entity(int x, int y)
{
this.x = new SimpleIntegerProperty(x);
this.y = new SimpleIntegerProperty(y);
}
public void update()
{
}
public void remove()
{
// Remove from level
removed = true;
}
public void setX(int x)
{
this.x.setValue(x);
}
public void setY(int y)
{
this.y.setValue(y);
}
public void setPosition(Point2D p)
{
this.setX((int) p.getX());
this.setY((int) p.getY());
}
public boolean isRemoved()
{
return removed;
}
public void init(Level level)
{
this.level = level;
}
// public Pane getVisual()
// {
// return visual;
// }
public Node getSkin()
{
return skin;
}
}
答案 0 :(得分:0)
localToScene
从本地坐标转换为场景坐标。本地坐标是相对于调用该方法的节点的原点。转换已包含此节点的layoutX
和layoutY
。因此,给定P = (layoutX, layoutY)
得到的结果是
Inverse(sceneToLocal) * P = Inverse(Inverse(nodeTransform)) * P
= Inverse(Inverse(Translation(P))) * P
= Translation(P) * P
= 2 * P
转换局部坐标系中的原点而不是获得实际位置:
p.setPosition(p.getSkin().localToScreen(0, 0));