利用C/C++實(shí)現(xiàn)較完整貪吃蛇游戲
記得在大一時(shí)剛學(xué)習(xí)c/c++語言,學(xué)到一半突然想用這門語言做一些小游戲出來,首先想到的便是貪吃蛇。于是本人利用空余時(shí)間寫出了這么一個(gè)簡單的小游戲。
由于當(dāng)時(shí)的我還沒有能力構(gòu)造出用戶界面,故直接使用dos界面運(yùn)行。那么問題來了,如何讓一個(gè)字符在dos界面上自由移動(dòng)???對于這個(gè)問題我采用的解決方案是實(shí)現(xiàn)gotoxy函數(shù)來控制指針位置從而實(shí)現(xiàn)字符的移動(dòng)。那么我們就先來實(shí)現(xiàn)這個(gè)函數(shù)。
gotoxy 函數(shù)并非系統(tǒng)函數(shù),我將其儲(chǔ)存于 gotoxy.h 的頭文件中方便調(diào)用。
gotoxy.h
#include <windows.h>
void gotoxy(int x,int y)
{
COORD pos;
pos.X = x - 1;
pos.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
現(xiàn)在我們已經(jīng)能夠利用 gotoxy 函數(shù)對指針進(jìn)行控制,那么實(shí)現(xiàn)字符的移動(dòng)則只需將原來位置的字符清除,然后利用此函數(shù)移動(dòng)指針到想去的坐標(biāo)后打印字符即可。
在對此函數(shù)進(jìn)行測試的時(shí)候,我發(fā)現(xiàn)了一個(gè)重要的問題,因?yàn)榇a是一行一行的運(yùn)行,那么在等待我輸入方向的時(shí)候,其他代碼是無法執(zhí)行的,這意味這我的蛇只能是我給一下方向它移動(dòng)一下,那么該如何使得字符在等待我輸出方向的同時(shí)自行移動(dòng)呢???對于這個(gè)問題有兩個(gè)解決方案:一、創(chuàng)建線程(對于當(dāng)時(shí)的我來說線程還很陌生) 二、利用 kbhit() 非阻塞函數(shù)(百度一下,你就知道)。當(dāng)然我選擇的是第二個(gè)方案,再配合使用 getch() 函數(shù)即可完美實(shí)現(xiàn)方向的輸入。
該游戲的兩個(gè)難點(diǎn)都解決了,話不多說 ↓
(由于沒有涉及什么算法,加之年少,代碼顯得過于冗長)
這里主要運(yùn)用到的知識(shí)有這些:結(jié)構(gòu)體,srand(), rand(), kbhit(), getch(), Sleep().
/*******************http://blog.csdn.net/lcsy000**********************/
#include<iostream>
#include"gotoxy.h"
#include<windows.h>
#include<conio.h>
#include<time.h>
using namespace std;
char direction_a,direction_b; //方向a、b,用于方向的限制
int scores,num,fool_x,fool_y,speed=100; //得分、num用于蛇身起步、食物x坐標(biāo)、食物y坐標(biāo)
bool end; //結(jié)束標(biāo)記
struct node //蛇身結(jié)點(diǎn)
{
int x,y;
node *next;
}*head=NULL,*p,*tail;
void init(); //初始化開始界面
void start(); //游戲開始入場
void init_snake(); //初始化蛇身
void delete_snake(); //刪除蛇身
void control(); //方向控制
void move(); //蛇身移動(dòng)
void limit(); //方向限制
void panduan(); //配合limit限制方向
void fool(); //食物的出現(xiàn)以及食物被吞
void isEnd(); //結(jié)束判斷
void zhuangwei(); //撞尾判斷
void zhuangqiang(); //撞墻判斷
int main ()
{
srand((unsigned)time(NULL));
init();
cin>>direction_a;
if(direction_a!='y'&&direction_a!='Y')
return 0;
do
{
system("cls"); //清除屏幕
end=false;
start();
delete_snake();
init_snake();
scores=0;
num=0;
fool_x=(rand() % (79-2+1))+ 2;
fool_y=(rand() % (22-2+1))+ 2;
gotoxy(fool_x,fool_y);
cout<<"0";
direction_a=getch();
while(direction_a!='d'&&direction_a!='s'&&direction_a!='w') direction_a=getch();
while(true)
{
if(num&&direction_a!='d'&&direction_a!='s'&&direction_a!='w'&&direction_a!='a')
{
direction_a=direction_b;
}
control();
fool();
Sleep(speed);
if(kbhit()) //kbhit 非阻塞函數(shù)
{
direction_a=getch(); //使用 getch 函數(shù)獲取鍵盤輸入
limit();
}
panduan();
num=1;
zhuangqiang();
zhuangwei();
if(end) break;
}
}while(direction_a=='y'||direction_a=='Y');
return 0;
}
void init()
{
gotoxy(35,8);
cout<<"★貪 吃 蛇★";
gotoxy(36,10);
cout<<"開始請輸入y:";
}
void start()
{
for(int i=0;i<=79;i++)
{
Sleep(10);
cout<<"*";
gotoxy(i+1,24);
cout<<"*";
gotoxy(i+2,1);
}
gotoxy(1,2);
for(int i=0;i<=21;i++)
{
Sleep(20);
cout<<"*";
for(int j=0;j<=77;j++) cout<<" ";
cout<<"*";
}
}
void init_snake()
{
int n=3;
head=new node;
tail=head;
head->x=40;
head->y=12;
while(n--)
{
p=new node;
tail->next=p;
p->x=tail->x-1;
p->y=tail->y;
tail=p;
}
tail->next=NULL;
node *q=head->next;
gotoxy(head->x,head->y);
cout<<'#';
while(q!=NULL)
{
gotoxy(q->x,q->y);
cout<<'*';
q=q->next;
}
}
void delete_snake()
{
while(head!=NULL)
{
node *q=head;
head=q->next;
delete q;
}
}
void move()
{
gotoxy(tail->x,tail->y);
cout<<" ";
gotoxy(head->next->x,head->next->y);
cout<<'*';
gotoxy(head->x,head->y);
cout<<'#';
node *q=tail;
tail=head;
while(tail->next!=q)
{
tail=tail->next;
}
tail->next=NULL;
delete q;
}
void control()
{
node *q=new node;
q->next=head;
q->x=head->x;
q->y=head->y;
head=q;
switch(direction_a)
{
case 'w': head->y--;break;
case 's': head->y++;break;
case 'a': head->x--;break;
case 'd': head->x++;break;
default : break;
}
move();
}
void limit()
{
if(direction_b=='s'&&direction_a=='w') direction_a='s';
if(direction_b=='w'&&direction_a=='s') direction_a='w';
if(direction_b=='a'&&direction_a=='d') direction_a='a';
if(direction_b=='d'&&direction_a=='a') direction_a='d';
}
void panduan()
{
if(direction_a=='s') direction_b='s';
if(direction_a=='w') direction_b='w';
if(direction_a=='d') direction_b='d';
if(direction_a=='a') direction_b='a';
}
void fool()
{
node *q;
if(head->x==fool_x&&head->y==fool_y)
{
fool_x=(rand() % (79-2+1))+ 2;
fool_y=(rand() % (22-2+1))+ 2;
gotoxy(fool_x,fool_y);
cout<<"0";
num=0;
scores++;
node *q=new node;
q->x=tail->x;
q->y=tail->y;
tail->next=q;
tail=q;
tail->next=NULL;
}
q=head;
while(q!=NULL)
{
if(q->x==fool_x&q->y==fool_y)
{
fool_x=(rand() % (79-2+1))+ 2;
fool_y=(rand() % (22-2+1))+ 2;
gotoxy(fool_x,fool_y);
cout<<"*";
q=head;
continue;
}
q=q->next;
}
}
void isEnd()
{
end=true;
Sleep(600);
system("cls");
gotoxy(35,8);
cout<<"您 輸 啦 ~";
gotoxy(33,10);
cout<<"您的分?jǐn)?shù)為: "<<scores;
gotoxy(31,12);
cout<<"重新開始請輸入y:";
cin>>direction_a;
}
void zhuangwei()
{
node *q=head->next;
while(q!=NULL)
{
if(head->x==q->x&&head->y==q->y)
{
isEnd();
break;
}
q=q->next;
}
}
void zhuangqiang()
{
if(head->x==80||head->x==1||head->y==24||head->y==1)
isEnd();
}
效果圖:
>


由于考慮到游戲的各種 BUG 故自定義函數(shù)很多,有興趣的朋友可以自行改動(dòng)一些函數(shù)對比效果。
關(guān)于C++小游戲的更多精彩內(nèi)容請點(diǎn)擊專題: 《C++經(jīng)典小游戲》 學(xué)習(xí)了解
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 貪吃蛇游戲C++命令行版實(shí)例代碼
- C++實(shí)現(xiàn)簡單貪吃蛇游戲
- C++基于控制臺(tái)實(shí)現(xiàn)的貪吃蛇小游戲
- C++結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)貪吃蛇
- C++代碼實(shí)現(xiàn)貪吃蛇小游戲
- C/C++實(shí)現(xiàn)貪吃蛇逐步運(yùn)動(dòng)效果
- C++ vector容器實(shí)現(xiàn)貪吃蛇小游戲
- C++控制臺(tái)實(shí)現(xiàn)貪吃蛇游戲
- C++控制臺(tái)循環(huán)鏈表實(shí)現(xiàn)貪吃蛇
- 利用C/C++實(shí)現(xiàn)貪吃蛇游戲
相關(guān)文章
C語言代碼實(shí)現(xiàn)點(diǎn)餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)點(diǎn)餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
Cocos2d-x中實(shí)現(xiàn)彈出對話框示例
這篇文章主要介紹了Cocos2d-x中實(shí)現(xiàn)彈出對話框示例,注意本文代碼中的注釋,本文同時(shí)給出了效果圖,需要的朋友可以參考下2014-09-09
使用C# 判斷給定大數(shù)是否為質(zhì)數(shù)的詳解
本篇文章是對使用C#判斷給定大數(shù)是否為質(zhì)數(shù)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
淺談C++/C關(guān)于#define的那些奇奇怪怪的用法
本文主要介紹了C++/C關(guān)于#define的那些奇奇怪怪的用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
C++使用JsonCpp庫操作json格式數(shù)據(jù)示例
這篇文章主要介紹了C++使用JsonCpp庫操作json格式數(shù)據(jù),結(jié)合實(shí)例形式詳細(xì)分析了JsonCpp庫的下載及C++使用JsonCpp庫對json格式數(shù)據(jù)序列化相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
C++實(shí)現(xiàn)宿舍管理查詢系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)宿舍管理查詢系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

