GUI:贪吃蛇

news2025/4/5 16:41:12

以上是准备工作

Data


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

public class Data {
    public static URL headerURL=Data.class.getResource("static/header.png");
    public static ImageIcon header =new ImageIcon(headerURL);

    public static URL upURL=Data.class.getResource("static/up.png");
    public static URL downURL=Data.class.getResource("static/down.png");
    public static URL leftURL=Data.class.getResource("static/left.png");
    public static URL rightURL=Data.class.getResource("static/right.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 URL bodyURL=Data.class.getResource("static/body.png");
    public static ImageIcon body =new ImageIcon(bodyURL);
    public static URL foodURL=Data.class.getResource("static/food.png");
    public static ImageIcon food =new ImageIcon(foodURL);
}

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 KeyListener , ActionListener {

        //定义蛇的数据结构
        int length;//蛇的长度
        // 蛇的x,y坐标
        int[]snakeX=new int[600];
        int[]snakeY=new int[500];
        String fx;
        //游戏当前的状态:开始,停止
        boolean isStart=false;//默认是不开始
        boolean isFail=false;//游戏结果的状态
    int score;
    int foody,foodx;
    Random  random=new Random();
    //定时器 ms为单位 1000ms=1s
    Timer timer=new Timer(100,this);

    //构造器

    public GamePanel(){
        init();
        //获得焦点和键盘事件
        this.setFocusable(true);
        this.addKeyListener(this);
        timer.start();//游戏qidong
    }
    public void init(){
        length=3;
        snakeX[0]=100;snakeY[0]=100;//脑袋坐标
        snakeX[1]=75;snakeY[1]=100;//第一个身体的坐标
        snakeX[2]=50;snakeY[2]=100;//第二个身体的坐标
        fx="R";//inti向右

        //随机分布food
        foodx=25+25*random.nextInt(34);
        foody=75+25*random.nextInt(24);
        score=0;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//清屏
        //绘制静态的面板
        this.setBackground(Color.WHITE);
        Data.header.paintIcon(this,g,25,11);//画头部广告
        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,foodx,foody);


        //把小蛇画上去
        if(fx.equals("R")){
            Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);//蛇头初始化向右
        }
        else if(fx.equals("L")){
            Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);//蛇头初始化向L
        }
        else if(fx.equals("U")){
            Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);//蛇头初始化向UP
        }
        else if(fx.equals("D")){
            Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);//蛇头初始化向down
        }

        for(int i=1;i<length;i++){
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i] );
        }

//游戏状态
        if(isStart==false){
            g.setColor(Color.white);
            g.setFont(new Font("微软雅黑",Font.BOLD,30));
            g.drawString("Pressed the Blank Key Begin Game",300,300);
        }


//游戏结束
        if(isFail){
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑",Font.BOLD,30));
            g.drawString("The Game Is Failed",250,300);
        }
    }



    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode=e.getKeyCode();//获得键盘参数
        //空格开始
        if(keyCode==KeyEvent.VK_SPACE){
            if(isFail){
                isFail=false;
            }else{
            isStart=!isStart;}
            repaint();
        }
        //小蛇移动
        if(keyCode==KeyEvent.VK_UP){
            fx="U";
        } else if (keyCode==KeyEvent.VK_DOWN) {
            fx="D";
        }else if (keyCode==KeyEvent.VK_LEFT) {
            fx="L";
        }else if (keyCode==KeyEvent.VK_RIGHT) {
            fx="R";
        }
        //走向
        if(fx.equals("R")){
            snakeX[0]=snakeX[0]+25;
            if(snakeX[0]>850){snakeX[0]=25;}//边界判断
        }else if(fx.equals("L")){
            snakeX[0]=snakeX[0]-25;
            if(snakeX[0]<25){snakeX[0]=850;}//边界判断
        }else if(fx.equals("U")){
            snakeY[0]=snakeY[0]-25;
            if(snakeY[0]<75){snakeY[0]=650;}//边界判断
        }else if(fx.equals("D")){
            snakeY[0]=snakeY[0]+25;
            if(snakeY[0]>650){snakeY[0]=75;}//边界判断
        }
    }
    @Override
    public void actionPerformed(ActionEvent e) {

        if(isStart&&isFail==false){
            for (int i = length-1; i >0 ; i--) {
                snakeX[i]=snakeX[i-1];
                snakeY[i]=snakeY[i-1];
            }
            if(snakeX[0]==foodx&&snakeY[0]==foody){
                length++;
                score+=10;
//重置食物
                foodx=25+25*random.nextInt(34);
                foody=75+25*random.nextInt(24);

            }
            //头部走向
            if(fx.equals("R")){
                snakeX[0] = snakeX[0]+25;   //头部右移25个单位(即一格)
                if(snakeX[0]>850){  //边界判断:如果蛇右移到了边界,则回到左边
                    snakeX[0] = 25;
                }
            }else if(fx.equals("L")){
                snakeX[0] = snakeX[0]-25;           //头部左移25个单位(即一格)
                if(snakeX[0]<25){snakeX[0] = 850;}  //边界判断
            }else if(fx.equals("U")){
                snakeY[0] = snakeY[0]-25;           //向上移动应该是-25
                if(snakeY[0]<75){snakeY[0] = 650;}  //边界判断
            }else if(fx.equals("D")){
                snakeY[0] = snakeY[0]+25;           //向下移动
                if(snakeY[0]>650){snakeY[0] = 75;}  //边界判断
            }
            for (int i = 1; i < length; i++) {  //头部与身体的某一节坐标重合,即撞到自己
                if(snakeX[0] == snakeX[i] && snakeY[0]==snakeY[i]){
                    isFail=true;
                    init();
                }
            }
            repaint();
        }
        timer.start();
    }
    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
}

