java的结课项目--贪吃蛇

9a2cfe0bf4ec4198bd1639d865d4afca.gifcbfffd5d4ae74ff4bca5d98a291dd008.gif

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; 
import java.util.Random; 

public class SnakeGame extends JPanel implements ActionListener { // 定义SnakeGame类,继承自JPanel并实现ActionListener接口
    static final int SCREEN_WIDTH =1000; // 定义屏幕宽度常量
    static final int SCREEN_HEIGHT = 1000; // 定义屏幕高度常量
    static final int UNIT_SIZE = 25; // 定义每个游戏单位的大小
    static final int GAME_UNITS = (SCREEN_WIDTH * SCREEN_HEIGHT) / UNIT_SIZE; // 计算游戏单位总数
    static final int DELAY = 200; // 定义游戏更新的延迟时间,单位为毫秒
    final int[] x = new int[GAME_UNITS]; // 创建一个数组,用于存储蛇的x坐标
    final int[] y = new int[GAME_UNITS]; // 创建一个数组,用于存储蛇的y坐标
    int bodyParts = 6; // 初始化蛇的身体部分数量
    int applesEaten; // 初始化吃掉的苹果数量
    int appleX; // 定义苹果的x坐标
    int appleY; // 定义苹果的y坐标
    char direction = 'R'; // 初始化蛇的移动方向为向右('R'代表Right)
    boolean running = false; // 初始化游戏状态为非运行状态
    Timer timer; // 定义一个Timer对象,用于控制游戏更新
    Random random; // 定义一个Random对象,用于生成随机数

