当前位置: 首页 > 工具软件 > ZhanQi > 使用案例 >

《ZhanQi》开发总结

蓬弘
2023-12-01

ZhanQi》开发总结

前言

说来可笑,上学期期末时Boss叫我没事开发一个战旗类的游戏时,我的回答是:“什么是战旗类的游戏?”搞得他还给上了一课,并发给我一个经典的游戏《火焰之纹章》。自己大概玩了一个星期吧,的确很经典的游戏。于是决定假期“开发”一款类似的2D战旗类游戏,这个项目也就由此而来了。

开始时自己认为不是很复杂的东西,初生牛犊不怕虎,自己已经看了一个学期游戏制作方面的资料,感觉是该做点东西了,于是自己晚上睡不着的时候便构思这个游戏架构,大概一个星期的时间吧,就开始写了,本想一个假期完成自己的“处女作”,可项目远比自己想的复杂。

由于是寒假,各种客观原因(借口吧!),在家基本上什么也没做,计划被打乱了;无奈之下,决定提前一星期回学校,希望完成这个“项目”,做一些东西。

终于一分耕耘一分收获,五千多行代码,虽然不是很成功,但自己的工作基本上是完成了。。。

游戏概述

游戏名称

ZhanQi》,实际自己本想做个通用性的东西,类似2D战旗类的游戏引擎,所以起了这个名字。自己并不打算做美工和策划的工作,不太擅长吧!这也是自己初期比较郁闷的原因——由于回来的比较早,工作室只有自己,一人兼三类人的工作!不过还好,只是2D的图片处理,顺便还练习了PSDirectX Texture Tool的使用。

游戏类型

2D战旗类游戏,自认为此种游戏轻松休闲,开发智力。

开发环境

工具:Microsoft Visual Studio 2005

包含库:DirectX 9.0c

由于是2D的战旗类游戏,没有用到DX3D功能,只是用到了Sprite(图元精灵)处理图片的显示,dmusic.h处理游戏声音的播放,dinput.h处理输入,D3DXFont处理文字的显示;真正用到的DX的功能很少。真正复杂的是游戏的逻辑处理和大量资源的配置。

编码实现

自认为自己写的东西可读性还是不错的,游戏文件的处理逻辑性还可以,主要是因为开始自己并不是想做一个游戏,而是弄一个此类游戏的框架。注释是一定要的,这一点感触颇深:当代码达到千行级时,不写注释会疯掉的!

下面是游戏所包含的主要文件:

CGameHeader.h——游戏所包含的所有DX库,windows库,以及全局的宏定义,游戏状态的枚举类型,子状态的枚举类型(战斗状态的细分,实际是后来加上的,前期没考虑全面)。

CGame.h——游戏类的定义,最复杂的类,包含所有游戏资源,逻辑处理;对外接口只有init(),render(),over()。

MainWindow.cpp——包含游戏的住入口。

游戏结构

CGame类处理所有的游戏逻辑。对外接口只有init(),render(),over(),供主函数调用。

其中init()中完成游戏的初始化,包括d3dinit(),windowinit(),loadmain(),loadmission(),loadpreffile()。Loadmain()会自动加载main.als文件,读取默认的配置文件和默认的任务文件,以完成loadmission()和laodpreffile();实际这里自己本想定义自己的脚本的,应该不是很难,只是简单的字符串处理,但只是构想而已,没有实现。

Render()中包含PreRender(),进行渲染前的游戏逻辑处理(gameLogic()),输入处理(inputProcess()),时间的更新(updateTime())。后是根据当前的游戏状态渲染各个游戏元素,包括角色,背景图片等等。

Over()自己实际本想释放所有游戏资源的,包含releaseAll()和gameReset()。

游戏元素

游戏元素主要是地图,角色,物品。还有一些游戏资源,像各个背景图片,可以由游戏逻辑随时调用;音乐资源,可以实现,但自己没有完成。

地图

地图相当复杂,包含大量信息,与角色战斗,行走都有关系。地图信息为

