⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g9.htm

📁 PC游戏编程
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html>
<head>
<title>游戏制作</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
<!--
body {  font-size: 14px}
td {  font-size: 14px}
a:active {  text-decoration: none}
a:link {  text-decoration: none}
a:visited {  color: #FFFFFF; text-decoration: none}
a:hover {  text-decoration: underline}
-->
</style>
</head>

<body bgcolor="#e8ffe8">
<br>
<table width="85%" border="0" cellspacing="0" cellpadding="0" align="center">
  <tr>
    <td>程序状态的转换 &nbsp;<br>
      我们在写DirectX程序的时侯,总有一种偏见,那就是不希望Windows界面出现在我们的&nbsp;<br>
      游戏里。于是什么都需要我们自己做。比如说窗口。因为窗口的刷新需要我们自己管理,&nbsp;<br>
      就觉得没有必要生成多个窗口了。这样所有的窗口消息就必须在唯一的一个函数里实现。&nbsp;<br>
      可是我们的游戏里有很多种不同的操作,比如界面,系统菜单,播放视频等,这些内容就&nbsp;<br>
      都必须在这个地方处理。所以我们就引入了程序状态这个概念。我们定义了一系列的状态&nbsp;<br>
      ,在每个状态里,有固定的操作和响应,状态之间的转换也在特定的时侯进行。这样我们&nbsp;<br>
      就很容易把一些关系不大的内容独立开来,降低程序的复杂性。 &nbsp;<br>
      其实我们在实现这一部分的时侯是很混乱的。你很难在代码中找到所有状态转换的地方&nbsp;<br>
      。但是它的实现很简单,一般的规则就是程序的对称性。有专门的装入函数和释放函数,&nbsp;<br>
      然后有显示函数,计算函数,鼠标消息响应函数,热键响应函数。在内部,需要结束本状&nbsp;<br>
      态时就发出一个状态转换的消息。在外部,只要在主程序的主循环和消息响应函数处针对&nbsp;<br>
      不同的状态执行它们不同的函数就可以了。 &nbsp;<br>
      这里的关键在于状态的转换。因为状态在转换中一定会释放和申请大量内存,如果有的&nbsp;<br>
      内存没有释放,转换次数一多就会出现问题。如果我们把状态转换的地方写好了,程序看&nbsp;<br>
      起来也非常干净整齐,Bug也会比较少。 &nbsp;<br>
      现在编写游戏,需要装入的图量非常大,很有必要制作一个装入时的画面,并且显示百&nbsp;<br>
      分比。这是我们可能需要一个装入中的状态。遗憾的是&lt;赤壁&gt;并没有实现这个,它的淡入&nbsp;<br>
      淡出效果仅仅是效果,程序在执行这部分时停止在这里。 &nbsp;<br>
      有关内容请详见CBGame.cpp和Interfac.cpp。 &nbsp;<br>
      &nbsp;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;执行任务 &nbsp;<br>
      一个士兵在接到我的命令之后,便开始了它的行动。它察看了一下它的命令,这是由两&nbsp;<br>
      个部分组成的。它先取出第一个部分,是行走。于是根据自己现在的位置和目的地位置先&nbsp;<br>
      计算了一下路线,把自己当前的状态设置为正在移动,然后根据计算好的方向和自己的速&nbsp;<br>
      度把自己移动到一个位置。如果这个位置已经到达目的地了,它就停止行走。又察看了一&nbsp;<br>
      下剩余命令的部分,是攻击。于是它拔出刀砍向附近的一个敌人。敌人死了么?它不停地&nbsp;<br>
      问自己。如果敌人真的&quot;哇&quot;的一声倒下了,它就得意地站在一旁,微笑着。 &nbsp;<br>
      这就是我们在战场的一个角落所看到的一个士兵的表现。而实事上,在程序里我们也是&nbsp;<br>
      这样做的。 &nbsp;<br>
      我们把每个士兵做为一个单元,独立地处理自己的事物。我们把每个命令划分得更加细&nbsp;<br>
      致,而称其为状态,执行每个状态时所需要的参数的执行的步骤是最简化的。每个命令都&nbsp;<br>
      是由一个或多个状态组成的。一个状态满足后就自动转向下一个状态。我们为每个状态都&nbsp;<br>
      编写专门的开始,运行中,和结束代码。这样每个士兵都在独立地按照顺序处理自己的事&nbsp;<br>
      务,一个个复杂的单元行动就变得有条有理了。 &nbsp;<br>
      有关内容请详见CBRun.cpp。 &nbsp;<br>
      &nbsp;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;阴影 &nbsp;<br>
      有人说Warcraft做得好,有人说C&amp;C做得好。我属于前者一派,这不仅仅因为我对&nbsp;<br>
      Warcraft的观察多一些,而且有一个理由足以说明Warcraft在程序上比C&amp;C更高一筹。那&nbsp;<br>
      就是阴影。大家都知道Warcraft是双层阴影,而C&amp;C是单层。双层阴影的好处是更加真实&nbsp;<br>
      。在我们去过一个地方之后,虽然我已经看清楚了地形,但是这里敌人的活动,我们不应&nbsp;<br>
      该永远知道。可是要把单层阴影变成双层,并不是只要加上一层显示就可以解决问题的。&nbsp;<br>
      &nbsp;<br>
      首先,增加一层阴影就增加了需要显示的时间。时间对于即时战略来讲是至关重要的。&nbsp;<br>
      它直接影响到游戏的表现效果和操作速度。多加一层阴影就意味着减少了我们增加效果的&nbsp;<br>
      机会。在我们这里,双层阴影占用了大约5-10%的显示时间。 &nbsp;<br>
      其次,增加一层阴影就增加了特殊的计算。一层阴影只需要一个二进制数组记录哪里被&nbsp;<br>
      打开,哪里被隐藏就可以了。而现在则不同,我们需要把那些已经打开的阴影再关上。我&nbsp;<br>
      们的做法是生成一个二维数组,每位表示一个图素格子。当有一个士兵的视野可以打开这&nbsp;<br>
      个格子上的阴影时,就把那里的计数器加一,离开时减一。当为0时则这块地形被重新隐&nbsp;<br>
      藏。 &nbsp;<br>
      第三,阴影下的单元需要特殊的处理。当我的士兵离开敌人阵地的时侯,敌人附近被半&nbsp;<br>
      透明的阴影重新覆盖了,这时我们需要把正在那里活动的敌人士兵隐藏起来,而建筑不动&nbsp;<br>
      。 &nbsp;<br>
      这就是双层阴影所带来的。可是为了效果,我们不得不如此。看起来还是达到了效果。&nbsp;<br>
      &nbsp;<br>
      除了双层阴影以外,阴影的边界也是很重要的问题。我们不可能把阴影做得和刀切的一&nbsp;<br>
      样,而让它必须和打开的地面相结合。于是我们必须要有一套贴图,用于阴影边界的各个&nbsp;<br>
      方向。好在我们在这里利用了一个偷懒的办法(当然是很巧的办法,是Onefish想出来的)&nbsp;<br>
      。我们采用了一个椭圆的贴图,让相邻的椭圆相切,从而造成边界。因为椭圆是没有方向&nbsp;<br>
      之分的,我们也就节省了一些贴图的内存和对使用哪张贴图的复杂计算。 &nbsp;<br>
      有关内容请详见CBShadow.cpp。 &nbsp;<br>
      &nbsp;<br>
      &nbsp;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;选中谁了 &nbsp;<br>
      &lt;赤壁&gt;战场里的格子是菱形的。这一点有多少人发现了?又有多少人知道它的代价?或许&nbsp;<br>
      有人认为菱形的格子并不是个很好的注意,但我们恰巧在这里使用了它。当鼠标按下时我&nbsp;<br>
      们需要知道它放在哪个格子里了。过去的经验是只要知道该点的位置和每个格子的宽度我&nbsp;<br>
      们就可以很快地算出格子的序号。但是在这里不行,因为格子是菱形的,在一个矩形区域&nbsp;<br>
      里的点不能被确定它到底属于哪个格子。 &nbsp;<br>
      怎么办呢?我制作了一个二进制二维数组,大小是格子的宽和高。在这个区域里,如果是&nbsp;<br>
      属于矩形内接菱形区域内的点设置为1,否则为0。当鼠标在某个矩形区域里时,我就用这&nbsp;<br>
      个栅格去判断该点的位置上的数值是1还是0。是1则这个点在这个菱形格子里,否则不在&nbsp;<br>
      。这个办法是我遇到的比较迅速的一个办法。 &nbsp;<br>
      &nbsp;<br>
      &nbsp;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;命令的产生 &nbsp;<br>
      一个由游戏者发出的命令,一般有三个部分:命令主体,命令本身和命令客体。命令主&nbsp;<br>
      体就是执行命令的人。我想对这支部队下达命令,这支部队就是命令的主体,在游戏里就&nbsp;<br>
      是我们用鼠标选中的一群士兵。命令本身是命令的标识。我想下达的是什么样的命令,在&nbsp;<br>
      游戏里,可能是我按下了某个命令按钮。命令客体是命令结果的接受者,如果我选择了攻&nbsp;<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -