最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

用c++寫控制臺貪吃蛇游戲完整步驟

 更新時間:2025年12月05日 09:46:50   作者:fish_xk  
用C++制作貪吃蛇游戲是一個經(jīng)典的編程練習,它涉及多個方面的編程知識,包括數(shù)據(jù)結構、圖形界面、事件處理等,這篇文章主要介紹了用c++寫控制臺貪吃蛇游戲的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

效果圖

要使用的東西。

1.鏈表,2.結構體,3.系統(tǒng)操作。

創(chuàng)建界面

了解界面的生成和輸入

先本地化環(huán)境用于在控制臺輸出中文setlocale(LC_ALL, "");要包含#include <locale.h>

要使用 system函數(shù),要包括頭文件windows.h。

void cj() {
    setlocale(LC_ALL, "");  // 設置本地化環(huán)境
    system("mode con cols=100 lines=40");  // 調(diào)整控制臺窗口尺寸
    system("pause");  // 防止窗口自動關閉
}

查看光標發(fā)現(xiàn)光標的長寬不匹配,調(diào)整cols和lines,來判斷那個是長的。

發(fā)現(xiàn)調(diào)整cols后長變了所以cols是窗口的長。

調(diào)整后發(fā)現(xiàn)2個長等于一個寬,所以我們設置時要設置2的倍數(shù)長

設置我們的游戲界面為25*25,加上邊框長乘2,54*27,再加上提示,36長。湊個整

100*30.

發(fā)現(xiàn)輸出都從左上角開始,所以需要定位光標位置來輸出,后續(xù)的內(nèi)容也要運用光標的定位,所以我們要定義一個函數(shù)來表示光標定位。

HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);

// 獲取控制臺輸出句柄
// 使用GetStdHandle(STD_OUTPUT_HANDLE)獲取標準輸出設備句柄

COORD pos = {x, y};  // 定義光標位置坐標(左上角為原點(0,0))

SetConsoleCursorPosition(houtput, pos);  // 將光標定位到指定坐標

void dw(int x, int y) {
    HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos = {x, y};
    SetConsoleCursorPosition(houtput, pos);
}

構建歡迎界面,(簡介版)

dw(40, 15);
wprintf(L"歡迎來到貪吃蛇游戲");//用wprintf來輸出寬字符,L表示后面的是寬字符,如中文等。
dw(40, 16);
system("pause");

到下一個界面我們要清空當前界面。

system("cls");來清空界面

system("cls");  // 清屏操作
dw(40, 16);     // 調(diào)用dw函數(shù),參數(shù)為40和16
system("pause");// 暫停程序執(zhí)行

下一步設置我們的提示

按W.S.A.D移動,F(xiàn)4加速,F(xiàn)5減速,space暫停,Esc退出。

定位要的位置輸出數(shù)據(jù),調(diào)整位置讓它 看起居中。

dw(24, 15);
wprintf(L"按W.S.A.D移動,F(xiàn)4加速,F(xiàn)5減速,space暫停,Esc退出。");
dw(40, 16);
printf("加速能得到更高的分數(shù)");
dw(40, 17);
system("pause");

構建游戲界面

構建蛇的活動范圍墻

發(fā)現(xiàn)高度不夠擴高一點到40;下移墻,在頂上標識提示詞表明游戲界面。

system("cls");
int i = 0, j = 0;
for (i = 3; i < 30; i++)
{
    dw(0, i);
    for (j = 0; j < 27; j++) {
        if (i == 3 || i == 29 || j == 0 || j == 26)
            wprintf(L"墻");
        else
            wprintf(L"  ");
    }
    printf("\n");
}
dw(14, 1);
wprintf(L"游戲界面");
dw(0, 32);
system("pause");

右邊加入提示詞

dw(60, 6);
wprintf(L"時間:%.2f", sj);
dw(60, 10);
wprintf(L"不能撞墻,不能碰到自己");
dw(60, 11);
wprintf(L"按W.S.A.D移動\n");
dw(60, 12);
wprintf(L"F4加速,F5減速\n");
dw(60, 13);
wprintf(L"space暫停,Esc退出");
dw(60, 14);
wprintf(L"fish_xk制作");

發(fā)現(xiàn)函數(shù)太長了,分別封裝成函數(shù)。

float sj = 0;
void dw(int x, int y) {
    HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos = { x,y };
    SetConsoleCursorPosition(houtput, pos);
}
void help() {
    dw(60, 6);
    wprintf(L"時間:%.2f", sj);
    dw(60, 10);
    wprintf(L"不能撞墻,不能碰到自己");
    dw(60, 11);
    wprintf(L"按W.S.A.D移動\n");
    dw(60, 12);
    wprintf(L"F4加速,F5減速\n");
    dw(60, 13);
    wprintf(L"space暫停,Esc退出");
    dw(60, 14);
    wprintf(L"fish_xk制作");
    system("pause");
}
void ks() {
    setlocale(LC_ALL, "");
    system("mode con cols=100 lines=40");
    dw(40, 15);
    wprintf(L"歡迎來到貪吃蛇游戲");
    dw(40, 16);
    system("pause");
    system("cls");
}
void zj() {
    dw(24, 15);
    wprintf(L"按W.S.A.D移動,F(xiàn)4加速,F(xiàn)5減速,space暫停,Esc退出。");
    dw(40, 16);
    printf("加速能得到更高的分數(shù)");
    dw(40, 17);
    system("pause");
    system("cls");
}
void yxjm() {
int i = 0, j = 0;
    for (i = 3; i < 30; i++)
    {
        dw(0, i);
        for (j = 0; j < 27; j++) {
            if (i == 3 || i == 29 || j == 0 || j == 26)
                wprintf(L"墻");
            else
                wprintf(L"  ");
        }
        printf("\n");
    }
    dw(22, 1);
    wprintf(L"游戲界面");
    dw(0, 32);
}
void cj() {
    ks();
    zj();
    yxjm();
    help();
}

這樣就完成了所有的界面的制作。

游戲本體

創(chuàng)建蛇

蛇由一個個節(jié)點組成,用鏈表來創(chuàng)建。重命名一下方便使用

typedef struct snakebody {
    struct tcs* next;
    int x;
    int y;
}snake,st;

有蛇,有果子,有速度。用一個結構體來表示。

蛇可以用頭節(jié)點來表示。

果可以看作一個在外的蛇身。

typedef struct tcs{
    snake* head;
    int v;
    snake* guo;
}tcs;

還要有狀態(tài),方向,總分數(shù),單個果子的權重。

typedef struct snakebody{
    struct tcs* next;
    int x;
    int y;
}snake;
enum gamezt {
    OK=1,
    FAIL,
    DIE_BYWALL,
    DIE_BYSELF
};
enum snakefx {
    UP = 1,
    DOWN,
    LEFT,
    RIGHT
};
typedef struct tcs{
    snake* head;//蛇
    snake* guo;//果
    int v;//速度
    enum gamezt zt;//狀態(tài)
    enum snakefx fx;//方向
    int food_weight;//單個分數(shù)
    int score;//總分數(shù)
}tcs;

初始化一下蛇的身體。

尾插鏈表來初始蛇身

void push(snake**ps,int x,int y) {//插入蛇的節(jié)點
    snake* news = (snake*)malloc(sizeof(snake));//開辟節(jié)點
    news->next = NULL;
    news->x = x;
    news->y = y;
    if (*ps == NULL) {
        *ps = news;
    }
    else
    {
        snake* pos = *ps;
        while (pos->next) {//鏈接到末尾
            pos = pos->next;
        }
        pos->next = news;
    }
}

snake* body = (snake*)malloc(sizeof(snake));
body = NULL;
int i;
for (i = 22; i < 27; i = i + 1) {
    push(&body,22+(i-22)*2, 16);
}
ps->head = body;
print(ps);

void print(snake*ps) {//打印蛇
	assert(ps);
	snake* cur = ps;
	while (cur) {//遍歷鏈表
		dw(cur->x, cur->y);
		wprintf(L"蛇");
		cur = cur->next;
	}
}
tcs* cjsnake() {//返回蛇的頭位置
	tcs*ps = (tcs*)malloc(sizeof(tcs));
	snake* body = (snake*)malloc(sizeof(snake));
	body = NULL;
	int i;
	for (i = 22; i < 27; i = i + 1) {//循環(huán)添加5個節(jié)點
		push(&body,22+(i-22)*2, 16);
	}
	ps->head = body;
	print(ps->head);//打印開始的蛇身
	cjguo(ps);
	ps->v = 200;
	ps->zt = OK;
	ps->fx = LEFE;
	ps->score = 0;
	ps->food_weight = 10;
	return ps;
}

下一步生成果子,要有隨機數(shù)要包含#include<time.h>

設置隨機數(shù)

srand(time(NULL))

void cjguo(tcs* ps) {
    snake* news = (snake*)malloc(sizeof(snake));
    news->next = NULL;
    snake* cur = ps->head;
    ag:
    news->x = (rand()%25+1+1)*2;//第一個+1是保證1到25,后一個+1,是不能是墻
    news->y = (rand() % 25 + 1+4 );
    cur = ps->head;
    while (cur){
        if (cur->x == news->x && cur->y == news->y)//如果和蛇重疊重新生成。
            goto ag;
        cur = cur->next;
    }
    ps->guo = news;
    dw(news->x, news->y);
    wprintf(L"果");//打印果的位置
}

設置其他數(shù)據(jù)

    ps->v = 200;//速度
    ps->zt = OK;//狀態(tài)
    ps->fx = LEFT;//方向
    ps->score = 0;//成績
    ps->food_weight = 10;//每個果子的分數(shù)

創(chuàng)建完畢

蛇的行走

while (cur->zt == OK) {
dw(60, 6);
wprintf(L"時間:%.2f秒", sj);
dw(60, 8);
printf("得分:%d", cur->score);
dw(60, 9);
printf("食物分值:%d", cur->food_weight);
snakedong(cur);//行動的函數(shù)
sj+=cur->v/1000.0;//行動時間
Sleep(cur->v);//行動間隔
}

設置循環(huán)判斷游戲狀態(tài)??梢栽偌尤霑r間

設置程序的休息時間,來實現(xiàn)運動間隔。

要控制程序,需要讀取輸入信息,所以定義一個讀取的宏

#define KEY_PRESS(vk)   ((GetAsyncKeyState(vk)&1)?1:0)

讀取一個虛擬鍵盤值,判斷是否按過。

if (KEY_PRESS(0x53) && snake->fx != UP) {//識別W
	snake->fx = DOWN;
}
else if (KEY_PRESS(0x57) && snake->fx != DOWN) {//識別S
	snake->fx = UP;
}
else if (KEY_PRESS(0x41) && snake->fx != RIGHT) {//識別A
	snake->fx = LEFE;
}
else if (KEY_PRESS(0x44) && snake->fx != LEFE) {//識別B
	snake->fx = RIGHT;
}
else if (KEY_PRESS(VK_SPACE)) {//識別空格
	while (1) {
		Sleep(200);
		if (KEY_PRESS(VK_SPACE)) {//循環(huán)停止游戲
			break;
		}
	}
}
else if (KEY_PRESS(VK_ESCAPE)) {//識別ESC
	snake->zt = END_NORMAL;
}
else if (KEY_PRESS(VK_F4)) {//識別F4
	snake->v = snake->v - 10;
	snake->food_weight = snake->food_weight + 5;
}
else if (KEY_PRESS(VK_F5)) {//識別F5
	snake->v = snake->v + 10;
	snake->food_weight = snake->food_weight - 5;
}

加入一個全局變量防止加速過頭

根據(jù)蛇的方向來改變蛇的身體坐標

snake* toupush(snake*ps,int x,int y) {//插入頭部,到達的節(jié)點
	snake* news = (snake*)malloc(sizeof(snake));
	news->next = ps;
	news->x = x;
	news->y = y;
	dw(news->x, news->y);
	wprintf(L"蛇");
	ps = news;
	return ps;
}
snake* pop(snake* ps) {//沒吃到果子,刪除多出來的節(jié)點
	snake* tail = ps;
	while (tail->next->next) {
		tail = tail->next;
	}
	dw(tail->next->x, tail->next->y);
	wprintf(L"  ");
	free(tail->next);
	tail->next = NULL;
	return ps;
}
if (snake->fx == UP) {//向上
	snake->head=toupush(snake->head, snake->head->x, snake->head->y - 1);
}
else if (snake->fx == DOWN) {//向下
	snake->head=toupush(snake->head, snake->head->x, snake->head->y + 1);
}
else if (snake->fx == LEFE) {//向左
	snake->head=toupush(snake->head, snake->head->x-2, snake->head->y );
}
else if (snake->fx == RIGHT) {//向右
	snake->head=toupush(snake->head, snake->head->x+2, snake->head->y );
}
if (snake->head->x != snake->guo->x || snake->head->y != snake->guo->y)//是否吃到果子
	snake->head=pop(snake->head);//沒吃到,刪除尾節(jié)點
else {
	free(snake->guo);//釋放果子的節(jié)點
	snake->guo = NULL;
	cjguo(snake);//重新生成果子
	snake->score += snake->food_weight;//加分
}

吃到果子就不刪尾,分數(shù)加權重,沒吃到就刪尾。

編寫失敗條件。

if (snake->head->x == 0 || snake->head->x == 52 || snake->head->y == 4 || snake->head->y == 29)//到達墻體
	snake->zt = DIE_BYWALL;//改變狀態(tài)
st* self = snake->head->next;
	while (self) {//遍歷自身,看是否相交
		if (snake->head->x == self->x && snake->head->y == self->y)
			snake->zt = DIE_BYSELF;//如相交更新狀態(tài)
		self = self->next;
	}

結束后輸出分數(shù)

system("cls");
dw(40, 15);
if (cur->zt == DIE_BYSELF)
	wprintf(L"失敗于撞到自己");
if (cur->zt == DIE_BYWALL)
	wprintf(L"失敗于撞墻");
if (cur->zt == END_NORMAL)
	wprintf(L"正常退出");
dw(40, 16);
wprintf(L"你堅持的時間是%.2f秒", sj);
dw(40, 17);
wprintf(L"你的得分是%d",cur->score);

隱藏光標

void gbyc() {
	//獲取標準輸出設備的句柄;
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	//定義一個光標結構體
	CONSOLE_CURSOR_INFO cursor_info = { 0 };
	//獲取houtput句柄相關的控制臺上的光標信息,存放cursor_info
	GetConsoleCursorInfo(houtput, &cursor_info);
	//設置吧光標的占比
	cursor_info.bVisible = false;//光標消失
	//設置和houtput句柄相關的控制臺的光標信息
	SetConsoleCursorInfo(houtput, &cursor_info);
}
void ck() {
	//創(chuàng)建窗口
	setlocale(LC_ALL, "");
	COORD pos = { 0,0 };
	system("mode con cols=100 lines=40");
	system("title.貪吃蛇");
	gbyc();
	//打印開始界面
}

到這里已經(jīng)全部完成了。

總結

到此這篇關于用c++寫控制臺貪吃蛇游戲完整步驟的文章就介紹到這了,更多相關c++寫控制臺貪吃蛇內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

沂南县| 南安市| 盐山县| 乐业县| 巴林右旗| 且末县| 茌平县| 砚山县| 芷江| 磐石市| 农安县| 乌恰县| 科技| 共和县| 永福县| 上饶市| 黑河市| 泊头市| 云浮市| 乐安县| 乐平市| 吉木乃县| 安龙县| 东山县| 抚顺市| 三江| 攀枝花市| 新余市| 兰坪| 安溪县| 隆回县| 哈巴河县| 沂水县| 科尔| 长兴县| 略阳县| 东港市| 虞城县| 博罗县| 恭城| 东乌|