gpt4 book ai didi

java - 贪吃蛇游戏如何让尾部跟随头部?

转载 作者:行者123 更新时间:2023-12-01 18:12:57 25 4
gpt4 key购买 nike

我正在制作一个贪吃蛇游戏,但我陷入了让尾部跟随头部的位置。我听说在头部和尾部使用添加和删除可以实现这一点,但我不知道从哪里开始。

这是我到目前为止的代码:

Screen.java

public class Screen extends JPanel implements ActionListener, KeyListener {
public static final JLabel statusbar = new JLabel("Default");
public static final int WIDTH = 800, HEIGHT = 800;
Timer t = new Timer(100, this);
int x = 400;
int y = 400;
int size = 5; //increase size if eat
private boolean right = false, left = false, up = false, down = false;

int head = 0;

private LinkedList<BodyPart> snake = new LinkedList<BodyPart>();
private BodyPart b;

public Screen(){

initSnake();

t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}

public void update(){

}

public void direction(){
if(right) x+=10;
if(left) x-=10;
if(up) y-=10;
if(down) y+=10;
}

public void trackOutBound(){
if(x < 0 || x > 800 || y < 0 || y > 800) {
x = 400;
y = 400;
}
}

public void initSnake(){
if(snake.size() == 0){
b = new BodyPart(x, y);
for(int i = 0; i < size; i++) {
snake.add(b);
}
System.out.println(snake);
}
}

public static void main(String[] args) {

}

@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(new Color(10, 50, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);

g.setColor(Color.BLACK);
for(int i = 0; i < WIDTH / 10; i++) {
g.drawLine(i * 10, 0, i * 10, HEIGHT);
}

for(int i = 0; i < HEIGHT / 10; i++) {
g.drawLine(0, i * 10, WIDTH, i * 10);
}

int tempx = 0, tempy = 0;
int temp = 0;
for(int i = 0; i < size; i++){
if(i == head) {
snake.get(i).x = x;
snake.get(i).y = y;
snake.get(i).draw(g);
g.setColor(Color.blue);
g.fillRect(x, y, 10, 10);
g.setColor(Color.white);
g.drawRect(x, y, 10, 10);
} else if(i > 0 && up) {
snake.get(i).x = x;
snake.get(i).y = y + temp;
snake.get(i).draw(g);
} else if(i > 0 && down) {
snake.get(i).x = x;
snake.get(i).y = y - temp;
snake.get(i).draw(g);
} else if(i > 0 && left) {
snake.get(i).x = x + temp;
snake.get(i).y = y;
snake.get(i).draw(g);
} else if(i > 0 && right) {
snake.get(i).x = x - temp;
snake.get(i).y = y;
snake.get(i).draw(g);
}
temp += 10;
}

/*
if(snake.size() == 5){
snake.add(b);
size += 1;
}
*/

}

@Override
public void actionPerformed(ActionEvent e) {
direction();
trackOutBound();
repaint();
// System.out.println(snake);
statusbar.setText("(" + x + " , " + y + ")");
}

@Override
public void keyTyped(KeyEvent e) {}

@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT && !left) {
up = false;
down = false;
right = true;
}
if(key == KeyEvent.VK_LEFT && !right) {
up = false;
down = false;
left = true;
}
if(key == KeyEvent.VK_UP && !down) {
left = false;
right = false;
up = true;
}
if(key == KeyEvent.VK_DOWN && !up) {
left = false;
right = false;
down = true;
}
}

@Override
public void keyReleased(KeyEvent e) {}
}

BodyPart.java

public class BodyPart {

int x;
int y;

public BodyPart(int x, int y) {
this.x = x;
this.y = y;
}
public void draw(Graphics g) {
this.x = x;
this.y = y;
g.setColor(Color.red);
g.fillRect(x, y, 10, 10);
g.setColor(Color.white);
g.drawRect(x, y, 10, 10);
}
}

Frame.java

public class Frame extends JPanel {
private static JLabel statusbar = new JLabel("Default");

public void statusbar(){
statusbar = Screen.statusbar;
}

public static void main(String[] args) {
JFrame f = new JFrame();
Screen s = new Screen();
f.add(s);

f.add(statusbar, BorderLayout.SOUTH);
f.setSize(800, 800);
f.setVisible(true);
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

现在这段代码只会使尾部翻转到水平或垂直,是否可以使用这段代码使尾部跟随头部?或者我需要更改我的代码?

谢谢

最佳答案

基本思想是,您需要某种包含蛇的所有点的List。从概念上讲,List 将包含虚拟坐标,即 1x1 将表示虚拟空间中的坐标,该坐标表示虚拟板上的一个位置(该位置具有一定的宽度和高度) )。

然后您可以将其转换到屏幕上,这样蛇的每个部分都比单个像素大。因此,如果每个部分都是 5x5 像素,那么屏幕中的 1x1 实际上就是 5x5

每次蛇移动时,您都会向头部添加一个新值,并从尾部删除最后一个值(假设它没有增长)。当您需要绘制蛇时,您只需迭代List,绘制蛇的每个点即可。

下面是一个简单的例子,它使用一个LinkedList,它将一个新的Point推送到List上,创建一个新的头,并删除每个周期的最后一个元素(尾部)。

这基本上可以归结为......

snakeBody.removeLast();
snakeBody.push(new Point(xPos, yPos));

作为一个可运行的概念

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Snake {

public static void main(String[] args) {
new Snake();
}

public Snake() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public static class TestPane extends JPanel {

public enum Direction {

UP, DOWN, LEFT, RIGHT
}

private int xPos, yPos;

private Direction direction = Direction.UP;

private LinkedList<Point> snakeBody = new LinkedList<>();

public TestPane() {
xPos = 100;
yPos = 100;

for (int index = 0; index < 50; index++) {
snakeBody.add(new Point(xPos, yPos));
}

bindKeyStrokeTo("up.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), new MoveAction(Direction.UP));
bindKeyStrokeTo("down.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), new MoveAction(Direction.DOWN));

bindKeyStrokeTo("left.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), new MoveAction(Direction.LEFT));
bindKeyStrokeTo("right.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), new MoveAction(Direction.RIGHT));

Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
switch (direction) {
case UP:
yPos--;
break;
case DOWN:
yPos++;
break;
case LEFT:
xPos--;
break;
case RIGHT:
xPos++;
break;
}
if (yPos < 0) {
yPos--;
} else if (yPos > getHeight() - 1) {
yPos = getHeight() - 1;
}
if (xPos < 0) {
xPos--;
} else if (xPos > getWidth() - 1) {
xPos = getWidth() - 1;
}

snakeBody.removeLast();
snakeBody.push(new Point(xPos, yPos));
repaint();
}
});
timer.start();
}

public void bindKeyStrokeTo(String name, KeyStroke keyStroke, Action action) {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();

im.put(keyStroke, name);
am.put(name, action);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (Point p : snakeBody) {
g2d.drawLine(p.x, p.y, p.x, p.y);
}
g2d.dispose();
}

public class MoveAction extends AbstractAction {

private Direction moveIn;

public MoveAction(Direction direction) {
this.moveIn = direction;
}

@Override
public void actionPerformed(ActionEvent e) {
direction = this.moveIn;
}

}

}

}

现在,它没有碰撞检测或其他功能,但你可以移动蛇,它会跟随自己

关于java - 贪吃蛇游戏如何让尾部跟随头部?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31508913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com