Windows API贪吃蛇游戏
1 // wanwan.cpp : 定义应用程序的入口点。 2 // 3 4 5 #include <windows.h> 6 7 #include<time.h> 8 #define LEFT VK_LEFT 9 #define RIGHT VK_RIGHT 10 #define DOWN VK_DOWN 11 #define UP VK_UP 12 13 14 15 LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); 16 17 /* Make the class name into a global variable */ 18 TCHAR szClassName[ ] = TEXT("WindowsApp"); 19 20 int WINAPI WinMain (HINSTANCE hThisInstance, 21 HINSTANCE hPrevInstance, 22 LPSTR lpszArgument, 23 int nFunsterStil) 24 25 { 26 HWND hwnd; 27 MSG messages; 28 WNDCLASSEX wincl; 29 30 wincl.hInstance = hThisInstance; 31 wincl.lpszClassName = szClassName; 32 wincl.lpfnWndProc = WindowProcedure; 33 wincl.style = CS_GLOBALCLASS; 34 wincl.cbSize = sizeof (WNDCLASSEX); 35 36 37 wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); 38 wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 39 wincl.hCursor = LoadCursor (NULL, IDC_ARROW); 40 wincl.lpszMenuName = NULL; /* No menu */ 41 wincl.cbClsExtra = 0; /* No extra bytes after the window class */ 42 wincl.cbWndExtra = 0; /* structure or the window instance */ 43 /* Use Windows's default color as the background of the window */ 44 wincl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 45 46 /* Register the window class, and if it fails quit the program */ 47 if (!RegisterClassEx (&wincl)) 48 return 0; 49 50 /* The class is registered, let's create the program*/ 51 hwnd = CreateWindowEx ( 52 WS_EX_TOOLWINDOW, /* Extended possibilites for variation */ 53 szClassName, /* Classname */ 54 TEXT("SNAKE"), /* Title Text */ 55 WS_SYSMENU, /* default window */ 56 CW_USEDEFAULT, /* Windows decides the position */ 57 CW_USEDEFAULT, /* where the window ends up on the screen */ 58 540, /* The programs width */ 59 380, /* and height in pixels */ 60 HWND_DESKTOP, /* The window is a child-window to desktop */ 61 NULL, /* No menu */ 62 hThisInstance, /* Program Instance handler */ 63 NULL /* No Window Creation data */ 64 ); 65 66 /* Make the window visible on the screen */ 67 ShowWindow (hwnd, nFunsterStil); 68 69 /* Run the message loop. It will run until GetMessage() returns 0 */ 70 while (GetMessage (&messages, NULL, 0, 0)) 71 { 72 /* Translate virtual-key messages into character messages */ 73 TranslateMessage(&messages); 74 /* Send message to WindowProcedure */ 75 DispatchMessage(&messages); 76 } 77 78 /* The program return-value is 0 - The value that PostQuitMessage() gave */ 79 return messages.wParam; 80 } 81 typedef struct snake 82 { 83 POINT node[1000]; 84 int num; 85 int direct; 86 int life; 87 }snk; 88 89 snk a={{{80,60},{60,60}},2,RIGHT,1}; 90 91 void rect(HDC hdc,POINT p,int a) 92 { 93 Ellipse(hdc,p.x,p.y,p.x+a,p.y+a);//???为什么设为零不行 94 } 95 96 97 // 用来判断边界!! 98 int ismax(POINT a,POINT b,POINT c,int l) 99 { 100 if((a.x<b.x)||(a.x>c.x)||(a.y>c.y)||(a.y<b.y)) 101 return 1; 102 else return 0; 103 } 104 105 106 /* This function is called by the Windows function DispatchMessage() */ 107 108 109 LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 110 { 111 HDC hdc; 112 PAINTSTRUCT ps; 113 static HPEN hpen=CreatePen(PS_SOLID,4,RGB(200,0,10)),hpen1=CreatePen(PS_SOLID,4,RGB(0,200,0)),hpen2=CreatePen(PS_SOLID,4,RGB(0,200,200)); 114 static HPEN hpenw=CreatePen(PS_SOLID,4,RGB(255,255,255)); 115 static int x=0,y=0,score=0,rank=1; 116 static POINT bound1={0,20},bound2; 117 static POINT food={200,200}; 118 TCHAR sco[50]; 119 static int intv=200;//代表200毫秒 120 static POINT era; 121 122 int i; 123 srand(time(NULL)); 124 switch (message) /* handle the messages */ 125 { 126 case WM_CREATE: 127 SetTimer(hwnd,1,intv,NULL); 128 break; 129 case WM_DESTROY: 130 131 KillTimer(hwnd,1); 132 PostQuitMessage (0); /* send a WM_QUIT to the message queue */ 133 break; 134 case WM_SIZE: 135 bound2.x=LOWORD(lParam); 136 bound2.y=HIWORD(lParam); 137 x=bound2.x/2;y=bound2.y/2; 138 break; 139 case WM_TIMER: 140 era=a.node[a.num-1]; 141 for(i=a.num-1;i>=1;i--) 142 a.node[i]=a.node[i-1]; 143 switch(a.direct) 144 { 145 case UP: 146 a.node[0].y-=20;break; 147 case DOWN: 148 a.node[0].y+=20;break; 149 case LEFT: 150 a.node[0].x-=20;break; 151 case RIGHT: 152 a.node[0].x+=20;break; 153 } 154 155 InvalidateRect(hwnd,NULL,FALSE); 156 break; 157 158 159 160 case WM_PAINT: 161 if(a.node[0].x==food.x&&a.node[0].y==food.y) 162 { 163 164 a.num++; 165 a.node[a.num-1]=a.node[a.num-2]; 166 //防止食物产生在蛇的身上 167 168 for(bool judge=true;judge==true;) 169 {food.x=rand()%(bound2.x/20)*20; 170 food.y=(rand()%((bound2.y-20)/20))*20+20; 171 for(int i=0;i<a.num;i++) 172 if(food.x==a.node[i].x&&food.y==a.node[i].y) 173 judge=true; 174 else 175 judge=false; 176 } 177 178 score+=10; 179 if(score%100==0)//能被100,蛇的移动速度减慢一次 180 { 181 intv-=30; 182 KillTimer(hwnd,1); 183 SetTimer(hwnd,1,intv,NULL); 184 rank++;//在记录分数的时候,分数每增长一位rank需要加1 185 } 186 187 } 188 for(i=1;i<=a.num-1;i++) 189 { 190 if((a.node[0].x==a.node[i].x&&a.node[0].y==a.node[i].y)||ismax(a.node[0],bound1,bound2,19)) 191 a.life=0; 192 } 193 if(a.life==1) 194 { 195 wsprintf(sco,TEXT("SCORE: %5d LV: %d"),score,rank); 196 hdc=BeginPaint(hwnd,&ps); 197 TextOut(hdc,20,0,sco,lstrlen(sco)); 198 SelectObject(hdc,hpen2); 199 MoveToEx(hdc,0,1,NULL); 200 LineTo(hdc,bound2.x,1); 201 MoveToEx(hdc,0,16,NULL); 202 LineTo(hdc,bound2.x,16); 203 SelectObject(hdc,hpen1); 204 rect(hdc,food,17); 205 SelectObject(hdc,hpen); 206 rect(hdc,a.node[0],17); 207 SelectObject(hdc,hpenw); 208 rect(hdc,era,17); 209 EndPaint(hwnd,&ps); 210 } 211 else 212 { 213 if(MessageBox(NULL,TEXT("a"),TEXT("b"),0)==IDOK); 214 PostQuitMessage (0); 215 } 216 217 break; 218 case WM_KEYDOWN: 219 220 221 222 switch(wParam) 223 { 224 case VK_UP: 225 if(a.direct!=UP&&a.direct!=DOWN) 226 a.direct=UP; 227 break; 228 229 case VK_DOWN: 230 if(a.direct!=UP&&a.direct!=DOWN) 231 a.direct=DOWN; 232 break; 233 case VK_RIGHT: 234 if(a.direct!=RIGHT&&a.direct!=LEFT) 235 a.direct=RIGHT; 236 break; 237 case VK_LEFT: 238 if(a.direct!=RIGHT&&a.direct!=LEFT) 239 a.direct=LEFT; 240 break; 241 242 } 243 244 InvalidateRect(hwnd,NULL,FALSE); 245 246 247 return 0; 248 default: /* for messages that we don't deal with */ 249 return DefWindowProc (hwnd, message, wParam, lParam); 250 } 251 252 return 0; 253 }