当前位置: 首页 > 知识库问答 >
问题:

蛇游戏在Java但我的重启按钮不工作

相弘和
2023-03-14

我的游戏重启按钮不起作用,点击后会成倍增加。我并不完全理解Java,我认为自己很好。

package snake_game;

public class snake {

  public static void main(String arg[]) {

    new GameFrame();
    // is exacly the same as frame f = new frame();
    // this is shorter and does the same job

  }
}
package snake_game;

// import java.awt.event.ActionEvent;
// import java.awt.event.ActionListener;
// import java.awt.Graphics;
// import java.awt.event.KeyAdapter;
// import java.awt.event.KeyEvent;
// or I could write simply 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;

import javax.swing.JPanel;

public class GamePanel extends JPanel implements ActionListener {

  // panal dimentions
  static final int SCREEN_WIDTH = 600;
  static final int SCREEN_HEIGHT = 600;
  // panal dimentions
  // size
  static final int UNIT_SIZE = 25;
  // size to make 600 * 600 = 1200 px equel between 25 px
  static final int GAME_UNITS = (SCREEN_WIDTH * SCREEN_HEIGHT) / UNIT_SIZE;
  // size
  // delay how fast the game will be
  static final int DELAY = 75;
  // delay
  // dimentions
  final int x[] = new int[GAME_UNITS];
  final int y[] = new int[GAME_UNITS];
  // dimentions
  // snake
  int bodyParts = 6;
  // snake
  // apple
  int appleEaten;
  int appleX;
  int appleY;
  // apple
  char direction = 'R';
  boolean running = false;
  Timer timer;
  Random random;
  GamePanel game;
  JButton resetButton;

  GamePanel() {

    random = new Random();
    this.setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
    this.setBackground(Color.black);
    this.setFocusable(true);
    this.addKeyListener(new MyKeyAdapter());
    startGame();
    // when we want to make the program to continie we must say what the programm
    // must execute next

  }

  public void startGame() {
    newApple();
    running = true;
    timer = new Timer(DELAY, this);
    timer.start();
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    draw(g);

  }

