C语言程序设计实践的课程设计我们写了个游戏,差点拿满分,先将代码与项目报告与大家分享^_^
先上截图:
游戏名称:DotA圣战
类型:回合制RPG战棋类游戏
分工:
SwordHoly:游戏主程序,英雄类,重绘功能的实现。
Emerson:游戏战斗动画的实现。
tarcyzhu:寻路功能的实现。
ZCH:友情技术支持。(大三学长。。)
实验环境:
1. 开发环境:Windows 7+Visual Studio 2008
2. 辅助软件: Photoshop CS3、Word 2010、QuickSnap、IconMaster、拳皇2000
整体构架:
1. 整体架构采取状态与显示分离,游戏运行过程中其实只是改变状态,然后调用OnPaint()重绘函数,进行画图,把状态通过表现出来
2. 这样设计的优点:
1. 降低各模块之间的耦合度,易于编码与维护,本来的话对于每次改变状态都要写一个对应的画图模块,那样会显得非常繁琐和混乱,不易统一管理和维护。
2. 易于调试,因为状态改变与显示过程的分离,使得调试也变的简单,每次调试的时候只要判断是在状态改变过程出错还是画图过程出错,更容易定位出错点。
开发模式:
先做出程序主体,然后一个一个模块加上去。当一个模块调试成功后再去做下一个模块,这样做的好处是容易查错,因为如果出错的话肯定是当前在做的那个模块有错,因为前一个模块已经调试成功了。而且这样边做边能看到成果,能鼓励自己把完整的游戏做下来。
功能模块:
1. 英雄模块:包含升级模块,死亡模块,经验系统,战斗模块(双倍暴击,闪避等)
2. 画图模块:显示英雄(普通状态,可以被攻击状态,和英雄属性显示),显示地形(普通状态,可以到达状态和特殊地形属性显示)。
3. 移动模块:
1. DFS过程判断该点是否可达,可达后地形显示变绿。
2. BFS 过程找出一条路径,然后把整条路的行走过程显示出来。
4. 特殊地形属性加成模块:英雄站在有些特殊地形上攻击力或防御力会增加,站在月亮井上每回合还会加血。
5. 血条模块:在英雄头像下面会有一个血条表示英雄当前血量
6. 回合转化:一方操作结束后,将其英雄禁用,另一方英雄启用。
7. 胜利条件模块:敌全灭或者占领对方基地3回合
8. 战斗动画模块:对于战斗过程中的暴击,闪避,普通攻击,英雄死亡都有不同的动画,在动画中还能用动态文本显示出扣了多少血。
遇到的困难及解决方法:
1. 时间紧任务重:
当开始准备写的时候已经只有两个星期了,而且有两个人退出了。
解决方法:
1.在压力面前往往能激发人的潜力,那两个星期把能翘的课都翘了,在机房一待就是一个下午和一个晚上,为这个游戏争取了足够多的时间,所以在压力面前不要退缩,要迎难而上。
2.砍掉一些功能,开始设计的时候野心很大,想把技能模块,物品模块,金钱模块和AI模块都做进去,不过时间实在来不及了,有时候放弃也是一种策略。
2. 没MFC基础:
虽然C语言的基础比较好,但是对于MFC还是一无所知的,要想做出界面来难度是可想而知的。
解决方法:
1. 要用到什么去学什么,如果再系统的去学MFC,一来时间不够,二来感觉还是在实践中学效率比较高,事实证明其实里面用到的MFC知识很少的,只要会贴图,画图,输出文本和一点消息映射的知识就完全可以把这个游戏做出来。
2. 向学长寻求帮助,对于MFC我还是很陌生的,对Visual Studio 2008也不是很熟悉,有些东西不清楚询问学长的话一般都能得到满意的答复,再这里对ZCH学长表示感谢。
3. 功能太复杂,无从下手
解决方法:将画图过程和状态变化过程分离,也就是前面写到的整体构架,这样一来整个程序的结构就清晰了,写起来也是水到渠成。
4. 资源很难找:
合适的图片很难找,合适的地图更难找,找来找去都感觉不合适,最后把正规DotA游戏里的图截下来,再用IconMaster截出几个64*64的单元格,将这几个单元格组合后当作地图。这个过程其实是很繁琐的,搞了整整一下午才搞定。英雄头像、开场画面和结束画面也是精挑细选的,还有把这些资源导入到工程中,也是个体力活,总之资源的收集过程也是充满艰辛的。
5. 发现绘图的一个BUG
将游戏的运行界面多拖动几次,程序就会死掉,最后多次调试发现是重绘过程中内存溢出,经过网上一番查找发现了,pDC没有Release掉,dcMemory没有delete掉,将这两个错误一改,程序跑的飞快^_^
6. 地形变绿和头像变灰不知道如何实现
这是一个很实际的问题,由于对MFC的颜色填充不熟悉,不知道该怎样将地形变绿和头像变灰。
解决方法:用了一个很富有创造性的方法,用Photoshop实现!!将原来的图拷一份出来,用Photoshop将其处理后再保存后导入到工程中,虽然比较繁琐,但还是实现了应有的功能。
7. 动画不会做
这应该算是一个技术难题,对于MFC都没怎么学过的人,怎么可能把动画加进去。
解决方法:
让Emerson去看MFC书寻找方法,他果然也不负所望。这个方法也是很富有创造性的:用Quicksnap把拳皇的战斗动画截成一幅幅的图片,每次要放动画时,新建一个对话框,在对话框里贴图,但是用一个time控件控制,每隔50ms换一副图,然后看上去就像一个完整的动画了,并且在动画中还能动态显示文字,描述战斗状况。
8. 路径如何显示
最开始英雄的移动是瞬移的,也就是说要移动了,英雄是瞬间从一个点移动到另一个点,显的很突兀。
解决方法:
tracyzhu写了个寻路模块,找出从起点到终点的一条路,然后每隔50ms从那条路上的点移动到路径上的下一个点,看起来自然多了。
感想及体会:
做完这个游戏以后,感慨颇多,也学到了很多。
1. 一个合理的构架很重要,一个好的构架,能极大的提高效率,让我们在编码,调试和维护上少走很多弯路,所以一定要想清楚大体结构后再开始写程序。
2. 一个好的工具能极大的提高效率,开始我是用VC6做的,不过VC6老是死掉,更有一次竟然连工程都打不开了,害我很郁闷的只能重新开始做。后来改用Visual Studiao 2008后效率高了不少,编译也快,界面看着舒服,最主要的从来都不会死掉。
3. 摆正心态很重要,在最后两个星期,我们的游戏还没有开工,有些人都想放弃了,认为期末考都快到了要抓紧时间复习了,为了这0.5个学分不值得,这个游戏难度太大等等。其实不是这样的,大学教育本来就是重理论轻实践的,好不容易有个可以实践的课程,这个机会不应该错过。读大学应该追求的是能力培养而不是那虚无缥缈的积点分。只有认识了这一点以后才能全力以赴去做这个东西。
4. 执着是获得成功的必备品质:
有些事情从来都不是轻松都能做成的,如果还没开始做或者做到一半就放弃的话是不可能成功的,只会留下遗憾。
5. 耐心:有些事情虽然很繁琐,但是我们也必须耐心把他做完,因为它是整个项目中必须的。
6. 坚持:有时候bug调不出来也是很郁闷,不过郁闷归郁闷,还是必须硬着头皮把它搞出来
7. 合作:合作真的很重要,一个人不可能什么都会,就算会也没那么多精力都去做,所以要把一件事情做成,必须与人合作。而且必须找对合作对象,对他们有足够的信任,还有分配任务时每个人之间的耦合度必须尽可能低,这样才能并行的把一个项目作出来。
8. 全力以赴:既然做了,就应该全力以赴把它做好。
变量表,函数表及其意义:
Public.h:
Class CPublic:
static int UNIT;//将屏幕划分成多个单元,每个单元大小为UNIT* UNIT,本游戏里设置为64*64;
static int MAPX,MAPY;//MAPX:每行最多包含的单元格,MAPY:每列最多包含的单元格;
static bool GAMESTART;//用来标记游戏是否开始,开始了为True,否则为False;
static bool GAMEOVER;//用来标记游戏是否结束,结束了为True;否则为False;
Heros.h:
Class Hero:
函数:
void Level_Up();//处理英雄升级过程
void GainExp(int exp);//获得经验值,里面判断经验是否够升级,能的话调用Level_Up();
bool Is_Dead();//判断英雄是否死亡
void Death();//对英雄死亡进行操作
bool Action_Attack(Hero &rhs,int Attadd,int Defadd);
//对rhs英雄进行攻击,攻击者有Attadd的攻击加成,防御者有Defadd的防御加成
void Show_Level_Up();//被Level_Up()所调用,显示升级过程
void Show_Miss(Hero &rhs);//显示闪避过程
void Show_AttackTwice(Hero &rhs);//显示二次攻击(已取消)
void Show_Death();//被Death()所调用,显示死亡
void Hero_Set(CString name,int rc,int max_hp,int attack,int denfense,
int movespeed,int attackspeed,int attackrange,int att_add,
int den_add,int hp_add,int as_add,int miss_probility,int
xx,int yy,int hid);//对英雄进行初始化设置
变量:
bool SelectEnable;//英雄能否被选中,能的话为True,否则为False,如果不能被选中的话头像还会变灰
int Money,ReLive,Now_MP,Now_HP;//Money后面没用到,本来想加金钱系统的;
//ReLive也没用到,本来想加复活功能的;
//Now_MP也没用到,本来表示当前魔法值;
//Now_HP当前生命值
int Level,Attack,Denfense,Max_MP,Max_HP,MoveSpeed,AttackSpeed,AttackRange;
//Level:等级
//Attack:攻击力
//Denfense:防御力
//Max_MP:本来表示最大魔法值,后来由于取消了魔法功能,该变量无效
//Max_HP:最大生命值
//MoveSpeed:最大移动点数
//AttackSpeed:本来表示攻击频率,后来改成表示双倍暴击率
//AttackRange:攻击范围
int Att_add,Den_add,MP_add,HP_add,MS_add,AS_add;
//Att_add:攻击成长
//Den_add:防御成长
//MP_add:最大魔法值成长(已取消)
//HP_add:最大生命值成长
//MS_add:移动速度成长(已禁用)
//AS_add:攻击频率(暴击率)成长
int Ability_Point,Exp,MovePoint,Miss_Probility;
//Ability_Point:技能点(已取消)
//Exp:当前经验值
//MovePoint:当前移动点
//Miss_Probility:闪避率
int Exp_Need_For_Level[MaxLevel+1];// Exp_Need_For_Level[i]表示升到i级所需经验值
int x,y;//x,y表示英雄所在单元格坐标
int Rc;//英雄头像的资源序号
int HID;//英雄编号
CString Name;//英雄名字
DotA_H4View.cpp:
函数:
// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnGamestart();//按游戏开始键后开始处理,进行游戏的初始化
public:
afx_msg void OnPaint();//重绘函数,主要实现重绘功能,也可以进行调用,所有的图形操作都在这里进行
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);//点击鼠标左键后进行的操作,控制英雄移动,攻击等
public:
afx_msg void OnCt();//对应回合结束键,用来进行一个回合结束后的一些初始化和月亮井的加血功能
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);//对应鼠标移动事件,用来显示英雄,特殊地形的状态
public:
afx_msg void OnGamehelp();//对应游戏帮助键,提供游戏帮助。。
//一些该文件下的全局函数
void ChangeTurn();//回合结束的处理函数
void SetHeroxy(int x,int y);//将x,y坐标上的英雄清空(该英雄已是死亡)
void dfs(int x,int y,int MP,int Heroi);//深搜过程,用来计算英雄所能到达的节点
void _Bfs_findroad ( int endx , int endy , int startx ,int starty );//宽搜过程,用来找出一条路;
变量:
Hero H[11];//一个Hero类数组表示10个英雄
int T,H1=5,H2=5,T2=0,T1=0,Winner;
//T表示现在轮到哪个玩家操作,T=0表示玩家1操作,T=5表示玩家2操作
//H1表示玩家 1还剩下几个英雄,用来判断游戏是否结束
//H2 表示玩家2还剩下几个英雄,用来判断游戏是否结束
//T1表示玩家1占领对手基地几回合
//T2表示玩家2 占领对手基地几回合
bool ReFresh;//OnMouseMove中需要用到,用来判断画面是否需要更新,如果鼠标移动到有英雄,特殊建筑所在的位置上ReFresh置为True,如果移动到非特殊地形,非英雄的位置,如果ReFresh为True就要对画面更新,否则不更新。
int map[101][101];//用来表示地图,map[i][j]存的是第i,j坐标的资源的序号
int IIsSelected[101][101];//表示某个点是否被选中,被选中的话在画图的时候会在这个坐标的外面画一个矩形框;
int Reachable[101][101];//表示这个坐标能否到达,能到达的话在画图的时侯在这个坐标上的地形标为绿色;
int Attackable[101][101];//表示这个坐标上的英雄能否被攻击到,能被攻击到的话用将这个英雄的头像标为红色;
int R[3000];//R[i]表示资源序号为i的某个地形的变绿后的图形或某个英雄变绿后的资源序号
int HTX[3000];//HTX[i]表示资源序号为i的某个英雄变灰后的图形的资源序号;
int MP_Need[3000];//MP_Need[i]表示走到资源序号为i的地形需要消耗的移动点数
int Att_add[3000];//Att_add[i]表示资源序号为i的地形上的攻击加成
int Def_add[3000];//Def_add[i]表示资源序号为i的地形上的防御加成
int Hero[101][101];//Hero[i][j]表示在i,j坐标上的英雄序号,0表示没有英雄
int Prex,Prey;//表示OnMouseMove事件上次发生的所在坐标,如果当前鼠标坐标等于上次鼠标坐标则不进行操作
bool fl;//深搜的时候用到的一个布尔标记,表示是不是第一次进入深搜过程,如果不是第一次进入并那个且上面有英雄,则深搜开始回溯,不再往下搜。Fl==false时表示时第一次进入深搜
//以下变量都是用来实现寻路功能的
struct node
{
int x,y;
};//宽搜中用到的节点,表示一条路上某个节点的坐标
node prenode[101][101];//prenode[i][j]表示坐标为i,j的前继坐标
node road[200];//用来存一条路
int location[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//4个方向的坐标变换
int issearched[101][101];//issearched[i][j]表示i,j这个坐标是否被搜索过
int sumcount;//表示路径长度
int startx,starty;//表示一条路的起始坐标
核心代码:
Heros.h
#define MaxLevel 10 #include <CString> #include"orzdlg.h" #include "time.h" using namespace std; class Hero { public: Hero(); public: void Level_Up(); void GainExp(int exp); bool Is_Dead(); void Death(); bool Action_Attack(Hero &rhs,int Attadd,int Defadd); void Show_Level_Up(); void Show_Miss(Hero &rhs); void Show_AttackTwice(Hero &rhs); void Show_Death(); void Hero_Set(CString name,int rc,int max_hp,int attack,int denfense, int movespeed,int attackspeed,int attackrange,int att_add, int den_add,int hp_add,int as_add,int miss_probility,int xx,int yy,int hid); public: bool SelectEnable; int Money,ReLive,Now_MP,Now_HP; int Level,Attack,Denfense,Max_MP,Max_HP,MoveSpeed,AttackSpeed,AttackRange; int Att_add,Den_add,MP_add,HP_add,MS_add,AS_add; int Ability_Point,Exp,MovePoint,Miss_Probility; int Exp_Need_For_Level[MaxLevel+1]; int x,y; int Rc; int HID; CString Name; };
Heros.cpp
#include "stdafx.h" #include "Heros.h" #include <stdlib.h> #include <time.h> #include <CString> #include <string> #include"orzdlg.h" Hero::Hero() { SelectEnable=false; Ability_Point=1; Level=1; Exp=0; MovePoint=0; Money=0; ReLive=0; Exp_Need_For_Level[1]=0; Exp_Need_For_Level[2]=100; Exp_Need_For_Level[3]=200; Exp_Need_For_Level[4]=300; Exp_Need_For_Level[5]=450; Exp_Need_For_Level[6]=700; Exp_Need_For_Level[7]=1000; Exp_Need_For_Level[8]=1300; Exp_Need_For_Level[9]=1600; Exp_Need_For_Level[10]=2000; } void Hero::Level_Up() { Level++; Attack+=Att_add; Denfense+=Den_add; Max_MP+=MP_add; Now_HP=Now_HP*(Max_HP+HP_add)/Max_HP; Max_HP+=HP_add; MoveSpeed+=MS_add; AttackSpeed+=AS_add; //Miss_Probility+=MP_add; Ability_Point++; Show_Level_Up(); } void Hero::GainExp(int exp) { int i; Exp+=exp; for(i=Level+1;i<=MaxLevel;i++) { if (Exp>=Exp_Need_For_Level[i]) Level_Up(); else break; } } bool Hero::Is_Dead() { if (Now_HP>0) return false; else return true; } void Hero::Death() { x=-1;y=-1; Money-=(Money/10); ReLive=Level; } bool Hero::Action_Attack(Hero &rhs,int Attadd,int Defadd) { int Hurt,PP; CString s; char ss[200]; bool fl; fl=false; srand(time(NULL)); PP=rand()%101; if (PP<=rhs.Miss_Probility) {Show_Miss(rhs);} else { Hurt=Attack+Attadd-rhs.Denfense-Defadd; if (Hurt<=0) Hurt=0; if (( rand()%101 )<=AttackSpeed ) { Hurt=Hurt*2; itoa(Hurt,ss,10); CString s0(ss); s=Name+_T("小宇宙爆发,双倍暴击!!"); s+=rhs.Name+_T("受到")+s0+_T("的伤害。"); Corzdlg dlg; dlg.getkind(1); dlg.GetString(s); dlg.DoModal(); //AfxMessageBox(s); } else { itoa(Hurt,ss,10); CString s0(ss); s=rhs.Name+_T("在")+Name+_T("的攻击下遭到")+s0+_T("的伤害。"); Corzdlg dlg; dlg.getkind(0); dlg.GetString(s); dlg.DoModal(); //AfxMessageBox(s); } rhs.Now_HP-=Hurt; if ( rhs.Is_Dead() ) { CString s; s=rhs.Name+_T("在")+Name+_T("的疯狗般的攻击下去见马克思了"); fl=true; // AfxMessageBox(s); Corzdlg dlg; dlg.getkind(3); dlg.GetString(s); dlg.DoModal(); rhs.Death(); Money+=(rhs.Money/10); GainExp(rhs.Level*100); } } return fl; } void Hero::Hero_Set(CString name,int rc,int max_hp,int attack,int denfense, int movespeed,int attackspeed,int attackrange,int att_add, int den_add,int hp_add,int as_add,int miss_probility,int xx,int yy,int hid) { Max_HP=max_hp; Now_HP=Max_HP; Attack=attack; Denfense=denfense; MoveSpeed=movespeed; MovePoint=MoveSpeed;// AttackSpeed=attackspeed; AttackRange=attackrange; Att_add=att_add; Den_add=den_add; HP_add=hp_add; AS_add=as_add; Miss_Probility=miss_probility; x=xx; y=yy; Name=name; Rc=rc; HID=hid; } void Hero::Show_Level_Up() { CString s; char ss[100]; s=Name; itoa(Level,ss,10); CString s0(ss); s=s+_T("升到")+s0+_T("级!"); AfxMessageBox(s); } void Hero::Show_Miss(Hero &rhs) { CString s; s=Name; s=s+_T("华丽的攻击被")+rhs.Name+_T("华丽的躲开了"); Corzdlg dlg; dlg.getkind(2); dlg.GetString(s); dlg.DoModal(); //AfxMessageBox(s); } void Hero::Show_AttackTwice(Hero &rhs) { CString s; s=Name+_T("小宇宙燃烧,进行二次攻击!"); AfxMessageBox(s); }
DotA_H4View.h
// DotA_H4View.h : CDotA_H4View 类的接口 // #pragma once class CDotA_H4View : public CView { protected: // 仅从序列化创建 CDotA_H4View(); DECLARE_DYNCREATE(CDotA_H4View);/ // 属性 public: CDotA_H4Doc* GetDocument() const; // 操作 public: void GameOver(int x); // 重写 public: virtual void OnDraw(CDC* pDC); // 重写以绘制该视图 virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: // 实现 public: virtual ~CDotA_H4View(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // 生成的消息映射函数 protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnGamestart(); public: afx_msg void OnPaint(); public: afx_msg void OnLButtonDown(UINT nFlags, CPoint point); public: afx_msg void OnCt(); public: afx_msg void OnMouseMove(UINT nFlags, CPoint point); public: afx_msg void OnGamehelp(); }; #ifndef _DEBUG // DotA_H4View.cpp 中的调试版本 inline CDotA_H4Doc* CDotA_H4View::GetDocument() const { return reinterpret_cast<CDotA_H4Doc*>(m_pDocument); } #endif
DotA_H4View.cpp
// DotA_H4View.cpp : CDotA_H4View 类的实现 // 经统计,这个工程的代码量已经达到了2000行——! #include "stdafx.h" #include "DotA_H4.h" #include "Public.h" #include "DotA_H4Doc.h" #include "DotA_H4View.h" #include<CString> #include<time.h> #include<queue> #include<memory.h> #include <windows.h> #include<stdio.h> #include<time.h> #include<stdlib.h> //using namespace std; #ifdef _DEBUG #define new DEBUG_NEW #endif // CDotA_H4View IMPLEMENT_DYNCREATE(CDotA_H4View, CView) BEGIN_MESSAGE_MAP(CDotA_H4View, CView) ON_COMMAND(GameStart, &CDotA_H4View::OnGamestart) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_COMMAND(CT, &CDotA_H4View::OnCt) ON_WM_MOUSEMOVE() ON_COMMAND(GameHelp, &CDotA_H4View::OnGamehelp) END_MESSAGE_MAP() // CDotA_H4View 构造/析构 Hero H[11]; int T,H1=5,H2=5,T2=0,T1=0,Winner; bool ReFresh; int map[101][101]={ {135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135}, {135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135}, {135,135,135,135,135,Tree7,Tree8,Tree8,Tree7,Tree8,Tree8,135,135,Moon1,135,135}, {135,135,135,135,Grass1,135,135,135,135,135,135,Grass1,135,135,135,135}, {Grass4,Grass4,135,135,Grass1,135,135,135,135,135,135,Grass1,135,135,Grass5,Grass5}, {Home,Grass4,135,135,Grass1,135,135,135,135,135,135,Grass1,135,135,Grass5,Home}, {Grass4,Grass4,135,135,Grass1,135,135,Grass6,135,135,135,Grass1,135,135,Grass5,Grass5}, {135,135,135,135,Grass1,135,135,135,135,135,135,Grass1,135,135,135,135}, {135,135,Moon1,135,135,Tree12,Tree12,Tree12,Tree12,Tree12,Tree12,135,135,135,135,135}, {135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135}, {135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135}, {135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135} }; int IIsSelected[101][101]={ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, }; int Reachable[101][101]={ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, }; int Attackable[101][101]={ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, }; int R[3000]={Rgrass6}; int HTX[3000]; int MP_Need[3000]={1}; int Att_add[3000]={0}; int Def_add[3000]={0}; int Hero[101][101]; int Prex=20,Prey=20; bool fl; struct node { int x,y; }; node prenode[101][101]; node road[200]; int location[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int issearched[101][101]; int sumcount; int startx,starty; void ChangeTurn() { int i; T=5-T; for(i=T+1;i<=T+5;i++) { H[i].SelectEnable=true; H[i].MovePoint=H[i].MoveSpeed; } for(i=5-T+1;i<=5-T+5;i++) { H[i].SelectEnable=false; H[i].MovePoint=0; } } void SetHeroxy(int x,int y) { Hero[x][y]=0; } void CDotA_H4View::GameOver(int x) { int i,j; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) { Attackable[i][j]=0; Reachable[i][j]=0; IIsSelected[i][j]=0; if (Hero[i][j]!=0) H[Hero[i][j]].SelectEnable=false; } CPublic::GAMEOVER=true; Winner=x; OnPaint(); } CDotA_H4View::CDotA_H4View() { // TODO: 在此处添加构造代码 } CDotA_H4View::~CDotA_H4View() { } BOOL CDotA_H4View::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 return CView::PreCreateWindow(cs); } // CDotA_H4View 绘制 void CDotA_H4View::OnDraw(CDC* /*pDC*/) { CDotA_H4Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: 在此处为本机数据添加绘制代码 } // CDotA_H4View 诊断 #ifdef _DEBUG void CDotA_H4View::AssertValid() const { CView::AssertValid(); } void CDotA_H4View::Dump(CDumpContext& dc) const { CView::Dump(dc); } CDotA_H4Doc* CDotA_H4View::GetDocument() const // 非调试版本是内联的 { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDotA_H4Doc))); return (CDotA_H4Doc*)m_pDocument; } #endif //_DEBUG // CDotA_H4View 消息处理程序 void CDotA_H4View::OnGamestart() { // TODO: 在此添加命令处理程序代码 int x,y,i,j; CDC *pDC; if ( (CPublic::GAMESTART) &&(!CPublic::GAMEOVER) ) { MessageBox(_T("游戏已经开始,要重新开始请重启游戏")); return ; } if (CPublic::GAMEOVER) { MessageBox(_T("游戏已经重新开始!!")); } MessageBox(_T("Game Start!!Player1's turn first!"),_T("游戏开始")); CPublic::GAMESTART=true; CPublic::GAMEOVER=false; H[1].Hero_Set(_T("AM"),AM,50,25,0,5,30,4,5,1,5,5,30,4,15,1); H[2].Hero_Set(_T("CM"),CM,30,20,5,3,20,8,3,2,3,4,50,6,15,2); H[3].Hero_Set(_T("DF"),DF,80,18,8,6,60,1,7,5,10,8,40,4,14,3); H[4].Hero_Set(_T("Panda"),Panda,120,10,10,3,0,1,7,9,10,10,0,5,14,4); H[5].Hero_Set(_T("Sven"),Sven,70,30,5,4,20,1,4,3,5,5,20,6,14,5); H[6].Hero_Set(_T("Karl"),Karl,50,25,0,5,30,4,5,1,5,5,30,4,0,6); H[7].Hero_Set(_T("Lich"),Lich,30,20,5,3,20,8,3,2,3,4,50,6,0,7); H[8].Hero_Set(_T("TB"),TB,80,18,8,6,60,1,7,5,10,8,40,4,1,8); H[9].Hero_Set(_T("Razor"),Razor,120,10,10,3,0,1,7,9,10,10,0,5,1,9); H[10].Hero_Set(_T("Zeus"),Zeus,70,30,5,4,20,1,4,3,5,5,20,6,1,10); MP_Need[Tree7]=2; MP_Need[Tree8]=2; MP_Need[Tree12]=2; MP_Need[Moon1]=3; MP_Need[Moon2]=3; MP_Need[Home]=3; MP_Need[Grass1]=1; MP_Need[Grass2]=1; MP_Need[Grass3]=1; MP_Need[Grass4]=1; MP_Need[Grass5]=1; MP_Need[Grass6]=1; Def_add[Tree7]=3; Def_add[Tree8]=3; Def_add[Tree12]=3; Def_add[Moon1]=4; Def_add[Moon2]=4; Att_add[Moon1]=5; Att_add[Moon2]=5; Def_add[Home]=-6; R[Grass6]=Rgrass6; R[Grass1]=Rgrass1; R[Tree7]=Rtree1; R[Tree8]=Rtree2; R[Tree12]=Rtree6; R[Moon1]=Rmoon1; R[Home]=Rhome; R[Grass5]=Rgrass5; R[Grass2]=Rgrass2; R[Grass4]=Rgrass4; R[AM]=RAM; R[CM]=RCM; R[DF]=RDF; R[Karl]=RKarl; R[Lich]=RLich; R[Panda]=RPanda; R[Razor]=RRazor; R[Sven]=RSven; R[TB]=RTB; R[Zeus]=RZeus; HTX[AM]=HAM; HTX[CM]=HCM; HTX[DF]=HDF; HTX[Karl]=HKarl; HTX[Lich]=HLich; HTX[Panda]=HPanda; HTX[Razor]=HRazor; HTX[Sven]=HSven; HTX[TB]=HTB; HTX[Zeus]=HZeus; ChangeTurn(); for(i=1;i<=100;i++) for(j=1;j<=100;j++) Hero[i][j]=0; for(i=1;i<=10;i++) Hero[H[i].x][H[i].y]=i; OnPaint(); } void SelectRec(int x,int y,CDC *pDC) { CPen BlackPen; BlackPen.CreatePen(PS_SOLID,3,RGB(100,200,100)); CPen *pOldPen; //pOldPen=pDC->SelectObject(&BlackPen); //pDC->Rectangle(x*64,y*64,x*64+64,y*64+64); pOldPen=pDC->SelectObject(&BlackPen); pDC->MoveTo(x*64,y*64); pDC->LineTo(x*64,y*64+64); pDC->LineTo(x*64+64,y*64+64); pDC->LineTo(x*64+64,y*64); pDC->LineTo(x*64,y*64); pDC->SelectObject(pOldPen); DeleteObject(BlackPen); } CString itoCS(int num) { char ss[100]; itoa(num,ss,10); CString s0(ss); return s0; } void CDotA_H4View::OnPaint() { int x,y; CPaintDC dc(this); // device context for painting if (CPublic::GAMEOVER) { CDC *pDC; pDC=GetDC(); CBitmap bitmap; CDC dcMemory; dcMemory.CreateCompatibleDC(pDC); bitmap.LoadBitmap(Desktop_GameOver); dcMemory.SelectObject(&bitmap); pDC->BitBlt(0,0,CPublic::UNIT*CPublic::MAPX,CPublic::UNIT*CPublic::MAPY,&dcMemory,0,0,SRCCOPY); ReleaseDC(pDC); DeleteObject(dcMemory); //////////////////////////////////////////////////////////////// CFont font; VERIFY(font.CreateFont( 200, // nHeight 0, // nWidth 0, // nEscapement 0, // nOrientation FW_NORMAL, // nWeight FALSE, // bItalic FALSE, // bUnderline 0, // cStrikeOut ANSI_CHARSET, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily _T("隶书"))); // lpszFacename // Do something with the font just created... CDC *pdc=GetDC(); CFont* def_font = pdc->SelectObject(&font); pdc->SetBkMode(TRANSPARENT); pdc->SetTextColor(RGB(255,125,130)); pdc->TextOut(50,200,_T("Game Over")); pdc->SelectObject(def_font); // Done with the font. Delete the font object. ReleaseDC(pdc); font.DeleteObject(); /////////////////////////////////////////////////////////////// VERIFY(font.CreateFont( 50, // nHeight 0, // nWidth 0, // nEscapement 0, // nOrientation FW_NORMAL, // nWeight FALSE, // bItalic FALSE, // bUnderline 0, // cStrikeOut ANSI_CHARSET, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily _T("隶书"))); // lpszFacename // Do something with the font just created... pdc=GetDC(); def_font = pdc->SelectObject(&font); pdc->SetBkMode(TRANSPARENT); pdc->SetTextColor(RGB(20,225,30)); pdc->TextOut(600,500,_T("Player")+itoCS(Winner)+_T(" Win!!")); pdc->SelectObject(def_font); // Done with the font. Delete the font object. ReleaseDC(pdc); font.DeleteObject(); /* CDC *pDc; CFont font; SetFont(&font); pDc=GetDC(); pDc->SetTextColor(RGB(20,225,30)); pDc->SetBkMode(TRANSPARENT); pDc->TextOut(600,500,_T("Player")+itoCS(Winner)+_T(" Win!!")); ReleaseDC(pDc);*/ } else if (CPublic::GAMESTART==true) { for(y=0;y<CPublic::MAPY;y++) { for(x=0;x<CPublic::MAPX;x++) { CDC *pDC; pDC=GetDC(); CBitmap bitmap; CDC dcMemory; dcMemory.CreateCompatibleDC(pDC); if (Hero[y][x]==0) { if (Reachable[y][x]==0) bitmap.LoadBitmap(map[y][x]); else bitmap.LoadBitmap(R[map[y][x]]); } else if (Attackable[y][x]==0) if (H[Hero[y][x]].SelectEnable) bitmap.LoadBitmap(H[Hero[y][x]].Rc); else bitmap.LoadBitmap(HTX[H[Hero[y][x]].Rc]); else bitmap.LoadBitmap(R[H[Hero[y][x]].Rc]); dcMemory.SelectObject(&bitmap); pDC->BitBlt(x*64,y*64,64,64,&dcMemory,0,0,SRCCOPY); if (Hero[y][x]!=0) { CPen BlackPen; BlackPen.CreatePen(PS_SOLID,5,RGB(250,30,0)); CPen *pOldPen; pOldPen=pDC->SelectObject(&BlackPen); pDC->MoveTo(x*64+3,y*64+60);//加3是为了让血条显示不连在一起 if (H[Hero[y][x]].Now_HP>0) //当血量大于0才显示,否则血条显示不正常 pDC->LineTo(x*64+(63*( H[Hero[y][x]].Now_HP )/( H[Hero[y][x]].Max_HP ) ),y*64+60); DeleteObject(BlackPen); } ReleaseDC(pDC);//Get的都要Release DeleteObject(dcMemory);//Create的都要Delete,防止内存泄露 } } for(y=0;y<CPublic::MAPY;y++) for(x=0;x<CPublic::MAPX;x++) if (IIsSelected[y][x]==1) { CDC *pDC; pDC=GetDC(); SelectRec(x,y,pDC); ReleaseDC(pDC); } } else { CDC *pDC; pDC=GetDC(); CBitmap bitmap; CDC dcMemory; dcMemory.CreateCompatibleDC(pDC); bitmap.LoadBitmap(Desktop); dcMemory.SelectObject(&bitmap); pDC->BitBlt(0,0,CPublic::UNIT*CPublic::MAPX,CPublic::UNIT*CPublic::MAPY,&dcMemory,200,200,SRCCOPY); ReleaseDC(pDC); DeleteObject(dcMemory); } // 不为绘图消息调用 CView::OnPaint() } void dfs(int x,int y,int MP,int Heroi)//MP==MovePoints { if ( (x<0)||(x>10)||(y<0)||(y>15) ) return ; //if (Reachable[x][y]) return ; if (fl && Hero[x][y]!=0) return; fl=true; if (MP>=0) { Reachable[x][y]=Heroi; dfs(x-1,y,MP-MP_Need[map[x-1][y]],Heroi); dfs(x,y-1,MP-MP_Need[map[x][y-1]],Heroi); dfs(x+1,y,MP-MP_Need[map[x+1][y]],Heroi); dfs(x,y+1,MP-MP_Need[map[x][y+1]],Heroi); } } void _Bfs_findroad ( int endx , int endy , int startx ,int starty ) { using namespace std; int i,j; for( i = 0 ; i<200 ; i++ ) road[i].x = road[i].y = 0; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) { issearched[i][j]=0; prenode[i][j].x=0; prenode[i][j].y=0; } //Init for the function Bfs queue<node> _road_q; node temp; temp.x = startx; temp.y = starty; _road_q.push( temp ); //AfxMessageBox(itoCS(startx)+_T(",")+itoCS(starty)+_T("->")+itoCS(endx)+_T(",")+itoCS(endy)); //just for debug while(_road_q.empty()!=true) { temp=_road_q.front(); _road_q.pop(); if( temp.x == endx && temp.y == endy ) break; for( i = 0 ; i < 4 ; i++ ) { node newnode; newnode.x=temp.x+location[i][0]; newnode.y=temp.y+location[i][1]; if( newnode.x < 0 || newnode.x > 10 || newnode.y < 0 || newnode.y > 15 ) continue; if(Reachable[ newnode.x ][newnode.y] == 0 || issearched [ newnode.x ][ newnode.y ] == 1 ) continue; issearched[ newnode.x ][ newnode.y ] = 1; prenode[ newnode.x ][ newnode.y ].x = temp.x; prenode[ newnode.x ][ newnode.y ].y = temp.y; _road_q.push(newnode); } } //BFS sumcount = 0; //rebuild the road for onpaint() road[++sumcount].x=temp.x; road[sumcount].y=temp.y; while(!(prenode[temp.x][temp.y].x==startx&&prenode[temp.x][temp.y].y==starty)) { int a,b; //AfxMessageBox(itoCS(temp.x)+_T(",")+itoCS(temp.y));//just for debug a=prenode[temp.x][temp.y].x; b=prenode[temp.x][temp.y].y; road[++sumcount].x=prenode[temp.x][temp.y].x; road[sumcount].y=prenode[temp.x][temp.y].y; temp.x=a; temp.y=b; } return; } void CDotA_H4View::OnLButtonDown(UINT nFlags, CPoint point) { int x,y,i,j; CDC *pDC=GetDC(); x=point.x/64; y=point.y/64; if ( (Hero[y][x]!=0)&&(H[Hero[y][x]].SelectEnable) ) { for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) IIsSelected[i][j]=0; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) Reachable[i][j]=0; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) Attackable[i][j]=0; IIsSelected[y][x]=1; fl=false; startx=x;starty=y; dfs(y,x,H[Hero[y][x]].MovePoint,Hero[y][x]); for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) if (Hero[i][j]!=0) Reachable[i][j]=0; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) { if ( (abs(y-i)+abs(x-j)<=H[Hero[y][x]].AttackRange)&&(Hero[i][j]!=0)&&(Hero[y][x]/6+Hero[i][j]/6==1) ) Attackable[i][j]=Hero[y][x]; } OnPaint(); } else { if (Attackable[y][x]!=0) { int yy=H[Attackable[y][x]].x; int xx=H[Attackable[y][x]].y; if (H[Attackable[y][x]].Action_Attack(H[Hero[y][x]],Att_add[map[yy][xx]],Def_add[map[y][x]])) { if (H[Hero[y][x]].HID<=5) H1--; else H2--; SetHeroxy(y,x); } for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) { Attackable[i][j]=0; Reachable[i][j]=0; } IIsSelected[yy][xx]=0; H[Hero[yy][xx]].SelectEnable=false; OnPaint(); if (H1==0) GameOver(1); else if (H2==0) GameOver(2); } else if (Reachable[y][x]!=0) { _Bfs_findroad ( y , x ,starty , startx ); int h=Reachable[y][x]; Hero[starty][startx]=0; IIsSelected[starty][startx]=0; Hero[road[sumcount].x][road[sumcount].y]=h; IIsSelected[road[sumcount].x][road[sumcount].y]=1; //for(i=sumcount-1;i>=1;i--) //MessageBox(itoCS(road[i].x)+_T(",")+itoCS(road[i].y));//just for debug OnPaint(); for(i=sumcount-1;i>=1;i--) { Sleep(40); Hero[road[i+1].x][road[i+1].y]=0; IIsSelected[road[i+1].x][road[i+1].y]=0; Hero[road[i].x][road[i].y]=h; IIsSelected[road[i].x][road[i].y]=1; OnPaint(); } H[h].x=y;H[h].y=x; H[h].MovePoint=0; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) IIsSelected[i][j]=0; IIsSelected[y][x]=1; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) Reachable[i][j]=0; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) Attackable[i][j] = 0; for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) { if ( (abs(y-i)+abs(x-j)<=H[Hero[y][x]].AttackRange)&&(Hero[i][j]!=0)&&(Hero[y][x]/6+Hero[i][j]/6==1) ) Attackable[i][j]=Hero[y][x]; } OnPaint(); } else { for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) { Attackable[i][j]=0; Reachable[i][j]=0; IIsSelected[i][j]=0; } OnPaint(); } } CView::OnLButtonDown(nFlags, point); } void CDotA_H4View::OnCt() { int i,j; if (!CPublic::GAMESTART) { MessageBox(_T("游戏还未开始,无法结束回合!")); return ; } if (CPublic::GAMEOVER) { MessageBox(_T("游戏已经结束,无法结束回合!")); return ; } for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) { IIsSelected[i][j]=0; Reachable[i][j]=0; Attackable[i][j]=0; } ChangeTurn(); if (T==0) MessageBox(_T("Now it's Player2's turn!!")); else MessageBox(_T("Now it's Player1's turn!!")); for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) if ((map[i][j]==Moon1)&&(Hero[i][j]!=0)) { int PreHP=H[Hero[i][j]].Now_HP; H[Hero[i][j]].Now_HP+=H[Hero[i][j]].Max_HP/10; if (H[Hero[i][j]].Now_HP>H[Hero[i][j]].Max_HP) H[Hero[i][j]].Now_HP=H[Hero[i][j]].Max_HP; MessageBox(H[Hero[i][j]].Name+_T("在月亮井上受到月神祝福,生命值加")+itoCS(H[Hero[i][j]].Now_HP-PreHP)); } for(i=0;i<CPublic::MAPY;i++) for(j=0;j<CPublic::MAPX;j++) if ((map[i][j]==Home)&&(Hero[i][j]!=0)&&(((j==0)&&(Hero[i][j]<=5))||((j>0)&&(Hero[i][j]>5)))) { if ((j==0)&&(T==0) ) { T2++; if (T2<=2) MessageBox(H[Hero[i][j]].Name+_T("已占领对手基地")+itoCS(T2)+_T("回合!")); else { MessageBox(H[Hero[i][j]].Name+_T("已经彻底占领对手基地"),_T("Player2获胜!!")); GameOver(2); } } else if ((j>0)&&(T==5) ) { T1++; if (T1<=2) MessageBox(H[Hero[i][j]].Name+_T("已占领对手基地")+itoCS(T1)+_T("回合!")); else { MessageBox(H[Hero[i][j]].Name+_T("已经彻底占领对手基地"),_T("Player1获胜!!")); GameOver(1); } } } else if (map[i][j]==Home) { if (j==0) T2=0; else T1=0; } OnPaint(); // TODO: 在此添加命令处理程序代码 } void CDotA_H4View::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (CPublic::GAMEOVER) return ; CString s; int dd=20; int x=point.x; int y=point.y; int xx=x/64; int yy=y/64; if (!(xx==Prex && yy==Prey)) { if ( (Hero[yy][xx]!=0)&&(!IIsSelected[yy][xx]) ) { CDC *pDc; pDc=GetDC(); pDc->SetTextColor(RGB(0,125,255)); pDc->SetBkMode(TRANSPARENT); OnPaint(); pDc->TextOut(xx*64+64,yy*64+24,_T("名字:")+H[Hero[yy][xx]].Name); pDc->TextOut(xx*64+64,yy*64+24+dd,_T("生命:")+itoCS(H[Hero[yy][xx]].Now_HP)+_T("/")+itoCS(H[Hero[yy][xx]].Max_HP)); pDc->TextOut(xx*64+64,yy*64+24+dd*2,_T("等级:")+itoCS(H[Hero[yy][xx]].Level)); pDc->TextOut(xx*64+64,yy*64+24+dd*3,_T("经验:")+itoCS(H[Hero[yy][xx]].Exp)+_T("/")+itoCS(H[Hero[yy][xx]].Exp_Need_For_Level[H[Hero[yy][xx]].Level+1])); pDc->TextOut(xx*64+64,yy*64+24+dd*4,_T("攻击:")+itoCS(H[Hero[yy][xx]].Attack)); pDc->TextOut(xx*64+64,yy*64+24+dd*5,_T("防御:")+itoCS(H[Hero[yy][xx]].Denfense)); pDc->TextOut(xx*64+64,yy*64+24+dd*6,_T("暴击率:")+itoCS(H[Hero[yy][xx]].AttackSpeed)); pDc->TextOut(xx*64+64,yy*64+24+dd*7,_T("闪避率:")+itoCS(H[Hero[yy][xx]].Miss_Probility)); //pDc->TextOut(xx*64+64,yy*64+24+dd*8,_T("生命成长:")+itoCS(H[Hero[yy][xx]].HP_add)); //pDc->TextOut(xx*64+64,yy*64+24+dd*9,_T("攻击成长:")+itoCS(H[Hero[yy][xx]].Att_add)); //pDc->TextOut(xx*64+64,yy*64+24+dd*10,_T("防御成长:")+itoCS(H[Hero[yy][xx]].Den_add)); //pDc->TextOut(xx*64+64,yy*64+24+dd*11,_T("暴击率成长:")+itoCS(H[Hero[yy][xx]].AS_add)); Prex=xx;Prey=yy; ReleaseDC(pDc); ReFresh=true; } else if ( (Hero[yy][xx]==0)&&(Att_add[map[yy][xx]]+Def_add[map[yy][xx]]!=0)&&(map[yy][xx]!=Moon1)&&(map[yy][xx]!=Home) ) { CDC *pDc; pDc=GetDC(); pDc->SetTextColor(RGB(0,125,255)); pDc->SetBkMode(TRANSPARENT); OnPaint(); pDc->TextOut(xx*64+64,yy*64+24,_T("攻击加成:")+itoCS(Att_add[map[yy][xx]])); pDc->TextOut(xx*64+64,yy*64+24+dd,_T("防御加成:")+itoCS(Def_add[map[yy][xx]])); Prex=xx;Prey=yy; ReleaseDC(pDc); ReFresh=true; } else if ((Hero[yy][xx]==0)&&(map[yy][xx]==Moon1)) { CDC *pDc; pDc=GetDC(); pDc->SetTextColor(RGB(0,125,255)); pDc->SetBkMode(TRANSPARENT); OnPaint(); pDc->TextOut(xx*64+64,yy*64+24,_T("受到月神祝福的月亮井:每回合回复10%的生命!!")); pDc->TextOut(xx*64+64,yy*64+24+dd,_T("攻击加成:")+itoCS(Att_add[map[yy][xx]])); pDc->TextOut(xx*64+64,yy*64+24+dd*2,_T("防御加成:")+itoCS(Def_add[map[yy][xx]])); Prex=xx;Prey=yy; ReleaseDC(pDc); ReFresh=true; } else if ( (Hero[yy][xx]==0) && (map[yy][xx]==Home) ) { CDC *pDc; pDc=GetDC(); pDc->SetTextColor(RGB(0,125,255)); pDc->SetBkMode(TRANSPARENT); OnPaint(); pDc->TextOut(xx*64+64,yy*64+24,_T("大本营:被对方占领3回合即宣告失败!!")); pDc->TextOut(xx*64+64,yy*64+24+dd,_T("攻击加成:")+itoCS(Att_add[map[yy][xx]])); pDc->TextOut(xx*64+64,yy*64+24+dd*2,_T("防御加成:")+itoCS(Def_add[map[yy][xx]])); Prex=xx;Prey=yy; ReleaseDC(pDc); ReFresh=true; } else if (ReFresh) { Prex=xx;Prey=yy; OnPaint(); ReFresh=false; } } CView::OnMouseMove(nFlags, point); } void CDotA_H4View::OnGamehelp() { // TODO: 在此添加命令处理程序代码 MessageBox(_T("每个英雄都各有特色,有的擅长攻击,有的擅长防御,有的移动速度快,有的成长高,灵活的应用各个英雄的特长是获得胜利的关键。有些地形还有攻击防御加成,在月亮井上面能回复生命,对地形的合理利用至关重要。胜利条件:敌方英雄全灭或者占领对方基地3回合!!Good Luck!!游戏愉快!!")); }
orzdlg.h
#pragma once // Corzdlg 对话框 class Corzdlg : public CDialog { DECLARE_DYNAMIC(Corzdlg) public: Corzdlg(CWnd* pParent = NULL); // 标准构造函数 virtual ~Corzdlg(); // 对话框数据 enum { IDD =208 }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnTimer(UINT_PTR nIDEvent); int godlike; int choose; void getkind(int num); void GetString(CString s); private: CString name; int m_nWidth; };
orzdlg.cpp
// orzdlg.cpp : 实现文件 // #include "stdafx.h" #include "DotA_H4.h" #include "orzdlg.h" #include"time.h" // Corzdlg 对话框 IMPLEMENT_DYNAMIC(Corzdlg, CDialog) Corzdlg::Corzdlg(CWnd* pParent /*=NULL*/) : CDialog(Corzdlg::IDD, pParent) , godlike(0) , choose(false) , name(_T("")) , m_nWidth(0) { } Corzdlg::~Corzdlg() { } void Corzdlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(Corzdlg, CDialog) ON_WM_CREATE() ON_WM_TIMER() END_MESSAGE_MAP() // Corzdlg 消息处理程序 int Corzdlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; SetTimer(1,100,NULL); // TODO: 在此添加您专用的创建代码 if(choose==0)godlike=193; else if(choose==1)godlike=230; else if(choose==2)godlike=231; else if(choose==3)godlike=237; m_nWidth=0; return 0; } void Corzdlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if(choose==0){m_nWidth+=30; CBitmap bitmap; bitmap.LoadBitmapW(godlike++); CBrush brush(&bitmap); CClientDC dc(this); dc.FillRect(CRect(0,0,600,300),&brush); TEXTMETRIC tm; dc.GetTextMetrics(&tm); CRect rect; rect.left=100; rect.top=240; rect.right=m_nWidth; rect.bottom=rect.top+tm.tmHeight; dc.SetTextColor(RGB(255,0,0)); dc.SetBkMode(TRANSPARENT); dc.DrawText(name,rect,DT_LEFT); // dc.TextOut(200,250,name); if(godlike==208)OnOK(); } else if(choose==1) {m_nWidth+=30; CBitmap bitmap; bitmap.LoadBitmapW(godlike--); CBrush brush(&bitmap); CClientDC dc(this); dc.FillRect(CRect(0,0,600,300),&brush); TEXTMETRIC tm; dc.GetTextMetrics(&tm); CRect rect; rect.left=100; rect.top=240; rect.right=m_nWidth; rect.bottom=rect.top+tm.tmHeight; dc.SetTextColor(RGB(255,0,0)); dc.SetBkMode(TRANSPARENT); dc.DrawText(name,rect,DT_LEFT); //dc.TextOut(200,250,name); if(godlike==208)OnOK(); } else if(choose==2) { m_nWidth+=100; CBitmap bitmap; bitmap.LoadBitmapW(godlike++); CBrush brush(&bitmap); CClientDC dc(this); dc.FillRect(CRect(0,0,600,300),&brush); TEXTMETRIC tm; dc.GetTextMetrics(&tm); CRect rect; rect.left=100; rect.top=240; rect.right=m_nWidth; rect.bottom=rect.top+tm.tmHeight; dc.SetTextColor(RGB(255,0,0)); dc.SetBkMode(TRANSPARENT); dc.DrawText(name,rect,DT_LEFT); //dc.TextOut(200,50,name); if(godlike==236)OnOK(); } else if(choose==3) {m_nWidth+=30; CBitmap bitmap; bitmap.LoadBitmapW(godlike++); CBrush brush(&bitmap); CClientDC dc(this); dc.FillRect(CRect(0,0,600,300),&brush); TEXTMETRIC tm; dc.GetTextMetrics(&tm); CRect rect; rect.left=100; rect.top=240; rect.right=m_nWidth; rect.bottom=rect.top+tm.tmHeight; dc.SetTextColor(RGB(255,0,0)); dc.SetBkMode(TRANSPARENT); dc.DrawText(name,rect,DT_LEFT); //dc.TextOut(200,250,name); if(godlike==256)OnOK(); } CDialog::OnTimer(nIDEvent); } void Corzdlg::getkind(int num) { choose=num; } void Corzdlg::GetString(CString s) { name=s; }
public.h
// Public.h: interface for the CPublic class. // ////////////////////////////////////////////////////////////////////// #include "Heros.h" #if !defined(AFX_PUBLIC_H__D6D464F4_8250_4FFD_9FC0_2C8D4E1DE24B__INCLUDED_) #define AFX_PUBLIC_H__D6D464F4_8250_4FFD_9FC0_2C8D4E1DE24B__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CPublic { public: CPublic(); virtual ~CPublic(); public: static int UNIT; static int MAPX,MAPY; static bool GAMESTART; static bool GAMEOVER; }; #endif // !defined(AFX_PUBLIC_H__D6D464F4_8250_4FFD_9FC0_2C8D4E1DE24B__INCLUDED_)
public.cpp
// Public.h: interface for the CPublic class. // ////////////////////////////////////////////////////////////////////// #include "Heros.h" #if !defined(AFX_PUBLIC_H__D6D464F4_8250_4FFD_9FC0_2C8D4E1DE24B__INCLUDED_) #define AFX_PUBLIC_H__D6D464F4_8250_4FFD_9FC0_2C8D4E1DE24B__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CPublic { public: CPublic(); virtual ~CPublic(); public: static int UNIT; static int MAPX,MAPY; static bool GAMESTART; static bool GAMEOVER; }; #endif // !defined(AFX_PUBLIC_H__D6D464F4_8250_4FFD_9FC0_2C8D4E1DE24B__INCLUDED_)
还有一些都是MFC自动生成的几个文件:DotA_H4.h,DotA_H4.cpp,DotA_H4Doc.h,DotA_H4Doc.cpp,Resource.h,Resource.cpp,stdafx.h,stdafx.cpp
这里就不贴了。