Java贪吃蛇小游戏

Java贪吃蛇小游戏

在这里插入图片描述

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

public class SnakeGame extends JFrame implements ActionListener, KeyListener {
    private static final long serialVersionUID = 1L;

    // 游戏区域的格子数和每个格子的大小
    private static final int GRID_SIZE = 20;
    private static final int CELL_SIZE = 20;

    // 蛇的坐标集合,食物的坐标,蛇的移动方向,计时器
    private LinkedList<Point> snake;
    private Point food;
    private char direction;
    private Timer timer;

    // 游戏窗口的构造函数
    public SnakeGame() {
        setTitle("Snake Game");  // 设置窗口标题
        setSize(GRID_SIZE * CELL_SIZE, GRID_SIZE * CELL_SIZE);  // 设置窗口大小
        setResizable(false);  // 设置窗口不可调整大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // 设置默认关闭操作
        setLocationRelativeTo(null);  // 设置窗口居中显示

        // 初始化蛇的起始位置,方向为向右
        snake = new LinkedList<>();
        snake.add(new Point(GRID_SIZE / 2, GRID_SIZE / 2));
        direction = 'R';

        // 生成初始食物
        spawnFood();

        // 设置计时器,用于触发蛇的移动
        timer = new Timer(100, this);
        timer.start();

        // 添加键盘事件监听器
        addKeyListener(this);
        setFocusable(true);
    }

    // 生成食物的方法
    public void spawnFood() {
        Random rand = new Random();
        int x = rand.nextInt(GRID_SIZE);
        int y = rand.nextInt(GRID_SIZE);

        food = new Point(x, y);

        // 确保食物不会生成在蛇的身体上
        while (snake.contains(food)) {
            x = rand.nextInt(GRID_SIZE);
            y = rand.nextInt(GRID_SIZE);
            food.setLocation(x, y);
        }
    }

    // 移动蛇的方法
    public void move() {
        Point head = snake.getFirst();
        Point newHead = new Point(head);

        switch (direction) {
            case 'U':
                newHead.translate(0, -1);
                break;
            case 'D':
                newHead.translate(0, 1);
                break;
            case 'L':
                newHead.translate(-1, 0);
                break;
            case 'R':
                newHead.translate(1, 0);
                break;
        }

        // 检查碰撞
        if (newHead.equals(food)) {
            snake.addFirst(food);
            spawnFood();
        } else {
            snake.addFirst(newHead);
            // 如果蛇没吃到食物,则移除尾部,否则保持尾部
            snake.removeLast();
        }

        // 检查蛇是否撞到自己
        if (snake.size() > 1 && snake.subList(1, snake.size()).contains(newHead)) {
            gameOver();
        }

        // 检查蛇是否撞到墙壁
        if (newHead.x < 0 || newHead.x >= GRID_SIZE || newHead.y < 0 || newHead.y >= GRID_SIZE) {
            gameOver();
        }
    }

    // 游戏结束的方法
    public void gameOver() {
        timer.stop();
        JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.INFORMATION_MESSAGE);
        System.exit(0);
    }

    // 画图的方法,用于绘制蛇、食物和网格
    public void paint(Graphics g) {
        super.paint(g);

        // 绘制蛇
        g.setColor(Color.GREEN);
        for (Point point : snake) {
            g.fillRect(point.x * CELL_SIZE, point.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
        }

        // 绘制食物
        g.setColor(Color.RED);
        g.fillRect(food.x * CELL_SIZE, food.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);

        // 绘制网格线
        g.setColor(Color.BLACK);
        for (int i = 0; i < GRID_SIZE; i++) {
            g.drawLine(i * CELL_SIZE, 0, i * CELL_SIZE, GRID_SIZE * CELL_SIZE);
            g.drawLine(0, i * CELL_SIZE, GRID_SIZE * CELL_SIZE, i * CELL_SIZE);
        }
    }

    // 主函数,创建SnakeGame对象并显示窗口
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SnakeGame game = new SnakeGame();
            game.setVisible(true);
        });
    }

    // 计时器触发的事件处理
    @Override
    public void actionPerformed(ActionEvent e) {
        move();
        repaint();
    }

    // 键盘按下事件处理
    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_UP:
                if (direction != 'D') direction = 'U';
                break;
            case KeyEvent.VK_DOWN:
                if (direction != 'U') direction = 'D';
                break;
            case KeyEvent.VK_LEFT:
                if (direction != 'R') direction = 'L';
                break;
            case KeyEvent.VK_RIGHT:
                if (direction != 'L') direction = 'R';
                break;
        }
    }

    // 未使用的键盘事件处理方法
    @Override
    public void keyTyped(KeyEvent e) {
    }

    // 未使用的键盘事件处理方法
    @Override
    public void keyReleased(KeyEvent e) {
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值