怎样去开发一款游戏

来源:互联网 发布:realtime pcr数据分析 编辑:程序博客网 时间:2024/03/29 04:16

最近有许多人问我怎样去开发一款游戏,网上并没有关于这个话题的文章,我就决定写一些东西来分享一下我的经验,关于游戏开发的整个过程。记住这只是一个概要,并且会因项目的不同而改变。


步骤一.选择你的游戏库
除非你想写自己的游戏库,包括那些麻烦的图形和声音编程模你应该需要一个开源的游戏库,他们都提供了相同的基本功能。
任何一款优秀的游戏库所需具备的特征:
加载和播放声音;
加载和显示图像;
基础的图像操作(旋转缩放等);
原始图形绘制方法(点,线,矩形等);
显示文字的方法;
多线程支持;
基本的计时器功能。

一些游戏引擎:
Simple Fast Multi-Media Library (SFML): http://www.sfml-dev.org/
Simple DirectMedia Layer (SDL): http://www.libsdl.org/
Allegro: http://www.allegro.cc/
penGL (GFX only, however, there are wrapper libs like AllegroGL): http://www.opengl.org/
DirectX (Windows only): http://msdn.microsoft.com/en-us/directx/
Irrlicht (3d lib): http://irrlicht.sourceforge.net/

步骤二.确定好剧本
所有游戏都从这里开始,想法来自大脑。
首先,想出一个游戏的点子,一旦你有了一个简单的点子,就去扩展它。例如,一个棋盘游戏,主题是什么,胜利条件是什么,规则又怎样。如果一个游戏有人物或故事,就去创造他们。一定要保证当你的游戏完成时,你对你的游戏将要成为什么样非常清楚。游戏越是复杂,在开始之前你就越需要花时间来计划,这样当你在编码的时候就不用去担心这些问题了。记住,你的游戏会像你当初创建它的样子。

步骤三.定制你的引擎
到这一步,你需要计划出你的游戏引擎所需的各个组件,并且能够让它们融合在一起,根据你项目的复杂程度,你也许不需要这个步骤,这也是检验你游戏引擎哥哥部分正常工作的好时机,确保他们在放到实际项目之前是正常工作的。同时,你也因该开始设计你项目中的类(如果你使用OOP的话)。记住,已经有一些现成的引擎,并且适用大部分的项目。

步骤四.编写你的引擎(如果你要自己动手的话)
现在可以正式开始编写游戏引擎了,这里不是说开始写游戏,而是核心渲染,物理,文件管理等等。用引擎里的类和方法来构建你的游戏。根据游戏的复杂度,引擎的代码可能与游戏的代码类似。
对于一个很复杂的游戏,可能还需要一个资源管理器,一个资源管理器所做的就像它的名字那样,管理资源(图像,音乐,声音等等),它可以保持代码整洁,并帮助你避免内存泄漏。可以参考一个优秀的资源管理器Xander314.尽量让你的代码严谨,接口简单,这样做之后,当你在写游戏的时候就不需要去查看源代码,找函数名了。一种好的编程方式就是OOP。
//put related components into classesclass collisions {    bool check_col(obj1*, obj2*); //you should have a base object class that all    void handle_col(obj1*, obj2*); //game objects are derived from, for easy passing to functions    public:        void handle_all(); //handles EVERYTHING collision related    }Collision;class rendering {    void bots();    void bullets();    void players();    public:        void draw_all(); //calls other functions for rendering    }Renderer;//this allows collision management and rendering in your game loop to be as simple as:Renderer.draw_all();Collision.handle_all();

Resource Manager by Xander314

/* ResourceManagerB.hpp - Generic template resource manager (C) Alexander Thorne (SFML Coder) 2011 <a href="http://sfmlcoder.wordpress.com/">http://sfmlcoder.wordpress.com/</a> Manages loading and unloading of a resource type specified by a template argument.****************************************************************/#include <map>#include <string>#include <exception>typedef const std::string URI;// exceptionsnamespace Exceptions {// thrown if user requests a resource URI not present in the manager's listclass URINotFound : public std::runtime_error { public: URINotFound(const std::string& Message = "The specified URI was not found in the resource index."): runtime_error(Message) { } };// thrown if a resource allocation failsclass BadResourceAllocation : public std::runtime_error {public: BadResourceAllocation(const std::string& Message = "Failed to allocate memory for resource."): runtime_error(Message) {}};}template <class Resource> class ResourceManagerB {typedef std::pair<URI, Resource*> ResourcePair;typedef std::map<URI, Resource*> ResourceList;// the list of the manager's resourcesResourceList Resources;public:~ResourceManagerB() { UnloadAll(); }// Load a resource with the specified URI// the URI could represent, e.g, a filenameURI& Load(URI& Uri);// unload a resource with the specified URIvoid Unload(URI& Uri);// unload all resourcesvoid UnloadAll();// get a pointer to a resourceResource* GetPtr(URI& Uri);// get a reference to a resourceResource& Get(URI& Uri);};template <class Resource>URI& ResourceManagerB<Resource>::Load(URI& Uri){// check if resource URI is already in list// and if it is, we do no moreif (Resources.find(Uri) == Resources.end()){// try to allocate the resource// NB: if the Resource template argument does not have a// constructor accepting a const std::std::string, then this// line will cause a compiler errorResource* temp = new (std::nothrow) Resource(Uri);// check if the resource failed to be allocated// std::nothrow means that if allocation failed// temp will be 0if (!temp)throw Exceptions::BadResourceAllocation();// add the resource and it's URI to the manager's listResources.insert(ResourcePair(Uri, temp));}return Uri;}template <class Resource>void ResourceManagerB<Resource>::Unload(URI& Uri){// try to find the specified URI in the listResourceList::const_iterator itr = Resources.find(Uri);// if it is found...if (itr != Resources.end()){// ... deallocate itdelete itr->second;// then remove it from the listResources.erase(Uri);}}template <class Resource>void ResourceManagerB<Resource>::UnloadAll(){// iterate through every element of the resource listResourceList::iterator itr;for (itr = Resources.begin(); itr != Resources.end(); itr++)// delete each resourcedelete itr->second;// finally, clear the listResources.clear();}template <class Resource>Resource* ResourceManagerB<Resource>::GetPtr(URI& Uri){// find the specified URI in the listResourceList::const_iterator itr;// if it is there...if ((itr = Resources.find(Uri)) != Resources.end())// ... return a pointer to the corresponding resourcereturn itr->second;// ... else return 0return 0;}template <class Resource>Resource& ResourceManagerB<Resource>::Get(URI& Uri){// get a pointer to the resourceResource* temp = GetPtr(Uri);// if the resource was found...if (temp)// ... dereference the pointer to return a reference// to the resourcereturn *temp;else// ... else throw an exception to notify the caller that// the resource was not foundthrow Exceptions::URINotFound();}



