1

我正在学习 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;
}


      }
4

1 回答 1

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();
            //...

GameMain您创建and的新实例Droid,它们与屏幕没有任何联系。

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

例如...

添加方法updateGameState

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

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

    //...

然后在GameMain's start 方法中,传递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方法,这将为你提供自动双缓冲并使用Key binding API over KeyListener。它更容易、以编程方式、可更新,并且不会遇到与焦点相关的问题KeyListener
于 2013-10-04T05:51:51.390 回答