package com.snake;
import com.snake.constants.SnakeConstant;
import com.snake.domain.DirectionEnum;
import com.snake.domain.Node;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/**
* @author gjq
* @version 1.0
* @description: 窗体构建类
* @date 2026/5/30 10:15
*/
public class MainFrame extends JFrame {
// 初始化蛇的信息
private final Snake snake = new Snake();
//定义定时器
private Timer timer;
// 游戏棋盘
private JPanel panel;
//定义食物
private final Food food = new Food();
//创建窗体对象时,初始化船体参数
public MainFrame() {
// 构建窗体
initFrame();
// 构建网格
initGamePanel();
// 内容撑开高度和宽度
pack();
// 窗体居中显示
setLocationRelativeTo(null);
// 初始化定时器
initTimer();
// 初始化键盘监听
setKeyListener();
// 显示窗口
setVisible(true);
}
// 初始化窗体参数
private void initFrame() {
// 设置窗体标题
setTitle(SnakeConstant.FRAME_TITLE);
// 设置窗体大小不能改变
setResizable(false);
// 设置窗体关闭按钮的作用,是正常退出
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// 构建内容
private void initGamePanel() {
panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/* -------- 绘制网格 --------- */
g.setColor(Color.BLACK);
// 横线
for (int i = 0; i <= SnakeConstant.ROWS; i++) {
int y = i * SnakeConstant.GRID_SIZE;
g.drawLine(0, y,
SnakeConstant.getFrameWidth(), y);
}
// 竖线
for (int i = 0; i <= SnakeConstant.COLS; i++) {
int x = i * SnakeConstant.GRID_SIZE;
g.drawLine(x, 0,
x, SnakeConstant.getFrameHeight());
}
/* -------- 绘制蛇 --------- */
g.setColor(Color.BLACK);
for (Node node : snake.getBody()) {
g.fillRect(node.getX() * SnakeConstant.GRID_SIZE,
node.getY() * SnakeConstant.GRID_SIZE,
SnakeConstant.GRID_SIZE,
SnakeConstant.GRID_SIZE);
}
/* -------- 绘制食物 --------- */
g.setColor(Color.RED);
g.fillRect(food.getX() * SnakeConstant.GRID_SIZE,
food.getY() * SnakeConstant.GRID_SIZE,
SnakeConstant.GRID_SIZE,
SnakeConstant.GRID_SIZE);
}
};
panel.setPreferredSize(new Dimension(
SnakeConstant.getFrameWidth(),
SnakeConstant.getFrameHeight()
));
// 添加到窗体中
add(panel);
}
//添加键盘监听
private void setKeyListener() {
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
// 获取选择的值
DirectionEnum newDirection = switch (e.getKeyCode()) {
case KeyEvent.VK_UP -> DirectionEnum.UP;
case KeyEvent.VK_DOWN -> DirectionEnum.DOWN;
case KeyEvent.VK_LEFT -> DirectionEnum.LEFT;
case KeyEvent.VK_RIGHT -> DirectionEnum.RIGHT;
default -> null;
};
// 调整方向
if (newDirection != null) {
snake.setDirection(newDirection);
}
}
});
}
// 初始化定时器
private void initTimer() {
timer = new Timer(100, e -> {
// 移动
boolean isLive = snake.move();
// 吃食物
snake.eatFood(food);
panel.repaint();
// 撞墙死亡
if (!isLive) {
((Timer) e.getSource()).stop();
JOptionPane.showMessageDialog(this, "游戏结束!蛇死亡了!");
}
});
timer.start();
}
public static void main(String[] args) {
// 创建窗体,并显示在屏幕上
new MainFrame();
}
}