struct SMapData         // 地图信息结构[ 2/5/2008 Arthur]

{

int NumOfSprite; // 图元编号[ 2/5/2008 Arthur]

int NumOfSpriteUnit; // 在特定图元内的图元点[ 2/5/2008 Arthur]

int Damage;        // 攻击加成[ 2/5/2008 Arthur]

int Defend;   // 防御加成[ 2/5/2008 Arthur]

int IsStay;   // 是否存在玩家,-1为无[ 2/5/2008 Arthur]

int LevelOfWalk; // 对单位行走的影响程度[ 2/5/2008 Arthur]

int TaggerID;  // 触发器编号,-1表示没有出发器[ 2/5/2008 Arthur]

int DrawFlag; // 绘制标记,表明绘制[ 2/19/2008 Arthur]

};

CMap类管理地图,其继承自CTile类。Ctile类是自己从书中看来的,很通用的2D地图贴片类。

角色

角色是包含属性和行为,由CGameRole管理,实际自己设计的不好,看书中应该把属性和行为分开,这样逻辑性更强些,而且方便处理。自己把属性和行为放在一个类中,增加了后期调试的复杂性和思考的程度。

角色属性包括:

// 各人物属性[ 2/9/2008 Arthur]

int                m_HP;                       // 当前生命值[ 2/9/2008 Arthur]

int                m_MaxHP;               // 最大生命值[ 2/9/2008 Arthur]

int                m_Level;               // 等级[ 2/9/2008 Arthur]

int                m_Experice;                 // 经验值[ 2/9/2008 Arthur]

int                m_Mind;                     // 智力,决定魔法[ 2/9/2008 Arthur]

int                m_Strength;                 // 力量,决定攻击力[ 2/9/2008 Arthur]

int                m_Deft;                     // 敏捷,决定攻击速度[ 2/9/2008 Arthur]

int                m_Skill;               // 技巧,决定命中率[ 2/9/2008 Arthur]

int                m_Speed;               // 速度,决定移动距离[ 2/9/2008 Arthur]

RoleAttribute m_Attribute;           // 人物属性,攻防相关[ 2/9/2008 Arthur]

int                m_AtactDistance;       // 攻击距离,,[ 2/26/2008 Arthur]

bool          m_IsBoss;              // 是否为Boss,与情节,攻击有关[ 2/29/2008 Arthur]

bool          m_IsDead;              // 是否死亡[ 3/1/2008 Arthur]

RoleCarrers        m_Carrer;              // 职业[ 2/9/2008 Arthur]

RoleActions        m_CurrAction;          // 动作状态[ 2/9/2008 Arthur]

 

角色行为包括:

enum RoleActions        // 人物行为状态[ 2/6/2008 Arthur]

{

Stay = 0,

PreMove,

Move,

PostMove,

Battle ,

Fight,

Say,

Listen,

};

主要是静止,说话,听,移动,战斗,使用物品(没有实现)。

物品

自己本想用CItem来管理物品,但因为时间原因没有实现,实际游戏中一切和物品有关的部分都没有完成。开学了。。。

焦点

焦点只是一个三针的动画,用以显示,选择角色等功能,用CFoucs类来管理,其继承自动画类CSpriteAnimation

整体逻辑

游戏逻辑还是用一般的方法——依据游戏状态处理。主要的游戏状态在CGameHeader.h中定义:

enum GameState

{

GameState_MainMenu=0,

GameState_SaveMenu,

GameState_LoadMenu,

GameState_OptionMenu,

GameState_InGameStory,

GameState_InGameBattle,

GameState_InGameMessage,

GameState_AskingOver,

GameState_GameOver

};

 

// 当游戏处于战斗状态时,其中包含的各种分状态[2/23/2008 Arthur]

enum BattleState

{

BattleNone = 0,             //  [ 2/23/2008 Arthur]

BattleMove,                 // 角色移动[ 2/23/2008 Arthur]

BattleSelect,          // 选择选项,决定下一步[ 2/23/2008 Arthur]

BattlePreFight,

BattleFight,           // 战斗中[ 2/23/2008 Arthur]

BattleQury,                 // 帮助状态[ 2/23/2008 Arthur]

};

 

