import java.awt.Color;
import java.awt.Dimension;
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 javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Board 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 Timer timer;
boolean live = true;
Image offScreenImage = null;
Snake mySnake = new Snake();
public static void main(String[] args) {
new Board().launchGame();
}
public void launchGame() {
JFrame myJFrame = new JFrame();
myJFrame.setTitle("Snake");
myJFrame.setLocation(400,200);
myJFrame.getContentPane().add((new Board()));
myJFrame.pack();
myJFrame.addKeyListener(new Board().new KeyMonitor());
myJFrame.setVisible(true);
myJFrame.setResizable(false);
myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
timer = new Timer(DELAY, this);
timer.start();
}
public Board() {
this.setBackground(Color.BLACK);
this.setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
this.setFocusable(true);
this.addKeyListener(new KeyMonitor());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setDoubleBuffered(true);
this.draw(g);
}
public void draw(Graphics g) {
mySnake.draw(g);
Food f = new Food();
f.draw(g);
}
@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.EventQueue;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
public class Snake {
Board b;
Direction dir = Direction.R;
int x, y, size;
private int sX[] = new int[Board.ALL_DOTS];
private int sY[] = new int[Board.ALL_DOTS];
public Snake() {
size = 2;
sX[0] = 1 * Board.DOT_SIZE;
sX[1] = 0 * Board.DOT_SIZE;
sY[0] = 0 * Board.DOT_SIZE;
sY[1] = 0 * Board.DOT_SIZE;
}
public Snake(int x, int y, Board b) {
this.x = x;
this.y = y;
this.b = b;
}
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], Board.DOT_SIZE, Board.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] -= Board.DOT_SIZE;
break;
case D :
sY[0] += Board.DOT_SIZE;
break;
case L :
sX[0] -= Board.DOT_SIZE;
break;
case R :
sX[0] += Board.DOT_SIZE;
break;
}
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class Food {
private int fX;
private int fY;
private static Random r = new Random();
public Food() {
fX = r.nextInt(Board.B_WIDTH / Board.DOT_SIZE) * Board.DOT_SIZE;
fY = r.nextInt(Board.B_HEIGHT / Board.DOT_SIZE) * Board.DOT_SIZE;
}
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.fillOval(fX, fY, Board.DOT_SIZE, Board.DOT_SIZE);
}
}
public enum Direction {
U, D, L, R
}
初学者写的贪吃蛇,用timer计时器,每隔一段时间调用一次repaint(),但运行起来发现,repaint是每隔一段时间被调用了,但paintComponent方法只被调用了一次(或者两次)。。求解啊这bug烦死我了