蛇游戏问题,蛇不动

时间:2014-04-16 18:02:43

标签: java

我正在尝试为我的编程课重新创建一个简单的蛇游戏。我在程序Eclipse上使用java。如果你不知道如何使用这个游戏,这是一个游戏,当蛇吃点,它生长,当蛇击中自己时游戏结束。任何帮助将不胜感激!

 import java.awt.Color; 
 import java.awt.Dimension;  
 import java.awt.Graphics;  
 import java.awt.Point;  
 import java.awt.event.KeyEvent;  
 import java.awt.event.KeyListener;  
 import java.awt.image.BufferedImage;  
 import java.util.LinkedList;  
 import java.util.Random;  
 import javax.swing.JFrame;
public class Source extends JFrame implements Runnable, KeyListener {
private final int boxHeight = 15; //each individual box height
private final int boxWidth = 15; //each individual box width
private final int gridWidth = 25; //Total width of all boxes in Grid
private final int gridHeight = 25; //Total height of all boxes in Grid
JFrame frame = new JFrame();
private LinkedList<Point> snake;
public Point fruit;
public int direction = Direction.noDirection;
private Thread runThread;
private Graphics globalGraphics;
private int score = 0;


public void paint (Graphics g)
{
    setBounds(0,0,500,500);
    snake = new LinkedList<Point>();
    GenerateDefaultSnake();
    PlaceFruit();
    globalGraphics = g.create();
    this.addKeyListener(this);
    if (runThread == null){
        runThread = new Thread(this);
        runThread.start();
    }
}
public void GenerateDefaultSnake(){

    score = 0;
    snake.clear();
    snake.add(new Point (0,2));
    snake.add(new Point (0,1));
    snake.add(new Point (0,0));
    direction = Direction.noDirection;
}

public void Draw (Graphics g){ //main method of what will be drawn
    g.clearRect(0, 0, boxWidth * gridWidth + 10, boxHeight * gridHeight +20);
    //create a new image
    BufferedImage buffer = new BufferedImage(boxWidth * gridWidth + 10, boxHeight * gridHeight +20, BufferedImage.TYPE_INT_ARGB);
    Graphics bufferGraphics = buffer.getGraphics();

    DrawFruit(bufferGraphics);  
    DrawGrid(bufferGraphics);
    DrawSnake(bufferGraphics);
    DrawScore(bufferGraphics);


    //flip
    g.drawImage(buffer, 0,0, boxWidth * gridWidth +10, boxHeight * gridHeight +20, this);

}
public void Move(){ //directions
    Point head = snake.peekFirst(); //head of snake, allows us to have body follow in chronological order
    Point newPoint = head;

    snake.remove(snake.peekLast()); //removes end of tail
    if(newPoint.equals(fruit))
    {
        score += 10;
        Point addPoint = (Point) newPoint.clone();
        //the snake has hit the fruit
        switch(direction){
        case Direction.North:
            newPoint = new Point (head.x, head.y -1);
            break;
        case Direction.South:
            newPoint = new Point(head.x,head.y +1);
            break;
        case Direction.West:
            newPoint = new Point(head.x -1,head.y);
            break;
        case Direction.East:
            newPoint = new Point(head.x + 1,head.y);
            break;
        }
        snake.push(addPoint);
        PlaceFruit();
    }
    else if (newPoint.x < 0 || newPoint.x > (gridWidth - 1)){
        //we went out of bounds, reset game
        GenerateDefaultSnake();
        return;
    }
    else if (newPoint.y < 0 || newPoint.y > (gridHeight - 1 )){
        //we went out of bounds, reset game
        GenerateDefaultSnake();
        return;
    }
    else if (snake.contains(newPoint)){
        //we ran into ourselves, reset game

        GenerateDefaultSnake();
        return;
    }
    //if we reach this point of the game, we are still good 
    snake.push(newPoint); //pushes all points one point ahead when you eat fruit and adds fruit that you ate at the end
}

public void DrawScore(Graphics g){
    g.drawString("Score: " + score,0, boxHeight * gridHeight +10);
}
public void DrawGrid (Graphics g){
    //drawing outer rectangle
    g.drawRect(0,0, gridWidth * boxWidth, gridHeight * boxHeight); //creates the outer rectangle
    //drawing vertical lines of grid
    for (int x = boxWidth; x < gridWidth * boxWidth; x += boxWidth){
        g.drawLine(x, 0, x, boxHeight * gridHeight);
    }
    //drawing horizontal lines of grid
    for(int y = boxHeight; y < gridHeight * boxHeight; y += boxHeight){
        g.drawLine(0, y, gridWidth * boxWidth, y);
    }
}
public void DrawSnake(Graphics g){
    g.setColor(Color.GREEN);
    for ( Point p : snake){
        g.fillRect(p.x * boxWidth,  p.y * boxHeight,  boxWidth,  boxHeight);
    }
    g.setColor(Color.BLACK);
}
public void DrawFruit(Graphics g){
    g.setColor(Color.RED);
    g.fillOval(fruit.x * boxWidth, fruit.y * boxHeight, boxWidth, boxHeight);
    g.setColor(Color.BLACK);
}
public void PlaceFruit()
{
    Random rand = new Random();
    int randomX = rand.nextInt(gridWidth);
    int randomY = rand.nextInt(gridHeight);
    Point randomPoint = new Point(randomX, randomY);
    while (snake.contains(randomPoint)){
        randomX = rand.nextInt(gridWidth);
        randomY = rand.nextInt(gridHeight);
        randomPoint = new Point(randomX, randomY);
    }
    fruit = randomPoint;

}
public void run() {
    while(true){
        //runs indefinitely, every second the objects in this loop will move
        Move();
        Draw(globalGraphics);
        try{
            Thread.currentThread();
            Thread.sleep(100); //game will be updating itself every tenth of a second (.1 of a second)
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}
@Override
public void keyPressed(KeyEvent e) {
    switch (e.getKeyCode())
    {
    case KeyEvent.VK_UP:
        if(direction != Direction.South)
            direction = Direction.North;
            break;

    case KeyEvent.VK_DOWN:
        if(direction != Direction.North)
        direction = Direction.South;
        break;
    case KeyEvent.VK_RIGHT:
        if(direction != Direction.West)
        direction = Direction.East;
        break;
    case KeyEvent.VK_LEFT:
        if(direction != Direction.East)
        direction = Direction.West;
        break;
    }
}
    public class Direction {
public static final int noDirection = 0;
public static final int North = 1;
public static final int South = 2;
public static final int West = 3;
public static final int East = 4;
   }
    public class Snake extends JFrame{



    c = new Source();
    c.setPreferredSize(new Dimension (640,480));
    c.setVisible(true);
    c.setFocusable(true);
    }
  @Override
  public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
  }
  @Override
   public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
     }
  }*

