基本上,我被建议使用键绑定而不是键侦听器,并且我很难找到一种使键绑定正常工作的方法。我相信问题又来自于焦点。
我想做的基本上只是让图像根据箭头键的输入移动。但问题本身可能是再次没有正确聚焦。
import javax.swing.JFrame;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Test extends JFrame implements ActionListener {
CardLayout crd;
JButton btn1, btn2, btn3, btn4;
Container cPane;
JPanel cPanel = new JPanel();
JPanel jPanel1,jPanel2,jPanel3;
Board board = new Board();
private int currCard = 1;
GridBagConstraints c = new GridBagConstraints();
Test() {
jPanel1 = new JPanel();
jPanel2 = new JPanel();
jPanel3 = new JPanel();
btn1 = new JButton("Start");
btn2 = new JButton("Help");
btn3 = new JButton("Back");
btn4 = new JButton("Exit");
cPane = getContentPane();
crd = new CardLayout();
cPanel.setLayout(crd);
buttons();
panel1();
panel2();
panel3();
cPanel.add(jPanel1, "1");
cPanel.add(jPanel2, "2");
cPanel.add(jPanel3, "3");
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
currCard = 3;
crd.show(cPanel, "" + (currCard));
board.setFocusable(true);
board.player.requestFocusInWindow();
}
});
btn2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
currCard = 2;
crd.show(cPanel, "" + (currCard));
}
});
btn3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
currCard = 1;
crd.show(cPanel, ""+ (currCard));
}
});
btn4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
getContentPane().add(cPanel);
}
void panel1() {
jPanel1.setBackground(Color.black);
jPanel1.setLayout(new GridBagLayout());
// Set the layout to GridBagLayout
c.fill = GridBagConstraints.CENTER;
c.insets = new Insets(15, 0, 0, 0); // Add vertical padding
jPanel1.add(btn1, c);
c.gridy = 1;
jPanel1.add(btn2, c);
c.gridy = 2;
jPanel1.add(btn4, c);
}
void panel2() {
JTextArea textField = new JTextArea("How to play: \n \nSpace bar to shoot.\nArrow keys to move around\nP to pause \nQ to go back to main menu \n \n"
+ "Protect Earth from the invading forces\nShoot down the enemies,\nGather powerups and protect your allies \nAvoid enemy fire your ship is fragile");
textField.setEditable(false);
textField.setHighlighter(null);
Font font = new Font("Courier", Font.BOLD, 35);
textField.setFont(font);
textField.setPreferredSize(new Dimension(500, 940));
textField.setForeground(Color.WHITE);
textField.setBackground(Color.black);
jPanel2.setBackground(Color.black);
jPanel2.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST; // Align component to the upper left corner
gbc.insets = new Insets(15, 0, 0, 0); // Add vertical padding
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0; // Expand horizontally
gbc.weighty = 0.5; // Expand vertically
jPanel2.add(textField, gbc);
gbc.gridx = 0;
gbc.gridy = 1; // Set the grid position for btn3
gbc.anchor = GridBagConstraints.NORTH; // Align component to the upper left corner
jPanel2.add(btn3, gbc);
}
void panel3() {
jPanel3.setLayout(new BorderLayout(0, 0));
jPanel3.add(board);
}
void buttons() {
// make the buttons look better and make it so they look good with the background, chane the size of them
btn1.setPreferredSize(new Dimension(75, 50));
btn1.setBackground(Color.black);
btn1.setForeground(Color.WHITE);
btn2.setPreferredSize(new Dimension(75, 50));
btn2.setBackground(Color.black);
btn2.setForeground(Color.WHITE);
btn3.setPreferredSize(new Dimension(75, 50));
btn3.setBackground(Color.black);
btn3.setForeground(Color.WHITE);
btn4.setPreferredSize(new Dimension(75, 50));
btn4.setBackground(Color.black);
btn4.setForeground(Color.WHITE);
}
public static void main(String argvs[]) {
System.out.println("aaa" + System.getProperty("user.dir"));
Test frame = new Test();
frame.setTitle("Space invaders");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent arg0) {
throw new UnsupportedOperationException("Unimplemented method 'actionPerformed'");
}
}
public class Board extends JPanel implements ActionListener {
Player player = new Player();
Timer timer=new Timer(2, this);
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
public Board(){
//addKeyListener((KeyListener) player);
//setFocusable(true);
timer.start();
}
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, (int)size.getWidth(), (int)size.getHeight());
/* g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, 3000, 3000);
g.setColor(Color.WHITE);
g.drawRect (20, 20, 864, 624);
g.setColor(Color.BLACK);
g.fillRect (21, 21, 863, 623);
g.setColor(Color.WHITE);
g.setFont(new Font("arial",Font.PLAIN,14)); */
player.paintComponent(g);
//repaint();
}
public void board(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Stroke stroke1 = new BasicStroke(4f);
g2d.setColor(Color.white);
g2d.setStroke(stroke1);
g2d.drawRect(20, 50, 850, 600);
g2d.setColor(Color.white);
float[] dashingPattern2 = {10f, 4f};
Stroke stroke2 = new BasicStroke(4f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 1.0f, dashingPattern2, 0.0f);
g2d.setStroke(stroke2);
g2d.drawLine(448, 50, 448, 650);
g.setFont(new Font("arial",Font.PLAIN,30));
}
public void actionPerformed(ActionEvent ev){
if(ev.getSource()==timer){
repaint();// this will call at every 1 second
}
}
}
public class Player extends JPanel {
private BufferedImage image;
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
private int playerX, playerY; // Position of the player
private double rotationAngle; // Angle in radians
public Player() {
setFocusable(true);
try {
image = ImageIO.read(getClass().getResourceAsStream("add what your path to an image is"));
} catch (IOException e) {
e.printStackTrace();
}
playerX = (int)(size.getWidth()/2);
playerY = (int)(size.getHeight()/2);
rotationAngle = 0;
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "moveUp");
getActionMap().put("moveUp", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
moveForward();
}
});
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DOWN"), "moveDown");
getActionMap().put("moveDown", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
moveForward();
}
});
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "rotateLeft");
getActionMap().put("rotateLeft", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
rotateLeft();
}
});
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "rotateRight");
getActionMap().put("rotateRight", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
rotateRight();
}
});
}
public void moveForward() {
System.out.print("test test");
int moveDistance = 5;
playerX += moveDistance * Math.sin(rotationAngle);
playerY -= moveDistance * Math.cos(rotationAngle);
repaint();
}
public void moveBackward() {
int moveDistance = 5;
playerX -= moveDistance * Math.sin(rotationAngle);
playerY += moveDistance * Math.cos(rotationAngle);
repaint();
}
public void rotateLeft() {
rotationAngle -= Math.toRadians(5);
repaint();
}
public void rotateRight() {
rotationAngle += Math.toRadians(5);
repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
AffineTransform oldTransform = g2d.getTransform(); // Save the current transform
AffineTransform rotationTransform = new AffineTransform();
rotationTransform.rotate(rotationAngle, playerX + image.getWidth() / 2, playerY + image.getHeight() / 2);
g2d.setTransform(rotationTransform);
g2d.drawImage(image, playerX, playerY, null);
g2d.setTransform(oldTransform); // Restore the original transform
}
@Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(), image.getHeight());
}
}
问题已解决,我忘了简单地将玩家添加到棋盘上。