一、鼠标键入消息

1.WM_LBUTTONDBLCLK       双击鼠标左键;

2.WM_LBUTTONDOWN         单击鼠标左键;

3.WM_LBUTTONUP               松开鼠标左键;

4.鼠标中键及右键分别将上述L替换为M、R;

5.WM_MOUSEMOVE            鼠标移动消息;

6.WM_MOLSEWHEEL          鼠标滚轮消息;

二、鼠标消息处理

1.lParam:其参数值分为高位字节与低位字节,低位字节存储鼠标光标的X坐标值,高位字节存储Y坐标值;

WORD   LOWORD(lParam 参数);

WORD   HIWORD(lParam 参数);

2.wParam:记录鼠标按键及Ctrl、Shift键,通过wParam与测试标志的与操作判断按键是否按下;

测试标志:MK_L/M/RBUTTON(左中右)、MK_SHIFT、MK_CONTROL

3.当处理滚轮消息时,1不变,wParam低位字节存储按键的状态信息,高位字节是120或-120,表示向前或向后滚动;

三、鼠标相关函数

1.HWND  SetCapture(HWND hwnd);

功能:获取窗口外的鼠标消息;

2.BOOL   SetCursorPos(int x轴坐标,int y轴坐标);

功能:设定鼠标光标位置,这里的位置是相对于屏幕左上角的坐标;

3.BOOL  ClientToScreen(HWND hwnd,LPPOINT  窗口点坐标);

功能:窗口点坐标转换为屏幕坐标,然后再使用SetCursorPos函数;

4.BOOL  ScreenToClient(HWND hwnd,LPPOINT  屏幕点坐标);

功能:把屏幕坐标转换为窗口坐标;

5. int      ShowCursor(BOOL true或false);

功能:隐藏及显示鼠标光标;

6.BOOL ClipCursor(CONST RECT 移动区域矩形);

功能:限制鼠标光标的移动区域,解除限制则参数设为NULL;

7.BOOL GetWindowRect(HWND hwnd,LPRECT 矩形结构);

功能:取得窗口外部区域矩形;

8.BOOL GetClientRect(HWND hwnd,LPRECT 矩形结构);

功能:取得窗口内部区域矩形;

四、飞机射击子弹的基本思路

1.一开始未按鼠标左键,则进行背景图的贴图并实现背景循环;

2.移动鼠标触发消息处理函数,获取鼠标光标的位置后,在贴图函数中,根据鼠标光标位置,确定飞机的贴图坐标,为了产生移

动效果,让飞机的坐标缓缓接近鼠标光标;

2.单击鼠标左键,消息处理函数处理该消息,设置第一颗子弹的贴图坐标(因为声明的子弹结构体是全局变量,所以它的成员变量

exist默认被初始化为0),然后回到贴图函数,先贴背景,再贴飞机,最后贴第一颗子弹,现在若不进行任何操作,则在主函数

内继续循环,该子弹的贴图坐标每次循环横坐标都要减10,直到小于0;

3.在第一颗子弹未消失之前,继续单击鼠标左键,此时实现的是两颗子弹的贴图,一直循环一直贴,直到消失;

五、效果

六、代码实现


