首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >编写Snake游戏,Snake中不能有多个块

编写Snake游戏,Snake中不能有多个块
EN

Stack Overflow用户
提问于 2013-12-06 23:31:26
回答 2查看 320关注 0票数 0

我正在写一个Snake程序,并试图让它吃每一块食物都会增加Snake的长度。取而代之的是食物和独长蛇重新定位。我不知道如何让它(例如)在吃完一种食物后,在第一个盒子的先前位置出现一个新盒子,然后蛇继续前进。提前感谢您能提供的任何帮助!

代码语言:javascript
运行
复制
import acm.program.*;
import acm.graphics.*;
import acm.util.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.Component.*;
import java.awt.Color.*;

import acm.program.*;
import acm.graphics.*;
import acm.util.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class Board extends GraphicsProgram 
{
  // constants
  private final int 
    APPLICATION_WIDTH = 300,
    APPLICATION_HEIGHT = 300; // application width and height should be equal

  private final int ALL_DOTS = 900;
  private final int DELAY = 100;

  ArrayList<GRect> snakeJoints = new ArrayList<GRect>();
  private Enemy enemy;
  private int dots, foodX, foodY;
  private int randPos = APPLICATION_WIDTH/10 - 1;
  private int dotSize = APPLICATION_WIDTH/30;
  private boolean right = false;
  private boolean left = false;
  private boolean up = false;
  private boolean down = false;
  private boolean gameOver = false;
  private GImage ball, food;
  private RandomGenerator rand;
  private GLabel gameLost;

  public void init()
  {
    setSize(APPLICATION_WIDTH + 3*dotSize, APPLICATION_HEIGHT + 8*dotSize);
    addKeyListeners();

    rand = new RandomGenerator();

    GRect dot = new GRect(dotSize, dotSize);

    snakeJoints.add(new GRect(dotSize, dotSize));
    snakeJoints.get(0).setFillColor(Color.RED);
    snakeJoints.get(0).setFilled(true);

    food = new GImage("food.png");
    food.setSize(.9 * dotSize, .9 * dotSize);

    setBackground(Color.BLACK);

    newSquare();

    placeFood();

    enemy = new Enemy(dotSize);
    add(enemy);
    enemy.setFillColor(Color.MAGENTA);
    enemy.setFilled(true);
    enemy.setLocation(rand.nextInt(1, randPos - 3)*dotSize, 
                      rand.nextInt(1, randPos - 3)*dotSize);
  }

  public void run() 
  {
    while (!gameOver) 
    {
      oneTimeStep();
      pause(DELAY);
    }
  }

  public void oneTimeStep()
  {
    checkLoseCollision();
    checkFood();
    move();
  }

  public void newSquare() 
  {
    snakeJoints.add(new GRect(dotSize, dotSize));
    snakeJoints.get(0).setFillColor(Color.RED);
    snakeJoints.get(0).setFilled(true);
    add(snakeJoints.get(0), APPLICATION_WIDTH/2, APPLICATION_HEIGHT/2);
  }

  public void placeFood() 
  {
    int i = (int) (Math.random() * randPos);
    foodX = ((i * dotSize));
    i = (int) (Math.random() * randPos);
    foodY = ((i * dotSize));
    add(food, foodX - dotSize, foodY - dotSize);
  }

  public void gameLost() 
  {
    gameOver = true;
    gameLost = new GLabel("Game Over", APPLICATION_WIDTH/2, 
                          APPLICATION_HEIGHT/2);
    gameLost.setColor(Color.BLUE);
    add(gameLost);
  }

  public void checkFood() 
  {
    if (snakeJoints.get(0).getBounds().intersects(food.getBounds())) 
    {
      remove(food);
      newSquare();
      placeFood();
    }
  }

  public void move()
  {
    for (int i = snakeJoints.size()-1; i > 0; i--)
    {
      snakeJoints.get(i).setLocation(snakeJoints.get(i-1).getX(), snakeJoints.get(i-1).getY());
    }

    if (left)
    {
      snakeJoints.get(0).move(-dotSize, 0);
    }

    if (right)
    {
      snakeJoints.get(0).move(dotSize, 0);
    }

    if (up) 
    {
      snakeJoints.get(0).move(0, -dotSize);
    }

    if (down) 
    {
      snakeJoints.get(0).move(0, dotSize);
    }
  }

  public void checkLoseCollision() 
  {
    for (int i = dots; i > 0; i--) 
    {
      if ((i > 4) && (snakeJoints.get(0).getBounds().intersects
                        (snakeJoints.get(i).getBounds()))) 
      {
        gameLost();
      }
    }

    if (snakeJoints.get(0).getY() + dotSize > APPLICATION_HEIGHT || snakeJoints.get(0).getY() < 0)
    {
      gameLost();
    }

    if (snakeJoints.get(0).getX() + dotSize > APPLICATION_WIDTH || snakeJoints.get(0).getX() < 0)
    {
      gameLost();
    }

    if (snakeJoints.get(0).getBounds().intersects(enemy.getBounds()))
    {
      gameLost();
    }
  }

  public void keyPressed(KeyEvent e)
  {
    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT)
    {
      left = true;
      right = false;
      up = false;
      down = false;
    }

    if (key == KeyEvent.VK_RIGHT)
    {
      right = true;
      left = false;
      up = false;
      down = false;
    }

    if (key == KeyEvent.VK_UP)
    {
      up = true;
      down = false;
      right = false;
      left = false;
    }

    if (key == KeyEvent.VK_DOWN)
    {
      down = true;
      up = false;
      right = false;
      left = false;
    }
  }
}
EN

