当前位置:

首页 > 编程开发 > 怎么用Java实现贪吃蛇大作战小游戏

怎么用Java实现贪吃蛇大作战小游戏

1.开发环境及游戏展示贪吃蛇大作战在设计与实验的过程中需要在Window10系统中进行,并使用开发工具IntelliJIDEACommunityEdition2020.3.2(jdk-15)完成代码的编写、编译、调试、测试等工作。程序需要的组件如贪吃蛇的蛇头、蛇身及背景图片等均使用图像软件AdobePhotoshop2020制作。1.1游戏主界面1.2移动界面1.3奖励界面1.游戏达到50分:2.游戏达到100分:1.4F加速功能界面按下F时,速度提高到100。1.5死亡界面2.需求分析贪吃蛇游戏是一个小

本文目录

    1.开发环境及游戏展示

    贪吃蛇大作战在设计与实验的过程中需要在Window 10系统中进行,并使用开发工具IntelliJ IDEA Community Edition 2020.3.2(jdk-15)完成代码的编写、编译、调试、测试等工作。程序需要的组件如贪吃蛇的蛇头、蛇身及背景图片等均使用图像软件Adobe Photoshop 2020制作。

    1.1 游戏主界面

    怎么用Java实现贪吃蛇大作战小游戏

    1.2 移动界面

    怎么用Java实现贪吃蛇大作战小游戏

    1.3 奖励界面

    1.游戏达到50分:

    怎么用Java实现贪吃蛇大作战小游戏

    2.游戏达到100分:

    怎么用Java实现贪吃蛇大作战小游戏

    1.4 F加速功能界面

    按下F时,速度提高到100。

    怎么用Java实现贪吃蛇大作战小游戏

    1.5 死亡界面

    怎么用Java实现贪吃蛇大作战小游戏

    2.需求分析

    贪吃蛇游戏是一个小型益智游戏,可用于人们日常的休闲、娱乐等场景。本次游戏设计涉及一维数组、Swing中的常用组件、GUI中的事件处理(事件监听器、键盘监听器)、类的封装与继承、static静态变量、包装类、随机数等方面的知识。

    具体需求概要如下:

    1.初始化界面为800×800大小,且游戏界面应保持在屏幕中央,窗口应有“贪吃蛇”字样;

    2.游戏界面应有必要的提示文字,提示游戏的得分和蛇的当前速度。开始界面应有操作提示文字(轻按空格游戏以开始/暂停游戏、按住F以加速),文字颜色应美观;

    3.在程序中初始化蛇的位置(靠近面板左侧)、蛇的方向(默认向右)、蛇的长度(默认为3),并初始化食物的位置;

    4.游戏的开始与暂停的实现:通过空格键控制游戏的开始与暂停;

    5.蛇移动功能的实现:用W、S、A、D或↑、↓、←、→控制蛇的运动方向为上、下、左、右进行游戏;

    6.当蛇头接触活动外围时:蛇头接触界面最右(左)端则从对称的左(右)端出现,以此类推,当蛇头接触界面最上(下)端则从对称的下(上)端出现;

    7.蛇吃食物的功能的实现:游戏过程中,蛇头触碰到食物时,即为吃食物。此时蛇的长度应加1,速度应增加10,得分增加10,并刷新食物的位置(随机位置);

    8.蛇加速功能的实现:当按住“F”键时,蛇加速运动,速度值达到100;当松开“F”键时,蛇恢复至默认速度10;

    9.蛇的死亡判定:当蛇头触碰到蛇身时,蛇死亡,游戏结束,界面靠近中央提示:“你的小蛇已经死亡,按下空格重新开始!”;

    10.游戏的奖励机制的实现:当得分为10时,游戏提示“Good!”字样;当得分为50时,游戏提示“Good!!!”字样;当得分为100时,游戏提示“Perfect!!!”字样;当得分达到200时,则游戏提示“无人能挡!!!”的字样;以上提示字样均位于蛇头;

    基本操作表如下:

    怎么用Java实现贪吃蛇大作战小游戏

    3.系统设计

    3.1 系统总体功能设计

    此贪吃蛇程序大方向上包含贪吃蛇的移动功能、贪吃蛇的主动加速功能、游戏规则判断功能、主界面控制功能、贪吃蛇吃食物功能。其中贪吃蛇的移动功能中包含移动方向的按键控制以及贪吃蛇的自动移动;游戏规则判断功能包括蛇的死亡判断、游戏开始与暂停判断以及越界规则;主界面控制功能包含蛇的初始化以及食物的初始化;贪吃蛇吃食物功能包括蛇身增长、蛇速度增加、积分增加和食物刷新位置。具体功能结构图如下:

    怎么用Java实现贪吃蛇大作战小游戏

    3.2 系统总体流程设计

    开始进入贪吃蛇程序时首先判断是否按下空格键,如果按下空格键则游戏开始。游戏开始后判断是否有按键输入,若有按键输入则根据按键设置改变蛇的移动方向或者进行加速操作;若没有按键操作则蛇继续保持原方向运动。在蛇运动过程中判断蛇是否吃到食物,若吃到食物则游戏得分加10,蛇的移动速度也相应增加;不管是否吃到食物都进行蛇是否死亡的判断,若死亡则游戏结束;若蛇没有死亡则继续判断是否有空格输入,若有则游戏暂停,反之则继续判断按键,根据按键改变蛇的运动状态,继续游戏,直到蛇死亡,游戏结束。

    怎么用Java实现贪吃蛇大作战小游戏

    4.功能设计

    4.1 贪吃蛇移动及加速功能设计

    贪吃蛇的移动功能主要依赖于选择语句和键盘监听器来实现,用W、S、A、D或↑、↓、←、→控制蛇的运动方向为上、下、左、右进行游戏。当按下F键时,蛇加速运动。

    怎么用Java实现贪吃蛇大作战小游戏

    4.2 贪吃蛇吃食物加速及死亡判定功能的设计

    在贪吃蛇吃食物以及死亡判定的过程中,使用到了以下参数:

    • Timer类的一个参数:int 类型的time,程序中调用timer.setDelay(time)方法更改定时器的参数(time越小,蛇运动越快);

    • 记录蛇死亡与否的参数:boolean 类型的isDied(true则蛇死,false则蛇活),默认为false;

    • 蛇的长度:int 类型的length(初始为3);

    • 积分参数:int 类型的score(初始为0),程序中通过循环控制每吃一次食物加10分;

    • 蛇头的坐标:int类型的snakeX[0]与snakeY[0],分别储存蛇头的横纵坐标;

    • 蛇身的坐标:int[] 类型的snakeX[i]和snakeY[i],分别储存每一节蛇身的横纵坐标(i≠0);

    • 食物的坐标:int 类型的foodX,foodY,分别储存食物的横纵坐标,foodX与foodY均为使用Random类中的nextInt()方法产生的随机数,故食物的坐标是随机的。

    以下使用上述参数时便不再赘述。

    4.2.1 贪吃蛇吃食物加速功能的设计

    当蛇头的坐标snakeX[0]与snakeY[0]分别与食物的坐标foodX,foodY相等时,得分score增加10,蛇身长度length加1,Timer参数time减10,从而完成蛇吃到食物后的加分,蛇身加长及加速功能。该功能的流程设计图如下:

    怎么用Java实现贪吃蛇大作战小游戏

    4.2.2 贪吃蛇死亡判定功能的设计

    当贪吃蛇吃到自己的时候蛇死亡,即蛇头坐标snakeX[0]与snakeY[0]分别与蛇身坐标snakeX[i]和snakeY[i]相等时,即蛇死亡。此时isDied=!isDied。

    怎么用Java实现贪吃蛇大作战小游戏

    4.3 贪吃蛇主动加速功能的设计

    贪吃蛇的主动加速功能即在游戏过程中按住F键,蛇的移动速度加快,若按住后松开,则蛇的速度恢复默认值。这主要通过GUI中的键盘监听器来实现,实现了键盘监听器的两个方法,keyPressed()与keyReleased()分别监听按下F键的操作和松开F键的操作。其次用到了参数time,程序中改变time的值通过调用timer.setDelay(time)方法(timer为Timer类的一个对象)从而改变定时器的频率,达到蛇速度加快的效果。

    怎么用Java实现贪吃蛇大作战小游戏

    4.4 贪吃蛇奖励机制功能的设计

    贪吃蛇奖励机制功能主要使用了选择结构以及通过paintComponent(Graphics g)方法中的画笔工具来实现。当游戏达到一定的得分时,程序会调用画笔工具中的g.drawString(“XXX”,snakeX[0],snakeY[0])方法,在蛇头位置绘制出提示文字。

    怎么用Java实现贪吃蛇大作战小游戏

    5.项目结构与项目实现

    5.1 项目结构及类间关系

    怎么用Java实现贪吃蛇大作战小游戏

    怎么用Java实现贪吃蛇大作战小游戏

    5.2 项目完整源码

    5.2.1 Images类

    该类为静态类,主要存储贪吃蛇组件的图片对象。

    package snakegame;
    
    import javax.swing.*;
    import java.net.URL;
    
    //Images类用于封装图片路径以及获取图片(使用静态对象便于用类名直接访问)
    public class Images {
        //将图片的路径封装成一个对象
        public static URL bodyURL=Images.class.getResource("/snake_images/body.jpg");
        public static URL backURL=Images.class.getResource("/snake_images/back.jpg");
        public static URL snakeDownURL=Images.class.getResource("/snake_images/snakeDown.jpg");
        public static URL snakeLeftURL=Images.class.getResource("/snake_images/snakeLeft.jpg");
        public static URL snakeRightURL=Images.class.getResource("/snake_images/snakeRight.jpg");
        public static URL snakeUpURL=Images.class.getResource("/snake_images/snakeUp.png");
        public static URL foodURL=Images.class.getResource("/snake_images/food.jpg");
        //将图片封装为程序中的对象
        public static ImageIcon bodyImg=new ImageIcon(bodyURL);
        public static ImageIcon backImg=new ImageIcon(backURL);
        public static ImageIcon snakeDownImg=new ImageIcon(snakeDownURL);
        public static ImageIcon snakeUpImg=new ImageIcon(snakeUpURL);
        public static ImageIcon snakeRightImg=new ImageIcon(snakeRightURL);
        public static ImageIcon snakeLeftImg=new ImageIcon(snakeLeftURL);
        public static ImageIcon foodImg=new ImageIcon(foodURL);
    }

    5.2.2 HighestScore

    该类实现历史最高分功能。

    package snakegame;
    
    import org.w3c.dom.Text;
    
    import java.io.*;
    
    //该类用于给游戏添加历史最高分功能
    public class HighestScore {
        static int score = 0;//最高分的存储
    
        public void highest() throws IOException {
            //得分为最高分时存储
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(String.valueOf(Text.class.getResourceAsStream("贪吃蛇大作战/score.txt"))));
            if (GamePanel.score > score) {
                score = GamePanel.score;
                String s1 = String.valueOf(score);
                bos.write(s1.getBytes());
            }
            bos.close();
        }
    
        //用于游戏开始时从文件读取最高分的值
        public void readHighest() throws IOException {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(String.valueOf(Text.class.getResourceAsStream("贪吃蛇大作战/score.txt"))));
            byte[] bys = new byte[1024];
            int len;
            while ((len = bis.read(bys)) != -1) {
                System.out.print(new String(bys, 0, len));//测试用
                String s2 = new String(bys, 0, len);
                score = Integer.valueOf(s2);
            }
            bis.close();
        }
    }

    5.2.3 GamePanel类

    该类用于绘制贪吃蛇游戏面板,以及实现游戏具体逻辑功能。

    package snakegame;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.io.IOException;
    import java.util.Random;
    
    //贪吃蛇游戏面板的绘制
    public class GamePanel extends JPanel {
        Timer timer;
        int time=100;
        static int score;//记录游戏分数
        //蛇属性部分
        boolean isDied;
        int length;//设置蛇长
        String direction;//蛇头朝向
        //分别储存蛇身的X,Y坐标
        int[] snakeX=new int[300];
        int[] snakeY=new int[300];
        //判断游戏是否开始
        boolean isStart=false;
        int foodX,foodY;//食物的X,Y坐标
        //贪吃蛇初始化方法
        public void init(){
            length=3;
            snakeX[0]=175;
            snakeY[0]=275;
            snakeX[1]=150;
            snakeY[1]=275;
            snakeX[2]=125;
            snakeY[2]=275;
            foodX=300;
            foodY=400;
            score=0;
            isDied=false;//蛇默认状态为活着
            direction="R";//U,D,L,R分别表示蛇头朝向上,下,左,右
        }
    
        //构造方法
        public GamePanel() throws IOException {
            init();
    
            if(GamePanel.score>HighestScore.score){
                new HighestScore().highest();
            }
            //焦点定位到当前面板
            this.setFocusable(true);
            //监听器的实现部分
            this.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    super.keyPressed(e);
                    int keyCode = e.getKeyCode();
                    //按下空格以开始游戏,以及方向键的控制
                    if (keyCode == KeyEvent.VK_SPACE) {
                        if(isDied){
                            init();
                        }else {
                            isStart = !isStart;
                            repaint();//重绘
                        }
                    } else if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_W) {
                        direction = "U";
                    } else if (keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_S) {
                        direction = "D";
                    } else if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_A) {
                        direction = "L";
                    } else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_D) {
                        direction = "R";
                    }
                }
            });
            //贪吃蛇加速功能的实现
            this.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    int keyCode=e.getKeyCode();
                    if(keyCode==KeyEvent.VK_F){
                        time=10;
                        timer.setDelay(time);//按下F时加速
                    }
                }
    
                @Override
                public void keyReleased(KeyEvent e) {
                    int keyCode=e.getKeyCode();
                    if(keyCode==KeyEvent.VK_F){
                        time=100;
                        timer.setDelay(time);//松开F键减速恢复默认速度
                    }
                }
            });
            //对定时器进行初始化,并实现监听器
                timer = new Timer(time, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        //当游戏处于开始状态且蛇活着时蛇活动,且后一节身子到前一节身子的位置上(每一节身子为25乘25像素)
                        if (isStart && isDied == false) {
                            //蛇身运动部分
                            for (int i = length - 1; i > 0; i--) {
                                snakeX[i] = snakeX[i - 1];
                                snakeY[i] = snakeY[i - 1];
                            }
                            //蛇头运动部分
                            if ("D".equals(direction)) {
                                snakeY[0] += 25;
                            }
                            if ("U".equals(direction)) {
                                snakeY[0] -= 25;
                            }
                            if ("L".equals(direction)) {
                                snakeX[0] -= 25;
                            }
                            if ("R".equals(direction)) {
                                snakeX[0] += 25;
                            }
                            //防止超出边界
                            if (snakeX[0] > 750) {
                                snakeX[0] = 25;
                            }
                            if (snakeX[0] < 25) {
                                snakeX[0] = 750;
                            }
                            if (snakeY[0] < 100) {
                                snakeY[0] = 725;
                            }
                            if (snakeY[0] > 725) {
                                snakeY[0] = 100;
                            }
                            //吃食物的动作,吃食物加10分且蛇身变长,蛇的速度提升10
                            if ((snakeX[0] == foodX && snakeY[0] == foodY)) {
                                length++;//蛇身长度加1
                                foodX = (new Random().nextInt(30) + 1) * 25;//随机生成X坐标[25,750]
                                foodY = (new Random().nextInt(26) + 4) * 25;//随机生成Y坐标[100,725]
                                score += 10;//吃一次食物积分加10
                                try {
                                    new HighestScore().highest();
                                } catch (IOException ioException) {
                                    ioException.printStackTrace();
                                }
                                if(time>10)
                                    timer.setDelay(time-=10);//吃一次食物速度增加10
                            }
                            //蛇的死亡机制判定
                            for (int i = 1; i < length; i++) {
                                if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                                    isDied = !isDied;
                                }
                            }
                            repaint();
                        }
                    }
                });
                timer.start();//定时器启动
        }
    
        //绘制面板部分
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            //填充背景颜色
            this.setBackground(new Color(164, 219, 246));
            //绘制初始蛇头的图片(默认右方朝向)
            Images.backImg.paintIcon(this,g,10,10);
            //调整画笔的颜色并绘制一个矩形面板
            g.setColor(new Color(219,226,219));
            g.fillRect(10,70,770,685);
            //蛇头的绘制;上下左右不同情况
            if("L".equals(direction)){
                Images.snakeLeftImg.paintIcon(this,g,snakeX[0],snakeY[0]);
            }
            if("R".equals(direction)){
                Images.snakeRightImg.paintIcon(this,g,snakeX[0],snakeY[0]);
            }
            if("U".equals(direction)){
                Images.snakeUpImg.paintIcon(this,g,snakeX[0],snakeY[0]);
            }
            if("D".equals(direction)){
                Images.snakeDownImg.paintIcon(this,g,snakeX[0],snakeY[0]);
            }
            //蛇身的绘制
            for(int i=1;i

    5.2.4 Start类

    页面的总体布局与程序的入口。

    package snakegame;
    
    import javax.swing.*;
    import java.awt.*;
    import java.io.IOException;
    
    //贪吃蛇总体界面布局以及程序的主方法
    public class Start {
        public static void main(String[] args) throws IOException {
            JFrame jf=new JFrame("贪吃蛇");
            //获取屏幕的大小,并使用数据使窗口位置居中
            int width= Toolkit.getDefaultToolkit().getScreenSize().width;
            int height= Toolkit.getDefaultToolkit().getScreenSize().height;
            jf.setBounds((width-800)/2,(height-800)/2,800,800);
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jf.setResizable(false);//设置窗口大小不能更改
            //添加GamePanel面板
            GamePanel panel=new GamePanel();
            jf.add(panel);
            jf.setVisible(true);
        }
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。