[英]Java- Graphics are not working for JPanel class once called by another class
我创建了一个计算器,该计算器应该在按下某些键时提示您进行Pong游戏。 我的乒乓球游戏是单独创建的,本身运行良好。 但是,一旦在我的Calculator程序中实现了图形,图形将拒绝移动。
下面是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) {
}
}
这是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);
}
}
}
最后是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) {
}
}
当您从KeyListener
初始化Pong
,负责动画的代码根本不会运行,因为它位于Pong.main2()
,并且您不会调用该代码。 但是,不要简单地这样称呼,因为这种方法还有其他问题:
如果从事件分派线程之外的其他任何地方调用Pong.main()
,就像它在正常运行时必须执行的操作一样,则Pong
类将在EDT外部错误地初始化其UI。 它还在EDT外部(在主线程中)运行游戏循环。 后来的错误使它起作用。
从KeyListener
启动时,如果调用Pong.main()
或以相同方式实现游戏循环的任何其他方法,则它将阻塞EDT,并且不会进行绘制。 而不是循环,应使用回转计时器来处理图形和更新。 这不会阻塞事件分发线程,并且在需要运行时也可以在EDT中正确运行相关代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.