windows可视化程序设计——贪吃蛇
#include<windows.h>
#include<conio.h>
#include<color.h>
#include<cstdlib>
#include<mmsystem.h>
#pragma comment(lib, "WINMM.LIB")
#include<ctime>
using namespace std;
/*定义蛇结构体,direction存放1、2、3、4分别表示蛇头移动的方向是上下左右;
length存放当前蛇的长度,headx、heady、nailx、naily存放蛇的头尾的位置*/
typedef struct Snake{
int headx;
int heady;
int nailx;
int naily;
int direction;
int length;
}Snake;
const int M = 25;
const int N = 40;
const int XCenter = 12;//画板中心1~23
const int YCenter = 20;//1~39
const int aveLevelFoods = 10 ;//每一个级别食物个数
const int aveFoodScores = 100 ;//每一个食物分数
const int aveLevelScores = aveLevelFoods * aveFoodScores;//每一个级别分数
const int maxLevel = 5;//最高级别
int board[M][N];//board[headx][heady]中存放值1、2、3、4分别蛇身位于当前位置的表示上下左右;5表示有食物
int level, speed[maxLevel] = {400, 200, 100, 50, 25}; //等级越高,速度越快
Snake snake;
//初始化函数
void init();
//控制光标移动
void gotoxy(int x, int y);
//绘制蛇形函数
void printSnake();
//定时移动蛇形,返回值为-1表示死亡
int moveSnake(char& key);
//产生食物
void popFood();
//积分打印
void printScore();
int main()
{
char key, isAgain = 'y', &referKey = key;
init();
printSnake();
while(1){
if(kbhit())//有键按下
key = getch();
if(moveSnake(referKey) == -1){
gotoxy(XCenter, YCenter - 3);
cout<<"Game Over!";
gotoxy(XCenter+2, YCenter - 5);
cout<<"是否开始下一局(y/n)?";
isAgain = getch();
if(isAgain != 'n' && isAgain != 'N'){
init();
printSnake();
}
else
break;
}
if(level > maxLevel){
gotoxy(XCenter, YCenter - 5);
cout<<"恭喜你,你已经通关了!";
gotoxy(XCenter+2, YCenter - 5);
cout<<"是否开始下一局(y/n)?";
isAgain = getch();
if(isAgain != 'n' && isAgain != 'N'){
init();
printSnake();
}
else
break;
}
Sleep(speed[level-1]);
}
return 0;
}
//积分打印
void printScore()
{
int score = (snake.length - 3) * 100;
BLACK_WHITE;
gotoxy(M, 0);
printf("\n");
if(score >= level * aveLevelScores){
++level;
if(level > maxLevel){
return;
}
}
int foods = (level * aveLevelScores - score) / aveFoodScores;
if(foods == 10)
printf(" 星星:%d\n\n", -foods);
else
printf(" 星星:%d \n\n", -foods);//把十位上0置为空
printf(" 得分:%-4d 等级:%d\n", score, level);
BLACK_RED;
}
//产生食物
void popFood()
{
int x, y;
srand(time(NULL));
do{
x = rand() % 23 + 1;//1~23
y = rand() % 38 + 1;
}while(board[x][y] > 0);
gotoxy(x, y);
BLACK_RED;
cout<<"★";
board[x][y] = 5;//表示该地点有食物
}
//定时移动蛇形
int moveSnake(char& key)
{
int hasfood = 0, eatself = 0;
//根据键值改变方向
if(key == 'w' || key == 'W'){
if(snake.direction > 2)//当前方向为水平方向
snake.direction = 1;
}else if(key == 's' || key == 'S'){
if(snake.direction > 2)
snake.direction = 2;
}else if(key == 'a' || key == 'A'){
if(snake.direction < 3)//当前方向为垂直方向
snake.direction = 3;
}else if(key == 'd' || key == 'D'){
if(snake.direction < 3)//当前方向为水平方向
snake.direction = 4;
}else if(key == 'p' || key == 'P'){//暂停
while(1){
if(kbhit())//有键按下
key = getch();
if(key == 'w' || key == 'W' || key == 'a' || key == 'A' || key == 's' || key == 'S' ||key == 'd' || key == 'D')
break;
}
}else;
//求解新的蛇头
int next = board[snake.headx][snake.heady];
if(snake.direction == 1 && next != 1){//next蛇身方向不能与前进方向相同
--snake.headx;
if(board[snake.headx][snake.heady] == 5){
hasfood = 1;
}
if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
eatself = 1;
}
board[snake.headx][snake.heady] = 2;
}
else if(snake.direction == 2 && next != 2){
++snake.headx;
if(board[snake.headx][snake.heady] == 5){
hasfood = 1;
}
if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
eatself = 1;
}
board[snake.headx][snake.heady] = 1;
}
else if(snake.direction == 3 && next != 3){
--snake.heady;
if(board[snake.headx][snake.heady] == 5){
hasfood = 1;
}
if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
eatself = 1;
}
board[snake.headx][snake.heady] = 4;
}
else if(snake.direction == 4 && next != 4){
++snake.heady;
if(board[snake.headx][snake.heady] == 5){
hasfood = 1;
}
if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
eatself = 1;
}
board[snake.headx][snake.heady] = 3;
}
else;
//出界死亡
if(eatself == 1 || snake.headx == 0 || snake.headx == M - 1 || snake.heady == 0 || snake.heady== N - 1)
return -1;
//吃到食物
if(hasfood){
++snake.length;
popFood();
printScore(); //打印积分
//PlaySound(TEXT("newmail.wav"),0,SND_FILENAME|SND_ASYNC); //播放音乐
//PlaySound(TEXT("a.wav"),0,SND_ASYNC | SND_LOOP); //播放背景音乐
return 0;
}
//清除蛇尾并求解新的蛇尾
gotoxy(snake.nailx, snake.naily);
cout<<" ";
board[snake.nailx][snake.naily] = 0; //离开了此地
int length = 0, x = snake.headx, y = snake.heady;
while(1){
++length;
if(length == snake.length)
break;
switch(board[x][y]){
case 1:
--x;
break;
case 2:
++x;
break;
case 3:
--y;
break;
case 4:
++y;
}
}
snake.nailx = x;
snake.naily = y;
printSnake();
return 0;
}
//绘制蛇形函数
void printSnake()
{
int x = snake.headx, y = snake.heady, length = 0;
BLACK_BLUE;
while(1){
gotoxy(x, y);
cout<<"⊙";//board[x][y];
++length;
if(length == snake.length)
break;
switch(board[x][y]){
case 1:
--x;
break;
case 2:
++x;
break;
case 3:
--y;
break;
case 4:
++y;
}
BLACK_RED;
}
}
//控制光标移动
void gotoxy(int x, int y)
{
COORD c;
c.X = 2*y;//数组和屏幕坐标方向不同且横向每个图形占两个字符
c.Y = x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
CONSOLE_CURSOR_INFO cursor_info = {1, 0}; //隐藏光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
//初始化函数
void init()
{
system("cls");
system("mode con cols=81 lines=35");//窗口宽度高度
memset(board, 0, sizeof(board));
memset(&snake, 0, sizeof(&snake));
level = 1;
snake.headx = XCenter;
snake.heady = YCenter;
snake.direction = 3; //向左
board[snake.headx][snake.heady] = 4; //蛇身在右边
board[snake.headx][snake.heady+1] = 4;
board[snake.headx][snake.heady+2] = 4;
snake.nailx = snake.headx;
snake.naily = snake.heady + 2;
snake.length = 3;
PlaySound(TEXT("a.wav"),0,SND_ASYNC | SND_LOOP); //播放背景音乐
for(int i = 0; i < M; ++i){
for(int j = 0; j < N; ++j){
BLACK_WHITE;
if(i == 0 || i == M - 1 || j == 0 || j == N - 1)
cout<<"█";
else
cout<<" ";
}
cout<<endl;
}
popFood(); //弹出食物
printScore(); //打印积分
//打印提示
gotoxy(M + 5, 0);
BLACK_GREEN;
cout<<"\tw(↑)\n\n";
cout<<"a(←)\t\td(→)\tp(暂停)\n\n";
cout<<"\ts(↓)";
}
803

被折叠的 条评论
为什么被折叠?



