2014-04-16 115 views
0

我想爲我的編程課程重新創建一個簡單的蛇遊戲。我在程序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

代碼的哪部分應該讓蛇移動? – CodeCamper

+0

只是出於好奇,你如何啓動這個(所以我可以測試你的方式)。 – user3507600

+0

代碼的公共void Move()部分應該讓蛇移動。我認爲問題出在@CodeCamper – user3542369

回答

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()方法的第一行。

+0

謝謝你的幫助,我改變了代碼,但它仍然看起來像蛇不動。有什麼建議麼? @ user3507600 – user3542369

+0

@ user3542369我假設你按下了一個按鈕,是嗎?由於您沒有指定起始方向,因此只有按下箭頭鍵後纔會移動。 – user3507600

+0

發生了一些事情。當我開始玩遊戲時,我發現有時候這個點不會在遊戲中出現。我猜測這是因爲這個點位移到蛇已經存在的地方,因此蛇在它實際上被看到之前「吃」了它。另一個點不出現,然後我們只剩下蛇。任何解決方案我認爲這是PlaceFruit()方法的一個問題。 @ user3507600 – user3542369

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 
} 
+0

蛇現在移動!除了現在,一旦它吃了水果,沒有其他的水果出現 – user3542369

+0

我已經注意到,並正在編輯修復它。 :) –

+0

沒關係,功能完美!非常感謝! – user3542369