游戏中大概分菜单状态和游戏中,游戏中又分为情节状态和战斗状态,战斗又分为战斗子状态。实际战斗子状态的设置是自己后来加上去的,开始设计时没想到战斗会这麽复杂,致使后面处理时根本没办法进行游戏逻辑,没办法,只能修正,导致游戏状态逻辑性下降。实际这是设计的问题,本来自己就没有一点设计的概念,只是凭自己大脑的构想,肯定会出问题的。今天才旁听了一节专业设计的课,感触还是很深的,终于知道项目开发是要OOA(分析),OOD(设计),OOP(编码)的。

回过头来,《ZhanQi》的主要逻辑由GameLogic()处理,在PreRender()中被调用。实际输入处理InputProcess()中也执行了一些游戏逻辑,致使逻辑处理这有点混乱,到后期调试是会在这两个函数间来回切换,比较麻烦,效率很低。实际怎样处理好这两个函数的关系,自己还是不太清楚,应该看看成品游戏的代码啊!

游戏情节

游戏情节由CStory类管理,自己本想提供简单通用的接口,方便以后任务添加。实际自己也基本上达到要求了,而且已经测试过了,可以顺利进行。

剧情的动作类型自己指抽象出了五种,以后如果需要还可以再加的(实际其中的Waiting也是自己后来加上的,尽管没怎么用):

// 剧情动作类型[2/21/2008 Arthur]

enum StoryAction

{

None = 0,

MoveRole ,

ShowMessage ,

TalkTo,

Waiting,

};

每种类型都有相应的结构管理数据,并且相互独立。在CStory类中,可以方便的添加各种类型的剧情,只是接口不同。实际CStory没有提供相应的逻辑处理,更像一个栈,提取当前的情节。真正的逻辑处理在CGame中实现,比较复杂了。

游戏战斗

游戏战斗由CFight类管理,在此实现了战斗逻辑,战斗场面的渲染,以及伤害的计算,经验的增加,等级的上升;默认战斗为敌我双方,可实现反击。战斗双方可以是近程攻击,也可以是远程攻击,攻击者可以是有弓箭或是魔法攻击,也可以是近身攻击,弓箭和魔法只是归为子弹类的表现形式;这些都是人物属性动作相关的。

实际在战斗中,比较复杂的是反击的实现,就是这个困扰了自己好几天。主要是开始没有想到要有反击,所有在头脑中构思的时候就没有考虑进来;只是后来要加进去,比较费事了。令人欣慰的是最后也终于实现了,一两天的郁闷也没有白白浪费。只是由于是补上去的,所以逻辑上有些不清晰,所以给后期调试是带来了不少的麻烦。自己越来越感到设计的重要性了。

游戏物品

还没有实现。很多原因了,复杂性是一个重要的;自己在没事的时候也考虑过,物品的实现是相当复杂的,包括物品的各种属性,物品的效果,物品的取得,物品的管理,物品的使用,物品的消亡,物品和角色的什么关系,角色使用物品,管理物品等等。

个人总结

写五百行的代码和写五千行的代码感觉真的是天壤之别,感触颇深,要总结的东西真的很多。

设计方面

今天还旁听了一节课,知道了什么是OOA,OOD,OOP了。设计在项目开发中占有极为终于的地位,可以说是项目开发的灵魂;良好的设计会大大提高以后编码实现,调试维护的工作效率。这一点自己感触颇深。

以前没有学过设计的相关课程,没有看过专业的书籍,也没有什么项目经验,可以说这个是自己五千行级的“处女作”。当代码上升时,开发难度,维护难度并不是线性上升,而是指数上升。有时只是一个小小的问题就够自己调试半天的,经常一个小时什么也发现不了。这是如果有良好的设计,清晰的逻辑,维护难度肯定会大大减少。

