Java Applet从另一个类重新绘制

时间:2013-10-04 05:09:38

标签: java applet awt paint keylistener

我正在学习Java游戏开发,而我正在理解为什么" Robot"没动。 我知道问题在于重画,但我无法弄明白。

请帮助

感谢

游戏类

     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

}

 }

线程类

    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 Class

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


      }

1 个答案:

答案 0 :(得分: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的引用传递给GameThread,而GameThread应该告诉GameMain更新游戏状态......

例如......

添加方法updateGameState

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

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

    //...

然后在GameMain的start方法中,将GameMain的引用传递给GameThread ...

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

然后在GameMain中,存储您传递的引用并删除对Droid的任何引用

public class GameThread extends Thread {

    //...
    private GameMain gameMain;

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

然后在GameTread#run中,拨打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方法,这将为您提供自动双缓冲并使用{{3} } KeyListener以上。它更容易,以编程方式,可更新,并且不会遇到与KeyListener
  4. 相同的焦点相关问题