2016-04-20 43 views
0

你好同胞程序員,JavaFX localToScene會導致結果變大一倍 - 爲什麼?

我目前正在爲我的研究寫一個小型圖形應用程序,應該在小2D遊戲中展示AI。儘管現在我有點困難。 我已經在頂部用Entity做了一個類層次結構來基本上代表任何實體,如玩家,敵人和障礙物,它具有一個Node屬性,它應該以圖形方式表示實體。實體還具有兩個受保護的SimpleIntegerProperty對象x和y,我將綁定Node屬性的佈局屬性,以便每當更改x和y的值時,圖形表示也會移動。

到目前爲止,我可以做任何不依賴實體對象座標的事情。 Collision works etc. 但是,當我試圖在玩家角色所在的位置(x和y屬性的值)生成子彈(小圓對象)的系統時,出現了雙倍距離的奇怪偏移量玩家必須到左上角(到右下角)。我進行了一些嘗試,看到當我通過localToScene方法檢查座標時,通過兩個屬性的值或者直接使用Node的layoutX和layoutY方法,它會給我座標TWICE AS BIG作爲實際座標。 我的窗格大小爲600x600像素,當我將我的播放器(另一個延伸到實體的對象)放在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處創建了子彈(佈局X和Y也證實了這一點)。然後,我將這個Projectile p2添加到一個ArrayList(不重要)。 第一次打印給了我兩個座標,200和200. 第二次打印給了我100和100. 第三次打印也給了我100和100(此外,這是一個窗格,不會改變任何東西顯然並不是原因)。

有沒有人有線索爲什麼它只是雙打一切?這裏是每個相關的類。

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

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)); 
+0

感謝您的回答,但我還沒有經過真正見過還沒完成。 當我用你建議的替換第一個打印圖像時,我得到(0,0)的值,儘管在視覺上彈丸產生在100,100處,如參數給出的那樣。 我想我仍然不完全瞭解管道是如何工作的。 – Grougal

+0

我的錯。 AFAIK節點當時沒有添加到它的父節點。 – fabian

+0

嗯,我現在很困惑。 我現在正在嘗試使用它,雖然localToScene(0,0)返回正確的值,但視覺上所有東西仍然是偏移的。 我需要做什麼才能使用作爲創建參數的值代表我將它們添加到的窗格座標?如果窗格的大小是600x600,並且我希望彈丸的數量爲300,300,我想給構造函數300和300作爲參數,並且它的視覺效果也是300,300。 – Grougal

相關問題