    SnakeGame() { // 构造函数
        random = new Random(); // 初始化随机数生成器
        this.setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT)); // 设置面板的首选大小为屏幕大小
        this.setBackground(Color.white); // 设置面板的背景颜色为白色
        this.setFocusable(true); // 设置面板可以获得焦点
        this.addKeyListener(new MyKeyAdapter()); // 为面板添加键盘监听器
        startGame(); // 调用startGame方法开始游戏
    }

    public void actionPerformed1(ActionEvent e) { // 这个方法名是错误的,应该使用actionPerformed
        if (running) {
            move(); // 移动蛇
            checkApple(); // 检查蛇是否吃到苹果
            checkCollisions(); // 检查蛇是否发生碰撞
        }
        repaint(); // 重绘面板
    }

    public void startGame() { // 初始化游戏
        if (timer != null) {
            timer.stop(); // 停止之前的计时器
        }
        newApple(); // 生成新的苹果
        running = true; // 设置游戏状态为运行
        bodyParts = 6; // 重置蛇的身体部分数量
        direction = 'R'; // 重置蛇的初始方向为向右
        x[0] = SCREEN_WIDTH / 2; // 设置蛇头的初始x坐标
        y[0] = SCREEN_HEIGHT / 2; // 设置蛇头的初始y坐标
        for (int i = 1; i < bodyParts; i++) { // 初始化蛇的身体部分
            x[i] = x[0] - i * UNIT_SIZE; // 设置每个身体部分的x坐标
            y[i] = y[0]; // 设置每个身体部分的y坐标
        }
        applesEaten = 0; // 重置吃掉的苹果数量
        timer = new Timer(DELAY, this); // 创建新的计时器,并设置延迟时间和监听器
        timer.start(); // 启动计时器
    }

    public void paintComponent(Graphics g) { // 重写paintComponent方法,用于绘制游戏界面
        super.paintComponent(g); // 调用父类的paintComponent方法
        if (running) {
            draw(g); // 如果游戏正在运行,调用draw方法绘制游戏元素
        } else {
            gameOver(g); // 如果游戏结束,调用gameOver方法显示游戏结束信息
        }
    }

    public void draw(Graphics g) { // 绘制游戏元素
        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, SCREEN_WIDTH, i * UNIT_SIZE); // 绘制水平线
        }
        g.setColor(Color.red); 
        g.fillOval(appleX, appleY, UNIT_SIZE, UNIT_SIZE); // 绘制苹果

        for (int i = 0; i < bodyParts; i++) { // 绘制蛇的身体
            g.setColor((i == 0) ? Color.green : new Color(45, 180, 0)); // 设置蛇头和身体的颜色
            g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE); // 绘制蛇的身体部分
        }
        g.setColor(Color.red); // 设置画笔颜色为红色
        g.setFont(new Font("华文楷体", Font.BOLD, 40)); // 设置字体
        FontMetrics metrics = getFontMetrics(g.getFont()); // 获取字体度量
        g.drawString("得分: " + applesEaten, (SCREEN_WIDTH - metrics.stringWidth("得分: " + applesEaten)) / 2, g.getFont().getSize());
    }

    public void newApple() { // 生成新的苹果
        appleX = random.nextInt((int) (SCREEN_WIDTH / UNIT_SIZE)) * UNIT_SIZE; // 随机生成苹果的x坐标
        appleY = random.nextInt((int) (SCREEN_HEIGHT / UNIT_SIZE)) * UNIT_SIZE; // 随机生成苹果的y坐标
    }

    public void move() { // 移动蛇
        for (int i = bodyParts; i > 0; i--) { // 更新蛇的身体部分位置
            x[i] = x[i - 1]; // 将前一个身体部分的x坐标赋值给当前身体部分
            y[i] = y[i - 1]; // 将前一个身体部分的y坐标赋值给当前身体部分
        }
        switch (direction) { // 根据方向更新蛇头的位置
            case 'U':
                y[0] -= UNIT_SIZE; // 向上移动
                break;
            case 'D':
                y[0] += UNIT_SIZE; // 向下移动
                break;
            case 'L':
                x[0] -= UNIT_SIZE; // 向左移动
                break;
            case 'R':
                x[0] += UNIT_SIZE; // 向右移动
                break;
        }
    }

    public void checkApple() { // 检查蛇是否吃到苹果
        if (x[0] == appleX && y[0] == appleY) { // 如果蛇头的位置与苹果的位置相同
            bodyParts++; // 增加蛇的身体部分
            applesEaten++; // 增加吃掉的苹果数量
            newApple(); // 生成新的苹果
        }
    }

    public void checkCollisions() { // 检查蛇是否发生碰撞
        for (int i = bodyParts; i > 0; i--) { // 检查蛇是否撞到自己
            if (x[i] == x[0] && y[i] == y[0]) {
                running = false; // 如果撞到自己,游戏结束
                break;
            }
        }
        if (x[0] < 0 || x[0] >= SCREEN_WIDTH || y[0] < 0 || y[0] >= SCREEN_HEIGHT) { // 检查蛇是否撞到边界
            running = false; // 如果撞到边界,游戏结束
        }
    }

    public void gameOver(Graphics g) { // 显示游戏结束信息
        g.setColor(Color.red); // 设置画笔颜色为红色
        g.setFont(new Font("华文楷体", Font.BOLD, 75)); // 设置字体为华文楷体,加粗,字号为75
        FontMetrics metrics = getFontMetrics(g.getFont()); // 获取字体度量
        String gameOverText = "游戏结束"; // 中文游戏结束文本
        g.drawString(gameOverText, (SCREEN_WIDTH - metrics.stringWidth(gameOverText)) / 2, SCREEN_HEIGHT / 2); // 绘制“游戏结束”文本

        g.setFont(new Font("华文楷体", Font.BOLD, 60)); // 设置字体为华文楷体,加粗,字号为60
        String scoreText = "得分: " + applesEaten; // 中文得分文本
        g.drawString(scoreText, (SCREEN_WIDTH - metrics.stringWidth(scoreText)) / 2, SCREEN_HEIGHT / 2 + g.getFont().getSize()); // 绘制得分

        String restartText = "按空格键重新开始       ";
        g.drawString(restartText, SCREEN_WIDTH / 2 - 100, SCREEN_HEIGHT / 2 + g.getFont().getSize() * 2); // 绘制重启提示
    }
    @Override
    public void actionPerformed(ActionEvent e) { // 处理计时器触发的动作事件
        if (running) {
            move(); // 移动蛇
            checkApple(); // 检查蛇是否吃到苹果
            checkCollisions(); // 检查蛇是否发生碰撞
        }
        repaint(); // 重绘面板
    }

    public class MyKeyAdapter extends KeyAdapter { // 内部类,用于处理键盘事件
        @Override
        public void keyPressed(KeyEvent e) { // 重写keyPressed方法,处理按键事件
            if (!running) { // 如果游戏不在运行状态
                if (e.getKeyCode() == KeyEvent.VK_SPACE) { // 如果按下空格键
                    startGame(); // 重新开始游戏
                }
            } else { // 如果游戏正在运行
                int key = e.getKeyCode(); // 获取按下的键的代码
                if ((key == KeyEvent.VK_LEFT || key == KeyEvent.VK_RIGHT) && direction != ((key == KeyEvent.VK_LEFT) ? 'R' : 'L')) {
                    direction = (key == KeyEvent.VK_LEFT) ? 'L' : 'R'; // 改变方向为左或右
                } else if ((key == KeyEvent.VK_UP || key == KeyEvent.VK_DOWN) && direction != ((key == KeyEvent.VK_UP) ? 'D' : 'U')) {
                    direction = (key == KeyEvent.VK_UP) ? 'U' : 'D'; // 改变方向为上或下
                }
            }
        }
    }

    public static void main(String[] args) { // 程序的入口点
        JFrame frame = new JFrame(); // 创建一个JFrame窗口
        SnakeGame game = new SnakeGame(); // 创建SnakeGame实例
        frame.add(game); // 将SnakeGame实例添加到窗口中
        frame.setTitle("贪吃蛇"); // 设置窗口的标题
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗口关闭时的操作
        frame.setResizable(false); // 设置窗口不可调整大小
        frame.pack(); // 调整窗口大小以适应其内容
        frame.setVisible(true); // 设置窗口可见
        frame.setLocationRelativeTo(null); // 将窗口居中显示
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值