如何设置焦点对象?

时间:2013-09-28 05:59:30

标签: java swing jbutton keylistener jdialog

我的游戏中有一个Canvas object,而focus中没有设置此对象,因为我的snake is not moving on the Board

基本上我正在处理snake game项目,我想要的是从play button点击PlayGame.java JDialog时,游戏应该开始,但我面临的问题是点击按钮{{1所以有人建议你gamescreen appearing on window but snake is not moving。 这就是为什么canvas object is not in focus whenever it is called

这是声明和实现canvas对象的类。

KeyLisener not able to listen to keyPresses /key strokes

而且我正在使用Play Button的actionPerformed()方法,我指的是package org.psnbtech; import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JFrame; import org.psnbtech.GameBoard.TileType; import org.psnbtech.Snake.Direction; public class Engine extends KeyAdapter { private static final int UPDATES_PER_SECOND = 15; private static final Font FONT_SMALL = new Font("Arial", Font.BOLD, 20); private static final Font FONT_LARGE = new Font("Arial", Font.BOLD, 40); public Canvas canvas; public GameBoard board; public Snake snake; public int score; public boolean gameOver; public Engine(Canvas canvas) { this.canvas = canvas; this.board = new GameBoard(); this.snake = new Snake(board); resetGame(); canvas.addKeyListener(this); //new Engine(canvas).startGame(); } public void startGame() { canvas.createBufferStrategy(2); Graphics2D g = (Graphics2D)canvas.getBufferStrategy().getDrawGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); long start = 0L; long sleepDuration = 0L; while(true) { start = System.currentTimeMillis(); update(); render(g); canvas.getBufferStrategy().show(); g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); sleepDuration = (1500L / UPDATES_PER_SECOND) - (System.currentTimeMillis() - start); if(sleepDuration > 0) { try { Thread.sleep(sleepDuration); } catch(Exception e) { e.printStackTrace(); } } } } public void update() { if(gameOver || !canvas.isFocusable()) { return; } TileType snakeTile = snake.updateSnake(); if(snakeTile == null || snakeTile.equals(TileType.SNAKE)) { gameOver = true; } else if(snakeTile.equals(TileType.FRUIT)) { score += 10; spawnFruit(); } } public void render(Graphics2D g) { board.draw(g); g.setColor(Color.WHITE); if(gameOver) { g.setFont(FONT_LARGE); String message = new String("Your Score: " + score); g.drawString(message, canvas.getWidth() / 2 - (g.getFontMetrics().stringWidth(message) / 2), 250); g.setFont(FONT_SMALL); message = new String("Press Enter to Restart the Game"); g.drawString(message, canvas.getWidth() / 2 - (g.getFontMetrics().stringWidth(message) / 2), 350); } else { g.setFont(FONT_SMALL); g.drawString("Score:" + score, 10, 20); } } public void resetGame() { board.resetBoard(); snake.resetSnake(); score = 0; gameOver = false; spawnFruit(); } public void spawnFruit() { int random = (int)(Math.random() * ((GameBoard.MAP_SIZE * GameBoard.MAP_SIZE) - snake.getSnakeLength())); // if '*' replace by '/' then only one fruit is there for snake int emptyFound = 0; int index = 0; while(emptyFound < random) { index++; if(board.getTile(index % GameBoard.MAP_SIZE, index / GameBoard.MAP_SIZE).equals(TileType.EMPTY)) { // if '/' replaced by '*' then nothing displays on the board emptyFound++; } } board.setTile(index % GameBoard.MAP_SIZE, index / GameBoard.MAP_SIZE, TileType.FRUIT); // it also show nothing when replacing '/' by '/' } @Override public void keyPressed(KeyEvent e) { if((e.getKeyCode() == KeyEvent.VK_UP)||(e.getKeyCode() == KeyEvent.VK_W)) { snake.setDirection(Direction.UP); } if((e.getKeyCode() == KeyEvent.VK_DOWN)||(e.getKeyCode() == KeyEvent.VK_S)) { snake.setDirection(Direction.DOWN); } if((e.getKeyCode() == KeyEvent.VK_LEFT)||(e.getKeyCode() == KeyEvent.VK_A)) { snake.setDirection(Direction.LEFT); } if((e.getKeyCode() == KeyEvent.VK_RIGHT)||(e.getKeyCode() == KeyEvent.VK_D)) { snake.setDirection(Direction.RIGHT); } if(e.getKeyCode() == KeyEvent.VK_ENTER && gameOver) { resetGame(); } } public static void main(String[] args) { new PlayGame().setVisible(true); /**JFrame frame = new JFrame("SnakeGame"); frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); frame.setResizable(false); Canvas canvas = new Canvas(); canvas.setBackground(Color.black); canvas.setPreferredSize(new Dimension(GameBoard.MAP_SIZE * GameBoard.TILE_SIZE, GameBoard.MAP_SIZE * GameBoard.TILE_SIZE)); frame.getContentPane().add(canvas); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); new Engine(canvas).startGame();*/ } }

canvas object

所以请告诉/建议我private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { JFrame frame = new JFrame("SnakeGame"); frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); frame.setResizable(false); Canvas canvas = new Canvas(); canvas.setBackground(Color.black); canvas.setPreferredSize(new Dimension(GameBoard.MAP_SIZE *GameBoard.TILE_SIZE,GameBoard.MAP_SIZE * GameBoard.TILE_SIZE)); frame.add(canvas); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); new Engine(canvas).startGame(); }

1 个答案:

答案 0 :(得分:3)

来自某人的建议:

  • 您的焦点问题实际上是XY problem
  • 相反,你不应该混合使用AWT(Canvas)和Swing(JFrame)组件,而应该坚持使用所有Swing组件
  • 使用Key Bindings代替KeyListener,您的焦点问题就会消失。
  • 根据this tutorial在JPanel的paintComponent(...)方法中绘制您的绘图。
  • 不要覆盖Swing应用的更新方法。