Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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

Java
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();

    }       


So please tell/suggest me how can i set canvas object in focus
Posted
Updated 27-Sep-13 21:28pm
v2
Comments
Richard MacCutchan 28-Sep-13 3:48am    
You need to call the render and update methods repeatedly, in a timed loop, each time checking for changes in direction etc. In your code, you only call them once, in the startGame method.
Member 10276989 28-Sep-13 4:35am    
in which code section i have to call these methods repeatidly..
Richard MacCutchan 28-Sep-13 4:43am    
Create a method that will loop continuously (until some flag is set), you could call it runGame for example. Then set that going after you have called the startGame method.
Member 10276989 28-Sep-13 4:54am    
so basically i have to call startGame() method inside/from runGame() method. and create a loop inside runGame() method and create a flag/boolean variable.
Richard MacCutchan 28-Sep-13 4:56am    
That should do it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900