There is a Canvas object in my game and this object is not set in focus, because of this my snake is not moving on the Board .
Basically i am working on snake game project, and i want is when play button is clicked from PlayGame.java JDialog ,game should start ,but problem i am facing is after clicking button gamescreen appearing on window but snake is not moving, so someone suggest me that your canvas object is not in focus whenever it is called. that is why KeyLisener not able to listen to keyPresses /key strokes.
This is the class in which canvas object is declared and implemented.
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();*/ } }
And also i am attching actionPerformed() method of Play Button where i am referring 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(); }
--- Update ---
So please tell/suggest me how can i set canvas object in focus