#include<Windows.h>
#include"resource.h"
#include"Node.h"
#include<stdlib.h>
#include<time.h>
TCHAR szAppname[] = TEXT("Snack_eat");
#define SIDE (x_Client/80)
#define x_Client 800
#define y_Client 800
#define X_MAX 800-20-SIDE //点x的范围
#define Y_MAX 800-60-SIDE //点y的范围
#define TIME_ID 1
#define SECOND 100
#define NUM_POINT 10 //点的总个数
#define ADD_SCORE 10
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd; //窗口句柄
MSG msg; //消息
WNDCLASS wndclass; //窗口类
HACCEL hAccel;//加速键句柄
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口的水平和垂直尺寸被改变时,窗口被重绘
wndclass.lpfnWndProc = WndProc; //窗口过程为WndProc函数
wndclass.cbClsExtra = 0; //预留额外空间
wndclass.cbWndExtra = 0; //预留额外空间
wndclass.hInstance = hInstance; //应用程序的实例句柄,WinMain的第一个参数
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //设置图标
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //载入预定义的鼠标指针
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置画刷
wndclass.lpszMenuName = szAppname; //设置菜单
wndclass.lpszClassName = szAppname; //设置窗口类的名字
if (!RegisterClass(&wndclass))//注册窗口类
{
MessageBox(NULL, TEXT("这个程序需要windows NT!"), szAppname, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppname, TEXT("Snack_eat"),//CreateWindow函数调用时,WndProc将受到WM_CREATE
WS_OVERLAPPEDWINDOW&~WS_THICKFRAME& ~WS_MAXIMIZEBOX,//普通的层叠窗口&禁止改变大小&禁止最大化
CW_USEDEFAULT, //初始x坐标(默认)
CW_USEDEFAULT, //初始y坐标
x_Client, //初始x方向尺寸 770
y_Client, //初始y方向尺寸 750
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //程序实例句柄 WinMain函数中第二个参数
NULL); //创建参数
ShowWindow(hwnd, iCmdShow);//显示窗口,iCmdShow是WinMain的第四个参数,决定窗口在屏幕中的初始化显示形式,例:SW_SHOWNORMAL表示正常显示
UpdateWindow(hwnd);//使窗口客户区重绘,通过向WndProc发送一条WM_PAINT消息而完成的
hAccel = LoadAccelerators(hInstance, szAppname);//加载加速键
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(hwnd, hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}/*
while (GetMessage(&msg, NULL, 0, 0))//GetMessage函数从消息队列中得到消息,填充msg。如果msg.message等于WM_QUIT,返回0,否则返回非0
{
TranslateMessage(&msg);//将msg返回给windows已进行某些键盘消息的转换
DispatchMessage(&msg);//将msg再次返回给windows
}*/
return msg.wParam;//msg.wParam是PostQuitMessage函数的参数值,通常是0
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;//设备环境句柄:物理输出设备(视频显示器)及其设备驱动程序
PAINTSTRUCT ps;//PAINTSTRUCT结构包含一些窗口过程对客户区进行绘制的信息
static int cxClient, cyClient;
static Snack sn;
static POINT food[NUM_POINT];
Node *node;
static szBuffer[50];
static int Moving;//正在前进方向,1上2下3左4右
int i;
static int SIGNAL_ENDING;
static HMENU hMenu; //菜单句柄
static int score;//得分
static Signal_Keydown;//1为接收键盘信息,0为不接收
switch (message)
{
case WM_CREATE:
srand(time(0));
SIGNAL_ENDING = 1;
return 0;
case WM_COMMAND:
hMenu = GetMenu(hwnd);
switch (LOWORD(wParam))
{
case ID_START:
//################初始化 计时器#################
if (SetTimer(hwnd, TIME_ID, SECOND, NULL))
{
EnableMenuItem(hMenu, ID_START, MF_GRAYED);//将开始键设为灰色
EnableMenuItem(hMenu, ID_STOP, MF_ENABLED);//将暂停键设为可用
}
//##############################################
//################初始化 蛇#################
sn.head = NULL;
Change_food(&food[0], X_MAX, Y_MAX, SIDE);
Create_snack(&sn, food[0]);
//##########################################
//################初始化 食物#################
for (i = 0; i < NUM_POINT; i++)
Change_food(&(food[i]), X_MAX, Y_MAX, SIDE);
//############################################
//################初始化 正在前进方向#########
Moving = 1;
//############################################
//################初始化 结束标记#############
SIGNAL_ENDING = 0;
//############################################
//################初始化 分数#################
score = 0;
//############################################
Signal_Keydown = 1;//接收键盘消息
break;
case ID_CONTINUE:
EnableMenuItem(hMenu, ID_CONTINUE, MF_GRAYED);//将继续键设为灰色
EnableMenuItem(hMenu, ID_STOP, MF_ENABLED);//将暂停键设为可用
SetTimer(hwnd, TIME_ID, SECOND, NULL);
Signal_Keydown = 1;//接收键盘消息
break;
case ID_STOP:
EnableMenuItem(hMenu, ID_STOP, MF_GRAYED);//将暂停键设为灰色
EnableMenuItem(hMenu, ID_CONTINUE, MF_ENABLED);//将继续键设为可用
KillTimer(hwnd, TIME_ID);
Signal_Keydown = 0;//不接收键盘消息
break;
case ID_QUIT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
case ID_ABOUT:
MessageBox(hwnd, TEXT("Jares's program\nPlease enjoy the game"), szAppname, MB_ICONINFORMATION | MB_OK);
break;
}
break;
case WM_TIMER://自动前进
switch (Moving)
{
case 1:
UP_snack(&sn, SIDE, X_MAX, Y_MAX, &Moving);
for (i = 0; i < NUM_POINT; i++)
{
if (Eat_food(&sn, food[i], 1, SIDE))//如果吃掉
{
score += ADD_SCORE;//加分
//################改变 食物#################
Change_food(&food[i], X_MAX, Y_MAX, SIDE);
//##########################################
}
}
break;
case 2:
DOWN_snack(&sn, SIDE, X_MAX, Y_MAX, &Moving);
for (i = 0; i < NUM_POINT; i++)
{
if (Eat_food(&sn, food[i], 2, SIDE))//如果吃掉
{
score += ADD_SCORE;//加分
//################改变 食物#################
Change_food(&food[i], X_MAX, Y_MAX, SIDE);
//##########################################
}
}
break;
case 3:
LEFT_snack(&sn, SIDE, X_MAX, Y_MAX, &Moving);
for (i = 0; i < NUM_POINT; i++)
{
if (Eat_food(&sn, food[i], 3, SIDE))//如果吃掉
{
score += ADD_SCORE;//加分
//################改变 食物#################
Change_food(&food[i], X_MAX, Y_MAX, SIDE);
//##########################################
}
}
break;
case 4:
RIGHT_snack(&sn, SIDE, X_MAX, Y_MAX, &Moving);
for (i = 0; i < NUM_POINT; i++)
{
if (Eat_food(&sn, food[i], 4, SIDE))//如果吃掉
{
score += ADD_SCORE;//加分
//################改变 食物#################
Change_food(&food[i], X_MAX, Y_MAX, SIDE);
//##########################################
}
}
break;
}
InvalidateRect(hwnd, NULL, TRUE);
break;
case WM_KEYDOWN:
if (Signal_Keydown == 0)//如果按下暂停Signal_Keydown=0,不接收键盘消息
break;
switch (wParam)
{
case VK_UP:
if (Moving == 1 || Moving == 2)
break;
UP_snack(&sn, SIDE, X_MAX, Y_MAX, &Moving);
for (i = 0; i < NUM_POINT; i++)
{
if (Eat_food(&sn, food[i], 1, SIDE))//如果吃掉
{
score += ADD_SCORE;//加分
//################改变 食物#################
Change_food(&food[i], X_MAX, Y_MAX, SIDE);
//##########################################
}
}
Moving = 1;
break;
case VK_DOWN:
if (Moving == 1 || Moving == 2)
break;
DOWN_snack(&sn, SIDE, X_MAX, Y_MAX, &Moving);
for (i = 0; i < NUM_POINT; i++)
{
if (Eat_food(&sn, food[i], 2, SIDE))//如果吃掉
{
score += ADD_SCORE;//加分
//################改变 食物#################
Change_food(&food[i], X_MAX, Y_MAX, SIDE);
//##########################################
}
}
Moving = 2;
break;
case VK_LEFT:
if (Moving == 3 || Moving == 4)
break;
LEFT