基于 Java Swing MVC 的贪吃蛇游戏。问题切换难度

标签 java swing model-view-controller

我正在使用 MVC 模式在 Java Swing 中编写蛇游戏。

ControllerView的代码如下所示。我正在尝试实现一个按钮来帮助玩家选择难度级别。

难度级别由Controller 类中的计时器控制。我是 Java 初学者,感谢帮助。

Controller类的代码:

public class Controller implements KeyListener, ActionListener{
private Renderer renderer;
private Timer mainTimer;
private Snake snake;

public Controller() {
    snake = new Snake();
    renderer = new Renderer(this);

    this.renderer.addKeyListener(this);
    this.mainTimer = new Timer(150, this);

    mainTimer.start();
}

public void stopGame(){
    mainTimer.stop();
}

public void startGame(){
    mainTimer.start();
}


public void keyPressed(KeyEvent e) {
    snake.onMove(e.getKeyCode());
}

public void keyReleased(KeyEvent e) {
}

public void keyTyped(KeyEvent e) {
}
public void actionPerformed(ActionEvent arg0) {
    renderer.moveForward();
}

public Snake getSnake(){
    return snake;
}

查看类:

class Renderer extends JFrame {
private final int WIDTH = 500;
private final int HEIGHT = 300;
private Snake snake;

public int LevelConst;

private Controller controller;
public JPanel pamel1, panel2;
public JButton[] ButtonBody = new JButton[200];
public JButton bonusfood;
public JTextArea textArea;
public Fruit fruit;
public int score;
public Random random = new Random();
public JMenuBar mybar;
public JMenu game, help, levels;

public void initializeValues() {
    score = 0;
}

Renderer(Controller controller) {
    super("Snake: Demo");
    this.controller = controller;
    snake = controller.getSnake();

    fruit = new Fruit();
    setBounds(200, 200, 506, 380);
    creatbar();
    initializeValues();
    // GUI 
    pamel1 = new JPanel();
    panel2 = new JPanel();
    // Scoreboard
    setResizable(false);
    textArea = new JTextArea("Счет : " + score);
    textArea.setEnabled(false);
    textArea.setBounds(400, 400, 100, 100);
    textArea.setBackground(Color.GRAY);
    // Eating and growing up
    bonusfood = new JButton();
    bonusfood.setEnabled(false);
    //
    createFirstSnake();

    pamel1.setLayout(null);
    panel2.setLayout(new GridLayout(0, 1));
    pamel1.setBounds(0, 0, WIDTH, HEIGHT);
    pamel1.setBackground(Color.GRAY);
    panel2.setBounds(0, HEIGHT, WIDTH, 30);
    panel2.setBackground(Color.black);

    panel2.add(textArea); // will contain score board
    // end of UI design
    getContentPane().setLayout(null);
    getContentPane().add(pamel1);
    getContentPane().add(panel2);
    show();
    setDefaultCloseOperation(EXIT_ON_CLOSE);

}


public void createFirstSnake() {

    for (int i = 0; i < 3; i++) {
        ButtonBody[i] = new JButton(" " + i);
        ButtonBody[i].setEnabled(false);
        pamel1.add(ButtonBody[i]);
        ButtonBody[i].setBounds(snake.x[i], snake.y[i], 10, 10);
        snake.x[i + 1] = snake.x[i] - 10;
        snake.y[i + 1] = snake.y[i];
    }
}

// Creating of menu bar
public void creatbar() {
    mybar = new JMenuBar();

    game = new JMenu("Game");
    JMenuItem newgame = new JMenuItem("New Game");
    JMenuItem exit = new JMenuItem("Exit");
    newgame.addActionListener(e -> reset());

    exit.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    });

    game.add(newgame);
    game.addSeparator();
    game.add(exit);

