我快速拖动标题栏就会出先画面重绘.
#include <windows.h>
#include "resource.h"
#include <stdio.h>
#define UP 0
#define LEFT 1
#define DOWN 2
#define RIGHT 3
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void GameMessage (HWND hwnd, int time ,int point)//结束时的对话框设置
{
TCHAR szBuffer[1024] ;
KillTimer (hwnd, 1) ;
sprintf(szBuffer,"所用时间: %d\n你的得分: %d ", time, point) ;
MessageBox (hwnd,szBuffer, TEXT ("GameOver"), 0) ;
}
BOOL CheckSnake ( HWND hwnd, RECT *Snake, RECT *TwoRect, int *Array)//检查是否蛇撞到自身和蛇头出界
{ //返回TRUE表示得到目标,FALSE表示还要爬行
RECT StRect[60] ;
int i ,Number ;
Number = Array[2] + 4 ;
switch (Array[0])
{
case UP :
if( TwoRect[1].right == Snake[Number].right && TwoRect[1].bottom == Snake[Number].top)
return TRUE ;
for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;
for (i = Number - 2 ; i >= 0 ; i--)
if(Snake[Number].top <= TwoRect[0].top ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))
{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}
Snake[Number].top -= 15 ;
Snake[Number].bottom -= 15 ;
break ;
case DOWN :
if (TwoRect[1].right == Snake[Number].right && TwoRect[1].top == Snake[Number].bottom)
return TRUE ;
for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;
Snake[Number].bottom += 15 ;
Snake[Number].top += 15 ;
for (i = Number - 2 ; i >= 0 ; i--)
if(Snake[Number].bottom >= TwoRect[0].bottom ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))
{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}
break ;
case LEFT :
if(TwoRect[1].right == Snake[Number].left && TwoRect[1].bottom == Snake[Number].bottom)
return TRUE ;
for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;
for (i = Number - 2 ; i >= 0 ; i--)
if(Snake[Number].left <= TwoRect[0].left ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))
{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}
Snake[Number].right -= 15 ;
Snake[Number].left -= 15 ;
break ;
case RIGHT :
if(TwoRect[1].left == Snake[Number].right && TwoRect[1].top == Snake[Number].top)
return TRUE ;
for (i = 0 ; i < Number + 1 ; i++)
StRect[i] = Snake[i] ;
for (i = 0 ; i < Number ; i++)
Snake[i] = StRect[i+1] ;
Snake[Number].left += 15 ;
Snake[Number].right += 15 ;
for (i = Number - 2 ; i >= 0 ; i--)
if(Snake[Number].right >= TwoRect[0].right ||
((Snake[Number].left == Snake[i].left && Snake[Number].top == Snake[i].top)))
{
GameMessage (hwnd, Array[1], Array[2]) ;
break ;
}
break ;
}
return FALSE ;
}
POINT GetRect (HWND hwnd, RECT MainRect, RECT *Snake, int Number) //得到目标黑色矩形
{
int i, xSize, ySize ;
BOOL In ;
POINT lPoint, rPoint ;
xSize = (MainRect.right - MainRect.left) / 15 ; //给窗口按比例缩放
ySize = (MainRect.bottom - MainRect.top) / 15 ;
In = FALSE ;
while(1) //让目标在主框内,并且不会和蛇碰到
{
lPoint.x = MainRect.left + (rand() % (xSize + 1)) * 15 ;
lPoint.y = MainRect.top + (rand() % (ySize + 1)) * 15 ;
rPoint.x = lPoint.x + 15 ;
rPoint.y = lPoint.y + 15 ;
if (PtInRect (&MainRect, lPoint) && PtInRect (&MainRect, rPoint))
{
for ( i =0 ; i <= Number ; i ++)
{
if (PtInRect (&Snake[i], lPoint) && PtInRect (&Snake[i], rPoint))
In = TRUE ;
}
if(In == FALSE)
break ;
}
}
return lPoint ;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
HACCEL hAccel ;
static TCHAR szAppName [] = TEXT ("Snake");
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
hwnd = CreateWindow (szAppName, TEXT ("Snake"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
hAccel = LoadAccelerators (hInstance, szAppName) ;
while (GetMessage (&msg, NULL, 0, 0))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps;
static int cxClient, cyClient, time, drection, point, i, Array[3];
static TCHAR szGetPoint[] = TEXT ("得分 : "),
szTime[] = TEXT ("时间 : "),
szBuffer[10] ;
static RECT MainRect, SnakeRect[60], DstRect, TwoRect[2] ;
HBRUSH Hbrush ;
static BOOL ChangeRect, Stop ;
static POINT RectPoint ;
HMENU hMenu ;
switch(message)
{
case WM_CREATE:
hdc = GetDC (hwnd) ;
time = 0 ;
drection = 3 ;
point = 0 ;
Stop = ChangeRect = TRUE ;
ReleaseDC (hwnd ,hdc) ;
return 0;
case WM_SIZE :
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
MainRect.left = cxClient / 12 ;
MainRect.top = cyClient / 12 ;
MainRect.right = 10 * MainRect.left ;
MainRect.bottom = 10 * MainRect.top ;
SetRect (&SnakeRect[0], MainRect.left + 45 , MainRect.top + 45, MainRect.left + 60, MainRect.top + 60) ;//设置5个蛇部分
for (i = 1 ; i < 5 ; i ++)
SetRect (&SnakeRect[i], SnakeRect[i-1].left + 15, SnakeRect[i-1].top, SnakeRect[i-1].right + 15, SnakeRect[i-1].bottom);
return 0;
case WM_TIMER:
time++;
InvalidateRect (hwnd ,NULL, TRUE) ;
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_UP :
if(drection == DOWN )
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over!"), TEXT (" Game Message "), 0) ;
}
else
drection = UP ;
break ;
case VK_DOWN :
if(drection == UP)
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over!"), TEXT (" Game Message "), 0) ;
}
else
drection = DOWN ;
break ;
case VK_LEFT :
if(drection == RIGHT)
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over "), TEXT (" Game Message "), 0) ;
}
else
drection = LEFT ;
break ;
case VK_RIGHT :
if(drection == LEFT)
{
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT (" Game Over "), TEXT (" Game Message "), 0) ;
}
else
drection = RIGHT ;
break ;
case VK_SPACE :
if(Stop)
{
KillTimer (hwnd, 1) ;
Stop = FALSE ;
}
else
{
SetTimer (hwnd, 1, 100, NULL) ;
Stop = TRUE ;
}
}
return 0 ;
case WM_COMMAND:
hMenu = GetMenu (hwnd) ;
switch (LOWORD (wParam))
{
case IDA_F2:
case IDM_START : //重新开始
drection = 3 ;
SetRect (&SnakeRect[0], MainRect.left + 45 , MainRect.top + 45, MainRect.left + 60, MainRect.top + 60) ;
for (i = 1 ; i < 5 ; i ++)
SetRect (&SnakeRect[i], SnakeRect[i-1].left + 15, SnakeRect[i-1].top, SnakeRect[i-1].right + 15, SnakeRect[i-1].bottom);
SetTimer (hwnd, 1, 100, NULL) ;
InvalidateRect (hwnd ,NULL, TRUE) ;
break;
case IDM_HELP :
KillTimer (hwnd, 1) ;
MessageBox (hwnd, TEXT ("空格暂停"), TEXT("about"), 0) ;
break;
}
return 0;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
Hbrush = GetStockObject (BLACK_BRUSH) ;
Rectangle (hdc, MainRect.left , MainRect.top, MainRect.right, MainRect.bottom ) ;
TextOut (hdc, MainRect.right + 40, 2 * MainRect.top, szTime, strlen (szTime)) ;
TextOut (hdc, MainRect.right + 40, 3 * MainRect.top, szGetPoint, strlen (szGetPoint)) ;
TextOut (hdc, MainRect.right + 80, 2 * MainRect.top, szBuffer, wsprintf( szBuffer, TEXT(" %d"), time / 10));
TextOut (hdc, MainRect.right + 80, 3 * MainRect.top, szBuffer, wsprintf( szBuffer, TEXT(" %d"), point));
if(ChangeRect)
{
RectPoint = GetRect (hwnd, MainRect, SnakeRect, 4 + point) ;
ChangeRect= FALSE ;
}
for(i = 4 + point ; i >= 0 ; i --)
Rectangle (hdc,SnakeRect[i].left, SnakeRect[i].top, SnakeRect[i].right, SnakeRect[i].bottom) ;
FillRect (hdc, &SnakeRect[4+point], Hbrush) ;
SetRect (&DstRect, RectPoint.x, RectPoint.y, RectPoint.x + 15, RectPoint.y + 15) ;
FillRect (hdc, &DstRect, Hbrush) ; //给蛇头涂黑
TwoRect[0] = MainRect ; //做这些是为了在CheckSnake中少放点参数进去
TwoRect[1] = DstRect ;
Array[0] = drection ;
Array[1] = time / 10;
Array[2] = point ;
if(ChangeRect = CheckSnake (hwnd, SnakeRect, TwoRect, Array))
{
point ++ ;
SnakeRect[4+point] = DstRect ;
}
EndPaint (hwnd, &ps) ;
return 0;
case WM_DESTROY:
KillTimer (hwnd,1) ;
PostQuitMessage (0) ;
return 0;
}
return DefWindowProc (hwnd ,message, wParam, lParam) ;
}