前几天写了一个sb一般的小游戏,然后没人玩,然后很难过。但是坑得填。
下面开始正经
第一部分 总述
cloudfight是我脑子里抽风了想出来的一个想法,基于C++ rand()做的一个小游戏。
【说是云打架。。其实没有云】
cloudfight【以下简称cf】完全由windows sdk开发 没有使用任何其他的库,开发环境为VS 社区版。
gui.cpp管理cf的ui界面,work.cpp管理计算部分 stdafx.h写了包含所需的头文件。
主要运行流程:
gui.cpp启动WinMain 由WinMain注册并创建主窗体。
Winproc处理消息,得到输入后由work.cpp执行操作
work.cpp先交由 init() initconf()创建随机种子并且读取配置文件。再由相关函数获得两人战斗力、hp等
最后由fight()获得战斗过程,并传给Winproc。
Winproc获得战斗过程后,创建新线程Paint,并打印战斗过程。
打印结束后回收相关内存,等待下一次输入。
【所以说麻雀虽小五脏俱全】
第二部分 细节分析
1.UI方面
全部UI基于win32 SDK 所以很丑
窗口创建啊,改背景颜色就不说了
控件部分:
LOGFONT fontRect; memset(&fontRect,0,sizeof fontRect); fontRect.lfHeight=25; fontRect.lfWeight=400; lstrcpy(fontRect.lfFaceName,L"黑体"); hFont=CreateFontIndirect(&fontRect); hwndTemp=CreateWindow(L"STATIC",L"输入姓名A",WS_CHILD|WS_VISIBLE|SS_SIMPLE,40,80,200,200,hwnd,NULL,clf,NULL); SendMessage(hwndTemp,WM_SETFONT,(WPARAM)hFont,(LPARAM)true); hwndTemp=CreateWindow(L"STATIC",L"输入姓名B",WS_CHILD|WS_VISIBLE|SS_SIMPLE,40,160,200,200,hwnd,NULL,clf,NULL); SendMessage(hwndTemp,WM_SETFONT,(WPARAM)hFont,(LPARAM)true); hwndEditA=CreateWindow(L"EDIT",L"",WS_CHILD|WS_VISIBLE|WS_BORDER,160,78,200,30,hwnd,NULL,clf,NULL); SendMessage(hwndEditA,WM_SETFONT,(WPARAM)hFont,(LPARAM)true); hwndEditB=CreateWindow(L"EDIT",L"",WS_CHILD|WS_VISIBLE|WS_BORDER,160,158,200,30,hwnd,NULL,clf,NULL); SendMessage(hwndEditB,WM_SETFONT,(WPARAM)hFont,(LPARAM)true); hwndBtn=CreateWindow(L"BUTTON",L" FIGHT ",WS_CHILD|WS_VISIBLE,160,250,120,120,hwnd,NULL,clf,NULL); SendMessage(hwndBtn,WM_SETFONT,(WPARAM)hFont,(LPARAM)true); hwndOut=CreateWindow(L"EDIT",NULL,WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_BORDER|ES_LEFT|ES_MULTILINE|ES_NOHIDESEL|ES_AUTOVSCROLL,440,20,420,400,hwnd,NULL,clf,NULL); fontRect.lfHeight=18;hFont=CreateFontIndirect(&fontRect); SendMessage(hwndOut,WM_SETFONT,(WPARAM)hFont,(LPARAM)true);
文字均用静态控件呈现,这样效率高
EDIT用WS_VSCROLL|WS_BORDER|ES_LEFT|ES_MULTILINE|ES_NOHIDESEL|ES_AUTOVSCROLL实现自动换行
比较值得说的一点就是字体的控制
想了半天用了这种方法,用CreateFontIndirect直接创建字体,然后再通过SendMessage改变字体
这样似乎是一种很好的方法?也许有更好的。
文字信息的输出:
为提高效率,在EDIT里采用追加方式输出文本
具体实现就是,跳转到最后一行,再输出文本
void inline makeout(HWND hwnd,char ss[]) { int len=strlen(ss),lst=0; for(int i=0;i<len;i++) { if(ss[i]=='#') { Sleep(1000); char output[500];memset(output,0,sizeof output); WCHAR Buf[500];memset(Buf,0,sizeof Buf); for(int j=lst,k=0;j<i;j++,k++)output[k]=ss[j]; strcat_s(output,"\r\n"); MultiByteToWideChar(CP_ACP,0,output,strlen(output)+1,Buf, sizeof(Buf)/sizeof(Buf[0])); SendMessage(hwnd,EM_SETSEL,-1,-1); SendMessage(hwnd,EM_REPLACESEL,0,(LPARAM)Buf); SendMessage(hwnd,WM_VSCROLL,SB_BOTTOM,0); lst=i+1; } } }
还有一件事,就是宽字符与窄字符互相转化,这里不多赘述
我也云里雾里,贴一下代码过几天学吧。
//宽字符转窄字符 int sz=WideCharToMultiByte(CP_ACP,0,Buf1,-1,NULL,0,NULL,NULL); WideCharToMultiByte(CP_ACP,0,Buf1,-1,BufA,sz,NULL,NULL); //窄字符转宽字符 MultiByteToWideChar(CP_ACP,0,output,strlen(output)+1,Buf,sizeof(Buf)/sizeof(Buf[0]));
“关于”对话框的实现:
用的VS的对话框编辑器,然后自己写一个控制函数就行了
我叫他 AbtProc 23333
有一点不理解 为什么必须return (INT_PTR)FALSE;
要不然会卡死。。以后再研究
特别说一下网页的打开
用默认浏览器打开直接open url就行,但是有些情况下会失效?
于是判断一下是否打开成功,如果不行,就用IE打开
void OpenUrl(LPCWSTR url) { HINSTANCE result=ShellExecute(NULL, L"open", url, NULL, NULL, SW_SHOW); if((int)result<=HINSTANCE_ERROR) result=ShellExecute(NULL, NULL, L"iexplore.exe", url, NULL, SW_SHOW); }
菜单栏实现:
用的VS的菜单编辑器 这里不提了
2.游戏方面
先计算随机数。。再得到power值。。再获取打架过程
代码太丑 不好意思说
可以透露的是,用的一个随机数种子是我的生日。
似乎没啥可说的。。悲伤
应该叫(雾)打架