第1讲(基础) 俄罗斯方块游戏界面
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <windows.h> #include <time.h> #define tMove #define tTime 1 200 //定时器的标识(编号) //单位:毫秒
7
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … switch (message) { case WM_TIMER: srand( (unsigned)time( NULL ) ); r = (rand()%10)%3; switch( r ) { case 0: //向左 if( startX>=5 ) startX -= 5; break; case 1: //向右 if( startX+200+5<=cxClient ) startX += 5; break; case 2: //向上 if( startY>=5 ) startY -= 5; break; case 3: //向下 if( startY+200+5<=cyClient ) startY += 5; break; } InvalidateRect( hwnd, NULL, TRUE ); break; 8
《面向对象程序设计》 面向对象程序设计》 面向对象程序设计课程设计》 《面向对象程序设计课程设计》
俄罗斯方块游戏
知识点
第05、06讲 俄罗斯方块游戏
5.1 需求分析 需求分析-俄罗斯方块游戏 5.2 补充知识 5.3 地图、方块的表示 地图的绘制 地图、方块的表示及地图的绘制
阶段程序:俄罗斯方块1 阶段程序:俄罗斯方块1
14
BitBlt函数说明 BitBlt
将源设备描述表的某个矩形区域拷贝到目标描述表的指 定位置。
BOOL BitBlt( HDC hdcDest, // handle to destination device context int nXDest, // x-coordinate of destination rectangle's upper-left // corner int nYDest, // y-coordinate of destination rectangle's upper-left // corner int nWidth, // width of destination rectangle int nHeight, // height of destination rectangle HDC hdcSrc, // handle to source device context int nXSrc, // x-coordinate of source rectangle's upper-left // corner int nYSrc, // y-coordinate of source rectangle's upper-left // corner DWORD dwRop // raster operation code );
3
5.2 补充知识
1. 定时器的使用 定时器的使用:当需要程序每间隔一个固定时间 每间隔一个固定时间 执行一段程序或某个功能,就需要使用定时器。 执行一段程序或某个功能 2. 避免闪烁 避免闪烁,思路:先在一张“位图”上画好图形, 先在一张“ 先在一张 位图”上画好图形, 然后“拷贝”到用户区。 然后“拷贝”到用户区 3. 人为的发送消息 人为的发送消息:消息通常是操作系统自动发送 给窗口的,在程序中也可以通过API函数人为地 通过API函数人为地 通过 发送一个消息。 发送一个消息
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … switch (message) { … case WM_CREATE: startX = startY = 100; SetTimer( hwnd, tMove, tTime, NULL ); break; … case WM_DESTROY : KillTimer( hwnd, tMove ); PostQuitMessage (0) ; break; … } }
13
InvalidateRect函数说明 InvalidateRect
该函数强制使得窗口客户区中某个区域无效,相当于向 Windows系统发送了一个刷新请求,这样Windows操作 系统会向窗口发送WM_PAINT消息。
BOOL InvalidateRect( HWND hWnd, const RECT *lpRect, BOOL bErase ); 参数: 参数: hWnd 指向需要重新绘制的窗口句柄。 指向需要重新绘制的窗口句柄。 lpRect 一个指向 一个指向RECT的结构体的指针,该结构体包含了需要更新的区 的结构体的指针, 的结构体的指针 如果该参数为NULL,则更新整个窗口客户区。 域;如果该参数为 ,则更新整个窗口客户区。 bErase 指定了当更新区域重新绘制时,更新区域的背景是否被擦除掉。 指定了当更新区域重新绘制时,更新区域的背景是否被擦除掉。
11
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … switch (message) { case WM_TIMER: srand( (unsigned)time( NULL ) ); r = (rand()%10)%3; switch( r ) { case 0: //向左 if( startX>=5 ) startX -= 5; break; case 1: //向右 if( startX+200+5<=cxClient ) startX += 5; break; case 2: //向上 if( startY>=5 ) startY -= 5; break; case 3: //向下 if( startY+200+5<=cyClient ) startY += 5; break; } InvalidateRect( hwnd, NULL, FALSE ); break; 12
§避免闪烁的方法主要有:
只有在有必要刷新时才刷新; 只刷新需要刷新的区域; 先在一张“位图”上画好图形,然后“拷贝”到用户区。 先在一张“位图”上画好图形,然后“拷贝”到用户区
10
测试程序-Project2:避免闪烁
§ 改进前面的Project1,避免闪烁
1) 2) 3) 4) 5) 创建与原设备描述表兼容的设备描述表; 创建与原设备描述表兼容的设备描述表 创建与原设备描述表兼容的位图; 创建与原设备描述表兼容的位图 将位图选入兼容的设备描述表; 将位图选入兼容的设备描述表 在兼容的设备描述表中绘图; 在兼容的设备描述表中绘图 绘图完毕将兼容的设备描述表拷贝到原设备描述表。 绘图完毕将兼容的设备描述表拷贝到原设备描述表
来自百度文库
方法一:定义一个函数, 方法一:定义一个函数,在函数中实 现需要定时执行的功能, 现需要定时执行的功能,在SetTimer 函数中将参数lpTimerFunc指定为该 函数中将参数 指定为该 函数名, 函数名,从而实现定时时间到自动执 行该函数。 行该函数。
方法二: 函数的参数lpTimerFunc为NULL,在 方法二:SetTimer函数的参数 函数的参数 为 , 函数WndProc中响应 中响应WM_TIMER消息。这样当定时时间 消息。 函数 中响应 消息 系统会向窗口发送WM_TIMER消息,从而 消息, 到,Windows系统会向窗口发送 系统会向窗口发送 消息 也实现了定时时间到自动执行某个功能。 也实现了定时时间到自动执行某个功能。
2
5.1 需求分析-俄罗斯方块游戏
§本课件所设计的俄罗斯方块游戏功能如下:
在窗口客户区 窗口客户区显示俄罗斯方块游戏地图; 窗口客户区 能随机地产生7种方块之一 随机地产生7 随机地产生 种方块之一,并显示出下一个将落下的 显示出下一个将落下的 方块。 方块 可以通过方向键控制当前方块的移动和旋转 方向键控制当前方块的移动和旋转 方向键控制当前方块的移动和旋转; 可以通过回车键控制游戏的暂停/重启 回车键控制游戏的暂停 回车键控制游戏的暂停/重启; 可以通过空格键将当前方块一步到位 空格键将当前方块一步到位 空格键将当前方块一步到位; 每当放置一个方块 放置一个方块,立刻清除“满”的行 下一个方块 清除“ 的行,下一个方块 放置一个方块 清除 落下。 落下
4
5.2.1 定时器的使用
§为了区分不同的定时器,为每个定时器定义一个 为每个定时器定义一个 标识-编号; 标识-编号 §定时器一个重要参数-定时时间 定时时间; 定时时间 §启动定时器-API函数:SetTimer SetTimer; §关闭定时器-API函数:KillTimer KillTimer。
9
5.2.2 避免闪烁
§造成闪烁的原因主要有:
在不必要刷新的时候刷新了(【二】实验3,Project4: 在不必要刷新的时候刷新 练习2修改,如果处理不好,就会因为这种情形出现闪 烁)。 刷新的频率太高了(比如,前面的Project1,每间隔200 刷新的频率太高 毫秒刷新整个用户工作区)。 只有部分区域需要刷新时,刷新整个用户工作区。 只有部分区域需要刷新时,刷新整个用户工作区
5.4 新方块落下 产生下一个随机的方块 新方块落下及产生下一个随机的方块
阶段程序:俄罗斯方块2 阶段程序:俄罗斯方块2
5.5 实现玩游戏(响应方向键 响应方向键) 响应方向键
阶段程序:俄罗斯方块3 阶段程序:俄罗斯方块3
5.6 完善游戏(响应回车键、空格键 响应回车键、 响应回车键 空格键)
阶段程序:俄罗斯方块4 阶段程序:俄罗斯方块4
6
测试程序-Project1:圆球定时移动
§修改“【二】实验3-Project3:移动用户区中的 圆”,实现圆球定时随机移动:
定义定时器的标识和定时时间(符号常量); 定义定时器的标识和定时时间 在WM_CREATE WM_CREATE消息中启动定时器 启动定时器; 启动定时器 响应WM_TIMER消息 消息; 响应WM_TIMER消息 在WM_DESTROY WM_DESTROY消息中关闭定时器 关闭定时器。 关闭定时器
UINT SetTimer( HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc );
5
BOOL KillTimer( HWND hWnd, UINT uIDEvent );
“定时执行某个功能”,“功能”的实现
UINT SetTimer( HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc );
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … 所创建的(与设备描述表 所创建的 与设备描述表 switch (message) 兼容的)位图是黑色的 兼容的 位图是黑色的 { case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; hdcMem = CreateCompatibleDC( hdc ); //(1) hBitMap = CreateCompatibleBitmap( hdc, cxClient, cyClient ); //(2) SelectObject( hdcMem, hBitMap ); //(3) Rectangle( hdcMem, 0, 0, cxClient, cyClient ); //画白色矩形,why? //画白色矩形 画白色矩形, hpen = (HPEN)GetStockObject(BLACK_PEN); SelectObject( hdcMem, hpen); //(4) hbrush = (HBRUSH)GetStockObject(BLACK_BRUSH BLACK_BRUSH); SelectObject( hdcMem, hbrush); //(4) Ellipse( hdcMem, startX, startY, startX+200, startY+200 ); //(4) DeleteObject(hpen); DeleteObject(hbrush); SRCCOPY BitBlt( hdc,0,0,cxClient,cyClient,hdcMem,0,0,SRCCOPY );//(5) DeleteDC( hdcMem ); EndPaint( hwnd, &ps ); break; … }
7
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … switch (message) { case WM_TIMER: srand( (unsigned)time( NULL ) ); r = (rand()%10)%3; switch( r ) { case 0: //向左 if( startX>=5 ) startX -= 5; break; case 1: //向右 if( startX+200+5<=cxClient ) startX += 5; break; case 2: //向上 if( startY>=5 ) startY -= 5; break; case 3: //向下 if( startY+200+5<=cyClient ) startY += 5; break; } InvalidateRect( hwnd, NULL, TRUE ); break; 8
《面向对象程序设计》 面向对象程序设计》 面向对象程序设计课程设计》 《面向对象程序设计课程设计》
俄罗斯方块游戏
知识点
第05、06讲 俄罗斯方块游戏
5.1 需求分析 需求分析-俄罗斯方块游戏 5.2 补充知识 5.3 地图、方块的表示 地图的绘制 地图、方块的表示及地图的绘制
阶段程序:俄罗斯方块1 阶段程序:俄罗斯方块1
14
BitBlt函数说明 BitBlt
将源设备描述表的某个矩形区域拷贝到目标描述表的指 定位置。
BOOL BitBlt( HDC hdcDest, // handle to destination device context int nXDest, // x-coordinate of destination rectangle's upper-left // corner int nYDest, // y-coordinate of destination rectangle's upper-left // corner int nWidth, // width of destination rectangle int nHeight, // height of destination rectangle HDC hdcSrc, // handle to source device context int nXSrc, // x-coordinate of source rectangle's upper-left // corner int nYSrc, // y-coordinate of source rectangle's upper-left // corner DWORD dwRop // raster operation code );
3
5.2 补充知识
1. 定时器的使用 定时器的使用:当需要程序每间隔一个固定时间 每间隔一个固定时间 执行一段程序或某个功能,就需要使用定时器。 执行一段程序或某个功能 2. 避免闪烁 避免闪烁,思路:先在一张“位图”上画好图形, 先在一张“ 先在一张 位图”上画好图形, 然后“拷贝”到用户区。 然后“拷贝”到用户区 3. 人为的发送消息 人为的发送消息:消息通常是操作系统自动发送 给窗口的,在程序中也可以通过API函数人为地 通过API函数人为地 通过 发送一个消息。 发送一个消息
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … switch (message) { … case WM_CREATE: startX = startY = 100; SetTimer( hwnd, tMove, tTime, NULL ); break; … case WM_DESTROY : KillTimer( hwnd, tMove ); PostQuitMessage (0) ; break; … } }
13
InvalidateRect函数说明 InvalidateRect
该函数强制使得窗口客户区中某个区域无效,相当于向 Windows系统发送了一个刷新请求,这样Windows操作 系统会向窗口发送WM_PAINT消息。
BOOL InvalidateRect( HWND hWnd, const RECT *lpRect, BOOL bErase ); 参数: 参数: hWnd 指向需要重新绘制的窗口句柄。 指向需要重新绘制的窗口句柄。 lpRect 一个指向 一个指向RECT的结构体的指针,该结构体包含了需要更新的区 的结构体的指针, 的结构体的指针 如果该参数为NULL,则更新整个窗口客户区。 域;如果该参数为 ,则更新整个窗口客户区。 bErase 指定了当更新区域重新绘制时,更新区域的背景是否被擦除掉。 指定了当更新区域重新绘制时,更新区域的背景是否被擦除掉。
11
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … switch (message) { case WM_TIMER: srand( (unsigned)time( NULL ) ); r = (rand()%10)%3; switch( r ) { case 0: //向左 if( startX>=5 ) startX -= 5; break; case 1: //向右 if( startX+200+5<=cxClient ) startX += 5; break; case 2: //向上 if( startY>=5 ) startY -= 5; break; case 3: //向下 if( startY+200+5<=cyClient ) startY += 5; break; } InvalidateRect( hwnd, NULL, FALSE ); break; 12
§避免闪烁的方法主要有:
只有在有必要刷新时才刷新; 只刷新需要刷新的区域; 先在一张“位图”上画好图形,然后“拷贝”到用户区。 先在一张“位图”上画好图形,然后“拷贝”到用户区
10
测试程序-Project2:避免闪烁
§ 改进前面的Project1,避免闪烁
1) 2) 3) 4) 5) 创建与原设备描述表兼容的设备描述表; 创建与原设备描述表兼容的设备描述表 创建与原设备描述表兼容的位图; 创建与原设备描述表兼容的位图 将位图选入兼容的设备描述表; 将位图选入兼容的设备描述表 在兼容的设备描述表中绘图; 在兼容的设备描述表中绘图 绘图完毕将兼容的设备描述表拷贝到原设备描述表。 绘图完毕将兼容的设备描述表拷贝到原设备描述表
来自百度文库
方法一:定义一个函数, 方法一:定义一个函数,在函数中实 现需要定时执行的功能, 现需要定时执行的功能,在SetTimer 函数中将参数lpTimerFunc指定为该 函数中将参数 指定为该 函数名, 函数名,从而实现定时时间到自动执 行该函数。 行该函数。
方法二: 函数的参数lpTimerFunc为NULL,在 方法二:SetTimer函数的参数 函数的参数 为 , 函数WndProc中响应 中响应WM_TIMER消息。这样当定时时间 消息。 函数 中响应 消息 系统会向窗口发送WM_TIMER消息,从而 消息, 到,Windows系统会向窗口发送 系统会向窗口发送 消息 也实现了定时时间到自动执行某个功能。 也实现了定时时间到自动执行某个功能。
2
5.1 需求分析-俄罗斯方块游戏
§本课件所设计的俄罗斯方块游戏功能如下:
在窗口客户区 窗口客户区显示俄罗斯方块游戏地图; 窗口客户区 能随机地产生7种方块之一 随机地产生7 随机地产生 种方块之一,并显示出下一个将落下的 显示出下一个将落下的 方块。 方块 可以通过方向键控制当前方块的移动和旋转 方向键控制当前方块的移动和旋转 方向键控制当前方块的移动和旋转; 可以通过回车键控制游戏的暂停/重启 回车键控制游戏的暂停 回车键控制游戏的暂停/重启; 可以通过空格键将当前方块一步到位 空格键将当前方块一步到位 空格键将当前方块一步到位; 每当放置一个方块 放置一个方块,立刻清除“满”的行 下一个方块 清除“ 的行,下一个方块 放置一个方块 清除 落下。 落下
4
5.2.1 定时器的使用
§为了区分不同的定时器,为每个定时器定义一个 为每个定时器定义一个 标识-编号; 标识-编号 §定时器一个重要参数-定时时间 定时时间; 定时时间 §启动定时器-API函数:SetTimer SetTimer; §关闭定时器-API函数:KillTimer KillTimer。
9
5.2.2 避免闪烁
§造成闪烁的原因主要有:
在不必要刷新的时候刷新了(【二】实验3,Project4: 在不必要刷新的时候刷新 练习2修改,如果处理不好,就会因为这种情形出现闪 烁)。 刷新的频率太高了(比如,前面的Project1,每间隔200 刷新的频率太高 毫秒刷新整个用户工作区)。 只有部分区域需要刷新时,刷新整个用户工作区。 只有部分区域需要刷新时,刷新整个用户工作区
5.4 新方块落下 产生下一个随机的方块 新方块落下及产生下一个随机的方块
阶段程序:俄罗斯方块2 阶段程序:俄罗斯方块2
5.5 实现玩游戏(响应方向键 响应方向键) 响应方向键
阶段程序:俄罗斯方块3 阶段程序:俄罗斯方块3
5.6 完善游戏(响应回车键、空格键 响应回车键、 响应回车键 空格键)
阶段程序:俄罗斯方块4 阶段程序:俄罗斯方块4
6
测试程序-Project1:圆球定时移动
§修改“【二】实验3-Project3:移动用户区中的 圆”,实现圆球定时随机移动:
定义定时器的标识和定时时间(符号常量); 定义定时器的标识和定时时间 在WM_CREATE WM_CREATE消息中启动定时器 启动定时器; 启动定时器 响应WM_TIMER消息 消息; 响应WM_TIMER消息 在WM_DESTROY WM_DESTROY消息中关闭定时器 关闭定时器。 关闭定时器
UINT SetTimer( HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc );
5
BOOL KillTimer( HWND hWnd, UINT uIDEvent );
“定时执行某个功能”,“功能”的实现
UINT SetTimer( HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc );
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { … 所创建的(与设备描述表 所创建的 与设备描述表 switch (message) 兼容的)位图是黑色的 兼容的 位图是黑色的 { case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; hdcMem = CreateCompatibleDC( hdc ); //(1) hBitMap = CreateCompatibleBitmap( hdc, cxClient, cyClient ); //(2) SelectObject( hdcMem, hBitMap ); //(3) Rectangle( hdcMem, 0, 0, cxClient, cyClient ); //画白色矩形,why? //画白色矩形 画白色矩形, hpen = (HPEN)GetStockObject(BLACK_PEN); SelectObject( hdcMem, hpen); //(4) hbrush = (HBRUSH)GetStockObject(BLACK_BRUSH BLACK_BRUSH); SelectObject( hdcMem, hbrush); //(4) Ellipse( hdcMem, startX, startY, startX+200, startY+200 ); //(4) DeleteObject(hpen); DeleteObject(hbrush); SRCCOPY BitBlt( hdc,0,0,cxClient,cyClient,hdcMem,0,0,SRCCOPY );//(5) DeleteDC( hdcMem ); EndPaint( hwnd, &ps ); break; … }