Java贪吃蛇源码:零基础也能懂的实战代码
很多初学者一听到“Java”和“游戏开发”,脑海里浮现的往往是庞大的Spring Boot架构或者复杂的微服务系统。
其实,写一个贪吃蛇小游戏,比配置一个Spring环境要简单得多。
它不需要数据库,不需要网络请求,甚至不需要安装任何IDE的高级插件。
只需要一个文本编辑器(比如记事本),加上JDK,你就能在屏幕上让一条蛇动起来。
今天不聊高深理论,咱们直接上手。我会把核心逻辑拆解得碎碎的,保证你哪怕没写过图形界面程序,也能看懂每一行代码在干什么。
为什么是Java?
你可能会问,Python几行代码就能搞定,为什么还要用Java这种“重型语言”?
因为Java是强类型语言,它的思维方式更接近计算机底层逻辑。
通过Java写贪吃蛇,你能直观地理解面向对象编程(OOP)的核心概念:封装、继承、多态。
比如,“蛇”是一个对象,“食物”也是一个对象,它们各自有属性(颜色、坐标)和行为(移动、生成)。
这种结构化的训练,对你后续学习任何大型项目都有极大的帮助。
说白了,这就是你的第一块“磨刀石”。
准备战场:Swing组件
Java自带的Swing库虽然老旧,但对于做这种控制台之上的图形界面来说,足够用了。
你不需要引入任何第三方JAR包,开箱即用。
核心类就两个:JFrame(窗口)和JPanel(画板)。
你可以把JFrame想象成一个相框,把JPanel想象成里面的画纸。
我们要做的所有绘制工作,都在这张“画纸”上进行。
import javax.swing.*;
import java.awt.*;
public class SnakeGame extends JFrame { public SnakeGame() { setTitle("Java贪吃蛇 - 零基础实战"); setSize(400, 400); // 窗口大小400x400像素 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); // 窗口居中显示 // 创建游戏面板并添加到窗口 add(new GamePanel()); }
public static void main(String[] args) { SwingUtilities.invokeLater(() -> { new SnakeGame().setVisible(true); }); } } ```
这段代码非常直白:设置标题、大小、关闭操作,然后把我们自定义的GamePanel塞进去。
注意最后一行SwingUtilities.invokeLater,这是Swing编程的黄金法则:确保UI操作发生在事件调度线程上,防止界面卡死。 的微服务系统
灵魂所在:游戏面板与绘图
真正的游戏逻辑,藏在我们刚才提到的GamePanel里。
这里我们需要重写paintComponent方法。
每次屏幕需要刷新时,Java都会调用这个方法,让我们重新绘制画面。
这就好比翻书,每一页都是新的,但上一页的内容如果没擦掉,就会留下痕迹。
所以,我们在每一帧开始时,必须先清空背景。
接着,我们要画格子、画蛇、画食物。
为了简化逻辑,我们把整个游戏区域看作一个网格。
假设每个格子是25x25像素,那么400x400的窗口就是16x16的网格。
class GamePanel extends JPanel implements ActionListener, KeyListener {
private final int BOARD_WIDTH = 400;
private final int BOARD_HEIGHT = 400;
private final int UNIT_SIZE = 25; // 单个格子大小
private final int GAME_UNITS = (BOARD_WIDTH * BOARD_HEIGHT) / (UNIT_SIZE * UNIT_SIZE);
// 游戏状态
private boolean running = false;
private Timer timer;
public GamePanel() { setPreferredSize(new Dimension(BOARD_WIDTH, BOARD_HEIGHT)); setBackground(Color.BLACK); setFocusable(true); // 允许接收键盘输入 addKeyListener(this); startGame(); }
public void startGame() { running = true; timer = new Timer(100, this); // 每100毫秒刷新一次 timer.start(); }
@Override public void paintComponent(Graphics g) { super.paintComponent(g); draw(g); }
private void draw(Graphics g) { if (running) { // 这里先画简单的方块,后续再细化为蛇身 for(int i=0; i
看,Timer是关键。它像一个节拍器,每隔100毫秒触发一次actionPerformed事件。
在这个事件里,我们更新蛇的位置,检测碰撞,然后重绘画面。
这就是游戏循环的本质:更新状态 -> 渲染画面 -> 等待下一帧。
让蛇动起来:方向与移动
现在,蛇还只是一个静态的背景网格。
我们需要给它加点“脑子”。
蛇的移动依赖于方向键(上下左右)。
在Java中,我们通过KeyListener来捕获按键事件。
当用户按下箭头键时,我们改变蛇的移动方向。
但是,这里有一个经典的Bug陷阱:如果蛇正在向右移动,用户瞬间按下左键,蛇会直接掉头撞到自己,导致游戏结束。
为了防止这种情况,我们需要判断新方向是否与当前方向相反。
private char direction = 'R'; // R:Right, L:Left, U:Up, D:Down
@Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_LEFT: if(direction != 'R') direction = 'L'; break; case KeyEvent.VK_RIGHT: if(direction != 'L') direction = 'R'; break; case KeyEvent.VK_UP: if(direction != 'D') direction = 'U'; break; case KeyEvent.VK_DOWN: if(direction != 'U') direction = 'D'; break; } } ```
这只是第一步。真正的移动逻辑在actionPerformed里。
我们需要维护一个队列来存储蛇身的坐标。
每次移动时,我们在头部添加一个新的点,并根据方向计算其位置。
同时,移除尾部的那个点(除非吃到了食物)。
这就好比一个人排队走路,头往前走一步,尾巴也跟着走一步,队伍长度不变。
如果吃到了食物,尾巴就不走了,队伍变长。
// 简化的逻辑示意
public void actionPerformed(ActionEvent e) {
if(running) {
move();
checkCollisions();
repaint();
}
}
private void move() { // 假设snakeBody是一个Deque
你看,逻辑并不复杂。
核心就在于坐标的计算和队列的操作。
Deque(双端队列)是Java集合框架中的好帮手,它支持在两端高效地添加和删除元素,非常适合模拟蛇的身体。
碰撞检测与游戏结束
蛇撞墙了吗?蛇撞自己了吗?
这些都需要在每一帧进行判断。
最简单的判断就是看蛇头的坐标是否超出了游戏区域的边界。
private void checkCollisions() {
// 检查撞墙
Point head = snakeBody.getFirst();
if(head.x < 0 || head.x >= BOARD_WIDTH ||
head.y < 0 || head.y >= BOARD_HEIGHT) {
running = false;
}
// 检查撞自己
// 从索引1开始遍历,因为0是头
for(int i = 1; i < snakeBody.size(); i++) {
if(head.x == snakeBody.get(i).x &&
head.y == snakeBody.get(i).y) {
running = false;
}
}
if(!running) {
timer.stop();
}
}
一旦running变为false,定时器停止,画面不再刷新。
此时,我们可以绘制“Game Over”文字,提示玩家重新开始。
这个过程虽然简单,但涵盖了游戏开发中最核心的状态管理逻辑。
给零基础的你的建议
写代码就像学骑自行车,看十遍教程不如摔几次跤。
这个贪吃蛇源码可能看起来只有几十行,但它包含了事件驱动、图形绘制、集合操作和逻辑判断等多个重要知识点。
建议你先把代码复制到IDE里,运行起来,看看效果。
然后,尝试修改参数:
把UNIT_SIZE改成50,看看蛇是不是变大了?
把Timer间隔改成50,看看速度是不是变快了?
再试着加一点分数显示,或者改变蛇的颜色。
通过这些微小的改动,你会逐渐建立起对Java GUI编程的直觉。
不要害怕报错。
每一个Exception都是你在和计算机对话的机会。
当你看到那一条绿色的蛇在黑色背景上灵活游走时,那种成就感是无可替代的。
这就是编程的魅力,从零到一,创造属于你的逻辑世界。
掌握Java贪吃蛇的编写逻辑,你就跨过了GUI编程的第一道门槛。
接下来,试着扩展功能,比如增加暂停键或计分板,你会发现编程的乐趣才刚刚开始。