简体   繁体   English

一旦被另一个类调用,Java图形将不适用于JPanel类

[英]Java- Graphics are not working for JPanel class once called by another class

I created a Calculator that is supposed to prompt a game of Pong when certain keys are pressed. 我创建了一个计算器,该计算器应该在按下某些键时提示您进行Pong游戏。 My pong game was created separately and runs fine by itself. 我的乒乓球游戏是单独创建的,本身运行良好。 However, the graphics refuse to move once it is implemented into my Calculator program. 但是,一旦在我的Calculator程序中实现了图形,图形将拒绝移动。

Below is the KeyAdapter code in the Calculator program that will prompt the Pong game: 下面是Calculator程序中的KeyAdapter代码,它将提示Pong游戏:

 import java.applet.Applet;
 import java.awt.List;
 import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.util.ArrayList;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.swing.JFrame;

 public class Konami extends KeyAdapter {

private ArrayList<Integer> keys  = new ArrayList<Integer>();
private ArrayList<Integer> keysMarked  = new ArrayList< >();


public ArrayList init(){

    keysMarked.add(KeyEvent.VK_UP);
    keysMarked.add(KeyEvent.VK_UP);
    keysMarked.add(KeyEvent.VK_DOWN);
    keysMarked.add(KeyEvent.VK_DOWN);
    keysMarked.add(KeyEvent.VK_LEFT);
    keysMarked.add(KeyEvent.VK_RIGHT);
    keysMarked.add(KeyEvent.VK_LEFT);
    keysMarked.add(KeyEvent.VK_RIGHT);
    keysMarked.add(KeyEvent.VK_B);
    keysMarked.add(KeyEvent.VK_A);

    return keysMarked;
}




@Override
public void keyTyped(KeyEvent event) {

}


@Override
public void keyPressed(KeyEvent event) {

    Konami pong = new Konami();

                keys.add(event.getKeyCode());

                if (keys.size() == keysMarked.size()){
                     if (keys.equals(keysMarked)){
                         System.out.println("PONG GAME");

 //Here I call the Pong game:

                         JFrame newFrame = new JFrame();
                         Pong game = new Pong();
                         game.setVisible(true);
                         newFrame.setBounds(450, 170, 400, 300);
                         newFrame.setResizable(false);
                         newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                         newFrame.add(game);

                         newFrame.setVisible(true);

                      } 
                     else 
                         keys.clear();
                }
                else if (keys.size() > keysMarked.size())
                {
                    keys.clear();
                }
}

@Override
public void keyReleased(KeyEvent event) {
}


}

