2013-10-04 54 views
1

我正在學習Java遊戲開發,並且我正在理解爲什麼「機器人」未移動的問題。 我知道這個問題是與重繪,但我無法弄清楚。Java Applet從另一個類重繪

請幫助

感謝

遊戲類

 public class GameMain extends Applet implements KeyListener { 


private Image image, character; 
private Graphics gpx; 
private Droid droid; 
private URL base; 
private static Background bg1, bg2; 

@Override 
public void init() { 

    setSize(800, 480); 
    setBackground(Color.BLACK); 
    setFocusable(true); 
    addKeyListener(this); 
    Frame frame = (Frame) this.getParent().getParent(); 
    frame.setTitle("My First Game"); 

    droid = new Droid(); 
    base = getDocumentBase(); 
    character = getImage(base, "data/char.png"); 

} 

@Override 
public void start() { 


    GameThread thread = new GameThread(); 
    thread.start(); 
    System.out.println("Thread Started"); 
} 

@Override 
public void stop() { 


} 


@Override 
public void destroy() { 

} 
@Override 
public void update(Graphics g) { 

    if(image == null){ 
     image = createImage(this.getWidth(), this.getHeight()); 
     gpx = image.getGraphics(); 
    } 

    gpx.setColor(getBackground()); 
    gpx.fillRect(0, 0, getWidth(), getHeight()); 
    gpx.setColor(getForeground()); 
    paint(gpx); 

    g.drawImage(image, 0, 0, this); 
} 

@Override 
public void paint(Graphics g) { 
    g.drawImage(character, droid.getPositionX() - 61, droid.getPositionY()- 63, this); 
} 

@Override 
public void keyPressed(KeyEvent key) { 

    switch(key.getKeyCode()){ 
    case KeyEvent.VK_UP: 

     break; 
    case KeyEvent.VK_DOWN: 

     break; 
    case KeyEvent.VK_LEFT: 
     droid.moveLeft(); 
     break; 
    case KeyEvent.VK_RIGHT: 
     droid.moveRight(); 
     break; 
    case KeyEvent.VK_SPACE: 
     droid.jump(); 
     break; 
    } 

} 

@Override 
public void keyReleased(KeyEvent key) { 
    switch(key.getKeyCode()){ 
    case KeyEvent.VK_UP: 

     break; 
    case KeyEvent.VK_DOWN: 

     break; 
    case KeyEvent.VK_LEFT: 
     droid.stop(); 
     break; 
    case KeyEvent.VK_RIGHT: 
     droid.stop(); 
     break; 
    case KeyEvent.VK_SPACE: 

     break; 
    } 
} 



@Override 
public void keyTyped(KeyEvent key) { 
    // TODO Auto-generated method stub 

} 

} 

Thread類

