我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java gui详解贪吃蛇小游戏实现流程

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

java gui详解贪吃蛇小游戏实现流程

根据狂神的视频做的,然后自己优化了一些bug,比如新生成食物的时候不会生成在蛇的身体上,再新增长身体的时候不会在左上角出现一个绿色的方块以及增加了难度控制功能,以及可以使用WASD进行控制,而不仅仅限于上下左右方向键
最后的游戏界面是这样的:

在这里插入图片描述

可以在上方的菜单栏里选择不同的难度进行游戏.难度对应的是不同的蛇移动的速度,点击退出游戏和点击右上角的X是一样的功能,都是退出游戏.然后点击重新开始就会回到最初的时候重新开始游戏.
按下空格开始游戏,随时可以再次按下空格进行暂停游戏.同时每吃到一个食物就会在右上角加10分.

在这里插入图片描述

游戏代码一共分成了三个类
一个是GameStart类,用来创建JFrame绘制游戏主体.
一个是GamePanel类,用来添加在JFrame中,里面加入了菜单栏以及一些键盘监听器,用来根据读入的信息操纵蛇移动.
另一个是Data类,用来读取statics文件夹中的图片素材,代码更简洁.

在这里插入图片描述

GameStart类代码如下:(具体代码后面都有注释)


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class GameStart {
    public static void main(String[] args) {
        JFrame jframe = new JFrame("贪吃蛇");
        jframe.setBounds(10, 10, 900, 720);//绘制游戏主界面的范围
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setResizable(false);//不可扩大缩小窗口
        GamePanel gamePanel = new GamePanel();
        jframe.add(gamePanel);
        jframe.setVisible(true);//显形
        gamePanel.setLayout(new BorderLayout());
    }
}

GamePanel类代码是:


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.Random;



public class GamePanel extends JPanel implements ActionListener, KeyListener {
    int length;//蛇的长度
    int[] snakeX = new int[500];//随便定义长度,反之不出意外是不会超过的
    int[] snakeY = new int[500];
    String direction;//蛇的方向,来根据这个改变蛇头的图片
    Timer timer = new Timer(60, this);//计时器,来触发蛇移动的事件
    int score;//分数
    Boolean isFail = false;//是否失败判断
    Boolean isStart = false;//是否启动判断
    int foodX;//食物坐标
    int foodY;
    Random random = new Random();//用来产生随机数的Random类的实例化


    public void init(){
        length = 3;//一开始蛇的三节
        snakeX[0] = 100;//蛇头为下标0
        snakeY[0] = 100;
        snakeX[1] = 75;
        snakeY[1] = 100;
        snakeX[2] = 50;
        snakeY[2] = 100;
        direction = "R";//初始化方向朝右边
        score = 0;
        foodX = getFoodX();//通过方法获取食物的坐标
        foodY = getFoodY();
    }
    public GamePanel(){
        //构造函数
        init();//进行初始化
        this.setFocusable(true);//设置可以被赋予焦点
        this.setForeground(Color.pink);//设置为粉色
        this.addKeyListener(this);//添加键盘的监听
        timer.start();//开始计时器
        JMenuBar menuBar = new JMenuBar();//选项栏
        JButton jb1 = new JButton("退出游戏");
        JButton jb3 = new JButton("新手难度");
        JButton jb4 = new JButton("高手难度");
        JButton jb5 = new JButton("地狱难度");
        menuBar.add(jb1);
        menuBar.add(jb3);
        menuBar.add(jb4);
        menuBar.add(jb5);
        jb1.addActionListener(e -> {//添加jb1的监听
            System.exit(0);//退出
        });
        jb3.addActionListener(e -> {
            this.requestFocus();//不获取焦点后面操作键盘都会在菜单栏里,就无法操作蛇了
            timer.stop();//把原来的timer停止
            timer = new Timer(80, this);//使蛇的速度变慢
            timer.start();//重新开始timer
        });
        jb4.addActionListener(e -> {
            this.requestFocus();
            timer.stop();
            timer = new Timer(40, this);
            timer.start();
        });
        jb5.addActionListener(e -> {
            this.requestFocus();
            timer.stop();
            timer = new Timer(20, this);
            timer.start();
        });
        this.add(menuBar);
        JButton jb2 =  new JButton("重新开始");
        jb2.addActionListener(e -> {
            init();//重新开始所以重新初始化一下
            repaint();//重画
            this.requestFocus();
        });
        this.add(jb2);
    }
    public int getFoodX(){
        //如果没有判断的话会出现bug,也就是食物可能出现在蛇的身体里,所以要进行判断优化
        boolean flag = true;
        int x = 25 + 25 * random.nextInt(34);//因为一格为25,所以要乘一个25
        while(flag){
            for(int i = 0; i < length; i++){
                if(snakeX[i] == x) {
                    x = 25 + 25 * random.nextInt(34);//如果和身体重合就重新随机一个数
                }else{
                    flag = false;
                }
            }
        }
        return x;
    }
    public int getFoodY(){
        boolean flag = true;
        int y = 75 + 25 * random.nextInt(24);//24是计算出来的,总panel的大小除以25
        while(flag){
            for(int i = 0; i < length; i++){
                if(snakeY[i] == y) {
                    y = 75 + 25 * random.nextInt(34);
                }else{
                    flag = false;
                }
            }
        }
        return y;
    }
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponents(g);//这个不加可能会出问题
        this.setBackground(Color.white);
        g.fillRect(0,0,90,30);
        g.setColor(Color.black);
        g.drawString("贪吃蛇大挑战",10,20);

