mport java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GamePanel extends JPanel implements ActionListener {
public static final int B_WIDTH = 450;
public static final int B_HEIGHT = 450;
public static final int DOT_SIZE = 15;
public static final int ALL_DOTS = 900;
public static final int DELAY = 100;
private static final Font gameOverFont = new Font("Verdana", Font.BOLD, 60);
public boolean inGame = true;
public String playerName;
public Timer timer;
boolean live = true;
JFrame myJFrame = null;
Image offScreenImage = null;
Snake mySnake = new Snake();
Food f = new Food();
public static void main(String[] args) {
new GamePanel().launchGame();
}
public void launchGame() {
myJFrame = new JFrame();
myJFrame.setTitle("Snake");
myJFrame.setLocation(400,200);
myJFrame.setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
myJFrame.setContentPane(new WelcomePanel(this));
myJFrame.addKeyListener(new GamePanel().new KeyMonitor());
myJFrame.pack();
myJFrame.setVisible(true);
myJFrame.setResizable(false);
myJFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
myJFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
timer.stop();
int exit = JOptionPane.showConfirmDialog(null, "确定退出吗", "友情提示", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if(exit == JOptionPane.YES_OPTION) {
System.exit(0);
} else {
timer.start();
return;
}
}
});
timer = new Timer(DELAY, this);
}
public GamePanel() {
this.setBackground(Color.BLACK);
this.setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
this.setFocusable(true);
this.addKeyListener(new KeyMonitor());
this.setVisible(false);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setDoubleBuffered(true);
mySnake.checkLive();
if(mySnake.isLive()) {
mySnake.draw(g);
} else {
timer.stop();
this.gameOver(g);
}
if(f.isLive()) {
f.draw(g);
} else {
f = new Food();
}
mySnake.eatFood(f);
}
private void gameOver(Graphics g) {
g.setFont(gameOverFont);
}
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
private class KeyMonitor extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
mySnake.keyPressed(e);
}
}
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class WelcomePanel extends JPanel implements ActionListener{
GamePanel gp;
JButton start = null;
JButton help = null;
JTextField inputName = null;
public WelcomePanel(GamePanel gp) {
this.gp = gp;
start = new JButton("START");
start.setBackground(Color.RED);
start.setBounds(160, 220, 130, 40);
start.setForeground(Color.RED);
start.addActionListener(this);
help = new JButton("HELP");
help.setBackground(Color.RED);
help.setBounds(160, 270, 130, 40);
help.setForeground(Color.RED);
help.addActionListener(this);
inputName = new JTextField("请输入你的昵称", 10);
inputName.setBounds(160, 160, 150, 40);
this.setBackground(Color.BLACK);
this.setPreferredSize(new Dimension(GamePanel.B_WIDTH, GamePanel.B_HEIGHT));
this.setLayout(null);
this.add(start);
this.add(inputName);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == start) {
gp.playerName = inputName.getText();
System.out.println(gp.playerName);
gp.myJFrame.setContentPane(gp);
gp.setVisible(true);
gp.timer.start();
} else if(e.getSource() == help) {
}
}
}
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
public class Snake {
GamePanel gp;
Direction dir = Direction.R;
int x, y, size;
private boolean live = true;
private int sX[] = new int[GamePanel.ALL_DOTS];
private int sY[] = new int[GamePanel.ALL_DOTS];
public Snake() {
size = 2;
sX[0] = 1 * GamePanel.DOT_SIZE;
sX[1] = 0 * GamePanel.DOT_SIZE;
sY[0] = 0 * GamePanel.DOT_SIZE;
sY[1] = 0 * GamePanel.DOT_SIZE;
}
public Snake(int x, int y, GamePanel gp) {
this.x = x;
this.y = y;
this.gp = gp;
}
public void draw(Graphics g) {
move();
Color c = g.getColor();
g.setColor(Color.GREEN);
for(int i=0; i<size; i++) {
g.fillOval(sX[i], sY[i], GamePanel.DOT_SIZE, GamePanel.DOT_SIZE);
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_UP :
if(dir == Direction.D) break;
dir = Direction.U;
break;
case KeyEvent.VK_DOWN :
if(dir == Direction.U) break;
dir = Direction.D;
break;
case KeyEvent.VK_LEFT :
if(dir == Direction.R) break;
dir = Direction.L;
break;
case KeyEvent.VK_RIGHT :
if(dir == Direction.L) break;
dir = Direction.R;
break;
}
}
public void move() {
for(int i=size-1; i>0; i--) {
sX[i] = sX[(i-1)];
sY[i] = sY[(i-1)];
}
switch(dir) {
case U :
sY[0] -= GamePanel.DOT_SIZE;
break;
case D :
sY[0] += GamePanel.DOT_SIZE;
break;
case L :
sX[0] -= GamePanel.DOT_SIZE;
break;
case R :
sX[0] += GamePanel.DOT_SIZE;
break;
}
System.out.println(dir);
}
public boolean eatFood(Food f) {
if(f.fX == sX[0] && f.fY == sY[0]) {
f.setLive(false);
this.grow();
return true;
}
return false;
}
private void grow() {
size ++;
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
public void checkLive() {
if(sX[0] < 0 || sX[0] >= GamePanel.B_WIDTH || sY[0] < 0 || sY[0] >= GamePanel.B_HEIGHT) {
this.setLive(false);
}
for(int i=1; i<size; i++) {
if(sX[0] == sX[i] && sY[0] == sY[i]) {
this.setLive(false);
break;
}
}
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class Food {
public int fX;
public int fY;
private boolean live = true;
private static Random r = new Random();
public Food() {
fX = r.nextInt(GamePanel.B_WIDTH / GamePanel.DOT_SIZE) * GamePanel.DOT_SIZE;
fY = r.nextInt(GamePanel.B_HEIGHT / GamePanel.DOT_SIZE) * GamePanel.DOT_SIZE;
}
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.fillOval(fX, fY, GamePanel.DOT_SIZE, GamePanel.DOT_SIZE);
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
}
public enum Direction {
U, D, L, R
}
按下键盘 keyPressed方法没有被调用啊。。焦点我设置了还是没用啊
跪求大神
主要是你定义了两个类GamePanel和WelcomePanel两个都是继承自JPanel的,但是键盘点击事件是添加到第一个GamePanel上的,一个JFrame中包含两个JPanel不知道它的事件是怎么处理的。
但是可以肯定的是,如果要修正代码的话,最好去掉WelcomePanel类,将其归并到GamePanel上来。
有个同样实现的问题,你完全可以参考:
http://ask.csdn.net/questions/241341
我找打原因了,是因为你的JFrame中使用了两个JPanel轮换显示的,在点击WelcomePanel的开始按钮后,界面切换显示的是GamePanel,但是该面板没有聚焦,导致它不能接收键盘点击事件。
修正你的WelcomePanel的actionPerformed方法,修正开始按钮的处理代码如下:
public void actionPerformed(ActionEvent e) {
if (e.getSource() == start) {
gp.playerName = inputName.getText();
System.out.println(gp.playerName);
gp.myJFrame.setContentPane(gp);
gp.setVisible(true);
// 必须主动聚焦,才能使它的键盘点击事件触发
gp.requestFocus();
gp.timer.start();
} else if (e.getSource() == help) {
}
}