Java--GUI--贪吃蛇小游戏

该文章展示了如何用Java编程实现一个基于图形用户界面(GUI)的贪吃蛇小游戏。代码包括启动类、数据类和面板绘制类,涉及键盘监听、游戏逻辑和图形绘制。游戏具有计分系统、游戏状态判断以及动态调整蛇的移动速度等功能。
摘要由CSDN通过智能技术生成

Java–GUI–贪吃蛇小游戏

效果示例图

贪吃蛇小游戏

代码示例

启动类

package com.zy.gui.snakegame;

import javax.swing.*;

/**
 *description: 主启动类
 *@program: 基础语法
 *@author: zy
 *@create: 2023-03-02 22:21
 */
public class StartGame {

    public void init(){
        // 容器实例化,放置组件
        JFrame frame = new JFrame();

        // 加载游戏面板
        frame.add(new GamePanel());

        frame.setTitle("贪吃蛇小游戏");
        frame.setBounds(200,200,900,720);
        frame.setResizable(false);
        // 尽量放在最后设置
        frame.setVisible(true);
        // 关闭
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new StartGame().init();
    }
}

数据类

package com.zy.gui.snakegame;

import javax.swing.*;
import java.net.URL;

/**
 *description: 数据中心
 *@program: 基础语法
 *@author: zy
 *@create: 2023-03-02 22:44
 */
public class GameData {

    public static URL rightUrl = GameData.class.getResource("/snakeimg/right.png");
    public static ImageIcon rightIcon = new ImageIcon(rightUrl);

    public static URL leftUrl = GameData.class.getResource("/snakeimg/left.png");
    public static ImageIcon leftIcon = new ImageIcon(leftUrl);

    public static URL downUrl = GameData.class.getResource("/snakeimg/down.png");
    public static ImageIcon downIcon = new ImageIcon(downUrl);

    public static URL upUrl = GameData.class.getResource("/snakeimg/up.png");
    public static ImageIcon upIcon = new ImageIcon(upUrl);

    public static URL foodUrl = GameData.class.getResource("/snakeimg/food.png");
    public static ImageIcon foodIcon = new ImageIcon(foodUrl);

    public static URL bodyUrl = GameData.class.getResource("/snakeimg/body.png");
    public static ImageIcon bodyIcon = new ImageIcon(bodyUrl);
}

面板绘制类

package com.zy.gui.snakegame;

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.Calendar;
import java.util.Date;
import java.util.Random;

/**
 *description: 游戏面板
 *@program: 基础语法
 *@author: zy
 *@create: 2023-03-02 22:25
 */
public class GamePanel extends JPanel implements KeyListener, ActionListener {

    /*
        总结:
            1.定义数据
            2.绘制
            3.监听事件
                1.键盘事件
                2.动作事件
     */

    // 蛇的长度
    private int snakeLen;
    // 蛇的横纵坐标:25*25
    private int[] snakeX = new int[900];
    private int[] snakeY = new int[900];
    // 方向
    private String orientation;
    // 游戏当前状态:开始/停止
    private boolean startState;
    // 食物的坐标以及随机数刷新坐标
    private int foodX;
    private int foodY;
    private Random foodRandom = new Random();
    // 游戏失败状态
    private boolean overState;
    // 游戏通关状态
    private boolean passState;
    // 计分
    private int score;
    // 计时
    private long startTime;
    private long suspendTime;
    private long suspendSumTime;
    private long seconds;
    private String showTime;
    // 每增长三节,则蛇的移动速度减缓
    private int delay;
    // 定时器控制蛇的移动:100毫秒执行一次
    private Timer timer = new Timer(delay,this);

    public GamePanel(){
        initSnake();
        // 获取焦点
        setFocusable(true);
        // 获取键盘事件
        addKeyListener(this);
    }
    
    /**
     * @Description 蛇的初始化
     * @author zy
     * []
     * void
     * @date 2023-3-2 23:11
     */
    public void initSnake(){
        snakeLen = 3;
        orientation = "right";
        for (int i = 0; i < snakeLen; i++) {
            snakeX[i] = 100-i*25;
            snakeY[i] = 100;
        }
        // 游戏之初定时器就启动
        delay = 100;
        timer.setDelay(delay);
        timer.start();
        // 食物坐标初始化:34*24
        foodX = 25 + 25*foodRandom.nextInt(34);
        foodY = 75 + 25*foodRandom.nextInt(24);
        // 计分初始化
        score = 0;
        // 计时初始化
        startTime = 0L;
        suspendTime = 0L;
        suspendSumTime = 0L;
        seconds = 0L;
        showTime = "00:00:00:000";
    }

