2013-09-28 2 views
0

В моей игре есть Canvas object, и этот объект не задан в focus, из-за этого мой snake is not moving on the Board.как я могу установить объект в фокусе

В основном я работаю над проектом snake game, и я хочу, когда play button щелкают от PlayGame.java JDialog, игра должна начаться, но проблема я столкнулся после кнопки gamescreen appearing on window but snake is not moving нажатия, так что кто-то предложить мне, что ваш canvas object is not in focus whenever it is called. поэтому KeyLisener not able to listen to keyPresses /key strokes.

Это класс, в котором объявлен и реализован объект холста.

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();*/ 


      }   
} 

А также я attching метод actionPerformed() кнопки Play, где я имею в виду 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(); 

    }  

Поэтому, пожалуйста, скажите/предложить мне how can i set canvas object in focus.

ответ

3

Предложения от кого-то, кто был там:

  • Ваша проблема фокусировки является действительно XY problem.
  • Вместо этого вы не должны смешивать AWT (Canvas) и Swing-компоненты (JFrame), но вместо этого должны придерживаться все-Свинг компонентов
  • Используйте Key Bindings вместо того, чтобы KeyListener и ваши проблемы фокусировки будет просто растает.
  • Сделайте свой рисунок в методе JPANEL paintComponent(...) согласно this tutorial.
  • Не переопределяйте метод обновления для Swing-приложений.
+0

то как я могу заменить KeyListener на KeyBinding, не затрагивая код, или мне нужно удалить keyListener из моего проекта. –

+0

@AnkushPruthi: это вместо KeyListener. Ознакомьтесь с учебным пособием. Независимо от того, вы действительно должны избавиться от Canvas и всех вещей AWT в любом случае. –

+0

ok Я делаю чек в учебнике, в дальнейшем, если останутся сомнения, я опубликую в поле комментариев. –

Смежные вопросы