使用VS2017编译
思路:
1.打印出游戏地图,也就是设计游戏地图类game_interdace,包括设计游戏开始界面的函数,游戏地图界面的函数,游戏结束界面的函数,以及设计一些辅助函数如(设置光标为目标点,改变颜色,隐藏光标)来完成上述设计。
2.设计方块图形类,包括生成图形,清理图形,图形移动,图形停止的处理,图形的消失(实质是得分)等。
#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(); //隐藏光标 int color(int c);//改变颜色 void gotoxy(int x, int y);//设置光标为目标点 void gotoprintf(int x, int y);//在目标点打印■ void gotoclear(int x, int y);//消除目标点■ void map(); //游戏地图界面 bool end_map(); //游戏结束界面 private: int grade; static int game_lv; }; int game_interdace::game_lv{}; game_interdace::game_interdace() :grade{ } { }//注意这里的花括号 class Graphic { public: class game_interdace interdace; Graphic(); int location_x;//用于判断和控制图形位置(x坐标) int location_y;//用于判断和控制图形位置(y坐标) int graph_id; //图形id int next_graph_id{};//下一图形id int random(); //生成随机数 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();//图形移动 bool graph_no_moving(int location_x, int location_y,int id);//图形不能超界和不能变形处理 int graph_change(int id); //按‘w'键时,图形的改变 void graph_stop(); //图形停止的处理 void graph_disppear(int location_x, int location_y); //图形的消失(实质是得分) bool game_end(); //游戏结束的判定 private: const int graph[15][8];//记录每个每个图形的各点坐标 int graph_active_pos[32][26]{};//方块活动地图的各坐标点的状态 const int graph_with[15];//记录每个每个图形的宽度 int stop_tgraph_top;// 记录所有已经下落的方块中的最高点 }; Graphic::Graphic(): graph { //两个值一组分别代表x,y 坐标就比如方形图形数据可以这么来看(0,0),(2,0),(0,2),(2,2) //由于每个方块由"■"的宽度为两个字符,所以x坐标成双增长 {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 << " 请在英文输入法中输入wsad控制方块 "; 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 << " 游戏等级 "; gotoxy(30, 16); color(5); std::cout << "====================================================="; color(3); gotoxy(30, 18); std::cout << " 游戏等级:(1)简单--(2)(困难)--(3)地狱"; gotoxy(30, 20); color(5); std::cout << "====================================================="; gotoxy(30, 22); color(7); std::cout << " 等级越高,方块下落的速度越快,加油吧! "; gotoxy(30, 24); color(9); std::cout << " 请输入游戏等级(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(" ");//"■"为两个字符,所以要覆盖两个字符 } void game_interdace::map() { int x, y;//边框打印 for (x = 0; x < 47; x +=2)//从第0列开始到第52列,两个字符一个"■",一共27个”■“ { gotoprintf(x, 0); gotoprintf(x, 26); } for (y = 0; y < 27; y++)//从第0行开始到第26行 { gotoprintf(0, y); gotoprintf(32, y); gotoprintf(46, y); }//x两格为一个前进坐标单位,y一格为一个前进单位 } bool game_interdace::end_map() { char isno{}; system("cls"); gotoprintf(14, 6); std::cout << "游戏结束\n"; std::cout << " 输入【y】键继续游戏\n"; std::cout << " 输入【n】键结束游戏\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); //使下落过程中颜色随机变化(有黑色的) 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()//按键后,如果符号要求就消除旧图形,打印新图形 { 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 << "游戏分数:"; 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); //按键结束后,打印新图形 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;//防止出现该路径没有返回值 } 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;//初始化初始坐标 location_y = 1; clear_graph(36, 3, next_graph_id);//清除图形预览 graph_id = next_graph_id; next_graph_id = random(); produce_graph(36, 3, next_graph_id);//生成新的图形预览 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; }