qq_37363354
Yake_Can
2017-02-21 11:42

Java写贪吃蛇遇到的食物生成问题

  • java
  • 线程

我是用线程方法让蛇和食物动起来的,不过食物和蛇一起写在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;
    }

}

  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

1条回答