版本:VS2015 语言:C++
今天不知道为什么没什么工作,书看着看着第三章就结束了,Windows高级编程部分内容比较杂乱,东西也比较多,但是作者压缩得很好,把多数懂点都突出出来了,推荐买这本书。(《Windows游戏编程大师技巧》还是把名字加上吧)
个人比较期待第十二章的人工智能,好想偷看一下,不过还是循序渐进吧。
本节的内容,主要介绍我在VS2015上玩的一些有趣的东西,然后试图在cocos中改变鼠标指针的方法,最后介绍如何输出一些文本文字。
而事件处理相关的内容就不介绍了,其实跟cocos中Touch事件差不多,有一个回调函理,根据参数进行不同的处理。
好了,让我们开始今天的内容吧。
想要添加一个资源,在cocos中很简单,把资源放到Resources下面,然后直接像Sprite::create("riinn.png")创建。或者第二种方法:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("senokiseki.plist");
Sprite* spriteRiinn = Sprite::createWithSpriteFrameName("riinn.png");
使用plist文件,这样我们就成功获取里恩私房照了。虽然plist并为了获取方便而设计的,不过Windows编程上获取资源的操作与之类似,所以拿来举例了。
以icon图标来说,首先准备个图标:
蘑菇,没错,稍微有点大,没事。把我们的ico文件放到工程底下,然后就是添加资源就行了。
简单的来说:kinoko.ico -> Win32Project.rc -> Resource.h -> 程序中。以这样的方式添加程序中使用,看起来有些复杂是吧。其实很方便的。
如果使用VS创建的默认工程的话rc和Resource.h这两个文件都是有的,在里面添加就行,没有的话,在工程目录底下新建一下。
让我们打开rc文件,添加这么一段:
#include "resource.h" //别忘了包含资源文件,有了的话就不用包含了
ICO_KINOKO ICON "kinoko.ico" //名称、类型、具体路径
这样我们可以用ICO_KINOKO字符串直接获取这个ico资源了。但是直接使用字符串获取的方法容易出错,而且VS2015中获取得有点问题,实例工程中都是使用Resource.h方法的,我们就不讨论字符串获取的方法了,有兴趣的玩家可以看看书,自己研究一下。
然后是Resource.h文件:
#define ICO_KINOKO 1024
没错只要定义标识符的唯一int值就行了,最后是程序中使用,在创建窗口类的时候:
wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ICO_KINOKO)); //任务栏上的图标
wndclass.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(ICO_KINOKO)); //应用上的图标
这样就能看到效果了:
这里使用MAKEINTRESOURCE宏,这个宏在添加资源的时候会一直用到的,不要忘了,它会把你所定义的int值转换为具体资源的索引。
其他资源的使用也差不多:
//rs文件
CUR_BLUE CURSOR "bluearrow.cur" //光标资源
WAV_CREATE WAVE "create.wav" //音乐资源
STRINGTABLE //字符表
{
STRING_ENTER "进入"
}
//Resource.h
#define CUR_BLUE 1025
#define WAV_CREATE 1026
#define STRING_ENTER 1027
//Windows程序中使用
wndclass.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(CUR_BLUE)); //光标的读取
PlaySound(MAKEINTRESOURCE(WAV_CREATE), hInstance, SND_ASYNC | SND_RESOURCE); //我说要声音,就有了声音,声音读取并播放!
LPTSTR buffer = new TCHAR[1024];
LoadString(hInstance, STRING_ENTER, buffer, lstrlen(buffer)); //读入字符串
以上是光标资源、音乐资源和字符表的使用,字符表稍微有点奇怪,但是很好理解。至于音乐的话,玩家们别忘了相关头文件的导入和lib的链接:
#include <playsoundapi.h>
然后在链接里面加入lib:WINMM.LIB。具体导入的方法,请看我第一篇Windows编程的文章。
在Windows上添加一个菜单栏也其实是差不多的,让我们来看看:
MENU_MINE MENU DISCARDABLE //一个简单的菜单,rc文件中
{
POPUP "&File"
{
POPUP "Open"
{
POPUP "NEW"
{
MENUITEM "NEW", MENU_FILE_ID_OPEN
}
}
MENUITEM "Close", MENU_FILE_ID_CLOSE
MENUITEM "Save", MENU_FILE_ID_SAVE
MENUITEM "Eixt", MENU_FILE_ID_EXIT
}
POPUP "Help"
{
MENUITEM "About", MENU_HELP_ABOUT
}
}
#define MENU_MINE 501 //菜单项的数值定义,Resource.h文件
#define MENU_FILE_ID_OPEN 502
#define MENU_FILE_ID_CLOSE 503
#define MENU_FILE_ID_SAVE 504
#define MENU_FILE_ID_EXIT 505
#define MENU_HELP_ABOUT 506
HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(MENU_MINE)); //获取一个菜单
SetMenu(hwnd, hMenu); //设置
有一个问题就是菜单为什么要定义那么多的值,这个是在触发事件的时候用到的,处理事件的时候得知道你点了哪个菜单项吧。
这个方法有点小BUG,就是最外层的菜单栏是无法点进去的,所以我绑定了一个快捷键:Alt+F,就是那个小小的&符号的应用了。
我们现在能改变资源了吧,那我就在想,把cocos在Windows平台上的光标给改掉吧。说干就干,弄了我好久,最后也只是勉强实现了,因为cocos用的是MFC,那里面的代码简直……我就不做深入探究了。
通过之前的方法导入想要的光标资源后,在main.cpp中的_tWinMain方法中加入这么三句代码:
HCURSOR hcur = NULL;
hcur = LoadCursor(myInstance, MAKEINTRESOURCE(CUR_MINE));
SetCursor(hcur);
但是只能在进入游戏的一瞬间才能看到改变了吧?哈哈,这个就是坑爹的地方,MFC会每隔一段时间,把光标还原会系统光标。要改的话得动cocos源代码了,有时间给大家出个攻略。
最后给大家介绍一下如何在屏幕上输出一段文字内容。找到我们之前写游戏主循环的地方:
// 进入主循环
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else //没有消息
{
//GameMain() //进入游戏的主循环
HDC hdc = GetDC(hwnd); //获取设备表句柄,一般是图形设备表,不用管它是什么,只要知道想要绘图一定要先写这句,最后在Release一下
SetTextColor(hdc, RGB(rand() % 256, rand() % 256, rand() % 256)); //设置文字颜色
SetBkColor(hdc, RGB(0, 0, 0)); //设置背景颜色
SetBkMode(hdc, TRANSPARENT); //设置背景是否要透明,不透明的参数:OPAQUE。设置了透明背景色当然就没用了
TextOut(hdc, rand() % 400, rand() % 400, TEXT("GDI Text Demo!"), strlen("GDI TextDemo!")); //在随机的0 *0 -> 400 * 400的区间内输出文字
ReleaseDC(hwnd, hdc); //释放
Sleep(100); //每隔0.1秒输出一次
}
}
好了,这样就可以看到文字输出在窗口上了:
真好玩!就是网上说MFC说得有点虚,嗯,我还是很在意光标的事情。
最后让我来讨论一个问题:
hdc = BeginPaint(hwnd, &ps);
//需要渲染的内容
EndPaint(hwnd, &ps);
以上的代码似乎和GetDC类似,就是要把自己输出的内容放到这两行代码之间。但是BeginPaint完全是个坑爹货,根据我实际操作发现它有时候并不能进行绘制,那么它会在什么时候绘制呢?
查了一下网上的资料:
1.BeginPaint仅用户无效区域内的绘图
2.GetDC主动绘图,指哪绘哪
所以大家就用GetDC就好了。
Windows编程上有很多知识点,我这个也不好总结,只能给大家看看使用的方法,然后一些问题,最后解决的方案。
编程上的事情,除了多看看别人的代码拓宽一下自己的思路以外,一定要自己手动去编编看。