  public void draw(Graphics g) {

    if (running) {

      for (int i = 0; i < SCREEN_HEIGHT / UNIT_SIZE; i++) {
        g.drawLine(i * UNIT_SIZE, 0, i * UNIT_SIZE, SCREEN_HEIGHT);
        g.drawLine(0, i * UNIT_SIZE, i * SCREEN_WIDTH, i * UNIT_SIZE);

      }
      g.setColor(Color.red);
      g.fillOval(appleX, appleY, UNIT_SIZE, UNIT_SIZE);

      for (int i = 0; i < bodyParts; i++) {
        if (i == 0) {
          g.setColor(Color.green);
          g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE);
        } else {
          g.setColor(new Color(45, 180, 0));
          // random color
          g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
          // random color
          g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE);
        }

      }
      g.setColor(Color.red);
      g.setFont(new Font("Ink Free", Font.BOLD, 30));
      FontMetrics metrics = getFontMetrics(g.getFont());
      g.drawString("SCORE:" + appleEaten, (SCREEN_WIDTH - metrics.stringWidth("SCORE:" + appleEaten)) / 2,
          g.getFont().getSize());
    } else {
      gameOver(g);
    }
  }

  public void newApple() {
    appleX = random.nextInt((int) (SCREEN_WIDTH / UNIT_SIZE)) * UNIT_SIZE;
    appleY = random.nextInt((int) (SCREEN_HEIGHT / UNIT_SIZE)) * UNIT_SIZE;
  }

  public void move() {

    for (int i = bodyParts; i > 0; i--) {
      x[i] = x[i - 1];
      y[i] = y[i - 1];

    }
    switch (direction) {
      case 'U':
        y[0] = y[0] - UNIT_SIZE;
        break;
      case 'D':
        y[0] = y[0] + UNIT_SIZE;
        break;
      case 'L':
        x[0] = x[0] - UNIT_SIZE;
        break;
      case 'R':
        x[0] = x[0] + UNIT_SIZE;
        break;
    }

  }

  public void checkApple() {
    if ((x[0] == appleX) && (y[0] == appleY)) {
      bodyParts++;
      appleEaten++;
      newApple();
    }
  }

  public void checkCollisions() {
    // check if head collides with body
    for (int i = bodyParts; i > 0; i--) {
      if ((x[0] == x[i]) && (y[0] == y[i])) {
        running = false;
      }

    }
    // check if head touches left border
    if (x[0] < 0) {
      running = false;
    }

    // check if head touches right border
    if (x[0] > SCREEN_WIDTH) {
      running = false;
    }
    // check if head touches top border
    if (y[0] < 0) {
      running = false;
    }
    // check if head touches bottom border
    if (y[0] > SCREEN_HEIGHT) {
      running = false;
    }
    if (!running) {
      timer.stop();
    }
  }

  public void gameOver(Graphics g) {
    // score
    g.setColor(Color.red);
    g.setFont(new Font("Ink Free", Font.BOLD, 30));
    FontMetrics metrics1 = getFontMetrics(g.getFont());
    g.drawString("SCORE:" + appleEaten, (SCREEN_WIDTH - metrics1.stringWidth("SCORE:" + appleEaten)) / 2,
        g.getFont().getSize());
    // game over text
    g.setColor(Color.red);
    g.setFont(new Font("Ink Free", Font.BOLD, 75));
    FontMetrics metrics2 = getFontMetrics(g.getFont());
    g.drawString("Game Over", (SCREEN_WIDTH - metrics2.stringWidth("Game Over")) / 2, SCREEN_HEIGHT / 2);
    // restart button
    resetButton = new JButton();
    resetButton.setText("Restart");
    resetButton.setSize(100, 50);
    resetButton.setLocation(150, 150);
    resetButton.addActionListener(this);

    game = new GamePanel();

    this.add(resetButton);
    this.add(game);
    this.setVisible(true);
    // restart button
  }

  @Override
  public void actionPerformed(ActionEvent e) {

    if (running) {
      move();
      checkApple();
      checkCollisions();

    }
    repaint();

    // restart button
    if (e.getSource() == resetButton) {
      this.remove(game);

      game = new GamePanel();
      this.add(game);
      resetButton.setVisible(false);
      SwingUtilities.updateComponentTreeUI(this);
      // restart button

    }

  }

  public class MyKeyAdapter extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {

      switch (e.getKeyCode()) {
        case KeyEvent.VK_LEFT:
          if (direction != 'R') {
            direction = 'L';
          }
          break;
        case KeyEvent.VK_RIGHT:
          if (direction != 'L') {
            direction = 'R';
          }
          break;
        case KeyEvent.VK_UP:
          if (direction != 'D') {
            direction = 'U';
          }
          break;
        case KeyEvent.VK_DOWN:
          if (direction != 'U') {
            direction = 'D';
          }
          break;

      }

    }

  }

}
package snake_game;

import javax.swing.JFrame;

public class GameFrame extends JFrame {

  GameFrame() {
    GamePanel panel = new GamePanel();
    this.add(panel);
    this.setTitle("Snake");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);
    this.pack();
    this.setVisible(true);
    this.setLocationRelativeTo(null);
    this.setUndecorated(false);
  }
}

共有1个答案

楚冷勋
2023-03-14

我将您的代码复制到我的Eclipse IDE并按原样运行它。我收到了以下运行时错误。

Exception in thread "main" java.awt.IllegalComponentStateException: The frame is displayable.
    at java.desktop/java.awt.Frame.setUndecorated(Frame.java:926)
    at com.ggl.testing.SnakeGame$GameFrame.<init>(SnakeGame.java:41)
    at com.ggl.testing.SnakeGame.main(SnakeGame.java:24)

Oracle有一个有用的教程,使用Swing创建GUI。跳过使用NetBeans IDE部分的学习Swing。密切关注Swing中的并发部分。

我编写Swing代码已经有10多年了,我的浏览器中有Oracle网站的书签。我仍然会查看如何使用某些组件,以确保正确使用它们。

我做的第一件事是放慢你的蛇的速度,这样我就可以测试游戏了。我将75的延迟更改为750的延迟。这是您当前GUI的屏幕截图。

查看您的代码,您可以扩展JFrame。您不需要扩展JFrame。您没有更改任何JFrame功能。使用JFrame要简单得多。这就引出了我的一条Java规则。

不要扩展Swing组件或任何Java类,除非您打算重写一个或多个类方法。

您确实扩展了JGroup。这很好,因为您覆盖了油漆组件方法。

最后,您的JPanel类做了太多的工作。您还大量使用静态字段。尽管只创建一个JPanel,但将每个类视为创建该类的多个实例是一个好习惯。这会减少你在未来遇到的问题。

你有正确的想法,创建三个类。

因此,让我们使用一些基本模式和Swing最佳实践来重新编写代码。现在,我不知道我们将创建多少个类。

当我编写Swing GUI时,我使用模型-视图-控制器(MVC)模式。该名称意味着您首先创建模型,然后创建视图,然后创建控制器。

应用程序模型由一个或多个普通Java getter/setter类组成。

视图由JFrame、一个或多个JPanels和任何其他必要的Swing组件组成。

控制器由一个或多个动作或动作监听器组成。在Swing中,通常没有一个控制器来“统领所有人”。

总结如下:

  • 视图从模型中读取信息
  • 视图不更新模型
  • 控制器更新模型并重新绘制/重新验证您的视图。

我创建了两个模型类,SnakeModel和Snake。

SnakeModel类是一个普通的Java getter/setter类,它包含一个Snake实例、吃苹果数、苹果位置、游戏区域大小和几个布尔值。一个布尔值指示游戏循环是否正在运行,另一个布尔值指示游戏是否结束。

游戏区使用java。awt。尺寸可容纳游戏区的宽度和高度。宽度和高度不必具有相同的值。游戏区域可以是矩形。

游戏区域是以单位来衡量的。在视图中,我将单位转换为像素。这与您所做的相反。如果您想更改游戏区域,您所要做的就是更改SnakeModel类中的维度。视图中的所有内容都基于游戏区域维度。

Snake类包含一个java.util.Listjava.awt.Point对象和一个char方向。java.awt.Point对象包含X和Y值。由于我们处理的是对象,而不是int值,因此当我们想要一个新的Point时,我们必须小心克隆对象。

所有Swing应用程序都必须从调用SwingU实用程序调用稍后方法开始。此方法可确保在事件调度线程上创建和执行Swing组件。

我创建了一个JFrame、一个绘图JGroup和一个单独的按钮JBoard。通常,将Swing组件添加到绘图JBoard不是一个好主意。通过创建一个单独的按钮JGroup,我几乎无需额外费用即可获得“开始游戏”按钮的附加功能。游戏运行时禁用该按钮。

必须按特定顺序调用JFrame方法。必须最后调用setVisible方法。

我为分数添加了一个单独的区域,使绘图变得更加复杂。

我只根据应用程序模型绘制游戏的状态,从而使绘制JGroup变得不那么复杂。句号。没有别的。

我将随机颜色限制在光谱的白色端,以保持蛇和绘图背景之间的对比度。

我使用键绑定而不是键侦听器。一个优点是,绘图无需聚焦。因为我有一个单独的按钮,所以绘图没有焦点。

另一个优点是,我可以用四行额外的代码添加WASD键。

一个缺点是键绑定代码看起来比键侦听器更复杂。一旦您编写了一些键绑定,您就会意识到这些优势。

我创建了三个控制器类,ButtonListener、TimerListener和MovementAction。

ButtonListener类实现了ActionListener。ButtonListener类初始化游戏模型并重新启动计时器。

TimerListener类实现了ActionListenerTimerListener类是游戏循环。这个类移动蛇,检查苹果是否被吃掉,检查蛇是否移动到游戏区域之外或触摸自己,并重新绘制绘图JBoard。我用你的代码作为这个类中代码的模型。

MovementAction类扩展了AbstractAction。类实现了动作。此类根据按键更改蛇的方向。

我创建了MovementAction类的四个实例,每个方向一个。这使得类的actionPerform方法简单得多。

这是当你开始游戏时修改后的GUI的样子。

这是游戏中修改过的GUI。

这是游戏结束时修改后的GUI。

下面是完整的可运行代码。我将所有附加的类都设置为内部类,以便将此代码作为一个块发布。

您应该将单独的类放在单独的文件中。

在设置Swing GUI项目时,我为模型、视图和控制器创建单独的包。这有助于我保持代码井井有条。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class SnakeGame implements Runnable {

    public static void main(String arg[]) {
        SwingUtilities.invokeLater(new SnakeGame());
    }
    
    private final GamePanel gamePanel;
    
    private final JButton restartButton;
    
    private final SnakeModel model;
    
    public SnakeGame() {
        this.model = new SnakeModel();
        this.restartButton = new JButton("Start Game");
        this.gamePanel = new GamePanel(model);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Snake");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(gamePanel, BorderLayout.CENTER);
        frame.add(createButtonPanel(), BorderLayout.SOUTH);
        
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        panel.setBackground(Color.black);
        
        restartButton.addActionListener(new ButtonListener(this, model));
        panel.add(restartButton);
        
        return panel;
    }
    
    public JButton getRestartButton() {
        return restartButton;
    }

    public void repaint() {
        gamePanel.repaint();
    }
    
    public class GamePanel extends JPanel {

        private static final long serialVersionUID = 1L;
        
        private final int margin, scoreAreaHeight, unitSize;
        
        private final Random random;
        
        private final SnakeModel model;
        
        public GamePanel(SnakeModel model) {
            this.model = model;
            this.margin = 10;
            this.unitSize = 25;
            this.scoreAreaHeight = 36 + margin;
            this.random = new Random();
            this.setBackground(Color.black);
            
            Dimension gameArea = model.getGameArea();
            int width = gameArea.width * unitSize + 2 * margin;
            int height = gameArea.height * unitSize + 2 * margin + scoreAreaHeight;
            this.setPreferredSize(new Dimension(width, height));
            setKeyBindings();
        }
        
        private void setKeyBindings() {
            InputMap inputMap = this.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = this.getActionMap();
            
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down");
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");
            
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
            inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
            
            actionMap.put("up", new MovementAction(model, 'U', 'D'));
            actionMap.put("down", new MovementAction(model, 'D', 'U'));
            actionMap.put("left", new MovementAction(model, 'L', 'R'));
            actionMap.put("right", new MovementAction(model, 'R', 'L'));
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            Dimension gameArea = model.getGameArea();
            drawHorizontalGridLines(g, gameArea);
            drawVerticalGridLines(g, gameArea);
            drawSnake(g);
            drawScore(g, gameArea);
            
            if (model.isGameOver) {
                drawGameOver(g, gameArea);
            } else {
                drawApple(g);
            }
        }

        private void drawHorizontalGridLines(Graphics g, Dimension gameArea) {
            int y1 = scoreAreaHeight + margin;
            int y2 = y1 + gameArea.height * unitSize;
            int x = margin;
            for (int index = 0; index <= gameArea.width; index++) {
                g.drawLine(x, y1, x, y2);
                x += unitSize;
            }
        }

        private void drawVerticalGridLines(Graphics g, Dimension gameArea) {
            int x1 = margin;
            int x2 = x1 + gameArea.width * unitSize;
            int y = margin + scoreAreaHeight;
            for (int index = 0; index <= gameArea.height; index++) {
                g.drawLine(x1, y, x2, y);
                y += unitSize;
            }
        }

        private void drawApple(Graphics g) {
            // Draw apple
            g.setColor(Color.red);
            Point point = model.getAppleLocation();
            if (point != null) {
                int a = point.x * unitSize + margin + 1;
                int b = point.y * unitSize + margin + scoreAreaHeight + 1;
                g.fillOval(a, b, unitSize - 2, unitSize - 2);
            }
        }

        private void drawScore(Graphics g, Dimension gameArea) {
            g.setColor(Color.red);
            g.setFont(new Font("Ink Free", Font.BOLD, 36));
            FontMetrics metrics = getFontMetrics(g.getFont());
            int width = 2 * margin + gameArea.width * unitSize;
            String text = "SCORE: " + model.getApplesEaten();
            int textWidth = metrics.stringWidth(text);
            g.drawString(text, (width - textWidth) / 2, g.getFont().getSize());
        }
        
        private void drawSnake(Graphics g) {
            // Draw snake
            Snake snake = model.getSnake();
            List<Point> cells = snake.getCells();
            Point cell = cells.get(0);
            drawSnakeCell(g, cell, Color.green);
            for (int index = 1; index < cells.size(); index++) {
//              Color color = new Color(45, 180, 0);
                // random color
                Color color = new Color(getColorValue(), getColorValue(), 
                        getColorValue());
                cell = cells.get(index);
                drawSnakeCell(g, cell, color);
            }
        }
        
        private void drawSnakeCell(Graphics g, Point point, Color color) {
            int x = margin + point.x * unitSize;
            int y = margin + scoreAreaHeight + point.y * unitSize;
            if (point.y >= 0) {
                g.setColor(color);
                g.fillRect(x, y, unitSize, unitSize);
            }
        }
        
        private int getColorValue() {
            // White has color values of 255
            return random.nextInt(64) + 191;
        }
        
        private void drawGameOver(Graphics g, Dimension gameArea) {
            g.setColor(Color.red);
            g.setFont(new Font("Ink Free", Font.BOLD, 72));
            FontMetrics metrics = getFontMetrics(g.getFont());
            String text = "Game Over";
            int textWidth = metrics.stringWidth(text);
            g.drawString(text, (getWidth() - textWidth) / 2, getHeight() / 2);
        }
        
    }
    
    public class ButtonListener implements ActionListener {
        
        private final int delay;
        
        private final SnakeGame view;
        
        private final SnakeModel model;
        
        private final Timer timer;

        public ButtonListener(SnakeGame view, SnakeModel model) {
            this.view = view;
            this.model = model;
            this.delay = 750;
            this.timer = new Timer(delay, new TimerListener(view, model));
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            JButton button = (JButton) event.getSource();
            String text = button.getText();
            
            if (text.equals("Start Game")) {
                button.setText("Restart Game");
            } 
            
            button.setEnabled(false);
            model.initialize();
            timer.restart();
        }
        
    }
    
    public class TimerListener implements ActionListener {
        
        private final SnakeGame view;
        
        private final SnakeModel model;

        public TimerListener(SnakeGame view, SnakeModel model) {
            this.view = view;
            this.model = model;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            moveSnake();
            checkApple();
            model.checkCollisions();
            if (model.isGameOver()) {
                Timer timer = (Timer) event.getSource();
                timer.stop();
                model.setRunning(false);
                view.getRestartButton().setEnabled(true);
            }
            view.repaint();
        }
        
        private void moveSnake() {
            Snake snake = model.getSnake();
            Point head = (Point) snake.getHead().clone();
            
            switch (snake.getDirection()) {
            case 'U':
                head.y--;
                break;
            case 'D':
                head.y++;
                break;
            case 'L':
                head.x--;
                break;
            case 'R':
                head.x++;
                break;
            }
            
            snake.removeTail();
            snake.addHead(head);
            
//          System.out.println(Arrays.toString(cells.toArray()));
        }
        
        private void checkApple() {
            Point appleLocation = model.getAppleLocation();
            Snake snake = model.getSnake();
            Point head = snake.getHead();
            Point tail = (Point) snake.getTail().clone();
            
            if (head.x == appleLocation.x && head.y == appleLocation.y) {
                model.incrementApplesEaten();
                snake.addTail(tail);
                model.generateRandomAppleLocation();
            }
        }
        
    }
    
    public class MovementAction extends AbstractAction {

        private static final long serialVersionUID = 1L;
        
        private final char newDirection, oppositeDirection;
        
        private final SnakeModel model;

        public MovementAction(SnakeModel model, char newDirection,
                char oppositeDirection) {
            this.model = model;
            this.newDirection = newDirection;
            this.oppositeDirection = oppositeDirection;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            if (model.isRunning()) {
                Snake snake = model.getSnake();
                char direction = snake.getDirection();
                if (direction != oppositeDirection && direction != newDirection) {
                    snake.setDirection(newDirection);
//                  System.out.println("New direction: " + newDirection);
                }
            }
        }
        
    }
    
    public class SnakeModel {
        
        private boolean isGameOver, isRunning;
        
        private int applesEaten;
        
        private Dimension gameArea;
        
        private Point appleLocation;
        
        private Random random;
        
        private Snake snake;
        
        public SnakeModel() {
            this.random = new Random();
            this.snake = new Snake();
            this.gameArea = new Dimension(24, 24);
        }
        
        public void initialize() {
            this.isRunning = true;
            this.isGameOver = false;
            this.snake.initialize();
            this.applesEaten = 0;
            
            Point point = generateRandomAppleLocation();
            // Make sure first apple isn't under snake
            int y = (point.y == 0) ? 1 : point.y;
            this.appleLocation = new Point(point.x, y);
        }
        
        public void checkCollisions() {
            Point head = snake.getHead();
            
            // Check for snake going out of the game area
            if (head.x < 0 || head.x > gameArea.width) {
                isGameOver = true;
                return;
            }
            
            if (head.y < 0 || head.y > gameArea.height) {
                isGameOver = true;
                return;
            }
            
            // Check for snake touching itself
            List<Point> cells = snake.getCells();
            for (int index = 1; index < cells.size(); index++) {
                Point cell = cells.get(index);
                if (head.x == cell.x && head.y == cell.y) {
                    isGameOver = true;
                    return;
                }
            }
        }
        
        public Point generateRandomAppleLocation() {
            int x = random.nextInt(gameArea.width);
            int y = random.nextInt(gameArea.height);
            this.appleLocation = new Point(x, y);
            return getAppleLocation();
        }
        
        public void incrementApplesEaten() {
            this.applesEaten++;
        }
        
        public boolean isRunning() {
            return isRunning;
        }

        public void setRunning(boolean isRunning) {
            this.isRunning = isRunning;
        }

        public boolean isGameOver() {
            return isGameOver;
        }

        public void setGameOver(boolean isGameOver) {
            this.isGameOver = isGameOver;
        }

        public Dimension getGameArea() {
            return gameArea;
        }

        public int getApplesEaten() {
            return applesEaten;
        }

        public Point getAppleLocation() {
            return appleLocation;
        }

        public Snake getSnake() {
            return snake;
        }
        
    }
    
    public class Snake {
        
        private char direction;
        
        private List<Point> cells;
        
        public Snake() {
            this.cells = new ArrayList<>();
            initialize();
        }
        
        public void initialize() {
            this.direction = 'R';
            cells.clear();
            for (int x = 5; x >= 0; x--) {
                cells.add(new Point(x, 0));
            }
        }

        public void addHead(Point head) {
            cells.add(0, head);
        }
        
        public void addTail(Point tail) {
            cells.add(tail);
        }
        
        public void removeTail() {
            cells.remove(cells.size() - 1);
        }
        
        public Point getHead() {
            return cells.get(0);
        }
        
        public Point getTail() {
            return cells.get(cells.size() - 1);
        }

        public char getDirection() {
            return direction;
        }

        public void setDirection(char direction) {
            this.direction = direction;
        }

        public List<Point> getCells() {
            return cells;
        }
        
    }

}
 类似资料:
  • 编辑:解决了,多亏了Mgorgon。 我正在创建一个简单的游戏,它(目前)允许你用鼠标点击在当前位置的每个方向上移动一个点1步。然而,这只在板是正方形(你可以选择板的大小)时才起作用。板由带有图像和2D数组的按钮表示,以跟踪位置,其中“1”是点的位置,“0”是一个空闲空间。actionlistener中的Pos1和Pos2打印出所单击的按钮的位置。当游戏棋盘是正方形时,这很有效,但当我把棋盘改成矩

  • 我是python新手,我正在尝试跟随一个教程,使用PyGame创建一个类似蛇的游戏。由于某种原因,我的界限不起作用。这可能很简单,但我看不出有什么理由不起作用。我没有犯任何错误,蛇只是越过了界限,比赛没有结束。

  • 我正在为iOS开发一个贪吃蛇游戏:https://github.com/ScottBouloutian/Snake 我的目标是让AI以最佳方式完成蛇的游戏(让蛇填满棋盘)。 我正在使用IDA*找到一条从蛇当前位置到食物的路径。这是有效的。然而,该算法没有考虑到它将来可能需要获得更多食物的事实。因此,有时它倾向于把自己框起来。 也就是说,蛇在任何给定时间的目标都是找到食物,而它的目标应该是填满棋盘(

  • 帖子底部的实际问题! 首先,我想解释我的问题。 我正在写一个基本的蛇游戏,我让蛇自动移动。当您执行代码时,它会自动移动到窗口的右侧,就像预期的那样。然而,我不能按我想要的方式控制我的蛇,它根本不会改变方向。 为了避免混淆,是类的一个实例。 为了解释蛇的运动: 对象有一个属性,它是一个包含对象的数组列表。每个对象都有和属性。使用此ArrayList,蛇通过在画布的y轴和x轴上使用和属性在画布上绘制小

  • 我在Java中创建了一个小TicTacToe游戏,我想编写更有效的代码,我会制作一个for循环来创建9个按钮。 我现在面临的问题是如何测试按下哪个按钮以确定胜利者。我已经注释掉了我的旧测试代码,因为它不再工作。

  • 问题内容: 我正在使用LibGDX开发Android游戏。菜单屏幕上有4个按钮,但是这些按钮中的按钮不起作用。 如何激活LibGDX中的按钮? 问题答案: 您必须将按钮添加到舞台并调用