JavaFX localToScene会导致结果的两倍 - 为什么?

时间:2016-04-20 21:36:25

标签: java javafx

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

}

1 个答案:

答案 0 :(得分:0)

localToScene从本地坐标转换为场景坐标。本地坐标是相对于调用该方法的节点的原点。转换已包含此节点的layoutXlayoutY。因此,给定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));