使用Java实现一个简单的贪吃蛇小游戏

article/2025/10/15 12:05:47

基于java实现贪吃蛇小游戏,主要通过绘制不同的图片并以一定速度一帧一帧地在窗体上进行展示。

开发工具:eclipse

java工具包:jdk1.8

一、创建新项目

创建一个新的项目,并命名。创建一个名为images的文件夹用来存放游戏相关图片。然后再在项目的src文件下创建一个com.xxx.view的包用来存放所有的图形界面类,创建一个com.xxx.controller的包用来存放启动的入口类(控制类)。如下所示;

二、主要的游戏界面

1.代码

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://chatgpt.dhexx.cn/article/6E4AAPIT.shtml

相关文章

Java贪吃蛇全代码

用Java编写精典小游戏——贪吃蛇&#xff01; 前言 我想贪吃蛇应该是不少90后和00后的童年&#xff08;我本人是01年的&#xff09;&#xff0c;回想起从前偷偷拿着我爹的诺基亚在被窝里玩贪吃蛇&#xff0c;不禁感慨万分&#xff0c;时间飞逝&#xff0c;没想到10年后的我也可…

JAVA小项目(四)—— 贪吃蛇【轻松入门,附源码】

目录 &#xff08;一&#xff09;效果图 &#xff08;二&#xff09;代码实现 &#xff08;1&#xff09;将图片加载到程序中 &#xff08;2&#xff09;创建窗体 &#xff08;3&#xff09;创建面板 &#xff08;4&#xff09;绘制静态的小蛇 &#xff08;5&#xff09; 加入监…

Java贪吃蛇大作战

作为Java新手小白&#xff0c;渴望学习一些好玩有趣的java程序 废话不多说&#xff0c;接下来我会一步一步实现java小程序&#xff1a;贪吃蛇大作战哦&#xff01; 实现 Java贪吃蛇一共分四个步骤&#xff1a; 1、画出窗体对象 2、绘制静态ui 3、使用鼠标监听器事件和定时器事…

Java简易小游戏贪吃蛇(Java实战)

这个版本的贪吃蛇我是跟着“黑马程序员”写的。小伙伴们可以跟着视频试着做一下&#xff0c;同时视频也会更详细。 B站学习链接&#xff1a;【黑马】两个小时带你用Java语言写一个贪吃蛇游戏【配套源码笔记】_哔哩哔哩_bilibili 相对于新手而言&#xff0c;贪吃蛇应该算是一个…

JAVA实现贪吃蛇游戏

本文实现的功能有: 1.绘制静态窗口 2.绘制游戏面板 3.绘制静态小蛇 4.通过键盘控制小蛇移动 5.吃食物 6.积分系统和失败判定 最近在学GUI&#xff0c;然后又有读者希望我写一下相关的实战。刚好博主在b站漫无目的的寻找着题材的时候看到了一个写贪吃蛇游戏的视频&#xff0c;于…

Java实现贪吃蛇大作战小游戏(完整版)

大家好&#xff0c;今天尝试用swing技术写一个贪吃蛇大作战小游戏&#xff0c;供大家参考。 效果展示 目录 效果展示 一、游戏界面 二、得分情况 项目介绍 项目背景 总体需求 实现过程 代码展示 主类 &#xff1a;Demo类 MyPanel类 ①构造方法 ②初始化方法 ③绘制方法…

用java写一个贪吃蛇小游戏(源码在最后)

一、引入 涉及技能&#xff1a; 循环、分支方法的抽取数组的使用面向对象继承&#xff0c;子类方法的重写接口&#xff0c;接口的实现GUI&#xff08;图像化界面编程&#xff09; GUI中的组件&#xff1a; 7.1 窗口 7.2 弹窗 7.3 面板 7.4 文本框 7.5 列表框 7.6 按钮 7.7 图…

安卓蓝牙开发总结(一)—蓝牙开启与关闭

蓝牙开启与关闭 1、引言2、布局文件3、蓝牙打开与关闭  3.1 通过对按钮监听方法  3.2 通过设置点击事件 4、结果展示及总结5、参考链接 1、引言 最近在学习如何在安卓手机上对蓝牙进行操控&#xff0c;作为初学者发现大多数博客对安卓开发的初学者极为不友好&#xff0c;特…

【Bluetooth|蓝牙开发】二、蓝牙开发入门

个人主页&#xff1a;董哥聊技术 我是董哥&#xff0c;嵌入式领域新星创作者 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; 【所有文章汇总】 1、蓝牙基础概念 蓝牙&#xff0c;是一种利用低功率无线电&#xff0c;支持设备短距离…

