繁体   English   中英

Java Applet从另一个类重绘

[英]Java Applet repaint from another class

我正在学习Java游戏开发,并且在理解为什么“机器人”不动时遇到问题。 我知道问题在于重涂,但我无法弄清楚。

请帮忙

谢谢

游戏类

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


 }

机器人类

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


      }

问题是,您要更新的droid不是您正在绘画的droid ...实际上,您要重新绘画的GameMain不是屏幕上的那个droid ...

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与屏幕之间没有任何连接。

相反,您应该GameMain的引用GameMainGameThread并且GameThread应该告诉GameMain更新游戏状态...

例如...

添加方法updateGameState

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

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

    //...

然后在GameMain的start方法中,将GameMain的引用GameMainGameThread ...

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方法,这将为您提供自动双重缓冲并在KeyListener使用Key绑定API 它更容易通过编程方式进行更新,并且不会遇到与KeyListener相同的焦点相关问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM