碰撞检测在贪吃蛇游戏中不起作用
Collision Detection not working in Snake Game
我一直在编写贪吃蛇游戏(复古街机游戏),在实现碰撞检测时,我意识到它根本不起作用。这不是我第一次不得不使用碰撞检测,所以我认为问题不在于此(但它可以!)。相反,我认为它与外部 类 以及坐标未更新有关,但也可能只是其他原因。这是代码:
注意:这不是完整的代码,但为了避免混淆......这里是所有 类 的列表(是的,我知道,有很多......但我喜欢有条理)
主要
看法
模型
移动动作
实体(接口)
食物
分割
蛇
方向(枚举)
型号
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Timer;
public class Model {
List<Entity> entities;
List<Direction> direction;
Snake snake;
Segment snakeHead;
Food food;
View view;
int timeSpent = 0;
public Model() {
entities = new ArrayList<Entity>(3);
direction = new ArrayList<Direction>();
direction.add(Direction.RIGHT);
snake = new Snake(new Point(100, 100));
food = new Food(new Point(300, 200));
entities.add(snake);
entities.add(food);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
update();
view.repaint();
}
});
timer.start();
}
public void update() {
Segment snakeHead = snake.getSegments()[0];
changeHeadLoc(snakeHead);
changeSegmentLoc();
}
public void checkFoodCol(Segment snakeHead) {
if (snakeHead.getLocation().x + snakeHead.getSize().width > food.getLocation().x) {
System.out.println("1");
// snake.increaseSegmentCount(1);
}
if (snakeHead.getLocation().x < food.getLocation().x + food.getSize().width) {
System.out.println("2");
// snake.increaseSegmentCount(2);
}
if (snakeHead.getLocation().y + snakeHead.getSize().height > food.getLocation().y) {
System.out.println("3");
// snake.increaseSegmentCount(3);
}
if (snakeHead.getLocation().y < food.getLocation().y + food.getSize().height) {
System.out.println("4");
// snake.increaseSegmentCount(4);
}
}
public void changeHeadLoc(Segment snakeHead) {
if (direction.contains(Direction.UP)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x, snakeHead.getLocation().y - 1));
}
if (direction.contains(Direction.DOWN)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x, snakeHead.getLocation().y + 1));
}
if (direction.contains(Direction.LEFT)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x - 1, snakeHead.getLocation().y));
}
if (direction.contains(Direction.RIGHT)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x + 1, snakeHead.getLocation().y));
}
}
public void changeSegmentLoc() {
if (!direction.isEmpty()) {
for (int i = 1; i <= snake.getSegmentCount(); i++) {
Segment currentSegment = snake.getSegments()[i];
Segment previousSegment = snake.getSegments()[i - 1];
if (currentSegment != null) {
if (direction.contains(Direction.UP)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x, previousSegment.getLocation().y - 1));
}
if (direction.contains(Direction.DOWN)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x, previousSegment.getLocation().y + 1));
}
if (direction.contains(Direction.LEFT)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x - 1, previousSegment.getLocation().y));
}
if (direction.contains(Direction.RIGHT)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x + 1, previousSegment.getLocation().y));
}
}
}
}
}
public Entity[] getEntities() {
return entities.toArray(new Entity[0]);
}
public List<Direction> getDirection() {
return direction;
}
public void setView(View view) {
this.view = view;
}
}
食物
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
public class Food implements Entity {
Point location;
Dimension size = new Dimension(15, 15);
public Food(Point location) {
this.location = location;
}
public Dimension getSize() {
return size;
}
public Point getLocation() {
return location;
}
@Override
public void paint(Graphics g) {
g.setColor(Color.RED);
g.fillRect(getLocation().x, getLocation().y, getSize().width, getSize().height);
}
}
段
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
public class Segment {
Point location;
Point oldLocation;
public Segment(Point location) {
this.location = location;
}
public Dimension getSize() {
return new Dimension(20, 20);
}
public void setLocation(Point location) {
oldLocation = location;
this.location = location;
}
public Point getLocation() {
return location;
}
public Point getOldLocation() {
return oldLocation;
}
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(location.x, location.y, 20, 20);
}
}
Snake
import java.awt.Graphics;
import java.awt.Point;
public class Snake implements Entity {
Point location;
Segment[] segments;
int segmentCount = 0;
public Snake(Point location) {
this.location = location;
segments = new Segment[25];
segments[segmentCount] = new Segment(new Point(location.x, location.y));
segmentCount++;
}
public void increaseSegmentCount(int relativeTo) {
// TODO Add code to make it add the new Segment correctly
segments[segmentCount] = new Segment(
new Point(segments[segmentCount - 1].getLocation().x + segments[segmentCount - 1].getSize().width,
segments[segmentCount - 1].getLocation().y + segments[segmentCount - 1].getSize().height));
if (relativeTo == 1) {
}
segmentCount++;
}
public Segment[] getSegments() {
return segments;
}
public int getSegmentCount() {
return segmentCount;
}
@Override
public void paint(Graphics g) {
for (Segment segment : segments) {
if (segment != null) {
segment.paint(g);
}
}
}
}
您需要在某个地方的更新方法中调用您的 checkFoodCol 方法,例如
public void update() {
Segment snakeHead = snake.getSegments()[0];
checkFoodCol(snakeHead);
changeHeadLoc(snakeHead);
changeSegmentLoc();
}
我一直在编写贪吃蛇游戏(复古街机游戏),在实现碰撞检测时,我意识到它根本不起作用。这不是我第一次不得不使用碰撞检测,所以我认为问题不在于此(但它可以!)。相反,我认为它与外部 类 以及坐标未更新有关,但也可能只是其他原因。这是代码:
注意:这不是完整的代码,但为了避免混淆......这里是所有 类 的列表(是的,我知道,有很多......但我喜欢有条理)
主要 看法 模型 移动动作 实体(接口) 食物 分割 蛇 方向(枚举)
型号
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Timer;
public class Model {
List<Entity> entities;
List<Direction> direction;
Snake snake;
Segment snakeHead;
Food food;
View view;
int timeSpent = 0;
public Model() {
entities = new ArrayList<Entity>(3);
direction = new ArrayList<Direction>();
direction.add(Direction.RIGHT);
snake = new Snake(new Point(100, 100));
food = new Food(new Point(300, 200));
entities.add(snake);
entities.add(food);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
update();
view.repaint();
}
});
timer.start();
}
public void update() {
Segment snakeHead = snake.getSegments()[0];
changeHeadLoc(snakeHead);
changeSegmentLoc();
}
public void checkFoodCol(Segment snakeHead) {
if (snakeHead.getLocation().x + snakeHead.getSize().width > food.getLocation().x) {
System.out.println("1");
// snake.increaseSegmentCount(1);
}
if (snakeHead.getLocation().x < food.getLocation().x + food.getSize().width) {
System.out.println("2");
// snake.increaseSegmentCount(2);
}
if (snakeHead.getLocation().y + snakeHead.getSize().height > food.getLocation().y) {
System.out.println("3");
// snake.increaseSegmentCount(3);
}
if (snakeHead.getLocation().y < food.getLocation().y + food.getSize().height) {
System.out.println("4");
// snake.increaseSegmentCount(4);
}
}
public void changeHeadLoc(Segment snakeHead) {
if (direction.contains(Direction.UP)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x, snakeHead.getLocation().y - 1));
}
if (direction.contains(Direction.DOWN)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x, snakeHead.getLocation().y + 1));
}
if (direction.contains(Direction.LEFT)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x - 1, snakeHead.getLocation().y));
}
if (direction.contains(Direction.RIGHT)) {
snakeHead.setLocation(new Point(snakeHead.getLocation().x + 1, snakeHead.getLocation().y));
}
}
public void changeSegmentLoc() {
if (!direction.isEmpty()) {
for (int i = 1; i <= snake.getSegmentCount(); i++) {
Segment currentSegment = snake.getSegments()[i];
Segment previousSegment = snake.getSegments()[i - 1];
if (currentSegment != null) {
if (direction.contains(Direction.UP)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x, previousSegment.getLocation().y - 1));
}
if (direction.contains(Direction.DOWN)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x, previousSegment.getLocation().y + 1));
}
if (direction.contains(Direction.LEFT)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x - 1, previousSegment.getLocation().y));
}
if (direction.contains(Direction.RIGHT)) {
currentSegment.setLocation(
new Point(previousSegment.getLocation().x + 1, previousSegment.getLocation().y));
}
}
}
}
}
public Entity[] getEntities() {
return entities.toArray(new Entity[0]);
}
public List<Direction> getDirection() {
return direction;
}
public void setView(View view) {
this.view = view;
}
}
食物
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
public class Food implements Entity {
Point location;
Dimension size = new Dimension(15, 15);
public Food(Point location) {
this.location = location;
}
public Dimension getSize() {
return size;
}
public Point getLocation() {
return location;
}
@Override
public void paint(Graphics g) {
g.setColor(Color.RED);
g.fillRect(getLocation().x, getLocation().y, getSize().width, getSize().height);
}
}
段
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
public class Segment {
Point location;
Point oldLocation;
public Segment(Point location) {
this.location = location;
}
public Dimension getSize() {
return new Dimension(20, 20);
}
public void setLocation(Point location) {
oldLocation = location;
this.location = location;
}
public Point getLocation() {
return location;
}
public Point getOldLocation() {
return oldLocation;
}
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(location.x, location.y, 20, 20);
}
}
Snake
import java.awt.Graphics;
import java.awt.Point;
public class Snake implements Entity {
Point location;
Segment[] segments;
int segmentCount = 0;
public Snake(Point location) {
this.location = location;
segments = new Segment[25];
segments[segmentCount] = new Segment(new Point(location.x, location.y));
segmentCount++;
}
public void increaseSegmentCount(int relativeTo) {
// TODO Add code to make it add the new Segment correctly
segments[segmentCount] = new Segment(
new Point(segments[segmentCount - 1].getLocation().x + segments[segmentCount - 1].getSize().width,
segments[segmentCount - 1].getLocation().y + segments[segmentCount - 1].getSize().height));
if (relativeTo == 1) {
}
segmentCount++;
}
public Segment[] getSegments() {
return segments;
}
public int getSegmentCount() {
return segmentCount;
}
@Override
public void paint(Graphics g) {
for (Segment segment : segments) {
if (segment != null) {
segment.paint(g);
}
}
}
}
您需要在某个地方的更新方法中调用您的 checkFoodCol 方法,例如
public void update() {
Segment snakeHead = snake.getSegments()[0];
checkFoodCol(snakeHead);
changeHeadLoc(snakeHead);
changeSegmentLoc();
}