C++實(shí)現(xiàn)俄羅斯方塊游戲
本文實(shí)例為大家分享了C++實(shí)現(xiàn)俄羅斯方塊游戲的具體代碼,供大家參考,具體內(nèi)容如下
使用VS2017編譯
思路:
1.打印出游戲地圖,也就是設(shè)計(jì)游戲地圖類game_interdace,包括設(shè)計(jì)游戲開始界面的函數(shù),游戲地圖界面的函數(shù),游戲結(jié)束界面的函數(shù),以及設(shè)計(jì)一些輔助函數(shù)如(設(shè)置光標(biāo)為目標(biāo)點(diǎn),改變顏色,隱藏光標(biāo))來完成上述設(shè)計(jì)。
2.設(shè)計(jì)方塊圖形類,包括生成圖形,清理圖形,圖形移動(dòng),圖形停止的處理,圖形的消失(實(shí)質(zhì)是得分)等。
#include <iostream> #include<conio.h> #include<windows.h> #include<time.h> #include<string> class game_interdace { public: friend class Graphic; game_interdace(); void start_interface();//游戲開始界面 void HideCursor(); //隱藏光標(biāo) int color(int c);//改變顏色 void gotoxy(int x, int y);//設(shè)置光標(biāo)為目標(biāo)點(diǎn) void gotoprintf(int x, int y);//在目標(biāo)點(diǎn)打印■ void gotoclear(int x, int y);//消除目標(biāo)點(diǎn)■ void map(); //游戲地圖界面 bool end_map(); //游戲結(jié)束界面 private: int grade; static int game_lv; }; int game_interdace::game_lv{}; game_interdace::game_interdace() :grade{ } { }//注意這里的花括號(hào) class Graphic { public: class game_interdace interdace; Graphic(); int location_x;//用于判斷和控制圖形位置(x坐標(biāo)) int location_y;//用于判斷和控制圖形位置(y坐標(biāo)) int graph_id; //圖形id int next_graph_id{};//下一圖形id int random(); //生成隨機(jī)數(shù) void produce_graph(int location_x, int location_y,int id );//生成圖形 void clear_graph(int location_x, int location_y,int id);//清理圖形 void graph_moving();//圖形移動(dòng) bool graph_no_moving(int location_x, int location_y,int id);//圖形不能超界和不能變形處理 int graph_change(int id); //按‘w'鍵時(shí),圖形的改變 void graph_stop(); //圖形停止的處理 void graph_disppear(int location_x, int location_y); //圖形的消失(實(shí)質(zhì)是得分) bool game_end(); //游戲結(jié)束的判定 private: const int graph[15][8];//記錄每個(gè)每個(gè)圖形的各點(diǎn)坐標(biāo) int graph_active_pos[32][26]{};//方塊活動(dòng)地圖的各坐標(biāo)點(diǎn)的狀態(tài) const int graph_with[15];//記錄每個(gè)每個(gè)圖形的寬度 int stop_tgraph_top;// 記錄所有已經(jīng)下落的方塊中的最高點(diǎn) }; Graphic::Graphic(): graph { //兩個(gè)值一組分別代表x,y 坐標(biāo)就比如方形圖形數(shù)據(jù)可以這么來看(0,0),(2,0),(0,2),(2,2) //由于每個(gè)方塊由"■"的寬度為兩個(gè)字符,所以x坐標(biāo)成雙增長 {0,0,2,0,0,1,2,1 }, //方形 {2,0,4,0,0,1,2,1},{0,0,0,1,2,1,2,2},// |_ // |形 {0,0,2,0,2,1,4,1},{2,0,0,1,2,1,0,2},// {0,0,2,0,4,0,6,0},{0,0,0,1,0,2,0,3},//條形 {2,0,0,1,2,1,4,1},{0,0,0,1,2,1,0,2},{0,0,2,0,4,0,2,1},{2,0,0,1,2,1,2,2} ,//T形 {0,0,2,0,0,1,0,2},{0,0,0,1,2,1,4,1},{0,0,2,0,2,1,2,2} ,{0,0,2,0,4,0,0,1}, }, //L形 graph_with{ 2,3,2,3,2,4,1,3,2,3,2,2,3,2,3 }, location_x{ 14 }, location_y{ 1 }, graph_id{ 5 }, stop_tgraph_top{ 26 } { } int main() { bool aganst{ false }; do { game_interdace interdace; interdace.HideCursor(); interdace.start_interface(); interdace.map(); Graphic graph; graph.graph_moving(); if (interdace.end_map()) { aganst = true; system("cls"); } } while (aganst); } void game_interdace::start_interface()//游戲開始界面 { color(2); gotoxy(30, 2); std::cout<<" 游戲說明 "; color(3); gotoxy(30, 5); std::cout << " 請(qǐng)?jiān)谟⑽妮斎敕ㄖ休斎雡sad控制方塊 "; color(4); gotoxy(30, 9); std::cout << " 'w'為變形 \n"; gotoxy(30, 10); std::cout << " 's'為快速下落 \n"; gotoxy(30, 11); std::cout << " 'a'為左移 "; gotoxy(30, 12); std::cout << " 'd'為右移 "; gotoxy(30, 14); color(5); std::cout << " 游戲等級(jí) "; gotoxy(30, 16); color(5); std::cout << "====================================================="; color(3); gotoxy(30, 18); std::cout << " 游戲等級(jí):(1)簡單--(2)(困難)--(3)地獄"; gotoxy(30, 20); color(5); std::cout << "====================================================="; gotoxy(30, 22); color(7); std::cout << " 等級(jí)越高,方塊下落的速度越快,加油吧! "; gotoxy(30, 24); color(9); std::cout << " 請(qǐng)輸入游戲等級(jí)(1-3): "; gotoxy(70, 24); std::cin >> game_lv; system("cls"); color(7); } void game_interdace::HideCursor() { CONSOLE_CURSOR_INFO cursor; cursor.bVisible = FALSE; cursor.dwSize = sizeof(4); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorInfo(handle, &cursor); } int game_interdace::color(int c) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); return 0; } void game_interdace::gotoxy(int x, int y) { COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); } void game_interdace::gotoprintf(int x, int y) { gotoxy(x, y); printf("■"); } void game_interdace::gotoclear(int x, int y) { gotoxy(x, y); printf(" ");//"■"為兩個(gè)字符,所以要覆蓋兩個(gè)字符 } void game_interdace::map() { int x, y;//邊框打印 for (x = 0; x < 47; x +=2)//從第0列開始到第52列,兩個(gè)字符一個(gè)"■",一共27個(gè)”■“ { gotoprintf(x, 0); gotoprintf(x, 26); } for (y = 0; y < 27; y++)//從第0行開始到第26行 { gotoprintf(0, y); gotoprintf(32, y); gotoprintf(46, y); }//x兩格為一個(gè)前進(jìn)坐標(biāo)單位,y一格為一個(gè)前進(jìn)單位 } bool game_interdace::end_map() { char isno{}; system("cls"); gotoprintf(14, 6); std::cout << "游戲結(jié)束\n"; std::cout << " 輸入【y】鍵繼續(xù)游戲\n"; std::cout << " 輸入【n】鍵結(jié)束游戲\n"; gotoxy(17, 10); std::cin >> isno; if (isno =='y') { return true; } else { return false; } } int Graphic::random() { srand((int)time(NULL)); int number = rand()%15; return number; } void Graphic::produce_graph(int location_x, int location_y,int id) { int X, Y; for (int i = 0; i < 4; i++) { X = location_x + graph[id][i * 2]; Y = location_y + graph[id][i * 2 + 1]; interdace.gotoprintf(X, Y); } } void Graphic::clear_graph(int location_x, int location_y,int id) { int X, Y; interdace.color(random()%15+1); //使下落過程中顏色隨機(jī)變化(有黑色的) for (int i = 0; i < 4; i++) { X = location_x + graph[id][i * 2]; Y = location_y + graph[id][i * 2 + 1]; interdace.gotoclear(X, Y ); } } void Graphic::graph_moving()//按鍵后,如果符號(hào)要求就消除舊圖形,打印新圖形 { int sign{}, sleep{ 400 }; graph_id = random(); next_graph_id = random(); produce_graph(36, 3, next_graph_id); while (true) { sign = 0; interdace.gotoxy(35, 9); std::cout << "游戲分?jǐn)?shù):"; interdace.gotoxy(39, 11); std::cout << interdace.grade * 10; if (_kbhit()) { sign = _getch(); } clear_graph(location_x, location_y, graph_id); switch (sign) { case 119: //如果按下'w'鍵, location_y += 1; if (graph_no_moving(location_x, location_y, graph_change(graph_id))) { location_y -= 1; break; } graph_id = graph_change(graph_id); break; case 115: //如果按下s'鍵 sleep = 50; location_y += 1; break; case 97: //如果按下a'鍵 location_x -= 2; location_y += 1; if (graph_no_moving(location_x, location_y, graph_id) ) { location_x += 2; location_y -= 1; } break; case 100: //如果按下'd'鍵 location_x += 2; location_y += 1; if (graph_no_moving(location_x, location_y, graph_id) ) { location_x -= 2; location_y -= 1; } break; default: location_y += 1; break; } produce_graph(location_x, location_y, graph_id); //按鍵結(jié)束后,打印新圖形 Sleep(sleep); sleep = (4- interdace.game_lv)*100; graph_stop();//如果符合停止要求就停止 if (game_end()) { break; } } } bool Graphic::graph_no_moving(int location_x, int location_y,int id) { for (int i = 0; i < 4; i++) { int X, Y; X = location_x + graph[id][i * 2]; Y = location_y + graph[id][i * 2 + 1]; if (location_x < 2 || graph_active_pos[X][Y] == 1 || location_x+ (graph_with[id]-1)*2 >30) { return true; } else return false; } return 0;//防止出現(xiàn)該路徑?jīng)]有返回值 } int Graphic::graph_change(int id) { switch (id) { case 0: id = 0; break; //方形 case 1: id = 2; break;//|_ case 2: id = 1; break;// | case 3: id = 4; break;// case 4: id = 3; break; case 5: id = 6; break;//條形 case 6: id = 5; break; case 7: id = 8; break;//T形 case 8: id = 9; break; case 9: id = 10; break; case 10: id = 7; break; case 11: id = 12; break;//L形 case 12: id = 13; break; case 13: id = 14; break; case 14: id = 11; break; default: break; } return id; } void Graphic::graph_stop() { int X{}, Y{}; for (int i = 0; i < 4; i++) { X = location_x + graph[graph_id][i * 2]; Y = location_y + graph[graph_id][i * 2 + 1]; if (graph_active_pos[X][Y+1] == 1||Y>=25) { for (int i = 0; i < 4; i++) { X = location_x + graph[graph_id][i * 2]; Y = location_y + graph[graph_id][i * 2 + 1]; graph_active_pos[X][Y] = 1; } if (stop_tgraph_top >location_y) { stop_tgraph_top = location_y; } graph_disppear(location_y, Y); location_x = 14;//初始化初始坐標(biāo) location_y = 1; clear_graph(36, 3, next_graph_id);//清除圖形預(yù)覽 graph_id = next_graph_id; next_graph_id = random(); produce_graph(36, 3, next_graph_id);//生成新的圖形預(yù)覽 produce_graph(location_x, location_y, graph_id);//打印新的初始圖形 } } } void Graphic::graph_disppear(int location_y,int Y) { int count{ 0 }; bool isno{ false }; for (int line = location_y + graph[graph_id][7] ; line > location_y; line--) { count = 0; isno = false; for (int column = 2; column < 32; column +=2) { if (graph_active_pos[column][line]==1) { count++; if (count==15) { count = 0; interdace.grade++; isno = true; } } if (isno) { for (int ls = 2; ls < 32; ls+=2) { for (int i = line; i >= stop_tgraph_top; i--) { if (graph_active_pos[ls][i]) { interdace.gotoclear(ls, i); } graph_active_pos[ls][i] = graph_active_pos[ls][i - 1]; if (graph_active_pos[ls][i]) { interdace.gotoprintf(ls, i); } } } } } } } bool Graphic::game_end() { if (stop_tgraph_top <=1)return true; else return false; }
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
聊聊C++中右值引用和移動(dòng)構(gòu)造函數(shù)的使用
這篇文章主要是來和大家一起聊聊C++中右值引用和移動(dòng)構(gòu)造函數(shù)的使用,文中通過示例進(jìn)行了詳細(xì)講解,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-07-07C語言中的pause()函數(shù)和alarm()函數(shù)以及sleep()函數(shù)
這篇文章主要介紹了C語言中的pause()函數(shù)和alarm()函數(shù)以及sleep()函數(shù),是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09C語言詳細(xì)講解通過遞歸實(shí)現(xiàn)掃雷的展開
windows自帶的游戲《掃雷》是陪伴了無數(shù)人的經(jīng)典游戲,本文將利用C語言實(shí)現(xiàn)這一經(jīng)典的游戲,文中的示例代碼講解詳細(xì),感興趣的可以學(xué)習(xí)一下2022-05-05