首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >JDK17实现超级马里奥游戏+完整版最新源码

JDK17实现超级马里奥游戏+完整版最新源码

原创
作者头像
家庭Q秋-3993387644
发布2025-07-09 23:14:23
发布2025-07-09 23:14:23
3270
举报

hello大家好,用java实现小游戏真的很锻炼编程技术,而且很有成就感。比起做增删改查的管理系统来说,简直是不同的两个阶层的程序员。

今天我就教大家用JDK17原生库来实现一个完整的 超级马里奥 ,初始编程的你,只要用心就能学会。会大大加深你对面向对象的理解!

源码为自己开发的源码, 商用必究!!!

源码很简单,不难,不要怕!!!能了解思想速成编程大师(不仅仅是java噢)

从这个游戏中你可以学到:

1. 场景是如何跟随玩家移动的(摄像机概念)。

2. 游戏关卡是如何在数据库中配置的(以后新增关卡只需在数据库中插入数据)。

3. 马里奥,红砖,蘑菇等游戏实体的管理。

4. 2D游戏的分层架构: 画图+逻辑管理器+实体 。

5. 游戏内的物理系统:碰撞检测,边界检测, 垂直重力加速度, 水平的惯性等。

视频演示

图片演示

技术栈描述

项目框架

- Java SE 17 - 主要编程语言 - Swing - GUI框架(JFrame、JPanel、Timer等) - Java 2D API - 图形渲染(Graphics2D、BufferedImage) - Java Sound API - 音效处理(Clip、AudioSystem) - Maven - 项目构建管理 - JDBC - 数据库连接

关键技术特性

- 双缓冲渲染 - 消除画面闪烁 - 60 FPS游戏循环 - 流畅的游戏体验 - 资源缓存机制 - 图片和音效缓存 - 多线程音频 - 并发音效播放

设计模式

1. 单例模式 (Singleton Pattern)

应用场景:

- `GameManager` :游戏核心管理器 - `ImageLoader` :图片资源管理器 - `SoundManager` :声音管理器 - `DatabaseConfig` :数据库配置类 - `LayerManager` :层级渲染管理器

优势: 确保全局只有一个实例,便于资源管理和状态控制。

2. 工厂模式 (Factory Pattern)

应用场景:

- `PlantManagerExt` 中的 plantPlant 方法根据 PlantType 枚举创建不同类型的植物对象 - 根据植物类型(向日葵、豌豆射手、坚果墙等)动态创建相应的植物实例 优势: 封装对象创建逻辑,便于扩展新的植物类型。

3. 策略模式 (Strategy Pattern)

应用场景:

- `GameObject` 抽象类定义了 update() 和 render() 抽象方法 - 不同的植物类( `Sunflower` 、 `Peashooter` 等)实现不同的行为策略 优势: 每种植物都有自己独特的行为逻辑,易于维护和扩展。

4. 观察者模式 (Observer Pattern)

应用场景:

- 游戏事件处理系统,如鼠标点击事件通过 `MouseListenerManagerExt` 分发给各个游戏实体 - 游戏状态变化时通知相关组件更新

5. 模板方法模式 (Template Method Pattern)

应用场景:

- `GameObject` 基类定义了游戏对象的通用结构和行为模板 - 子类重写特定方法实现自己的逻辑,如 update() 、 render() 等

6. 外观模式 (Facade Pattern)

应用场景:

- `DrawManagerExt` 提供统一的绘制接口,封装了复杂的渲染逻辑 - 各种 ManagerExt 类为复杂的游戏逻辑提供简化的接口

7. 组合模式 (Composite Pattern)

应用场景:

- 游戏场景中的层级结构,通过 `LayerManager` 管理不同渲染层级的对象 - 统一处理单个对象和对象集合的渲染

8. 命令模式 (Command Pattern)

应用场景:

- 游戏中的各种操作(种植植物、收集阳光等)被封装成具体的方法调用 - 便于实现撤销、重做等功能

9. 状态模式 (State Pattern)

应用场景:

- 游戏状态管理(游戏中、暂停、结束、胜利)通过 `Constants.java` 中定义的状态常量进行切换 - 不同状态下游戏有不同的行为表现

10. 享元模式 (Flyweight Pattern)

应用场景:

- `ImageLoader` 使用缓存机制避免重复加载相同的图片资源 - `SoundManager` 缓存音频资源

游戏实现的功能

1. 玩家控制系统

- 马里奥角色控制 : `Mario` 类实现了完整的玩家控制 - 移动机制 : 左右移动、跳跃、滑行、摩擦力模拟 - 物理系统 : 重力、速度、碰撞检测等真实物理效果 - 键盘输入 : 支持上下左右方向键控制移动,空格键射击

2. 角色形态系统

- 小马里奥 : 初始形态,碰到敌人会死亡 - 大马里奥 : 吃蘑菇后变大,有更强的生存能力 - 射击的马里奥 : 吃花道具后获得射击能力 - 形态转换 : 支持不同形态间的动态切换和动画效果

3. 道具系统

- 蘑菇道具 : `Mushroom` - 使马里奥变大或获得额外生命 - 花道具 : `Flower` - 赋予马里奥射击能力 - 道具砖块 : `PowerUpBrick` - 问号砖块,撞击后产生道具 - 金币系统 : 砖块中隐藏金币,收集后增加分数

4. 敌人系统

- 敌人类 : `Enemy` 实现了智能敌人行为 - 自动移动 : 敌人会自动左右移动巡逻 - 碰撞反应 : 遇到障碍物会自动转向 - 攻击机制 : 与马里奥碰撞时造成伤害 - 被击败 : 可被马里奥踩踏或子弹击中消灭

5. 射击系统

- 子弹发射 : `Bullet` 实现火球射击功能 - 弹道物理 : 子弹具有重力、弹跳效果 - 射击冷却 : 防止连续射击的冷却机制 - 敌人击中 : 子弹可以击败敌人

6. 碰撞检测系统

- 精确碰撞 : `DamageCheckManagerExt` 实现全面的碰撞检测 - 多层碰撞 : 马里奥与地形、敌人、道具的碰撞 - 方向判断 : 能够判断碰撞的方向(上下左右) - 物理反应 : 根据碰撞方向产生相应的物理反应

7. 音效系统

- 背景音乐 : `SoundManager` 管理所有音频 - 音效播放 : 跳跃、收集道具、击败敌人等动作音效 - 音量控制 : 支持背景音乐和音效的独立开关 - 音频缓存 : 优化音频加载和播放性能

8. 关卡系统

关卡的配置都是在数据库里面,主要分为以下表:

levels表: 配置了主关卡信息,包括关卡 名称,世界长度,马里奥生命条数,背景乐。

bricks表: 砖块表, 包括了: x,y坐标,连续有多少块砖。第多少块砖有硬币等。

enemys表: 移动的敌人表,包括了: x,y左边, 移动速度等。

grounds表: 地面表, 类似于砖块, 没有隐藏道具,无法死亡。

pips表: 静态的下水管道。

power_bricks表: 道具砖块表, 里面可以顶出 蘑菇,花道具。

目前游戏只有2关,后续可以直接在表中插入数据配置关卡场景。无需改动任何代码。

游戏实现原理

本小结将讲解游戏中各大类的具体功能,每个类都是实现游戏不可或缺的部分,他们紧密相连来实现一个完整的游戏系统。

数据库加载关卡

DatabaseManager 类是连接数据库的核心,里面加载了db.properties得到数据库信息,然后连接数据库。然后通过LevelManager类去加载数据库指定关卡的数据。

代码语言:javascript
复制
/**
 * 开始指定关卡
 */
public boolean startLevel(int levelNumber) {
    // 加载关卡
    this.levels = databaseManager.getLevelByNumber(Levels.class, levelNumber);
    System.out.println("加载关卡:" + levels);
    if (this.levels == null) {
        return false;
    }
    // 加载地面砖块
    this.grounds = databaseManager.getLevelByLevelId(Grounds.class, levelNumber);
    // 加载 金币道具砖块
    this.bricks = databaseManager.getLevelByLevelId(Bricks.class, levelNumber);
    // 特色道具砖块
    this.powerBricks = databaseManager.getLevelByLevelId(PowerBricks.class, levelNumber);
    this.enemys = databaseManager.getLevelByLevelId(Enemys.class, levelNumber);
    this.pips = databaseManager.getLevelByLevelId(Pips.class, levelNumber);


    this.currentLevelNumber = levelNumber;
    return true;
}

游戏循环的启动

点击开始游戏时会初始化 GameFrame 类,这个就是游戏的主界面,里面有一个 GamePanel ,就是游戏内容画图的核心。在GamePanel 的里面有一个循环定时器,就是游戏的主循环位置:

代码语言:javascript
复制
/**
 * 开始游戏循环
 */
public void startGameLoop() {
    if (gameTimer == null || !running) {
        gameManager.startGame(1);
        running = true;

        // 创建Timer,每隔FRAME_DELAY毫秒执行一次
        gameTimer = new Timer(FRAME_DELAY, e -> {
            if (running) {
                // 更新游戏逻辑
                try {
                    gameManager.update();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                // 重绘画面
                repaint();
            }
        });
        gameTimer.start();
    }
}

游戏循环的逻辑很清晰, 就是先更新一些逻辑数据,比如玩家的坐标值,敌人,子弹的状态,是否死亡等等。然后调用 repaint(); 方法去画图,就会执行当前类的画图逻辑:

代码语言:javascript
复制
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    // 清空后缓冲
    backGraphics.setColor(Color.BLACK);
    backGraphics.fillRect(0, 0, Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT);

    // 根据游戏状态绘制不同内容
    switch (gameManager.getGameState()) {
        case Constants.GAME_STATE_PLAYING:
            drawGame(backGraphics);
            break;
        case Constants.GAME_STATE_PAUSED:
            drawGame(backGraphics);
            drawPauseOverlay(backGraphics);
            break;
        case Constants.GAME_STATE_GAME_OVER:
            drawGameOver(backGraphics);
            break;
        case Constants.GAME_STATE_VICTORY:
            drawVictory(backGraphics);
            break;
    }

    // 将后缓冲绘制到屏幕
    g.drawImage(backBuffer, 0, 0, null);
}

/**
 * 绘制游戏画面
 */
private void drawGame(Graphics2D g2d) {
    // 绘制游戏实体
    DrawManagerExt.onDraw(g2d);
}

画图的逻辑就是获取到所有的游戏实体,然后调用实体自身的 render方法进行画图(传递了Graphics 用来画图的对象 )。

植游戏统一的碰撞检测

为了统一碰撞检测,我们将所有游戏实体的碰撞放到了 DamageCheckManagerExt 里面,这样作不仅仅提高了效率,还便于统一管理:

代码语言:javascript
复制
/**
 * 检查所有碰撞
 */
public static void check() {
    GameManager gameManager = GameManager.getInstance();
    Mario mario = gameManager.getMario();
    if (mario == null || !mario.isAlive()) {
        return;
    }

    // 重置地面状态,将在碰撞检测中重新设置
    mario.setOnGround(false);

    // 检查马里奥与地面的碰撞
    checkMarioGroundCollision(mario, gameManager.getGrounds());

    // 检查马里奥与砖块的碰撞
    checkMarioBrickCollision(mario, gameManager.getBricks());
 
    // 检查马里奥与道具砖块的碰撞
    checkMarioPowerUpBrickCollision(mario, gameManager.getPowerUpBricks());
 
    // 检查马里奥与道具的碰撞
    checkMarioPowerUpCollision(mario, gameManager.getPowerUps());
 
    // 检查道具与地形的碰撞
    checkPowerUpTerrainCollision(gameManager.getPowerUps(), gameManager.getGrounds(), gameManager.getBricks(), gameManager.getPowerUpBricks());
 
    // 检查子弹与地形的碰撞
    checkBulletTerrainCollision(gameManager.getBullets(), gameManager.getGrounds(), gameManager.getBricks(), gameManager.getPowerUpBricks());
 
    // 检查敌人与地形的碰撞
    checkEnemyTerrainCollision(gameManager.getEnemies(), gameManager.getGrounds(), gameManager.getBricks(), gameManager.getPowerUpBricks());
 
    // 检查敌人与马里奥的碰撞
    checkEnemyMarioCollision(gameManager.getEnemies(), mario);
 
    // 检查子弹与敌人的碰撞
    checkBulletEnemyCollision(gameManager.getBullets(), gameManager.getEnemies());
 
    // 检查马里奥与管道的碰撞
    checkMarioPipeCollision(mario, gameManager.getPipes());
 
    // 检查敌人与管道的碰撞
    checkEnemyPipeCollision(gameManager.getEnemies(), gameManager.getPipes());
 
    // 检查子弹与管道的碰撞
    checkBulletPipeCollision(gameManager.getBullets(), gameManager.getPipes());
 
    // 检查马里奥与终点屋的碰撞
    checkMarioFinishHouseCollision(mario, gameManager.getFinishHouses());

    // 检测 马里奥是否掉出 窗外
    checkY(mario);
}

游戏还涉及到很多有趣的设计,比如: 马里奥的子弹的轨迹和障碍物的回弹,马里奥本人的水平移动惯性和垂直掉落时的加速度等待,我就不一一讲解了,大家可以跟着源码来打开新世界的大门。。。

游戏启动

将源码导入到idea中,这个项目就是一个普通的maven管理的项目, 导入前,请设置好maven的仓库配置。

设置好JDK的环境为17

用navicate工具连接数据库,新建数据库,然后执行sql创建表:

数据库的版本用8就可以了。

修改数据库配置db.properties:

等待编译好,启动Main就可以了。游戏图片,声音素材资源在resource目录下面。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 视频演示
  • 图片演示
  • 技术栈描述
    • 项目框架
    • 关键技术特性
    • 设计模式
      • 1. 单例模式 (Singleton Pattern)
      • 2. 工厂模式 (Factory Pattern)
      • 3. 策略模式 (Strategy Pattern)
      • 4. 观察者模式 (Observer Pattern)
      • 5. 模板方法模式 (Template Method Pattern)
      • 6. 外观模式 (Facade Pattern)
      • 7. 组合模式 (Composite Pattern)
      • 8. 命令模式 (Command Pattern)
      • 9. 状态模式 (State Pattern)
      • 10. 享元模式 (Flyweight Pattern)
  • 游戏实现的功能
    • 1. 玩家控制系统
    • 2. 角色形态系统
    • 3. 道具系统
    • 4. 敌人系统
    • 5. 射击系统
    • 6. 碰撞检测系统
    • 7. 音效系统
    • 8. 关卡系统
  • 游戏实现原理
    • 数据库加载关卡
    • 游戏循环的启动
    • 植游戏统一的碰撞检测
  • 游戏启动
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档