当前只用到了3个类:
代表蛇:Snake.java
代表地图:Garden.java
代表方向的枚举类:Dir.java
遇到的问题:我是采取在蛇头前添加一节,然后去掉尾巴上最后一节,再重画的方式
来让蛇移动,但是去蛇尾的方法好像没起作用,问题不知道出在哪了,有大神来看看么?
想要达到的效果:只有一个格子在移动,而不是这样每动一次,原来的还在。
Snake.java------------------------------------------------------------
```import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
public class Snake {
private Node head = null;
private Node tail = null;
private int size;
Node n = new Node(15, 10, Dir.L);
private Garden gd;
public Snake(Garden gd) {
head = n;
tail = n;
size = 1;
this.gd = gd;
}
// 添尾
public void addToTail() {
Node node = null;
switch (tail.dir) {
case L:
node = new Node(tail.x + 1, tail.y, Dir.L);
break;
case R:
node = new Node(tail.x - 1, tail.y, Dir.R);
break;
case U:
node = new Node(tail.x, tail.y + 1, Dir.U);
break;
case D:
node = new Node(tail.x, tail.y - 1, Dir.L);
break;
}
node.prev = tail;
tail.next = node;
tail = node;
size++;
}
// 去尾
public void deleteTail() {
if (size == 0)
return;
tail = tail.prev;
tail.next = null;
}
// 添头
public void addToHead() {
Node node = null;
switch (head.dir) {
case L:
node = new Node(head.x - 1, head.y, head.dir);
break;
case R:
node = new Node(head.x + 1, head.y, head.dir);
break;
case U:
node = new Node(head.x, head.y - 1, head.dir);
break;
case D:
node = new Node(head.x, head.y + 1, head.dir);
break;
}
node.next = head;
head.prev = node;
head = node;
size++;
}
public void move() {
if (size == 0)
return;
addToHead();
deleteTail();
}
Node n1 = new Node(n.x-5, n.y, n.dir);
Node n2 = new Node(n.x-10, n.y, n.dir);
public void draw(Graphics g) {
if (size <= 0)
return;
move();
for (Node theNode = head; theNode != null; theNode = theNode.next) {
theNode.draw(g);
}
}
private class Node {
private int x, y;
Dir dir = null;
private int w = Garden.wide;
Node next = null;
Node prev = null;
public Node(int x, int y, Dir dir) {
this.x = x;
this.y = y;
this.dir = dir;
}
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.fillRect(x * w, y * w, w, w);
g.setColor(c);
}
}
public void KeyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch (key) {
case KeyEvent.VK_W:
head.dir = Dir.U;
break;
case KeyEvent.VK_S:
head.dir = Dir.D;
break;
case KeyEvent.VK_A:
head.dir = Dir.L;
break;
case KeyEvent.VK_D:
head.dir = Dir.R;
break;
}
}
}
Garden.java-----------------------------------------------------------------------
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Garden extends JPanel {
private JFrame jf = null;
// 格子大小
public static int wide = 20;
// 窗口大小
private int gWidth = 500;
private int gHeigth = 500;
Snake s = new Snake(this);
Egg e = new Egg();
public static void main(String[] args) {
new Garden().init();
}
// 初始化窗口
private void init() {
jf = new JFrame();
jf.add(this);
jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);
jf.setLocation(20, 20);
jf.setSize(gWidth + 7, gHeigth + 30);
jf.setResizable(false);
jf.setVisible(true);
jf.addKeyListener(new KeyMonitor());
new Thread(new PaintThread()).start();
}
public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.GREEN);
// 画格子
for (int i = 0; i < gHeigth; i += wide) {
for (int j = 0; j < gWidth; j += wide) {
g.drawRect(i, j, wide, wide);
}
}
g.setColor(c);
s.draw(g);
e.drawEgg(g);
}
private class PaintThread implements Runnable {
@Override
public void run() {
while(true) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class KeyMonitor extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
s.KeyPressed(e);
}
}
}
Dir.java---------------------------------------------------------------------------
public enum Dir {
L,R,U,D;
}