GUI编程19:贪吃蛇小游戏及GUI总结

news2024/11/16 1:24:54

视频链接:21、贪吃蛇之界面绘制_哔哩哔哩_bilibiliicon-default.png?t=O83Ahttps://www.bilibili.com/video/BV1DJ411B75F?p=21&vd_source=b5775c3a4ea16a5306db9c7c1c1486b5

1.游戏中用的的图片素材

1.贪吃蛇游戏的主启动类StartGame;

package com.yundait.snake;

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

//贪吃蛇游戏的主启动类;
public class StartGame {
    public static void main(String[] args) {

        JFrame frame = new JFrame("我的游戏—贪吃蛇");//创建游戏窗口

        frame.setBounds(10,10,915,745);//设置窗口的位置和长宽
        frame.setResizable(false);//设置窗口尺寸不可调
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置窗口关闭事件

        Container container = frame.getContentPane();//创建一个内容窗格的容器
        container.add(new GamePanel());//将面板放在容器上

        frame.setVisible(true);//设置窗口可见
    }
}

2.贪吃蛇游戏的数据类Data:存放游戏界的图片

package com.yundait.snake;

import javax.swing.*;
import java.net.URL;
public class Data {
    public static URL headerURL = Data.class.getResource("statics/header.png");//获取标题图片
    public static ImageIcon header = new ImageIcon(headerURL);//创建标题图标
    public static URL upURL = Data.class.getResource("statics/up.png");//获取朝上的头部图片
    public static URL downURL = Data.class.getResource("statics/down.png");//获取朝下的头部图片
    public static URL leftURL = Data.class.getResource("statics/left.png");//获取朝左的头部图片
    public static URL rightURL = Data.class.getResource("statics/right.png");//获取朝右的头部图片
    public static URL bodyURL = Data.class.getResource("statics/body.png");//获取朝右的头部图片
    public static ImageIcon up = new ImageIcon(upURL);//创建朝上的头部图标
    public static ImageIcon down = new ImageIcon(downURL);//创建朝下的头部图标
    public static ImageIcon left = new ImageIcon(leftURL);//创建朝左的头部图标
    public static ImageIcon right = new ImageIcon(rightURL);//创建朝右的头部图标
    public static ImageIcon body = new ImageIcon(bodyURL);//创建朝右的头部图标
    public static URL foodURL = Data.class.getResource("statics/food.png");//获取食物图片
    public static ImageIcon food = new ImageIcon(foodURL);//创建食物图标
}

3.贪吃蛇游戏的游戏面板GamePanel:主要功能都在类下此实现

