snake_贪吃蛇.java

本文介绍了一个基于Java实现的贪吃蛇游戏源代码。游戏中包括地图绘制、蛇的移动逻辑、食物生成及碰撞检测等功能。通过键盘控制蛇的方向,实现吃食物增长身体的基本玩法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

snake.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import simpleFrame.FrameUtil;
import simpleFrame.MyFrame;

public class SnakeView extends JPanel {

    // 地图的宽和高
    public static final int WIDTH = 40;
    public static final int HEIGHT = 30;

    // 格子的宽和高
    public static final int CELLWIDTH = 20;
    public static final int CELLHEIGHT = 20;

    // 使用四个常量表示四个方向
    public static final int UP_DIRECTION = 1; // 上
    public static final int DOWN_DIRECTION = -1; // 下
    public static final int LEFT_DIRECTION = 2; // 左
    public static final int RIGHT_DIRECTION = -2; // 右

    // 蛇当前的方向
    int currentDrection = -2; // 蛇默认向右行走

    // 记录游戏是否结束
    static boolean isGameOver = false; // 默认游戏没有结束

    // 包含蛇所有节点的信息
    LinkedList<Point> snake = new LinkedList<Point>();

    // 食物
    Point food;

    // 地图
    public char[][] background = new char[HEIGHT][WIDTH];

    // 改变当前方向
    public void changeDirection(int newDirection) {
        // 判断新方向与当前方向是否是相反方向
        if (newDirection + currentDrection != 0) {
            this.currentDrection = newDirection;
        }

    }

    // 蛇移动的方法
    public void move() {
        Point head = snake.getFirst();
        // 蛇是根据当前方向移动的
        switch (currentDrection) {
        case UP_DIRECTION:
            snake.addFirst(new Point(head.x, head.y - 1));
            break;
        case DOWN_DIRECTION:
            snake.addFirst(new Point(head.x, head.y + 1));
            break;
        case LEFT_DIRECTION:
            if (head.x == 0) {
                snake.addFirst(new Point(WIDTH - 1, head.y));
            } else {
                snake.addFirst(new Point(head.x - 1, head.y));
            }
            break;
        case RIGHT_DIRECTION:
            if (head.x == WIDTH - 1) {
                snake.addFirst(new Point(0, head.y));
            } else {
                snake.addFirst(new Point(head.x + 1, head.y));
            }
            break;
        default:
            break;
        }
        if (eatFood()) {
            // 吃到了食物
            createFood();
        } else {
            // 删除蛇尾
            snake.removeLast();
        }

    }

    // 初始化地图
    public void initBackground() {
        for (int rows = 0; rows < background.length; rows++) {
            for (int cols = 0; cols < background[rows].length; cols++) {
                if (rows == 0 || rows == HEIGHT - 1 || cols == 0
                        || cols == WIDTH - 1) {
                    background[rows][cols] = '*'; // 打印墙体
                } else {
                    background[rows][cols] = ' '; // 打印空白
                }
            }
        }
    }

    // 初始化蛇
    public void initSnake() { // 初始化蛇在地图的中间位置
        int x = WIDTH / 2;
        int y = HEIGHT / 2;
        snake.addFirst(new Point(x - 1, y));
        snake.addFirst(new Point(x, y));
        snake.addFirst(new Point(x + 1, y));
    }

    // 生成食物
    public void createFood() {
        // 创建一个随机数对象
        Random random = new Random();
        while (true) {
            int x = random.nextInt(WIDTH); // 0~width-3
            int y = random.nextInt(HEIGHT);

            if (background[y][x] != '*') {
                food = new Point(x, y);
                break;
            }

        }
    }

    // 吃食物
    public boolean eatFood() {
        // 获取蛇头
        Point head = snake.getFirst();
        if (head.equals(food)) {
            return true;
        }
        return false;
    }

