本文实例讲述了C++实现基于控制台界面的吃豆子游戏。分享给大家供大家参考。具体分析如下:
程序运行界面如下所示:
ESC键可退出游戏。
main.cpp源文件如下:
#include "lib.h"
#pragma once
extern int level;
int main()
{
FOOD food;
WALL wall;
BODY CurPos;
HALL hall;
int iExit = 0;
while(1)
{
if(iExit)
break;
Init(&food,&wall,&CurPos,&hall);
MakeWall(&wall);
while(1)
{
Sleep(200);
int res = Move(&food,&wall,&CurPos);
if(1 == res) //重新开局
break;
else if(-1 == res) //用户退出
{
iExit = 1;
break;
}
ShowScore(&CurPos,&food);
}
}
return 0;
}
lib.h头文件如下:
#include#include #include #include //标识用户按下的方向键 #define KEY_UP WM_USER + 1 #define KEY_DOWN WM_USER + 2 #define KEY_LEFT WM_USER + 3 #define KEY_RIGHT WM_USER + 4 //标识用户当前运动方向 #define DIRECTION_UP WM_USER + 5 #define DIRECTION_DOWN WM_USER + 6 #define DIRECTION_LEFT WM_USER + 7 #define DIRECTION_RIGHT WM_USER + 8 //标识要打印的元素类型 #define PRINT_WALL WM_USER + 9 #define PRINT_FOOD WM_USER + 10 #define PRINT_BODY WM_USER + 11 #define PRINT_CLEAN WM_USER + 12 #define KNOCK_WALL WM_USER + 13 #define KNOCK_FOOD WM_USER + 14 struct POS { int x; int y; }; struct WALL { POS pos[9999]; int len; }; struct FOOD { POS pos[8]; int len; int IsHidden; }; struct BODY { POS pos; int Direction; }; struct HALL{ POS pos[200]; int len; }; void Init(FOOD *pFood,WALL *pWall,BODY *pBody,HALL *pHall); //进行一些初始化操作 void Print(POS *pos,int TYPE,int ix = 0); //完成打印功能 void MakeWall(WALL *pWall); //生成墙 void MakeFood(HALL *pHall,FOOD *pFood); //生成食物 int Move(FOOD *pFood,WALL *pWall,BODY *pBody); //用户移动 void ShowScore(BODY *pBody,FOOD *pFood); //显示等级 和剩余豆子数 int IsOver(POS pos1,POS pos2,int TYPE); //判断2点是否重合 int IsKnock(WALL *pWall,BODY *pBody,FOOD *pFood,int TYPE); //判断是否撞墙、吃到豆子 int GetKey(); //得到用户按键
lib.cpp源文件如下:
#include "lib.h"
#pragma once
HANDLE hMain_Out;
HANDLE hMain_In;
CONSOLE_CURSOR_INFO info;
int iBeans = 0;
int level = 1;
//extern short wall[17][24];
short wall[17][24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,-1,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,
0,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,-1,0,0,0,0,0,-1,-1,-1,0,0,
0,-1,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0,0,
0,-1,-1,-1,-1,-1,0,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,-1,-1,0,0,
0,-1,0,0,-1,0,-1,0,0,0,0,-1,0,-1,-1,-1,0,0,0,0,0,0,0,0,
0,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,0,-1,0,0,0,0,0,0,0,0,
0,-1,0,0,0,0,0,0,0,0,0,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,0,
0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,0,0,-1,0,0,0,0,
0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,0,0,-1,0,0,0,0,
0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,-1,-1,-1,-1,0,-1,-1,0,
0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,-1,0,0,
0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,
0,0,-1,-1,-1,-1,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,
0,-1,-1,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,
0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
int IsKnock(WALL *pWall,BODY *pBody,FOOD *pFood,int TYPE)
{
if(KNOCK_WALL == TYPE)
{
int i;
for(i = 0 ; i < pWall->len ; ++i)
{
if(IsOver(pBody->pos,pWall->pos[i],KNOCK_WALL))
return 1; //与墙相撞
}
}
else if(KNOCK_FOOD == TYPE)
{
int i;
for(i = 1 ; i <= pFood->len ; ++i)
{
if(IsOver(pFood->pos[i],pBody->pos,KNOCK_WALL))
return i; //与食物相撞
}
}
return 0;
}
int Move(FOOD *pFood,WALL *pWall,BODY *pBody)
{
BODY prePos = *pBody;
// POS prePos = pBody->pos;
int iKey = GetKey();
if(-1 == iKey) //用户退出
return -1;
if(iKey)
{
pBody->Direction = iKey + 4;
iKey = 0;
}
if(0 == iKey)
{
if(DIRECTION_UP == pBody->Direction)
--pBody->pos.y;
else if(DIRECTION_DOWN == pBody->Direction)
++pBody->pos.y;
else if(DIRECTION_LEFT == pBody->Direction)
--pBody->pos.x;
else if(DIRECTION_RIGHT == pBody->Direction)
++pBody->pos.x;
}
if(IsKnock(pWall,pBody,pFood,KNOCK_WALL))
{
*pBody = prePos;
return 0;
}
int ix = IsKnock(pWall,pBody,pFood,KNOCK_FOOD);
if(ix)
{
++iBeans;
//删除初吃掉的食物
int i;
for(i = ix ; i <= (pFood->len - 1) ; ++i)
pFood->pos[i] = pFood->pos[i + 1];
--(pFood->len);
if(0 == pFood->len) //当局完成
{
++level;
return 1;
}
}
Print(&prePos.pos,PRINT_CLEAN); //先删除上一个输出
Print(&pBody->pos,PRINT_BODY);
return 0;
}
int IsOver(POS pos1,POS pos2,int TYPE)
{
if(KNOCK_WALL == TYPE) //pos1,the body. pos2,the wall
if((pos1.x == pos2.x && pos1.y == pos2.y) || (pos2.x + 1 == pos1.x && pos2.y == pos1.y))
return 1;
return 0;
}
void MakeWall(WALL *pWall)
{
int x,y;
int ix = 0;
for(x = 0 ; x <= 16 ; ++x)
{
for(y = 0 ; y <= 23 ; ++y)
{
if(0 == wall[x][y])
{
pWall->pos[ix].x = 2 * y;
pWall->pos[ix].y = x;
Print(&pWall->pos[ix++],PRINT_WALL);
}
}
}
pWall->len = ix; //更新墙的数量
}
void Init(FOOD *pFood,WALL *pWall,BODY *pBody,HALL *pHall)
{
//得到控制台标准输入输出句柄
hMain_Out = GetStdHandle(STD_OUTPUT_HANDLE);
hMain_In = GetStdHandle(STD_INPUT_HANDLE);
//隐藏光标
GetConsoleCursorInfo(hMain_Out,&info);
info.bVisible = FALSE;
SetConsoleCursorInfo(hMain_Out,&info);
//初始化结构体
pFood->len = 0;
pWall->len = 0;
pHall->len = 0;
//改变控制台大小
system("mode con cols=50 lines=21");
//走廊结构体赋值
int x,y;
int ix = 0;
for(x = 0 ; x < 17 ; ++x)
{
for(y = 0 ; y < 24 ; ++y)
{
if(wall[x][y]) //非墙
{
pHall->pos[ix].x = 2 * y;
pHall->pos[ix++].y = x;
}
}
}
pHall->len = ix;
pBody->pos.x = 2;
pBody->pos.y = 1;
pBody->Direction = DIRECTION_DOWN;
printf("%d %dn",pHall->pos[0].x,pHall->pos[0].y);
//输出食物
int i;
MakeFood(pHall,pFood);
for(i = 1 ; i <= 7 ; ++i)
{
Print(&pFood->pos[i],PRINT_FOOD,i);
}
}
int GetKey()
{
if(GetAsyncKeyState(VK_UP))
return KEY_UP;
if(GetAsyncKeyState(VK_DOWN))
return KEY_DOWN;
if(GetAsyncKeyState(VK_LEFT))
return KEY_LEFT;
if(GetAsyncKeyState(VK_RIGHT))
return KEY_RIGHT;
if(GetAsyncKeyState(VK_ESCAPE))
return -1; //用户退出
return 0;//用户没有有效按键
}
void Print(POS *p,int TYPE,int ix)
{
COORD pos;
pos.X = p->x;
pos.Y = p->y;
SetConsoleCursorPosition(hMain_Out,pos);
if(PRINT_WALL == TYPE)
printf("■");
else if(PRINT_FOOD == TYPE)
printf("%d",ix);
else if(PRINT_BODY == TYPE)
printf("1");
else if(PRINT_CLEAN == TYPE)
printf(" ");
}
void ShowScore(BODY *pBody,FOOD *pFood)
{
COORD pos;
pos.X = 0;
pos.Y = 18;
SetConsoleCursorPosition(hMain_Out,pos);
printf("tBeans left : %d | pos : x=%d,y=%dn",pFood->len,pBody->pos.x,pBody->pos.y);
printf("ttLevel : %d",level);
// for(int i = 1 ; i <= pFood->len ; ++i)
// printf("(x=%d,y=%d)",pFood->pos[i].x,pFood->pos[i].y);
}
void MakeFood(HALL *pHall,FOOD *pFood)
{
srand((unsigned)time(NULL));
int tot;
for(tot = 1 ; tot <= 7 ; ++tot)
{
int ixFood = rand() * pHall->len / RAND_MAX;
pFood->pos[tot].x = pHall->pos[ixFood].x;
pFood->pos[tot].y = pHall->pos[ixFood].y;
}
pFood->len = 7;
}
希望本文所述对大家的C++程序设计有所帮助。



