问题描述:
实现贪吃蛇游戏,有等级,分数,并且会保存最高等级和最高分
easysnake.h代码:
#pragma once
#include
#include
#include
#include
#include
#include
#include "resource.h"
#pragma comment(lib, "winmm.lib")
#define SNAKE_DRAW_SIZE 15
#define WND_WIDTH 1000
#define WND_HEIGHT 600
#define REGION_WIDTH 600
#define REGION_HEIGHT 600
#define RIGHT_EDGE_WIDTH 10
#define HEADLINE_POSX 265
#define HEADLINE_POSY 120
#define TEXT_TIME_POSX 670
#define TEXT_TIME_POSY 100
#define TEXT_LEVEL_POSX 670
#define TEXT_LEVEL_POSY 100
#define TEXT_SCORE_POSX 670
#define TEXT_SCORE_POSY 200
#define TEXT_LEN_POSX 670
#define TEXT_LEN_POSY 300
#define TEXT_HIGHSCORE_POSX 670
#define TEXT_HIGHSCORE_POSY 400
#define TEXT_HIGHLEVEL_POSX 670
#define TEXT_HIGHLEVEL_POSY 500
#define SNAKE_INIT_PT_X (REGION_WIDTH / SNAKE_DRAW_SIZE / 5)
#define SNAKE_INIT_PT_Y (REGION_HEIGHT / SNAKE_DRAW_SIZE / 2)
#define FIRST_ITEM_POSX 375
#define FIRST_ITEM_POSY 250
#define FIRST_ITEM_WIDTH 220
#define FIRST_ITEM_HEIGHT 30
#define SECOND_ITEM_POSX 375
#define SECOND_ITEM_POSY 350
#define SECOND_ITEM_WIDTH 220
#define SECOND_ITEM_HEIGHT 30
#define THIRD_ITEM_POSX 375
#define THIRD_ITEM_POSY 450
#define THIRD_ITEM_WIDTH 220
#define THIRD_ITEM_HEIGHT 30
#define BIGFOOD_SHOWTIME 6000
#define BIGFOOD_STEPTIME 100
#define FOOD_SCORE 1
#define BIG_FOOD_SCORE 5
#define INIT_SPEED 110
#define MINUS_SPEED 10
#define TOTAL_TIME 100
#define SNAKE_MAX ((REGION_WIDTH / SNAKE_DRAW_SIZE) * (REGION_HEIGHT / SNAKE_DRAW_SIZE))
#define BREAKTHROUGHAPPNAME L"BreakThrough"
#define BREAKTHROUGHSCORE L"HighScore"
#define BREAKTHROUGHLEVEL L"HighLevel"
#define TIMELIMITEDAPPNAME L"TimeLimited"
#define TIMELIMITEDSCORE L"HighScore"
int arrScore[] = { 0, 8, 16, 24, 32, 40, 48, 60, 72, 85, 95, 118, 130, 155, 170, 190, 210, 230, 250, 270, 300, 350, 400,
460, 500, 550, 600, 650, 700, 750, 810, 880, 950, 1000, 1100,
1250, 1400, 1600, 1850, 2100, 2400, 2700, 3000, 3400, 3800, 4200, 4600, 5000,
5500, 5900, 6300, 6800, 7500, 8000, 8500, 9000, 9500, 10000 };
enum EmPattern
{
emBreakThroughPattern = 1,
emTimeLimitedPattern,
emIntelligencePattern,
};
enum EmStage
{
emChooseStage = 1,
emPlayStage,
};
enum EmDir
{
emDirUp = 72,
emDirDown = 80,
emDirLeft = 75,
emDirRight = 77,
};
struct Point
{
int x;
int y;
};
struct Snake
{
int nCount;
Point pt[SNAKE_MAX];
EmDir dir;
};
struct Food
{
Point fpt;
char isEat;
};
struct BigFood
{
Point fpt;
char isEat;
};
EmStage stage = EmStage::emChooseStage;
EmPattern pattern = EmPattern::emBreakThroughPattern;
Snake snake;
Food food;
BigFood bigFood;
int nBigFoodTimer = 0;
int nCurLevel = 1;
int nCurScore = 0;
int nSnakeLen = 3;
int nHighLevel = 0;
int nHighScore = 0;
int nCurSpeed = INIT_SPEED;
int nRemainTime = TOTAL_TIME;
int nTimePast = 0;
void SetMouseNormal();
void SetMouseHand();
void SetLevelText();
void SetHoverStyle();
void SetNormalStyle();
void TackleMouseMove(int x, int y);
void TackleLeftButtonDown(int x, int y);
void TackleMouseAction();
void InitFirstScene();
void InitSecondBackGround();
void InitSecondScene();
void GameInit();
void PlayGame();
int IsFoodPosOk(int x, int y);
void ProduceFood();
void DrawFood();
int ProduceBigFood();
void DrawBigFood();
int IsEatBigFood();
void EatFood();
void LevelUp();
void DrawSnake();
void SnakeMove();
void ChangeDir();
void BreakSnake();
void WriteRecord();
void BigFoodDisappear();
void TimeEclipse();
void DecideHeadDirection();
void DrawSnakeHead(int nIndex);
void DecideCornerDirection(int idx);
void DrawCorner(int nIndex, int idx);
void DecideBodyDirection(int idx);
void DrawBody(int nIndex, int idx);
void DecideTailDirection(int idx);
void DrawTail(int nIndex, int idx);
void BreakThroughPattern();
void TimeLimitedPattern();
easysnake.cpp
#include "easysnake.h"
BOOL KExpandEnvironmentString(IN LPCTSTR lpEnvironmentString, OUT LPTSTR lpExpandString, IN ULONG ulExpandStringLength)
{
BOOL bResult = FALSE;
LPTSTR lpBuffer = NULL;
ULONG ulRetLength = 0;
if (!lpEnvironmentString || !lpExpandString || 1 > ulExpandStringLength)
{
goto _abort;
}
ulRetLength = ::ExpandEnvironmentStrings(lpEnvironmentString, NULL, 0);
if (1 > ulRetLength || ulRetLength > ulExpandStringLength - 1)
{
goto _abort;
}
__try
{
lpBuffer = new TCHAR[ulRetLength];
if (!lpBuffer)
{
goto _abort;
}
::RtlZeroMemory(lpBuffer, sizeof(TCHAR)* ulRetLength);
ulRetLength = ::ExpandEnvironmentStrings(lpEnvironmentString, lpBuffer, ulRetLength);
if (ulRetLength && ulRetLength <= ulExpandStringLength - 1)
{
_tcsncpy_s(lpExpandString, ulExpandStringLength - 1, lpBuffer, ulRetLength);
bResult = TRUE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
bResult = FALSE;
}
_abort:
if (lpBuffer)
{
delete[] lpBuffer;
lpBuffer = NULL;
}
return bResult;
}
void SetMouseNormal()
{
HCURSOR hcur = LoadCursor(NULL, IDC_ARROW);
HWND hwnd = GetHWnd();
SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);
}
void SetMouseHand()
{
HCURSOR hcur = LoadCursor(NULL, MAKEINTRESOURCE(32649));
HWND hwnd = GetHWnd();
SetClassLong(hwnd, GCL_HCURSOR, (long)hcur);
}
void SetLevelText()
{
switch (pattern)
{
case EmPattern::emBreakThroughPattern:
outtextxy(FIRST_ITEM_POSX, FIRST_ITEM_POSY, L"闯关模式");
break;
case EmPattern::emTimeLimitedPattern:
outtextxy(SECOND_ITEM_POSX, SECOND_ITEM_POSY, L"限时模式");
break;
case EmPattern::emIntelligencePattern:
outtextxy(THIRD_ITEM_POSX, THIRD_ITEM_POSY, L"智能模式");
break;
default:
break;
}
}
void SetHoverStyle()
{
settextcolor(RGB(255, 0, 119));
SetLevelText();
SetMouseHand();
}
void SetNormalStyle()
{
settextcolor(BROWN);
SetLevelText();
SetMouseNormal();
}
void TackleMouseMove(int x, int y)
{
if (stage == EmStage::emPlayStage)
return;
if (x > FIRST_ITEM_POSX && x < FIRST_ITEM_POSX + FIRST_ITEM_WIDTH && y >FIRST_ITEM_POSY && y < FIRST_ITEM_POSY + FIRST_ITEM_HEIGHT)
{
pattern = EmPattern::emBreakThroughPattern;
SetHoverStyle();
return;
}
else
{
pattern = EmPattern::emBreakThroughPattern;
SetNormalStyle();
}
if (x > SECOND_ITEM_POSX && x < SECOND_ITEM_POSX + SECOND_ITEM_WIDTH && y > SECOND_ITEM_POSY && y < SECOND_ITEM_POSY + SECOND_ITEM_HEIGHT)
{
pattern = EmPattern::emTimeLimitedPattern;
SetHoverStyle();
return;
}
else
{
pattern = EmPattern::emTimeLimitedPattern;
SetNormalStyle();
}
if (x > THIRD_ITEM_POSX && x < THIRD_ITEM_POSX + THIRD_ITEM_WIDTH && y > THIRD_ITEM_POSY && y < THIRD_ITEM_POSY + THIRD_ITEM_HEIGHT)
{
pattern = EmPattern::emIntelligencePattern;
SetHoverStyle();
}
else
{
pattern = EmPattern::emIntelligencePattern;
SetNormalStyle();
}
}
void TimeLimitedPattern()
{
settextstyle(20, 20, L"楷体", 0, 0, 900, 0, 0, 0);
setbkmode(TRANSPARENT);
settextcolor(RGB(255, 0, 0));
WCHAR szCurRemainTime[32];
WCHAR szCurScore[32];
WCHAR szSnakeLen[32];
WCHAR szHighScore[32];
swprintf_s(szCurRemainTime, L"剩余时间: %d", nRemainTime);
swprintf_s(szCurScore, L"当前得分: %d", nCurScore);
swprintf_s(szSnakeLen, L"蛇身长度: %d", snake.nCount);
swprintf_s(szHighScore, L"最高分数: %d", nHighScore);
outtextxy(TEXT_TIME_POSX, TEXT_TIME_POSY, szCurRemainTime);
outtextxy(TEXT_SCORE_POSX, TEXT_SCORE_POSY, szCurScore);
outtextxy(TEXT_LEN_POSX, TEXT_LEN_POSY, szSnakeLen);
outtextxy(TEXT_HIGHSCORE_POSX, TEXT_HIGHSCORE_POSY, szHighScore);
}
void BreakThroughPattern()
{
settextstyle(20, 20, L"楷体", 0, 0, 900, 0, 0, 0);
setbkmode(TRANSPARENT);
settextcolor(RGB(255, 0, 0));
WCHAR szCurLevel[32];
WCHAR szCurScore[32];
WCHAR szSnakeLen[32];
WCHAR szHighLevel[32];
WCHAR szHighScore[32];
swprintf_s(szCurLevel, L"当前级别: %d", nCurLevel);
swprintf_s(szCurScore, L"当前得分: %d", nCurScore);
swprintf_s(szSnakeLen, L"蛇身长度: %d", snake.nCount);
swprintf_s(szHighLevel, L"最高级别: %d", nHighLevel);
swprintf_s(szHighScore, L"最高分数: %d", nHighScore);
outtextxy(TEXT_LEVEL_POSX, TEXT_LEVEL_POSY, szCurLevel);
outtextxy(TEXT_SCORE_POSX, TEXT_SCORE_POSY, szCurScore);
outtextxy(TEXT_LEN_POSX, TEXT_LEN_POSY, szSnakeLen);
outtextxy(TEXT_HIGHSCORE_POSX, TEXT_HIGHSCORE_POSY, szHighLevel);
outtextxy(TEXT_HIGHLEVEL_POSX, TEXT_HIGHLEVEL_POSY, szHighScore);
}
void TackleLeftButtonDown(int x, int y)
{
if (x > FIRST_ITEM_POSX && x < FIRST_ITEM_POSX + FIRST_ITEM_WIDTH && y >FIRST_ITEM_POSY && y < FIRST_ITEM_POSY + FIRST_ITEM_HEIGHT)
{
pattern = EmPattern::emBreakThroughPattern;
InitSecondScene();
}
if (x > SECOND_ITEM_POSX && x < SECOND_ITEM_POSX + SECOND_ITEM_WIDTH && y > SECOND_ITEM_POSY && y < SECOND_ITEM_POSY + SECOND_ITEM_HEIGHT)
{
pattern = EmPattern::emTimeLimitedPattern;
InitSecondScene();
}
if (x > THIRD_ITEM_POSX && x < THIRD_ITEM_POSX + THIRD_ITEM_WIDTH && y > THIRD_ITEM_POSY && y < THIRD_ITEM_POSY + THIRD_ITEM_HEIGHT)
{
pattern = EmPattern::emIntelligencePattern;
InitSecondScene();
}
}
void TackleMouseAction()
{
MOUSEMSG msg;
while (1)
{
msg = GetMouseMsg();//获取鼠标信息
switch (msg.uMsg)
{
case WM_LBUTTONDOWN://处理鼠标的左键点击消息
TackleLeftButtonDown(msg.x, msg.y);
break;
case WM_MOUSEMOVE://处理鼠标的左键点击消息
TackleMouseMove(msg.x, msg.y);
break;
default:
break;
}
}
}
void InitFirstScene()
{
cleardevice();
stage = EmStage::emChooseStage;
IMAGE img;
for (int i = 0; i < 22; i++)
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG1), SNAKE_DRAW_SIZE * 3, SNAKE_DRAW_SIZE * 3);
putimage(4 + SNAKE_DRAW_SIZE * 3 * i, 0, &img);
}
settextstyle(38, 38, L"楷体", 0, 0, 1000, 0, 0, 0);
setbkmode(TRANSPARENT);
settextcolor(RGB(255, 0, 0));
outtextxy(HEADLINE_POSX, HEADLINE_POSY, L"贪吃蛇大作战");
settextstyle(28, 28, L"楷体", 0, 0, 1000, 0, 0, 0);
setbkmode(TRANSPARENT);
pattern = EmPattern::emBreakThroughPattern;
SetNormalStyle();
pattern = EmPattern::emTimeLimitedPattern;
SetNormalStyle();
pattern = EmPattern::emIntelligencePattern;
SetNormalStyle();
pattern = EmPattern::emBreakThroughPattern;
TackleMouseAction();
}
void InitSecondBackGround()
{
setlinecolor(RED);
setlinestyle(PS_SOLID, RIGHT_EDGE_WIDTH);
line(REGION_WIDTH + 4, 0, REGION_WIDTH + 4, REGION_HEIGHT);
if (EmPattern::emBreakThroughPattern == pattern)
BreakThroughPattern();
else if (EmPattern::emTimeLimitedPattern == pattern)
TimeLimitedPattern();
else if (EmPattern::emIntelligencePattern == pattern)
BreakThroughPattern();
}
void InitSecondScene()
{
cleardevice();
stage = EmStage::emPlayStage;
GameInit();
InitSecondBackGround();
PlayGame();
}
void GameInit()
{
snake.dir = EmDir::emDirRight;
snake.nCount = 3;
for (int i = 0; i < snake.nCount; i++)
{
snake.pt[i].x = SNAKE_INIT_PT_X - i;
snake.pt[i].y = SNAKE_INIT_PT_Y;
}
food.isEat = 1;
bigFood.isEat = 1;
nBigFoodTimer = 0;
WCHAR szTempPath[MAX_PATH] = { 0 };
WCHAR szIniPath[MAX_PATH] = { 0 };
KExpandEnvironmentString(L"%TEMP%", szTempPath, MAX_PATH);
swprintf_s(szIniPath, L"%s\\record.ini", szTempPath);
nCurSpeed = INIT_SPEED;
nCurLevel = 1;
nCurScore = 0;
nSnakeLen = 3;
nRemainTime = TOTAL_TIME;
nTimePast = 0;
nHighLevel = ::GetPrivateProfileInt(BREAKTHROUGHAPPNAME, BREAKTHROUGHLEVEL, 1, szIniPath);
if (pattern == EmPattern::emTimeLimitedPattern)
nHighScore = ::GetPrivateProfileInt(TIMELIMITEDAPPNAME, TIMELIMITEDSCORE, 0, szIniPath);
else
nHighScore = ::GetPrivateProfileInt(BREAKTHROUGHAPPNAME, BREAKTHROUGHSCORE, 0, szIniPath);
}
void PlayGame()
{
while (1)
{
while (!_kbhit())
{
ProduceFood();
BigFoodDisappear();
TimeEclipse();
BeginBatchDraw();
cleardevice();
InitSecondBackGround();
DrawFood();
DrawBigFood();
EatFood();
SnakeMove();
DrawSnake();
Sleep(nCurSpeed);
EndBatchDraw();
BreakSnake();
}
ChangeDir();
}
}
void TimeEclipse()
{
if (pattern != EmPattern::emTimeLimitedPattern)
return;
nTimePast += nCurSpeed;
nRemainTime = TOTAL_TIME - nTimePast / 1000;
nCurSpeed = INIT_SPEED - nTimePast / 1000;
if (nRemainTime < 0)
{
WCHAR szScore[32] = { 0 };
swprintf_s(szScore, L"你的得分是: %d", nCurScore);
::MessageBox(0, szScore, L"时间到", 0);
WriteRecord();
InitFirstScene();
}
}
void BigFoodDisappear()
{
if (1 == bigFood.isEat)
return;
nBigFoodTimer += BIGFOOD_STEPTIME;//大食物定时消失
if (nBigFoodTimer >= BIGFOOD_SHOWTIME)
{
bigFood.isEat = 1;
nBigFoodTimer = 0;
}
}
void WriteRecord()
{
WCHAR szTempPath[MAX_PATH] = { 0 };
WCHAR szIniPath[MAX_PATH] = { 0 };
WCHAR szHighScore[8] = { 0 };
WCHAR szHighLevel[8] = { 0 };
KExpandEnvironmentString(L"%TEMP%", szTempPath, MAX_PATH);
swprintf_s(szIniPath, L"%s\\record.ini", szTempPath);
if (pattern == EmPattern::emBreakThroughPattern)
{
nHighLevel = ::GetPrivateProfileInt(BREAKTHROUGHAPPNAME, BREAKTHROUGHLEVEL, 1, szIniPath);
nHighScore = ::GetPrivateProfileInt(BREAKTHROUGHAPPNAME, BREAKTHROUGHSCORE, 0, szIniPath);
if (nCurScore > nHighScore)
{
swprintf_s(szHighScore, L"%d", nCurScore);
WritePrivateProfileString(BREAKTHROUGHAPPNAME, BREAKTHROUGHSCORE, szHighScore, szIniPath);
}
if (nCurLevel > nHighLevel)
{
swprintf_s(szHighLevel, L"%d", nCurLevel);
WritePrivateProfileString(BREAKTHROUGHAPPNAME, BREAKTHROUGHLEVEL, szHighLevel, szIniPath);
}
}
else if (pattern == EmPattern::emTimeLimitedPattern)
{
nHighScore = ::GetPrivateProfileInt(TIMELIMITEDAPPNAME, TIMELIMITEDSCORE, 0, szIniPath);
if (nCurScore > nHighScore)
{
swprintf_s(szHighScore, L"%d", nCurScore);
WritePrivateProfileString(TIMELIMITEDAPPNAME, TIMELIMITEDSCORE, szHighScore, szIniPath);
}
}
}
void BreakSnake()
{
if (snake.pt[0].x < 0 || snake.pt[0].x > REGION_WIDTH / SNAKE_DRAW_SIZE - 1 || snake.pt[0].y < 0 || snake.pt[0].y > REGION_HEIGHT / SNAKE_DRAW_SIZE - 1)
{
::MessageBox(0, L"你撞墙了", L"游戏失败", 0);
WriteRecord();
InitFirstScene();
}
for (int i = snake.nCount - 2; i > 0; i--)
{
if (snake.pt[i].x == snake.pt[0].x && snake.pt[i].y == snake.pt[0].y)
{
::MessageBox(0, L"你咬到尾巴了", L"游戏失败", 0);
WriteRecord();
InitFirstScene();
}
}
}
void ChangeDir()
{
int dir = _getch();
switch (dir)
{
case EmDir::emDirUp:
if (snake.dir != EmDir::emDirDown)
snake.dir = EmDir::emDirUp;
break;
case EmDir::emDirDown:
if (snake.dir != EmDir::emDirUp)
snake.dir = EmDir::emDirDown;
break;
case EmDir::emDirLeft:
if (snake.dir != EmDir::emDirRight)
snake.dir = EmDir::emDirLeft;
break;
case EmDir::emDirRight:
if (snake.dir != EmDir::emDirLeft)
snake.dir = EmDir::emDirRight;
break;
default:
break;
}
}
void SnakeMove()
{
for (int i = snake.nCount; i > 0; i--)
{
snake.pt[i].x = snake.pt[i - 1].x;
snake.pt[i].y = snake.pt[i - 1].y;
}
switch (snake.dir)
{
case EmDir::emDirUp:
snake.pt[0].y--;
break;
case EmDir::emDirDown:
snake.pt[0].y++;
break;
case EmDir::emDirLeft:
snake.pt[0].x--;
break;
case EmDir::emDirRight:
snake.pt[0].x++;
break;
default:
break;
}
}
void DecideHeadDirection()
{
if (snake.pt[0].y == snake.pt[1].y && snake.pt[0].x > snake.pt[1].x)//头往右走
DrawSnakeHead(0);
else if (snake.pt[0].y == snake.pt[1].y && snake.pt[0].x < snake.pt[1].x)//头往左走
DrawSnakeHead(1);
else if (snake.pt[0].x == snake.pt[1].x && snake.pt[0].y < snake.pt[1].y)//头往上走
DrawSnakeHead(2);
else if (snake.pt[0].x == snake.pt[1].x && snake.pt[0].y > snake.pt[1].y)//头往下走
DrawSnakeHead(3);
}
void DrawSnakeHead(int nIndex)
{
IMAGE img;
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG2 + nIndex), SNAKE_DRAW_SIZE, SNAKE_DRAW_SIZE);
putimage(snake.pt[0].x * SNAKE_DRAW_SIZE, snake.pt[0].y * SNAKE_DRAW_SIZE, &img);
}
void DecideCornerDirection(int idx)
{
if (snake.pt[idx].y > snake.pt[idx - 1].y && snake.pt[idx].x == snake.pt[idx - 1].x && snake.pt[idx].y == snake.pt[idx + 1].y && snake.pt[idx].x > snake.pt[idx + 1].x)
DrawCorner(0, idx);//右->上
else if (snake.pt[idx].y == snake.pt[idx - 1].y && snake.pt[idx].x > snake.pt[idx - 1].x && snake.pt[idx].y > snake.pt[idx + 1].y && snake.pt[idx].x == snake.pt[idx + 1].x)
DrawCorner(0, idx);//下->左
else if (snake.pt[idx].y > snake.pt[idx - 1].y && snake.pt[idx].x == snake.pt[idx - 1].x && snake.pt[idx].y == snake.pt[idx + 1].y && snake.pt[idx].x < snake.pt[idx + 1].x)
DrawCorner(1, idx);//左->上
else if (snake.pt[idx].y == snake.pt[idx - 1].y && snake.pt[idx].x < snake.pt[idx - 1].x && snake.pt[idx].y > snake.pt[idx + 1].y && snake.pt[idx].x == snake.pt[idx + 1].x)
DrawCorner(1, idx);//下->右
else if (snake.pt[idx].y < snake.pt[idx - 1].y && snake.pt[idx].x == snake.pt[idx - 1].x && snake.pt[idx].y == snake.pt[idx + 1].y && snake.pt[idx].x > snake.pt[idx + 1].x)
DrawCorner(2, idx);//右->下
else if (snake.pt[idx].y == snake.pt[idx - 1].y && snake.pt[idx].x > snake.pt[idx - 1].x && snake.pt[idx].y < snake.pt[idx + 1].y && snake.pt[idx].x == snake.pt[idx + 1].x)
DrawCorner(2, idx);//上->左
else if (snake.pt[idx].y < snake.pt[idx - 1].y && snake.pt[idx].x == snake.pt[idx - 1].x && snake.pt[idx].y == snake.pt[idx + 1].y && snake.pt[idx].x < snake.pt[idx + 1].x)
DrawCorner(3, idx);//左->下
else if (snake.pt[idx].y == snake.pt[idx - 1].y && snake.pt[idx].x < snake.pt[idx - 1].x && snake.pt[idx].y < snake.pt[idx + 1].y && snake.pt[idx].x == snake.pt[idx + 1].x)
DrawCorner(3, idx);//上->右
else
DecideBodyDirection(idx);//不是corner的情况在考虑body
}
void DrawCorner(int nIndex, int idx)
{
IMAGE img;
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG6 + nIndex), SNAKE_DRAW_SIZE, SNAKE_DRAW_SIZE);
putimage(snake.pt[idx].x * SNAKE_DRAW_SIZE, snake.pt[idx].y * SNAKE_DRAW_SIZE, &img);
}
void DecideBodyDirection(int idx)
{
if (snake.pt[idx].x == snake.pt[idx - 1].x || snake.pt[idx].x == snake.pt[idx + 1].x)//上下
DrawBody(0, idx);
else if (snake.pt[idx].y == snake.pt[idx - 1].y || snake.pt[idx].y == snake.pt[idx + 1].y)//左右
DrawBody(1, idx);
}
void DrawBody(int nIndex, int idx)
{
IMAGE img;
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG10 + nIndex), SNAKE_DRAW_SIZE, SNAKE_DRAW_SIZE);
putimage(snake.pt[idx].x * SNAKE_DRAW_SIZE, snake.pt[idx].y * SNAKE_DRAW_SIZE, &img);
}
void DecideTailDirection()
{
int idx = snake.nCount - 1;
if (snake.pt[idx].y == snake.pt[idx - 1].y && snake.pt[idx].x < snake.pt[idx - 1].x)//往右
DrawTail(0, idx);
else if (snake.pt[idx].y == snake.pt[idx - 1].y && snake.pt[idx].x > snake.pt[idx - 1].x)//往左
DrawTail(1, idx);
else if (snake.pt[idx].y > snake.pt[idx - 1].y && snake.pt[idx].x == snake.pt[idx - 1].x)//往上
DrawTail(2, idx);
else if (snake.pt[idx].y < snake.pt[idx - 1].y && snake.pt[idx].x == snake.pt[idx - 1].x)//往下
DrawTail(3, idx);
}
void DrawTail(int nIndex, int idx)
{
IMAGE img;
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG12 + nIndex), SNAKE_DRAW_SIZE, SNAKE_DRAW_SIZE);
putimage(snake.pt[idx].x * SNAKE_DRAW_SIZE, snake.pt[idx].y * SNAKE_DRAW_SIZE, &img);
}
void DrawSnake()
{
for (int i = 0; i < snake.nCount; i++)
{
if (0 == i)
DecideHeadDirection();
else if (i == snake.nCount - 1)
DecideTailDirection();
else
DecideCornerDirection(i);
}
}
int IsEatBigFood()
{
if (1 == bigFood.isEat)
return 0;
for (int i = bigFood.fpt.x; i < bigFood.fpt.x + 3; i++)
{
for (int j = bigFood.fpt.y; j < bigFood.fpt.y + 3; j++)
{
if (snake.pt[0].x == i && snake.pt[0].y == j)
return 1;
}
}
return 0;
}
void LevelUp()
{
if (pattern == EmPattern::emTimeLimitedPattern)
return;
WCHAR szLevelUp[32];
if (nCurScore > arrScore[nCurLevel])
{
swprintf_s(szLevelUp, L"恭喜你,升到第%d级", nCurLevel + 1);
::MessageBox(0, szLevelUp, L"升级啦", 0);
nCurLevel++;
if (nCurSpeed > 0)
nCurSpeed -= MINUS_SPEED;
}
}
void EatFood()
{
if (snake.pt[0].x == food.fpt.x && snake.pt[0].y == food.fpt.y)
{
nCurScore += FOOD_SCORE;
snake.nCount++;
food.isEat = 1;
ProduceBigFood();
}
if (IsEatBigFood())
{
nCurScore += BIG_FOOD_SCORE;
snake.nCount++;
bigFood.isEat = 1;
}
LevelUp();
}
int IsFoodPosOk(int x, int y)
{
for (int i = 0; i < snake.nCount; i++)
{
if (snake.pt[i].x == x && snake.pt[i].y == y)
return 0;
}
if (0 == bigFood.isEat)
{
for (int i = bigFood.fpt.x; i < bigFood.fpt.x + 3; i++)
{
for (int j = bigFood.fpt.y; j < bigFood.fpt.y + 3; j++)
{
if (x == i && y == j)
return 0;
}
}
}
return 1;
}
int IsBigFoodPosOk(int x, int y)
{
for (int i = x; i < x + 3; i++)
{
for (int j = y; j < y + 3; j++)
{
if (i < 0 || i > REGION_WIDTH / SNAKE_DRAW_SIZE - 1 || j < 0 || j > REGION_HEIGHT / SNAKE_DRAW_SIZE - 1)
return 0;
for (int k = 0; k < snake.nCount; k++)
{
if (snake.pt[k].x == i && snake.pt[k].y == j)
return 0;
}
}
}
return 1;
}
void ProduceFood()
{
if (0 == food.isEat)
return;
while (1)
{
food.fpt.x = rand() % (REGION_WIDTH / SNAKE_DRAW_SIZE);
food.fpt.y = rand() % (REGION_HEIGHT / SNAKE_DRAW_SIZE);
if (IsFoodPosOk(food.fpt.x, food.fpt.y))
break;
}
food.isEat = 0;
}
void DrawFood()
{
IMAGE img;
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG1), SNAKE_DRAW_SIZE, SNAKE_DRAW_SIZE);
putimage(food.fpt.x * SNAKE_DRAW_SIZE, food.fpt.y * SNAKE_DRAW_SIZE, &img);
}
int ProduceBigFood()
{
if (0 == bigFood.isEat)//大食物没被吃掉,不产生
return 0;
if (rand() % 2 == 0)
{
while (1)
{
bigFood.fpt.x = rand() % (REGION_WIDTH / SNAKE_DRAW_SIZE);
bigFood.fpt.y = rand() % (REGION_HEIGHT / SNAKE_DRAW_SIZE);
if (IsBigFoodPosOk(bigFood.fpt.x, bigFood.fpt.y))
break;
}
bigFood.isEat = 0;
return 1;
}
return 0;
}
void DrawBigFood()
{
if (1 == bigFood.isEat)
return;
IMAGE img;
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG1), SNAKE_DRAW_SIZE * 3, SNAKE_DRAW_SIZE * 3);
putimage(bigFood.fpt.x * SNAKE_DRAW_SIZE, bigFood.fpt.y * SNAKE_DRAW_SIZE, &img);
}
int main()
{
HWND hWnd = GetConsoleWindow();
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)));
initgraph(WND_WIDTH, WND_HEIGHT);
srand((unsigned int)time(NULL));
InitFirstScene();
getchar();
closegraph();
return 0;
}
resource.h
#define IDI_ICON1 101
#define IDR_JPG1 108
#define IDR_JPG2 110
#define IDR_JPG3 111
#define IDR_JPG4 112
#define IDR_JPG5 113
#define IDR_JPG6 114
#define IDR_JPG7 115
#define IDR_JPG8 116
#define IDR_JPG9 117
#define IDR_JPG10 118
#define IDR_JPG11 119
#define IDR_JPG12 120
#define IDR_JPG13 121
#define IDR_JPG14 122
#define IDR_JPG15 123