还有,自己基本上前期没有设计的概念,只是头脑中构思出游戏的大体架构,需要什么类,类的功能,成员是什么,就开始编码了;这样简单的时候还行,当类变的逐渐复杂时,自己就承受不了了,很多功能自己当时没有想到,完成大部分时有发现自己忽略了莫个功能,于是大改特改,弄得游戏逻辑面目全非,很是复杂,维护困难。

总之,设计是非常重要的,自己应该在这一环节上多花些时间,而且应该用些科学的方法,UMLOOA,OOD,我还不是很了解,看的书太少了,一定要多看看这方面的东西,而且今天还知道了大三的正在上这门课,有时间要听一听。

编码方面

前两天一个同学问我对于面向对象的认识,与面向过程有什么不同;自己感觉面向对象的开发方法最大的优点是大大的减少了人的思维量,令人们从繁杂的数据中解脱出来。

以前设计程序,总是要考虑计算机是怎样实现这一功能的,而自己又究竟需要什麽功能。自己的思维总是徘徊于大脑和电脑之间,当数据不太多时还可以控制,但当数据达到一定的数量级,大脑是完成不了这浩瀚的工作的。而OOP则简单的很,你怎样想的,按照C++的语法输进电脑,编译执行,一切都OK了。因为客观世界是有类和对象组成的,面向对象的思考是对客观世界的最直接简单的抽象,而各种对象的复杂关系也正是OOP最擅长解决的。

随着代码量的增加,自己也感觉到注释的重要性了。即便是很清晰的代码,两天后自己看也会很吃力,更何况是几个月后,或是别人看呢?自己总不能一直自己开发东西吧?团队合作还是很重要的。

令人庆幸的是VS很好用,尤其是增加注释方面,几乎只是几个按键就可以搞定了,效率很高,自己也越来越喜欢加注释了!微软的确是个又让人爱又让人恨的企业。哎,解决问题就好了。

效率方面

效率永远是生命,无论是在哪一方面!在有限的时间内做尽可能多的事情!

感觉开发《ZhanQi》这几天效率还是不错的,虽然和理想还有差距,但比以前强多了,可能是比较安静,没有什么打扰吧!不过能够做一些事情真的感觉很好,不会浪费时间。

实际自己郁闷的主要原因也就是效率底下了。自己现在只有时间可用了,如果不利用有限的时间与精力学点东西,做点事情,真不知道自己以后会怎样!

效率永远是根本!不过怎么提高效率呢?还是适当调整,劳役结合吧!

 

 

 

ZhanQi》终于告一段落了,长舒一口气。感觉自己不是做的很成功的,本想做个比较通用性的东西,再设计一个脚本语言(比较初级的,字符串分析),后再弄个配套的地图编辑器,任务编辑器,这样就可以做一个真正有情节,有故事的游戏,可以玩了。现在只是个简单的Demo罢了,基本的游戏架构是实现了,而且逻辑处理的还可以,比较易于理解。但我想到此而至,不打算继续完善她了。

原因还是很多的,主要是没有时间了,开学后事情就多了,课程很紧的,而且都很重要,数据库,C++,操作系统,汇编,编译,重头戏都上演了,每门课都不可以忽视;而且开学后,工作室的事情也多了起来了,这不前几天接了个商业项目,得好好做了;时间是有限的,精力也是有限的,只是事情是做不完的,而自己的效率又不是很高,是个问题,好好考虑了。

还有一个重要的原因是这毕竟是个2D的游戏,大四的学长说的很对,不必把太多的精力放在2D上面,3D是主流,只要做个简单的,大概了解下2D的开发方法,工作流程就行了。这是很正确的观点,其实自己开始就不应该这么认真的想开发一个通用的甚至于游戏引擎类的东西,做这个只是一种尝试罢了。

 

后记

实际在写总结之前自己应经很就没看《ZhanQi》了,早该完成总结了,但课程真的很多,而且工作室也有东西要做的;或许是借口吧!但不管怎么说,自己总算是写完了,一件事情也总算是过去了,新的生活开始了!

 

 

 

 

Arthur Li

2008-3-10

 
 类似资料: