C++實(shí)現(xiàn)俄羅斯方塊游戲
本文實(shí)例為大家分享了C++實(shí)現(xiàn)俄羅斯方塊游戲的具體代碼,供大家參考,具體內(nèi)容如下
使用VS2017編譯
思路:
1.打印出游戲地圖,也就是設(shè)計(jì)游戲地圖類game_interdace,包括設(shè)計(jì)游戲開(kāi)始界面的函數(shù),游戲地圖界面的函數(shù),游戲結(jié)束界面的函數(shù),以及設(shè)計(jì)一些輔助函數(shù)如(設(shè)置光標(biāo)為目標(biāo)點(diǎn),改變顏色,隱藏光標(biāo))來(lái)完成上述設(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();//游戲開(kāi)始界面
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ù)可以這么來(lái)看(0,0),(2,0),(0,2),(2,2)
//由于每個(gè)方塊由"■"的寬度為兩個(gè)字符,所以x坐標(biāo)成雙增長(zhǎng)
{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()//游戲開(kāi)始界面
{
color(2);
gotoxy(30, 2);
std::cout<<" 游戲說(shuō)明 ";
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)簡(jiǎn)單--(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列開(kāi)始到第52列,兩個(gè)字符一個(gè)"■",一共27個(gè)”■“
{
gotoprintf(x, 0);
gotoprintf(x, 26);
}
for (y = 0; y < 27; y++)//從第0行開(kāi)始到第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); //使下落過(guò)程中顏色隨機(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)專題,分享給大家:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用Qt/C++實(shí)現(xiàn)WGS84,高德GCJ-02與百度BD-09坐標(biāo)系間相互轉(zhuǎn)化
這篇文章主要為大家詳細(xì)介紹了如何使用Qt實(shí)現(xiàn)WGS84、高德GCJ-02與百度BD-09坐標(biāo)系間相互轉(zhuǎn)化,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-07-07
C語(yǔ)言圍圈報(bào)數(shù)題目代碼實(shí)現(xiàn)
大家好,本篇文章主要講的是C語(yǔ)言圍圈報(bào)數(shù)題目代碼實(shí)現(xiàn),感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01
詳解C++設(shè)計(jì)模式編程中策略模式的優(yōu)缺點(diǎn)及實(shí)現(xiàn)
這篇文章主要介紹了C++設(shè)計(jì)模式編程中策略模式的優(yōu)缺點(diǎn)及實(shí)現(xiàn),文中討論了策略模式中設(shè)計(jì)抽象接口的繼承和組合之間的區(qū)別,需要的朋友可以參考下2016-03-03
詳解計(jì)數(shù)排序算法及C語(yǔ)言程序中的實(shí)現(xiàn)
技術(shù)排序算法與我們普通接觸的冒泡排序和快速排序等基于元素比較的算法不同,在編程中通過(guò)C語(yǔ)言的數(shù)組能夠清除地表達(dá)出來(lái),這里我們就來(lái)詳解計(jì)數(shù)排序算法及C語(yǔ)言程序中的實(shí)現(xiàn)2016-07-07
C語(yǔ)言中const,volatile,restrict的用法總結(jié)
以下是對(duì)C語(yǔ)言中const,volatile,restrict的用法進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下2013-10-10
C語(yǔ)言冷知識(shí)之預(yù)處理字符串操作符詳解
當(dāng)年學(xué)習(xí)C語(yǔ)言的第一門課就提到過(guò)標(biāo)記(Token)的概念,不過(guò),相信在多年之后你再次聽(tīng)到這個(gè)術(shù)語(yǔ)時(shí)會(huì)一臉懵逼,比如我。因此特地翻了翻資料,整理下來(lái)這些筆記,希望對(duì)大家有所幫助2022-11-11