2 个答案:

答案 0 :(得分:1)

问题在于您的move()方法,在最后一种情况下(else if (snake.contains(newPoint)))总是会失败,因为您创建的新点始终位于当前蛇的内部。

我正在为你制定解决方案。

修改

这部分错了:

if(newPoint.equals(fruit))
{
    score += 10;
    Point addPoint = (Point) newPoint.clone();
    //the snake has hit the fruit
    switch(direction){
    case Direction.North:
        newPoint = new Point (head.x, head.y -1);
        break;
    case Direction.South:
        newPoint = new Point(head.x,head.y +1);
        break;
    case Direction.West:
        newPoint = new Point(head.x -1,head.y);
        break;
    case Direction.East:
        newPoint = new Point(head.x + 1,head.y);
        break;
    }
    snake.push(addPoint);
    PlaceFruit();
}

编辑2:无脑框是正确的,点和addPoint应该在检查水果。我还添加了一些逻辑来更好地处理水果。

public void Move(){ //directions

    Point head = snake.peekFirst(); //head of snake, allows us to have body follow in chronological order
    Point newPoint = head;

    snake.remove(snake.peekLast()); //removes end of tail


    Point addPoint = (Point) newPoint.clone();
    switch(direction) {
    case Direction.North:
        newPoint = new Point (head.x, head.y -1);
        break;
    case Direction.South:
        newPoint = new Point(head.x,head.y +1);
        break;
    case Direction.West:
        newPoint = new Point(head.x -1,head.y);
        break;
    case Direction.East:
        newPoint = new Point(head.x + 1,head.y);
        break;
    }

    //the snake has hit the fruit
    if(newPoint.equals(fruit))
    {
        score += 10;
        fruit = null;
        snake.push(addPoint);
    }
    else if (newPoint.x < 0 || newPoint.x > (gridWidth - 1)){
        //we went out of bounds, reset game
        GenerateDefaultSnake();
        return;
    }
    else if (newPoint.y < 0 || newPoint.y > (gridHeight - 1 )){
        //we went out of bounds, reset game
        GenerateDefaultSnake();
        return;
    }
    else if (snake.contains(newPoint)){
        //we ran into ourselves, reset game
        GenerateDefaultSnake();
        return;
    }

    //if we reach this point of the game, we are still good 
    PlaceFruit();
    snake.push(newPoint); //pushes all points one point ahead when you eat fruit and adds fruit that you ate at the end
}

除此之外,添加if (fruit != null) return;作为PlaceFruit()方法的第一行。

答案 1 :(得分:0)

让你的蛇移动的代码略有不正确。你应该总是移动,只有加入分数并重新创造一个水果,如果蛇进入它。见下文:

public void Move(){ //directions

    Point head = snake.peekFirst(); //head of snake, allows us to have body follow in chronological order
    Point newPoint = head;

    snake.remove(snake.peekLast()); //removes end of tail


    Point addPoint = (Point) newPoint.clone();
    switch(direction) {
    case Direction.North:
        newPoint = new Point (head.x, head.y -1);
        break;
    case Direction.South:
        newPoint = new Point(head.x,head.y +1);
        break;
    case Direction.West:
        newPoint = new Point(head.x -1,head.y);
        break;
    case Direction.East:
        newPoint = new Point(head.x + 1,head.y);
        break;
    }

    //the snake has hit the fruit
    if(newPoint.equals(fruit))
    {
        score += 10;
        snake.push(addPoint);
        PlaceFruit();
    }
    else if (newPoint.x < 0 || newPoint.x > (gridWidth - 1)){
        //we went out of bounds, reset game
        GenerateDefaultSnake();
        PlaceFruit();
        return;
    }
    else if (newPoint.y < 0 || newPoint.y > (gridHeight - 1 )){
        //we went out of bounds, reset game
        GenerateDefaultSnake();
        PlaceFruit();
        return;
    }
    else if (snake.contains(newPoint)){
        //we ran into ourselves, reset game
        GenerateDefaultSnake();
        PlaceFruit();
        return;
    }

    //if we reach this point of the game, we are still good 
    snake.push(newPoint); //pushes all points one point ahead when you eat fruit and adds fruit that you ate at the end
}