    /**
     * @Description 绘制面板
     * @author zy
     * [g]
     * void
     * @date 2023-3-2 22:26
     */
    @Override
    protected void paintComponent(Graphics g) {
        // 清屏
        super.paintComponent(g);
        // 绘制静态面板
        this.setBackground(Color.white);
        // 头部记分器
        g.drawRect(25,11,850,45);
        // 游戏框界面
        g.fillRect(25,75,850,600);
        // 绘制满分
        g.setColor(Color.green);
        g.setFont(new Font("宋体",Font.BOLD,16));
        g.drawString("5000分即可通关,加油哦!!!!!!",100,40);
        // 绘制时长
        g.setColor(Color.orange);
        g.setFont(new Font("宋体",Font.BOLD,16));
        g.drawString(showTime,500,40);
        // 绘制计分
        g.setColor(Color.red);
        g.setFont(new Font("微软雅黑",Font.BOLD,16));
        g.drawString("长度:"+snakeLen,750,30);
        g.drawString("分数:"+score,750,50);
        // 绘制食物
        GameData.foodIcon.paintIcon(this,g,foodX,foodY);
        // 初始化蛇
        for (int i = 0; i < snakeLen; i++) {
            if(i == 0){
                // 头部,判断方向设置不同的头部
                switch (orientation){
                    case "right":
                        GameData.rightIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
                        break;
                    case "left":
                        GameData.leftIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
                        break;
                    case "down":
                        GameData.downIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
                        break;
                    case "up":
                        GameData.upIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
                        break;
                }
            }else{
                // 身体
                GameData.bodyIcon.paintIcon(this,g,snakeX[i],snakeY[i]);
            }
        }
        // 游戏状态
        if(!startState){
            // 设置游戏提示
            g.setColor(Color.white);
            g.setFont(new Font("宋体",Font.BOLD,40));
            g.drawString("按下空格开始游戏",300,300);
        }
        // 游戏失败
        if(overState){
            // 设置游戏提示
            g.setColor(Color.orange);
            g.setFont(new Font("宋体",Font.BOLD,40));
            g.drawString("游戏失败,按下空格重新开始",200,300);
        }
        // 游戏通关
        if(passState){
            // 设置游戏提示
            g.setColor(Color.green);
            g.setFont(new Font("宋体",Font.BOLD,40));
            g.drawString("游戏通关,按下空格重新开始",200,300);
        }
        g.setColor(Color.black);
    }

    /**
     * @Description 键盘监听
     * @author zy
     * [e]
     * void
     * @date 2023-3-3 21:19
     */
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        // 开始/停止游戏
        if(keyCode == KeyEvent.VK_SPACE){
            // 游戏失败,重新开始
            if(overState){
                overState = false;
                initSnake();
            }else if(passState){
                passState = false;
                initSnake();
            }else{
                startState = !startState;
                repaint();
            }
        }
        // 开始状态设置蛇的方向
        if(startState && !overState && !passState){
            switch (keyCode){
                case KeyEvent.VK_UP:
                    orientation = "up";
                    repaint();
                    break;
                case KeyEvent.VK_DOWN:
                    orientation = "down";
                    repaint();
                    break;
                case KeyEvent.VK_LEFT:
                    orientation = "left";
                    repaint();
                    break;
                case KeyEvent.VK_RIGHT:
                    orientation = "right";
                    repaint();
                    break;
            }
        }
    }

    /**
     * @Description 蛇的移动
     * 事件监听--定时器
     * @author zy
     * [e]
     * void
     * @date 2023-3-3 21:39
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        // 开始状态设置蛇的移动
        if(startState && !overState && !passState){
            if(startTime == 0){
                startTime = System.currentTimeMillis();
            }
            // 计时
            seconds = System.currentTimeMillis() - startTime - suspendSumTime;
            showTime = format(seconds);

            // 计分:吃食物
            if(snakeX[0] == foodX && snakeY[0] == foodY){
                // 蛇的长度+1
                snakeLen++;
                // 分数+10
                score += 10;
                // 刷新食物
                foodX = 25 + 25*foodRandom.nextInt(34);
                foodY = 75 + 25*foodRandom.nextInt(24);
                // 判断蛇的移动速度是否减缓
                if(snakeLen%10 == 0){
                    delay += 50;
                    // 定时器开启
                    timer.setDelay(delay);
                }
                // 判断是否通关
                if(snakeLen>=500){
                    passState = true;
                }
            }

            // 身体移动
            for (int i = snakeLen - 1; i > 0; i--) {
                snakeX[i] = snakeX[i-1];
                snakeY[i] = snakeY[i-1];
            }
            // 头部控制方向移动
            switch (orientation){
                case "right":
                    snakeX[0] += 25;
                    // 边界判断
                    if(snakeX[0]>850){
                        snakeX[0] = 25;
                    }
                    break;
                case "left":
                    snakeX[0] -= 25;
                    // 边界判断
                    if(snakeX[0]<25){
                        snakeX[0] = 850;
                    }
                    break;
                case "down":
                    snakeY[0] += 25;
                    // 边界判断
                    if(snakeY[0]>650){
                        snakeY[0] = 75;
                    }
                    break;
                case "up":
                    snakeY[0] -= 25;
                    // 边界判断
                    if(snakeY[0]<75){
                        snakeY[0] = 650;
                    }
                    break;
            }
            // 失败判断
            for (int i = 1; i < snakeLen; i++) {
                if(snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){
                    overState = true;
                }
            }
            // 重画页面
            repaint();
        }else if(!startState && seconds>0){
            // 暂停时长计算
            suspendTime = System.currentTimeMillis();
            suspendSumTime += (System.currentTimeMillis() - suspendTime);
        }
        // 定时器开启
        timer.start();
    }


    @Override
    public void keyReleased(KeyEvent e) {}
    @Override
    public void keyTyped(KeyEvent e) {}

    private String format(long timekeeping){
        int hour,minute,second,milli;
        milli = (int) (timekeeping%1000);
        timekeeping /= 1000;
        second = (int) (timekeeping%60);
        timekeeping /= 60;
        minute = (int) (timekeeping%60);
        timekeeping /= 60;
        hour = (int) (timekeeping%60);
        return String.format("%02d:%02d:%02d:%03d",hour,minute,second,milli);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值