- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在制作一个贪吃蛇游戏,除了蛇吃自己的部分外,它运行良好。
到目前为止,这是我的代码:
障碍类
class Obstacle {
int x, y;
public Obstacle(int x, int y) {
this.x = x;
this.y = y;
}
public void draw(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(x, y, 10, 10);
}
}
食品类
class Food {
int x, y;
public Food(int x, int y) {
this.x = x;
this.y = y;
}
public void draw(Graphics g) {
g.setColor(Color.red);
g.fillRect(x, y, 10, 10);
}
}
body 等级
class Body {
int x, y;
public Body(int x, int y) {
this.x = x;
this.y = y;
}
public void draw(Graphics g) {
g.setColor(Color.green);
g.fillRect(x, y, 10, 10);
g.setColor(Color.black);
g.drawRect(x, y, 10, 10);
}
}
屏幕类
class Screen extends JPanel implements ActionListener, KeyListener {
int WIDTH = 800, HEIGHT = 800;
public static int time = 50;
Timer t;
int x = 400, y = 400;
boolean right = false, left = false, up = false, down = false;
public static int grade = 0;
LinkedList<Food> foods;
LinkedList<Body> snake;
LinkedList<Obstacle> block;
Body b;
Food f;
Obstacle k;
Random rand = new Random();
int size = 3;
public Screen() {
init();
}
public void init() {
block = new LinkedList<Obstacle>();
foods = new LinkedList<Food>();
snake = new LinkedList<Body>();
level();
t = new Timer(time, this);
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void tracking() {
if (x < 0 || x > 800 || y < 0 || y > 800) {
hit();
}
}
public void level() {
Object[] options = {"Level 1", "Level 2", "Level 3"};
int option = JOptionPane.showOptionDialog(null, "Please Select a Level", "Level Option",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
switch (option) {
case JOptionPane.YES_OPTION:
System.out.println("Before: " + time);
time = 50;
System.out.println("After: " + time);
break;
case JOptionPane.NO_OPTION:
System.out.println("Before: " + time);
time = 30;
System.out.println("After: " + time);
break;
case JOptionPane.CANCEL_OPTION:
System.out.println("Before: " + time);
time = 10;
System.out.println("After: " + time);
break;
}
}
public void hit() {
t.stop();
if (JOptionPane.showConfirmDialog(null, "Snake: You hit the wall! \nRestart the Game?", "OUCH!!!",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
x = 400;
y = 400;
while (snake.size() != 3) {
snake.remove();
size = 3;
}
init();
} else {
System.exit(0);
}
}
public void move() {
if (right) x += 10;
if (left) x -= 10;
if (up) y -= 10;
if (down) y += 10;
}
public void snake() {
if (snake.size() == 0) {
b = new Body(x, y);
snake.add(b);
}
move();
b = new Body(x, y);
snake.add(b);
if (snake.size() > size) {
snake.remove(0);
}
}
public void food() {
if (foods.size() == 0) {
int ok = 0;
int rx = 0;
int ry = 0;
while (ok != 1) {
rx = (int) (rand.nextInt(700) + 1);
ry = (int) (rand.nextInt(700) + 1);
if ((rx % 10) == 0 && (ry % 10) == 0) {
ok = 1;
}
}
f = new Food(rx, ry);
foods.add(f);
}
if (snake.get(snake.size() - 1).x == foods.get(0).x && snake.get(snake.size() - 1).y == foods.get(0).y) {
foods.remove();
size++;
grade += 100;
}
}
public void block() {
if (block.size() == 0) {
int ok = 0;
int rx = 0;
int ry = 0;
while (ok != 15) {
rx = (int) (rand.nextInt(750) + 1);
ry = (int) (rand.nextInt(750) + 1);
if ((rx % 10) == 0 && (ry % 10) == 0) {
k = new Obstacle(rx, ry);
block.add(k);
int temp = 10;
int r = (int) (rand.nextInt(2) + 1);
for (int i = 0; i < 5; i++) {
if (r == 1) {
k = new Obstacle(rx + temp , ry);
} else if (r == 2) {
k = new Obstacle(rx , ry + temp);
}
block.add(k);
if ((k.x == foods.get(0).x && k.y == foods.get(0).y) ||
(k.x == 400 && k.y == 400) ||
((k.x >= 350 && k.x <= 450) && (k.y >= 350 && k.y <= 450))) {
block.remove(k);
}
temp += 10;
}
ok++;
}
}
}
for (int i = 0; i < block.size(); i++) {
if (snake.get(snake.size() - 1).x == block.get(i).x && snake.get(snake.size() - 1).y == block.get(i).y) {
hit();
}
}
}
public void update() {
snake();
food();
block();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
for (int i = 1; i < WIDTH / 10; i++) {
g.drawLine(i * 10, 0, i * 10, HEIGHT);
}
for (int i = 1; i < HEIGHT / 10; i++) {
g.drawLine(0, i * 10, WIDTH, i * 10);
}
for (int i = 0; i < snake.size(); i++) {
snake.get(i).draw(g);
}
for (int i = 0; i < foods.size(); i++) {
foods.get(i).draw(g);
}
for (int i = 0; i < block.size(); i++) {
block.get(i).draw(g);
}
}
@Override
public void actionPerformed(ActionEvent e) {
update();
tracking();
repaint();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT && left == false) {
up = false;
down = false;
right = true;
}
if (key == KeyEvent.VK_LEFT && right == false) {
up = false;
down = false;
left = true;
}
if (key == KeyEvent.VK_UP && down == false) {
left = false;
right = false;
up = true;
}
if (key == KeyEvent.VK_DOWN && up == false) {
left = false;
right = false;
down = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
}
和主类 SnakeGame
public class SnakeGame extends JFrame {
public static void main(String[] args) {
JFrame f = new JFrame();
Screen s = new Screen();
f.add(s);
f.setSize(810, 810);
f.setVisible(true);
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
所以一开始我决定比较蛇头吃尾部的时候,但是因为我的蛇是动的;尾部的 x 和 y 在头部的 x 和 y 之后,所以比较总是正确的
我也想到了当蛇改变方向,然后做一些代码来跟踪x y坐标和它的尾部x y坐标,但我不知道如何走
有没有其他方法可以让游戏在蛇吃自己的时候停止?
最佳答案
当您调用 move();
时您获得了 x
的新值和 y
,蛇的“头”移动到的位置。我看到你的 LinkedList<Body> snake;
有蛇 body 各部分的位置。
如果每次调用 move();
,你将你的下一个“头部”位置与蛇的所有其他部分进行比较,你会发现它是否命中。
像这样:
for (int i = 0; i < snake.size(); i++) {
if ((x == snake.get(i).x) && y == snake.get(i).y) {
hit();
}
}
游戏将从 hit();
开始因为“头”的x
和 y
匹配您的全局 x
和 y
变量,所以你必须修复它(即等待 move();
调用开始检查)。
编辑:
这是一个示例修改:
添加boolean started = false;
给你的Screen class
:
更改 snake()
检查碰撞的方法:
public void snake() {
if (snake.size() == 0) {
b = new Body(x, y);
snake.add(b);
}
move();
if (started) {
for (int i = 0; i < snake.size(); i++) {
if ((x == snake.get(i).x) && y == snake.get(i).y) {
hit();
}
}
}
b = new Body(x, y);
snake.add(b);
if (snake.size() > size) {
snake.remove(0);
}
}
添加started = true;
到 food()
的结尾方法(找不到更好的地方,但我认为你可以!):
public void food() {
if (foods.size() == 0) {
int ok = 0;
int rx = 0;
int ry = 0;
while (ok != 1) {
rx = (int) (rand.nextInt(700) + 1);
ry = (int) (rand.nextInt(700) + 1);
if ((rx % 10) == 0 && (ry % 10) == 0) {
ok = 1;
}
}
f = new Food(rx, ry);
foods.add(f);
}
if (snake.get(snake.size() - 1).x == foods.get(0).x
&& snake.get(snake.size() - 1).y == foods.get(0).y) {
foods.remove();
size++;
grade += 100;
started = true;
}
}
它应该可以工作!
关于java - 蛇游戏 : how to stop the game when the snake eat itself,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31552958/
我想将一个字符串分成两组。该字符串的结构非常简单,但我无法使其工作。 txt library(stringr) >str_match(txt, "([a-zA-Z]*)([0-9].*)")
介绍性胡言乱语: 我当前的项目有点像 Lisp 解析器,而 RegEx 确实是一个奇迹,尽管它在这个特定的函数中让我有点头疼: 该函数应该做什么: 接收一个包含方程的字符串并返回它的格式,以便解析器可
解析代码 $str = 'My name is Michael. I am a sportsman!'; preg_match('|My name is (.*?)\. I am a (.*?)|',
解析代码 $str = 'My name is Michael. I am a sportsman!'; preg_match('|My name is (.*?)\. I am a (.*?)|',
之后: String content = "Some \n multiline \n content"; //actually, content comes from request (tomcat
我编写了这段代码,通过更改 IAT 和 EAT 中的地址来 Hook API 函数:http://pastebin.com/7d9N1J2c 当我想 Hook “recv”或“connect”时,这很
如何处理 TestNG 中的预期异常,以便无论测试方法中的代码是否抛出异常,测试都会通过 我有 testng 测试方法,它创建某些对象的列表。在 for 循环中,针对每个对象执行特定操作。此操作可能会
我在 shell 变量中有一些多行字符串。字符串的所有行都有至少几个空白字符的未知缩进级别(在我的示例中为 8 个空格,但可以是任意的)。例如,让我们看一下这个示例字符串: I am
我正在使用官方 Sybase JDBC 驱动程序连接到数据库并通过创建 CallableStatement、将参数绑定(bind)到它并在其上调用 .execute() 来调用存储过程。 但是,我发现
我正在开发一个抽屉,用于在我的应用程序的屏幕之间导航。我有一个主屏幕,其标签为“Home”,在编译应用程序时Drawer仅显示“Hom”而不显示全名(Home) 环境: react 原生0.60 re
我使用 for 循环将请求发送到 http://www.example.com : for(int i = 0; i .我将这个 10 槽函数连接到信号 finished(QNetworkR
我有一些学校的 C 练习练习,从昨天开始我就一直在做这些练习,但我对某个特定的练习非常生硬。 在这个程序中,它必须重复最多 5 次或直到用户未能回答“安全问题”: 必须要求用户输入密码(最初是“abc
据我所见,当您向下滚动时,下面的 div 会吞噬上面的图像,从而创建我认为不错的视觉效果。 我唯一的问题是我不知道搜索有关该过程本身的教程的术语是什么。 有人知道我会使用什么搜索词来找到好的教程吗?我
我有一个 UI 线程和另一个线程,我想使用 PostMessage() 从另一个 trhead 向 UI 线程发送一条用户定义的消息。 如果UI线程显示一个消息框,然后我发送用户自定义消息,消息框的消
我遇到了一个(至少对我而言)非常的奇怪情况。 我正在尝试重写蛇,并且移动进行得非常顺利,只有蛇在吃自己,虽然我正在删除 1 段并添加 1 (x + 1 - 1 = x?) 但是蛇消失了,而 Array
我将如何进行导出地址表 (EAT) Hook ? 我能够进行 IAT(导入地址表) Hook 。 有人能给我举个例子吗? 谢谢! 最佳答案 EAT Hook 遵循与 IAT Hook 非常相似的方法,
我所说的“吃”是指:当 Sprite A(马里奥)与 Sprite B(一枚硬币)发生碰撞时,会检测到碰撞并将硬币从场景中移除;然而,马里奥的运动并没有因为与硬币的碰撞而改变。 目前我正在使用 SKP
由于我的其他错误已解决,我针对此错误发布了一个新问题。 我制作了一个贪吃蛇 Canvas 游戏,但是当您同时按下两个按钮时我的蛇往往会吃掉自己。我不确定如何正确解释它,但事情就是这样: 假设我的蛇向左
首先这是我正在使用的: KDE neon 用户版 5.20 (Ubuntu 20.04) symfony CLI v4.21.3 php v7.4.3 PostgreSQL v12.5 Apache2
Closed. This question is opinion-based。它当前不接受答案。 想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。 已关闭6年。
我是一名优秀的程序员,十分优秀!