java贪吃蛇移动问题求解 1C

当前只用到了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;
}


1个回答

你应该加个 lastTail,在 deleteTail() 中把去掉的一格记下来。
这样在 move() 之后只要 head.draw(g) 画一格和 `lastTail.clar(g)'清一格。

Tiger_Zhao
Tiger_Zhao 回复千叶鸟: 这也是一种方案。看你原先的代码以为是不想全部重绘,所以要加个lastTail.clear(g)
大约 4 年之前 回复
qq_26788389
千叶鸟 回复Tiger_Zhao: 问题解决了,每次重画的时候应该先重画背景。。
大约 4 年之前 回复
Tiger_Zhao
Tiger_Zhao 更正:lastTail.clear(g)
大约 4 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!