1. 项目概述与核心价值最近在整理过往的项目资料翻到了一个几年前用 libgdx 引擎开发的 ACE 弹幕射击游戏项目。这个项目当时是为了验证一个想法能否用一套代码在保证性能的前提下快速开发出具有复杂弹幕逻辑和流畅手感的移动端射击游戏。最终的结果是令人满意的项目不仅成功在 Android 上跑了起来其核心架构和设计思路对于今天想入门游戏开发或者想从 Unity 等引擎转向更底层、更可控框架的朋友来说依然有很高的参考价值。简单来说这是一个基于 libgdx 框架为 Android 平台量身定制的纵版弹幕射击游戏STG。它不只是一个简单的“打飞机”Demo而是包含了完整的游戏循环、敌机波次生成、复杂的弹幕模式设计、碰撞检测、分数系统以及资源管理。对于开发者而言这个项目的价值在于它完整地展示了如何利用 libgdx 这个轻量级但强大的框架从零开始构建一个游戏的所有核心模块尤其是如何处理 STG 游戏中最具特色的“弹幕”系统。无论你是想学习 libgdx 的实战应用还是想深入了解 2D 游戏开发中的实体管理、状态机和性能优化这个项目都能提供一个清晰的蓝本。2. 技术选型为什么是 LibGDX在开始动手之前技术栈的选择是决定项目成败和开发体验的关键。市面上有 Unity、Cocos、Godot 等诸多成熟的游戏引擎为什么偏偏选择了 LibGDX这背后是基于几个非常实际的考量。2.1 跨平台与原生性能的平衡LibGDX 是一个用 Java 编写的游戏开发框架而非一个带有可视化编辑器的完整引擎。它的核心优势在于“轻量”和“可控”。它通过一套统一的 API抽象了底层的图形OpenGL ES、音频、输入和文件 I/O 操作。这意味着你写的核心游戏逻辑代码只需要极少的修改就可以部署到桌面Windows, Linux, Mac、Android、iOS通过 RoboVM甚至 Web通过 GWT。对于 ACE 这个项目我们的首要目标是 Android但保不齐未来想发布到 Steam 或者做个网页版LibGDX 提供了这种可能性而无需重写核心代码。更重要的是性能。像 Unity 这样的引擎虽然功能强大但对于一个纯粹的 2D 像素风或矢量风弹幕游戏来说其运行时开销有时显得“过重”。LibGDX 让你更接近“金属”你可以精细地控制渲染批次SpriteBatch、纹理管理甚至直接调用 OpenGL 指令进行优化。在弹幕射击游戏中屏幕上同时可能存在数百甚至上千个子弹实体对渲染效率的要求极高。LibGDX 的轻量级特性使得我们能够实现更高效的实体管理和绘制确保在低端 Android 设备上也能维持 60 FPS 的流畅体验。2.2 开发环境与学习曲线LibGDX 使用 Java或 Kotlin作为开发语言这对于广大的 Android 应用开发者来说入门门槛相对较低。你不需要去学习 C# 或引擎特定的脚本语言。开发环境可以是你熟悉的 Android Studio 或 IntelliJ IDEA调试体验与开发普通应用无异。框架本身提供了清晰的项目模板通过官方的gdx-setup工具能快速生成包含桌面启动器和 Android 模块的项目结构省去了大量配置时间。框架的架构也非常清晰。它没有强制的“场景-节点”树状结构而是提供了ApplicationListener接口或更常用的Game和Screen类来管理游戏生命周期用SpriteBatch进行绘制用ShapeRenderer绘制几何图形用AssetManager管理资源。这种设计给了开发者极大的自由度去组织自己的游戏架构比如采用经典的实体组件系统ECS或者更简单的面向对象模型。对于 ACE 项目我们采用了基于状态机的实体管理结合面向对象的设计这在后续会详细展开。2.3 针对弹幕游戏的特殊优势弹幕射击游戏有几个技术特点大量小型对象的快速生成与销毁、精确到像素的碰撞检测、复杂的运动轨迹计算。LibGDX 在这方面有天然优势对象池PoolingLibGDX 内置了Pool类可以极大地优化子弹、敌机等频繁创建销毁的对象性能避免 GC 卡顿。数学库com.badlogic.gdx.math包提供了强大的向量Vector2、矩形Rectangle、圆形Circle以及碰撞检测方法非常适合用来计算子弹位置、敌机移动路径和碰撞。粒子系统Particle Editor虽然 ACE 的核心是弹幕但爆炸、击中特效等也必不可少。LibGDX 自带一个可视化的粒子编辑器可以方便地创建和加载华丽的粒子效果。灵活的渲染你可以轻松地实现图层如背景层、子弹层、敌机层、UI层管理以及自定义的着色器Shader来为弹幕添加发光、扭曲等高级视觉效果。基于以上几点LibGDX 成为了开发 ACE 弹幕射击游戏的不二之选。它提供了足够的“轮子”让我们快速起步又保留了足够的“底层”让我们能针对游戏类型进行深度优化。3. 核心架构设计与模块拆解一个可维护、易扩展的游戏项目离不开良好的架构。在 ACE 项目中我们没有采用过于复杂的 ECS 框架而是设计了一个清晰分层的、基于状态机的面向对象架构这更适合中小型团队或个人开发者快速迭代。整个项目可以划分为以下几个核心模块。3.1 游戏状态与屏幕管理LibGDX 推荐使用Game和Screen接口来管理游戏的不同状态。在 ACE 中我们创建了以下几个主要的ScreenLoadingScreen加载屏幕游戏启动后第一个屏幕使用AssetManager异步加载所有纹理、音效、字体、粒子效果等资源。同时显示一个进度条提升用户体验。MainMenuScreen主菜单屏幕包含开始游戏、设置、关于等选项。GameScreen游戏主屏幕这是核心所有的游戏逻辑都在这里运行。PauseScreen暂停屏幕游戏暂停时覆盖在 GameScreen 上层的界面。GameOverScreen游戏结束屏幕显示最终得分、是否破纪录并提供重试或返回主菜单的选项。使用Screen的好处是状态隔离清晰资源可以按需加载和释放。例如当从 MainMenuScreen 切换到 GameScreen 时可以释放菜单界面的部分资源游戏结束时GameScreen 会被销毁释放所有游戏实体占用的内存。3.2 实体系统玩家、敌机与子弹这是游戏逻辑的心脏。我们为游戏中的每个可交互对象定义了一个基类Entity。public abstract class Entity { protected Vector2 position; // 位置 protected Vector2 velocity; // 速度 protected Rectangle bounds; // 碰撞矩形 protected TextureRegion texture; // 纹理区域 protected boolean active true; // 是否活跃 public abstract void update(float deltaTime); // 更新逻辑 public abstract void render(SpriteBatch batch); // 渲染 public abstract void onCollision(Entity other); // 碰撞处理 }所有具体的游戏对象都继承自EntityPlayer玩家飞机包含生命值、火力等级、移动速度、射击冷却时间等属性。它的update方法处理触摸/键盘输入控制移动和发射子弹。onCollision方法处理与敌机或敌弹的碰撞减少生命值并触发无敌时间。Enemy敌机这是一个抽象基类。不同类型的敌机如普通小飞机、中BOSS、大BOSS继承它。敌机拥有自己的生命值、分数价值、移动模式如直线、正弦曲线、追逐玩家和攻击模式即弹幕模式。Bullet子弹同样是一个基类。分为PlayerBullet和EnemyBullet。子弹的属性包括伤害、速度、方向、纹理以及一个可选的“弹幕行为”引用。EnemyBullet的update方法可能会根据其绑定的弹幕行为来计算复杂的运动轨迹。所有活跃的实体被分别存放在Player,ListEnemy,ListBullet等集合中在GameScreen的render方法里统一更新和绘制。这里的关键是使用对象池PoolBullet来管理子弹避免频繁的new和垃圾回收。3.3 弹幕系统模式与行为分离弹幕是 STG 游戏的灵魂。一个设计良好的弹幕系统应该将“模式”和“行为”解耦。弹幕模式Pattern描述在某一时刻敌机如何发射子弹。例如“向玩家方向发射3发子弹”、“以自身为中心环形发射24发子弹”、“发射一排缓慢的激光”。模式是数据驱动的可以用 JSON 或自定义格式来配置包含参数如子弹类型、发射数量、角度范围、速度等。弹幕行为Behavior附着在子弹上控制子弹发射后的运动轨迹。例如“直线运动”、“匀加速运动”、“正弦波运动”、“追踪玩家运动”。行为是一个组件在子弹创建时被注入。EnemyBullet的update方法会调用其Behavior.update()来计算下一帧的位置。这种分离带来了巨大的灵活性。一个敌机可以在不同的生命值阶段切换不同的弹幕模式Pattern而同一个“环形发射”模式发射出的子弹可以分别赋予“直线”和“正弦”两种行为Behavior创造出丰富多样的弹幕效果。在 ACE 项目中我们实现了一个简单的Behavior接口和一系列具体实现这是整个游戏视觉效果和难度的核心。3.4 资源与资产管理游戏离不开图片、声音和字体。LibGDX 的AssetManager是管理资源的利器。我们在项目启动的LoadingScreen中就预加载所有资源assetManager.load(graphics/player.png, Texture.class); assetManager.load(graphics/enemy_boss.png, Texture.class); assetManager.load(audio/shoot.wav, Sound.class); assetManager.load(particles/explosion.p, ParticleEffect.class); // ... 加载更多在GameScreen中我们通过assetManager.get()来获取资源。AssetManager不仅提供了异步加载和进度跟踪还能自动处理纹理的销毁防止内存泄漏。对于纹理我们通常还会使用TextureAtlas纹理图集将许多小图片打包成一张大图通过TextureRegion来引用这能显著减少 OpenGL 的状态切换提升渲染性能对于有大量子弹和敌机精灵的游戏至关重要。4. 核心功能实现与关键技术点有了清晰的架构接下来就是填充血肉实现游戏的核心玩法。这部分将深入几个关键技术的实现细节。4.1 玩家控制与移动手感优化在移动设备上玩家控制通常有两种方式虚拟摇杆和触屏拖拽。ACE 项目选择了后者因为对于纵版射击游戏直接拖拽飞机更符合直觉。输入处理在Player.update()方法中我们检测触摸输入。使用Gdx.input.isTouched()获取最近的触摸点坐标。坐标转换触摸坐标是屏幕像素坐标需要转换为游戏世界坐标。这通过GameScreen的摄像机OrthographicCamera的unproject()方法实现。平滑移动直接让飞机瞬间跳到触摸点会显得很生硬。我们采用线性插值Lerp来实现平滑追随。Vector2 touchPos getTouchWorldPosition(); // 获取转换后的触摸点 float lerpFactor 0.1f; // 插值系数值越小越平滑 position.x (touchPos.x - position.x) * lerpFactor; position.y (touchPos.y - position.y) * lerpFactor;同时需要给移动速度设置一个上限并限制飞机在游戏边界内移动。手感调优lerpFactor的值需要反复测试。太大会有延迟感太小则移动不够跟手。通常还会加入一个“死区”Dead Zone当触摸点与飞机当前位置距离小于某个阈值时飞机不移动避免微操时的抖动。4.2 敌机与弹幕生成逻辑敌机的出现通常由波次Wave或生成器Spawner控制。在GameScreen中我们维护一个敌机生成时间线。波次设计可以定义一个Wave类包含敌机类型、生成位置、生成延迟、移动路径等信息。游戏按顺序或随机执行这些波次。弹幕模式执行每个Enemy子类内部有一个AttackPattern列表和一个当前模式索引。在敌机的update方法中会根据时间或条件切换到下一个模式。public void update(float delta) { // ... 移动逻辑 attackTimer delta; if (attackTimer currentPattern.interval) { fireCurrentPattern(); attackTimer 0; } // 检查是否切换到下一个模式例如生命值低于50% if (health maxHealth * 0.5f !patternSwitched) { currentPatternIndex; patternSwitched true; } }fireCurrentPattern方法这是弹幕生成的核心。根据模式描述创建多个EnemyBullet实例并为每个子弹设置初始位置、速度方向并附加相应的Behavior。private void fireCurrentPattern() { Pattern p patterns.get(currentPatternIndex); for (int i 0; i p.bulletCount; i) { float angle p.startAngle (p.angleRange * i / (p.bulletCount - 1)); Vector2 dir new Vector2(1, 0).setAngleDeg(angle); // 根据角度计算方向向量 EnemyBullet bullet bulletPool.obtain(); bullet.init(this.position.x, this.position.y, dir.scl(p.speed)); bullet.setBehavior(BehaviorFactory.create(p.behaviorType, p.behaviorParams)); gameWorld.addEnemyBullet(bullet); } }4.3 精确碰撞检测的实现射击游戏的碰撞检测必须快速且精确。我们采用两阶段检测法以平衡性能和准确性。边界矩形粗略检测Broad Phase每一帧我们遍历所有玩家子弹和敌机、敌弹和玩家。首先使用Rectangle.overlaps()方法进行快速的矩形相交测试。这是一个非常廉价的操作能快速过滤掉绝大多数不可能发生碰撞的对象对。像素/形状精确检测Narrow Phase对于通过粗略检测的对象对进行更精确的检测。对于圆形物体如一些子弹使用Circle.overlaps()或计算圆心距离。对于矩形物体已经用矩形检测即可或者使用更精细的 oriented bounding box (OBB)。对于需要像素级精度的情况如不规则形状的BOSS可以使用Intersector类中的多边形相交测试或者预先为精灵生成一个简化的碰撞多边形碰撞遮罩。在 ACE 中为了性能我们大多使用圆形或矩形对于大型 BOSS可能会将其拆分为多个矩形碰撞区域如核心区、装甲区。碰撞处理一旦检测到碰撞调用双方的onCollision方法。例如玩家子弹击中敌机则敌机减血子弹标记为待回收敌弹击中玩家则玩家进入无敌状态并闪烁播放受击音效。注意性能陷阱。避免在每一帧进行 O(n²) 的全量碰撞检测。可以利用空间划分算法如网格法Grid将游戏世界划分为格子只检测在同一格或相邻格内的实体。对于弹幕游戏由于子弹密集且移动快简单的矩形检测配合对象池管理在实体数量可控时几百个以内通常已足够。4.4 游戏状态管理与数据持久化游戏需要记录最高分、设置如音效开关等数据。LibGDX 提供了Preferences类用于在本地存储简单的键值对数据在 Android 上对应 SharedPreferences。// 保存最高分 Preferences prefs Gdx.app.getPreferences(ACE_Game_Data); prefs.putInteger(high_score, Math.max(currentScore, prefs.getInteger(high_score, 0))); prefs.flush(); // 写入磁盘 // 读取音效设置 boolean soundOn prefs.getBoolean(sound_on, true);对于更复杂的数据如解锁的角色、关卡进度可以考虑使用 JSON 序列化对象后存储。游戏中的暂停、继续、重新开始等状态则通过GameScreen内部的状态标志位和Screen的切换来管理。5. 性能优化与内存管理实战移动设备资源有限性能优化是保证游戏流畅运行的关键。在 ACE 项目中我们重点关注了以下几个方面。5.1 渲染优化SpriteBatch 与纹理管理SpriteBatch是 LibGDX 2D 渲染的核心。它的工作原理是将多个绘制调用Draw Call合并成一个批次提交给 GPU减少状态切换开销。批量绘制确保在调用batch.begin()和batch.end()之间绘制所有使用同一张纹理或纹理图集的精灵。频繁切换纹理会打断批次。batch.begin(); // 先画所有使用“bullets.png”图集的子弹 for (Bullet bullet : playerBullets) { bullet.render(batch); // 内部调用 batch.draw(...) } // 再画所有使用“enemies.png”图集的敌机 for (Enemy enemy : enemies) { enemy.render(batch); } batch.end();在实践中我们会按图层和纹理对实体进行排序后再绘制。使用 TextureAtlas这是必须的。将游戏中的所有小纹理打包成一张或几张大的图集。LibGDX 的TexturePacker工具可以自动完成这项工作并生成一个.atlas文件描述每个子图的位置。这不仅能减少 Draw Call还能节省内存减少纹理边界浪费。控制绘制范围只绘制在摄像机视野内的物体。在更新实体时就判断其位置是否在屏幕内如果完全在屏幕外且不会返回如飞走的敌机可以提前回收。5.2 对象池杜绝频繁 GC在弹幕游戏中子弹和敌机的创建与销毁极其频繁。如果每一发子弹都new Bullet()被击中或飞出屏幕后就等待垃圾回收器GC处理很快就会引起 GC 的频繁启动导致游戏卡顿。 LibGDX 提供了Pool抽象类我们需要实现它public class BulletPool extends PoolBullet { Override protected Bullet newObject() { return new Bullet(); // 当池为空时创建新对象 } Override public void free(Bullet bullet) { bullet.reset(); // 非常重要在放回池子前重置对象状态 super.free(bullet); } }使用时// 获取子弹 Bullet bullet bulletPool.obtain(); bullet.init(x, y, velocity); activeBullets.add(bullet); // 回收子弹当子弹飞出屏幕或被击中 bullet.setActive(false); activeBullets.removeValue(bullet, true); bulletPool.free(bullet);通过对象池我们复用了对象避免了内存的频繁分配和回收这是保证游戏流畅度的最关键优化之一。5.3 内存泄漏排查与预防在 Android 上内存泄漏会导致应用崩溃。常见陷阱静态引用避免在静态变量或单例中持有Activity或Screen的引用。监听器未注销如果注册了全局的输入或事件监听器在Screen.hide()或dispose()时要记得注销。资源未释放所有通过assetManager.load()加载的资源在游戏不再需要时如切换 Screen应通过assetManager.unload()卸载。或者在Screen的dispose()方法中调用assetManager.dispose()注意这会释放所有资源。纹理和声音确保在游戏退出或资源不用时调用texture.dispose()和sound.dispose()。使用AssetManager可以自动化这个过程。5.4 帧率稳定与时间步长处理游戏逻辑更新应该基于时间增量delta time而不是固定的帧。这能确保在不同刷新率的设备上游戏速度一致。Override public void render(float deltaTime) { // 累积时间 accumulator deltaTime; // 固定时间步长更新例如每秒60次逻辑更新 while (accumulator TIME_STEP) { updateGameLogic(TIME_STEP); // 更新物理、位置、碰撞等 accumulator - TIME_STEP; } // 渲染渲染可以独立于更新频率 renderGame(); }这种固定时间步长的更新方式能有效避免因帧率波动导致的“子弹速度时快时慢”问题。TIME_STEP通常取 1/60f 或 1/120f。6. 从开发到发布Android 平台适配与打包当游戏核心功能完成后最后一步是让它成为一个真正的 Android App。6.1 项目结构解析一个标准的 LibGDX 项目通常包含多个模块core: 这是核心模块包含所有平台共享的游戏逻辑代码。我们的Entity,GameScreen, 资源管理类等都放在这里。android: Android 平台特定的模块。它依赖core模块并包含AndroidLauncher类继承自AndroidApplication和AndroidManifest.xml。desktop: 桌面启动模块用于在 PC 上调试。ios/html: 可选的其他平台模块。在 Android Studio 中android模块就是一个标准的 Android 应用项目。你需要在这里配置权限如振动权限、设置屏幕方向通常为竖屏或横屏锁定、图标和应用名称。6.2 屏幕适配与不同分辨率处理Android 设备分辨率碎片化严重。LibGDX 使用虚拟分辨率Viewport来解决这个问题。定义虚拟世界大小我们为游戏世界定义一个固定的逻辑尺寸例如 480x800宽x高。所有的游戏坐标、碰撞检测都基于这个逻辑尺寸。选择 ViewportFitViewport: 保持宽高比将游戏世界完整显示在屏幕上屏幕两侧或上下可能出现黑边。适合需要看到完整游戏区域的游戏如策略游戏但对于射击游戏黑边可能影响沉浸感。FillViewport: 拉伸游戏世界以填满屏幕可能会造成图像变形。不推荐。StretchViewport: 直接拉伸到屏幕尺寸会变形。ScreenViewport: 使用物理像素坐标游戏世界大小随屏幕变化。不适合需要固定比例的2D游戏。推荐对于纵版射击游戏我通常使用ExtendViewport。它会在一个方向上通常是宽度固定为虚拟尺寸另一个方向高度进行扩展以填满屏幕同时保持宽高比。这样既能充分利用屏幕空间又不会导致核心游戏区域被裁剪。// 在 AndroidLauncher 的 onCreate 中 ExtendViewport viewport new ExtendViewport(480, 800); // 基础尺寸 initialize(new MyGame(), config);UI 适配游戏内的 UI分数、生命值图标通常使用另一个Stage和Viewport如ScreenViewport来管理使其始终贴合屏幕边缘不受游戏世界缩放影响。6.3 打包与签名发布生成签名密钥Keystore这是发布到应用商店的必需步骤。可以使用 Android Studio 的Build - Generate Signed Bundle / APK向导来创建。配置 build.gradle在android模块的build.gradle中可以设置应用ID、版本号、版本名称以及启用代码压缩ProGuard/R8以减小 APK 体积。android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile(proguard-android.txt), proguard-rules.pro signingConfig signingConfigs.release // 引用你的签名配置 } } }生成 APK 或 App Bundle使用 Android Studio 的生成签名包功能选择 APK 或更现代的 Android App BundleAAB。AAB 格式能让 Google Play 为不同设备生成最优化的 APK。测试务必在多种不同分辨率、不同系统版本的实体机或模拟器上进行全面测试确保没有因适配问题导致的崩溃或显示异常。7. 常见问题排查与调试技巧在开发过程中你一定会遇到各种“坑”。这里记录了一些典型问题及其解决方法。7.1 游戏运行卡顿或帧率不稳定检查对象池首先确认是否对子弹、敌机等频繁创建的对象使用了对象池。使用Pool并确保正确free。分析渲染批次在ApplicationListener的实现类中可以重写render()方法在开头调用Gdx.app.log(FPS, Gdx.graphics.getFramesPerSecond());监控帧率。更深入的分析可以使用Gdx.app.getGraphics().getFramesPerSecond()并结合SpriteBatch的渲染调用次数通过自定义ShaderProgram或工具类统计。确保纹理切换最小化。内存泄漏使用 Android Studio 的 Profiler 工具监控内存使用情况。反复进入退出游戏场景观察内存是否持续增长。重点检查静态集合、未注销的监听器。逻辑更新耗时复杂的碰撞检测或寻路算法可能成为瓶颈。考虑使用空间划分优化碰撞检测或对 AI 逻辑进行分帧计算。7.2 碰撞检测不准确或失灵坐标系问题确保碰撞检测使用的坐标世界坐标和渲染使用的坐标是一致的。注意Viewport可能对坐标系进行了缩放和位移碰撞检测应在游戏逻辑坐标系虚拟分辨率中进行。更新顺序碰撞检测应在所有实体位置更新update之后渲染之前进行。错误的顺序会导致检测基于过时的位置信息。边界框Bounds未更新Entity的bounds矩形或圆形必须随着position的更新而同步更新。一个常见的错误是只在构造函数中初始化bounds之后忘了更新它。public void update(float delta) { position.add(velocity.x * delta, velocity.y * delta); // 更新碰撞框位置 bounds.setPosition(position.x - bounds.width/2, position.y - bounds.height/2); }7.3 资源加载失败或显示黑屏/白屏文件路径错误LibGDX 在 Android 和桌面端的文件路径处理方式不同。对于资源文件应放在core/assets/目录下然后使用Gdx.files.internal(path/to/file.png)来访问。绝对不要使用硬编码的绝对路径。纹理尺寸非2的幂在 OpenGL ES 2.0 上纹理的宽和高最好是2的幂如 64, 128, 256, 512...否则在某些设备上可能无法显示或性能低下。使用TexturePacker打包图集时它会自动处理。AssetManager 异步加载未完成如果在资源加载完成前就尝试使用会导致黑屏。确保在LoadingScreen中等待assetManager.update()返回true表示加载完成后再切换屏幕。7.4 在真机上调试启用 USB 调试在 Android 设备的开发者选项中打开 USB 调试。连接 Android Studio用数据线连接手机和电脑在 Android Studio 的运行配置中选择你的设备。查看日志游戏中的Gdx.app.log()或Gdx.app.error()输出可以在 Android Studio 的Logcat窗口中查看这是排查运行时错误的最重要工具。性能分析使用 Android Studio Profiler 实时查看 CPU、内存、网络和能耗情况。开发这样一个项目最大的体会是游戏开发是工程和艺术的结合。LibGDX 给了你搭建舞台的工具但如何让角色实体在舞台上流畅表演逻辑与渲染如何设计引人入胜的剧情游戏性与弹幕模式则需要不断的打磨和测试。从确定虚拟分辨率到调优一颗子弹的运动曲线每一个细节都影响着最终玩家的体验。这个 ACE 项目就像一份详细的施工图纸希望它能帮助你在构建自己的游戏世界时少走一些弯路多享受一些创造的乐趣。如果在实现过程中遇到具体问题多查阅 LibGDX 的官方 Wiki 和社区那里有非常多热情的开发者和丰富的解决方案。