步骤五.图像和声音
基于你的游戏的观点,开始创建你的图形和声音特效。当你开始深入开发的时候,你可能需要去创造更大的GFX和SFX,还会删除掉那些不需要的资源,这个过程可能会贯穿整个过程。

步骤六.写游戏
当你完成了你的游戏引擎之后,你可以开始写游戏了。这包含了很多东西,包括规则,故事,游戏的主循环也会在这里创建。这个循环会一遍遍地跑,并且会更新游戏中的所有事物。

看下面的例子,如果你编写的引擎是正确的,这将比编写引擎更容易一些,也更有趣。当你在某个地方加入一些音效的时候,也会很棒。当舞台搭建完毕,你应该保存一份能偶跑起来的代码,确定你看到的是你所预期的。

//your loop will probaly be very different from this, especially for board games//but this is the basic structurewhile (!Game.lost()) //or whatever your condition is (esc key not pressed, etc){    Game.handle_input(); //get user input    AI.update_bots(); //let your bots move    Collision.handle_col(); //check for collisions    Game.check_win(); //see if the player won or lost    Renderer.draw_all(); //draw everything    Game.sleep(); //pause so your game doesn't run too fast    //your game lib of choice will have a function for this}



步骤七.优化
游戏能够跑起来并不意味着就完成了,除了添加最后一点剧情,你还可以对代码进行优化,包括内存使用(不要使用全局变量,检查内存分配等等),游戏提速(保证你的代码不会太慢,并且不是在任何时候都在大量地消耗CPU)。测试也可以放到这一步。

步骤八.打包发布
现在你的游戏完成了,你需要将其打包,然后发布。对于打包,尽量保持有调理,并把最终产品放进一个单文件中(安装文件,zip等),让发布变得更加简单。

提示
我至今已经学了很多关于游戏制作的知识,有些东西真的很难。
下面的事情你应该做好:
首先保持有条理。你应该对每一件事都有一个很好的整理,你的代码,你的图片,你的音效等等。我建议你把代码根据用途放到不同的文件中,比如说碰撞检测放到一个文件,资源管理放到另一个文件,AI放到另一个文件中......这样做的话,如果你需要跟踪一个bug,你会很容易找到对应的方法,还可能直接找到bug本身。保持代码的了好结构同理(不同的类处理不同的事,渲染,AI,碰撞检测等,而不是一口气在一个类里面写上上百个方法)。
同时,努力让代码保持整洁和高效,尽可能重用变量,避免使用全局变量,检查内存泄漏,不要一次性地加载所有的图形和声音等。
不要硬编码数据到游戏中,而是实现一个数据文件加载系统,这将保持代码的可维护行,并且当你想要升级的时候,不需要去编译所有的文件,

Chrisname的一些新手建议
你没必要工作得那么拼命,你需要做的是学习一套边吃的教程。不要在一天之内做太多的东西,否则就会厌倦或者没有动力。不要按时间设置目标,那没用的。如果你在学习中半途而废,你会忘掉你学的打部分的东西。把这个网址 ( http://cplusplus.com/doc/tutorial/ )上的教程都过一遍。目标是每天两篇。不要在中途停下来(除非是确实需要休息一下),不要一次性做太多,否则你会记不住,我建议你仔细阅读,并且去敲每一个例子(不是复制和粘贴,是自己亲手敲进去,这会帮助你了解代码的含义),编译并执行,看看发生了什么变化,修改一下代码,看看又有什么改变。我还建议你看一下别人的优秀的代码。当你在学习教程的时候,记住一件事-如果不能亲口解释清楚,就不算理解。
一旦你开始学习这篇教程或者其他的教程(我曾阅读过同一主题的三篇教程,因为用不同的方式表述同一件事对理解和记忆都很有帮助),你可以阅读一下SFML的教程(http://sfml-dev.org/tutorials/1.6/),学习SFML将会教你如何做2d游戏,我同样推荐你学习SDL(http://lazyfoo.net/SDL_tutorials/index.php ),因为很多游戏都用到了它,你最终也很可能完成。
之后,如果你想制作3D游戏,你应当学习OpenGL,SFML把这变得十分简单,SFML的教程中包含了使用OpenGL的教程,对于OpenGL或许这里的其他人能给你推荐一些书或教程。
在整个过程中,你应该记住,掌握好自己的节奏很重要,不要一口气吃成胖子,消化不了,第二天有考试的话,不要熬夜到半夜三点。

为了让开发变得简单,让游戏开发更加有效,你需要做的还有许多,但是这些是最重要的。


原文链接:http://www.cplusplus.com/articles/1w6AC542/

原创粉丝点击