Here is the code for the Pong game: 这是Pong游戏的代码:

 package cs1302.calc;
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Dimension;
 import java.util.logging.*;
 import java.awt.Graphics;
 import java.awt.event.KeyEvent;
 import static java.lang.Math.abs;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
 import javax.swing.JTextArea;
 import javax.swing.JTextField;

  public class Pong extends JPanel{
int x = 0;
int y = 0;

static int xP = 0;
static int yP = 150;

static int xP2 = 390;
static int yP2 = 150;

int border = 30;
boolean ballGoingDown = true;
boolean ballGoingRight = true;

private void moveBall(){

    if (ballGoingRight == true){
        x = x + 1;
    }

    if (ballGoingRight == false){
        x = x - 1;
    }


    if (ballGoingDown == true){
        y = y + 1;
    }

    if (ballGoingDown == false){
        y = y - 1;
    }

    //detects hit bottom
    if (y== getHeight() - border){
        ballGoingDown = false;
    }

    if (y== 0){
        ballGoingDown = true;
    }


    //detects hit bat
    if (abs(x-xP) <3  &&  abs(y-yP) <30 ){
        ballGoingRight = true;
    }

    if (abs(x-xP2) <23  &&  abs(y-yP2) <30 ){
        ballGoingRight = false;
    }

    //detects ball moving past border
    if (x < 0){
        System.out.println("PLAYER 2 WINS.");
        System.exit(0);
    };

    if (x > getWidth()){
        System.out.println("PLAYER 1 WINS.");
        System.exit(0);
    };

}

private void moveBat(){
    Control c = new Control();


}


@Override
public void paint(Graphics g){
    super.paint(g);
    g.setColor(Color.ORANGE);
    g.fillOval(x, y, 30, 30);

    g.setColor(Color.BLUE);
    g.fillRect(xP, yP, 10,30);


    g.setColor(Color.BLUE);
    g.fillRect(xP2, yP2, 10,30);



}




public static void main2(String s) throws InterruptedException{
        //My window code
       JFrame myFrame = new JFrame("pong");


        myFrame.setBounds(450, 170, 400, 300);
        myFrame.setResizable(false);
       myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       //My game code
       Pong game = new Pong();
       myFrame.add(game);

       game.setFocusable(true);
       game.requestFocusInWindow();
       Control control = new Control();
       game.addKeyListener(control);


       new BorderLayout();
       JTextArea textArea = new JTextArea("Player 1: S Key (up) Z Key(down)"
               + "| Player 2: Up(up) Down (down)");
       game.add(textArea, BorderLayout.PAGE_END);

       myFrame.setVisible(true);


       while (true)
       {
           game.moveBall();
           game.repaint();

           Thread.sleep(10);
       }


}

}

Lastly is the KeyAdapter class that controls the graphics within the Pong game: 最后是KeyAdapter类,用于控制Pong游戏中的图形:

 import java.awt.Graphics;
 import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
 import cs1302.calc.Pong;

  public class Control extends KeyAdapter {

@Override
public void keyTyped(KeyEvent event) {

}

@Override
 public void keyPressed(KeyEvent event) {
      if (event.getKeyCode() == KeyEvent.VK_S){  

          Pong.yP = Pong.yP - 25;
      }
       if (event.getKeyCode() == KeyEvent.VK_Z){        
          Pong.yP = Pong.yP + 25;

      }

        if (event.getKeyCode() == KeyEvent.VK_UP){  
          Pong.yP2 = Pong.yP2 - 25;
      }
       if (event.getKeyCode() == KeyEvent.VK_DOWN){        
          Pong.yP2 = Pong.yP2 + 25;

      }
}

  @Override
public void keyReleased(KeyEvent event) {
}
 }

When you initialize Pong from the KeyListener , the code responsible for the animation is not run at all, since it's in Pong.main2() , and you don't call that code. 当您从KeyListener初始化Pong ,负责动画的代码根本不会运行,因为它位于Pong.main2() ,并且您不会调用该代码。 However, don't simply call that since there are further problems with that approach: 但是,不要简单地这样称呼,因为这种方法还有其他问题:

If Pong.main() is called from anywhere else than the event dispatch thread , like you must be doing when it appears to run correctly, the Pong class initializes its UI incorrectly outside the EDT. 如果从事件分派线程之外的其他任何地方调用Pong.main() ,就像它在正常运行时必须执行的操作一样,则Pong类将在EDT外部错误地初始化其UI。 It also runs a game loop outside the EDT (in the main thread). 它还在EDT外部(在主线程中)运行游戏循环。 That later bug makes it work. 后来的错误使它起作用。

When started from a KeyListener , if you called Pong.main() , or any other method where you implemented the game loop the same way, it would block the EDT and no drawing would happen. KeyListener启动时,如果调用Pong.main()或以相同方式实现游戏循环的任何其他方法,则它将阻塞EDT,并且不会进行绘制。 Instead of a loop, you should use a swing Timer to handle the drawing and updates. 而不是循环,应使用回转计时器来处理图形和更新。 That does not block the event dispatch thread, and it also runs the relevant code correctly in the EDT when it's the time to run it. 这不会阻塞事件分发线程,并且在需要运行时也可以在EDT中正确运行相关代码。

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

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