Я начал процесс обучения самому java-дизайну игры, и я столкнулся с первым препятствием: у меня есть объект KeyListener, который вызывается прямо сейчас, когда пользователь щелкает правой или левой клавишами. Когда он называется, у меня есть консольная печать «это работает», и я обновляю vel до 1 или -1. Однако, пока консоль печатает vel, не будет обновляться. Почему это?Обновление переменных с помощью EventListener
public class Paddle{
private int width = 100;
private int height = 15;
private int winWidth;
private int posX;
private int posY;
int vel = 0;
Game game;
public Paddle(){
}
public Paddle(int winWidth, int winHeight, Game game){
posX = winWidth/2;
posY = winHeight - 70;
this.winWidth = winWidth;
this.game = game;
}
**public void move(){
if((posX + vel < winWidth) && (posX + vel > 0)){
posX += vel;
}
}**
public void paint(Graphics2D g){
g.setColor(Color.BLACK);
g.fillRect(posX, posY, width, height);
}
**public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
System.out.println("This works");
this.vel = 1;
}
if(e.getKeyCode() == KeyEvent.VK_LEFT){
vel = -1;
}
}
public void keyReleased(KeyEvent e) {
vel = 0;
}**
}
.
public class Keyboard implements KeyListener{
Paddle paddle = new Paddle();
@Override
public void keyPressed(KeyEvent e) {
paddle.keyPressed(e);
}
@Override
public void keyReleased(KeyEvent e) {
paddle.keyReleased(e);
}
@Override
public void keyTyped(KeyEvent e) {
//Not using it
}
}
.
public class Game extends JPanel{
public int width = 900;
public int height = width/16 * 9;
private static boolean running = true;
Ball ball = new Ball(width, height, this);
Paddle paddle = new Paddle(width, height, this);
Keyboard keyboard = new Keyboard();
public Game(){
JFrame frame = new JFrame("Mini Tennis");
this.addKeyListener(keyboard);
this.setFocusable(true);
frame.add(this);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width, height);;
frame.setLocationRelativeTo(null);
System.out.println(frame.getHeight());
}
public void move(){
ball.move();
paddle.move();
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
ball.paint(g2d);
paddle.paint(g2d);
}
public void gameOver(){
running = false;
System.out.println("Game Over");
}
public static void main(String[] args) throws InterruptedException{
Game game = new Game();
while(running){
game.move();
game.repaint();
Thread.sleep(10);
}
}
}
Пока мы находимся в режиме обучения, давайте рассмотрим некоторые неотложные проблемы/улучшения. Как общая рекомендация, вы должны переопределить paintComponent вместо краски, возможно, не имеют большого значения для вас, вы знаете, но может взорваться на вашем лице позже. Я бы избегал использовать поток (или ваш цикл while) в качестве механизма обновления до тех пор, пока у вас не будет лучшего представления о том, что вы делаете, Swing не является потокобезопасным, вместо этого рассмотрите использование таймера Swing. Вы должны избегать KeyListener и предпочитаете API привязки ключей, он исправляет проблемы, связанные с фокусом, и обеспечивает более многократно используемую структуру. – MadProgrammer
Проблема, с которой вы сталкиваетесь, - это экземпляр Paddle, который меняется KeyListener, это не тот, который вы рисуете , Как идея, ваш KeyListener должен устанавливать какую-то переменную состояния (состояния), которая затем передается игровым элементам при выполнении цикла обновления, это отделяет механизм ввода от игровых элементов, что облегчает изменение – MadProgrammer
@MadProgrammer Большое вам спасибо за отзывы! Я обязательно рассмотрю все эти рекомендации. Однако у меня есть два очень глупых вопроса. Что вы имеете в виду, когда говорите игровые элементы, и можете ли вы дать мне пример KeyListener, передающего переменную состояния. Мне жаль, что я некоторое время работал с основами Java, но я только что перешел к разработке игр. –