Java实现贪吃蛇游戏

news/2024/12/24 10:44:10/

目录

一、项目结构

二、实现步骤

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 对象,代表蛇的身体部位。

java">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 类用于表示游戏中的食物。每次蛇吃到食物后,食物都会重新出现在一个随机的位置。

java">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 类是游戏的核心,负责管理游戏状态、更新界面和处理游戏逻辑。

java">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 类负责启动游戏窗口,并启动游戏的主循环。

java">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.ppmy.cn/news/1557719.html

相关文章

云技术基础知识(二):虚拟化与容器技术

内容预览 ≧∀≦ゞ 虚拟化与容器技术虚拟化技术一、虚拟化的核心概念二、虚拟化的主要类型1. 服务器虚拟化2. 操作系统虚拟化&#xff08;容器化&#xff09;3. 网络虚拟化4. 存储虚拟化 三、虚拟化的实现方法和工具1. 服务器虚拟化实现2. 操作系统虚拟化&#xff08;容器化&am…

最新雷蛇鼠标键盘驱动Razer Synapse 4(雷云) 下载与安装

雷蛇最近更新了驱动程序&#xff0c;Razer Synapse 4&#xff08;雷云&#xff09; 拥有全新的多线程架构&#xff0c;速度提高了 30%*。通过简化的界面体验无与伦比的速度、流畅性和稳定性&#xff0c;使用户能够快速导航&#xff0c;实现独立安装和精确设置配置。 更新一&am…

gitlab克隆仓库报错fatal: unable to access ‘仓库地址xxxxxxxx‘

首次克隆仓库&#xff0c;失效了&#xff0c;上网查方法&#xff0c;都说是网络代理的问题&#xff0c;各种清理网络代理后都无效&#xff0c;去问同事&#xff1a; 先前都是直接复制的网页url当做远端url&#xff0c;或者点击按钮‘使用http克隆’ 这次对于我来说有效的远端u…

使用FreeNAS软件部署ISCSI的SAN架构存储(IP-SAN)练习题

一&#xff0c;实验用到工具分别为&#xff1a; VMware虚拟机&#xff0c;安装教程&#xff1a;VMware Workstation Pro 17 安装图文教程 FreeNAS系统&#xff0c;安装教程&#xff1a;FreeNAS-11.2-U4.1安装教程2024&#xff08;图文教程&#xff09; 二&#xff0c;新建虚…

Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果,Kotlin(2)

Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果&#xff0c;Kotlin&#xff08;2&#xff09; 在 Android使用PorterDuffXfermode的模式PorterDuff.Mode.SRC_OUT实现橡皮擦&#xff0c;Kotlin&#xff08;1&#xff09;-CSDN博客文章浏览阅…

实战设计模式之抽象工厂模式

概述 前一篇文章中提到的工厂方法模式允许子类决定具体要创建的对象类型&#xff0c;但它一次只创建一个对象。抽象工厂模式则更加复杂&#xff0c;它关注的是创建一系列相关的对象。这些对象通常构成了一个完整的“家族”&#xff0c;并且在不同的实现中保持一致性和兼容性。 …

基于自定义注解与 AOP 切面实现接口日志全面数据库存储

基于自定义注解与 AOP 切面实现接口日志全面数据库存储 一、引言 在当今复杂的软件系统开发与运维过程中&#xff0c;详细且精准地记录接口的各项信息对于系统性能监测、问题排查、安全审计以及业务分析都有着极为关键的意义。本文将深入讲解如何运用自定义注解与 AOP&#x…

C# Winform简单的俄罗斯方块小游戏源码2

文章目录 一、设计来源俄罗斯方块小游戏讲解1.1 主界面1.2 游戏界面1.3 游戏结束界面1.4 游戏积分界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载更多优质源码分享 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/…