    @Override
    public void paint(Graphics g) {

        // 画地图
        for (int rows = 0; rows < background.length; rows++) {
            for (int cols = 0; cols < background[rows].length; cols++) {
                if (background[rows][cols] == '*') {
                    // 石头
                    g.setColor(Color.GRAY);
                } else {
                    // 地图
                    g.setColor(Color.white);
                }
                g.fill3DRect(cols * CELLWIDTH, rows * CELLHEIGHT, CELLWIDTH,
                        CELLHEIGHT, true);
            }
        }

        // 画蛇
        // 画出蛇头
        Point head = snake.getFirst();
        g.setColor(Color.red);
        g.fill3DRect(head.x * CELLWIDTH, head.y * CELLHEIGHT, CELLWIDTH,
                CELLHEIGHT, true);
        // 蛇身
        for (int i = 1; i < snake.size(); i++) {
            Point body = snake.get(i);
            g.setColor(Color.green);
            g.fill3DRect(body.x * CELLWIDTH, body.y * CELLHEIGHT, CELLWIDTH,
                    CELLHEIGHT, true);
        }

        // 显示食物
        background[food.y][food.x] = '@';
        if (background[food.y][food.x] == '@') {
            g.setColor(Color.BLUE);
            g.fill3DRect(food.x * CELLWIDTH, food.y * CELLHEIGHT, CELLWIDTH,
                    CELLHEIGHT, true);
        }
    }

    // 游戏结束的方法
    public void isGameOver() {
        // 撞墙结束
        Point head = snake.getFirst();
        if (background[head.y][head.x] == '*') {
            isGameOver = true;
        }

        // 咬到自己
        for (int i = 1; i < snake.size(); i++) {
            Point body = snake.get(i);
            if (head.equals(body)) {
                isGameOver = true;
            }
        }

    }

    //游戏运行
    public void Start() {
        JFrame frame = new JFrame("贪吃蛇      @羊羊羊");
        JFrame frame2 = new JFrame("游戏结束");
        SnakeView snakeView = new SnakeView();
        frame.setResizable(false);
        snakeView.initBackground();
        snakeView.initSnake();
        snakeView.createFood();
        frame.add(snakeView);

        FrameUtil.initFrame(frame, WIDTH * CELLWIDTH + 10, HEIGHT * CELLHEIGHT
                + 35);

        // 给窗口添加事件监听器
        frame.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                int code = e.getKeyCode();
                switch (code) {
                case KeyEvent.VK_UP:
                    snakeView.changeDirection(UP_DIRECTION);
                    break;
                case KeyEvent.VK_DOWN:
                    snakeView.changeDirection(DOWN_DIRECTION);
                    snakeView.repaint();
                    break;
                case KeyEvent.VK_LEFT:
                    snakeView.changeDirection(LEFT_DIRECTION);
                    snakeView.repaint();
                    break;
                case KeyEvent.VK_RIGHT:
                    snakeView.changeDirection(RIGHT_DIRECTION);
                    snakeView.repaint();
                    break;
                default:
                    break;
                }
                snakeView.move();
                snakeView.isGameOver(); // 判断游戏是否结束
                // 刷新游戏
                snakeView.repaint(); // 实际上就是调用paint的方法
                if (isGameOver) {
                    /*
                     * System.out.println("游戏结束"); System.exit(0);
                     */
                    MyFrame.init(frame2, 300, 200);
                }
                snakeView.repaint();
            }
        });
    }

    //游戏退出
    public void Exit(){
        System.exit(0);
    }

    public static void main(String[] args) {
        SnakeView snakeView = new SnakeView();
        snakeView.Start();
    }
}



FrameUtil.java

import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;

//初始化窗口的工具类
public class FrameUtil {

    public static void initFrame(JFrame frame,int width,int height){
        Toolkit toolkit=Toolkit.getDefaultToolkit();  //获取一个与系统相关的工具类对象
        //返回屏幕的尺寸
        Dimension d=toolkit.getScreenSize();
        int x=(int)d.getWidth();
        int y=(int)d.getHeight();
        frame.setBounds((x-width)/2, (y-height)/2, width, height);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值