package com.yundait.snake;

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 KeyListener, ActionListener {
    int length; //定义蛇的长度
    int[]snakeX= new int[600];//蛇的X坐标
    int[]snakeY= new int[500];//蛇的Y坐标
    String direction;//定义小蛇头的方向参数
    int food_x;
    int food_y;
    int score;
    Random random = new Random();
    boolean isStart;//游戏开始、结束的状态
    boolean isFail;//游戏失败状态
    Timer timer = new Timer(100,this);//创建一个定时器,每100毫秒执行一次(每秒执行10次)

    //构造器方法
    public GamePanel() {
        init();
        this.setFocusable(true);//获得焦点事件
        this.addKeyListener(this);//添加键盘监听
    }

    //数据初始化方法
    public void init(){
        length = 3;//初始化小蛇长度,包含小蛇头
        snakeX[0] = 100;snakeY[0] = 100;//初始化小蛇脑袋的坐标
        snakeX[1] = 75;snakeY[1] = 100;//初始化小蛇第1段身体的坐标
        snakeX[2] = 50 ;snakeY[2] = 100;//初始化小蛇第2段身体的坐标
        direction = "right"; //初始化小蛇头的方向(向右)
        isStart = false;//游戏默认处于停止状态
        isFail = false;
        timer.start();//游戏一开始,就启动定时器。
        score = 0;

        //把食物随机分派在界面上
        food_x = 25 + 25*random.nextInt(34);
        food_y = 75 + 25*random.nextInt(24);

    }

    //绘制面板,我们游戏中的所有东西,都用这支画笔来画
    @Override
    protected void paintComponent(Graphics g) {

        //清屏
        super.paintComponent(g);

        //绘制静态游戏面板
        this.setBackground(new Color(255, 255, 255));//设置面板的颜色
        Data.header.paintIcon(this,g,25,11);//把头部广告栏画上去
        g.setColor(new Color(110, 164, 176));//设置画笔的颜色
        g.fillRect(25,75,850,600);//画一个默认的矩形游戏界面

        //把分数画在界面上
        g.setColor(Color.white);
        g.setFont(new Font("微软雅黑",Font.BOLD,18));
        g.drawString("长度:" + length,750,30);
        g.drawString("分数:" + score,750,55);

        //把食物画在界面上
        Data.food.paintIcon(this,g,food_x,food_y);

        //使用switch选择结构把小蛇的头画在面板上
        switch (direction){
            case "right":
                Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝右的小蛇头画在面板上
                break;
            case "left":
                Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝左的小蛇头画在面板上
                break;
            case "up":
                Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝上的小蛇头画在面板上
                break;
            case "down":
                Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);//把朝下的小蛇头画在面板上
                break;
        }

        //使用循环结构把小蛇身体画在面板上
        for (int i = 1; i < length; i++) {
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
        }

        //判断游戏状态,按下空格键开始或结束游戏
        if (!isStart){
            g.setColor(Color.white);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("请按下空格开始游戏",300,350);
        }
        
        //判断游戏是否失败,失败后显示:"游戏失败,按下空格重新开始"
        if (isFail){
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("游戏失败,按下空格重新开始",300,350);

        }
    }

    //键盘监听事件
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();//获得键盘按下了哪一个
        if (keyCode == KeyEvent.VK_SPACE){
            if (isFail){
                //游戏重新开始
                isFail =false;
                init();
            }else {
                isStart = !isStart;//游戏状态取反
            }
            repaint();
        }
        
        //监听键盘输入,根据键盘输入不同,改变小蛇方向
        if (keyCode == KeyEvent.VK_UP && !direction.equals("down")){
            direction = "up";
        } else if (keyCode == KeyEvent.VK_DOWN && !direction.equals("up")) {
            direction = "down";
        } else if (keyCode == KeyEvent.VK_LEFT && !direction.equals("right")) {
            direction = "left";
        } else if (keyCode == KeyEvent.VK_RIGHT && !direction.equals("left")) {
            direction = "right";
        }
    }

    //事件监听----需要通过固定的时间来刷新
    @Override
    public void actionPerformed(ActionEvent e) {

        if (isStart && !isFail){
            
            //监听小蛇吃食物
            if (snakeX[0] == food_x && snakeY[0] == food_y){
                //再次随机一个食物的坐标
                food_x = 25 + 25*random.nextInt(34);
                food_y = 75 + 25*random.nextInt(24);
                //吃完食物,身体长度加1
                length = length +1;
                score+=10;
            }
            
            //使用for循环让小蛇的后一节身体一动到前一节位置
            for (int i = length-1; i > 0 ; i--) {
                snakeX[i] = snakeX[i-1];
                snakeY[i] = snakeY[i-1];
            }

            //控制小蛇移动,撞墙后游戏失败
            if (direction.equals("right")){
                snakeX[0] = snakeX[0]+25;
                if (snakeX[0]>850){isFail = true;}
            } else if (direction.equals("left")) {
                snakeX[0] = snakeX[0]-25;
                if (snakeX[0]<25){isFail = true;}
            } else if (direction.equals("up")) {
                snakeY[0] = snakeY[0]-25;
                if (snakeY[0]<75){isFail = true;}
            } else if (direction.equals("down")) {
                snakeY[0] = snakeY[0]+25;
                if (snakeY[0]>650){isFail = true;}
            }
            
            //判断小蛇是否撞到自己,撞到自己后游戏失败
            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 keyTyped(KeyEvent e) {

    }//用不到,不需要重写方法,放在这里即可;
    @Override
    public void keyReleased(KeyEvent e) {

    }//用不到,不需要重写方法,放在这里即可;
}

4.GUI编程内容总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2155926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ArcGISPro】配置模块

ArcGIS Pro 配置类似于加载项&#xff0c;但提供了扩展应用程序的其他方法。它可以帮助您设计更贴近您组织品牌和工作流的 ArcGIS Pro 版本。 托管配置是比 Add-in 更高级别的自定义。 配置可以提高加载项安全级别并添加非管理员指定的已知文件夹。 配置可以提供比插件更广泛…

全国832个贫困县名单及精准扶贫脱贫数据(2016-2020.11)

自党的十八大以来&#xff0c;通过全党全国各族人民的共同努力&#xff0c;中国成功实现了现行标准下9899万农村贫困人口的全部脱贫&#xff0c;832个贫困县全部摘帽。 摘帽名单 2016年-2020.11全国832个贫困县名单及精准扶贫脱贫数据整理&#xff08;大数据&#xff09;https…

图解 TCP 四次挥手|深度解析|为什么是四次|为什么要等2MSL

写在前面 今天我们来图解一下TCP的四次挥手、深度解析为什么是四次&#xff1f; 上一片文章我们已经介绍了TCP的三次握手 解析四次挥手 数据传输完毕之后&#xff0c;通信的双方都可释放连接。现在客户端A和服务端B都处于ESTABLISHED状态。 第一次挥手 客户端A的应用进…

笔尖划出秋季的声息

笔尖划出秋季的声息 进入秋分&#xff0c;天气渐趋凉爽&#xff0c;天空青蓝明朗&#xff0c;难言伤感。 九月&#xff0c;把一些句子记录好&#xff0c;明年拿出来晒一晒&#xff0c;秋季也就有了答案。 1、经历 9月6日&#xff0c;台风“摩羯”席卷而过粤西&#xff0c;…

尚品汇-秒杀商品定时任务存入缓存、Redis发布订阅实现状态位(五十一)

目录&#xff1a; &#xff08;1&#xff09;秒杀业务分析 &#xff08;2&#xff09;搭建秒杀模块 &#xff08;3&#xff09;秒杀商品导入缓存 &#xff08;4&#xff09;redis发布与订阅实现 &#xff08;1&#xff09;秒杀业务分析 需求分析 所谓“秒杀”&#xff0…

STM32CSDK生成代码报错

STM32CubeMX not found 在使用STM32CSDK时报错 STM32CubeMX not found - ver. “5.2.0” or higher is required Download STM32CubeMx 解决方案 重新安装STM32CubeMX&#xff0c;选择为所有用户安装 MotorControl reference pack not found: 解决方案 1.选择合适的STM32…

Python语法(二)——函数

文章目录 函数语法格式函数参数链式调用嵌套调用函数递归变量作用域 函数 一段可以被重复使用的代码片段 求数列的和, 不使用函数 # 1.求1-100的和 sum 0 for i in range(1, 101):sum i print(fsum {sum})# 2.求300-400的和 sum 0 for i in range(300, 401):sum i print(…

为什么推荐使用英文版LabVIEW

在LabVIEW开发中&#xff0c;中文版和英文版主要在界面语言、功能习惯以及社区支持等方面存在差异。以下是两者的特点以及推荐使用英文版的原因&#xff1a; 中文版特点&#xff1a; 界面和帮助文档为中文&#xff1a;对于中文母语开发者来说&#xff0c;中文版LabVIEW的界面和…

在 Windows 11 中,可以通过修改注册表来更改系统的自动更新时间设置

regedit 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings FlightSettingsMaxPauseDays 36524

YOLOV8 OpenCV + usb 相机 实时识别

1 OpenCV 读相机 import cv2cap cv2.VideoCapture(0) while (1):# get a frameret, frame cap.read()# show a framecv2.imshow("capture", frame)if cv2.waitKey(1) & 0xFF ord(q):# cv2.imwrite("/opt/code/image/fangjian2.jpeg", frame)#passb…

设置CentOS7使用代理服务器上网

搭建代理 软件设置-参数设置-允许来自局域网的连接 软件设置-参数设置-为局域网开启新的端口(可选) 记录本机ip与端口号 配置系统代理 永久设置 # 编辑配置文件 vi /etc/profile# 在文件后添加以下内容&#xff1a; export http_proxyhttp://代理服务器IP:端口号 export h…

python - 子类为什么调用父类的方法

菜鸟教程 - 面向对象https://www.runoob.com/python3/python3-class.html为什么写这个呢 &#xff0c;因为很多时候&#xff0c;事情很简单&#xff0c;但我往往记住了使用方式&#xff0c;忘记了使用原因&#xff0c;也因为自己看到super()时&#xff0c;也想问为什么要用supe…

重生之我们在ES顶端相遇第16 章 - Lucene 写入流程

文章目录 前言写入流程图refreshRefresh 触发时机Translog FlushMerge 前言 上一章我们介绍了倒排索引的数据结构。 本章我们将深入介绍 Lucene 写入流程。 该知识点在面试中比较常问&#xff0c;也是理解 ES 必须掌握的知识点。 写入流程图 在第 14 章&#xff0c;我在介绍…

web基础—dvwa靶场(七)SQL Injection

SQL Injection&#xff08;SQL注入&#xff09; SQL Injection&#xff08;SQL注入&#xff09;&#xff0c;是指攻击者通过注入恶意的SQL命令&#xff0c;破坏SQL查询语句的结构&#xff0c;从而达到执行恶意SQL语句的目的。SQL注入漏洞的危害是巨大的&#xff0c;常常会导致…

有毒有害气体检测仪的应用和性能_鼎跃安全

随着现代工业的不断发展和扩张&#xff0c;越来越多的企业涉及到有毒有害气体的生产、使用和处理。工业规模的扩大导致有毒有害气体的排放量增加&#xff0c;同时也增加了气体泄漏的风险。在发生火灾、爆炸或危险化学品泄漏等紧急事件时&#xff0c;救援人员需要迅速了解现场的…

自动化立体仓库与堆垛机单元的技术参数

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》人俱乐部 完整版文件和更多学习资料&#xff0c;请球友到知识星球【智能仓储物流技术研习社】自行下载。 这份文件是一份自动化立体仓库与堆垛机单…

Java内存泄漏排查

内存泄漏排查 1. 堆内存快照导出2. 导入内存分析工具 1. 堆内存快照导出 获取 Java 进程 ID Windows&#xff1a;执行 jps 命令&#xff0c;或任务管理器查看&#xff0c;又或者执行 tasklist 命令。 注意&#xff1a;当有多个 Java 进程时&#xff0c;任务管理器或 tasklist |…

SpringSecurity6.x整合手机短信登录授权

前言&#xff1a;如果没有看过我的这篇文章的Springboot3.x.x使用SpringSecurity6(一文包搞定)_springboot3整合springsecurity6-CSDN博客需要看下&#xff0c;大部分多是基于这篇文章的基础上实现的。 明确点我们的业务流程&#xff1a; 需要有一个发送短信的接口&#xff0…

springboot小区物业报修管理系统-计算机毕业设计源码03418

摘 要 本课题的研究对象是小区物业报修管理系统app的设计与实现&#xff0c;该系统实现了用户管理、业主信息管理、报修信息管理、维修记录管理、通知公告管理等功能。本系统在设计上&#xff0c;考虑到系统内容以及系统的受众群体&#xff0c;在系统的美工方面采用了比较正规的…

Automated Construction of Theme-specific Knowledge Graphs

文章目录 题目摘要引言相关工作方法实验消融研究结论 题目 自动构建主题特定知识图谱 论文地址&#xff1a;https://arxiv.org/pdf/2404.19146 摘要 尽管知识图谱 (KG) 广泛应用于问答、智能对话系统等各种任务&#xff0c;但现有的 KG 面临两大挑战&#xff1a;信息粒度有限和…