windows游戏输入消息处理
windows游戏输入消息处理
虚拟键码与键盘消息
在windows中,所有键盘的按键都被定于为一组通用的“虚拟键码”,在Windows系统下所有按键都被视为虚拟键,而每一个虚拟键都有其对应的虚拟键码
indows虚拟键盘码
虚拟键码 | 对应值 | 对应键 | 虚拟键码 | 对应值 | 对应键 | |
---|---|---|---|---|---|---|
VK_LBUTTON | 1 | 鼠标左键 | VK_NUMPAD6 | 102 | 小键盘 6 | |
VK_RBUTTON | 2 | 鼠标右键 | VK_NUMPAD7 | 103 | 小键盘 7 | |
VK_CANCEL | 3 | Cancel | VK_NUMPAD8 | 104 | 小键盘 8 | |
VK_MBUTTON | 4 | 鼠标中键 | VK_NUMPAD9 | 105 | 小键盘 9 | |
VK_XBUTTON1 | 5 | VK_MULTIPLY | 106 | 小键盘 * | ||
VK_XBUTTON2 | 6 | VK_ADD | 107 | 小键盘 + | ||
VK_BACK | 8 | Backspace | VK_SEPARATOR | 108 | 小键盘 Enter | |
VK_TAB | 9 | Tab | VK_SUBTRACT | 109 | 小键盘 - | |
VK_CLEAR | 12 | Clear | VK_DECIMAL | 110 | 小键盘 . | |
VK_RETURN | 13 | Enter | VK_DIVIDE | 111 | 小键盘 / | |
VK_SHIFT | 16 | Shift | VK_F1 | 112 | F1 | |
VK_CONTROL | 17 | Ctrl | VK_F2 | 113 | F2 | |
VK_MENU | 18 | Alt | VK_F3 | 114 | F3 | |
VK_PAUSE | 19 | Pause | VK_F4 | 115 | F4 | |
VK_CAPITAL | 20 | Caps Lock | VK_F5 | 116 | F5 | |
VK_KANA | 21 | VK_F6 | 117 | F6 | ||
VK_HANGUL | 21 | VK_F7 | 118 | F7 | ||
VK_JUNJA | 23 | VK_F8 | 119 | F8 | ||
VK_FINAL | 24 | VK_F9 | 120 | F9 | ||
VK_HANJA | 25 | VK_F10 | 121 | F10 | ||
VK_KANJI | 25* | VK_F11 | 122 | F11 | ||
VK_ESCAPE | 27 | Esc | VK_F12 | 123 | F12 | |
VK_CONVERT | 28 | VK_F13 | 124 | |||
VK_NONCONVERT | 29 | VK_F14 | 125 | |||
VK_ACCEPT | 30 | VK_F15 | 126 | |||
VK_MODECHANGE | 31 | VK_F16 | 127 | |||
VK_SPACE | 32 | Space | VK_F17 | 128 | ||
VK_PRIOR | 33 | Page Up | VK_F18 | 129 | ||
VK_NEXT | 34 | Page Down | VK_F19 | 130 | ||
VK_END | 35 | End | VK_F20 | 131 | ||
VK_HOME | 36 | Home | VK_F21 | 132 | ||
VK_LEFT | 37 | Left Arrow | VK_F22 | 133 | ||
VK_UP | 38 | Up Arrow | VK_F23 | 134 | ||
VK_RIGHT | 39 | Right Arrow | VK_F24 | 135 | ||
VK_DOWN | 40 | Down Arrow | VK_NUMLOCK | 144 | Num Lock | |
VK_SELECT | 41 | Select | VK_SCROLL | 145 | Scroll | |
VK_PRINT | 42 | VK_LSHIFT | 160 | |||
VK_EXECUTE | 43 | Execute | VK_RSHIFT | 161 | ||
VK_SNAPSHOT | 44 | Snapshot | VK_LCONTROL | 162 | ||
VK_INSERT | 45 | Insert | VK_RCONTROL | 163 | ||
VK_DELETE | 46 | Delete | VK_LMENU | 164 | ||
VK_HELP | 47 | Help | VK_RMENU | 165 | ||
48 | 0 | VK_BROWSER_BACK | 166 | |||
49 | 1 | VK_BROWSER_FORWARD | 167 | |||
50 | 2 | VK_BROWSER_REFRESH | 168 | |||
51 | 3 | VK_BROWSER_STOP | 169 | |||
52 | 4 | VK_BROWSER_SEARCH | 170 | |||
53 | 5 | VK_BROWSER_FAVORITES | 171 | |||
54 | 6 | VK_BROWSER_HOME | 172 | |||
55 | 7 | VK_VOLUME_MUTE | 173 | VolumeMute | ||
56 | 8 | VK_VOLUME_DOWN | 174 | VolumeDown | ||
57 | 9 | VK_VOLUME_UP | 175 | VolumeUp | ||
65 | A | VK_MEDIA_NEXT_TRACK | 176 | |||
66 | B | VK_MEDIA_PREV_TRACK | 177 | |||
67 | C | VK_MEDIA_STOP | 178 | |||
68 | D | VK_MEDIA_PLAY_PAUSE | 179 | |||
69 | E | VK_LAUNCH_MAIL | 180 | |||
70 | F | VK_LAUNCH_MEDIA_SELECT | 181 | |||
71 | G | VK_LAUNCH_APP1 | 182 | |||
72 | H | VK_LAUNCH_APP2 | 183 | |||
73 | I | VK_OEM_1 | 186 | ; : | ||
74 | J | VK_OEM_PLUS | 187 | = + | ||
75 | K | VK_OEM_COMMA | 188 | |||
76 | L | VK_OEM_MINUS | 189 | - _ | ||
77 | M | VK_OEM_PERIOD | 190 | |||
78 | N | VK_OEM_2 | 191 | / ? | ||
79 | O | VK_OEM_3 | 192 | ` ~ | ||
80 | P | VK_OEM_4 | 219 | [ { | ||
81 | Q | VK_OEM_5 | 220 | \ | | ||
82 | R | VK_OEM_6 | 221 | ] } | ||
83 | S | VK_OEM_7 | 222 | ’ " | ||
84 | T | VK_OEM_8 | 223 | |||
85 | U | VK_OEM_102 | 226 | |||
86 | V | VK_PACKET | 231 | |||
87 | W | VK_PROCESSKEY | 229 | |||
88 | X | VK_ATTN | 246 | |||
89 | Y | VK_CRSEL | 247 | |||
90 | Z | VK_EXSEL | 248 | |||
VK_LWIN | 91 | VK_EREOF | 249 | |||
VK_RWIN | 92 | VK_PLAY | 250 | |||
VK_APPS | 93 | VK_ZOOM | 251 | |||
VK_SLEEP | 95 | VK_NONAME | 252 | |||
VK_NUMPAD0 | 96 | 小键盘 0 | VK_PA1 | 253 | ||
VK_NUMPAD1 | 97 | 小键盘 1 | VK_OEM_CLEAR | 254 | ||
VK_NUMPAD2 | 98 | 小键盘 2 | ||||
VK_NUMPAD3 | 99 | 小键盘 3 | ||||
VK_NUMPAD4 | 100 | 小键盘 4 | ||||
VK_NUMPAD5 | 101 | 小键盘 5 |
Windows系统是一个消息驱动的环境,一旦在键盘上进行输入操作,系统就会接受到相应的键盘消息,以下就是五种常见的键盘消息;
键盘消息类型 | 精析 |
---|---|
WM_KEYDOWN | 按下按键的消息 |
WM_KEYUP | 松开按键消息 |
WM_SYSKEYDOWN | 按下系统键 |
WM_SYSKEYUP | 按下消息键 |
WM_CHAR | 字符消息 |
当某一按键按下去,伴随这个操作产生以虚拟键码类型传送的WM_KEYDOWN与WM_KEYUP消息,当程序接受这些消息,便可由虚拟键码的消息来得知是那个按键按下,WM_CHAR是由ASCII中可打印字符时,便发送此消息;
键盘消息处理
windows中,键盘消息和其他消息一视同仁,同样在消息处理函数中间来处理的,而按下事件一定紧随一个松开按键的事件,因此WM_KEYDOWN与WM_KEYUP两种消息陈队发送的,一般处理,WM_KEYDOWN消息处理,无视WM_KEYUP消息
WindowsProc是窗口过程函数,窗口过程函数有两个参数与消息输出有关,他们是wParam IParam,当键盘消息触发时,wParam的值为按下按键的虚拟键码,Windows定义的虚拟键码是VK开头的,IParam存储按键的相关状态消息,程序要对键盘输入操作处理,可以用switch进行wParam就可以对内容进行处理;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{switch( message ) //switch语句开始{case WM_KEYDOWN: //按下键盘消息//判断按键的虚拟键码switch (wParam) {case VK_ESCAPE: //按下【Esc】键DestroyWindow(hwnd); // 销毁窗口, 并发送一条WM_DESTROY消息PostQuitMessage( 0 ); //结束程序break;case VK_UP: //按下【↑】键//根据按键加入人物移动的量(每次按下一次按键移动10个单位),来决定人物贴图坐标的X与Y值,接着判断坐标是否超出窗口区域,若有则进行修正g_iY -= 10;g_iDirection = 0;if(g_iY < 0)g_iY = 0;break;case VK_DOWN: //按下【↓】键g_iY += 10;g_iDirection = 1; // 主要这个变量,它可以通过对应的数字来进行贴图if(g_iY > WINDOW_HEIGHT-135)g_iY = WINDOW_HEIGHT-135; break;case VK_LEFT: //按下【←】键 g_iX -= 10;g_iDirection = 2;if(g_iX < 0)g_iX = 0; break;case VK_RIGHT: //按下【→】键g_iX += 10;g_iDirection = 3;if(g_iX > WINDOW_WIDTH-75)g_iX = WINDOW_WIDTH-75;break;} break; //跳出该switch语句case WM_DESTROY: //若是窗口销毁消息Game_CleanUp(hwnd); //调用自定义的资源清理函数Game_CleanUp()进行退出前的资源清理PostQuitMessage( 0 ); //向系统表明有个线程有终止请求。用来响应WM_DESTROY消息break; //跳出该switch语句default: //若上述case条件都不符合,则执行该default语句return DefWindowProc( hwnd, message, wParam, lParam ); //调用缺省的窗口过程}return 0; //正常退出
}
windows 鼠标消息处理
Windows中鼠标设备输入时消息类型:
十进制 | 十六进制 | WINUSER.H标识符 | 必需? | IBM兼容键盘 |
---|---|---|---|---|
1 | 01 | VK_LBUTTON | 鼠标左键 | |
2 | 02 | VK_RBUTTON | 鼠标右键 | |
3 | 03 | VK_CANCEL | ˇ | Ctrl-Break |
4 | 04 | VK_MBUTTON | 鼠标中键 |
鼠标消息与处理键盘消息的方法类似,在消息处理函数中加入要处理的鼠标消息类型,当鼠标消息发生时,输入的参数wParam与IParam存储的鼠标状态相关信息
在IParam参数中,可分为高位字节和低位字节,高位存储鼠标光标所在的X坐标,低位y坐标,用以下两个宏获得坐标值:
WORD LOWORD(DWORD dwValue) //返回鼠标光标所在的X坐标值
WORD HIWORD(DWORD dwValue) //返回鼠标光标所在的y坐标值
wParam参数,这个参数记录鼠标按键及键盘的ctrl与shift键的状态信息;
符号常量 | 数值 | 含义 |
---|---|---|
MK_CONTROL | 8 | Ctrl键被按下 |
MK_LBUTTON | 1 | 左鼠标键被按下 |
MK_MBUTTON | 16 | 中鼠标键被按下 |
MK_RBUTTON | 2 | 右鼠标键被按下 |
MK_SHIFT | 4 | Shift键被按下 |
比如某个鼠标消息发生时,测试鼠标左键是否按下,就可以用wParam与某种消息进行&一下就可以知道:
if(wParam & MK_LBUTTON)
{//鼠标左键相应的处理的代码
}
滚轮消息:WM_MOUSEWHEEL,当鼠标滚轮转动消息发生时,IParam参数中的值同样记录着光标所在的位置,而wParam参数分别对应着高低位两部分,低位记录着存储鼠标键,shift ctrl等信息,高位记录着数字,也就是120 -120 这样的滚动数字
HIWORD(wParam);//高位组
LOWORD(wParam);//低位组
鼠标相关的API
设定鼠标光标位置的函数:SetCursorPos函数设定光标的位置
WINUSERAPI BOOL WINAPI SetCursorPos(_In_ int X, // x 坐标_In_ int Y); // y 坐标 这个坐标是相对于屏幕左上角的,// 需要API 中的一个将窗口坐标转换到屏幕坐标的函数,
WINUSERAPI BOOL WINAPI ClientToScreen(_In_ HWND hWnd, //转换到屏幕坐标的窗口的句柄_Inout_ LPPOINT lpPoint); // 指向一个含有要转换的用户坐标结构的指针
// 上面API中逆向的转换函数
WINUSERAPI BOOL WINAPI ScreenToClient(_In_ HWND hWnd,_Inout_ LPPOINT lpPoint);
//显示与隐藏鼠标光标的函数
WINUSERAPI int WINAPI ShowCursor(_In_ BOOL bShow); // 取true显示光标,取flase 隐藏光标
//获取窗口外鼠标消息的函数,这个函数的意思是只要捕获当前线程的鼠标,无论鼠标是否在窗口它都会获取
WINUSERAPI HWND WINAPI SetCapture( _In_ HWND hWnd); // 当前线程里捕获鼠标的窗口句柄
//释放当前鼠标
WINUSERAPI BOOL WINAPI ReleaseCapture(VOID);
//限制鼠标光标移动区域的函数
WINUSERAPI BOOL WINAPI ClipCursor(_In_opt_ CONST RECT *lpRect);
//指向RECT的结构体,这个结构体是一个限制矩形区域左上角和右下角的屏幕坐标,如果为空可以在任意角度来移动//取得窗口外部的区域及内部区域的函数
WINUSERAPI BOOL WINAPI GetWindowRect( //取得窗口外部的矩形区域_In_ HWND hWnd, _Out_ LPRECT lpRect);WINUSERAPI BOOL WINAPI GetClientRect( //取得窗口内部的矩形区域_In_ HWND hWnd,_Out_ LPRECT lpRect);
code:
//-----------------------------------【程序说明】----------------------------------------------
// 描述:Windows消息处理之 鼠标消息处理 示例程序
//------------------------------------------------------------------------------------------------//-----------------------------------【头文件包含部分】---------------------------------------
// 描述:包含程序所依赖的头文件
//------------------------------------------------------------------------------------------------
#include <windows.h>
#include <tchar.h>//使用swprintf_s函数所需的头文件//-----------------------------------【库文件包含部分】---------------------------------------
// 描述:包含程序所依赖的库文件
//------------------------------------------------------------------------------------------------
#pragma comment(lib,"winmm.lib") //调用PlaySound函数所需库文件
#pragma comment(lib,"Msimg32.lib") //添加使用TransparentBlt函数所需的库文件//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_WIDTH 800 //为窗口宽度定义的宏,以方便在此处修改窗口宽度
#define WINDOW_HEIGHT 600 //为窗口高度定义的宏,以方便在此处修改窗口高度
#define WINDOW_TITLE L"【致我们永不熄灭的游戏开发梦想】Windows消息处理之 鼠标消息处理 " //为窗口标题定义的宏//-----------------------------------【全局结构体定义部分】-------------------------------------
// 描述:全局结构体定义
//------------------------------------------------------------------------------------------------
struct SwordBullets //SwordBullets结构体代表剑气(子弹)
{int x,y; //剑气(子弹)坐标bool exist; //剑气(子弹)是否存在
};//-----------------------------------【全局变量声明部分】-------------------------------------
// 描述:全局变量的声明
//------------------------------------------------------------------------------------------------
HDC g_hdc=NULL,g_mdc=NULL,g_bufdc=NULL; //全局设备环境句柄与全局内存DC句柄
HBITMAP g_hSwordMan=NULL,g_hSwordBlade=NULL,g_hBackGround=NULL; //定义位图句柄用于存储位图资源
DWORD g_tPre=0,g_tNow=0; //声明l两个函数来记录时间,g_tPre记录上一次绘图的时间,g_tNow记录此次准备绘图的时间
int g_iX=0,g_iY=0,g_iXnow=0,g_iYnow=0; //g_iX,g_iY代表鼠标光标所在位置,g_iXnow,g_iYnow代表当前人物坐标,也就是贴图的位置
int g_iBGOffset=0,g_iBulletNum=0; //g_iBGOffset为滚动背景所要裁剪的区域宽度,g_iBulletNum记录剑侠现有剑气(子弹)数目
SwordBullets Bullet[30]; //声明一个“SwordBullets”类型的数组,用来存储剑侠发出的剑气(子弹)//-----------------------------------【全局函数声明部分】-------------------------------------
// 描述:全局函数声明,防止“未声明的标识”系列错误
//------------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );//窗口过程函数
BOOL Game_Init(HWND hwnd); //在此函数中进行资源的初始化
VOID Game_Paint( HWND hwnd); //在此函数中进行绘图代码的书写
BOOL Game_CleanUp(HWND hwnd ); //在此函数中进行资源的清理//-----------------------------------【WinMain( )函数】--------------------------------------
// 描述:Windows应用程序的入口函数,我们的程序从这里开始
//------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{//【1】窗口创建四步曲之一:开始设计一个完整的窗口类WNDCLASSEX wndClass = { 0 }; //用WINDCLASSEX定义了一个窗口类wndClass.cbSize = sizeof( WNDCLASSEX ) ; //设置结构体的字节数大小wndClass.style = CS_HREDRAW | CS_VREDRAW; //设置窗口的样式wndClass.lpfnWndProc = WndProc; //设置指向窗口过程函数的指针wndClass.cbClsExtra = 0; //窗口类的附加内存,取0就可以了wndClass.cbWndExtra = 0; //窗口的附加内存,依然取0就行了wndClass.hInstance = hInstance; //指定包含窗口过程的程序的实例句柄。wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE); //本地加载自定义ico图标wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); //指定窗口类的光标句柄。wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); //为hbrBackground成员指定一个白色画刷句柄 wndClass.lpszMenuName = NULL; //用一个以空终止的字符串,指定菜单资源的名字。wndClass.lpszClassName = L"ForTheDreamOfGameDevelop"; //用一个以空终止的字符串,指定窗口类的名字。//【2】窗口创建四步曲之二:注册窗口类if( !RegisterClassEx( &wndClass ) ) //设计完窗口后,需要对窗口类进行注册,这样才能创建该类型的窗口return -1; //【3】窗口创建四步曲之三:正式创建窗口HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE, //喜闻乐见的创建窗口函数CreateWindowWS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );//【4】窗口创建四步曲之四:窗口的移动、显示与更新MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true); //调整窗口显示时的位置,使窗口左上角位于(250,80)处ShowWindow( hwnd, nShowCmd ); //调用ShowWindow函数来显示窗口UpdateWindow(hwnd); //对窗口进行更新,就像我们买了新房子要装修一样//游戏资源的初始化,若初始化失败,弹出一个消息框,并返回FALSEif (!Game_Init (hwnd)) {MessageBox(hwnd, L"资源初始化失败", L"消息窗口", 0); //使用MessageBox函数,创建一个消息窗口return FALSE;}PlaySound(L"仙剑三·原版战斗3.wav", NULL, SND_FILENAME | SND_ASYNC|SND_LOOP); //循环播放背景音乐 //【5】消息循环过程MSG msg = { 0 }; //定义并初始化msgwhile( msg.message != WM_QUIT ) //使用while循环,如果消息不是WM_QUIT消息,就继续循环{if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) //查看应用程序消息队列,有消息时将队列中的消息派发出去。{TranslateMessage( &msg ); //将虚拟键消息转换为字符消息DispatchMessage( &msg ); //分发一个消息给窗口程序。}else{g_tNow = GetTickCount(); //获取当前系统时间if(g_tNow-g_tPre >= 5) //当此次循环运行与上次绘图时间相差0.1秒时再进行重绘操作Game_Paint(hwnd);}}//【6】窗口类的注销UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance); //程序准备结束,注销窗口类return 0;
}//-----------------------------------【WndProc( )函数】--------------------------------------
// 描述:窗口过程函数WndProc,对窗口消息进行处理
//------------------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{switch( message ) //switch语句开始{case WM_KEYDOWN: //按下键盘消息//判断按键的虚拟键码switch (wParam) {case VK_ESCAPE: //按下【Esc】键DestroyWindow(hwnd); // 销毁窗口, 并发送一条WM_DESTROY消息PostQuitMessage( 0 ); //结束程序break;}break;case WM_LBUTTONDOWN: //单击鼠标左键消息for(int i=0;i<30;i++){if(!Bullet[i].exist){Bullet[i].x = g_iXnow; //剑气(子弹)x坐标Bullet[i].y = g_iYnow + 30; //剑气(子弹)y坐标Bullet[i].exist = true;g_iBulletNum++; //累加剑气(子弹)数目break;}}case WM_MOUSEMOVE: //鼠标移动消息//对X坐标的处理g_iX = LOWORD(lParam); //取得鼠标X坐标if(g_iX > WINDOW_WIDTH-317) //设置临界坐标g_iX = WINDOW_WIDTH-317;else if(g_iX < 0)g_iX = 0;//对Y坐标的处理g_iY = HIWORD(lParam); //取得鼠标Y坐标if(g_iY > WINDOW_HEIGHT-283)g_iY = WINDOW_HEIGHT-283;else if(g_iY < -200)g_iY = -200;break;case WM_DESTROY: //若是窗口销毁消息Game_CleanUp(hwnd); //调用自定义的资源清理函数Game_CleanUp()进行退出前的资源清理PostQuitMessage( 0 ); //向系统表明有个线程有终止请求。用来响应WM_DESTROY消息break; //跳出该switch语句default: //若上述case条件都不符合,则执行该default语句return DefWindowProc( hwnd, message, wParam, lParam ); //调用缺省的窗口过程}return 0; //正常退出
}//-----------------------------------【Game_Init( )函数】--------------------------------------
// 描述:初始化函数,进行一些简单的初始化
//------------------------------------------------------------------------------------------------
BOOL Game_Init( HWND hwnd )
{HBITMAP bmp;g_hdc = GetDC(hwnd); g_mdc = CreateCompatibleDC(g_hdc); //创建一个和hdc兼容的内存DCg_bufdc = CreateCompatibleDC(g_hdc);//再创建一个和hdc兼容的缓冲DCbmp = CreateCompatibleBitmap(g_hdc,WINDOW_WIDTH,WINDOW_HEIGHT);//设定人物贴图初始值,鼠标位置初始值g_iX = 300;g_iY = 100;g_iXnow = 300;g_iYnow = 100;SelectObject(g_mdc,bmp);//加载各张跑动图及背景图g_hSwordMan = (HBITMAP)LoadImage(NULL,L"swordman.bmp",IMAGE_BITMAP,317,283,LR_LOADFROMFILE);g_hSwordBlade = (HBITMAP)LoadImage(NULL,L"swordblade.bmp",IMAGE_BITMAP,100,26,LR_LOADFROMFILE);g_hBackGround = (HBITMAP)LoadImage(NULL,L"bg.bmp",IMAGE_BITMAP,WINDOW_WIDTH,WINDOW_HEIGHT,LR_LOADFROMFILE);POINT pt,lt,rb;RECT rect;//设定光标位置pt.x = 300;pt.y = 100;ClientToScreen(hwnd,&pt);SetCursorPos(pt.x,pt.y);ShowCursor(false); //隐藏鼠标光标//限制鼠标光标移动区域GetClientRect(hwnd,&rect); //取得窗口内部矩形//将矩形左上点坐标存入lt中lt.x = rect.left;lt.y = rect.top;//将矩形右下坐标存入rb中rb.x = rect.right;rb.y = rect.bottom;//将lt和rb的窗口坐标转换为屏幕坐标ClientToScreen(hwnd,<);ClientToScreen(hwnd,&rb);//以屏幕坐标重新设定矩形区域rect.left = lt.x;rect.top = lt.y;rect.right = rb.x;rect.bottom = rb.y;//限制鼠标光标移动区域ClipCursor(&rect);Game_Paint(hwnd);return TRUE;
}//-----------------------------------【Game_Paint( )函数】--------------------------------------
// 描述:绘制函数,在此函数中进行绘制操作
//--------------------------------------------------------------------------------------------------
VOID Game_Paint( HWND hwnd )
{//先在mdc中贴上背景图SelectObject(g_bufdc,g_hBackGround);BitBlt(g_mdc,0,0,g_iBGOffset,WINDOW_HEIGHT,g_bufdc,WINDOW_WIDTH-g_iBGOffset,0,SRCCOPY);BitBlt(g_mdc,g_iBGOffset,0,WINDOW_WIDTH-g_iBGOffset,WINDOW_HEIGHT,g_bufdc,0,0,SRCCOPY);wchar_t str[20] = {};//计算剑侠的贴图坐标,设定每次进行剑侠贴图时,其贴图坐标(g_iXnow,g_iYnow)会以10个单位慢慢向鼠标光标所在的目的点(x,y)接近,直到两个坐标相同为止if(g_iXnow < g_iX)//若当前贴图X坐标小于鼠标光标的X坐标{g_iXnow += 10;if(g_iXnow > g_iX)g_iXnow = g_iX;}else //若当前贴图X坐标大于鼠标光标的X坐标{g_iXnow -=10;if(g_iXnow < g_iX)g_iXnow = g_iX;}if(g_iYnow < g_iY) //若当前贴图Y坐标小于鼠标光标的Y坐标{g_iYnow += 10;if(g_iYnow > g_iY)g_iYnow = g_iY;}else //若当前贴图Y坐标大于于鼠标光标的Y坐标{g_iYnow -= 10; if(g_iYnow < g_iY)g_iYnow = g_iY;}//贴上剑侠图SelectObject(g_bufdc,g_hSwordMan);TransparentBlt(g_mdc,g_iXnow,g_iYnow,317,283,g_bufdc,0,0,317,283,RGB(0,0,0));//剑气(子弹)的贴图,先判断剑气(子弹)数目“g_iBulletNum”的值是否为“0”。若不为0,则对剑气(子弹)数组中各个还存在的剑气(子弹)按照其所在的坐标(b[i].x,b[i].y)循环进行贴图操作SelectObject(g_bufdc,g_hSwordBlade);if(g_iBulletNum!=0)for(int i=0;i<30;i++)if(Bullet[i].exist){//贴上剑气(子弹)图TransparentBlt(g_mdc,Bullet[i].x-70,Bullet[i].y+100,100,33,g_bufdc,0,0,100,26,RGB(0,0,0));//设置下一个剑气(子弹)的坐标。剑气(子弹)是从右向左发射的,因此,每次其X轴上的坐标值递减10个单位,这样贴图会产生往左移动的效果。而如果剑气(子弹)下次的坐标已超出窗口的可见范围(h[i].x<0),那么剑气(子弹)设为不存在,并将剑气(子弹)总数g_iBulletNum变量值减1.Bullet[i].x -= 10;if(Bullet[i].x < 0){g_iBulletNum--;Bullet[i].exist = false;}}HFONT hFont; hFont=CreateFont(20,0,0,0,0,0,0,0,GB2312_CHARSET,0,0,0,0,TEXT("微软雅黑")); //创建字体SelectObject(g_mdc,hFont); //选入字体到g_mdc中SetBkMode(g_mdc, TRANSPARENT); //设置文字背景透明SetTextColor(g_mdc,RGB(255,255,0)); //设置文字颜色//在左上角进行文字输出swprintf_s(str,L"鼠标X坐标为%d ",g_iX);TextOut(g_mdc,0,0,str,wcslen(str));swprintf_s(str,L"鼠标Y坐标为%d ",g_iY);TextOut(g_mdc,0,20,str,wcslen(str));//贴上背景图BitBlt(g_hdc,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,g_mdc,0,0,SRCCOPY);g_tPre = GetTickCount();g_iBGOffset += 5; //让背景滚动量+5if(g_iBGOffset==WINDOW_WIDTH)//如果背景滚动量达到了背景宽度值,就置零g_iBGOffset = 0;
}//-----------------------------------【Game_CleanUp( )函数】--------------------------------
// 描述:资源清理函数,在此函数中进行程序退出前资源的清理工作
//---------------------------------------------------------------------------------------------------
BOOL Game_CleanUp( HWND hwnd )
{//释放资源对象DeleteObject(g_hBackGround);DeleteDC(g_bufdc);DeleteDC(g_mdc);ReleaseDC(hwnd,g_hdc);return TRUE;
}
windows游戏输入消息处理相关推荐
- 【Visual C++】游戏开发笔记十二 游戏输入消息处理(一) 键盘消息处理
相信大家都熟悉<仙剑奇侠传98柔情版>的人机交互方式,用的仅仅是键盘.在那个物质并不充裕的时代,一台配置并不高的电脑,一款名叫<仙剑奇侠传>的游戏,却能承载一代人对梦想的追逐. ...
- 【Visual C 】游戏开发笔记十二 游戏输入消息处理 一 键盘消息处理
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...
- 【Visual C++】游戏开发笔记十三 游戏输入消息处理(二) 鼠标消息处理
本系列文章由zhmxy555编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7405479 作者:毛星云 邮箱: happyl ...
- 【Visual C++】游戏开发笔记十三 游戏输入消息处理(二) 鼠标消息处理
上一节我们讲解了键盘消息处理相关的知识.键盘加鼠标作为目前人机交互方式依旧的主流,在讲完键盘消息处理之后接着讲鼠标消息处理,自然是理所当然的. 这一节主要介绍各种鼠标消息的处理方式以及一些相关函数的运 ...
- 【Visual C++】游戏开发笔记四十二 浅墨DirectX教程之十 游戏输入控制利器 DirectInput专场
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...
- 游戏输入控制利器:DirectInput
---------------------------------------------------------------------------------------------------- ...
- 【Visual C++】游戏开发笔记四十二 浅墨DirectX教程之十 游戏输入控制利器:DirectInput专场...
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhmxy555/article/details/8547531 作者:毛星云(浅墨) ...
- Windows游戏编程快速入门方法
Windows游戏编程快速入门方法 Easideao(简单思路) 序言: 从2001年到2005年,在不知不觉中我已经渡过了4年的职业游戏开发生涯.在这4年里经常会有些网友向我询问编程的入门有没有捷径 ...
- Windows游戏编程之从零开始d
Windows游戏编程之从零开始d I'm back~~恩,几个月不见,大家还好吗? 这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧. woxiangnifrr童鞋说每天都在来 ...
- 【Visual C++】游戏开发笔记四十二 浅墨DirectX教程之十 游戏输入控制利器:DirectInput专场
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8547531 作者:毛星云(浅墨 ...
最新文章
- ubuntu chrome java插件_在Ubuntu中为Chrome安装Java插件
- 【转】使用Xcode中的iOS SDK给iphone开发出第一个App程序
- eclipse新建一个java_Eclipse中新建一个java源文件的步骤
- bat 执行 java jar包
- Silverlight 2 相关文章汇总
- mysql order by 日期_mysql order by基于时间的盲注
- 谷歌离线地图Api附获取教程
- java中如何做模糊查询_到底Java里的模糊查询语句该怎么写
- 自学python要多久-大家觉得自学python多久能学会?
- asp.net网上零食销售商城系统
- Struts1的工作流程
- WebCralwer_java
- 分叉币的发展史及价值|ETH、BCH、BSV 2020-03-08
- CSS常用英语词汇大全
- Django介绍,mvc设计模式及mvt设计模式介绍及对比
- input输入框中嵌入下拉选项
- js中的==和===
- Google Gmail 使用 Outlook2003
- python 批量下载财务数据_Python+Wind 批量下载上市公司年报 - Part 1/2
- ID卡(工卡)复制到手机NFC