StartGame


import javax.swing.*;

public class StartGame {
    public static void main(String[] args) {
        JFrame frame=new JFrame();
        frame.setBounds(10,10,900,720);
        //窗口设置大小固定
        frame.setResizable(false);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //正常游戏界面都应该在面上
        frame.add(new GamePanel());
        frame.setVisible(true);
    }
}

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

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

相关文章

【树的存储结构,孩子链表】

文章目录 树和森林树的存储结构孩子链表 树和森林 森林&#xff1a;是m(m>0)棵互不相交的树的集合。 树的存储结构 1.双亲表示法 实现&#xff1a;定义结构数组存放树的结点&#xff0c;每个结点含两个域。 数据域&#xff1a;存放结点本身信息。 双亲域&#xff1a;指…

如何设计vue项目的权限管理?

权限管理的重要性及必要性 数据安全&#xff1a;权限管理可以确保只有具有相应权限的用户能够访问和操作特定的数据。这可以保护敏感数据不被未授权的用户访问&#xff0c;从而提高数据的安全性。功能控制&#xff1a;权限管理可以根据用户的角色和权限设置&#xff0c;控制用户…

Ansible自动化运维工具(常用模块与命令)

ansible基于Python开发&#xff0c;实现了批量系统配置&#xff0c;批量程序部署&#xff0c;批量运行命令等功能 ansible特点 部署简单&#xff0c;只需在主控端部署Ansible环境&#xff0c;被控端无需做任何操作&#xff1b;默认使用ssh协议对设备进行管理&#xff1b;有大…

SPASS-交叉表分析

导入数据 修改变量测量类型 分析->描述统计->交叉表 表中显示行、列变量通过卡方检验给出的独立性检验结果。共使用了三种检验方法。上表各种检验方法显著水平sig.都远远小于0.05,所以有理由拒绝实验准备与评价结果是独立的假设&#xff0c;即认为实验准备这个评价指标是…

DehazeNet: An End-to-End System for Single Image Haze Removal(端到端的去雾模型)

1、论文去雾总体思路 DehazeNet是2016年华南理工大学的研究者提出的一个端到端的深度学习模型&#xff0c;该模型主要通过输入的原始有雾图像拟合出该图所对应的medium transmission map&#xff08;透射率t值图&#xff09;&#xff0c;并使用引导滤波对t值进行refine&#x…

SpringCloud - OpenFeign 参数传递和响应处理(全网最详细)

目录 一、OpenFeign 参数传递和响应处理 1.1、feign 客户端参数传递 1.1.1、零散类型参数传递 1. 例如 querystring 方式传参 2. 例如路径方式传参 1.1.2、对象参数传递 1. 对象参数传递案例 1.1.3、数组参数传递 1. 数组传参案例 1.1.4、集合类型的参数传递&#xf…

PHP+MySQL人才招聘小程序系统源码 带完整前端+后端搭建教程

在当今竞争激烈的人才市场中&#xff0c;招聘平台的需求日益增长。传统的招聘平台往往需要投入大量的人力物力进行维护和管理&#xff0c;这对于许多中小企业来说是一个沉重的负担。因此&#xff0c;开发一个简单易用、高效便捷的招聘平台显得尤为重要。 PHP是一种流行的服务器…

通过docker-compose部署elk日志系统,并使用springboot整合

ELK是一种强大的分布式日志管理解决方案&#xff0c;它由三个核心组件组成&#xff1a; Elasticsearch&#xff1a;作为分布式搜索和分析引擎&#xff0c;Elasticsearch能够快速地存储、搜索和分析大量的日志数据&#xff0c;帮助用户轻松地找到所需的信息。 Logstash&#xf…

逐次变分模态分解(Sequential Variational Mode Decomposition,SVMD)(附代码)

