|
16| 0
|
[项目分享] 俄罗斯方块!!!(C++) |
终于制作好了![]() #include<iostream> #include<vector> #include<Windows.h> #include<graphics.h> #include<string> #include<conio.h> #include<chrono> //#pragma comment(lib, "libcpmtd.lib")//Debug #pragma comment(lib, "libcpmt.lib")//Release #ifdef _WIN32 bool is_WIN32 = true,k=true,pibm=false; int _width, _height, BLOCK_SIZE; std::vector<std::vector<int>>game_interface; const std::vector<std::vector<std::vector<bool>>> BLOCK{ // 0: ':. { {1, 1, 0}, {0, 1, 1} }, // 1: .:' { {0, 1, 1}, {1, 1, 0} }, // 2: : // : { {1}, {1}, {1}, {1} }, // 3: :: { {1, 1}, {1, 1} }, // 4: .:. { {0, 1, 0}, {1, 1, 1} }, // 5: ..: { {0, 0, 1}, {1, 1, 1} }, // 6: :.. { {1, 0, 0}, {1, 1, 1} } }; const std::vector<COLORREF>block_color{ RGB(255, 0, 0),//红 RGB(255, 255, 0),//黄 RGB(0, 255, 0),//绿 RGB(0, 255, 255),//青 RGB(0, 0, 255),//蓝 RGB(255, 0, 255)//粉 }; int ran, lran, ll; #elif bool is_WIN32 = false; #endif //TODO:解决BLOCK[5]:..,BLOCK[6]..:的旋转小问题 static void input_width_or_height(int* _input, const bool IS_HEIGHT) { while (true) { std::string input_str; if (IS_HEIGHT) { std::wcout << "\n请输入游戏高度(大于9):"; } else { std::wcout << "\n请输入游戏宽度(大于9):"; } std::cin >> input_str; try { int input_val = stoi(input_str); if (input_val < 10) { std::wcout << "\n数值必须大于9!\n"; continue; } int max_val = GetSystemMetrics(IS_HEIGHT) - IS_HEIGHT ? 300 : 100; if (input_val > max_val) { std::wcout << "\n数值过大,最大为" << max_val << "!\n"; continue; } *_input = input_val; break; } catch (std::out_of_range) { std::wcout << "\n数值超出范围!\n"; } catch (...) { std::wcout << "\n请输入有效数字!\n"; } } } static void print_interface(const int TIMES, const int SCORE, const int LEVEL, const bool IS_RAN = false) { cleardevice(); int x, y; if (TIMES > 0) { const std::vector<std::vector<bool>>WATING = BLOCK[lran]; setfillcolor(block_color[(TIMES - IS_RAN) % 6]); for (y = 0; y < WATING.size(); y++) { for (x = 0; x < WATING[0].size(); x++) { if (WATING[y][x]) { fillrectangle(BLOCK_SIZE * _width + 25 + 25 * x, 25 + 25 * y, BLOCK_SIZE * _width + 50 + 25 * x, 50 + 25 * y); } } } if (IS_RAN) { lran = ran; ran = rand() % 7; } } outtextxy(BLOCK_SIZE * _width + 25, 125, L"分数:"); outtextxy(BLOCK_SIZE * _width + 85, 125, std::to_wstring(SCORE).c_str()); outtextxy(BLOCK_SIZE * _width + 25, 150, L"等级:"); outtextxy(BLOCK_SIZE * _width + 85, 150, std::to_wstring((LEVEL < 0) ? ll : LEVEL).c_str()); ll = LEVEL; setcolor(DARKGRAY); for (y = 0; y <= _height; y++) {//画横线 line(0, y * BLOCK_SIZE, BLOCK_SIZE * _width, y * BLOCK_SIZE); } for (x = 0; x < _width + 1; x++) {//画竖线 line(x * BLOCK_SIZE, BLOCK_SIZE * _height, x * BLOCK_SIZE, 0); } for (y = 0; y < _height; y++) { for (x = 0; x < _width; x++) { if (game_interface[y][x] > 0) { setfillcolor(block_color.at((game_interface[y][x] - 1) % 6)); setcolor(block_color.at((game_interface[y][x] - 1) % 6)); fillrectangle(x * BLOCK_SIZE, y * BLOCK_SIZE, (x + 1) * BLOCK_SIZE, (y + 1) * BLOCK_SIZE); setcolor(WHITE); const unsigned short this_block_value = game_interface[y][x]; //描边↓ //上 if (y == _height - 1) { line(x * BLOCK_SIZE, (y + 1) * BLOCK_SIZE, (x + 1) * BLOCK_SIZE, (y + 1) * BLOCK_SIZE); } else if (game_interface[y + 1][x] != this_block_value) { line(x * BLOCK_SIZE, (y + 1) * BLOCK_SIZE, (x + 1) * BLOCK_SIZE, (y + 1) * BLOCK_SIZE); } //下 if (y == 0) { line(x * BLOCK_SIZE, y * BLOCK_SIZE, (x + 1) * BLOCK_SIZE, y * BLOCK_SIZE); } else if (game_interface[y - 1][x] != this_block_value) { line(x * BLOCK_SIZE, y * BLOCK_SIZE, (x + 1) * BLOCK_SIZE, y * BLOCK_SIZE); } //左 if (x == 0) { line(x * BLOCK_SIZE, (y + 1) * BLOCK_SIZE, x * BLOCK_SIZE, y * BLOCK_SIZE); } else if (game_interface[y][x - 1] != this_block_value) { line(x * BLOCK_SIZE, (y + 1) * BLOCK_SIZE, x * BLOCK_SIZE, y * BLOCK_SIZE); } //右 if (x == _width - 1) { line((x + 1) * BLOCK_SIZE, (y + 1) * BLOCK_SIZE, (x + 1) * BLOCK_SIZE, y * BLOCK_SIZE); } else if (game_interface[y][x + 1] != this_block_value) { line((x + 1) * BLOCK_SIZE, (y + 1) * BLOCK_SIZE, (x + 1) * BLOCK_SIZE, y * BLOCK_SIZE); } } } } } static void put_in_block(int* status, const int TIMES) { const int x = _width / 2 - (BLOCK[lran][0].size()) / 2; const std::vector<std::vector<bool>>WATING = BLOCK[lran];//暂存形状 pibm = (lran == 6 || lran == 5); for (int ty = 0; ty < WATING.size(); ty++) { for (int tx = x; tx - x < WATING[0].size(); tx++) { if (WATING[ty][tx - x]) { if (game_interface[ty][tx] == 0) { game_interface[ty][tx] = TIMES; } else { *status = -1; return; } } } } *status = 0; } static void block_moves(const int MODE, int* status, int* times, int* score, int* erased_line, bool add_s_s_t = false, const bool FASTLY_DOWN = false ,const bool s = false) { std::vector<std::vector<int>>coords{ {},{} }; int i, x, y; //下落 MODE==0 if (!MODE) { //收集//下落判断 for (y = 0; y < _height; y++) { for (x = 0; x < _width; x++) { if (game_interface[y][x] == *times) { if (y == _height - 1) { if (add_s_s_t) { *status = 1; *times++; } return; } else { if ((game_interface[y + 1][x] != 0 && game_interface[y + 1][x] != *times)) { if (add_s_s_t) { *status = 1; *times++; } return; } } coords[0].push_back(x); coords[1].push_back(y); } } } //执行 for (i = 0; i < coords[0].size(); i++) { game_interface[coords[1][i]][coords[0][i]] = 0; } for (i = 0; i < coords[0].size(); i++) { game_interface[coords[1][i] + 1][coords[0][i]] = *times; } if (FASTLY_DOWN) { if (add_s_s_t) { *score += 5; } if (s) { block_moves(0, &*status, &*times, &*score, &*erased_line, add_s_s_t, true, true); } } } //旋转 MODE==2 else if (MODE == 2) { //收集 for (y = 0; y < _height; y++) { for (x = 0; x < _width; x++) { if (game_interface[y][x] == *times) { coords[0].push_back(y); coords[1].push_back(x); } if (coords[0].size() == 4) { break; } } if (coords[0].size() == 4) { break; } } //确定质心 std::vector<int>centroid{ 0,0 }; for (i = 0; i < 4; i++) { centroid[0] += coords[0][i]; centroid[1] += coords[1][i]; } centroid[0] /= 4; centroid[1] /= 4; const bool x_correct = pibm||((coords[1][3] - coords[1][0]) % 2); //判断 for (i = 0; i < 4; i++) { const int cx = centroid[1] - coords[0][i] + centroid[0] + x_correct+pibm, cy = centroid[0] + coords[1][i] - centroid[1]; if (-1 < cx && cx < _width && -1 < cy && cy < _height) { if (game_interface[cy][cx] != 0 && game_interface[cy][cx] != *times) { *status = 1; *times++; return; } } else { return; } } //执行 for (i = 0; i < 4; i++) { game_interface[coords[0][i]][coords[1][i]] = 0; } for (i = 0; i < 4; i++) { game_interface[centroid[0] + coords[1][i] - centroid[1]][centroid[1] - coords[0][i] + centroid[0] + x_correct] = *times; } block_moves(0, &*status, &*times, &*score, &*erased_line, true); } //平移 MODE==±1 else { //收集//判断 for (x = 0; x < _width; x++) { for (y = 0; y < _height; y++) { if (game_interface[y][x] == *times) { if ((MODE == -1) ? (x == 0) : (x == _width - 1)) { return; } else if (game_interface[y][x + MODE] != *times && game_interface[y][x + MODE] != 0) { block_moves(0, &*status, &*times, &*score, &*erased_line, true); return; } coords[0].push_back(x); coords[1].push_back(y); } } } //执行 for (i = 0; i < 4; i++) { game_interface[coords[1][i]][coords[0][i]] = 0; } for (i = 0; i < 4; i++) { game_interface[coords[1][i]][coords[0][i] + MODE] = *times; } block_moves(0, &*status, &*times, &*score, &*erased_line, true); } } static void clear_line(int* erased_line, int* score) { std::vector<int> erase_list, fall_block; erase_list.reserve(4); fall_block.reserve(_width); int y, x; for (y = _height - 1; y >= 0; y--) { bool is_full = true; for (x = 0; x < _width; x++) { if (game_interface[y][x] == 0) { is_full = false; break; } } if (is_full) { erase_list.emplace_back(y); for (const int tx : game_interface[y]) { bool _find = false; for (const int i : fall_block) { _find = (tx == i); if (_find) { break; } } if (!_find) { fall_block.emplace_back(tx); } } *erased_line++; } } if (!erase_list.empty()) { switch (erase_list.size()) { case 1: *score += 100; break; case 2: *score += 200; break; case 3: *score += 400; break; default: *score += 800; break; } for (y = 0; y < erase_list.size(); y++) { for (x = 0; x < _width; x++) { game_interface[erase_list[y]][x] = 0; } } std::cout << 0; print_interface(0, *score, *erased_line / 10); for (int y : erase_list) { game_interface.erase(game_interface.begin() + y); } for (int y : erase_list) { game_interface.insert(game_interface.begin(), std::vector<int>(_width, 0)); } fall_block.pop_back(); for (int i : fall_block) { block_moves(0, nullptr, &i, nullptr, &*erased_line, false, true); } Sleep(300); print_interface(0, *score, *erased_line / 10); } } int main() { if (is_WIN32) { std::wcout << "(游戏结束后按esc退出)\n上键:逆时针旋转方块\n下键:加速游戏\n\n左键:方块左移\n右键:方块右移\ns:方块直接下落 (英文输入法!!!)\n"; input_width_or_height(&_height, true); input_width_or_height(&_width, false); //判断方块尺寸用 if ((GetSystemMetrics(SM_CYSCREEN) - 100) > _height * 30 && (GetSystemMetrics(SM_CXSCREEN) - 100) > _width * 30) { BLOCK_SIZE = 30; } else if ((GetSystemMetrics(SM_CYSCREEN) - 100) / _height > (GetSystemMetrics(SM_CXSCREEN) - 100) / _width) { BLOCK_SIZE = (GetSystemMetrics(SM_CXSCREEN) - 100) / _width; } else { BLOCK_SIZE = (GetSystemMetrics(SM_CYSCREEN) - 100) / _height; } initgraph(BLOCK_SIZE * _width + 200, BLOCK_SIZE * _height); game_interface.resize(_height); for (int y = 0; y < _height; ++y) { game_interface[y].resize(_width, 0); } int times = 0, score = 0, erased_line = 0; int status = 1;//1:允许 0:不允许【(已有方块下落中)不得同时出现两个方块】 -1:添加失败(游戏结束) bool speed_up = false, lks = false; srand(time(0)); ran = rand() % 7; print_interface(times, score, erased_line / 10, true); setfont(20, 10, L"黑体"); //主循环 while (true) { bool ks = false; int key = 0; if (_kbhit()) { ks = true; key = _getch(); if (key == 's') { block_moves(0, &status, ×, &score, &erased_line, true, true, true); } if (key == 0 || key == 0xE0) { key = _getch(); } } if (!lks && ks) { switch (key) { case 0x48: // 上键 block_moves(2, &status, ×, &score, &erased_line); speed_up = false; break; case 0x50: // 下键 speed_up = true; break; case 0x4B: // 左键 block_moves(-1, &status, ×, &score, &erased_line); speed_up = false; break; case 0x4D: // 右键 block_moves(1, &status, ×, &score, &erased_line); speed_up = false; break; default: // 其他按键 speed_up = false; break; } } if (lks && !ks) { speed_up = false; } lks = ks; if (status == 1) { clear_line(&erased_line, &score); times++; put_in_block(&status, times); print_interface(times, score, erased_line / 10, true); } else if (status == 0) { block_moves(0, &status, ×, &score, &erased_line, true); print_interface(times, score, erased_line / 10); } else { std::wstring result = L"你最终放置了"; result += std::to_wstring(times - 1); result += L"个方块,清除了"; result += std::to_wstring(erased_line); result += L"行,已暂停游戏(esc退出)"; outtext(result.c_str()); while (true) { if (_kbhit()) { if (_getch() == 27) { return 0; } } Sleep(50); } } auto start = std::chrono::high_resolution_clock::now(); while (true) { if (_kbhit()|| std::chrono::high_resolution_clock::now()-start> std::chrono::duration<double>(speed_up ? 0.1 : 0.3)) { break; } } } } else { std::wcout << "无法进行游戏,因为此设备的系统非Windows\n"; Sleep(3000); } } |
39.84 KB, 下载次数: 1
沪公网安备31011502402448© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed