更新内容:1、解决了变向延迟问题。
2、解决了帮助界面信息显示不全问题。
3、解决了道具有时未刷新问题。
4、设置了欢迎界面。
5、为蛇设置了吐舌头功能。
6、按与前进方向相反的键不会导致死亡,但是会使其无效化。
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
/*=========================================================================================================*/
#define LEN 30
#define WID 24
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define WAIT_TIME 30000
/*=========================================================================================================*/
int snake_direction = LEFT;
int snake_length = 3;
int Score = 0;
int Lv = 1;
int Scene = 1;
int num = 0;
int Speed = 100;
int Now_time;
int flag1 = 1;
bool step_c = false;
bool alive = true;
bool eatup = false;
bool ispause = false;
bool ismagic = false;
bool istongue = false;
/*=========================================================================================================*/
//光标相关
void Set_Cursor_To(int x, int y);
//蛇相关
void direction_snake();
void flag_snake();
void draw_snake();
void eraser_snake();
void tongue_snake();
void eraser_tongue();
//食物相关
void product_food();
void product_barriers(int i);
void product_magic();
void eraser_barriers();
void draw_barriers();
void draw_magic();
//环境相关
void welcome();
void draw_boundary();
void draw_info();
//控制相关
void Game_Over();
void initialize();
void Lv_system();
void Help();
void Chose_Scene();
/*=========================================================================================================*/
//光标相关
HANDLE handle_console = GetStdHandle(STD_OUTPUT_HANDLE);
//设置光标位置
void Set_Cursor_To(int x, int y)
{
COORD position = { x, y };
SetConsoleCursorPosition(handle_console, position);
}
/*=========================================================================================================*/
//蛇相关
int snake[LEN][WID] = { 0 }; //全地图标识数组
//检测移动方向
void direction_snake()
{
if (kbhit())
{
int ch = getch();
if(ch == -32||ch == 0||ch == 224)
{
ch = getch();
}
switch (ch)
{
case 'p': ispause = true;break;
case 'q': exit(0);break;
case 'h': Help();break;
case 'c': Chose_Scene();step_c = true;break;
case ',': Speed-=10;break;
case '.': Speed+=10;break;
case ' ': istongue = true;break;
case UP: if(snake_direction != DOWN)snake_direction = UP; break;
case DOWN: if(snake_direction != UP)snake_direction = DOWN; break;
case LEFT: if(snake_direction != RIGHT)snake_direction = LEFT; break;
case RIGHT: if(snake_direction != LEFT)snake_direction = RIGHT;break;
default: break;
}
ch = 0;
}
if(ispause == false)
{
eraser_snake();
flag_snake();
draw_snake();
tongue_snake();
istongue = false;
}
}
//标记蛇
void flag_snake()
{
int Snake_ix, Snake_iy;
for (int x = 0; x < LEN; x++)
for (int y = 0; y < WID; y++)
{
if (snake[x][y] == 1)//记录蛇头Snake_ix/iy
{
switch (snake_direction)
{
case UP:Snake_ix = x; Snake_iy = y - 1; break;
case DOWN:Snake_ix = x; Snake_iy = y + 1; break;
case LEFT:Snake_ix = x-1; Snake_iy = y; break;
case RIGHT:Snake_ix = x+1; Snake_iy = y; break;
default: break;
}
if ((snake[Snake_ix][Snake_iy] == -3)||(snake[Snake_ix][Snake_iy] == -2))//检查移动后头坐标是否满足规则
{
alive = false;
}
if (snake[Snake_ix][Snake_iy] > 0)//检查移动后头位置是否满足规则
{
alive = false;
}
if (snake[Snake_ix][Snake_iy] == -1)
{
snake_length++;
Score += 10 * (1 + 0.5*Lv);
Lv_system();
eatup = true;
}
if (snake[Snake_ix][Snake_iy] == -10)
{
Lv++;
Set_Cursor_To(25,12);
printf("Lv Up! Lv:%d",Lv);
Sleep(1000);
system("cls");
draw_boundary();
draw_barriers();
draw_magic();
ismagic = false;
}
if (snake[Snake_ix][Snake_iy] == -11)
{
Score += 20;
Lv_system();
ismagic = false;
}
if (snake[Snake_ix][Snake_iy] == -12)
{
Score += 40;
Lv_system();
ismagic = false;
}
if (snake[Snake_ix][Snake_iy] == -13)
{
Score += 80;
Lv_system();
ismagic = false;
}
if (snake[Snake_ix][Snake_iy] == -14)
{
Score += 100;
Lv_system();
ismagic = false;
}
}
if (snake[x][y] == snake_length)//必要时清除蛇尾
{
snake[x][y] = 0;
}
if (snake[x][y] > 0)//对蛇身进行编号
{
snake[x][y] += 1;
}
}
snake[Snake_ix][Snake_iy] = 1;
}
//画蛇
void draw_snake()
{
for (int i = 0; i < LEN;i++)
for (int j = 0; j < WID;j++)
{
if (snake[i][j]>0 &&snake[i][j]<800)
{
Set_Cursor_To(2 * i, j);
printf("■");
}
if(snake[i][j] == -1)
{
Set_Cursor_To(2 * i, j);
printf("★");
}
}
}
//除尾
void eraser_snake()
{
for (int i = 0; i < LEN;i++)
for (int j = 0; j < WID; j++)
{
if (snake[i][j] == snake_length)
{
Set_Cursor_To(2 * i, j);
printf(" ");
}
}
}
//吐舌
void tongue_snake()
{
int tongue_ix,tongue_iy;
if(istongue == true)
{
for (int x = 0; x < LEN; x++)
for (int y = 0; y < WID; y++)
{
if (snake[x][y] == 1)
{
switch (snake_direction)
{
case UP: tongue_ix = x; tongue_iy = y - 1; break;
case DOWN: tongue_ix = x; tongue_iy = y + 1; break;
case LEFT: tongue_ix = x - 1; tongue_iy = y; break;
case RIGHT: tongue_ix = x + 1; tongue_iy = y; break;
default: break;
}
}
}
if( (snake[tongue_ix][tongue_iy] == 0 ) || (snake[tongue_ix][tongue_iy] == -1) || (snake[tongue_ix][tongue_iy] == -10)|| (snake[tongue_ix][tongue_iy] == -11)|| (snake[tongue_ix][tongue_iy] == -12)|| (snake[tongue_ix][tongue_iy] == -13)|| (snake[tongue_ix][tongue_iy] == -14))
{
Set_Cursor_To(2*tongue_ix,tongue_iy);
printf("〓");
}
if (snake[tongue_ix][tongue_iy] == -1)
{
snake_length++;
Score += 10 * (1 + 0.5*Lv);
Lv_system();
eatup = true;
snake[tongue_ix][tongue_iy] = -20;
}
if (snake[tongue_ix][tongue_iy] == -10)
{
Lv++;
Set_Cursor_To(25,12);
printf("Lv Up! Lv:%d",Lv);
Sleep(1000);
system("cls");
draw_boundary();
draw_barriers();
draw_magic();
ismagic = false;
snake[tongue_ix][tongue_iy] = -20;
}
if (snake[tongue_ix][tongue_iy] == -11)
{
Score += 20;
Lv_system();
ismagic = false;
snake[tongue_ix][tongue_iy] = -20;
}
if (snake[tongue_ix][tongue_iy] == -12)
{
Score += 40;
Lv_system();
ismagic = false;
snake[tongue_ix][tongue_iy] = -20;
}
if (snake[tongue_ix][tongue_iy] == -13)
{
Score += 80;
Lv_system();
ismagic = false;
snake[tongue_ix][tongue_iy] = -20;
}
if (snake[tongue_ix][tongue_iy] == -14)
{
Score += 100;
Lv_system();
ismagic = false;
snake[tongue_ix][tongue_iy] = -20;
}
if (snake[tongue_ix][tongue_iy] == 0)
{
snake[tongue_ix][tongue_iy] = -20;
}
}
}
//擦舌
void eraser_tongue()
{
for (int i = 0; i < LEN;i++)
for (int j = 0; j < WID; j++)
{
if (snake[i][j] == -20)
{
Set_Cursor_To(2 * i, j);
printf(" ");
snake[i][j] = 0;
}
}
}
/*=========================================================================================================*/
//食物相关
//生产食物
void product_food()
{
int food_ix, food_iy;
food_ix = rand() % LEN;
food_iy = rand() % WID;
while (snake[food_ix][food_iy] != 0)
{
food_ix = rand() % LEN;
food_iy = rand() % WID;
}
snake[food_ix][food_iy] = -1;
Set_Cursor_To(2 * food_ix, food_iy);
printf("★");
eatup = false;
}
//生成障碍
void product_barriers(int i)
{
int barrier_ix,barrier_iy;
for(;i>0;i--)
{
do
{
barrier_ix = rand()%LEN;
barrier_iy = rand()%WID;
}while(snake[barrier_ix][barrier_iy]!=0);
snake[barrier_ix][barrier_iy] = 10000;
Set_Cursor_To(2*barrier_ix,barrier_iy);
printf("χ");
}
}
//清除障碍
void eraser_barriers()
{
for (int i = 0; i < LEN;i++)
for (int j = 0; j < WID; j++)
{
if (snake[i][j] == 10000)
{
Set_Cursor_To(2 * i, j);
printf(" ");
}
}
}
//画障碍
void draw_barriers()
{
for (int i = 0; i < LEN;i++)
for (int j = 0; j < WID; j++)
{
if (snake[i][j] >= 10000)
{
Set_Cursor_To(2 * i, j);
printf("χ");
}
}
}
//生产道具
void product_magic()
{
int magic_ix,magic_iy;
if(Score*11%6 == 3)
{
do
{
magic_ix = rand()%LEN;
magic_iy = rand()%WID;
}while(snake[magic_ix][magic_iy]!=0);
snake[magic_ix][magic_iy] = -rand()%4 - 10;
ismagic = true;
}
}
//画道具
void draw_magic()
{
for (int i = 0; i < LEN;i++)
for (int j = 0; j < WID; j++)
{
if (snake[i][j] == -10)
{
Set_Cursor_To(2 * i, j);
printf("№");
}
if (snake[i][j] == -11)
{
Set_Cursor_To(2 * i, j);
printf("Ⅰ");
}
if (snake[i][j] == -12)
{
Set_Cursor_To(2 * i, j);
printf("Ⅱ");
}
if (snake[i][j] == -13)
{
Set_Cursor_To(2 * i, j);
printf("Ⅲ");
}
if (snake[i][j] == -14)
{
Set_Cursor_To(2 * i, j);
printf("Ⅳ");
}
}
}
/*=========================================================================================================*/
//环境相关
//欢迎界面
void welcome()
{
Set_Cursor_To(0,2);
printf(" _____ __ _ ___ _ _ _____ \n");
printf(" / ___/ | \\ | | / | | | / / | ____| \n");
printf(" | |___ | \\| | / /| | | |/ / | |__ \n");
printf(" \\___ \\ | |\\ | / /_| | | |\\ \\ | __| \n");
printf(" ___| | | | \\ | / __ | | | \\ \\ | |___ \n");
printf(" /_____/ |_| \\_| /_/ |_| |_| \\_\\ |_____| \n");
Set_Cursor_To(0,9);
printf(" /^\\/^\\ \n");
printf(" _|_O| O| \n");
printf(" \\/ /~ \\_/ \\ \ \n");
printf(" \\__|__________/ \\ \\ \n");
printf(" \\________ \\ \\\\ \n");
printf(" `\\ \\ \\ \\ \n");
printf(" --* | | ___ \\ \\ \n");
printf(" /| / / _-~ ~-_ _/ | \n");
printf(" / ( ( _-~ __ ~-_-~ / \n");
printf(" hybest__/ \\ ~-__-~ _-~ ~-_ _-~ \n");
printf(" ~-_ _-~ ~-__-~ \n");
printf(" ~-___-~ \n\n");
printf(" /// Press any key to continue. /// ");
Set_Cursor_To(52,4);
printf("Snake: My name is hybest.");
Set_Cursor_To(52,6);
printf("Snake:I want to catch stars.");
Set_Cursor_To(52,8);
printf("Snake:But I can't do that.");
Set_Cursor_To(52,10);
printf("Snake:Can you help me?");
Set_Cursor_To(55,20);
printf("[Greedy Snake V2.2]");
Set_Cursor_To(55,22);
printf(" --Bit_Percy");
system("pause>nul");
}
//边界
void draw_boundary()
{
for (int i = 0; i < LEN; i++)//上下边界
{
Set_Cursor_To(2 * i, 0);
printf("--");
Set_Cursor_To(2 * i, WID - 1);
printf("--");
snake[i][0] = -2;
snake[i][WID - 1] = -2;
}
for (int i = 0; i < WID; i++)
{
Set_Cursor_To(0, i);
printf("|");
Set_Cursor_To(2*LEN - 1, i);
printf("|");
snake[0][i] = -3;
snake[LEN-1][i] = -3;
}
}
//信息
void draw_info()
{
Set_Cursor_To(63,1);
printf("'H':Help.");
Set_Cursor_To(63,3);
printf("'P':Pause.");
Set_Cursor_To(63,5);
printf("'Q':Quit.");
Set_Cursor_To(63,7);
printf("'C':Chose Scenes.");
Set_Cursor_To(63,9);
printf("',':Speed Up.");
Set_Cursor_To(63,11);
printf("'.':Speed Down.");
Set_Cursor_To(63,13);
printf("'空格':Tongue.");
Set_Cursor_To(63,19);
printf("Speed:\t0.%03ds",Speed);
Set_Cursor_To(63,20);
printf("Score:\t%d",Score);
Set_Cursor_To(63,21);
printf("Lv:\t%d",Lv);
Set_Cursor_To(63,22);
printf("Length:\t%d",snake_length);
Set_Cursor_To(63,23);
printf("Barriers:%d",num);
}
/*=========================================================================================================*/
//控制相关
//判定游戏结束
void Game_Over()
{
Set_Cursor_To(25, 12);
printf("~~傻屌,你死了~~");
Set_Cursor_To(21, 13);
printf("Press any key to replay.");
system("pause > nul");
}
//初始化
void initialize()
{
Score = 0;
Lv = 1;
snake_length = 3;
for (int x = 0; x < LEN; x++)
for (int y = 0; y < WID; y++)
{
snake[x][y] = 0;
}
draw_boundary();
draw_info();
for (int i = 0; i < snake_length; i++) //初始化蛇
{
snake[i + 12][12] = i + 1;
}
draw_snake();
product_food();
alive = true;
ispause = false;
snake_direction = LEFT;
ismagic = false;
istongue = false;
}
//等级系统
void Lv_system()
{
if(Score > (Lv+1)*(Lv)*20)
{
Lv++;
Set_Cursor_To(25,12);
printf("Lv Up! Lv:%d",Lv);
Sleep(1000);
system("cls");
draw_boundary();
draw_barriers();
draw_magic();
}
}
//帮助界面
void Help()
{
system("cls");
Set_Cursor_To(10,2);
printf("It's a game produced by Bit[CS2013]_Percy.");
Set_Cursor_To(10,4);
printf("Game's name: Gluttonous Snake.");
Set_Cursor_To(10,6);
printf("Game's version: V2.2.");
Set_Cursor_To(10,8);
printf("Game's operation: you can press'Up'、'Down'、'Left'、\n\t\t'Right' to control the snake to eat the star.");
Set_Cursor_To(10,11);
printf("When the snake eatup the star,the score will increase.\n\t\tAnd your level will increase,too.");
Set_Cursor_To(10,14);
printf("Try to press ' ' ,you will find a tongue!!wakaka!!");
Set_Cursor_To(10,15);
printf("Oh,I nearly foget to say that you will be much longer\n\t\t when you eat the star.");
Set_Cursor_To(10,18);
printf("■:The body of the snake.");
Set_Cursor_To(40,18);
printf("№:Lv UP.");
Set_Cursor_To(55,18);
printf("χ:The barriers.");
Set_Cursor_To(10,20);
printf("Ⅰ:20 scores.");
Set_Cursor_To(25,20);
printf("Ⅱ:40 scores.");
Set_Cursor_To(40,20);
printf("Ⅲ:80 scores.");
Set_Cursor_To(55,20);
printf("Ⅳ:100 scores.");
Set_Cursor_To(10,22);
printf("★:The star which can increase your length and scores.");
system("pause > nul");
system("cls");
draw_boundary();
draw_barriers();
draw_magic();
}
//场景选择
void Chose_Scene()
{
system("cls");
Set_Cursor_To(10,4);
printf("Please chose a scene you like.");
Set_Cursor_To(10,6);
printf("1、No barriers.");
Set_Cursor_To(10,8);
printf("2、Barriers.");
switch(getch())
{
case '1': Scene = 1;break;
case '2': Scene = 2;break;
default : break;
}
if(Scene == 2)
{
Set_Cursor_To(10,10);
printf("Please input the number of barriers:");
scanf("%d",&num);
}
system("cls");
draw_boundary();
}
/*=========================================================================================================*/
int main()
{
system("title Bit[CS2013]_Percy_贪吃蛇V2.2");
welcome();
Chose_Scene();
srand((unsigned)time(NULL));
Now_time = clock();
while(1)
{
if(Scene == 1)
{
flag1 = 0;
while (1)
{
system("cls");
initialize();
while (1)
{
if (alive == false)
{
Game_Over();
break;
}
else
{
if (eatup == true)
{
product_food();
}
if(ispause == true)
{
system("pause > nul");
ispause = false;
}
if(ismagic == false)
{
product_magic();
draw_magic();
}
direction_snake();
if(Scene != 1)
{
break;
}
draw_info();
Sleep(Speed);
eraser_tongue();
}
}
if(Scene != 1)
{
break;
}
}
}
else
{
for(int times = 0;;times++)
{
system("cls");
initialize();
if(times != 0 || flag1 == 1)
product_barriers(num);
while (1)
{
if (alive == false)
{
Game_Over();
break;
}
else
{
if (eatup == true)
{
product_food();
}
if(ispause == true)
{
system("pause > nul");
ispause = false;
}
if(ismagic == false)
{
product_magic();
draw_magic();
}
direction_snake();
if(Scene != 2)
{
break;
}
else
{
if(step_c == true)
{
eraser_barriers();
product_barriers(num);
step_c = false;
}
}
draw_info();
Sleep(Speed);
eraser_tongue();
}
}
if(Scene != 2)
{
break;
}
}
}
}
return 0;
}
/*=========================================================================================================*/