public class GameThread extends Thread { 

GameMain game; 
Droid droid; 

private static Background bg1, bg2; 

public GameThread(){ 

    bg1 = new Background(0,0); 
    bg2 = new Background(2160, 0); 


} 



@Override 
public void run() { 
    game = new GameMain(); 
    droid = new Droid(); 
    //Game while loop 
    while(true){ 

     droid.update(); 
     game.repaint(); 
    //bg1.update(); 
    //bg2.update(); 


    try { 
     Thread.sleep(17); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
} 


} 

的Droid類

 public class Droid { 

private int positionX = 100; 
private int positionY = 382; 

private int speedX = 0; 
private int speedY = 1; 

private boolean jump = false; 

    public void update(){ 

    //Update X Position 
    if(speedX < 0){ 
     positionX += speedX; 

    }else if(speedX == 0){ 
     System.out.println("Do not scroll the background."); 
    }else{ 

     if(positionX <= 150){ 
      positionX += speedX; 

     }else{ 
      System.out.println("Scroll Background Here"); 
     } 
    } 
    //Update Y Position 
    if(positionY + speedY >= 382){ 
     positionY = 382; 
    }else{ 
     positionY += speedY; 
    } 

    //update Jump 

    if(jump == true){ 
     speedY += 1; 

     if(positionY + speedY >= 382){ 
      positionY = 382; 
      speedY = 0; 
      jump = false; 
     } 
    } 
} 

    public void moveRight(){ 
speedX = 6; 
System.out.println(speedX); 
    } 

    public void moveLeft(){ 
speedX = -6; 
System.out.println(speedX); 
    } 

public void stop(){ 
speedX = 0; 
} 
public void jump(){ 
if(jump == false){ 
    speedY = -15; 
    jump = true; 
} 
    } 



public void setPositionX(int positionX){ 

    this.positionX = positionX; 
} 

public int getPositionX(){ 
    return positionX; 
} 

    public void setPositionY(int positionY){ 

    this.positionY = positionY; 
} 

public int getPositionY(){ 
    return positionY; 
} 

public void setSpeedX(int speedX){ 
    this.speedX = speedX; 
} 

public int getSpeedX(){ 
    return speedX; 
} 

public void setSpeedY(int speedY){ 
    this.speedY = speedY; 
} 

public int getSpeedY(){ 
    return speedY; 
} 


     } 
+0

1-小程序已過時,您應該使用'JApplet'; 2 - 我會非常小心地使用'this.getParent()。getParent()',如果你在瀏覽器中部署了這個結果,你可能不喜歡這個結果...... – MadProgrammer

+0

爲了更好地幫助你,請發佈一個[SSCCE](http ://sscce.org/)。 –

+0

順便說一句 - 1)爲什麼要編寫一個小程序?如果這是由於規格。由老師,請參考[爲什麼CS老師應該停止教Java applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/)。 2)爲什麼選擇AWT而不是Swing?在[Swing extras over AWT]上看到這個答案(http://stackoverflow.com/a/6255978/418556)有很多很好的理由放棄使用AWT組件。如果您需要支持較老的基於AWT的API,請參閱[混合重量級和輕量級組件](http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html)。 –

回答

1

的問題是,你正在更新機器人不是droid你畫...其實,你重繪GameMain不是一個是一個屏幕...

public class GameMain extends Applet implements KeyListener { 

    //... 
    private Droid droid; 
    //... 

    @Override 
    public void init() { 
     //... 
     droid = new Droid(); 
     //... 
    } 

    @Override 
    public void paint(Graphics g) { 
     g.drawImage(character, droid.getPositionX() - 61, droid.getPositionY()- 63, this); 
    } 

然後在你GameThread;

public class GameThread extends Thread { 

    GameMain game; 
    Droid droid; 

    //... 

    @Override 
    public void run() { 
     // Created a new GameMain 
     game = new GameMain(); 
     // Created a new Droid... 
     droid = new Droid(); 
     //Game while loop 
     while (true) { 

      droid.update(); 
      game.repaint(); 
      //... 

您創建的GameMainDroid新的情況下,這些沒有連接什麼那麼到屏幕上。

相反,你應該傳遞的GameMain一個參考GameThreadGameThread應該告訴GameMain更新遊戲狀態...

例如...

添加方法updateGameState

public class GameMain extends Applet implements KeyListener { 
    //... 

    public void updateGameState() { 
     droid.update(); 
     repaint(); 
    } 

    //... 

然後在GameMain的啓動方法中,將參考GameMain傳遞給GameThread ...

GameThread thread = new GameThread(this); 
thread.start(); 

然後在GameMain,存儲你傳遞的參考和GameTread#run刪除任何參考Droid

public class GameThread extends Thread { 

    //... 
    private GameMain gameMain; 

    public GameThread(GameMain gameMain) { 
     this.gameMain = gameMain; 
     //... 

然後,調用gameMain.updateGameState(); ...

public void run() { 
    while (true) { 
     gameMain.updateGameState(); 
     try { 
      Thread.sleep(17); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

作爲一個側面說明...

  1. Applet是過時的,你應該使用JApplet的
  2. 我會非常小心使用this.getParent().getParent(),你可能不喜歡的結果,如果你在瀏覽器中部署該..
  3. 當你開始使用JApplet,打動你遊戲渲染到像JPanel,覆蓋它的paintComponent方法,這會給你自動雙緩衝,並使用 Key binding API。它更容易,更容易編程,更新並且不會遭受與焦點相關的問題KeyListener
+0

非常感謝您解釋答案,而不僅僅是爲我解答。 – user2510952

+0

它是完全有道理的,你解釋 – user2510952