问题
I am trying to make my first game without the help a youtube video. I have watched many youtube series about making java games and they never where what I wanted to do, so after learning enough I started making my own game. I know enough Java to get around and so far everything has worked with no issues.
I have tried searching for some help but all I could find where people saying the try something along the lines of:
setFocusable(true);
requestFocus();
This however has not worked for me. I know that most people would not like to just look through all my code but I think it will be manageable (Its not that much code yet).
I plan on making it a sort of snake like game where you get bigger instead of longer and you are a guinea pig (represented by the orange rectangle for now) instead of a snake.
Game.java:
package com.kaperly.game;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JFrame {
private static final long serialVersionUID = 1L;
public static JFrame frame;
public static JPanel panel;
public static int width = 1000;
public static int height = 600;
public Game() {
frame = new JFrame();
panel = new Panel();
frame.setPreferredSize(new Dimension(width, height));
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Guinea Pig Eat");
frame.setLayout(new BorderLayout());
frame.setVisible(true);
panel.setFocusable(true);
panel.requestFocus(true);
frame.add(panel, BorderLayout.CENTER);
frame.pack();
}
public static void init() {
}
public static void loop() throws InterruptedException { while(true) {
Character.move();
Thread.sleep(10);
}}
public static void main(String[] args) throws InterruptedException, IOException {
Game game = new Game();
init();
loop();
}
}
Panel.java:
package com.kaperly.game;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
public class Panel extends JPanel implements KeyListener {
private static final long serialVersionUID = 1L;
public static Image startButton;
public static boolean goingRight = false;
public static boolean goingLeft = false;
public static boolean goingUp = false;
public static boolean goingDown = false;
private static int changeDirection = 0;
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W) {
goingUp = true;
changeDirection = 1;
System.out.println("Moved Up!");
}else if(e.getKeyCode() == KeyEvent.VK_A) {
goingLeft = true;
changeDirection = 2;
}else if(e.getKeyCode() == KeyEvent.VK_S) {
goingDown = true;
changeDirection = 3;
}else if(e.getKeyCode() == KeyEvent.VK_D) {
goingRight = true;
changeDirection = 4;
}else if(changeDirection == (1 | 2 | 3 | 4)) {
changeDirection = 0;
if(changeDirection == 1) {
goingLeft = false;
goingDown = false;
goingRight = false;
}else if(changeDirection == 2) {
goingUp = false;
goingDown = false;
goingRight = false;
}else if(changeDirection == 3) {
goingUp = false;
goingLeft = false;
goingRight = false;
}else if(changeDirection == 4) {
goingUp = false;
goingLeft = false;
goingDown = false;
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Set background color
g.setColor(Color.GRAY);
g.fillRect(0, 0, Game.width, Game.height);
//Make Walls
g.setColor(Color.BLACK);
g.fillRect(0, 0, Game.width, 25);
g.fillRect(0, 550, Game.width, 25);
g.fillRect(0, 0, 25, Game.height);
g.fillRect(970, 0, 25, Game.height);
//Show Character
g.setColor(Color.ORANGE);
g.fillRect(Character.x, Character.y, Character.width, Character.height);
repaint();
}
}
Character.java:
package com.kaperly.game;
public class Character {
public static int x = 475;
public static int y = 250;
public static int width = 50;
public static int height = 75;
public static void move() {
if(Panel.goingUp == true) {
y = y ++;
}
if(Panel.goingLeft == true) {
x = x --;
}
if(Panel.goingDown == true) {
y = y --;
}
if(Panel.goingRight == true) {
x = x ++;
}
}
}
回答1:
KeyListener should be avoid BECAUSE of it's inherent focus related issues. You never know what might take keyboard focus away from your component.
Instead, take advantage of the Key Bindings API, which allows you to control the focus level required to trigger your key events.
It will also allow you to reuse underlying Action associated with the key binding in other places...
You'd be wise to rename you class Panel to something more meaningful. AWT already has a Panel class and it would be very easy to confuse the two
回答2:
KeyListener has 2 big issues, they are binded for all keys and besides component must be focusable and in focus, JPanel is not focusable by default.
It's strongly dicourage the use of requestFocus see the api.
Instead of that you can use KeyBindings where you bind a specific key an action.
You may interested in @camickr blog where he post swing utils things like this Motion using the keyboard.
Also don't call a class Panel cause it's JPanel parent class name , it's gives to confusion.
Change this:
public class Game extends JFrame {
private JFrame frame;
}
to
public class Game {
private JFrame frame;
}
Another thing don't implement KeyListener at top level class, instead of that use anonymous classes or private classes you are breaking Single Responsability Principle
回答3:
You need to register the keylistener on either your game or panel class. The docs have this to say:
The listener object created from that class is then registered with a component using the component's addKeyListener method. A keyboard event is generated when a key is pressed, released, or typed. The relevant method in the listener object is then invoked, and the KeyEvent is passed to it.
So in Panel you could do the following
public Panel(){
addKeyListener(this);
}
There are other things wrong with your code but this should have input working.
来源:https://stackoverflow.com/questions/18029136/keylistener-not-working-requestfocus-not-fixing-it