    mybar.add(game);
    levels = new JMenu("Level");
    JMenuItem easy = new JMenuItem("Easy");
    easy.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            LevelConst = 0;

        }
    });

    JMenuItem middle = new JMenuItem("Medium");
    middle.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            LevelConst = 1;

        }
    });
    JMenuItem hard = new JMenuItem("Hard");
    hard.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            LevelConst = 2;

        }
    });
    levels.add(easy);
    levels.addSeparator();
    levels.add(middle);
    levels.addSeparator();
    levels.add(hard);
    mybar.add(levels);
    help = new JMenu("Help");

    JMenuItem creator = new JMenuItem("There must be a button");

    creator.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(pamel1, "Random text");

        }
    });

    help.add(creator);
    mybar.add(help);

    setJMenuBar(mybar);
}


void reset() {
    initializeValues();
    pamel1.removeAll();

    controller.stopGame();

    createFirstSnake();
    textArea.setText("Score: " + score);

    controller.startGame();
}


void growup() {
    ButtonBody[snake.getLength()] = new JButton(" " + snake.getLength());
    ButtonBody[snake.getLength()].setEnabled(false);
    pamel1.add(ButtonBody[snake.getLength()]);
    ButtonBody[snake.getLength()].setBounds(snake.getPointBody()[snake.getLength() - 1].x, snake.getPointBody()[snake.getLength() - 1].y, 10, 10);
    snake.setLength(snake.getLength() + 1);
}

void moveForward() {
    for (int i = 0; i < snake.getLength(); i++) {
        snake.getPointBody()[i] = ButtonBody[i].getLocation();
    }

    snake.x[0] += snake.getDirectionX();
    snake.y[0] += snake.getDirectionY();
    ButtonBody[0].setBounds(snake.x[0], snake.y[0], 10, 10);

    for (int i = 1; i < snake.getLength(); i++) {
        ButtonBody[i].setLocation(snake.getPointBody()[i - 1]);
    }

    if (snake.x[0] == WIDTH) {
        controller.stopGame();
    } else if (snake.x[0] == 0) {
        controller.stopGame();
    } else if (snake.y[0] == HEIGHT) {
        controller.stopGame();
    } else if (snake.y[0] == 0) {
        controller.stopGame();
    }

    createFruit();

    collisionFruit();
    pamel1.repaint();

}

private void collisionFruit() {
    if (fruit.isFood()) {
        if (fruit.getPoint().x == snake.x[0] && fruit.getPoint().y == snake.y[0]) {
            pamel1.remove(bonusfood);
            score += 1;
            growup();
            textArea.setText("Score: " + score);
            fruit.setFood(false);

        }
    }
}

private void createFruit() {
    if (!fruit.isFood()) {
        pamel1.add(bonusfood);
        bonusfood.setBounds((10 * random.nextInt(50)), (10 * random.nextInt(25)), 10,
                10);
        fruit.setPoint(bonusfood.getLocation());
        fruit.setFood(true);
    }
}

类模型:水果:

public class Fruit {
private Point point;
private boolean food;
public Fruit() {
    point = new Point();
}

public Point getPoint() {
    return point;
}
public void setPoint(Point point) {
    this.point = point;
}

public boolean isFood() {
    return food;
}

public void setFood(boolean food) {
    this.food = food;
}

类模型:Snake:

public class Snake {
  private Point[] pointBody = new Point[300];
  private int length;

  private boolean isLeft;
  private boolean isRight;
  private boolean isUp;
  private boolean isDown;

  private int directionX;
  private int directionY;

  public int[] x = new int[300];
  public int[] y = new int[300];

  public Snake() {
    isLeft = false;
    isRight = true;
    isUp = true;
    isDown = true;
    setDirectionX(10);
    setDirectionY(0);
    length = 3;
    y[0] = 100;
    x[0] = 150;
}

public void onMove(int side) {
    switch (side) {
        case KeyEvent.VK_LEFT:
            if (isLeft) {
                setDirectionX(-10);
                setDirectionY(0);
                isRight = false;
                isUp = true;
                isDown = true;
            }
            break;
        case KeyEvent.VK_UP:
            if (isUp) {
                setDirectionX(0);
                setDirectionY(-10);
                isDown = false;
                isRight = true;
                isLeft = true;
            }
            break;
        case KeyEvent.VK_DOWN:
            if (isDown) {
                setDirectionX(0);
                setDirectionY(+10);
                isUp = false;
                isRight = true;
                isLeft = true;
            }
            break;
        case KeyEvent.VK_RIGHT:
            if (isRight) {
                setDirectionX(+10);
                setDirectionY(0);
                isLeft = false;
                isUp = true;
                isDown = true;
            }
            break;

        default:
            break;
    }
}

public int getLength() {
    return length;
}

public void setLength(int length) {
    this.length = length;
}

public Point[] getPointBody() {
    return pointBody;
}

public void setPointBody(Point[] pointBody) {
    this.pointBody = pointBody;
}

public int getDirectionX() {
    return directionX;
}

public void setDirectionX(int directionX) {
    this.directionX = directionX;
}

public int getDirectionY() {
    return directionY;
}

public void setDirectionY(int directionY) {
    this.directionY = directionY;
}

主要:

public class Main {
  public static void main(String[] args) {
    new Controller();
  }
}

最佳答案

在 Controller 中创建属性更改监听器:

public PropertyChangeListener getViewListener() {
    return new ViewListener();
}

private class ViewListener implements PropertyChangeListener {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {

        System.out.println("Level is "+ evt.getNewValue());
        //use level 
    }
}

通过以下方式调用createbar:creatbar(controller.getViewListener());
并使用监听器:

public void creatbar(PropertyChangeListener listener) {
    mybar = new JMenuBar();
    mybar.addPropertyChangeListener(listener);//add listener to menu bar

    game = new JMenu("Game");
    JMenuItem newgame = new JMenuItem("New Game");
    JMenuItem exit = new JMenuItem("Exit");
    newgame.addActionListener(e -> reset());

    exit.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    });

    game.add(newgame);
    game.addSeparator();
    game.add(exit);

    mybar.add(game);
    levels = new JMenu("Level");
    JMenuItem easy = new JMenuItem("Easy");
    easy.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            mybar.firePropertyChange("Level", LevelConst, 0); //use listener 
            LevelConst = 0;   
        }
    });

    JMenuItem middle = new JMenuItem("Medium");
    middle.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            mybar.firePropertyChange("Level", LevelConst, 1);
            LevelConst = 1;
        }
    });
    JMenuItem hard = new JMenuItem("Hard");
    hard.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            mybar.firePropertyChange("Level", LevelConst, 2);
            LevelConst = 2;
        }
    });
    levels.add(easy);
    levels.addSeparator();
    levels.add(middle);
    levels.addSeparator();
    levels.add(hard);
    mybar.add(levels);
    help = new JMenu("Help");

    JMenuItem creator = new JMenuItem("There must be a button");

    creator.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(pamel1, "Random text");

        }
    });

    help.add(creator);
    mybar.add(help);

    setJMenuBar(mybar);
}

关于基于 Java Swing MVC 的贪吃蛇游戏。问题切换难度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44465859/

相关文章:

php - Zend_Framework- 在哪里放置 $_GET 和 $_POST(HTTP 请求)处理?

ruby-on-rails - rails 4 : how to check if an instance has been deleted

加载另一个部分后,Javascript 函数仍然保留

java - 软件实践 - 可以使用输出参数使方法多态吗

java - Hibernate 使用 hbm2ddl.auto=update 保留一些表,使用 hbm2ddl.auto=create 重新加载一些表

java - 版权符号怎么写?

java - hibernate - SQLGrammarException : could not extract ResultSet on Persist

java - 如何获取字体的行高,例如在 JTextArea 中?

python - 结合 Tkinter (Python) 和 Swing (Jython)

java - JTabbedPane的选项卡区域添加按钮,可以显示,但无法点击