我创建了一个计算器,当按下某些键时,它应该提示乒乓球游戏。 我的乒乓球游戏是单独创建的,并且本身运行良好。 但是,一旦图形实施到我的计算器程序中,图形就会拒绝移动。
以下是计算器程序中的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) {
}
}
这是乒乓球游戏的代码:
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);
}
}
}
最后是控制Pong游戏中图形的KeyAdapter类:
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 中正确运行相关代码。