#include "stdafx.h"
#include <stdio.h>struct BULLET//定义子弹结构体
{int x,y;bool exist;
};HINSTANCE hInst;
HBITMAP bg,ship,bullet;
HDC     hdc,mdc,bufdc;
HWND    hWnd;
DWORD   tPre,tNow;
int     x,y,nowX,nowY;//光标坐标,飞机贴图坐标
int     w=0,bcount;//w为滚动背景所要裁剪的宽度;记录飞机现有的子弹数目
BULLET  b[30];//存储飞机发出的子弹ATOM               MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
void                MyPaint(HDC hdc);int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR     lpCmdLine,int       nCmdShow)
{MSG msg;MyRegisterClass(hInstance);if (!InitInstance (hInstance, nCmdShow)) {return FALSE;}while( msg.message!=WM_QUIT ){if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) ){TranslateMessage( &msg );DispatchMessage( &msg );}else{tNow = GetTickCount();if(tNow-tPre >= 40)MyPaint(hdc);}}return msg.wParam;
}ATOM MyRegisterClass(HINSTANCE hInstance)
{WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX); wcex.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;wcex.lpfnWndProc    = (WNDPROC)WndProc;wcex.cbClsExtra     = 0;wcex.cbWndExtra        = 0;wcex.hInstance     = hInstance;wcex.hIcon         = NULL;wcex.hCursor        = NULL;wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground   = (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName  = NULL;wcex.lpszClassName  = "canvas";wcex.hIconSm      = NULL;return RegisterClassEx(&wcex);
}BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{HBITMAP bmp;POINT pt,lt,rb;RECT rect;hInst = hInstance;hWnd = CreateWindow("canvas", "绘图窗口" , WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);if (!hWnd){return FALSE;}MoveWindow(hWnd,100,100,640,480,true);ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);hdc = GetDC(hWnd);mdc = CreateCompatibleDC(hdc);bufdc = CreateCompatibleDC(hdc);bmp = CreateCompatibleBitmap(hdc,640,480);SelectObject(mdc,bmp);bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,648,480,LR_LOADFROMFILE);ship = (HBITMAP)LoadImage(NULL,"ship.bmp",IMAGE_BITMAP,100,148,LR_LOADFROMFILE);bullet = (HBITMAP)LoadImage(NULL,"bullet.bmp",IMAGE_BITMAP,10,20,LR_LOADFROMFILE);x = 300;              y = 300;nowX = 300;nowY = 300;设定鼠标光标位置pt.x = 300;pt.y = 300;ClientToScreen(hWnd,&pt);//把窗口坐标转化为屏幕坐标,因为SetCursorPos只认屏幕坐标SetCursorPos(pt.x,pt.y);ShowCursor(false);     //隐藏鼠标光标//限制鼠标光标移动区域GetClientRect(hWnd,&rect);//获取客户区窗口的大小lt.x = rect.left;lt.y = rect.top;rb.x = rect.right;rb.y = rect.bottom;ClientToScreen(hWnd,&lt);ClientToScreen(hWnd,&rb);rect.left = lt.x;rect.top = lt.y;rect.right = rb.x;rect.bottom = rb.y;ClipCursor(&rect);//限制鼠标在矩形区域内MyPaint(hdc);return TRUE;
}void MyPaint(HDC hdc)
{char str[20] = "";int i;SelectObject(bufdc,bg);BitBlt(mdc,0,0,w,480,bufdc,640-w,0,SRCCOPY);BitBlt(mdc,w,0,640-w,480,bufdc,0,0,SRCCOPY);//飞机贴图缓慢向鼠标移动if(nowX < x){nowX += 10;if(nowX > x)nowX = x;}else{nowX -=10;if(nowX < x)nowX = x;}if(nowY < y){nowY += 10;if(nowY > y)nowY = y;}else{nowY -= 10;if(nowY < y)nowY = y;}SelectObject(bufdc,ship);BitBlt(mdc,nowX,nowY,100,74,bufdc,0,74,SRCAND);BitBlt(mdc,nowX,nowY,100,74,bufdc,0,0,SRCPAINT);SelectObject(bufdc,bullet);if(bcount!=0)for(i=0;i<30;i++)if(b[i].exist){BitBlt(mdc,b[i].x,b[i].y,10,10,bufdc,0,10,SRCAND);BitBlt(mdc,b[i].x,b[i].y,10,10,bufdc,0,0,SRCPAINT);b[i].x -= 10;if(b[i].x < 0){bcount--;b[i].exist = false;}}sprintf(str,"X坐标%d    ",x);TextOut(mdc,0,0,str,strlen(str));sprintf(str,"Y坐标%d    ",y);TextOut(mdc,0,20,str,strlen(str));BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);tPre = GetTickCount();w += 10;if(w==640)w = 0;
}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{int i;switch (message){case WM_KEYDOWN:                if(wParam==VK_ESCAPE)     //只要按下一次鼠标左键,都会从(nowX,nowY+30)出现一颗子弹PostQuitMessage(0);break;case WM_LBUTTONDOWN:           for(i=0;i<30;i++){if(!b[i].exist){b[i].x = nowX;     b[i].y = nowY + 30; b[i].exist = true;bcount++;            break;}}case WM_MOUSEMOVE:x = LOWORD(lParam);          if(x > 530)x = 530;else if(x < 0)x = 0;y = HIWORD(lParam);     if(y > 380)y = 380;else if(y < 0)y = 0;break;case WM_DESTROY:               ClipCursor(NULL);           DeleteDC(mdc);DeleteDC(bufdc);DeleteObject(bg);DeleteObject(bullet);DeleteObject(ship);ReleaseDC(hWnd,hdc);PostQuitMessage(0);break;default:                    return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}

Visual C++游戏编程基础之利用鼠标消息实现贴图相关推荐

  1. Visual C++游戏编程基础之键盘消息

    一.键盘 1.虚拟键码:Windows系统下所有的按键被视为虚拟键(包含鼠标在内),每一个虚拟键都有其对应的虚拟键码: 2.键盘消息 (1)VM_KEWDOWN:按下按键消息: (2)VM_KEYUP ...

  2. Visual C++游戏编程基础之追逐移动

    一.基本思路 1.追逐移动的实现与飞机追随鼠标光标原理类似: 2.现在小鸟作为追逐者,设定其贴图坐标为(nowX-25,nowY-16),其中(nowX,nowY)是飞机的贴图坐标: 3.通过判断小鸟 ...

  3. Visual C++游戏编程基础之透明半透明效果

    一.基本思路 1.半透明的原理 一张位图由许多像素组成,而每一像素包含R.G.B三原色,三原色的值决定了像素的色彩,要实现半透明效果,需要把前景图    和背景图彼此对应的像素颜色按某一比例进行调配, ...

  4. Visual C++游戏编程基础之多背景循环动画

    一.基本思路 1.现在有三张背景图:天空和草地.山峦.房屋: 2.天空在最远处,其次是草地和山峦(因为山峦在草地上),最后是房屋: 3.背景的循环速度是天空最慢.然后是山峦.最后是草地和房屋: 4.恐 ...

  5. Visual C++游戏编程基础之摩擦力、加速度、重力

    一.基本思路 1.假设小球在空中只受到重力作用,一开始给它一个水平的速度,就像是平抛运动一样: 2.当小球碰到地面时,受到摩擦力作用,分为x方向和y方向: 3.在摩擦力作用下,1.减少水平方向的速度, ...

  6. Visual C++游戏编程基础之景物贴图

    一.基本思路 1.首实现斜角贴图,需要显示菱形图块,使用矩形图块贴图,但是要将它的周围进行透明处理,只显示菱形部分 2.计算图块索引值的公式: 列编号 = 索引值 / 每一列的图块个数: 行编号 =  ...

  7. VC++游戏编程基础无法找到“d3d9.h”问题

    经反复查阅是缺少Direct X SDK导致的,我用的是VC++6.0,支持Direct X SDK 9.0b及之前的版本,最新版DX SDK(JUNE)VC6驾驭不了...下面是我解决问题的思路(只 ...

  8. 游戏编程基础(五)背景地图滚动显示

    在游戏过程中,背景地图需要跟着人物的移动而动态的滚动变换.C++游戏编程基础中介绍了2D游戏中常用的3种动态背景表现手法.其原理和实现技巧分析如下: 方法一:单一背景滚动         原理是:利用 ...

  9. Building JavaScript Games for Phones Tablets and Desktop(2)-游戏编程基础

    2019独角兽企业重金招聘Python工程师标准>>> 这章覆盖了游戏编程的基本原理.首先,你会了解到游戏的基本框架,就是一个游戏世界和一个游戏循环.你将会通过不同的例子学到如何用J ...

最新文章

  1. 论文大盘点|卷积神经网络必读的100篇经典论文,包含检测/识别/分类/分割多个领域...
  2. hdu 杭电 1045 Fire Net
  3. 多线程还是多进程的选择及区别
  4. 输入3个字符串,按由小到大顺序输出
  5. Python zipfile模块(压缩解压zip)
  6. oozie的常见错误
  7. 配置nginx作为下载站点
  8. 第13课:JSP动作 Indude动作和指令的区别(JSP教程 JSP入门实战教程 黄菊华Java网站开发系列教程)
  9. 中介效应分析及R实现
  10. CentOS7的locale配置
  11. Android App网络通信中通过runOnUiThread快速操纵界面以及利用线程池Executor调度异步任务实战(附源码 简单易懂)
  12. 最后一公里极速配送(三)
  13. 51单片机之 LCD1602液晶显示屏
  14. 【Java面向对象编程——喂养三种宠物】
  15. Android中使用dimen定义尺寸
  16. 【LeetCode】971. Flip Binary Tree To Match Preorder Traversal
  17. 线控转向 四轮转向控制 4WIS CarSim与Simulink联合
  18. 建造者模式——案例分析与代码演示
  19. fence_ipmilan 的一个缺陷
  20. 黑马视频学习笔记-OC-继承

热门文章

  1. 推荐25个免费下载精美网站模板的网站
  2. 学习单片机的第18天—A/D和D/A工作原理(3)
  3. 在Photoshop中设计一个漂亮的下拉按钮
  4. 大数据技术原理与应用—第10讲 Spark(林子雨老师)课后习题
  5. Android9.0 Fiddler 模拟器抓包
  6. 遇到错误:python文件读写权限permission denied
  7. 【C语言】求素数的三种方案
  8. Ubuntu Linux画图与截屏修改软件FLAMESHOT与快捷键
  9. Harbor仓库概述
  10. 菜鸟前路---java小游戏的实现(一)