`
kyg313wd
  • 浏览: 11652 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

游戏编程101

 
阅读更多

游戏编程101
2011年11月21日
  游戏编程101
  前言[/b]
  我曾经写过一些小的关于游戏初学者的编程指南,现在我决定把这些小文章组织一下,形成一个系列指南,当然了,是针对初学者的。(老鸟就不用看了)我一直怀疑游戏编程是否能给你带来财富,但是世事如棋,努力的工作加上一点想象力,你可能发大财呀!(我并没有想向你要钱的意思)。
  最初,我考虑连同一个小游戏同时讲解,直到游戏完成,后来我放弃了这个想法,决定写一篇广泛一点的文章。只要我有时间,我就会写下去的。
  阅读本篇文章,你学要有一些C和C++的基础知识,原因是我经常混合使用它们,因为有些部分用C表达好一些,而有些部分用C++表达好一些。如果你只熟悉其中的一种,我想不会影响你看懂这篇指南的。如果你真的遇到困难,你可以写信给我,我将竭力帮助你。
  当然了,我如果没能达到我所预期的目的,我也是同你一样的人,难免会出错。如果你发现任何错误,请告诉我,谢谢。
  开始吧!
  [b]非常初级
[/b]
  实话实说,任何一个希望自己有一个光明前途的游戏程序员,至少要了解DirectX。当然,还有其它的工具,如图形工具OpenGL和最新的音频工具OpenAL,但是近期的工业标准是DirectX,所以我们就用它。你还需要一个编译器,能够编译成Win32可执行文件的。(这里我们将使用Microsoft Visual C++6.0,当然,其它的也可以)和一个DirectX SDK软件包。(我们将使用7.0版本)你可以从Microsoft的主页上下载。
  我也假设你知道怎样编译普通的Win32文件和使用扩展库。使用DirectX前需要一点准备,下面我介绍一下在Visual C++6.0中的配置DirectX的过程:
  首先点击Tool菜单,选择Options,然后点击Directories,在Show Directories for 组合框下拉菜单中选择Include files,增加一个新的目录。将你的DirectX的路径填入。(例如:C:\DXSDK\include)然后将它移到列表的第一位,使编译时第一个寻找它(防止寻找老版本)。然后选择Show Directories for组合框下拉菜单中的Library files,方法同前,只是把\include改成\lib。现在,你已经设置完了DirectX。你仍然需要手动增加一些库文件到你的项目中,但先不急,我将在下一部分讲它。
  我们将着手第一个游戏Pong Clone(不知道怎么翻译,惭愧),你有很多途径去编写游戏,我将介绍我喜欢的一条途径,如果你喜欢其它的,随便你了。我坚持用它是因为我当学徒期间一直用它。
  我的编写游戏过程是:
  1.  设计完整的游戏
  2.  建立所有的游戏资源、游戏引擎和游戏必备的工具。
  3.  在测试平台上开发各个部件。
  4.  组合各个部件为一个完整的游戏
  5.  测试和更正。
  6.  定草稿
  7.  让公众测试
  我喜欢用以上步骤完成游戏的制作;如果你有自己的,最好用自己的。
  提醒注意:第三条可以理解为边开发各个部件边测试各个部件。
  [b]▲第一个设计
[/b]
  当我最初编写游戏时,我从来没有事先设计过,我认为这是一项乏味的工作,我不喜欢它(现在我也不太喜欢)。因为我认为游戏在我的头脑中,设计或者是不设计,根本就不会影响我编写程序代码。现在,我知道我错了,完全的错了。事先设计好游戏,可以使你全面的考虑好整个游戏,不至于有大的纰漏,更不至于当你写完500行代码后,发现这个结构就不应该这么定义,这个周末的工作被扔进了垃圾箱。尽管我们所要编写的这个Pong游戏是一个十分小的游戏,但我们仍然先在纸上把它勾画出来,而不是只在头脑中勾画。当然,如果你有自己的设计模板,用你自己的好了,萝卜青菜各有所爱吗!我习惯于自己的方式并且它可以使我更舒服的设计自己的游戏。
  ◎     简介
  这是一个简单的游戏介绍。该游戏运行在Windows平台,需要DirectX插件。进入游戏后,游戏者控制的飞船要反击另一个游戏者或电脑,目的是使球通过目标区域。
  ◎     最小的说明书
  你可能想忽略设计文档的这一部分,但是它的确是组成完整游戏设计文档的必备部分。
  奔腾166以上CPU
  16M以上显存
  3M以上硬盘空间
  与DirectX完全兼容的显示卡
  Windows 95,98或者2000
  ◎     游戏规则
  这一部分是必不可少的,即使再小的游戏也需要。大游戏可能要把这部分分解成好几部分。
  本游戏的规则十分直接和容易,游戏的目的是得分。游戏操纵者要使球通过目标线,而对手(另一个游戏者或电脑)不让球通过。优秀者控制的飞船只能在固定的区域移动。【我没有玩过,所以只能翻译成这样,领会精神】
  ◎     菜单
  这一节可以分成几个部分,当然,小游戏可能写在一个或者两个部分里面就OK了。
  主菜单由四个部分组成:新游戏、最高记录、积分榜、退出游戏。背景你可以放上一张图,任你行。
  #新游戏:弹出另一个菜单,你可以选择难易程度和单人游戏或双人游戏。
  #最高记录:显示最高的得分
  #积分榜:所有的或者前十名的分数
  #退出游戏:问是否真的要退出,选择后退出或者返回游戏
  当你暂停游戏时,会弹出一个菜单,由三个选项组成:继续游戏、重新开始游戏、退回到主菜单。
  #继续游戏:就是继续游戏
  #重新开始游戏:就是重新开始游戏
  #退回到主菜单:可以重新选择难度及其它
  ◎     图形
  所有的图形都将从SpriteLib库产生。所有的背景图片你可以找一些星空图片代替。
  ◎     图形引擎
  有时这一部分同设计文档分开。
  这里将制作一个图形引擎Ping,它可以从磁碟导入图片,渲染和平滑移动。
  文字部分将用GDI(Graphics Device Interface)实现。
  ◎     游戏的操纵
  通常游戏都允许操作者自己设置操纵键,但是这里我们就武断一点,已经定义好了。
  控制飞船相当容易,第一个游戏者只需要控制两个键,UP和Down(就是上下键),另一个游戏者控制A和D键,飞船只能上下移动。(不要失望,我们只是在学习)
  ◎     人工智能
  若是大一点的项目,我会单独拿出一个文档讨论它的。但这里就不必了。
  本游戏有四个难度级别:容易、一般、难、你疯了。
  电脑将根据选择的难度级别利用不同的计算公式和循环判断来反击游戏者。
  ◎     进度表(时间表)
  这是编写游戏最可能出现问题的部分。几乎没有人能够精准的为游戏创作制定时间表,但游戏每一部分的生成需要一个时间表。
  这里我就不做时间表了,因为我只能利用业余的时间为大家写文章。
  这就是全部的计划文档,当然了,是按照我的喜好作的,你可以有自己的。
  [b]▲开动吧!
[/b]
  §前言
  我回来了,带来了一些好消息和一些坏消息。坏消息是我们可能不能继续进行上篇文章所说的立即编写程序,原因是我们还需要介绍一些前提的工作,尤其是Win32构架和错误处理,学会了这些后,我想我们能更容易应用DirectX。好消息是文章的结尾处将要给一个完整的源代码。它可能不是很好,但它能工作。(至少我希望如此)
  废话少说,让我们干吧。
  §错误处理
  在我们介绍Win32架构前,我们先应该创立一个错误处理系统。由于用GDI在DirectX里显示文本不是很快,我们用自己的出错文本文件代替。我们还要建立一个必要的退出功能,当文件编译出错时,我们不希望死机。我们将建立Cerror类来处理所有的出错信息。类的原形将是下面的样子:
  class Cerror
  {
  public:
  FILE *fErrorLog;
  Bool bQuit;
  LPSTR  lpzMessage;
  CError(LPSTR,bool);
  ~CError();
  ProcessError(DWORD);
  };
  现在我们来为每一个变量做一个简短的解释。FErrorLog是一个指向所有出错信息的指针;bQbuit是一个布尔变量,通过被赋值true或false来决定程序出错时是否退出;lpzMessage是实际的错误信息,系统将分配适当的内存给它;CError是构造函数,它有两个参数,字符串参数和布尔参数,当程序出错时,相对应的出错信息将传递给字符串参数,代表是否退出程序的true或false将传递给布尔参数。~CError()是析构函数,将释放我们所占用的内存。
  对于C语言程序员来说,类就相当于结构的功能,当然,类有更广泛的应用,但我们将不涉及它。
  下面我们将开始错误处理程序的编码。首先我们必须编写构造函数和析构函数。
  CError::CError(LPSTR lpzFileName,bool  bQuitOnError)
  {
  fErrorLog = fopen(lpzFileName , “wt”);
  bQuit = bQuitOnError;
  }
  CError::~CError( )
  {
  }
  构造函数的内容很简单,首先以文本模式打开了一个以wt命名的文件,并把文件内容赋值给了fErrorLong,然后把退出标记赋值给了bQuit。
  目前,析构函数是一个空函数。
  下一部分是错误处理的核心。现在,它是非常基础的,不过我们会不断增加内容的。
  CError::ProcessError(DWORD dwError)
  {
  DWORD  dwMsgSize;
  Switch(dwError)
  {
  default :
  dwMsgSize = strlen(“Unkown error”);
  lpzMessage = (LPSTR)malloc(dwMsgSize + 1);
  strcpy(lpzMessage,”Unkown  error”);
  break;
  }
  if(fErrorLog != NULL)
  {
  fprintf(fErrorLog, lpzMessage);
  }
  if(lpzMessage != NULL)
  {
  free(lpzMessage);
  }
  if(bQuit == true)
  {
  if(fErrorLog != NULL)
  {
  fclose(fErrorLog);
  }
  PostQuitMessage(dwError);
  }
  return 0;
  }
  让我们仔细的看这段程序,我们首先声明了一个变量存放字符串的长度;然后用switch检测程序正在哪个错误上。马上,我们发现只有default(默认)状态,它处理了三件事:1、检查了字符串的长度;2、分配足够的内存空间给它;3、把它拷贝给类的成员变量lpzMessage。然后我们检测是否有必要把消息传送给文件并且显示出来。然后我们释放字符串占用的内存,最后检测是否应该退出程序和关闭文件。
  我想加入下面两项功能:1、无论我们想要加入一个什么样的错误检测,都应该在default之前,我们将稍后做它。2、我们没有作任何检测错误检测功能的本身是否正确,这是你的作业。试着检测一下内存是否分配正确,文件是否被成功打开等等。自己试一试,若有问题可以给我写信 akura@crosswinds.net (英文的),我将尽力帮助你。
  我们现在需要一个类的实例:
  CError  ErrorHandling(“errors.log”,true);
  它是做错误处理的。
  现在让我们进入Windows的世界。
  [b]▲
Win32的框架[/b]
  据我所知,很多游戏程序员都没有系统的学习过Windows编程基础,他们往往从别的程序里拷贝窗口的框架,当然,这并没有什么错。我也并不是想教你Windows API的编程,但我将教你一点建立窗口的必备知识。
  char szClassName [] = "Chapter2";
  char szWinName [] = "Chapter2";
  LRESULT CALLBACK WndProc(HWND,UINT, WPARAM, LPARAM);
  头两个变量是类的名称和窗口的名称,我们将马上用到。第三行实质上是消息处理。
  对于DOS和UNIX的程序员来说,C/C++程序总是从void main()开始,在Windows里,从WinMain开始,并且含有几个参数,你必须需要window.h这个头文件。
  int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  {
  MSG    msg;
  HWND    hWnd;
  WNDCLASSEX  wcl;
  bool    bRunning;
  ZeroMemory (&wcl, sizeof (WNDCLASSEX));
  wcl.cbSize  = sizeof (WNDCLASSEX);
  wcl.hInstance  = hInst;
  wcl.lpszClassName = szClassName;
  wcl.lpfnWndProc = WndProc;
  wcl.style   = 0;
  wcl.lpszMenuName = NULL;
  wcl.cbClsExtra  = NULL;
  wcl.cbWndExtra  = NULL;
  wcl.hIcon  = LoadIcon (NULL, IDI_APPLICATION);
  wcl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
  wcl.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
  WinMain返回的类型是int APIENTRY。接下来有四个参数(括号里的):第一个是当前的实例句柄;第二个在Windows98、95、NT中已经不用了,通常设置为NULL。第三个是一个指向字符串的指针。反正很少用它,先不理它。第四个参数决定了窗口在初始显示时的状态。
  我们还需要四个变量。第一个是消息变量msg,该变量保存有对于执行代码而言非常重要的信息。每当接收到新的消息时,消息变量的值就被重新装入。第二个变量hWnd指的是实际的程序窗口。第三个变量wcl将掌握窗口类的信息。第四个变量bRunning指明程序是否运行。
  剩下的就是窗口类的信息。就不多说了。【若不懂,参看《Windows图形编程》。译者按】
  if (!RegisterClassEx(&wcl))
  {
  ErrorHandling.ProcessError (ERROR_REGISTER_CLASS);
  return (-1);
  }
  上面这一小段儿是说:进行窗口类注册,若有错,调用错误处理功能。你需要把#define ERROR_REGISTER_CLASS加入到Error.h头文件中,并把下列代码加入到ProcessError的default:前面。
  case ERROR_REGISTER_CLASS :
  dwMsgSize = strlen ("Chapter 2 - Error log file\nCould'nt register class...\n");
  lpzMessage = (LPSTR) malloc (dwMsgSize + 1);
  strcpy (lpzMessage, "Chapter 2 - Error log file\nCould'nt register class...\n");
  break;
  这将增加一个“Couldn’t register class”(不能注册类)的错误处理。
  回到WinMain,我们还需要创建和显示窗口。我们来设置类的名称,窗口的名称和窗口的类型,窗口的坐标和大小(0,0,640,480),父窗口,没有默认得菜单,当前的实例和最后赋值为NULL的参数。最后我们显示窗口。如下:
  hWnd = CreateWindow (szClassName, szWinName, WS_OVERLAPPEDWINDOW,0 , 0, 640, 480,
  HWND_DESKTOP, NULL, hInst, NULL);
  ShowWindow(hWnd, nCmdShow);
  现在我们来到WinMain的最后一个环节,创建一个消息循环。程序在此处不断检测消息或命令的输入,并将相应的消息发送出去,传送给消息处理部分。
  while (bRunning)
  {
  if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  {
  if (msg.message == WM_QUIT)
  {
  bRunning = false;
  }
  TranslateMessage(&msg);
  DispatchMessage(&msg);
  }
  else
  {
  }
  }
  return 0;
  }
  最后,我们return 0,来让程序知道一切正常。
  完了吗?还没有,我们还需要谈谈信息的处理部分。
  [b]▲信息的处理
[b][/b]
  LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  {
  switch (msg)
  {
  case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
  default:
  return DefWindowProc (hWnd, msg, wParam, lParam);
  break;
  }
  return 0;
  }
  所有的消息处理多是如此样子,不用太深究参数部分。Switch部分才是重要的。最简单的就是如上:只有一个case WM_DESTROY,它的地作用就是接收到关闭窗口的命令(消息)时,执行PostQuitMessage。所有不是程序需要处理的消息,都通过default下的DefWindowProc 处理了。
  ▲     结论
  就到这里吧。我希望你能了解我们所讲到的,如果你有问题或建议,写信给我。akura@crosswinds.net (英文的)谢谢你有耐心读完这篇文章。下载源代码请到
  http://www.gamedev.net/reference/programming/features/gp101_2/Chapter2.zip
分享到:
评论

相关推荐

    [C++游戏编程入门]101-200页.pdf

    C++游戏编程入门:英文版教程,从基础介绍C++游戏编程。

    游戏编程精粹8--随书光盘源代码(part2/2)

    该资料是《游戏编程精粹8》一书的随书光盘代码:共两部分,这是第2部分 游戏编程精粹8 基本信息 中文名: 游戏编程精粹8 原名: Game Programming Gems 8 作者: Adam Lake 图书分类: 软件 资源格式: PDF 版本: 插图...

    游戏编程精粹8--随书光盘源代码(part1/2)

    该资料是《游戏编程精粹8》一书的随书光盘代码:共两部分,这是第1部分 游戏编程精粹8 基本信息 中文名: 游戏编程精粹8 原名: Game Programming Gems 8 作者: Adam Lake 图书分类: 软件 资源格式: PDF 版本: 插图...

    VC++6游戏编程入门及源码

    4.2.3 变量函数……………………………………………………………………(101) 4.2.4 具体实现……………………………………………………………………(102) 4.2.5 附加内容……………………………………………………...

    游戏编程指南 doc

    游戏编程指南 1 目 录 1 导 读 1 第一章 表述游戏的语言 1 1.1 VC.net概述 1 1.2 入门知识 4 1.2.1 数与数据类型 4 1.2.2 变量与常量 4 1.2.3 Namespace 5 1.2.4 操作符与表达式 6 1.3 预编译指令 7 1.4 结构,...

    VC++6.0游戏编程

    4.2.3 变量函数……………………………………………………………………(101) 4.2.4 具体实现……………………………………………………………………(102) 4.2.5 附加内容……………………………………………………...

    VC++6 游戏 编程

    4.2.3 变量函数……………………………………………………………………(101) 4.2.4 具体实现……………………………………………………………………(102) 4.2.5 附加内容……………………………………………………...

    台北101大楼-少儿编程scratch项目源代码文件案例素材.zip

    台北101大楼-少儿编程scratch项目源代码文件案例素材.zip

    200个经典C程序源码小游戏

    147 VGA256色模式编程 148 绘制蓝天图案 149 屏幕检测程序 150 运动的小车动画 151 动态显示位图 152 利用图形页实现动画 153 图形时钟 154 音乐动画 第五部分 系统篇 155 读取DOS系统中...

    游戏之旅--我的编程感悟【有目录】

    第1 章计算机,游戏,我_ 我,云风,从二十年前的计 算机游戏萌芽阶段一路走来。计 算机,并不神秘。程序,也只是 表达计算机控制逻辑的符号而 巳。 第2 章算法,程序的灵魂 算法,先千计算机存在于世, 比编程语言...

    我的编程感悟(中文PDF)(共37M二分卷)分卷二

    本书忠实地记录了作者十余年来对游戏编程的所思、所感、所悟。全书按照作者本人学习和实践的过程,带着读者从基础的计算机知识到高级的编程技术,从非常专业的汇编优化到非常实际的项目管理进行了一次游戏开发的全景...

    VC++小游戏开发实例教程

    4.2.3 变量函数……………………………………………………………………(101) 4.2.4 具体实现……………………………………………………………………(102) 4.2.5 附加内容……………………………………………………...

    射击类小游戏c++源代码

    在VC++6.0的环境下,用C++语言利用了EZwin编写的原创射击类小游戏,代码简单,适合初学者了解如何在屏幕上显示图片,加入音乐等问题。

    linux编程白皮书

    9.4 游戏杆编程 308 第10章 把应用程序移植到Linux上 309 10.1 介绍 309 10.2 信号处理 309 10.2.1 SVR4、BSD和POSIX.1下 的信号 310 10.2.2 Linux信号选项 310 10.2.3 Linux下的信号 310 10.2.4 Linux支持的信号 ...

    Linux编程资料

    9.4 游戏杆编程 308 第10章 把应用程序移植到Linux上 309 10.1 介绍 309 10.2 信号处理 309 10.2.1 SVR4、BSD和POSIX.1下 的信号 310 10.2.2 Linux信号选项 310 10.2.3 Linux下的信号 310 10.2.4 Linux支持的信号 ...

    Windows网络编程

    91.3.3 传输层 91.3.4 应用层 101.4 网络接口层及其相关协议 101.4.1 面向字符的链路层协议和面向比特的链路层协议 101.4.2 高级数据链路控制规程HDLC 111.4.3 X.25的链路层协议LAPB 131.4.4 点到点协议(PPP...

    Java趣味编程100例 清华大学出版社.zip

    第10章介绍了9个趣味游戏;第11章介绍了11个其他趣味问题。  本书适合高校、职业技术院校及社会培训学校的学生阅读,也适合Java编程爱好者阅读,还可作为各级程序设计选拔赛和全国青少年信息学奥林匹克竞赛的参考...

    网络游戏开发核心资料(英)

    WinSock2 游戏编程  网络游戏开发 101  异步 Sockets 编程指南  多用户的服务器/客户模式聊天工具的开发  TCP/IP 协议介绍摘要  如何设计一个多人游戏  多人游戏的本质  制作一套网络消息引擎  使用...

    经典网络游戏开发教程下载

    WinSock2 游戏编程\网络游戏开发 101\异步 Sockets 编程指南\多用户的服务器/客户模式聊天工具的开发\TCP/IP 协议介绍摘要

Global site tag (gtag.js) - Google Analytics