|
100鱼币
代码如下#include <windows.h>
#include <time.h>
#include <stdlib.h>
//定义4个方向
#define UP 1 //向上,蛇头y坐标不断减小
#define DOWN 2 //向下,蛇头y坐标不断增大
#define LEFT 3 //向左,蛇头x坐标不断减小
#define RIGHT 4 //向右,蛇头x坐标不断增大
#define SNAKEWIDTH 10 //单节蛇的大小
#define XWIDTH 20 //游戏区的宽度
#define YHEIGHT 20 //游戏区的高度
#define GETSCORE 10 //吃一个食物的得分
#define ID_TIMER 1 //定时器ID
#define TIMERSET 600 //定时间隔
static int direct = RIGHT; //方向(注:方向由蛇头决定)
static int Score; //吃到的食物数量
bool IsOver = false, bEat = false;
struct Snake
{
Snake() :next(NULL), before(NULL)
{
pt.x = 0; pt.y = 0;
}
Snake(const POINT &npt, Snake *, Snake *);
POINT pt;
Snake * next, *before;
} snake; //定义蛇头
Snake::Snake(const POINT &npt, Snake * nnext, Snake * nbefore) :
pt(npt), next(nnext), before(nbefore) {}
Snake * psLast = NULL, *food = NULL;
bool GameClient[XWIDTH][YHEIGHT]; //定义游戏区坐标布尔值,表示相应点的蛇身以及是否有食物。
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
TCHAR szAppName[] = TEXT("Snake"),
szWindowName[] = TEXT("贪吃蛇");
WNDCLASS wndcls;
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.hCursor = LoadCursor(hInstance, IDC_ARROW);
wndcls.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = WndProc;
wndcls.lpszClassName = szAppName;
wndcls.lpszMenuName = NULL;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
HWND hwnd = CreateWindow(szAppName, szWindowName,
WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, (XWIDTH + 10) * SNAKEWIDTH, (YHEIGHT + 5) * SNAKEWIDTH,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//新食物刷新
void NewFood(HWND hwnd)
{
food = new Snake();
SYSTEMTIME st;
GetLocalTime(&st);
srand(st.wMilliseconds);
food->pt.x = rand() % XWIDTH, food->pt.y = rand() % YHEIGHT;
while (GameClient[food->pt.x][food->pt.y])
{
GetLocalTime(&st);
srand(st.wMilliseconds);
food->pt.x = rand() % XWIDTH, food->pt.y = rand() % YHEIGHT;
}
GameClient[food->pt.x][food->pt.y] = true;
InvalidateRect(hwnd, NULL, TRUE);
}
//判断前方是否是食物
inline bool IsFood()
{
if (snake.pt.x == food->pt.x && snake.pt.y == food->pt.y)
return true;
else
return false;
}
//判断是否撞墙或者撞到自己身体
bool TouchWall()
{
Snake * temp = psLast;
//超越边界判断
if (snake.pt.x >= XWIDTH ||
snake.pt.x < 0 ||
snake.pt.y < 0 ||
snake.pt.y >= YHEIGHT)
return true;
//碰撞自身身体判断
while (temp != &snake)
{
if (snake.pt.x == temp->pt.x &&
snake.pt.y == temp->pt.y)
return true;
temp = temp->before;
}
return false;
}
void Move(HWND hwnd)
{
int x, y; //用于记录蛇头的当前位置(未前进时)
//标记前方是否为食物,默认为不是食物,表示系通常的前进
Snake * temp = psLast;
//记录蛇头当前坐标
x = snake.pt.x;
y = snake.pt.y;
//测试前进的地方是否是食物,同时将蛇头前进
switch (direct)
{
case UP:
--snake.pt.y;
break;
case DOWN:
++snake.pt.y;
break;
case LEFT:
--snake.pt.x;
break;
case RIGHT:
++snake.pt.x;
break;
default:
break;
}
//如果不是食物,作如下处理
if (!IsFood())
{
//最后一节不是蛇头
if (temp != &snake)
{
GameClient[temp->pt.x][temp->pt.y] = false;
while (temp != snake.next)
{
temp->pt.x = temp->before->pt.x;
temp->pt.y = temp->before->pt.y;
temp = temp->before;
}
temp->pt.x = x;
temp->pt.y = y;
GameClient[temp->pt.x][temp->pt.y] = true;
}
else //psLast == &snake,即蛇只有蛇头
GameClient[x][y] = false;
if (TouchWall())
IsOver = true; //则标记游戏结束
else
GameClient[snake.pt.x][snake.pt.y] = true; //不然移动后的蛇头位置标记为有方块了
InvalidateRect(hwnd, NULL, TRUE); //刷新游戏区
}
//如果是食物,作如下处理
else
{
++Score;
food->before = psLast;
psLast->next = food;
if (temp != &snake)
{
food->pt.x = psLast->pt.x;
food->pt.y = psLast->pt.y;
while (temp != snake.next)
{
temp->pt.x = temp->before->pt.x;
temp->pt.y = temp->before->pt.y;
temp = temp->before;
}
temp->pt.x = x;
temp->pt.y = y;
}
else //psLast == &snake,即蛇只有蛇头
{
food->pt.x = x; food->pt.y = y;
}
psLast = food;
NewFood(hwnd);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
static int cxChar, cyChar;
TCHAR szScore[] = TEXT("得分:"),
szGameOver[] = TEXT("游戏结束!"),
szPause[] = TEXT("游戏暂停!"),
szBuffer[20],
*szText = NULL;
int x, y;
static bool pause = false;
switch (message)
{
case WM_CREATE:
direct = RIGHT; //游戏开局,默认方向向右
snake.pt.x = XWIDTH / 2; //默认显示在游戏区中间位置
snake.pt.y = YHEIGHT / 2;
psLast = &snake;
GameClient[snake.pt.x][snake.pt.y] = true;
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cyChar = tm.tmExternalLeading + tm.tmHeight;
ReleaseDC(hwnd, hdc);
NewFood(hwnd);
SetTimer(hwnd, ID_TIMER, TIMERSET, NULL);
return 0;
case WM_TIMER:
if (pause) return 0;
Move(hwnd);
if (IsOver)
{
KillTimer(hwnd, ID_TIMER);
InvalidateRect(hwnd, NULL, TRUE);
}
return 0;
case WM_KEYDOWN:
if (IsOver || pause) return 0;
switch (wParam)
{
case VK_UP:
if (direct != DOWN)
{
direct = UP;
Move(hwnd);
}
break;
case VK_DOWN:
if (direct != UP)
{
direct = DOWN;
Move(hwnd);
}
break;
case VK_LEFT:
if (direct != RIGHT)
{
direct = LEFT;
Move(hwnd);
}
break;
case VK_RIGHT:
if (direct != LEFT)
{
direct = RIGHT;
Move(hwnd);
}
break;
default:
break;
}
return 0;
case WM_CHAR:
if (IsOver && wParam != 'r') return 0;
switch (wParam)
{
case 'p':
{
pause = !pause;
InvalidateRect(hwnd, NULL, TRUE);
}
break;
case 'r':
{
for (int x = 0; x < XWIDTH; ++x)
for (int y = 0; y < YHEIGHT; ++y)
GameClient[x][y] = false;
}
SetTimer(hwnd, ID_TIMER, TIMERSET, NULL);
direct = RIGHT; //游戏开局,默认方向向右
snake.pt.x = XWIDTH / 2; //默认显示在游戏区中间位置
snake.pt.y = YHEIGHT / 2;
psLast = &snake;
IsOver = false;
pause = false;
GameClient[snake.pt.x][snake.pt.y] = true;
NewFood(hwnd);
break;
default:
break;
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SetViewportOrgEx(hdc, SNAKEWIDTH, SNAKEWIDTH, NULL);
//画游戏区的边框
MoveToEx(hdc, -1, -1, NULL);
LineTo(hdc, XWIDTH * SNAKEWIDTH + 1, -1);
LineTo(hdc, XWIDTH * SNAKEWIDTH + 1, YHEIGHT * SNAKEWIDTH + 1);
LineTo(hdc, -1, YHEIGHT * SNAKEWIDTH + 1);
LineTo(hdc, -1, -1);
TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, 0, szScore, lstrlen(szScore));
TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, cyChar,
szBuffer, wsprintf(szBuffer, TEXT("%4d"), Score));
if (pause)
TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, 3 * cyChar, szPause, lstrlen(szPause));
else if (IsOver)
TextOut(hdc, (XWIDTH + 1) * SNAKEWIDTH, 3 * cyChar, szGameOver, lstrlen(szGameOver));
SelectObject(hdc, GetStockObject(BLACK_BRUSH));
for (x = 0; x < XWIDTH; ++x)
{
for (y = 0; y < YHEIGHT; ++y)
{
if (GameClient[x][y])
Rectangle(hdc, x * SNAKEWIDTH, y * SNAKEWIDTH,
(x + 1) * SNAKEWIDTH, (y + 1) * SNAKEWIDTH);
}
}
return 0;
case WM_DESTROY:
KillTimer(hwnd, ID_TIMER);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
这两句看不懂,想问一下,这部分需要补充什么内容的知识,然后这个代码我的编译器会报一些编译错误,他的main函数在哪里?
这是windows编程的内容,后面的MFC框架的基础
你可以去简单学习一下windows编程设计课程
|
最佳答案
查看完整内容
这是windows编程的内容,后面的MFC框架的基础
你可以去简单学习一下windows编程设计课程
|