        g.setColor(Color.LIGHT_GRAY);//分数提示框
        g.fillRect( 25, 36, 850, 40);

        g.setColor(Color.pink);//游戏主界面
        g.fillRect(25,75, 850, 600);

        if ("R".equals(direction)) {//判断是什么蛇头朝向,选择不同的蛇头图片
            Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if ("L".equals(direction)) {
            Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if ("U".equals(direction)) {
            Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if ("D".equals(direction)) {
            Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
        }

        for (int i = 1; i < length; i++) {//通过for循环绘制蛇的身体
            Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);
        }
        g.setColor(Color.WHITE);
        g.setFont(new Font("微软雅黑", Font.BOLD, 18));
        g.drawString("长度:"+length,650,54);
        g.drawString("分数:"+score,750,54);//分数长度等的绘制
        Data.food.paintIcon(this, g, foodX, foodY);//绘制食物
        if (!isStart) {//如果还没开始就提示按下空格开始
            g.setColor(Color.WHITE);
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("按下空格来开始游戏", 300, 300);
        }

        if (isFail) {//如果失败了就提示按下空格重新开始
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("蛇死了哦,按下空格重新开始吧", 200, 300);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (isStart && !isFail) {//如果已经开始并且没有失败
            for (int i = length - 1; i > 0; i--) {
                snakeX[i] = snakeX[i - 1];
                //就把每节身体的位置都变成上一个身体的位置来模拟移动
                snakeY[i] = snakeY[i - 1];
            }

            if ("R".equals(direction)) {
                //动完了身体,这里动蛇头,根据不同的方向来动到位置
                snakeX[0] = snakeX[0] + 25;
                if (snakeX[0] > 850) {
                    snakeX[0] = 25;
                }
            } else if ("L".equals(direction)) {
                snakeX[0] = snakeX[0] - 25;
                if (snakeX[0] < 25) {
                    snakeX[0] = 850;
                }
            } else if ("U".equals(direction)) {
                snakeY[0] = snakeY[0] - 25;
                if (snakeY[0] < 75) {
                    snakeY[0] = 650;
                }
            } else if ("D".equals(direction)) {
                snakeY[0] = snakeY[0] + 25;
                if (snakeY[0] > 650) {
                    snakeY[0] = 75;
                }
            }

            if (snakeX[0] == foodX && snakeY[0] == foodY) {//判断是否吃到食物
                //如果两者的xy坐标重合了就说明吃到了
                length++;//吃到了长度加一
                snakeX[length - 1] = foodX - 1;//这里是避免出现一个bug,没有这两行就会在吃吃到以后左上角出现一个绿方块
                //这是因为新增加的身体没有赋值坐标,所以就默认在00的位置
                snakeY[length - 1] = foodY - 1;
                score = score + 10;
                foodX = getFoodX();//重新生成新的食物
                foodY = getFoodY();
            }
            for(int i = 1; i < length; i++){//进行判断是否死亡,当蛇头和身体重合就是死亡
                if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                    isFail = true;
                    break;
                }
            }
            repaint();//蛇移动了所以需要重新画一遍
        }
        timer.start();//计时器重新开始,蛇再进行下一步移动
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();//这个为接受的键盘的按键对应的代码
        if(keyCode == KeyEvent.VK_SPACE){//如果是空格的话激素hi进行判断
            if(!isFail){//如果没有失败就进行暂停与重新游戏的功能实现
                isStart = !isStart;
            }else{//如果已经死了就重新开始
                isFail = false;
                init();
            }
            repaint();//重新绘制
        }
        if (keyCode == KeyEvent.VK_LEFT && !"R".equals(direction)) {//检查获取的是上下左右的哪个进行蛇头转向
            direction = "L";
        } else if (keyCode == KeyEvent.VK_RIGHT && !"L".equals(direction)) {
            direction = "R";
        } else if (keyCode == KeyEvent.VK_UP && !"D".equals(direction)) {
            direction = "U";
        } else if (keyCode == KeyEvent.VK_DOWN && !"U".equals(direction)) {
            direction = "D";
        }
        if (keyCode == KeyEvent.VK_A && !"R".equals(direction)) {//检查获取的是wasd的哪个进行蛇头转向
            //注意当是与蛇头反方向的不可以进行转动,毕竟也不能180度转脖子把
            direction = "L";
        } else if (keyCode == KeyEvent.VK_D && !"L".equals(direction)) {
            direction = "R";
        } else if (keyCode == KeyEvent.VK_W && !"D".equals(direction)) {
            direction = "U";
        } else if (keyCode == KeyEvent.VK_S && !"U".equals(direction)) {
            direction = "D";
        }
    }




    //这两个没有用,所以不用写了
    @Override
    public void keyTyped(KeyEvent e) {

    }
    @Override
    public void keyReleased(KeyEvent e) {

    }
}

Data类代码是:


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


public class Data {
    //读取statics文件夹里的图片,加载成图片
    public static URL bodyURL = Data.class.getResource("/statics/body.png");
    public static URL foodURL = Data.class.getResource("/statics/food.png");
    public static URL downURL = Data.class.getResource("/statics/down.png");
    public static URL upURL = Data.class.getResource("/statics/up.png");
    public static URL rightURL = Data.class.getResource("/statics/right.png");
    public static URL leftURL = Data.class.getResource("/statics/left.png");
    public static ImageIcon body = new ImageIcon(bodyURL);
    public static ImageIcon food = new ImageIcon(foodURL);
    public static ImageIcon down = new ImageIcon(downURL);
    public static ImageIcon up = new ImageIcon(upURL);
    public static ImageIcon right = new ImageIcon(rightURL);
    public static ImageIcon left = new ImageIcon(leftURL);
}

整个项目文件可以在github上自取,点击蓝字
github
上不去的也可以在gitee上自取,点击蓝字
gitee

💕
真的不下一个自己玩一玩吗[手动滑稽]

到此这篇关于java gui详解贪吃蛇小游戏实现流程的文章就介绍到这了,更多相关java 贪吃蛇内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

java gui详解贪吃蛇小游戏实现流程

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java实现贪吃蛇游戏

下面是一个简单的Java实现贪吃蛇游戏的示例代码:```javaimport javax.swing.*;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.ev
2023-08-09

Java+JFrame怎么实现贪吃蛇小游戏

这篇文章主要讲解了“Java+JFrame怎么实现贪吃蛇小游戏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java+JFrame怎么实现贪吃蛇小游戏”吧!首先创建一个合适大小的窗口,我这里
2023-07-01

java如何实现简单贪吃蛇小游戏

这篇文章给大家分享的是有关java如何实现简单贪吃蛇小游戏的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体内容如下有两个类,放在同一文件下下即可,背景图片,标题,蛇尾可自行更改import java.awt.*
2023-06-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录