代码原理 逐次变分模态分解&#xff08;Sequential Variational Mode Decomposition&#xff0c;SVMD&#xff09;是一种用于信号处理和数据分析的方法。它可以将复杂的信号分解为一系列模态函数&#xff0c;每个模态函数代表了信号中的一个特定频率成分。SVMD的主要目标是提取…

【每日一题】咒语和药水的成功对数

文章目录 Tag题目来源解题思路方法一&#xff1a;排序二分 写在最后 Tag 【排序二分】【数组】【2023-11-10】 题目来源 2300. 咒语和药水的成功对数 解题思路 方法一&#xff1a;排序二分 我们首先对 points 进行升序排序&#xff0c;然后枚举 spells 中的 x&#xff0c;需…

持续集成交付CICD:安装Gitlab Runner(从节点)

目录 一、实验 1.选择Gitlab Runner版本 2.安装Gitlab Runner&#xff08;第一种方式&#xff1a;交互式安装&#xff09; 3.安装Gitlab Runner&#xff08;第二种方式&#xff1a;非交互式安装&#xff09; 二、问题 1.如何查看Gitlab版本 一、实验 1.选择Gitlab Runne…

如何用Excel软件制作最小二乘法①

一、用自带的选项&#xff08;不推荐&#xff09;&#xff0c;因为感觉只是近似&#xff0c;虽然结果一样 1.在Excel中输入或打开要进行在excel中输入或打开要进行最小二乘法拟合的数据&#xff0c;如图所示。 2.按住“shift”键的同时&#xff0c;用鼠标左键单击以选择数据&a…

android手机平板拓展电脑音频

&#xff08;1&#xff09;首先确保电脑上有声卡&#xff0c;就是电脑右下角小喇叭能调音量&#xff0c;不管电脑会不会响&#xff0c;如果小喇叭标记了个错误&#xff0c;说明没有声卡&#xff0c;安装图上的虚拟声卡软件。 &#xff08;2&#xff09;图上第一个PC免安装及局…

Code Review最佳实践

Code Review最佳实践 Code Review 我一直认为Code Review&#xff08;代码审查&#xff09;是软件开发中的最佳实践之一&#xff0c;可以有效提高整体代码质量&#xff0c;及时发现代码中可能存在的问题。包括像Google、微软这些公司&#xff0c;Code Review都是基本要求&…

07、SpringBoot+微信支付 -->处理超时订单(定时查询、核实微信支付平台的订单、调用微信支付平台查单接口、更新本地订单状态、记录支付日志)

目录 Native 支付处理超时订单定时的讲解需求分析代码定时任务&#xff1a;WxPayTask定时查询的方法&#xff1a;核实订单状态等操作 &#xff1a;WxPayServiceImpl查单接口方法&#xff1a;queryOrder更新本地订单状态&#xff1a;updateStatusByOrderNo记录支付日志&#xff…

tqdm学习

from tqdm import tqdmepochs 10 epoch_bar tqdm(range(epochs)) count 0 for _ in epoch_bar:count count1print("count {}".format(count))print(_)每次就是一个epoch

CSDN每日一题学习训练——Java版(克隆图、最接近的三数之和、求公式的值)

版本说明 当前版本号[20231109]。 版本修改说明20231109初版 目录 文章目录 版本说明目录克隆图题目解题思路代码思路参考代码 最接近的三数之和题目解题思路代码思路参考代码 求公式的值题目解题思路代码思路参考代码 克隆图 题目 给你无向 连通(https://baike.baidu.com…

电商项目之Java8函数式接口落地实践

文章目录 1 问题背景2 前言3 多处重复的重试机制代码4 优化后的代码5 进一步优化 1 问题背景 在电商场景中&#xff0c;会调用很多第三方的云服务&#xff0c;比如发送邮件、发起支付、发送验证码等等。由于网络存在抖动&#xff0c;有时候发起调用后会拿到500的状态码&#xf…

Visual Studio2022安装教程【图文详解】(大一小白)编译软件

工欲善其事&#xff0c;必先利其器。想要学好编程&#xff0c;首先要把手中的工具利用好&#xff0c;今天小编教一下大家如何下载安装并使用史上最强大的编译器--Visual Studio&#x1f357; 一.Visual Studio下载及安装 https://visualstudio.microsoft.com/ 打开文件 点击.ex…

Halcon的相机内参外参的标定

halcon标定相机内参只能使用方向标定板和圆点标定板。并且方向标定板可也可用性极高。 1.打开halcon的标定助手&#xff0c;选择标定板的描述文件&#xff0c;填写标定板的厚度&#xff0c;根据相机选择像元的尺寸和镜头的焦距。如果已有相机内参&#xff0c;只标定外参&#…