nimble 蓝牙开发一:BLE 蓝牙 Host 规范概述

目录 nimble 蓝牙开发一&#xff1a;概述一、BLE 简介二、BLE 基础知识蓝牙设备地址BLE 广播类型标准广播数据 三、BLE 工作概述BLE 常见的操作有&#xff1a;BLE 常见的工作流程&#xff1a; 四、BLE 使用的协议规范GAP1. GAP 工作角色2. GAP 工作模式3. GAP 工作流程4. GAP 工…

ESP32 蓝牙开发

1. 低功耗蓝牙&#xff08;BLE&#xff09;协议栈 低功耗蓝牙协议是蓝牙通信协议的一种&#xff0c;BLE协议栈就是实现低功耗蓝牙协议的代码 1.1 层次协议 蓝牙协议规定了两个层次的协议&#xff0c;分别为蓝牙核心协议&#xff08;Bluetooth Core&#xff09;和蓝牙应用层协…

Android蓝牙开发 — 经典蓝牙BLE蓝牙

一&#xff0c;前期基础知识储备 1&#xff09;蓝牙是一种支持设备之间短距离通信的无线电技术&#xff08;其他还包括红外&#xff0c;WIFI&#xff09;&#xff1b; 支持移动电话、笔记本电脑、无线耳机等设备之间进行信息的交换&#xff1b; Android支持的蓝牙协议栈&…

Android 蓝牙开发——概述(一)

一、蓝牙简介 蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术连接。 其中将1.x~3.0之间的版本称之为经典蓝牙,4.x开始的蓝牙称之为低功耗蓝牙,也就是蓝牙BLE。 1、蓝牙协议介绍…

低功耗蓝牙开发入门概念科普

一、概述 1、缘起 低功耗蓝牙起源于Bluetooth4.0版本&#xff0c;至今已发展到5.3 4.0 bluetooth low enerngy 这个阶段低功耗蓝牙的基础框架已经稳定成型&#xff0c;后面版本主要退出新特性和扩展特性&#xff0c;同时保证和4.0的原生兼容性 4.1 multi role&#xff08;主从…

ESP32开发三_蓝牙开发

蓝牙开发 交流QQ: 1048272975 QQ交流群: 636564526 蓝牙是一种不断创新发展的无线通信技术标准&#xff0c;采用了2.4G ISM频段&#xff0c;在音频传输、数据传输、位置服务、设备组网这些场景有着广泛的应用。 1. 蓝牙概述 蓝牙技术分经典蓝牙(Classic BT)和低…

iOS 蓝牙开发实现文件传输

这是一篇旧文&#xff0c;三年前就写过了&#xff0c;一直没有时间分享出来&#xff0c;最近简单整理了下&#xff0c;希望能帮到有需要的人。   由于我这里没有相关的蓝牙设备&#xff0c;主要用了两个手机&#xff0c;一个作为主设备&#xff0c;一个做为从设备。另外进行蓝…

Android经典蓝牙开发全流程

一、基本介绍 所谓蓝牙(Bluetooth)技术&#xff0c;实际上是一种短距离无线电技术&#xff0c;最初是由爱立信公司公司发明的。技术始于爱立信公司 1994 方案&#xff0c;它是研究在移动电话和其他配件间进行低功耗、低成本无线通信连接的方法。发明者希望为设备间的通讯创造一…

Android - 蓝牙开发

文章目录 科普SIG类型制式选择逻辑链路控制适配协议 (L2CAP)L2CAP的功能 蓝牙框架和 RFCOMM 协议蓝牙安全白名单机制 编程蓝牙权限Classic BluetoothBluetooth Low Energy术语角色 & 职能查找 BLE 设备连接设备上的 GATT 服务器绑定服务蓝牙设置连接到设备连接到 GATT 服务…

Android 蓝牙开发 uuid,Android蓝牙开发之 UUID

UUID&#xff1a;全球唯一标识符 在蓝牙中&#xff0c;每个Service和Characteristic都唯一地由"全球唯一标识符" (UUID)来校验&#xff0c;主要是保证他们的唯一性。 UUID可分为&#xff1a;16位、32位、128 位UUID Bluetooth_Base_UUID&#xff1a;蓝牙UUID基数 UUI…

Android 低功耗蓝牙开发简述

低功耗蓝牙简述 一、什么是低功耗蓝牙&#xff1f;二、怎么做低功耗蓝牙应用&#xff1f;① 之前有没有接触Android蓝牙开发&#xff1f;② 蓝牙设备固件是公司自己的吗&#xff1f;③ 有没有蓝牙固件和蓝牙应用的文档和Demo&#xff1f;④ 具体的业务功能需求明确吗&#xff1…