贪吃蛇游戏


一、创建新项目
创建一个新的项目,并命名。

创建一个名为images的文件夹用来存放游戏相关图片。

然后再在项目的src文件下创建一个com.xxx.view的包用来存放所有的图形界面类,

创建一个com.xxx.controller的包用来存放启动的入口类(控制类)

二、游戏界面 

package com.snake.view;import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;public class SnakeJPanel extends JPanel implements ActionListener{private boolean start;//当前游戏状态private int speed;//速度private boolean exist;//当前是否存在食物private int foodType;//食物种类private int x;//豆子的横坐标private int y;//豆子的纵坐标private ArrayList<int[]> localList;//蛇public String direction;//方向private String direction2;//引导方向public boolean flag;Random rand = new Random();private ImageIcon up;private ImageIcon down;private ImageIcon right;private ImageIcon left;private ImageIcon body;private ImageIcon food;private ImageIcon title;Timer time;private int score;//当前得分情况private int num;//吃到的食物个数//    private Image offScreenImage;  //图形缓存//图片绘制@Overridepublic void paint(Graphics g) {direction = direction2;g.setColor(Color.WHITE);g.fillRect(0, 0, 900, 700);//绘制游戏框//标题框
//        g.drawRect(25, 30, 800, 75);title.paintIcon(this, g, 25, 10);//内容框g.setColor(Color.black);g.fillRect(25, 75, 850, 600);//绘制食物的坐标位置if(!exist) {//如果当前不存在豆子,随机绘制一个豆子    if(num % 5 == 0) {foodType = 1;}else {foodType = 0;}boolean isProduce = true;while(isProduce) {isProduce = false;x = rand.nextInt(33) * 25 + 25;        y = rand.nextInt(23) * 25 + 75;            for (int[] arr:localList) {if(x == arr[0] && y == arr[1]) {    isProduce = true;break;    }}}            System.out.println(x + "---" + y);}if(eat()) {exist = false;}else {exist = true;}if(foodType == 0) {//绘制食物g.setColor(Color.blue);
//            g.fillRect(x, y, 25, 25);g.drawImage(food.getImage(),x, y, 25, 25,null);}else {//绘制食物g.setColor(Color.WHITE);g.fillRect(x, y, 25, 25);
//            g.drawImage(food.getImage(),x, y, 25, 25,null);}//绘制头g.setColor(Color.red);
//        g.fillRect(localList.get(0)[0], localList.get(0)[1], 25, 25);    ImageIcon head = null;//判断当前方向if(direction.equals("R")) {head = right;}else if(direction.equals("L")) {head = left;}else if(direction.equals("U")) {head = up;}else if(direction.equals("D")) {head = down;}        
//        g.drawImage(head.getImage(), localList.get(0)[0], localList.get(0)[1], 25, 25,null);head.paintIcon(this, g,localList.get(0)[0], localList.get(0)[1]);//绘制身体g.setColor(Color.white);for (int i = 1; i < localList.size(); i++) {
//            g.fillRect(localList.get(i)[0], localList.get(i)[1], 25, 25);
//            g.drawImage(body.getImage(), localList.get(i)[0], localList.get(i)[1], 25, 25,null);body.paintIcon(this, g, localList.get(i)[0], localList.get(i)[1]);}
//        g.fillRect(localList.get(1)[0], localList.get(1)[1], 25, 25);
//        g.fillRect(localList.get(2)[0], localList.get(2)[1], 25, 25);//绘制分数和长度//长度g.setColor(Color.GREEN);g.setFont(new Font("宋体", Font.BOLD, 18));g.drawString("长度:" + (localList.size() - 1), 25, 30);//分数g.drawString("分数:" + score, 25, 48);if(!start) {//如果游戏未启动,结束移动和重绘g.setColor(Color.white);g.setFont(new Font("宋体", Font.BOLD, 30));g.drawString("暂停/开始(请按任意键开始,空格键暂停)", 150, 300);time.stop();}else {time.start();}//        speed();//移动后进行下一次绘制        
//      move();//移动
//        repaint();//重新绘制        }//    //解决闪烁问题
//    //如果为JFrame 为重量级  程序不会调用update()方法
//    //如果为Frame 为轻量级  重写update()方法 做双缓冲
//    //如果为JPanel 不会闪烁
//      @Override
//        public void update(Graphics g)
//        {
//            System.out.println("update");
//               if(offScreenImage == null)
//                  offScreenImage = this.createImage(900, 700);  //新建一个图像缓存空间,这里图像大小为800*600
//                  Graphics gImage = offScreenImage.getGraphics();  //把它的画笔拿过来,给gImage保存着
//                  paint(gImage);                                   //将要画的东西画到图像缓存空间去
//                  g.drawImage(offScreenImage, 0, 0, null);         //然后一次性显示出来
//        }@Overridepublic void actionPerformed(ActionEvent e) {        //移动后进行下一次绘制        move();//移动repaint();//重新绘制        }/*** 绘制速度*/
//    private void speed() {
//        try {//按一定速度进行移动
//            Thread.sleep(speed);//控制移动速度
//        } catch (InterruptedException e) {
//            // TODO 自动生成的 catch 块
//            e.printStackTrace();
//        }
//    }/*** 初始化图片*/private void drawImage() {up = new ImageIcon("images/up.png");down = new ImageIcon("images/down.png");right = new ImageIcon("images/right.png");left = new ImageIcon("images/left.png");body = new ImageIcon("images/body.png");food = new ImageIcon("images/food.png");title = new ImageIcon("images/title.jpg");}private boolean eat() {if(localList.get(0)[0] == x && localList.get(0)[1] == y) {//如果当前蛇头吃到了豆子System.out.println("eat");num++;if(foodType == 0) {score += 10;}else {score += (rand.nextInt(5) * 10 + 10);}int last = localList.size() - 1;//蛇尾            //在蛇尾后面添加一节身体localList.add(new int[] {localList.get(last)[0],localList.get(last)[1]});return true;}return false;}//移动方法public void move() {//判断是否游戏结束if(isbody()) {System.out.println("game over");start = false;//结束游戏移动JOptionPane.showMessageDialog(null,"游戏已结束!");time.stop();init();        }if(flag && localList != null) {//如果长度不为空且游戏未结束                int last = localList.size() - 1;//记录蛇尾for (int i = last; i > 0; i--) {//从蛇尾开始,每节身体移动到前一节身体的位置上localList.set(i,new int[] {localList.get(i - 1)[0],localList.get(i - 1)[1]});}//记录头位置int[] local = localList.get(0);//判断当前方向,并进行模拟移动,判断是否与边界重合if(direction.equals("R")) {if(local[0] >= 850) {local[0] = 25;}else {local[0] += 25;}}else if(direction.equals("L")) {if(local[0] <= 25) {local[0] = 850;}else {local[0] -= 25;}}else if(direction.equals("U")) {if(local[1] <= 75) {local[1] = 650;}else {local[1] -= 25;}}else if(direction.equals("D")) {if(local[1] >= 650) {local[1] = 75;}else {local[1] += 25;}}            //更改头的位置localList.set(0, local);        }    }//判断下一步是否为蛇身private boolean isbody() {// TODO 自动生成的方法存根//记录头位置int x = localList.get(0)[0];int y = localList.get(0)[1];//判断当前方向,并进行模拟移动,判断是否与边界重合if(direction.equals("R")) {x += 25;}else if(direction.equals("L")) {x -= 25;}else if(direction.equals("U")) {y -= 25;}else if(direction.equals("D")) {y += 25;}            for (int i = 1; i < localList.size(); i++) {if(localList.get(i)[0] == x && localList.get(i)[1] == y) {return true;}}return false;}//    //判断下一步是否为边界
//    private boolean isborder() {
//        // TODO 自动生成的方法存根
//        //记录头位置
//        // TODO 自动生成的方法存根
//        //记录头位置
//        int x = localList.get(0)[0];
//        int y = localList.get(0)[1];
//
//        //判断当前方向,并进行模拟移动,判断是否与边界重合
//        if(direction.equals("R")) {
//            x += 25;
//        }else if(direction.equals("L")) {
//            x -= 25;
//        }else if(direction.equals("U")) {
//            y -= 25;
//        }else if(direction.equals("D")) {
//            y += 25;
//        }    
//                
//        if(x < 25 || x > (33 * 25 + 25)) {
//            return true;//当x坐标超出边界,则返回true
//        }
//        if(y < 105 || y > (23 * 25 + 105)) {
//            return true;//当y坐标超出边界,则返回true
//        }
//        return false;//蛇头移动后未超出边界,返回false
//        
//    }/*** Create the frame.*/public SnakeJPanel(int speed) {this.speed = speed; //初始化速度//初始化游戏面板的基本信息this.setSize(900, 700);this.setLocation(0, 30);this.setFocusable(true);init();//初始化界面drawImage();//绘制图片moveByKey();//给界面添加一个键盘监听}/** 键盘监听* 通过键盘输入上下左右来控制当前蛇头移动的方向* 先判断当前蛇头方向,再来改变引导方向* 当进行绘制时再修改蛇的方向* 保证不会因为在短时间内快速变换方向导致蛇头逆向转向*/private void moveByKey() {addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {int key = e.getKeyCode();//边界值判断switch(key) {case 65:case 37:{//向左走if(!direction.equals("R")) {direction2 = "L";}break;}                case 87:case 38:{//向上走if(!direction.equals("D")) {direction2 = "U";}                break;}                case 68:case 39:{//向右走if(!direction.equals("L")) {direction2 = "R";}break;}case 83:case 40:{//向下走if(!direction.equals("U")) {direction2 = "D";}                    break;}case KeyEvent.VK_SPACE:{//如果当前键盘输入为空格start = !start;//调整游戏状态System.out.println("暂停/开始");repaint();//重绘}}//任意键开始if(!start && key != KeyEvent.VK_SPACE) {//如果当前状态为暂停状态,且键盘输入不是空格start = true;repaint();//重绘}                }});}/*** 初始化游戏基本信息*/private void init() {start = false;exist = true;direction2 = "U";flag = true;localList = new ArrayList<int[]>();localList.add(0,new int[] {75,125});//蛇头localList.add(1,new int[] {75,150});//蛇身1localList.add(2,new int[] {75,175});//蛇身2//创建第一个食物的位置//通过循环保证当前生成的食物不在身体所在的坐标上boolean isProduce = true;while(isProduce) {//循环生成食物坐标isProduce = false;//结束本次循环x = rand.nextInt(33) * 25 + 25;        y = rand.nextInt(23) * 25 + 75;            for (int[] arr:localList) {//循环遍历蛇头及蛇身的坐标if(x == arr[0] && y == arr[1]) {//如果食物坐标和蛇的某一节坐标重合isProduce = true;//跳转循环状态,继续下一次食物生成break;    }}//蛇身遍历完成,没有重合坐标,结束食物坐标生成}time = new Timer(speed, this);setLayout(null);score = 0;num = 0;foodType = 0;//        repaint();}}

三、构造启动类

package com.snake.controller;import javax.swing.JFrame;
import javax.swing.JOptionPane;import com.snake.view.SnakeJPanel;public class SnakeStart {public static void main(String[] args) {int speed = 0;String showInputDialog = null;//初始化时间//得到速度while(true) {showInputDialog = JOptionPane.showInputDialog("蛇移动速度(1 - 5)","3");if(showInputDialog == null) {showInputDialog = "3";//默认速度break;}if(showInputDialog.length() > 1) {continue;}char[] a = showInputDialog.toCharArray();if(a[0] >= '1' && a[0] <= '5') {break;}}speed = Integer.parseInt(showInputDialog) * 50;SnakeJPanel snakeJPanel = new SnakeJPanel(speed);//创建一个JFrame窗口,将游戏面板添加进行窗口中JFrame jFrame = new JFrame();//设置窗口的某些属性jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jFrame.setSize(920, 750);jFrame.add(snakeJPanel);jFrame.setLocationRelativeTo(null);jFrame.setVisible(true);}}

四、游戏启动
设置游戏速度

游戏界面

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

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

相关文章

Kafka 集群如何实现数据同步?

哈喽大家好&#xff0c;我是咸鱼 最近这段时间比较忙&#xff0c;将近一周没更新文章&#xff0c;再不更新我那为数不多的粉丝量就要库库往下掉了 T﹏T 刚好最近在学 Kafka&#xff0c;于是决定写篇跟 Kafka 相关的文章&#xff08;文中有不对的地方欢迎大家指出&#xff09;…

Unity2021及以上 启动或者禁用自动刷新

Unity 2021以以上启动自动刷新 Edit---> Preferences--> Asset Pipline --> Auto Refresh 禁用的结果 如果不启动自动刷新在Project面板选择Refresh是不会刷新已经修改后的脚本的。

数据挖掘复盘——apriori

read_csv函数返回的数据类型是Dataframe类型 对于Dataframe类型使用条件表达式 dfdf.loc[df.loc[:,0]2]df: 这是一个DataFrame对象的变量名&#xff0c;表示一个二维的表格型数据结构&#xff0c;类似于电子表格或SQL表。 df.loc[:, 0]: 这是使用DataFrame的.loc属性来进行…

一文了解Word2vec 阐述训练流程

一文了解Word2vec 阐述训练流程 个性嵌入&#xff08;Personality Embeddings&#xff09; 词嵌入&#xff08;Word Embeddings&#xff09; 嵌入向量效果分析 语言模型 模型介绍 模型训练 Word2vec训练方法 CBOW方法 Skip-gram方法 CBOW方法与Skip-gram方法总结 重构…

nodejs+vue慢性胃炎健康管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计

随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于慢性胃炎健康管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了慢性胃炎健康管理系统&#xff0c; 系统首页、个…

AtCoder Beginner Contest 329 题解A~F

A - Spread 输入字符串&#xff0c;字符之间加上空格输出 B - Next 输出数组当中第二大的数 C - Count xxx 统计每个字符出现过的最长长度&#xff0c;再累加即可 #include<bits/stdc.h> #pragma GCC optimize("Ofast") #define INF 0x3f3f3f3f #define I…

【面试经典150 | 算术平方根】

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;数学表达式方法二&#xff1a;二分法 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并…

广州华锐互动VRAR:VR教学楼地震模拟体验增强学生防震减灾意识

在当今社会&#xff0c;地震作为一种自然灾害&#xff0c;给人们的生活带来了巨大的威胁。特别是在学校这样的集体场所&#xff0c;一旦发生地震&#xff0c;后果将不堪设想。因此&#xff0c;加强校园安全教育&#xff0c;提高师生的防震减灾意识和能力&#xff0c;已经成为了…

Python编程技巧 – 使用字符串(Strings)

Python编程技巧 – 使用字符串&#xff08;Strings) Python Programming Essentials – Using Strings 本文简要介绍如何使用字符串&#xff0c;来进行Python编程。字符串有很多用途&#xff0c;包括输出结果、反馈状态、数据处理以及切片和文本筛选等 1. 字符串 字符串(St…

详解自动化测试之 Selenium

目录 1. 什么是自动化 2.自动化测试的分类 3. selenium&#xff08;web 自动化测试工具&#xff09; 1&#xff09;选择 selenium 的原因 2&#xff09;环境部署 3&#xff09;什么是驱动&#xff1f; 4. 一个简单的自动化例子 5.selenium 常用方法 5.1 查找页面元素&…

基于SSM的北海旅游网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

nodejs微信小程序-实验室上机管理系统的设计与实现-安卓-python-PHP-计算机毕业设计

用户&#xff1a;管理员、教师、学生 基础功能&#xff1a;管理课表、管理机房情况、预约机房预约&#xff1b;权限不同&#xff0c;预约类型不同&#xff0c;教师可选课堂预约和个人&#xff1b;课堂预约。 目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 …

2023.11.18 每日一题(AI自生成应用)【C++】【Python】【Java】【Go】 动态时间序列分析

目录 一、编程挑战&#xff1a;动态时间序列分析 实际应用&#xff1a; 实现提示&#xff1a; 二、实现 1. C 2. Python 3. JAVA 4. Go 一、编程挑战&#xff1a;动态时间序列分析 问题描述&#xff1a; 假设你是一名软件工程师&#xff0c;需要开发一个应用来分析和预…

asp.net心理健康管理系统VS开发sqlserver数据库web结构c#编程计算机网页项目

一、源码特点 asp.net 心理健康管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 系统视频链接 https://www.bilibili.com/video/BV19w411H7P4/ 二、功能介绍 本系统使用Microsoft Visual Studio…

初识Linux:目录的创建销毁

目录 ​编辑 提示&#xff1a;以下指令均在Xshell 7 中进行 零、桌面的本质 &#x1f4bb; 扩展&#x1f387;&#xff1a; 一、cd指令&#xff1a; 1、cd - &#xff1a; 2、cd ~&#xff1a; 重命名命令&#xff1a;alias 二、stat指令 冷知识&#xff1a; 如果…

SpringCloud总结

注&#xff1a;本文并不涉及具体功能是怎么实现的&#xff0c;而只是微服务技术栈的整体总结和理解。 目录 一.基础概念--认识微服务 1.单体架构 2.分布式架构 3.微服务 4.SpringCloud 二.服务的拆分原则 三.RestTemplate--实现不同服务之间的通信与远程调用 四.Eurek…

代码随想录算法训练营第二十八天| 78 子集 90 子集|| 93 复原IP地址

78 子集 由题意可知数组中的元素互不相同&#xff0c;所以在dfs中我们可以将当前的path直接加入到res中。 class Solution {List<List<Integer>>res new ArrayList<>();List<Integer>path new LinkedList<>();public List<List<Integer…

系列一、JVM概述

一、概述 1.1、Java发展中的重大事件 1.2、虚拟机 vs Java虚拟机 1.2.1、虚拟机 1.2.2、Java虚拟机 1.2.3、Java虚拟机的作用 Java虚拟机是二进制字节码的运行环境&#xff0c;负责装载字节码到其内部&#xff0c;解释/编译为对应平台上的机器指令指令。每一条Java指令&#…

鸿蒙:使用Stack、ContentTable、Flex等组件和布局实现一个显示界面

效果展示 一.概述 跟随官网继续HarmonyOS学习 本篇博文实现一个食物详情页的开发Demo 通过这个开发过程学习如何使用容器组件Stack、Flex和基本组件Image、Text&#xff0c;构建用户自定义组件&#xff0c;完成图文并茂的食物介绍 二.构建Stack布局 1.食物名称 创建Stack…

【Dubbo】Dubbo负载均衡实现解析

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…