Java实现贪吃蛇游戏

目录

一、项目结构

二、实现步骤

1. 创建 Snake 类

2. 创建 Food 类

3. 创建 GameBoard 类

4. 创建 SnakeGame 类

三、总结

贪吃蛇是一个经典的电子游戏,它的玩法非常简单,但又充满了挑战。玩家通过控制蛇的移动,吃到食物并不断成长,目标是尽可能长时间生存。本文将介绍如何使用 Java 实现一个简单的贪吃蛇游戏。我们将重点展示游戏的核心实现,包括蛇的移动、碰撞检测、食物生成等功能。

一、项目结构

本项目将使用 Java 的图形用户界面库 javax.swing 来创建界面,利用 KeyListener 监听键盘输入。整体的项目结构如下:

- SnakeGame.java        // 游戏主程序,启动游戏窗口
- GameBoard.java        // 游戏面板,包含游戏逻辑和绘制
- Snake.java            // 贪吃蛇类,控制蛇的移动和行为
- Food.java             // 食物类,用于生成和管理食物

二、实现步骤

1. 创建 Snake 类

首先,我们创建 Snake 类来控制贪吃蛇的行为。蛇是由一系列的方块构成,每个方块可以看作是一个 Point 对象,代表蛇的身体部位。

import java.awt.Point;
import java.util.LinkedList;public class Snake {private LinkedList<Point> body;private int direction; // 方向 0 - 上, 1 - 右, 2 - 下, 3 - 左private boolean growing; // 是否在增长public Snake(int startX, int startY) {body = new LinkedList<>();body.add(new Point(startX, startY));direction = 1; // 初始方向向右growing = false;}// 获取蛇的身体public LinkedList<Point> getBody() {return body;}// 获取蛇的头部public Point getHead() {return body.getFirst();}// 控制蛇的移动public void move() {Point head = getHead();Point newHead = null;// 根据方向移动蛇头switch (direction) {case 0: newHead = new Point(head.x, head.y - 1); break; // 向上case 1: newHead = new Point(head.x + 1, head.y); break; // 向右case 2: newHead = new Point(head.x, head.y + 1); break; // 向下case 3: newHead = new Point(head.x - 1, head.y); break; // 向左}// 向蛇的身体前端添加新头部body.addFirst(newHead);if (!growing) {// 如果没有增长,移除尾部body.removeLast();} else {// 如果正在增长,保持尾部不变growing = false;}}// 蛇吃到食物后增长public void grow() {growing = true;}// 检查蛇是否与自己相撞public boolean hasCollided() {Point head = getHead();for (int i = 1; i < body.size(); i++) {if (head.equals(body.get(i))) {return true;}}return false;}// 检查蛇是否撞墙public boolean hasHitWall(int width, int height) {Point head = getHead();return head.x < 0 || head.x >= width || head.y < 0 || head.y >= height;}// 改变蛇的方向public void setDirection(int newDirection) {// 防止蛇直接掉头if (Math.abs(direction - newDirection) != 2) {direction = newDirection;}}
}

2. 创建 Food 类

Food 类用于表示游戏中的食物。每次蛇吃到食物后,食物都会重新出现在一个随机的位置。

