展开全部
/******************************************************************
002
贪食蛇 Preview
003
此版本贪吃蛇用蛇的方块是集合用的是数组
004
蛇移动是以Sleep()阻断进程实现的
005
故蛇移动看似较为卡顿,且数组插入数据效率较低,
006
故操作体验十分一般
007
*******************************************************************/
008
#include<windows.h>
009
#include <time.h>
010
011
#pragma comment(lib,"winmm.lib")
012
013
#define LENGTH 40 //游戏场地的宽
014
#define WIDTH 10 //组成蛇的的正方形的边长
015
#define RANGE 50 //游戏场地与客户去之间间隔
016
#define SNAKE_COLOR RGB(255,0,0) //蛇的颜色
017
#define BK_COLOR RGB(204,232,207) //窗体背景色
018
#define NO_SNAKE 0
019
#define HAS_SNAKE 1
020
#define STEP 2
021
#define MAKECOOR(x) (x)*WIDTH //把flags数组的下标映射为坐标
022
023
typedef struct
024
{
025
int x;
026
int y;
027
int flag;
028
} GRID;//蛇的结构
029
030
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
031
void MakePartSnake(int,int,int,GRID *); //为蛇身增加或设置一个方块
032
void MoveSnake(HWND); //移动蛇
033
void MakeFood(GRID *food); //制造随机方块
034
void initializer(); //初始化游戏
035
void Manager();
036
037
TCHAR szAppName[] = TEXT("Gluttony Snake");
038
int flags[LENGTH][LENGTH]; //游戏区域所有方块的状态标记
039
RECT playground; //游戏场地
040
GRID *snake = NULL; //蛇所在位置数组
041
GRID *food = NULL; //食物对象
042
static int MAX_LENGTH = 0;//默认蛇分配的最大长度(可变的)
043
int snake_len = 0;
044
int direct = 0;
045
int WINAPI WinMain(HINSTANCE hInstance,
046
HINSTANCE hPrevInstance,
047
PSTR szCmdLine,
048
int iCmdShow)
049
{
050
MSG msg;
051
HWND hwnd;
052
WNDCLASS wndclass;
053
while(TRUE)
054
{
055
wndclass.cbClsExtra = 0;
056
wndclass.cbWndExtra = 0;
057
wndclass.hbrBackground=CreateSolidBrush(RGB(203,202,201));
058
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
059
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
060
wndclass.hInstance = hInstance;
061
wndclass.lpfnWndProc = WndProc;
062
wndclass.lpszMenuName = NULL;
063
wndclass.lpszClassName = szAppName;
064
wndclass.style = CS_VREDRAW | CS_HREDRAW;
065
066
if(!RegisterClass(&wndclass))
067
{
068
MessageBox(NULL,TEXT("Register class failed!! Retry??"),szAppName,0);
069
return 0;
070
}
071
break;
072
}
073
hwnd = CreateWindow(szAppName,
074
TEXT("Gluttony Snake Preview V1.0.1"),
075
WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MINIMIZEBOX ^ WS_MAXIMIZEBOX,
076
CW_USEDEFAULT,
077
CW_USEDEFAULT,
078
CW_USEDEFAULT,
079
CW_USEDEFAULT,
080
NULL,NULL,
081
hInstance,
082
NULL);
083
084
ShowWindow(hwnd,SW_NORMAL);
085
UpdateWindow(hwnd);
086
while(TRUE)
087
{
088
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
089
{
090
if(msg.message == WM_QUIT)
091
break;
092
TranslateMessage(&msg);
093
DispatchMessage(&msg);
094
}
095
else
096
{
097
MoveSnake(hwnd);
098
}
099
}
100
return msg.wParam;
101
}
102
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
103
{
104
HDC hdc;
105
PAINTSTRUCT ps;
106
HBRUSH hBrush;
107
switch(message)
108
{
109
case WM_DESTROY:
110
PostQuitMessage(0);
111
return 0;
112
113
case WM_CREATE:
114
//PlaySound(TEXT("HG.wav"),NULL ,SND_ASYNC | SND_LOOP);//播放游戏音乐;
115
initializer();
116
MoveWindow(hwnd,RANGE * 2,RANGE * 2,WIDTH * LENGTH + RANGE * 3,WIDTH * LENGTH + RANGE * 3,TRUE);
117
return 0;
118
case WM_KEYDOWN:
119
switch(wParam)
120
{
121
case VK_LEFT:
122
if(direct != VK_RIGHT)
123
direct = VK_LEFT;
124
break;
125
case VK_RIGHT:
126
if(direct != VK_LEFT)
127
direct = VK_RIGHT;
128
break;
129
case VK_UP:
130
if(direct != VK_DOWN)
131
direct = VK_UP;
132
break;
133
case VK_DOWN:
134
if(direct != VK_UP)
135
direct = VK_DOWN;
136
break;
137
default:
138
break;
139
}
140
return 0;
141
142
case WM_PAINT:
143
for(int i = 0; i != snake_len; ++i)
144
{
145
flags[(snake + i)->x][(snake + i)->y] = (snake + i)->flag;
146
}
147
hdc = BeginPaint(hwnd,&ps);
148
SetViewportOrgEx(hdc,RANGE/2,RANGE,NULL);
149
hBrush = CreateSolidBrush(BK_COLOR);
150
SelectObject(hdc,hBrush);
151
Rectangle(hdc,playground.left,playground.top,playground.right,playground.bottom);
152
DeleteObject(hBrush);
153
hBrush = CreateSolidBrush(SNAKE_COLOR);
154
SelectObject(hdc,hBrush);
155
for(int i = 0; i != LENGTH;++i)
156
{
157
for(int j = 0; j != LENGTH;++j)
158
{
159
if(flags[i][j] == HAS_SNAKE)
160
{
161
Rectangle(hdc,MAKECOOR(i),MAKECOOR(j),MAKECOOR(i+1),MAKECOOR(j+1));
162
}
163
}
164
}
165
DeleteObject(hBrush);
166
EndPaint(hwnd,&ps);
167
}
168
return DefWindowProc(hwnd,message,wParam,lParam);
169
}
170
//////////////////////////初始化游戏各个参数////////////////////////////////////////////////////////////
171
void initializer()
172
{
173
if(snake != NULL)
174
free(snake);
175
if(food != NULL)
176
free(food);
177
snake_len = 3; //蛇的初始长度为3
178
direct = VK_RIGHT; //蛇的初始方向为向右
179
MAX_LENGTH = 100; //蛇默认最初分配最大长度为20
180
food = (GRID *)calloc(1,sizeof(GRID));//分配储存food的内存
181
snake = (GRID *)calloc(MAX_LENGTH,sizeof(GRID));//分配储存蛇的内存
182
/*************初始化游戏场地*******************/
183
playground.left = 0;
184
playground.top = 0;
185
playground.right = WIDTH * LENGTH;
186
playground.bottom = WIDTH * LENGTH;
187
/**************初始化游戏场地********************/
188
189
for(int i = 0 ;i < LENGTH;++i)
190
{
191
for(int j = 0; j < LENGTH;++j)
192
{
193
flags[i][j] = NO_SNAKE;
194
}
195
}
196
for(int i = 0; i != snake_len;++i)
197
{
198
MakePartSnake(LENGTH / 2 + 2 - i,LENGTH / 2,HAS_SNAKE,(snake + i));
199
}///初始化蛇
200
MakeFood(food);///产生food
201
}
202
203
void MakePartSnake(int x,int y,int flag,GRID * snake)
204
{
205
snake->x = x;
206
snake->y = y;
207
snake->flag = flag;
208
}
209
////////////////////////////////////////////////////////////////////////////////
210
211
212
213
//////////////////控制蛇的移动///////////////////////
214
void MoveSnake(HWND hwnd)
215
{
216
Manager();
217
flags[(snake + snake_len - 1)->x][(snake + snake_len - 1)->y] = NO_SNAKE;//把蛇的尾部去除(表现为蛇移动一格)
218
219
for(int i = snake_len - 1; i > 0;--i)
220
{
221
(snake+i)->x = (snake + i -1)->x;
222
(snake+i)->y = (snake + i -1)->y;
223
}
224
if(direct == VK_LEFT)
225
{
226
snake->x -= 1;
227
}
228
if(direct == VK_RIGHT)
229
{
230
snake->x += 1;
231
}
232
if(direct == VK_UP)
233
{
234
snake->y -= 1;
235
}
236
if(direct == VK_DOWN)
237
{
238
snake->y += 1;
239
}
240
InvalidateRect(hwnd,NULL,FALSE);
241
Sleep(200);
242
}
243
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
244
245
//////////////////////////////////通过随机生成food
246
void MakeFood(GRID *food)
247
{
248
srand((unsigned) time(NULL));
249
food->x = rand() % LENGTH;
250
food->y = rand() % LENGTH;
251
food->flag = HAS_SNAKE;
252
flags[food->x][food->y] = food->flag;
253
}
254
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
255
256
//////////////////////////////////游戏规则的映射及内存的处理///////////////////////////////////////////////////
257
void Manager()
258
{
259
if(snake_len >= MAX_LENGTH - 2)
260
{
261
MAX_LENGTH += STEP;
262
snake = (GRID *)realloc(snake,MAX_LENGTH * sizeof(GRID));
263
}//若蛇的长度数组snake将超过所分配的内存就再次扩充分配
264
265
if(snake->x < 0 || snake->x >= LENGTH || snake->y < 0 || snake->y >= LENGTH)
266
{
267
MessageBox(NULL,TEXT("Game Over!!"),szAppName,0);
268
initializer();
269
return;
270
}///判断蛇是否碰到边界
271
272
for(int i = 4;i < snake_len;++i)
273
{
274
if(snake->x == (snake + i)->x && snake->y == (snake + i)->y)
275
{
276
MessageBox(NULL,TEXT("Game Over!!"),szAppName,0);
277
initializer();
278
return;
279
}
280
}////判断蛇是否碰到自身
281
282
if(food->x == snake->x && food->y == snake->y)
283
{
284
MakePartSnake(
285
(snake + snake_len - 1)->x
286
,(snake + snake_len - 1)->y
287
,HAS_SNAKE
288
,snake + snake_len
289
);
290
++snake_len;
291
MakeFood(food);
292
}///判断蛇是否吃到food
293
}
294
////////////////////////////////////////////////////////////////////////////////
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询