在我的游戏中有一个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();*/
}
}
而且我正在附加我所指的播放按钮的 actionPerformed() 方法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
。