import java.awt.Point;
import java.util.Random;public class Food {private Point position;public Food(int width, int height) {// 随机生成食物的位置Random rand = new Random();position = new Point(rand.nextInt(width), rand.nextInt(height));}// 获取食物的位置public Point getPosition() {return position;}// 重置食物的位置public void relocate(int width, int height) {Random rand = new Random();position.setLocation(rand.nextInt(width), rand.nextInt(height));}
}

3. 创建 GameBoard 类

GameBoard 类是游戏的核心,负责管理游戏状态、更新界面和处理游戏逻辑。

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;public class GameBoard extends JPanel {private Snake snake;private Food food;private boolean gameOver;private int score;private int boardWidth = 30;private int boardHeight = 20;private final int tileSize = 20;public GameBoard() {snake = new Snake(5, 5);food = new Food(boardWidth, boardHeight);score = 0;gameOver = false;// 设置键盘监听addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {if (gameOver) return;int keyCode = e.getKeyCode();if (keyCode == KeyEvent.VK_UP) {snake.setDirection(0);} else if (keyCode == KeyEvent.VK_RIGHT) {snake.setDirection(1);} else if (keyCode == KeyEvent.VK_DOWN) {snake.setDirection(2);} else if (keyCode == KeyEvent.VK_LEFT) {snake.setDirection(3);}}});setFocusable(true);}// 更新游戏状态public void update() {if (gameOver) return;// 移动蛇snake.move();// 检查蛇是否撞墙或自咬if (snake.hasHitWall(boardWidth, boardHeight) || snake.hasCollided()) {gameOver = true;return;}// 检查蛇是否吃到食物if (snake.getHead().equals(food.getPosition())) {snake.grow();score++;food.relocate(boardWidth, boardHeight);}repaint();}// 绘制游戏界面@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);// 绘制游戏边界g.setColor(Color.BLACK);g.fillRect(0, 0, boardWidth * tileSize, boardHeight * tileSize);// 绘制蛇g.setColor(Color.GREEN);for (Point p : snake.getBody()) {g.fillRect(p.x * tileSize, p.y * tileSize, tileSize, tileSize);}// 绘制食物g.setColor(Color.RED);g.fillRect(food.getPosition().x * tileSize, food.getPosition().y * tileSize, tileSize, tileSize);// 绘制游戏状态if (gameOver) {g.setColor(Color.WHITE);g.setFont(new Font("Arial", Font.BOLD, 30));g.drawString("Game Over! Score: " + score, 50, boardHeight * tileSize / 2);}}
}

4. 创建 SnakeGame 类

SnakeGame 类负责启动游戏窗口,并启动游戏的主循环。

import javax.swing.*;public class SnakeGame {public static void main(String[] args) {JFrame frame = new JFrame("贪吃蛇");GameBoard gameBoard = new GameBoard();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(gameBoard.getPreferredSize());frame.add(gameBoard);frame.setVisible(true);// 游戏主循环while (true) {gameBoard.update();try {Thread.sleep(100); // 控制游戏速度} catch (InterruptedException e) {e.printStackTrace();}}}
}

三、总结

通过上述代码,我们成功实现了一个简单的贪吃蛇游戏。这个实现涵盖了游戏的基本逻辑,包括蛇的控制、食物的生成、碰撞检测和游戏结束条件。你可以在此基础上进一步扩展功能,比如增加难度设置、得分排行榜、音效和动画等。

贪吃蛇不仅是一个有趣的游戏,也是学习编程的一项经典练习。通过实现这个项目,你可以深入理解 Java 图形界面编程、事件处理以及基本的面向对象设计思想。

希望这篇文章能够帮助你实现自己的贪吃蛇游戏,也欢迎在评论区分享你的修改和优化建议!

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

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

相关文章

构建高性能异步任务引擎:FastAPI + Celery + Redis

在现代应用开发中&#xff0c;异步任务处理是一个常见的需求。无论是数据处理、图像生成&#xff0c;还是复杂的计算任务&#xff0c;异步执行都能显著提升系统的响应速度和吞吐量。今天&#xff0c;我们将通过一个实际项目&#xff0c;探索如何使用 FastAPI、Celery 和 Redis …

go面试问题

1 Go的内存逃逸如何分析 go build -gcflags-m main_pointer.go 2 http状态码 300 请求的资源可包括多个位置&#xff0c;相应可返回一个资源特征与地址的列表用于用户终端&#xff08;例如&#xff1a;浏览器&#xff09;选择 301 永久移动。请求的资源已被永久的移动到新U…

JVM性能优化一:初识内存泄露-内存溢出-垃圾回收

本文主要是让你充分的认识到什么叫做内存泄露&#xff0c;什么叫做内存溢出&#xff0c;别再傻傻分不清了&#xff0c;别再动不动的升级服务器的内存了。 文章目录 1.基本概念1.1.内存泄露1.2.内存溢出1.3.垃圾回收1.4.内存泄露-垃圾回收-内存溢出三者的关系关系 2.代码示例2.…

安装milvus以及向量库增删改操作

首先电脑已经安装了docker windows电脑可下载yml文件 https://github.com/milvus-io/milvus/releases/download/v2.4.6/milvus-standalone-docker-compose.yml 创建milvus文件夹&#xff0c;并在这个目录下创建五个文件夹&#xff1a;conf、db、logs、pic、volumes、wal 然后…

ARP..

ARP 0 前言 真正接触到现网才发现ARP十分重要&#xff0c;无论是排错还是S-MLAG都需要用到ARP这个协议&#xff0c;以前对于ARP的理解比较混乱&#xff1b;所以这次对其中的主要内容做个梳理&#xff1b;一定要学好ARP&#xff01;&#xff01;&#xff01; 1 ARP的概念 Ar…

单片机上电后程序不运行怎么排查问题?

1.电源检查。使用电压表测量单片机的电源电压是否正常&#xff0c;确保电压在规定的范围内&#xff0c;如常见的5V。 2.复位检查。检查复位引脚的电压是否正常&#xff0c;在单片机接通电源时&#xff0c;复位引脚通常会有一个高电平&#xff0c;按下复位按钮时&#xff0c;复位…

SKETCHPAD——允许语言模型生成中间草图,在几何、函数、图算法和游戏策略等所有数学任务中持续提高基础模型的性能

概述 论文地址&#xff1a;https://arxiv.org/pdf/2406.09403 素描是一种应用广泛的有效工具&#xff0c;包括产生创意和解决问题。由于素描能直接传达无法用语言表达的视觉和空间信息&#xff0c;因此从古代岩画到现代建筑图纸&#xff0c;素描在世界各地被用于各种用途。儿童…

Linux应用开发————mysql数据库表

mysql数据库表操作 查看表的结构 mysql> desc / describe 表名; 或者&#xff1a; mysql> show create table 表名; 常见数据库引擎&#xff1a; innodb, myISAM... 删除表 mysql> drop tabl…

【C#】实现Json转Lua (Json2Lua)

关键词: C#、JsonToLua、Json2Lua、对象序列化Lua 前提需引入NewtonsofJson&#xff0c;引入方法可先在Visual Studio 2019 将Newtonsoft.Json.dll文件导入Unity的Plugins下。 Json格式字符串转Lua格式字符串&#xff0c;效果如下&#xff1a; json字符串 {"1": &q…

2.4 网络概念(分层、TCP)

网络层与传输层概述 网络层&#xff1a; 抽象概念&#xff1a;网络层是基于 IP 的抽象概念&#xff0c;与数据链路层用 MAC 地址标记设备不同。MAC 地址是一种具体化的概念&#xff0c;绑定于所在的物理网络&#xff0c;而 IP 地址可以是固定的&#xff0c;也可以通过路由动态…

LabVIEW伸缩臂参数监控系统

LabVIEW开发伸缩臂越野叉车参数监控系统主要应用于工程机械中的越野叉车&#xff0c;以提高车辆的作业效率和故障诊断能力。系统通过PEAK CAN硬件接口和LabVIEW软件平台实现对叉车作业参数的实时监控和故障分析&#xff0c;具有良好的实用性和推广价值。 系统组成 系统主要由P…

多目标优化常用方法:pareto最优解

生产实际中的许多优化问题大都是多目标问题&#xff0c;举个例子&#xff1a;我们想换一份工资高、压力小、离家近的新工作&#xff0c;这里工资高、压力小、离家近就是我们的目标&#xff0c;显然这是一个多目标问题&#xff0c;那我们肯定想找到这三个目标同时最优的工作&…

跨站脚本攻击的多种方式——以XSS-Labs为例二十关详解解题思路

一、XSS-Labs靶场环境搭建 1.1、XSS介绍 跨站脚本攻击&#xff08;XSS&#xff09;_跨站脚本测试-CSDN博客https://coffeemilk.blog.csdn.net/article/details/142266454 1.2、XSS-Labs XSS-Labs是一个学习XSS攻击手法的靶场&#xff0c;方便我们系统性的学习掌握跨站脚本攻击…

【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)

一、RAGFlow简介 RAGFlow是一个基于对文档深入理解的开源RAG&#xff08;Retrieval-augmented Generation&#xff0c;检索增强生成&#xff09;引擎。 主要作用&#xff1a; 让用户创建自有知识库&#xff0c;根据设定的参数对知识库中的文件进行切块处理&#xff0c;用户向大…

54、库卡机器人轴的软限位设置

步骤1&#xff1a;将用户组改为“专家”。 步骤2&#xff1a;点击“投入运行”----“售后服务”-----“软件限位开关” 步骤3&#xff1a;就可以针对每个轴修改对应的角度值&#xff0c;然后点击“保存”。

0基础学前端-----CSS DAY9

0基础学前端-----CSS DAY9 视频参考&#xff1a;B站Pink老师 今天是CSS学习的第九天&#xff0c;今天开始的笔记对应Pink老师课程中的CSS第四天的内容。 本节重点&#xff1a;常见网页布局以及清除浮动 2. 常见网页布局 2.1 常见网页布局 有以下三种&#xff1a; 参考代码…

【自动化】Python SeleniumUtil 工具 开启开发者模式 自动安装油猴用户脚本等

【自动化】Python SeleniumUtil 工具 【Python】使用Selenium 操作浏览器 自动化测试 记录-CSDN博客文章浏览阅读58次。文章浏览阅读42次。【附件】Selenium chromedriver 驱动及浏览器下载。【附件】Selenium chromedriver 驱动及浏览器下载-CSDN博客。3.安装Chrome浏览器驱动…

UE5 移植Editor或Developer模块到Runtime

要将源码中的非运行时模块移植到Runtime下使用&#xff0c;个人理解就是一个解决编译报错的过程&#xff0c;先将目标模块复制到项目的source目录内&#xff0c;然后修改模块文件夹名称&#xff0c;修改模块.build.cs与文件夹名称保持一致 修改build.cs内的类名 &#xff0c;每…

全志H618 Android12修改doucmentsui选中图片资源详情信息

背景: 由于当前的文件管理器在我们的产品定义当中,某些界面有改动的需求,所以需要在Android12 rom中进行定制以符合当前产品定义。 需求: 进入file文件管理器后,点击选中图片资源,选中功能按钮,获取信息,不显示“调试信息(仅开发者)”;现状是,获取信息,显示“调试信…

【WPS安装】WPS编译错误总结:WPS编译失败+仅编译成功ungrib等

WPS编译错误总结&#xff1a;WPS编译失败仅编译成功ungrib等 WPS编译过程问题1&#xff1a;WPS编译失败错误1&#xff1a;gfortran: error: unrecognized command-line option ‘-convert’; did you mean ‘-fconvert’?解决方案 问题2&#xff1a;WPS编译三个exe文件只出现u…