如果你不知道怎么安裝EasyX圖形庫
鏈接: 點擊這里.
這個作者的安裝教程很好,當時本人也是看這個一步一步做的
另外如果你想要一個寫的思路,可以直接看我的原始碼,一步一步的推敲,也可以直接看這個作者的文章點擊查看.
這個貪吃蛇原始碼實作了以下的功能:
**
(1)需要能在界面指定位置(x,y)直接輸出對應內容
(2)需要動態陣列儲存蛇的身體節點
(3)需要能接收鍵盤指令對貪吃蛇運動方向進行調整
(4)需要隨機生成食物
(5)判斷蛇是否撞到墻或者自己的身體
(6)在你的計算機的C盤生成一個C:/snakeTemp/score.txt的路徑的一個文本檔案,在你不再玩的時候請記得洗掉這個檔案,這個文本是用來記錄你的歷史最高得分
**
#include<cstring>
#include<string>
#include<iostream>
#include<iomanip>
#include<graphics.h>
#include<easyx.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
#include<cstdlib>
#include<fstream>
#include<io.h>
#include <direct.h>
using namespace std;
//專案啟動于2021.1.31日
//author:芽孢子
//本次修改時間:2021.2.6日
//實作:按下p暫停,添加了箭頭操作,
//本次修改時間:2021.2.5日
//增加了蛇會咬死自己,成功的實作了蛇的加長(不要給我亂刪指標),處理好了檔案操作,優化了界面顯示
//本次修改時間:2021.2.4日
//實作:修整了第三個地圖的bug,優化了蛇的死亡的判斷,增加了最高分數的的顯示功能(使用了檔案讀取)
//本次修改時間:2021.2.3日
//實作:修改一個蛇身的加長的大bug(沒有成功),做了第二張地圖,初始界面,死亡影片,做了第三個地圖
//本次修改時間:2021.2.2日
//實作:食物生成,分數統計,蛇身加長,控制蛇
//另:
//2021.1.31已經實作默認的傳參修改能夠修改地圖中網格的大小
//2021.2.2減少了代碼的冗余,實作了能夠操控蛇的移動
//生成食物的函式
void setfood();
//判斷蛇的死活
void snakeAlive();
//顯示玩家的分數
void getScore();
//顯示玩家已經死亡
void dead();
//開始的界面
void be();
//生成新的蛇的方法每次的移動都是蛇的重繪與生成
void createsnake(int direction);
//分數檔案的讀取
int readScore();
//分數檔案的寫入
void writeScore(int score);
struct snake {
int x = 1;
int y = 1;
snake* next = NULL;
}*p;
//對于這個資料當前的坐標為橫56,寬24,這個資料中邊界地部分是不可以使用地
//坐標的范圍是會隨著方塊地長度和間隔地變化而變化的,所以不要給我隨便修改
const int JFramx = 1400, JFramy = 600, length = 20, interval = 5, sum = length + interval;
const int snakespeed = 95;//蛇的移動速度
int foodx=8, foody=8;//生成食物的坐標
//int lastx=2, lasty=2;//在尾部添加蛇身而準備的引數//盡量生成的資料不要是沒有指向的
int score ;//統計玩家的得分
int level = '1';//地基關卡//實際資料大小應該為(1-9)字符型
bool snakearr[60][30];//判斷蛇是否死亡的bool陣列
string fileName = "C:/snakeTemp/score.txt";
class Main {
public:
//默認的蛇的生成//可以寫在類的內部//但我怕出現bug就不改了
//坐標只是影響蛇出現的快慢
//snake e = { 6,6,NULL };
//snake d = { 6,7,&e };
snake c = { 6,8,NULL};
snake b = { 6,9,&c };
snake a = { 6,10,&b };
snake* head = &a;
snake* p = &a;
int snakeLength = 3;//蛇的長度
//生成地圖的構造引數(默認地圖的建構式)
//2021.2.1添加構造已無需在修改呼叫游戲的啟動時直接俄new這個構造就行
//2021.2.4日這個構造不在修改,功能完善了
Main(int levelNumber) {
score = 0;
//先生成上部的方塊
for (int i = 0; i < JFramx / (length + interval); i++) {
//首先宣告顏色,否則第一個格子怪怪的
setfillcolor(BLUE);
setcolor(BLUE);
fillrectangle(i * (length + interval), 0, i * (length + interval) + length, length);
snakearr[i][0]=1;
Sleep(30);
}
//對中間的方塊·的操作決定了關卡的不同的說
if (levelNumber=='2') {
for (int i = 1; i <= JFramy / (length + interval)-2; i++) {
fillrectangle(0, i * (length + interval), length, i * (length + interval) + length);
snakearr[0][i]=1;
if (i!=11&&i!=10&&i!=12) {
fillrectangle(37*sum,i*sum,37*sum+length,i*sum+length);
snakearr[37][i] = 1;
}
if (i!=7&&i!=8&&i!=14&&i!=15) {
fillrectangle(17 * sum, i * sum, 17 * sum + length, i * sum + length);
snakearr[17][i] = 1;
}
fillrectangle((JFramx / (length + interval) - 1) *sum, i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
snakearr[JFramx / (length + interval) - 1][i] = 1;
Sleep(30);
}
}
else if (levelNumber=='3') {
for (int i = 1; i <= JFramy / sum - 2;i++) {
fillrectangle(0,i*sum,length,i*sum+length);
snakearr[0][i]=1;
for (int i2 = 5; i2 < 9;i2++) {
for (int i1 = 12; i1 < 16;i1++) {
snakearr[i1][i2] = 1;
}
for (int i1 = 37; i1 < 41;i1++) {
snakearr[i1][i2] = 1;
}
}
for (int i2 = 7; i2 < 10;i2++) {
for (int i1 = 24; i1 < 27;i1++) {
snakearr[i1][i2] = 1;
}
}
for (int i2 = 13; i2 < 16;i2++) {
for (int i1 = 24; i1 < 27;i1++) {
snakearr[i1][i2] = 1;
}
}
for (int i2 = 17; i2 < 21; i2++) {
for (int i1 = 12; i1 < 16; i1++) {
snakearr[i1][i2] = 1;
}
for (int i1 = 37; i1 < 41; i1++) {
snakearr[i1][i2] = 1;
}
}
if (i==5||i==6) {
for (int i1 = 12; i1 < 16;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 37; i1 < 41;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
}
else if (i==8||i==7) {
for (int i1 = 12; i1 < 16;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 37; i1 < 41;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 24; i1 < 27;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
}
else if (i==9||i==13||i==14||i==15) {
for (int i1 = 24; i1 < 27;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
}
else if (i == 17 || i == 18 || i == 19||i==20) {
for (int i1 = 12; i1 < 16;i1++) {
fillrectangle(i1*sum,i*sum,i1*sum+length,i*sum+length);
Sleep(30);
}
for (int i1 = 37; i1 < 41; i1++) {
fillrectangle(i1 * sum, i * sum, i1 * sum + length, i * sum + length);
Sleep(30);
}
}
fillrectangle((JFramx / (length + interval) - 1) * (length + interval), i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
snakearr[JFramx / (length + interval) - 1][i]=1;
Sleep(30);
}
}
else {
//玩家不存在選關的操作時
level = '1';//令關卡的變數為零
for (int i = 1; i <= JFramy / (length + interval)-2; i++) {
fillrectangle(0, i * (length + interval), length, i * (length + interval) + length);
snakearr[0][i]=1;
fillrectangle((JFramx / (length + interval) - 1) * (length + interval), i * (length + interval), (JFramx / (length + interval) - 1) * (length + interval) + length, i * (length + interval) + length);
snakearr[JFramx / (length + interval) - 1][i]=1;
Sleep(30);
}
}
//底部的生成
for (int i = 0; i < JFramx / (length + interval); i++) {
fillrectangle(i * (length + interval), (JFramy / (length + interval) - 1) * (length + interval), i * (length + interval) + length, JFramy - interval);
snakearr[i][JFramy / (length + interval) - 1]=1;
Sleep(30);
}
Main('s');
}
//這個構造完善了,不能在修改,時間2021.2.3
//蛇的加入構造,其中還有蛇的移動方法
Main(char numebr) {
int temp_key = 's';//接受鍵盤輸入的事件的暫時量,為了使蛇的身體不會實作倒退的情況
while (1) {//接受鍵盤的事件
int ch;//接受鍵盤上的事件的得到的資料
Sleep(5);
if (_kbhit()) {
ch = _getch();
if (ch == 27) { closegraph(); break; }
else if ((ch == 'd'||ch==77) && temp_key != 'a') {//向右移動//新加入了判斷蛇回退的判斷
temp_key = 'd';
}else if ((ch == 'w'||ch==72)&&temp_key!='s') { //向上移動//判斷已添加
temp_key = 'w';
}else if ((ch == 's'||ch==80)&&temp_key!='w') { //向上移動//判斷已添加
temp_key = 's';
}else if ((ch == 'a'||ch==75)&&temp_key!='d') { //向上移動//判斷已添加
temp_key = 'a';
}else if (ch=='p') {
pauseGame();
}
}
//這里是蛇身移動的方法,在沒有輸入的時候的情況//已經減少了代碼的冗余
if (temp_key=='d') {
createsnake(1);
}if (temp_key=='w') {
createsnake(2);
}if (temp_key=='s') {
createsnake(4);
}if (temp_key=='a') {
createsnake(3);
}
}
}
//生成新的蛇的方法每次的移動都是蛇的重繪與生成
void createsnake(int direction) {
//直接在生成蛇的時候就直接判斷蛇的死亡
getScore();
setfood();
if (head->x==foodx&&head->y==foody) {
snake* endsnake=new snake;
endsnake->x = head->x;
endsnake->y = head->y;
endsnake->next = head;
snake* s = new snake;
head=endsnake;
}
for (p = head; p; p = p->next) {
clearrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
}
int tempy = head->y;
int tempx = head->x;
int tempx02;
int tempy02;
if (direction == 1) { head->x++; }
else if (direction == 2) { head->y--; }
else if (direction == 3) { head->x--; }
else if (direction == 4) { head->y++; }
for (p = head; p; p = p->next) {
if (p == head) {
setcolor(RED);
setfillcolor(LIGHTRED);
}
else {
setcolor(GREEN);
setfillcolor(GREEN);
}
if (p == head) {
fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
}
else {
tempx02 = p->x;
tempy02 = p->y;
p->x = tempx;
p->y = tempy;
fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
tempx = tempx02;
tempy = tempy02;
}
}
Sleep(snakespeed);
snakeAlive(level);
}
//生成食物的函式
void setfood() {
if (head->x == foodx&&head->y==foody) {
score++;//分數的增加
addSnake();
unsigned seed=(time(0));
srand(seed);
foody = rand() % 22 + 1;
if (level=='1') {
foodx = rand() % 54 + 1;
}
else if (level=='2') {
if (head->x<17) {
foodx = rand()%17+20;
}
else if (head->x<37) {
foodx = rand()%17+38;
}
else if (head->x<55) {
foodx = rand() % 16 + 1;
}
}
else if (level=='3') {
if (head->x<12) {
foodx = rand()%7+16;
}
else if (head->x<24) {
foodx = rand() % 10+27;
}
else if (head->x<37) {
foodx = rand() % 14 + 41;
}
else if (head->x<54) {
foodx = rand() % 12 + 1;
}
}
setfillcolor(LIGHTMAGENTA);
fillrectangle(foodx*sum,foody*sum,foodx*sum+length,foody*sum+length);
}
else {
setcolor(LIGHTMAGENTA);
setfillcolor(LIGHTMAGENTA);
fillrectangle(foodx * sum, foody * sum, foodx * sum + length, foody * sum + length);
}
}
//判斷蛇是否死亡
//本次修改時間:2021.2.4
//已經優化了特別多了,不要再修改了
//被呼叫的上級createSnake();
void snakeAlive(int level) {
for (p = head; p;p=p->next) {
if (head->x==p->x&&head->y==p->y&&p!=head) {
dead();
closegraph();
}
}
if (snakearr[head->x][head->y]==1) {
dead();
closegraph();
}
}
//使地圖顯示分數
void getScore() {
RECT r = { sum,sum,1200, 550 };
string s = "你的分數";
string stemp = to_string(score);
s += stemp;
settextcolor(GREEN);
drawtext(_T(s.c_str()),&r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
//屆幾個在類外實作了
void addSnake();
void dead();
static void createTempFile();
static void createTempDirectory();
void pauseGame();//游戲的暫停方法
};
void Main::pauseGame() {
bool temp = 1;
while (temp) {
if (_kbhit()) {
temp = 0;
}
}
}
void Main::createTempDirectory() {
const char* temp_directory = "C:/snakeTemp";
if (_access(temp_directory,0)!=0) {
_mkdir(temp_directory);
}
}
//生成檔案
void Main::createTempFile() {
//下面這個判斷在檔案存在時回傳的為0,于是在不為0時檔案就不存在了
createTempDirectory();
if (_access(fileName.c_str(),0)!=0) {
ofstream temp_os(fileName, ios::app);
temp_os << '0';
temp_os.close();
}
}
void Main::addSnake() {
snake* endsnake=head,*q=new snake;
while (endsnake ->next!=NULL) {
endsnake = endsnake -> next;
}
q->x = endsnake->x;
q->y = endsnake->y;
endsnake->next = q;
}
//死亡的影片
//時間2021.2.4:方法差不多完善了,之后可以在加一個io流的方法
void Main::dead() {
for (int i = 0; i < 5;i++) {
for (p = head; p;p=p->next) {
clearrectangle(p->x*sum,p->y*sum,p->x*sum+length,p->y*sum+length);
}
Sleep(200);
for (p = head; p;p=p->next) {
if (p->x==head->x&&p->y==head->y) {
setfillcolor(RED);
fillrectangle(p->x * sum, p->y * sum, p->x * sum + length, p->y * sum + length);
}
else {
setfillcolor(GREEN);
fillrectangle(p->x*sum,p->y*sum,p->x*sum+length,p->y*sum+length);
}
}
Sleep(30);
}
if (score>readScore()) {//如果本次得分比上一次的高就保存在本地檔案
writeScore(score);
}
clearcliprgn();
char string[] = "時間停止了,你..死了!";
char string01[] = " ";
settextcolor(RED);
settextstyle(100, 0, _T("宋體"));
for (int i = 0; i < 3; i++) {
outtextxy(250, 300, string);
Sleep(500);
outtextxy(250, 300, string01);
Sleep(1000);
}
settextcolor(GREEN);
char string02[] = "馬上就會回到初始界面";
settextstyle(100, 0, _T("宋體"));
outtextxy(250, 300, string02);
Sleep(1000);
clearcliprgn();
be();
}
int readScore() {
fstream scorefile(fileName, ios::in);
string s;
getline(scorefile,s);
scorefile.close();
return stoi(s);
}
void writeScore(int score) {
fstream scorefile(fileName, ios::trunc | ios::out);
scorefile << score;
scorefile.close();
}
void be() {
Main::createTempFile();
memset(snakearr, 0, sizeof(snakearr));//bool陣列的賦值
initgraph(JFramx, JFramy);
char str_0[] = "》貪吃蛇《";
char tips[] = "提示:";
char str_1[] = "歡迎你的游玩,本游戲由芽孢子獨立完成,特別鳴謝張百害";
char str_2[] = "·使用WASD控制蛇的移動,箭頭也行";
char str_3[] = "·撞墻而死.按p暫停";
char str_4[] = "·游戲界面可以顯示你的分數";
char str_5[] = " 點擊任意鍵繼續";
char str_6[] = "·鍵盤輸入數字可以選關(1-3)";
char deletestr[] = " ";
settextstyle(50, 0, _T("宋體"));
outtextxy(620, 50, str_0);
settextstyle(20, 0, _T("宋體"));
outtextxy(500, 130, str_1);
outtextxy(500, 180, tips );
outtextxy(500, 230, str_2);
outtextxy(500, 280, str_3);
outtextxy(500, 330, str_4);
outtextxy(500, 380, str_6);
settextstyle(50, 0, _T("宋體"));
int scoreFileNumber = readScore();
string scoreFile = " 你的最高分數:";
scoreFile += to_string(scoreFileNumber);
char Outscore[1024];
strcpy_s(Outscore,sizeof(Outscore),scoreFile.c_str());//c_str()方法能加字串轉化為字符陣列
while (1) {
if (_kbhit()) {
level =_getch();//再鍵盤上得到的字符型別,從零開始計數的話,0的ASCll的值為48
if (level=27) {//在初始的界面中所加上的一個退出的的選項
closegraph();
}
break;
}
outtextxy(450, 500, str_5);
Sleep(500);
outtextxy(450, 500, deletestr);
Sleep(500);
outtextxy(450,500,Outscore);
Sleep(700);
outtextxy(450, 500, deletestr);
Sleep(500);
}
clearcliprgn();
new Main(level);//這里傳值
}
int main() {
be();
getchar();
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/272581.html
標籤:其他
上一篇:2020年年終總結
下一篇:20210323第一家量產國產化藍牙AOA高精度定位基站生態合能培訓會上海站現場直播下午內容視頻錄像回放-深圳核芯物聯原廠工程師羅良技術分享
