近期都在忙着复习考试,忙里偷闲,抽空写了个贪吃蛇。没时间写具体的思路了,代码里有比較具体的凝视,有兴趣的同学能够自己看看。(感觉写的相对来说还是比較简短的。假设有什么写的不好或是不正确的地方,欢迎各位指出)。
在写这个贪吃蛇时,我省去了非常多不必要的功能。仅仅实现了最主要的功能,界面也比較粗糙,游戏功能也不见得非常完好,仅仅是为了用尽量少的代码来实现主体功能,大家能够在这个基础上进行改动和完好。
/*--------------------------------------------------------------
名称: 简单的贪吃蛇
开发环境:VC++ 6.0
类型:控制台应用程序
完毕时间:2014.06.20
开发原则:大道至简,仅仅实现了最主要的功能。没有加入什么复杂的功能
作者:风语
运用的技术:双缓存。防止闪屏
---------------------------------------------------------------*/
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#define CMD_UP 1
#define CMD_DOWN 2
#define CMD_LEFT 4
#define CMD_RIGHT 8
#define CMD_QUIT 16
const int MAXN = 1000;
bool flag, tag;
int num, dir, score, a[MAXN];//num表示蛇节点的数目,dir表示蛇前进方向(0,1,2,3)(上下左右)
POINT d[4] = {{0, -10}, {0, 10}, {-10, 0}, {10, 0}};//方向向量
POINT food, node[MAXN];//node蛇的节点坐标
POINT wall[10] = {{20, 10}, {460, 10}, {460, 350}, {20, 350}, {20, 10},
{39, 29}, {441, 29}, {441, 331}, {39, 331}, {39, 29}};//墙
HDC hdc = NULL, mdc = NULL;//mdc内存dc
HWND hwnd = FindWindow("ConsoleWindowClass", NULL);//窗体句柄
HBRUSH hbrush;//画刷
HPEN hpen;//画笔
HBITMAP bmp;//位图
void CreateFood() //产生食物
{
if(tag) return; //tag == true,表明食物存在
while(!tag)//直到产生的食物在有效位置为止
{
food.x = 10 * (rand() % 40) + 40;
food.y = 10 * (rand() % 30) + 30;
Rectangle(mdc, food.x, food.y, food.x + 10, food.y + 10);
tag = true;
//检測食物是否产生在蛇身上,假设在,标记食物为不存在
for(int i = 0; i < 4 * num; i++)
{
if(food.x == node[i].x && food.y == node[i].y)
{
tag = false;
break;
}
}
}
}
void Gotoxy(int x,int y) //设置光标的位置
{
COORD coord;
coord.X = x - 1;
coord.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void GameInit() //游戏初始化
{
srand(unsigned(time(NULL)));
num = 6; dir = 3; score = 0;
flag = true;//flag==true标记游戏能够进行
tag = false;
system("color F0");//设置控制台背景和前景颜色
hdc = GetDC(hwnd);
mdc = CreateCompatibleDC(hdc);//创建兼容dc
bmp = CreateCompatibleBitmap(hdc, 640, 480);//创建兼容位图
SelectObject(mdc, bmp);
hbrush = CreateSolidBrush(RGB(0, 255, 0));
SelectObject(mdc, hbrush);
RECT rect;//将mdc背景色设置为白色
GetClientRect(hwnd, &rect);
hbrush = CreateSolidBrush(RGB(255, 255, 255));
FillRect(mdc, &rect, hbrush);
Polygon(mdc, wall, 10);//绘制墙
Gotoxy(45, 25);
int t = 4 * num - 1;//初始化蛇
node[t].x = 40; node[t].y = 30;
node[t-1].x = 40; node[t-1].y = 40;
node[t-2].x = 50; node[t-2].y = 40;
node[t-3].x = 50; node[t-3].y = 30;
for(int i = t - 4; i >= 0; i--)
{
node[i].x = node[i + 4].x + 10;
node[i].y = node[i + 4].y;
}
for(i = 0; i < MAXN; i++)
{
a[i] = 4;
}
}
void GetDir() //依据用户输入,获取蛇,新的移动方向
{
int c = 0;
if (GetAsyncKeyState(VK_UP) & 0x8000) c |= CMD_UP;
if (GetAsyncKeyState(VK_DOWN) & 0x8000) c |= CMD_DOWN;
if (GetAsyncKeyState(VK_LEFT) & 0x8000) c |= CMD_LEFT;
if (GetAsyncKeyState(VK_RIGHT) & 0x8000) c |= CMD_RIGHT;
if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) c |= CMD_QUIT;
if (c & CMD_UP) if(1 != dir) dir = 0;
if (c & CMD_DOWN) if(0 != dir) dir = 1;
if (c & CMD_LEFT) if(3 != dir) dir = 2;
if (c & CMD_RIGHT) if(2 != dir) dir = 3;
if (c & CMD_QUIT) flag = false;
}
void Release() //释放资源
{
DeleteObject(hbrush);
DeleteObject(hpen);
DeleteObject(bmp);
DeleteDC(mdc);
ReleaseDC(hwnd, hdc);
}
void MoveHead() //蛇的头结点的移动
{
for(int i = 0; i < 4; i++)
{
node[i].x += d[dir].x;
node[i].y += d[dir].y;
}
}
void Translate()//传递蛇身,前一个节点的位置是下一个节点下一步要到的位置
{
for(int i = 4 * num - 1; i >= 4; i--)
{
node[i].x = node[i-4].x;
node[i].y = node[i-4].y;
}
}
void GameOver() //游戏结束与否
{
if(node[0].x > 440 || node[0].x < 50 || node[0].y > 320 || node[0].y < 30)
flag = false;//撞墙
for(int i = 4; i < 4 * num; i += 4)//咬自己
{
if(node[0].x == node[i].x && node[0].y == node[i].y &&
node[2].x == node[i+2].x && node[2].y == node[i+2].y)
{
flag = false;
return;
}
}
}
void PaintSnake() //绘制出蛇
{
PolyPolygon(mdc, node, a, num);
}
void EatFood() //检測蛇是否吃到食物
{
if(node[0].x == food.x + 10 && node[0].y == food.y)
{
tag = false;
num++;
score += 10;
}
}
int main()
{
GameInit();
while(flag)
{
GetDir();
Translate();
MoveHead();
EatFood();
GameOver();
/*绘制出蛇*/
hpen = (HPEN)GetStockObject(BLACK_PEN);
SelectObject(mdc, hpen);
hbrush = CreateSolidBrush(RGB(0, 0, 0));
SelectObject(mdc, hbrush);
CreateFood();
PaintSnake();
BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);//将图像从内存dc复制到当前窗体
if(!flag) break;
/*擦除蛇运动留下的阴影*/
hpen = (HPEN)GetStockObject(WHITE_PEN);
SelectObject(mdc, hpen);
hbrush = CreateSolidBrush(RGB(255, 255, 255));
SelectObject(mdc, hbrush);
PaintSnake();
char str[256];//绘制得分
sprintf(str, "score : %d", score);
TextOut(mdc, 465, 200, str, strlen(str));
Sleep(80);
}
Gotoxy(40, 25);
Sleep(3000);
Release();
return 0;
}