JAVA贪吃蛇代码(带注释)

JAVA贪吃蛇代码(带注释)贪吃蛇图片是代码里面的素材游戏数据类packagecom.tang.retor_snaker;importjavax.swing.*;importjava.net.URL;publicclassData{privatestaticURLbodyURL=Data.class.getResource(“/com/tang/retor_snaker/statics/body.png”);privatestaticImageIconbo

大家好,又见面了,我是你们的朋友全栈君。

贪吃蛇

这是游戏效果

在这里插入图片描述

图片是代码里面的素材

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

游戏数据类

package com.tang.retor_snaker;

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

public class Data { 
   
    private static URL bodyURL = Data.class.getResource("/com/tang/retor_snaker/statics/body.png");
    private static ImageIcon body = new ImageIcon(bodyURL);
    private static ImageIcon food = new ImageIcon(Data.class.getResource("/com/tang/retor_snaker/statics/food.png"));

    private static ImageIcon up = new ImageIcon(Data.class.getResource("/com/tang/retor_snaker/statics/up.png"));
    private static ImageIcon down = new ImageIcon(Data.class.getResource("/com/tang/retor_snaker/statics/down.png"));
    private static ImageIcon left = new ImageIcon(Data.class.getResource("/com/tang/retor_snaker/statics/left.png"));
    private static ImageIcon right = new ImageIcon(Data.class.getResource("/com/tang/retor_snaker/statics/right.png"));

    public static ImageIcon getBody() { 
   
        return body;
    }

    public static void setBody(ImageIcon body) { 
   
        Data.body = body;
    }

    public static ImageIcon getUp() { 
   
        return up;
    }

    public static void setUp(ImageIcon up) { 
   
        Data.up = up;
    }

    public static ImageIcon getDown() { 
   
        return down;
    }

    public static void setDown(ImageIcon down) { 
   
        Data.down = down;
    }

    public static ImageIcon getLeft() { 
   
        return left;
    }

    public static void setLeft(ImageIcon left) { 
   
        Data.left = left;
    }

    public static ImageIcon getRight() { 
   
        return right;
    }

    public static void setRight(ImageIcon right) { 
   
        Data.right = right;
    }

    public static ImageIcon getFood() { 
   
        return food;
    }

    public static void setFood(ImageIcon food) { 
   
        Data.food = food;
    }
}

游戏面板类

package com.tang.retor_snaker;

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

public class GamePanel extends JPanel implements KeyListener, ActionListener { 
   
    // 设置蛇头的方向
    String snakeHead;
    // 蛇的长度
    int length;
    int[] snakeX;
    int[] snakeY;
    // 游戏状态:开始=true - 停止=false
    boolean isStart = false;
    // 定时器:第一个参数就是定时执行时间
    Timer timer = new Timer(170, this);
    // 食物
    int foodX;
    int foodY;
    // 让食物出现的位置随机
    Random random = new Random();
    // 游戏是否结束:结束为=true - 游戏中=false
    boolean isFail = false;
    // 游戏是否胜利:胜利为true - 没胜利为false
    boolean isVictory = false;
    // 游戏分数
    int score;

    public GamePanel() { 
   
        // 初始化面板
        init();
        // 设置焦点事件
        this.setFocusable(true);
        // 给面板添加键盘监听事件
        this.addKeyListener(this);
        timer.start();
    }

    public void init() { 
   
        // 初始化蛇头向右
        snakeHead = "right";
        // 初始化蛇有三节,包括小脑袋
        length = 3;
        snakeX = new int[1000];
        snakeY = new int[1000];
        snakeX[0] = 75;
        snakeY[0] = 75;
        snakeX[1] = 50;
        snakeY[1] = 75;
        snakeX[2] = 25;
        snakeY[2] = 75;
        // 初始化实物数据
        foodX = 75 + 25 * random.nextInt(21);
        foodY = 75 + 25 * random.nextInt(19);
        // 让生成的食物不会和蛇重合
        for (int i = 0; i < length; i++) { 
   
            if (foodX == snakeX[i] && foodY == snakeY[i]) { 
   
                foodX = 75 + 25 * random.nextInt(21);
                foodY = 100 + 25 * random.nextInt(19);
                i = 0;
            }
        }

        // 初始化游戏分数
        score = 0;
    }

    // 画组件
    @Override
    protected void paintComponent(Graphics g) { 
   
        super.paintComponent(g);
        // 设置面板背景色
        this.setBackground(Color.white);
        // 绘制游戏区域
        g.fillRect(25, 50, 600, 575);
        // 绘制蛇头
        if (snakeHead.equals("up")) { 
   
            Data.getUp().paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if (snakeHead.equals("down")) { 
   
            Data.getDown().paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if (snakeHead.equals("left")) { 
   
            Data.getLeft().paintIcon(this, g, snakeX[0], snakeY[0]);
        } else if (snakeHead.equals("right")) { 
   
            Data.getRight().paintIcon(this, g, snakeX[0], snakeY[0]);
        }
        // 绘制蛇的身体
        for (int i = 1; i < length; i++) { 
   
            Data.getBody().paintIcon(this, g, snakeX[i], snakeY[i]);
        }
        // 画食物
        Data.getFood().paintIcon(this, g, foodX, foodY);
        // 绘制局内游戏信息
        g.setColor(Color.black);
        g.setFont(new Font("宋体", Font.BOLD, 15));
        g.drawString("长度:" + length, 25, 20);
        g.drawString("分数:" + score, 25, 40);
        // 绘制游戏暂停时的 提示信息
        if (!isStart) { 
   
            g.setColor(Color.white);
            g.setFont(new Font("楷体", Font.BOLD, 40));
            g.drawString("按下空格开始游戏!", 125, 300);
        }
        // 绘制游戏失败时的 提示信息
        if (isFail) { 
   
            g.setColor(Color.red);
            g.setFont(new Font("楷体", Font.BOLD, 40));
            g.drawString("失败,按下空格重新开始", 125, 300);
        }
        // 绘制游戏胜利时的 提示信息

        if (isVictory) { 
   
            g.setColor(Color.red);
            g.setFont(new Font("宋体", Font.BOLD, 35));
            g.drawString("胜利,你是为数不多的天才", 125, 300);
            g.drawString("按下空格重新开始新一轮游戏", 100, 350);
        }
    }

    // 键盘监听事件,某个键按下执行方法
    @Override
    public void keyPressed(KeyEvent e) { 
   
        /* 当用户按下空格时:先判断游戏有没有结束, 如果游戏结束那么就重新开始 如果游戏没有结束那么就继续原来的游戏 */
        if (e.getKeyCode() == KeyEvent.VK_SPACE) { 
   
            if (isFail || isVictory) { 
   
                isFail = false;
                isVictory = false;
                init();
            } else { 
   
                isStart = !isStart;
            }
            repaint();
        }
        // 让用户用键盘的上下左右键来操作蛇头,
        // 并且让蛇不能直接回头,当蛇在往上走,那么就不能立刻往下走
        if (e.getKeyCode() == KeyEvent.VK_UP) { 
   
            snakeHead = snakeHead.equals("down") ? "down" : "up";
        } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { 
   
            snakeHead = snakeHead.equals("up") ? "up" : "down";
        } else if (e.getKeyCode() == KeyEvent.VK_LEFT) { 
   
            snakeHead = snakeHead.equals("right") ? "right" : "left";
        } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) { 
   
            snakeHead = snakeHead.equals("left") ? "left" : "right";
        }
    }

    // 定时执行的操作
    @Override
    public void actionPerformed(ActionEvent e) { 
   
        // 如果游戏处于开始状态,并且没有结束,则小蛇可以移动
        if (isStart && !isFail && !isVictory) { 
   
            // 身体移动:右移:即让后一个移到前一个的位置即可!
            for (int i = length - 1; i > 0; i--) { 
   
                snakeX[i] = snakeX[i - 1];
                snakeY[i] = snakeY[i - 1];
            }
            // 头部移动,通过方向控制,;
            if (snakeHead.equals("right")) { 
   
                snakeX[0] = snakeX[0] + 25;
                if (snakeX[0] > 600) snakeX[0] = 25;
            } else if (snakeHead.equals("left")) { 
   
                snakeX[0] = snakeX[0] - 25;
                if (snakeX[0] < 25) snakeX[0] = 600;
            } else if (snakeHead.equals("up")) { 
   
                snakeY[0] = snakeY[0] - 25;
                if (snakeY[0] < 50) snakeY[0] = 600;
            } else if (snakeHead.equals("down")) { 
   
                snakeY[0] = snakeY[0] + 25;
                if (snakeY[0] > 600) snakeY[0] = 50;
            }
            // 吃食物:当蛇头和食物的坐标一致时,算吃到食物
            if (snakeX[0] == foodX && snakeY[0] == foodY) { 
   
                length++;
                // 每吃一个食物,增加10积分
                score = score + 10;
                // 长度等于300,游戏获胜
                // 当length到达一定的值,蛇移动的速度就变快
                if (length == 300) { 
   
                    isVictory = true;
                } else if (length == 25) { 
   
                    timer = new Timer(145, this);
                } else if (length == 50) { 
   
                    timer = new Timer(125, this);
                } else if (length == 100) { 
   
                    timer = new Timer(100, this);
                } else if (length == 200) { 
   
                    timer = new Timer(70, this);
                }
                // 重新生成食物
                foodX = 75 + 25 * random.nextInt(21);
                foodY = 75 + 25 * random.nextInt(19);
                // 让生成的食物不会和蛇重合
                for (int i = 0; i < length; i++) { 
   
                    if (foodX == snakeX[i] && foodY == snakeY[i]) { 
   
                        foodX = 75 + 25 * random.nextInt(21);
                        foodY = 75 + 25 * random.nextInt(19);
                        i = 0;
                    }
                }
            }
            // 结束判断,头和身体的坐标一致时,游戏结束
            for (int i = 2; i < length; i++) { 
   
                if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) { 
   
                    System.out.println(Arrays.toString(snakeX));
                    System.out.println(Arrays.toString(snakeY));
                    isFail = true;
                }
            }
            // 需要不断的更新页面实现动画
            repaint();
        }
        // 让时间动起来!
        timer.start();
    }

    @Override
    public void keyTyped(KeyEvent e) { 
   

    }

    @Override
    public void keyReleased(KeyEvent e) { 
   

    }

}

主程序

package com.tang.retor_snaker;

import javax.swing.*;

public class RetroSnakeGame { 
   
    public static void main(String[] args) { 
   
        // 创建窗口
        JFrame frame = new JFrame("贪吃蛇");
        // 固定窗口大小
        frame.setResizable(false);
        // 设置窗口出现位置和大小
        frame.setBounds(300,300,675,675);
        // 让窗口可关闭
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 添加游戏面板的组件
        frame.add(new GamePanel());
        // 设置窗口可见性
        frame.setVisible(true);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141523.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 资源网站(电驴替代方案)

    资源网站(电驴替代方案) 0、http://www.emule-project.net/这个不用说了,emule官方,没有它就没有下面的所有一切,德国人开的。只提供官方版emule软件,没有资源下载。秉承理念“eMule是完全免费的,它也决不包含广告软件、间谍和流氓软件。我们之所以创造eMule是为了快乐和知识,而不是为了金钱。”eMule的作者是一个德国人Merkur,本名Hendrik.Breitk…

    2022年7月15日
    20
  • vuethink 配置

    vuethink 配置

    2021年10月11日
    67
  • android之R cannot be resolved to a variable

    刚才又遇到了R cannot be resolved to a variable的问题,就翻了翻网上的资料,调理的整理了一下1. 检查Android 的SDK是否丢失需要重新下载,检查build path,把需要导入的JAR包确认都导入成功2. 确保class没有import Android.R,注意是不能有Android.R,可以有其他R文件,比如你自己的包;3. 错误cla

    2022年3月9日
    64
  • MongoDB和Redis的区别是什么

    MongoDB和Redis的区别是什么

    2022年2月20日
    53
  • eclipse离线安装svn插件使用教程_eclipse导入svn项目

    eclipse离线安装svn插件使用教程_eclipse导入svn项目最近要在eclipse上安装一个svn插件,本来以为是很简单的一件事,没想到尝试了很多方法,还是各种不成功以下是网上常见的解决方案:第一种(失败):help->EclipseMarketplace在线安装结果:下载不下来,换一个版本的插件安装成功,但连接仓库会提示0x00400006第二种(失败):help->InstallNewSoftware手动在线安装:给的地址是类似这样的:http://subclipse.tigris.org/update_1.8…

    2022年10月14日
    4
  • 面试官,不要再问我三次握手和四次挥手「建议收藏」

    面试官,不要再问我三次握手和四次挥手「建议收藏」三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。见过比较典型的面试场景是这样的:面试官:请介绍下三次握手求职者:第一次握手就是客户端给服务器端发送一个报文,第二次就是服务器收到报文之后,会应答一个报文给客户端,第三次握手就是客户端收到报文后再给服务器发送一个报文,三次握手就…

    2022年4月29日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号