我正在写一个Snake程序,并试图让它吃每一块食物都会增加Snake的长度。取而代之的是食物和独长蛇重新定位。我不知道如何让它(例如)在吃完一种食物后,在第一个盒子的先前位置出现一个新盒子,然后蛇继续前进。提前感谢您能提供的任何帮助!
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;
}
}
}
发布于 2013-12-06 23:44:39
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)。
请注意,如果你的蛇头图形与其他部分相同,你基本上可以把食物变成正方形,然后把它变成蛇头(效果是一样的--蛇变长了)。
发布于 2013-12-06 23:46:14
在这段代码中,您有几个问题:
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()
会将新的关节添加到列表的末尾,但您随后将继续操作第一个元素。此外,您还可以将新连接的坐标设置到屏幕的中间。
我认为你应该做的是在你移动蛇之前检查你的蛇什么时候会吃到食物。这样你就可以让食物矩形成为你的蛇的第一个关节,而你不再需要在这次迭代中移动它。
编辑:一些思考的食粮(伪代码):
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());
}
}
https://stackoverflow.com/questions/20427708
复制相似问题