回答 2

Stack Overflow用户

发布于 2013-12-06 23:44:39

代码语言:javascript
运行
复制
 public void newSquare() 
  {
    snakeJoints.add(new GRect(dotSize, dotSize));
    snakeJoints.get(0).setFillColor(Color.RED);
    snakeJoints.get(0).setFilled(true);
    **add(snakeJoints.get(0), APPLICATION_WIDTH/2, APPLICATION_HEIGHT/2);**
  }

我相信您的最后一行(APPLICATION add(snakeJoints.get(0),APPLICATION_WIDTH/2,APPLICATION_HEIGHT/2); )将您的蛇置于中心。调用checkFood调用newSquare,它不是在蛇的末端添加新的正方形,而是将它设置在应用程序窗口的中心(尺寸/2)。

请注意,如果你的蛇头图形与其他部分相同,你基本上可以把食物变成正方形,然后把它变成蛇头(效果是一样的--蛇变长了)。

票数 0
EN

Stack Overflow用户

发布于 2013-12-06 23:46:14

在这段代码中,您有几个问题:

代码语言:javascript
运行
复制
public void newSquare() 
  {
    snakeJoints.add(new GRect(dotSize, dotSize));
    snakeJoints.get(0).setFillColor(Color.RED);
    snakeJoints.get(0).setFilled(true);
    add(snakeJoints.get(0), APPLICATION_WIDTH/2, APPLICATION_HEIGHT/2);
  }

snakeJoins.add()会将新的关节添加到列表的末尾,但您随后将继续操作第一个元素。此外,您还可以将新连接的坐标设置到屏幕的中间。

我认为你应该做的是在你移动蛇之前检查你的蛇什么时候会吃到食物。这样你就可以让食物矩形成为你的蛇的第一个关节,而你不再需要在这次迭代中移动它。

编辑:一些思考的食粮(伪代码):

代码语言:javascript
运行
复制
public void move()
  {
    for (int i = snakeJoints.size()-1; i > 0; i--)
    {
      snakeJoints.get(i).setLocation(snakeJoints.get(i-1).getX(), snakeJoints.get(i-1).getY());
    }
    GRect newPosition = new GRect(snakeJoints.get(0).getBounds());
    if (left)
    {
      newPostition.setLocation(newPostition.getX()-dotSize, newPosition.getY());
    }

    if (right) {//etc
    }

    if (intersectsWithFood(newLocation) {
      //repaint food as snake joint
      food.setFillColor(Color.RED);
      food.setFilled(true);
      snakeJoints.addFirst(food); //add food as a joint
      createFood();//create another food
    } else {
      snakeJoints.get(0).setLocation(newLocation.getX(), newLocation.getY());
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20427708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档