问题遇到的现象和发生背景
贪吃蛇运行正常,但是键盘操控不了,且帮助点击不会跳转。
问题相关代码,请勿粘贴截图
包关系:
controller包:
package controller;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;
import object.Food;
import object.Ground;
import object.Snake;
import listener.SnakeListener;
import view.BottonPanel;
import view.GamePanel;
import view.Menu;
public class Controller extends KeyAdapter implements SnakeListener {
private Snake snake;
private Food food;
private Ground ground;
private GamePanel gamePanel;
private Menu menu;
private BottonPanel bottonPanel;
public Controller(Snake snake,Food food,Ground ground,Menu menu,GamePanel gamePanel,BottonPanel bottonPanel) {
this.snake=snake;
this.food=food;
this.ground=ground;
this.gamePanel=gamePanel;
this.menu= menu;
this.bottonPanel=bottonPanel;
init();
}
public void init() {
bottonPanel.getStartButton().addActionListener( new startHandler());
bottonPanel.getPauseButton().addActionListener(new pauseHandler());
bottonPanel.getEndButton().addActionListener(new endHandler());
menu.getitem1().addActionListener(new Item1Handler());
menu.getitem2().addActionListener(new Item2Handler());
menu.getitem3().addActionListener(new Item3Handler());
menu.getitem4().addActionListener(new Item4Handler());
menu.getSpItem1().addActionListener(new spItem1Handler());
menu.getSpItem2().addActionListener(new spItem2Handler());
menu.getSpItem3().addActionListener(new spItem3Handler());
menu.getSpItem4().addActionListener(new spItem4Handler());
menu.getMapItem1().addActionListener(new mapItem1Handler());
//menu.getmapItem2().addActionListener(new mapItem2Handler());
//menu.getmapItem3().addActionListener(new mapItem3Handler());
menu.getHelpMenu().addActionListener(new helpItemHandler());
bottonPanel.getStartButton().setEnabled(true);
}
/**********获取对象*************/
public Snake getSnake() {
return snake;
}
public Ground getGround() {
return ground;
}
public GamePanel getGamePanel() {
return gamePanel;
}
public Menu getMenu() {
return menu;
}
public BottonPanel getBottonPanel() {
return bottonPanel;
}
/*********键盘**********/
@Override
public void KeyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
/*case KeyEvent.VK_UP:
snake.changeDirection(Snake.UP);
break;
case KeyEvent.VK_DOWN:
snake.changeDirection(Snake.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.changeDirection(Snake.LEFT);
break;
case KeyEvent.VK_RIGHT:
snake.changeDirection(Snake.RIGHT);
break;
case KeyEvent.VK_W:
snake.speedUp();
break;
case KeyEvent.VK_S:
snake.speedDown();
break;
default:
break;*/
case KeyEvent.VK_I:
snake.changeDirection(Snake.I);
break;
case KeyEvent.VK_K:
snake.changeDirection(Snake.K);
break;
case KeyEvent.VK_J:
snake.changeDirection(Snake.J);
break;
case KeyEvent.VK_L:
snake.changeDirection(Snake.L);
break;
case KeyEvent.VK_W:
snake.speedUp();
break;
case KeyEvent.VK_S:
snake.speedDown();
break;
default:
break;
}
}
@Override
public void snakeMoved(Snake sanke) {
gamePanel.display(sanke, food, ground); //移动更新面板
if(food.isFoodEated(sanke)) {
snake.eatFood();
food.newFood(ground.getPoint());
bottonPanel.repaint(); //更新分数板
setScore();
}
if(ground.RockEat(sanke)) { //碰到石头
snake.die();
bottonPanel.getStartButton().setEnabled(true);
}
if(snake.isEatBody()) { //碰到身体
snake.die();
bottonPanel.getStartButton().setEnabled(true);
}
}
public void setScore() {
int score = snake.getFoodCount();
bottonPanel.setScore(score);
}
/******开始新游戏***********/
public void newGame() {
ground.clear();
switch(ground.getMapType()) { //地图类型
case 1:
ground.setRocks();
break;
case 2:
ground.setRocks();
break;
case 3:
ground.setRocks();
break;
}
food.newFood(ground.getPoint());
bottonPanel.setScore(0);
bottonPanel.repaint();
}
/*********游戏监听*********/
class startHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent arg0) {
gamePanel.requestFocus(true);
snake.clear();
snake.init();
snake.begin();
newGame();
bottonPanel.getStartButton().setEnabled(false);
}
}
/*******暂停键***********/
class pauseHandler implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.requestFocus(true);
snake.changePause();
if(e.getActionCommand()=="暂停游戏")
bottonPanel.getPauseButton().setText("继续游戏");
else {
bottonPanel.getPauseButton().setText("暂停游戏");
}
}
}
/********结束游戏监听**********/
class endHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
snake.die();
bottonPanel.getStartButton().setEnabled(true);
}
}
/********菜单监听***********/
class Item1Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "选择颜色", Color.BLACK);
gamePanel.backgroundColor = color;
}
}
class Item2Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "选择颜色", Color.BLACK);
food.setFoodColor(color);
}
}
class Item3Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "选择颜色", Color.BLACK);
snake.setHeadColor(color);
}
}
class Item4Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Color color = JColorChooser.showDialog(gamePanel, "选择颜色", Color.BLACK);
snake.setBodyColor(color);
}
}
class spItem1Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(800);
}
}
class spItem2Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(500);
}
}
class spItem3Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(180);
}
}
class spItem4Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
snake.setSleepTime(15);
}
}
class mapItem1Handler implements ActionListener {
@Override
public void actionPerformed(ActionEvent argc0) {
ground.setMapType(1); ///////////////////////////////////////////////////
}
}
class helpItemHandler implements ActionListener { ///////////////////////////////
@Override
public void actionPerformed(ActionEvent e) {
StringBuffer sb = new StringBuffer();
sb.append("方向键控制方向\n");
sb.append("w++,s--\n");
String message = sb.toString();
JOptionPane.showMessageDialog(null, message, "使用说明", JOptionPane.INFORMATION_MESSAGE);
}
}
}
GameFrame包: 运行
package game;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import javax.swing.*;
import controller.Controller;
import listener.SnakeListener;
import object.Food;
import object.Ground;
import object.Snake;
import utiliy.Global;
import view.GamePanel;
import view.Menu;
import view.BottonPanel;
public class GameFrame extends JFrame{
public static void main(String[] args) {
new GameFrame(new Controller(new Snake(),new Food(),new Ground(),new Menu(),new GamePanel(),new BottonPanel()));
}
private GamePanel gamePanel;
private Menu menu;
private Snake snake;
private Controller controller;
private JPanel buttonPanel;
public GameFrame(Controller c) {
this.controller =c;
snake = controller.getSnake();
menu = controller.getMenu();
gamePanel = controller.getGamePanel();
buttonPanel = controller.getBottonPanel();
setTitle("范盈盈吃老鼠");
setBounds(300,100,Global.width*Global.cellsize+250,Global.height*Global.cellsize+60);
setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = this.getContentPane();
this.setJMenuBar(menu);
contentPane.add(gamePanel);
contentPane.add(buttonPanel);
setResizable(false);
setVisible(true);
/****窗口调整*******/
//this.setLocation(this.getToolkit().getScreenSize().width /2 - this.getWidth() /3, this.getToolkit().getScreenSize().height - this.getHeight());
gamePanel.addKeyListener(controller);
snake.addSnakeListener(controller);
controller.newGame();
}
}
listener包:
package listener;
import java.awt.event.KeyEvent;
import object.Snake;
public interface SnakeListener {
void snakeMoved(Snake snake);
void KeyPressed(KeyEvent e);
}
object包:
Food:
package object;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import utiliy.Global;
public class Food extends Point{
private static final long serialVersionUID =1L;
private Color foodColor;
public void setFoodColor(Color foodColor) {
this.foodColor = foodColor;
}
public Color getFoodColor() {
return foodColor;
}
public void newFood(Point p) {
setLocation(p);
}
public boolean isFoodEated(Snake snake) {
return this.equals(snake.getHead());
}
public void drawMe(Graphics g) {
if(foodColor == null) {
g.setColor(Color.blue);
}else {
g.setColor(foodColor);
}
g.fill3DRect(x*Global.cellsize, y*Global.cellsize, Global.cellsize, Global.cellsize, true);
}
}
package object;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import utiliy.Global;
public class Food extends Point{
private static final long serialVersionUID =1L;
private Color foodColor;
public void setFoodColor(Color foodColor) {
this.foodColor = foodColor;
}
public Color getFoodColor() {
return foodColor;
}
public void newFood(Point p) {
setLocation(p);
}
public boolean isFoodEated(Snake snake) {
return this.equals(snake.getHead());
}
public void drawMe(Graphics g) {
if(foodColor == null) {
g.setColor(Color.blue);
}else {
g.setColor(foodColor);
}
g.fill3DRect(x*Global.cellsize, y*Global.cellsize, Global.cellsize, Global.cellsize, true);
}
}
Ground:
package object;
import java.awt.*;
import java.util.*;
import utiliy.Global;
public class Ground {
private boolean [][] rocks = new boolean [Global.width][Global.height];
private int mapType = 1;
/******Map*******/
public int getMapType() {
return mapType;
}
public void setMapType(int mapType) {
this.mapType = mapType;
}
/*******InitMap*****/
public void clear() {
for (int x=0;x<Global.width;x++)
for (int y=0;y<Global.height;y++)
rocks[x][y] = false;
}
/******MakeMap******/
public void setRocks() {
for (int y=0;y<6;y++) {
rocks[0][y] = true;
rocks[Global.width-1][y] = true;
rocks[0][Global.height-1-y] = true;
rocks[Global.width -1][Global.height -1-y] =true;
}
}
/*****RockEat*********/
public boolean RockEat(Snake snake) {
for(int x=0; x<Global.width;x++) {
for(int y=0;y<Global.height;y++) {
if(rocks[x][y] == true && (x==snake.getHead().x && y==snake.getHead().y)) {
return true;
}
}
}
return false;
}
/******SnakeMove*****/
public Point getPoint() {
Random random = new Random();
int x=0,y=0;
do {
x= random.nextInt(Global.width);
y= random.nextInt(Global.height);
}
while(rocks[x][y] == true);
return new Point(x,y);
}
public void drawMe(Graphics g) {
g.setColor(Color.gray); //snake_color
for(int x=0; x<Global.width;x++) {
for(int y=0; y<Global.height;y++) {
if(rocks[x][y] == true){
g.fill3DRect(x*Global.cellsize, y*Global.cellsize, Global.cellsize, Global.cellsize, true);
}
}
}
}
}
Snake:
package object;
import java.awt.*;
import java.util.*;
import utiliy.Global;
import listener.SnakeListener;
public class Snake {
/*****SnakeDirection*********/
/*public static final int UP = 1;
public static final int DOWN = -1;
public static final int LEFT = 2;
public static final int RIGHT = -2;*/
public static final int I = 1;
public static final int K = -1;
public static final int J = 2;
public static final int L = -2;
/*********Listener*********/
private Set<SnakeListener> listeners = new HashSet<SnakeListener>();
/*********Point************/
private LinkedList<Point> body = new LinkedList <Point>();
/*********SnakeDefinition*********/
private boolean life;
private boolean pause;
private int oldDirection,newDirection;
private Point oldTail;
private int foodCount = 0;
private Color headColor;
private Color bodyColor;
private int sleepTime;
public boolean isLife() {
return life;
}
public int getSleepTime() {
return sleepTime;
}
public void setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
}
public void setHeadColor(Color headColor) {
this.headColor = headColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
public void init() {
int x =Global.width/2;
int y =Global.height/2;
for(int i = 0; i<3;i++) {
body.addLast(new Point(x--,y));
}
//oldDirection = newDirection = DOWN; ///////////////////初始方向
oldDirection = newDirection = I;
foodCount = 0;
life = true;
pause = false;
if(sleepTime == 0) {
sleepTime = 1000; ////////////////////初始速度
}
}
/*********clearSnake******/
public void clear() {
body.clear();
}
public void setLife(boolean life) {
this.life = life;
}
public boolean getPause() {
return pause;
}
public void setPause(boolean pause) {
this.pause = pause;
}
/******PauseChange*******/
public void changePause() {
pause =!pause;
}
/******SnakeDie*********/
public void die() {
life = false;
}
/*****SnakeMove*********/
public void move() {
if(!(oldDirection + newDirection ==0)) {
oldDirection = newDirection;
}
/*****DeleteSnakeTile*****/
oldTail = body.removeLast();
int x = body.getFirst().x;
int y = body.getFirst().y;
switch(oldDirection) {
/*case UP:
y--;
if (y<0) {
y = Global.height -1;
}
break;
case DOWN:
y++;
if (y>=Global.height) {
y = 0;
}
break;
case LEFT:
x--;
if (x<0) {
y = Global.width -1;
}
break;
case RIGHT:
x++;
if (x>=Global.width) {
x = 0;
}
break;
}*/
case I:
y--;
if (y<0) {
y = Global.height -1;
}
break;
case K:
y++;
if (y>=Global.height) {
y = 0;
}
break;
case J:
x--;
if (x<0) {
y = Global.width -1;
}
break;
case L:
x++;
if (x>=Global.width) {
x = 0;
}
break;
}
/*********addSnakeHead*******/
Point newHead = new Point(x,y);
body.addFirst(newHead);
}
/*********ChangeSnakeDirection********/
public void changeDirection(int direction) {
newDirection =direction;
}
/**********SnakeEatFood********/
public void eatFood() {
body.addLast(oldTail);
foodCount++;
}
public int getFoodCount() {
return foodCount;
}
/**********SnakeEatBody********/
public boolean isEatBody() {
for(int i=1; i<body.size();i++) {
if(body.get(i).equals(this.getHead()))
return true;
}
return false;
}
/********GetSankeHead**********/
public Point getHead() {
return body.getFirst();
}
/********DrawMe****************/
public void drawMe(Graphics g) {
if (bodyColor == null) {
g.setColor(new Color(0x3333FF));
}else {
g.setColor(bodyColor);
}
for (Point p : body) {
g.fillRoundRect(p.x*Global.cellsize, p.y*Global.cellsize, Global.cellsize, Global.cellsize, 15, 12);
}
drawHead(g);
}
/**********DrawSnakeHead*******/
public void drawHead(Graphics g) {
if (headColor == null)
g.setColor(Color.YELLOW);
else {
g.setColor(headColor);
}
g.fillRoundRect(getHead().x * Global.cellsize, getHead().y * Global.cellsize, Global.cellsize, Global.cellsize, 15, 12);
}
/********ControlSnakeMove******/
private class SnakeDriver implements Runnable{
public void run() {
while (life == true) {
if (pause == false) {
move();
for (SnakeListener l :listeners)
l.snakeMoved(Snake.this);
}
try {
Thread.sleep(sleepTime);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
/****StartThread*******/
public void begin() {
new Thread(new SnakeDriver()).start();
}
/*****监听******/
public void addSnakeListener(SnakeListener l) {
if(l != null ) {
listeners.add(l);
}
}
/******加速*******/
public void speedUp() {
if (sleepTime >50) {
sleepTime -=20;
}
}
/******减速*******/
public void speedDown() {
if (sleepTime <700) {
sleepTime +=20;
}
}
}
Global:
package utiliy;
public class Global {
public static final int cellsize=18;
public static final int width=25;
public static final int height=25;
}
BotttonPanel:
package view;
import java.awt.*;
import javax.swing.*;
public class BottonPanel extends JPanel {
private static final long serialVersiomUID = 1L;
private JButton startButton;
private JButton pauseButton;
private JButton endButton;
private JLabel scoreLabel;
private int score;
public BottonPanel() {
setLayout(null);
setBounds(455,0,235,450);
startButton = new JButton("开始游戏");
startButton.setBounds(10, 20, 100, 25);
add(startButton);
pauseButton = new JButton("暂停游戏");
pauseButton.setBounds(10, 60, 100, 25);
add(pauseButton);
endButton = new JButton("结束游戏");
endButton.setBounds(10, 100, 100, 25);
add(endButton);
/*
scoreLabel = new JLabel("得分:");
scoreLabel.setFont(new Font("Serif",Font.BOLD,18));
scoreLabel.setBounds(30, 140, 100, 30);
add(scoreLabel);*/
Color c =new Color(0,250,154);
this.setBackground(c);
this.setFocusable(true);
}
public JButton getStartButton() {
return startButton;
}
public JButton getPauseButton() {
return pauseButton;
}
public JButton getEndButton() {
return endButton;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score=score;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.PINK);
g.setFont(new Font("Serif",Font.BOLD,50));
g.drawString(score+"", 40, 230);
}
}
GamePanel:
package view;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import object.Snake;
import object.Food;
import object.Ground;
import utiliy.Global;
public class GamePanel extends JPanel{
private static final long seriaVersionUID = 1L;
private Snake snake;
private Food food;
private Ground ground;
public Color backgroundColor;
public GamePanel() {
setLocation(0,0);
/*****大小、布局*******/
this.setSize(Global.width * Global.cellsize,Global.height * Global.cellsize);
this.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
this.setFocusable(true);
}
public void display(Snake snake,Food food,Ground ground) {
this.snake=snake;
this.food=food;
this.ground=ground;
repaint();
}
public void clearDraw(Graphics g) {
if(backgroundColor == null) {
g.setColor(new Color(0xacaf)); /***********************默认背景颜色*****************************/
}else {
g.setColor(backgroundColor);
}
g.fillRect(0, 0, Global.width*Global.cellsize, Global.height*Global.cellsize);
}
@Override
public void paint(Graphics g) {
clearDraw(g);
if(ground != null && snake != null && food != null) {
ground.drawMe(g);
food.drawMe(g);
snake.drawMe(g);
}
if(snake != null && snake.isLife()==false) {
recover(g);
}
}
/******恢复***********/
public void recover(Graphics g) {
clearDraw(g);
/******game over*******/
g.setColor(Color.gray); /**********************默认失败颜色**************************/
g.setFont(new Font("Serif",Font.BOLD,50));
g.drawString("Game Over!", 130, 210);
}
}