我在網上看別人寫的程式后,用visual studio 2019重新撰寫了一邊,撰寫完成后,程式可以運行,食物也會生成,也可以吃食物,但是蛇無法通過按鍵移動,只會按照初始方向移動,一旦按鍵蛇就會停止移動,但程式不會停止,且按鍵后會右邊的顯示視窗列印出相應的字符,求大神指導一下。以下是程式代碼:由于發帖時,文章不能帶有黑色方塊,所以我將其替換為BLACK,請運行時改回來。
#pragma warning(disable:4996)
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#define INFO_X 100 //提示資訊區橫坐標
#define WIDE 50 //游戲界面寬度
#define HIGH 36 //游戲界面高度
#define LEVELUP 5 //升級所需的食物個數
struct Snakes
{
int X[100]; //蛇身的橫坐標
int Y[100]; //蛇身的縱坐標
int length; //蛇的長度
int speed; //蛇移動速度
int count; //蛇吃到食物個數
};
struct Food
{
int X; //食物橫坐標
int Y; //食物縱坐標
};
/* 定義全域變數 */
unsigned char key;
int i, j, k, end[2]; //i,j,k為回圈變數,end陣列用來做蛇尾坐標的中間變數
struct Snakes s, * snake = &s; //定義蛇的結構體指標并指向蛇的結構體
struct Food f, * food = &f; //定義食物結構體指標并指向食物結構體
/* 食物結構 */
/* 蛇身結構 */
void Setcolor(int forcolor, int bakcolor)
{
/*
0=黑色, 8=灰色,
1=藍色, 9=淡藍色,
2=綠色, A=淡綠色,
3=湖藍色, B=淡淺綠色,
4=紅色, C=淡紅色,
5=紫色, D=淡紫色,
6=黃色, E=淡黃色,
7=白色, F=亮白色
*/
HANDLE winhandle;
winhandle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(winhandle, forcolor + bakcolor * 0x10);
}
/* 設定游標位置 */
void SetPos(int x, int y)
{
HANDLE winhandle;
COORD pos = { x,y };
winhandle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(winhandle, pos);
}
/* 顯示提示和選單 */
void ShowMenu()
{
SetPos(INFO_X + 17, 1);
Setcolor(9, 0);
printf("歡迎來到貪吃蛇!");
SetPos(INFO_X + 17, 5);
printf("Esc 退出游戲");
SetPos(INFO_X + 17, 7);
printf("空格 暫停游戲");
SetPos(INFO_X + 17, 9);
printf("↑↓←→ 控制蛇頭方向");
SetPos(INFO_X + 17, 11);
printf("長按方向鍵加速");
SetPos(INFO_X + 17, 15);
printf("游戲得分:%d", snake->count * 100);
SetPos(INFO_X + 17, 17);
printf("當前級別:%d", snake->count / LEVELUP + 1);
SetPos(INFO_X + 17, 19);
printf("當前速度:%d", snake->speed);
SetPos(INFO_X + 17, 21);
printf("吃到食物:%d", snake->count);
SetPos(INFO_X + 17, 23);
printf("食物坐標:%-2d,%-2d", food->X, food->Y);
}
/* 游戲結束 */
void GameOver()
{
system("cls");
SetPos(WIDE, HIGH / 2);
printf("游戲結束!");
ShowMenu();
SetPos(0, HIGH);
exit(0);
getchar();
}
/* 設定控制臺標題和大小 */
void SetTitle()
{
//設定控制臺視窗大小
system("mode con cols=150 lines=40");
//設定控制臺標題
SetConsoleTitle("貪吃蛇");
}
/* 設定控制臺顏色 */
void Cleanlin(int x, int y)
{
SetPos(x, y);
for (i = 0;i < 50;i++)
{
printf(" ");
}
}
/* 設定游戲界面 */
void Table()
{
for (i = 0;i < HIGH;i++)
{
if (i == 0 || i == HIGH - 1)
{
for (k = 0;k < WIDE * 2 - 1;k += 2)
{
SetPos(k, i);
printf("BLACK");
}
continue;
}
else
{
for (j = 0;j < WIDE * 2 - 1;j += 2)
{
if (j == 0 || j == WIDE * 2 - 2)
{
SetPos(j, i);
printf("BLACK");
}
}
}
}
}
/* 顯示提示和選單 */
void init_snake()
{
snake->X[0] = WIDE; //初始化蛇的橫坐標
snake->Y[0] = HIGH / 2; //初始化蛇的豎坐標
end[0] = *snake->X; //記住蛇尾橫坐標
end[1] = *snake->Y; //記住蛇尾縱坐標
snake->speed = 300; //初始化蛇的速度為300ms
snake->length = 3; //初始化蛇的長度為3節
snake->count = 0; //初始化蛇吃的個數為0
for (i = 1;i < snake->length;i++)
{
/* 依次得到蛇身、蛇頭的坐標 */
snake->X[i] = snake->X[i - 1] + 2;
snake->Y[i] = snake->Y[i - 1];
}
}
/* 移動蛇身 */
void move_snake()
{
SetPos(snake->X[0], snake->Y[0]);
printf(" "); /* 清除蛇尾*/
for (i = 1;i < snake->length;i++)
{/* 后一節的坐標依次取代前一節的坐標 */
snake->X[i - 1] = snake->X[i];
snake->Y[i - 1] = snake->Y[i];
}
}
/* 顯示蛇身 */
void print_snake()
{
for (i = 0;i < snake->length;i++)
{
SetPos(snake->X[i], snake->Y[i]);
if (i == 0)
{
printf("^"); //列印蛇尾
}
else if (i == snake->length - 1)
{
printf("¤"); //列印蛇頭
}
else
{
printf("⊙"); //列印蛇身
}
}
}
/* 產生食物 */
void get_food()
{
srand((unsigned)time(NULL));
while (1)
{
food->X = ((rand() % (WIDE - 3)) + 1) * 2;
food->Y = (rand() % (HIGH - 2)) + 1;
for (i = 0;i < snake->length;i++)
{
if (food->X == snake->X[i] && food->Y == snake->Y[i])
{
break;
}
}
if (i == snake->length)
{
SetPos(food->X, food->Y);
Setcolor(10, 0);
printf("⊙");
Setcolor(9, 0);
break;
}
}
}
/* 吃食物 */
void eat_food()
{
if (snake->X[snake->length - 1] == food->X && snake->Y[snake->length - 1] == food->Y)
{/*如果蛇頭坐標和食物坐標相同,吃掉食物,身長加1。*/
snake->length++;
for (i = snake->length - 1;i > 0;i--)
{/* 蛇后節坐標依次賦值給蛇前一節的坐標,依次得到蛇身及蛇頭的坐標 */
snake->X[i] = snake->X[i - 1];
snake->Y[i] = snake->Y[i - 1];
}
snake->X[0] = end[0];
snake->Y[0] = end[1];
get_food();
snake->count++;
if (snake->count % LEVELUP == 0)
{/* 當蛇吃LEVELUP個食物時,速度加快20毫秒并且升一級 */
snake->speed -= 20;
}
}
}
/* 穿墻 */
void through_wall()
{ /* 當蛇碰到移動方向的邊界時,蛇身穿過邊界從相對的另一邊出現。*/
if (key == 72 && snake->Y[snake->length - 1] == 0)//上鍵
{
snake->Y[snake->length - 1] = HIGH - 2;
}
if (key == 77 && snake->X[snake->length - 1] == WIDE * 2 - 2)//右鍵
{
snake->X[snake->length - 1] = 2;
}
if (key == 80 && snake->Y[snake->length - 1] == HIGH - 1)//下鍵
{
snake->Y[snake->length - 1] = 1;
}
if (key == 75 && snake->X[snake->length - 1] == 0)//左鍵
{
snake->X[snake->length - 1] = (WIDE - 2) * 2;
}
}
/* 判斷蛇的死亡 */
void die()
{
for (i = 0;i < snake->length - 1;i++)
{ /* 當蛇頭碰到蛇身,蛇死亡。 */
if (snake->X[snake->length - 1] == snake->X[i] && snake->Y[snake->length - 1] == snake->Y[i])
{
GameOver();
}
}
}
/* 得到用戶輸入 */
void GetKey()
{
switch (key)
{
case 27://Esc鍵--結束游戲
{
GameOver();
break;
}
case 32://空格鍵--暫停游戲
{
SetPos(INFO_X + 13, HIGH - 5);
Setcolor(5, 0);
Sleep(500);
printf("游戲暫停,按方向鍵繼續!");
Setcolor(9, 0);
SetPos(0, HIGH);
break;
}
case 72://上鍵
{
move_snake();
snake->Y[snake->length - 1] -= 1;
break;
}
case 77://右鍵
{
move_snake();
snake->X[snake->length - 1] += 2;
break;
}
case 80://下鍵
{
move_snake();
snake->Y[snake->length - 1] += 1;
break;
}
case 75://左鍵
{
move_snake();
snake->X[snake->length - 1] -= 2;
break;
}
}
}
/* 開始游戲 */
void GameStar()
{
key = 77; //初始化蛇向右移動
SetTitle(); //設定控制臺標題和大小
Setcolor(4, 0);
Table(); //初始化游戲界面
init_snake(); //初始化蛇身
get_food(); //初始化第一個食物
while (1)
{
Cleanlin(INFO_X, HIGH - 5);
ShowMenu();
end[0] = snake->X[0];
end[1] = snake->Y[0];
j = 0;
if (_kbhit())
{/* 判斷是否按下鍵盤,如果按下,ch接收鍵盤輸入 */
key = getchar();
if (_kbhit())
{/* 如果長按鍵盤,則加速 */
Sleep(20);
j = 1;
}
}
GetKey();
through_wall();
eat_food();
print_snake();
die();
if (j == 0)
{
Sleep(snake->speed); //延遲時間
}
else
{
Sleep(10);
}
}
}
int main()
{
GameStar();
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/156959.html
標籤:C語言
上一篇:對某班學生成績排序。
下一篇:逗號運算式求最后一個式子的值
