简体   繁体   English

Java Applet从另一个类重绘

[英]Java Applet repaint from another class

I am learning Java game development and I am having an issue understanding why the "Robot" is not moving. 我正在学习Java游戏开发,并且在理解为什么“机器人”不动时遇到问题。 I know the issue is with the repaint but I can not figure it out. 我知道问题在于重涂,但我无法弄清楚。

please help 请帮忙

Thank 谢谢

Game Class 游戏类

     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 Class 螺纹类

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


      }

The problem is, the droid you're updating isn't the droid you're painting...in fact, the GameMain you're repainting isn't the one that is one the screen... 问题是,您要更新的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);
    }

And then in you GameThread ; 然后在您的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();
            //...

You create new instances of GameMain and Droid , these have no connection what so ever to the screen. 您创建GameMainDroid新实例, GameMain与屏幕之间没有任何连接。

Instead, you should be passing a reference of GameMain to the GameThread and GameThread should be telling GameMain to update the game state... 相反,您应该GameMain的引用GameMainGameThread并且GameThread应该告诉GameMain更新游戏状态...

For example... 例如...

Add the method updateGameState 添加方法updateGameState

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

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

    //...

Then in GameMain 's start method, pass a reference of GameMain to GameThread ... 然后在GameMain的start方法中,将GameMain的引用GameMainGameThread ...

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

Then in GameMain , store the reference you are passed and remove any reference to Droid 然后在GameMain ,存储您传递的引用,并删除对Droid任何引用

public class GameThread extends Thread {

    //...
    private GameMain gameMain;

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

Then in GameTread#run , call gameMain.updateGameState(); 然后在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();
        }
    }
}

As a side note... 作为旁注...

  1. Applet is outdated, you should be using JApplet Applet已过时,您应该使用JApplet
  2. I'd be very careful using this.getParent().getParent() , you may not like the results if you deployed this in a browser.. 使用this.getParent().getParent() ,我会非常小心,如果将其部署在浏览器中,则可能不喜欢结果。
  3. And when you start using JApplet , move you game rendering to something like JPanel , overriding it's paintComponent method, this will give you automatic double buffering and use the Key binding API over KeyListener . 当您开始使用JApplet ,将游戏渲染移至JPanel ,并覆盖其paintComponent方法,这将为您提供自动双重缓冲并在KeyListener使用Key绑定API It's more easily, programmatically, updatable and doesn't suffer from the same focus related issues as KeyListener 它更容易通过编程方式进行更新,并且不会遇到与KeyListener相同的焦点相关问题

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

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