千叶鸟 2015-08-19 09:07 采纳率: 0%
浏览 2473
已结题

java贪吃蛇移动问题求解

当前只用到了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条回答 默认 最新

  • Tiger_Zhao 2015-08-19 09:24
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?