簡體   English   中英

有沒有辦法可以輪換一個 object 而不是兩個?

[英]Is there a way I can rotate one object and not both of them?

我正在從事一個具有 GUI 和移動坦克的項目。 雖然坦克移動得很好,但我無法弄清楚如何單獨移動/旋轉它們。 我還需要清理我的代碼,因為我覺得我有很多額外的事情要做。

這是一些代碼,這是我嘗試過的。

我有四個班級。 導彈坦克董事會 我在Tank class 中調用 keylisteners。我應該在 doDrawing 方法中這樣做嗎? doDrawing方法在Board class中。

private void doDrawing(Graphics g)
{
    final double rads = Math.toRadians(120);
    final double sin = Math.abs(Math.sin(rads));
    final double cos = Math.abs(Math.cos(rads));
    final int w = (int) Math.floor(tank1.getX() * cos + tank1.getX() * sin);
    final int h = (int) Math.floor(tank1.getY() * cos + tank1.getY() * sin);

    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(w, h);
    g2d.rotate(rot, tank1.getX(), tank1.getY());

    AffineTransform backup = g2d.getTransform();
    AffineTransform trans = new AffineTransform();

    g2d.setTransform(backup);
    //g2d.drawImage(tank1.getImage(), tank1.getX(), tank1.getY(), this);

    trans.setToIdentity();
    trans.rotate(rot, h, w);
    trans.translate(h, w);
    trans.setTransform(backup);

    g2d.drawImage(tank1.getImage(), tank1.getX(), tank1.getY(), this);

    //g2d.drawImage(tank1.getImage(), tank1.getX(), tank1.getY(), this);
    g2d.drawImage(tank2.getImage(), tank2.getX(), tank2.getY(), this);

    List<Missile> missiles = tank1.getMissiles();

    for (Missile missile : missiles)
    {
        //trans.rotate(Math.toRadians(rads), w/2, h/2);
        g2d.drawImage(missile.getImage(), missile.getX(), missile.getY() - 7, this);
        //g2d.rotate(rot, missile.getX(), missile.getY() - 7);
    }
}

所以,只是看着...

private void doDrawing(Graphics g)
{
    //...
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(w, h);
    g2d.rotate(rot, tank1.getX(), tank1.getY());

    AffineTransform backup = g2d.getTransform();
    AffineTransform trans = new AffineTransform();
    
    g2d.setTransform(backup);
    //g2d.drawImage(tank1.getImage(), tank1.getX(), tank1.getY(), this);
    
    trans.setToIdentity();
    trans.rotate(rot, h, w); 
    trans.translate(h,w);
    trans.setTransform(backup);
                
    g2d.drawImage(tank1.getImage(), tank1.getX(), tank1.getY(), this);
    g2d.drawImage(tank2.getImage(), tank2.getX(), tank2.getY(), this);
    //...
}

很明顯,您正在對Graphics上下文應用一個永遠不會撤消的轉換,因此在它之后繪制的所有內容都將應用相同的轉換。

您需要做的第一件事是分解繪制邏輯,以便它可以繪制單個實體。

您需要做的第二件事是在對其進行任何修改之前創建Graphics上下文的副本,這將防止父副本繼續進行這些修改,這些修改將與未來的修改混合在一起。

也許像...

private void doDrawing(Graphics g) {
    // Because I don't trust anybody
    Graphics2D g2d = (Graphics2D) g.create();
    drawTank(tank1, g2d);
    g2d.dispose();
    g2d = (Graphics2D) g.create();
    drawTank(tank2, g2d);
    g2d.dispose();
}

private void drawTank(Tank tank, Graphics2D g) {
    final double rads = Math.toRadians(120);
    final double sin = Math.abs(Math.sin(rads));
    final double cos = Math.abs(Math.cos(rads));
    final int w = (int) Math.floor(tank.getX() * cos + tank.getX() * sin);
    final int h = (int) Math.floor(tank.getY() * cos + tank.getY() * sin);

    Graphics2D g2d = (Graphics2D) g.create();
    g2d.translate(w, h);
    // `rot` should be derived from the tank ... no idea where this is
    g2d.translate(tank.getX(), tank.getY());
    // Origin has now been translated to the tanks position
    g2d.rotate(rot, 0, 0);
    g2d.drawImage(tank.getImage(), 0, 0, this);
    
    // We no longer to need to keep these resources
    g2d.dispose();
    // Create a new "clean" copy
    g2d = (Graphics2D) g.create();
    // I don't know if it's needed, but I would, personally, calculate
    // any required rotation again, but that's me
    List<Missile> missiles = tank1.getMissiles();
    for (Missile missile : missiles) {
        g2d.drawImage(missile.getImage(), missile.getX(), missile.getY() - 7, this);
    }
}

例如,參見:

建議:

  1. 使用模型視圖代碼結構將邏輯與顯示分開
  2. 為此,創建一個 Tank邏輯class,它知道自己的 position和自己的方向(或角度),並將您的java.util.List<Tank>保存在程序的 model 中。
  3. 在聽眾中更改 Tank position 和方向。
  4. 僅使用視圖類(GUI 類)來 a) 繪制類的 model 的 state 和 b) 從用戶那里獲取輸入。
  5. 側面建議:如果這是 Swing,請避免使用 KeyListeners,而是使用Key Bindings
  6. 您可以為每個坦克使用單獨的仿射變換

如果您的坦克同步移動/旋轉,我想原因是它們都收到相同的關鍵事件並以相同的方式做出反應。

將按鍵監聽器(或另一個答案中建議的更好的按鍵綁定)放入您的板 class。監聽器將檢查按下/釋放哪個鍵,並向正確的坦克發出移動或轉動或其他任何命令。 這樣你就可以讓一個坦克對 WASD 做出反應,而另一個坦克對上/下/左/右做出反應。

然而,坦克 class 中的方法不會對關鍵事件做出反應,但可以命名為前進、后退、左轉、右轉。

doDrawing 方法應該像它的名字所暗示的那樣做:只是執行繪圖。 這可能會發生任何次數以獲得良好的屏幕刷新率或在另一個 window 不再隱藏您的游戲后重新繪制棋盤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM