
1. 项目概述为什么选择C做游戏如果你点开这篇文章大概率是刚接触编程或者学过一点Python、Java但对“用C做游戏”这个听起来很酷又有点吓人的目标感到无从下手。我当年也是这么过来的从对着黑框命令行敲“Hello World”到能做出一个带图形界面的小游戏中间踩过的坑、熬过的夜现在想想都是宝贵的经验。今天我就以一个过来人的身份和你聊聊新手如何系统地从零开始用C踏上游戏制作这条路。首先我们必须直面一个核心问题为什么是C现在游戏引擎这么发达Unity用C#Godot用GDScriptUnreal Engine虽然用C但门槛不低为什么还要从“硬核”的C学起我的答案是理解底层掌控全局。C就像乐高积木最基础的颗粒用它搭建东西确实更费劲但你对整个结构的理解是透彻的。当你用C从零开始实现一个游戏循环、处理一次碰撞检测、管理一堆游戏对象时你学到的不是某个引擎的按钮怎么点而是“游戏”这个软件最核心的运行逻辑。这份理解能让你在未来使用任何高级引擎时都知其然更知其所以然遇到性能瓶颈或诡异Bug时你有能力深入底层去排查和优化而不是只能上网搜索“Unity为什么卡顿”。当然这条路对新手绝不友好。指针、内存管理、多态、模板……这些概念足以劝退很多人。但别怕我们的目标不是一开始就写出3A大作而是用一个个可达成的小项目像爬楼梯一样逐步构建起你的知识体系和信心。我们将从最基础的“猜数字”文字游戏开始过渡到使用简单的图形库制作2D小游戏最终挑战一个包含基本游戏循环、图形渲染和简单逻辑的完整项目。这个过程我会把每个阶段的关键技术点、容易踩的坑以及我自己的调试心得毫无保留地分享给你。2. 学习路径规划从零到一的四个阶段盲目学习是最低效的。根据我辅导新手的经验一个结构清晰、目标明确的学习路径至关重要。我把从零基础到能独立完成一个小型C游戏Demo的过程划分为四个循序渐进的阶段。每个阶段都有明确的目标、核心要掌握的知识点以及一个标志性的产出项目。2.1 第一阶段夯实C语言基础约1-2个月这个阶段的目标不是“学会C全部”而是掌握足以支撑我们开始游戏编程的必要子集。很多教程一上来就讲面向对象、设计模式对新手来说信息过载。我们应该聚焦在游戏开发中最常用、最基础的部分。核心学习清单语法基础变量、数据类型、运算符、流程控制if/else, for/while。这是所有编程的起点。函数如何定义函数、传递参数值传递、引用传递、返回值。理解函数是组织代码的基本单元。数组与字符串如何存储和处理一系列数据。游戏中的角色属性、地图格子、敌人列表都离不开它们。指针与引用重中之重这是C的“坎”也是其威力的来源。你需要理解内存地址的概念明白指针如何指向数据引用如何作为别名。在游戏里高效地传递和操作大型对象如一个包含大量顶点的模型离不开它们。一开始会晕多写代码多用调试器观察内存变化。结构体与类面向对象入门学会用struct或class将相关的数据和函数打包。比如你可以定义一个Player类包含health,position属性和move(),attack()方法。这是组织游戏对象的核心思想。简单的文件I/O学会从文本文件中读取关卡数据、配置或保存游戏进度。本阶段产出项目控制台小游戏不要小看黑框框。在这个阶段你应该能独立完成一个猜数字游戏或一个简易的文字冒险游戏。这能锻炼你处理输入输出、随机数生成、游戏状态判断和循环逻辑的能力。例如你的文字冒险游戏可以有多个房间、简单的物品系统和基于文本的战斗。实操心得这个阶段切忌贪多求快。不要急着去啃《C Primer》这样的巨著。找一本薄一点的入门书或一套口碑好的视频教程跟着敲每一行代码。理解不了指针就写个小程序声明一个整型变量和一个指针用调试器如VS的调试模式一步步执行观察变量地址和指针值的变化这是最直观的学习方式。2.2 第二阶段引入图形库与游戏循环约1-2个月当你能熟练地用C在控制台里“做游戏”后就可以拥抱图形界面了。这里我们不会直接上复杂的游戏引擎而是选择一个轻量级的2D图形库目的是理解游戏循环这一核心概念。工具选型SFML 或 Raylib我强烈推荐这两个库给新手。它们都易于安装、API友好且跨平台。SFML (Simple and Fast Multimedia Library)模块化设计清晰图形、窗口、音频、网络等C风格浓郁文档和社区资源非常丰富。用它你能清晰地看到窗口、事件、图形绘制是如何分离的。Raylib更极简API设计非常直观一个头文件包含所有功能对新手极其友好。它的理念是“让学习游戏编程变得有趣”非常适合快速原型开发。本阶段核心目标理解并实现游戏循环游戏循环是游戏程序的“心脏”。一个最简单的游戏循环伪代码如下while (游戏是否运行) { 处理输入键盘、鼠标事件 更新游戏状态角色位置、敌人AI、物理模拟等 渲染图形清屏、绘制背景、绘制所有游戏对象 }你的任务就是用SFML或Raylib创建一个窗口并在其中实现这个循环。例如让一个方块能用键盘上下左右移动。本阶段产出项目2D图形交互Demo实现一个“打砖块”或“贪吃蛇”的极简版本。这个项目会强迫你思考图形绘制如何加载图片或绘制几何图形输入处理如何响应键盘事件来控制挡板或蛇头简单碰撞检测如何判断球碰到了砖块或墙游戏状态管理分数怎么算生命值怎么扣游戏何时结束注意事项第一次配置图形库可能会遇到问题比如链接库文件、找不到头文件等。这是每个C开发者必经的“环境配置之痛”。请耐心阅读官方安装指南确保你的编译器如GCC、Clang或MSVC能正确找到库文件。在Windows上使用Visual Studio或VS Code CMake来管理项目会比直接命令行更省心。2.3 第三阶段构建简单游戏框架约1-2个月完成一两个小游戏后你会发现代码开始变得混乱main函数越来越长游戏对象的数据和逻辑散落各处。这时你需要学习如何组织代码构建一个微型的、属于你自己的游戏框架。需要掌握的核心概念面向对象设计深化运用继承和多态。比如创建一个GameObject基类然后派生出Player、Enemy、Bullet等子类。这样你可以用一个std::vectorGameObject*来管理所有游戏对象在循环里统一调用它们的Update()和Draw()方法。资源管理学习如何设计一个ResourceManager类来统一加载和管理纹理、字体、音效等资源避免重复加载和内存泄漏。简单场景管理实现一个GameState或Scene基类然后派生出MainMenuState、PlayState、PauseState等。这能让你的游戏逻辑如开始界面和游玩界面清晰分离。基础设计模式了解单例模式用于全局管理器、状态模式用于场景管理等但不要滥用在确实需要时再引入。本阶段产出项目小型2D动作游戏尝试制作一个类似“雷电”的竖版射击游戏STG。这个项目复杂度适中但能完整运用上述所有概念游戏对象系统玩家飞机、敌机、子弹、爆炸特效都是GameObject。资源管理集中加载所有飞机、子弹的图片和音效。场景/状态至少包含开始界面和游戏主界面。碰撞检测实现玩家子弹与敌机、玩家与敌机/敌弹的碰撞。简单AI让敌机沿着预定路径移动或进行简单的追踪。2.4 第四阶段集成引擎与深入优化长期当你能够不依赖教程独立完成第三阶段的项目时你已经是一个合格的C游戏编程入门者了。此时你可以选择两条路继续深耕自研框架学习更高级的图形API如OpenGL、物理引擎如Box2D、音频库不断完善自己的小引擎。这条路对深入理解计算机图形学和游戏引擎架构帮助极大。转向成熟的游戏引擎将你学到的扎实的C基础应用到像Unreal Engine这样的工业级引擎中。UE本身就用C编写你写的C代码可以直接驱动游戏逻辑性能强大能接触到PBR渲染、蓝图系统、网络同步等高级主题。无论选择哪条路你之前打下的基础——对内存、指针、面向对象、游戏循环的理解——都将是你最宝贵的财富让你在学习新工具时快人一步在解决问题时思路清晰。3. 开发环境搭建与工具链选择工欲善其事必先利其器。一个顺手的开发环境能极大提升学习效率和幸福感尤其是在C这种环境配置比较复杂的语言上。下面我针对不同操作系统和偏好给出最务实的选择建议。3.1 编译器与IDE新手如何选择Windows平台首选Visual Studio 2022 Community Edition理由微软官方出品对Windows支持最好安装即用集成了强大的MSVC编译器、调试器和图形化项目管理系统。它的调试器是业界标杆对于排查C的内存错误如访问越界、内存泄漏极其方便。对于纯粹的新手这是最省心、最强大的选择。安装注意安装时记得勾选“使用C的桌面开发”工作负载。如果遇到网络问题导致某些组件安装失败可以尝试修改安装源或使用离线安装包。次选Visual Studio Code MSVC/MinGW理由更轻量更灵活。你需要自己配置编译器路径MSVC或MinGW-GCC、安装C扩展并编写tasks.json和launch.json来定义编译和调试任务。这个过程本身就是一个很好的学习经历能让你理解编译、链接背后的命令。适合喜欢折腾、希望更深入了解工具链的同学。macOS/Linux平台首选Clang CMake 任意编辑器VS Code, CLion, Sublime Text等理由Clang是macOS的默认编译器在Linux上也极易安装。CMake是一个跨平台的构建系统生成器可以帮你生成Makefile或Xcode项目等是管理C项目的标准工具之一。这套组合是跨平台开发的事实标准。简易方案直接使用JetBrains CLion。这是一个优秀的跨平台C IDE内置了对CMake的完美支持智能代码提示和重构功能强大开箱即用但它是商业软件对学生有免费许可。避坑指南关于“Microsoft Visual C Redistributable”和“vcbuild.exe”错误。 这是Windows平台上一个经典错误。当你运行别人编译好的程序或使用某些Node.js的C原生模块如node-sass时可能会提示缺少VC运行库或vcbuild.exe。缺少运行库去微软官网下载对应版本的“Microsoft Visual C Redistributable”安装即可。通常需要安装2015、2017、2019、2022等多个版本因为它们互相独立。vcbuild.exe错误这通常是因为你的系统缺少Visual Studio的构建工具。你需要安装“Visual Studio Build Tools”或完整的Visual Studio并确保安装了对应版本的“C桌面开发”组件。vcbuild.exe是旧版VS的构建工具新版是MSBuild.exe。对于纯粹学习C游戏开发安装完整的Visual Studio Community版是根除这类问题的最佳方法。3.2 必备辅助工具版本控制Git为什么必须学它能保存你代码的每一个历史版本。当你尝试一个大胆的修改把项目搞崩了可以轻松回退到之前能运行的状态。也是未来团队协作的基石。从第一天就开始用。入门在官网下载Git学习git init,git add,git commit,git status这几个最基础的命令。图形化客户端如GitHub Desktop, Sourcetree可以帮你起步。调试器IDE如VS, CLion内置的图形化调试器是你的主要武器。学会设置断点、单步执行、查看变量值、观察调用栈。这是理解程序运行流程、定位Bug的最有效手段比盲目cout打印高效得多。包管理器/依赖管理当你需要引入SFML、Raylib或其他第三方库时手动下载、配置头文件和库文件路径很麻烦。推荐vcpkg微软开发的跨平台C库管理器。你只需要在命令行输入vcpkg install sfml它就会自动下载、编译并配置好SFML库并生成供你的IDE或CMake使用的配置文件极大简化了库管理流程。4. 第一个图形化项目实战SFML版“打砖块”理论说再多不如动手做一遍。让我们用SFML库一步步实现一个最经典的“打砖块”游戏。这个项目涵盖了窗口创建、事件处理、图形绘制、碰撞检测和游戏状态管理是一个完美的入门综合练习。4.1 项目初始化与SFML配置首先确保你已经按照SFML官网的教程在你的开发环境中成功安装并配置好了SFML。这里以使用Visual Studio 2022和vcpkg为例安装vcpkg如果尚未安装git clone https://github.com/Microsoft/vcpkg.git cd vcpkg .\bootstrap-vcpkg.bat # Windows # ./bootstrap-vcpkg.sh # Linux/macOS使用vcpkg安装SFML.\vcpkg install sfml安装完成后vcpkg会告诉你如何集成到你的项目中。对于Visual Studio它通常是通过“项目属性 - VC目录 - 包含目录/库目录”来设置或者使用CMake的find_package命令。创建新项目在VS中创建一个新的“控制台应用”或“空项目”。在项目属性中根据vcpkg的提示正确配置包含目录、库目录并在链接器-输入-附加依赖项中添加sfml-graphics.lib; sfml-window.lib; sfml-system.lib;Debug配置下可能带-d后缀。4.2 核心类设计与实现我们不把所有代码堆在main.cpp里。良好的结构从第一天开始培养。我们设计几个核心类1. Game类游戏总管这是游戏的主循环和总调度器。// Game.h #pragma once #include SFML/Graphics.hpp class Game { public: Game(); void run(); // 主游戏循环 private: void processEvents(); // 处理输入 void update(sf::Time deltaTime); // 更新游戏逻辑 void render(); // 渲染画面 sf::RenderWindow mWindow; // SFML窗口对象 // 其他游戏对象Ball, Paddle, BrickField等将作为成员变量 // ... };run()方法就是我们的游戏循环核心// Game.cpp void Game::run() { sf::Clock clock; // SFML的时间类用于计算帧间隔 while (mWindow.isOpen()) { sf::Time deltaTime clock.restart(); // 获取上一帧到这一帧的时间差 processEvents(); update(deltaTime); // 传入时间差实现与帧率无关的匀速运动 render(); } }这里的关键是deltaTime常写作dt。我们使用它来计算物体每一帧应该移动的距离速度 * dt这样无论电脑快慢30帧还是60帧物体的移动速度在现实中都是恒定的。2. Ball类小球// Ball.h #pragma once #include SFML/Graphics.hpp class Ball { public: Ball(float radius, const sf::Vector2f position); void update(sf::Time dt); // 根据速度和dt更新位置 void draw(sf::RenderWindow window); // 绘制自己 sf::FloatRect getBounds() const; // 获取用于碰撞检测的边界矩形 void setVelocity(const sf::Vector2f vel) { mVelocity vel; } sf::Vector2f getVelocity() const { return mVelocity; } void move(const sf::Vector2f offset) { mShape.move(offset); } private: sf::CircleShape mShape; // SFML的圆形图形对象 sf::Vector2f mVelocity; // 速度向量 (x, y) };3. Paddle类挡板// Paddle.h #pragma once #include SFML/Graphics.hpp class Paddle { public: Paddle(const sf::Vector2f size, const sf::Vector2f position); void handleInput(); // 处理键盘输入左右移动 void update(sf::Time dt); // 更新位置限制在窗口内 void draw(sf::RenderWindow window); sf::FloatRect getBounds() const; private: sf::RectangleShape mShape; float mMoveSpeed; };在handleInput中我们检测sf::Keyboard::isKeyPressed(sf::Keyboard::Left/Right)来判断按键状态并相应地设置挡板的速度。4. BrickField类砖块阵列用一个二维std::vector来管理砖块。每个砖块可以是一个简单的sf::RectangleShape并附带一个bool mIsDestroyed状态。4.3 碰撞检测的实现这是游戏逻辑的核心。我们实现一个简单的**轴对齐边界框AABB**碰撞检测。// 工具函数检查两个FloatRect是否相交 bool isColliding(const sf::FloatRect rect1, const sf::FloatRect rect2) { return rect1.intersects(rect2); } // 在Game::update中处理球与挡板的碰撞 void Game::update(sf::Time dt) { mBall.update(dt); mPaddle.update(dt); // 球与挡板碰撞 if (isColliding(mBall.getBounds(), mPaddle.getBounds())) { // 简单处理反转Y方向速度并根据击中挡板的位置微调X速度增加可玩性 sf::Vector2f vel mBall.getVelocity(); vel.y -std::abs(vel.y); // 确保Y速度向上 // 计算球击中挡板的相对位置-0.5到0.5 float hitPos (mBall.getPosition().x - mPaddle.getPosition().x) / mPaddle.getSize().x; vel.x hitPos * 5.0f; // 根据击中位置赋予一个横向速度 mBall.setVelocity(vel); } // 球与砖块碰撞遍历所有未销毁的砖块 for (auto brickRow : mBrickField.getBricks()) { for (auto brick : brickRow) { if (!brick.isDestroyed() isColliding(mBall.getBounds(), brick.getBounds())) { brick.destroy(); // 简单碰撞响应反转Y速度 sf::Vector2f vel mBall.getVelocity(); vel.y -vel.y; mBall.setVelocity(vel); // 可以在这里加分、播放音效 break; // 一帧只处理一次碰撞避免复杂情况 } } } // 球与墙壁碰撞左、右、上 sf::Vector2f ballPos mBall.getPosition(); sf::Vector2f ballVel mBall.getVelocity(); if (ballPos.x 0 || ballPos.x mWindow.getSize().x) { ballVel.x -ballVel.x; // 左右墙反弹 } if (ballPos.y 0) { ballVel.y -ballVel.y; // 上墙反弹 } if (ballPos.y mWindow.getSize().y) { // 球落到底部游戏结束或扣生命 resetBallAndPaddle(); // 重置球和挡板位置 } mBall.setVelocity(ballVel); }4.4 游戏状态与体验完善基础的碰撞完成后我们可以丰富游戏添加分数和生命值在Game类中增加mScore和mLives变量。击碎砖块时加分球落底时减生命。游戏状态管理用枚举类GameState定义Playing,Paused,GameOver等状态。在processEvents中按Esc键可以暂停/继续按R键可以重新开始。资源管理创建一个AssetManager单例类用于加载和存储纹理、字体、音效。让砖块、挡板、背景使用不同的纹理让游戏看起来更美观。添加音效和音乐使用SFML的sf::Sound和sf::Music类在碰撞、得分、游戏结束时播放相应的音效。当你完成以上所有步骤一个由你亲手打造的、拥有完整游戏循环和逻辑的“打砖块”就诞生了。虽然它看起来简单但你已经实践了商业游戏开发中最核心的那套流程。5. 进阶学习与资源推荐完成第一个项目后你可能会感到兴奋也可能会遇到瓶颈。这是学习过程中最关键的时期。下面我为你梳理了后续的学习方向和优质资源帮你少走弯路。5.1 知识体系深化必须啃下的硬骨头C语言本身标准模板库STL这是C的瑞士军刀。熟练掌握vector,map/unordered_map,string等容器以及algorithm里的常用函数如sort,find。在游戏中你会频繁使用它们来管理对象、查找数据。内存管理理解栈和堆的区别掌握new/delete以及更现代的std::unique_ptr和std::shared_ptr。智能指针能帮你自动管理内存避免内存泄漏是现代C游戏开发中的必备工具。多线程现代游戏充分利用多核CPU。学习std::thread,std::async以及如何安全地进行线程间通信互斥锁std::mutex、条件变量等。例如可以将音频播放、文件加载放到独立线程避免阻塞主游戏循环。数学基础线性代数向量位置、速度、方向、矩阵变换、旋转、缩放是图形和物理的基石。你不需要成为数学家但必须理解点乘、叉乘、矩阵乘法的几何意义。几何与三角学计算角度、距离、判断点是否在图形内、实现简单的射线检测等都离不开它们。游戏编程特定领域游戏物理从最简单的匀速运动、加速度到碰撞检测与响应不只是AABB还有圆形、OBB等再到引入物理引擎如Box2D。人工智能状态机FSM是游戏AI最常用的模型。学习如何为敌人设计“巡逻”、“追击”、“攻击”、“逃跑”等状态及其转换条件。游戏设计模式实体组件系统ECS是现代高性能游戏引擎的架构趋势。学习《游戏编程模式》这本书理解对象池、命令模式、观察者模式等在游戏中的实际应用。5.2 优质学习资源导航书籍经典永流传《C Primer》语言学习的权威参考书适合系统学习时查阅。《Effective C》/《More Effective C》教你如何正确、高效地使用C避开常见陷阱。《游戏编程模式》将经典设计模式与游戏开发紧密结合提供可直接复用的解决方案。《游戏引擎架构》虽然较深但能让你对商业游戏引擎的各个模块有宏观认识学有余力时强烈推荐。在线教程与社区LearnOpenGL如果你想深入了解计算机图形学这是最好的入门教程使用C和OpenGL。SFML官方教程与文档清晰易懂是学习SFML的不二之选。Raylib by ExampleRaylib的示例代码库通过大量小例子学习各种功能。Stack Overflow 和 Game Development Stack Exchange遇到具体错误或设计难题时优先来这里搜索提问前请先阅读如何提问的指南。GitHub多看看别人用C写的开源小游戏项目学习他们的代码组织方式。项目实践建议不要一直停留在教程里。给自己设定一系列难度递增的“克隆”项目贪吃蛇-打砖块-太空侵略者巩固2D图形和基础逻辑。推箱子-简易RPG地图探索学习关卡数据加载从文件读地图格子、更复杂的游戏状态管理。平台跳跃游戏如超级马里奥的简化版引入重力、跳跃物理、更精确的像素级碰撞检测。简易的2D RTS即时战略或塔防学习管理大量单位、路径寻找A*算法、简单的经济系统。6. 常见问题与调试心法实录最后分享一些我踩过坑后总结出的“血泪经验”。这些问题你大概率会遇到希望我的经验能帮你快速脱困。6.1 编译与链接错误大全“undefined reference tosf::...” 或 “LNK2019: 无法解析的外部符号”原因这是最典型的链接错误。编译器找到了函数声明在头文件里但链接器找不到函数的具体实现在库文件里。排查检查项目属性中“附加库目录”是否包含了SFML库文件.lib所在的路径。检查“附加依赖项”是否添加了所有必需的.lib文件名如sfml-graphics.lib。Debug和Release配置、32位和64位平台的库文件不能混用如果你用vcpkg确保你运行了vcpkg integrate install并且在VS中正确选择了“Triplet”如x64-windows。“Cannot open include file: ‘SFML/Graphics.hpp’”原因编译器找不到SFML的头文件。排查检查项目属性中“附加包含目录”是否添加了SFML的include文件夹路径。程序运行时崩溃提示“缺少dll”原因你的可执行文件需要动态链接库.dll才能运行但这些dll没有放在exe同级目录或系统路径中。解决将SFML的bin目录下的所有.dll文件如sfml-graphics-2.dll复制到你的项目生成的可执行文件.exe所在的目录下。6.2 运行时逻辑错误与调试技巧物体移动飞快或闪烁原因没有使用deltaTime进行与帧率无关的移动。在高速电脑上每帧时间极短速度 * 1会让物体瞬间飞走。解决永远记住在update函数中更新位置时使用position velocity * deltaTime.asSeconds();。碰撞检测“穿透”或不准原因速度太快一帧移动的距离超过了物体的尺寸导致从物体一侧直接“穿越”到了另一侧没有触发碰撞检测。解决降低速度这是最简单的办法。使用连续碰撞检测不是只检测物体当前帧的位置而是检测从上一帧到这一帧的整个运动轨迹是否与障碍物相交。对于高速子弹等物体是必要的。缩小检测区域有时用比渲染图形稍小的区域做碰撞检测体验会更自然。内存泄漏现象程序运行时间越长占用内存越大最终可能崩溃。排查养成习惯对于每个new都要想好在哪里delete。优先使用栈对象或智能指针std::unique_ptr。使用工具在Windows上可以使用Visual Studio的“诊断工具”窗口中的“内存使用率”来观察。更专业的工具有ValgrindLinux/macOS或Visual Studio的CRT调试库。“黑窗口一闪而过”原因main函数执行完毕程序正常退出。对于图形程序通常是因为游戏循环结束比如窗口被关闭的条件判断有误或者循环内直接return了。调试在main函数末尾或疑似提前退出的地方前加一句system(“pause”);仅Windows或std::cin.get();来暂停控制台看看程序是否真的执行到了那里。更好的方法是在IDE中设置断点进行调试。6.3 心态与学习方法避坑不要试图一次性理解所有概念C和游戏开发的知识体系庞大。接受“螺旋式上升”的学习过程先了解概念能跑通代码在项目中遇到问题再回头深入理解。比如多态一开始知道它能用基类指针调用子类方法就够了用多了自然就理解其背后的虚函数表机制。“抄代码”不可耻但要“带着脑子抄”初学者模仿优秀代码是学习的捷径。但抄的时候要逐行理解为什么这么写尝试修改参数看有什么变化最后能脱离教程自己重新实现一遍。遇到问题先自己思考再精准搜索将错误信息直接复制到搜索引擎如Google、Bing很大概率能找到解决方案。在论坛提问时提供最小可复现代码、错误信息、你已经尝试过的方法这样别人才愿意帮你。完成比完美更重要你的第一个游戏可能很简陋Bug很多。没关系把它做完看到小球动起来砖块被击碎那种成就感是无与伦比的。它是你继续前进的最大动力。优化和重构是下一个阶段的事情。这条路不会轻松你会无数次与编译错误、诡异的Bug和失控的代码作斗争。但每解决一个问题你对计算机如何工作、游戏如何运行的理解就会加深一分。当你最终看到自己亲手创造的世界在屏幕上活起来接受玩家的操控时你会觉得这一切都是值得的。拿起你的编译器从今天从第一行“Hello, Game!”开始吧。