我是用线程方法让蛇和食物动起来的,不过食物和蛇一起写在paint方法里,repaint一次,食物也会随机变换位置,我想通过观察蛇长是否改变来决定是否new一个新对象,但原来的食物位置不知道怎么记录下来,求教,或者其他更好的解决的方法,谢谢。
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Shell extends Frame {
private static final int Width = 900;
private static final int Height = 700;
private static final int XOffset = 50;
private static final int YOffset = 50;
private static final int XEnd = 850;
private static final int YEnd = 650;
public static final int Row = 30;
public static final int Col = 40;
public static final int Block_Size = 20;
public static Food myFood = null;
private Node myNode = null;
private static Snake mySnake = new Snake();
private static Shell shell = new Shell();
public Shell() {
this.setTitle("贪吃蛇");
this.setSize(Width, Height);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.addKeyListener(new KeyHandler(mySnake));
//produceFood();
this.setVisible(true);
}
public void paint(Graphics g) {
drawGrid(g);
drawFood(g);
drawSnake(g);
}
private void drawGrid(Graphics g) {
g.setColor(Color.BLACK);
for(int i=0; i<=Row; i++) {
g.drawLine(XOffset, Block_Size*i+50, XEnd, Block_Size*i+50);
}
for(int i=0; i<=Col; i++) {
g.drawLine(Block_Size*i+50, YOffset, Block_Size*i+50, YEnd);
}
}
public void drawSnake(Graphics g) {
g.setColor(Color.BLACK);
for(int i=0; i<mySnake.getLength(); i++) {
myNode = mySnake.getNode(i);
g.fillRect(myNode.X, myNode.Y, Block_Size, Block_Size);
}
}
private void drawFood(Graphics g) {
myFood = new Food();
g.setColor(Color.RED);
g.fillRect(myFood.getX(), myFood.getY(), Block_Size, Block_Size);
}
public Food getFood() {
return myFood;
}
public static Food produceFood() {
boolean finished;
Food food;
do{
finished = true;
food =new Food();
for(int i=0; i<mySnake.getLength(); i++) {
if(mySnake.getNode(i).X == food.getX() || mySnake.getNode(i).Y == food.getY()) {
finished = false;
}
}
} while(!finished);
myFood = food;
return food;
}
public static void main(String[] args) {
produceFood();
new Updater(shell, mySnake).start();
}
}
class Updater extends Thread {
private Shell shell = null;
private Snake snake = null;
public Updater(Shell shell, Snake snake) {
this.shell = shell;
this.snake = snake;
}
public void run() {
while(true) {
snake.move(shell);
shell.repaint();
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
import java.util.ArrayList;
import java.util.List;
public class Snake {
List<Node> Nodes = null;
public Direction direction = null;
private Node newNode = null;
private Node headNode = null;
private Direction nextDirection = null;
public Snake() {
Nodes = new ArrayList<Node>();
reset();
}
public void setDirection(Direction d) {
switch(this.direction) {
case LEFT :
if(d == Direction.RIGHT)
return ;
break;
case RIGHT :
if(d == Direction.LEFT)
return ;
break;
case UP :
if(d == Direction.DOWN)
return ;
break;
case DOWN :
if(d == Direction.UP)
return ;
break;
}
nextDirection = d;
}
public void move(Shell shell) {
headNode = Nodes.get(0);
this.direction = nextDirection;
switch(this.direction) {
case LEFT:
newNode = new Node(headNode.X-Shell.Block_Size, headNode.Y);
break;
case RIGHT:
newNode = new Node(headNode.X+Shell.Block_Size, headNode.Y);
break;
case UP:
newNode = new Node(headNode.X, headNode.Y-Shell.Block_Size);
break;
case DOWN:
newNode = new Node(headNode.X, headNode.Y+Shell.Block_Size);
break;
}
Food myFood = shell.getFood();
if (myFood.getX() == headNode.X && myFood.getY() == headNode.Y) {
Nodes.add(0,new Node(myFood.getX(),myFood.getY()));
//Shell.produceFood();
} else {
Shell.myFood = null;
Nodes.add(0,newNode);
Nodes.remove(Nodes.size()-1);
}
}
public int getLength() {
return Nodes.size();
}
public Node getNode(int index) {
return Nodes.get(index);
}
private void reset() {
Nodes.clear();
Nodes.add(new Node(Shell.Block_Size*10+50,Shell.Block_Size*10+50));
Nodes.add(new Node(Shell.Block_Size*9+50,Shell.Block_Size*10+50));
Nodes.add(new Node(Shell.Block_Size*8+50,Shell.Block_Size*10+50));
Nodes.add(new Node(Shell.Block_Size*7+50,Shell.Block_Size*10+50));
nextDirection = Direction.RIGHT;
}
}
import java.util.Random;
public class Food {
public static int X = 0;
public static int Y = 0;
Random random = new Random();
public int getX() {
return Shell.Block_Size*random.nextInt(Shell.Col)+50;
}
public int getY() {
return Shell.Block_Size*random.nextInt(Shell.Row)+50;
}
}
public enum Direction {
LEFT,
RIGHT,
UP,
DOWN
}
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyHandler extends KeyAdapter{
private Snake snake = null;
public KeyHandler(Snake snake) {
this.snake = snake;
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_UP :
snake.setDirection(Direction.UP);
break;
case KeyEvent.VK_DOWN :
snake.setDirection(Direction.DOWN);
break;
case KeyEvent.VK_RIGHT :
snake.setDirection(Direction.RIGHT);
break;
case KeyEvent.VK_LEFT :
snake.setDirection(Direction.LEFT);
break;
}
}
}
public class Node {
public int X = 0;
public int Y = 0;
public Node(int X, int Y) {
this.X = X;
this.Y = Y;
}
}