溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++怎么實現(xiàn)俄羅斯方塊

發(fā)布時間:2021-04-14 11:31:24 來源:億速云 閱讀:369 作者:小新 欄目:編程語言

小編給大家分享一下C++怎么實現(xiàn)俄羅斯方塊,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

具體內容如下

工具:vc++2010,圖庫:EasyX

先看效果圖片

C++怎么實現(xiàn)俄羅斯方塊

純手寫,沒有面向對象思想,看全部源碼

#include <stdio.h>
#include <graphics.h>
#include <time.h>
#include <conio.h>

#define BLOCK_COUNT 5
#define BLOCK_WIDTH 5
#define BLOCK_HEIGHT 5
#define UNIT_SIZE 20
#define START_X  130

#define START_Y  30
#define KEY_UP  72
#define KEY_RIGHT 77
#define KEY_LEFT  75
#define KEY_SPACE 32
#define KEY_DOWN  76
typedef enum{
 BLOCK_UP,
 BLOCK_RIGHT,
 BLOCK_DOWN, 
 BLOCK_LEFT
}block_dir_t;
typedef enum{
 MOVE_DOWN,
 MOVE_LEFT,
 MOVE_RIGHT

}move_dir_t;
int speed = 500;
int NextIndex = -1;//下一個方塊種類
int BlockIndex = -1;//當前方塊種類
int score = 0;//分數(shù)
int rank = 0;//等級
int visit[30][15];//訪問數(shù)組
int markcolor[30][15];//表示顏色
int minX = 30;
int minY = 30;
int color[BLOCK_COUNT]={
 GREEN,CYAN,MAGENTA,BROWN,YELLOW
};
int block[BLOCK_COUNT*4][BLOCK_HEIGHT][BLOCK_WIDTH] = {
 //條形方塊
 {
 0,0,0,0,0,
 0,0,1,0,0,
 0,0,1,0,0,
 0,0,1,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,0,0,0,
 0,1,1,1,0,
 0,0,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,1,0,0,
 0,0,1,0,0,
 0,0,1,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,0,0,0,
 0,1,1,1,0,
 0,0,0,0,0,
 0,0,0,0,0},
 //L形方塊
 {
 0,0,0,0,0,
 0,0,1,0,0,
 0,0,1,0,0,
 0,0,1,1,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,0,0,0,
 0,1,1,1,0,
 0,1,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,1,1,0,0,
 0,0,1,0,0,
 0,0,1,0,0,
 0,0,0,0,0}, 
 {
 0,0,0,0,0,
 0,0,0,1,0,
 0,1,1,1,0,
 0,0,0,0,0,
 0,0,0,0,0}, 
 //田字型
 {
 0,0,0,0,0,
 0,1,1,0,0,
 0,1,1,0,0,
 0,0,0,0,0,
 0,0,0,0,0}, 
 {
 0,0,0,0,0,
 0,1,1,0,0,
 0,1,1,0,0,
 0,0,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,1,1,0,0,
 0,1,1,0,0,
 0,0,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,1,1,0,0,
 0,1,1,0,0,
 0,0,0,0,0,
 0,0,0,0,0},
 //T字形方塊
 {
 0,0,0,0,0,
 0,1,1,1,0,
 0,0,1,0,0,
 0,0,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,0,1,0,
 0,0,1,1,0,
 0,0,0,1,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,1,0,0,
 0,1,1,1,0,
 0,0,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,1,0,0,
 0,0,1,1,0,
 0,0,1,0,0,
 0,0,0,0,0},
 //Z字形方塊
 {
 0,0,0,0,0,
 0,1,1,0,0,
 0,0,1,1,0,
 0,0,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,0,1,0,
 0,0,1,1,0,
 0,0,1,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,1,1,0,0,
 0,0,1,1,0,
 0,0,0,0,0,
 0,0,0,0,0},
 {
 0,0,0,0,0,
 0,0,0,1,0,
 0,0,1,1,0,
 0,0,1,0,0,
 0,0,0,0,0}
};

//歡迎界面
void welcome(){
 //初始化畫布
 initgraph(550,660);

 //設置窗口標題
 HWND window = GetHWnd();//獲取窗口
 SetWindowText(window,_T("俄羅斯方塊 GWF"));//設置窗口標題


 //設置文本字體樣式
 setfont(0,30,_T("微軟雅黑"));
 setcolor(YELLOW);
 outtextxy(150,200,_T("俄羅斯方塊"));
 setfont(0,10,_T("微軟雅黑"));
 outtextxy(175,300,_T("IT編程從俄羅斯方塊開始"));
 Sleep(3000);
 
}
//初始化游戲屏幕
void initGameScene(){
 char str[16];
 //清除屏幕
 cleardevice();

 rectangle(27,27,336,635);
 rectangle(29,29,334,633);
 rectangle(370,50,515,195);
 setfont(24,0,_T("楷體"));
 setcolor(LIGHTGRAY);
 outtextxy(405,215,_T("下一個"));
 setcolor(RED);
 outtextxy(405,280,_T("分數(shù)"));
 sprintf(str,"%d",score);
 outtextxy(415,310,str);
 outtextxy(405,375,_T("等級"));
 sprintf(str,"%d",rank);
 outtextxy(415,405,str);
 setcolor(LIGHTBLUE);
 outtextxy(390,475,"操作說明");
 outtextxy(390,500,"↑:旋轉");
 outtextxy(390,525,"↓:下降");
 outtextxy(390,550,"→:向右");
 outtextxy(390,575,"←:向左");
 outtextxy(390,600,"空格:暫停");



}
void drawBlock(int x,int y){//右上角畫出方塊
 setcolor(color[NextIndex]);
 setfont(23,0,"楷體");
 for(int i= 0;i<BLOCK_HEIGHT;i++){
 for(int j= 0;j<BLOCK_WIDTH;j++){
 if(block[NextIndex*4][i][j] == 1){
 outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");
 }
  }
 }
}
void drawBlock(int x,int y,int blockIndex,block_dir_t dir){//按索引畫出什么方塊指定位置方塊指定方向
 setcolor(color[blockIndex]);
 setfont(23,0,"楷體");
 int id = blockIndex*4+dir;
 for(int i= 0;i<BLOCK_HEIGHT;i++){
 for(int j= 0;j<BLOCK_WIDTH;j++){
 if(block[id][i][j] == 1){
 outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");
 }
  }
 }
}

void clearBlock(int x, int y){
 setcolor(BLACK);
 setfont(23,0,"楷體");
 for(int i= 0;i<BLOCK_HEIGHT;i++){
 for(int j= 0;j<BLOCK_WIDTH;j++){
 outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");
  }
 }
}
void clearBlock(int x, int y,block_dir_t dir){
 setcolor(BLACK);
 int id = BlockIndex *4+dir;
 y+=START_Y;
 for(int i= 0;i<BLOCK_HEIGHT;i++){
 for(int j= 0;j<BLOCK_WIDTH;j++){
 if(block[id][i][j] == 1){
 outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■");
 }
  }
 }
}
void nextblock(){
 clearBlock(391,71);//清除右上角方塊
 //隨機選擇一種方塊
 srand(time(NULL));//時間函數(shù)的返回值產生隨機數(shù)種子
 NextIndex = rand()%BLOCK_COUNT;
 drawBlock(391,71);//畫出方塊

}
//如果在指定位置可以向方向移動
int moveable(int x0,int y0,move_dir_t moveDir,block_dir_t blockDir){
 int x = (y0 - minY)/UNIT_SIZE;
 int y = (x0 - minX)/UNIT_SIZE;
 int id = BlockIndex * 4+blockDir;
 int ret = 1;
 if(moveDir == MOVE_DOWN){
 for(int i = 0;i<5;i++){
 for(int j = 0;j<5;j++){
 if(block[id][i][j] == 1 &&(x+i+1>=30 || visit[x+i+1][y+j]==1)){
  ret=0;
 }
 }
 }
 }else if(moveDir == MOVE_LEFT){
 for(int i = 0;i<5;i++){
 for(int j = 0;j<5;j++){
 if(block[id][i][j] == 1 &&(y+j==0 || visit[x+i][y+j-1]==1)){
  ret=0;
 }
 }
 }
 }else if(moveDir == MOVE_RIGHT){
 for(int i = 0;i<5;i++){
 for(int j = 0;j<5;j++){
 if(block[id][i][j] == 1 &&(y+j+1>=15 || visit[x+i][y+j+1]==1)){
  ret=0;
 }
 }
 }
 }
 return ret;
}
void failCheck(){//游戲是否結束
 if(!moveable(START_X,START_Y,MOVE_DOWN,BLOCK_UP)){
 setcolor(WHITE);
 setfont(45,0,"隸體");
 outtextxy(75,300,"GAME OVER!");
 Sleep(1000);
 system("pause");
 closegraph();
 exit(0);
 }
}
int wait(int interval){//等待
 int count = interval/5;
 for(int i = 0;i<count;i++){
 Sleep(5);
 if(kbhit()){
 return 0;
 }
 }
}//判斷當前方向是否可以轉到指定方向
int rotatable(int x,int y,block_dir_t dir){
 int id= BlockIndex * 4 +dir;
 int xIndex = (y-minY)/20;
 int yIndex = (x-minX)/20;

 if(!moveable(x,y,MOVE_DOWN,dir)){
 return 0 ;
 }
 for(int i = 0;i<5;i++){
 for(int j = 0;j<5;j++){
 if(block[id][i][j] ==1&&(yIndex+j<0||yIndex+j>=15||visit[xIndex+i][yIndex+j] ==1)){
 return 0 ;
 }
 }
 }
 return 1;
}
void mark(int x,int y,int blockIndex,block_dir_t dir){
 int id = blockIndex*4+dir;
 int x2 = (y-minY)/20;
 int y2 = (x-minX)/20;
 for(int i=0;i<5;i++){
 for(int j=0;j<5;j++){
 if(block[id][i][j] ==1){
 visit[x2+i][y2+j]=1;
 markcolor[x2+i][y2+j]=color[blockIndex];
 }
 }
 }
}
void clear_down(int x){//消除第x行,并把上面的行都下移
 for(int i = x;i>0;i--){
 for(int j=0;j<15;j++){
 if(visit[i-1][j]){//上面有東西
 visit[i][j]=1;
 markcolor[i][j]=markcolor[i-1][j];
 setcolor(markcolor[i][j]); 
 outtextxy(20*j+minX,20*i+minY,"■");
 }else{
 visit[i][j] =0;
 setcolor(BLACK);
 outtextxy(20*j+minX,20*i+minY,"■");
 }
 }
 }
 //清除最頂層那一行,就是行標位0的哪一行
 setcolor(BLACK);
 for(int j = 0;j<15;j++){
 visit[0][j] = 0;
 outtextxy(20*j+minX,minY,"■");
 }
}
void updataGrade(){
//更新等級提示
//假設:50分一級
 char str[10];
 rank = score/50;
 sprintf(str,"%d",rank);
 outtextxy(425,405,str);
 //更新速度,等級越高速度越快,speed越小
 //最慢是500,最快是50
 speed = 500-rank*50;
 if(speed<=0){
 speed = 50;
 }
}
void addScore(int lines){//更新分數(shù),line表示消除的行數(shù)
 char str[32];
 setcolor(RED);
 score+=lines*10;
 sprintf(str,"%d",score);
 outtextxy(415,310,str);
}
void check(){//消去方塊
 int i,j;
 int clearLines =0;
 for(i=29;i>=0;i--){
 for(j=0;j<15 && visit[i][j];j++);
 //執(zhí)行到此處有兩種情況,
 //1.第I行沒有滿,即表示有空位,此時j<15
 //2.第i行已經滿了,j就大于等于15
 if(j>=15){
 //此時第i行已經滿了,就需要消除第i行
 clear_down(i);//清除第i行,并把上面的行都下移動
 i++;
 clearLines++;
 }
 }
 //更新分數(shù)
 addScore(clearLines);
 //更新等級
 updataGrade();
}
void move(){
 int x = START_X;
 int y = START_Y;
 int k = 0;
 int curSpeed = speed;
 block_dir_t blockDir = BLOCK_UP;

 //檢查游戲是否結束
 failCheck();
 while(1){
 if(kbhit()){
 int key = getch();
 if(KEY_SPACE == key){
 getch();
 }
 }
 //清除當前方塊
 clearBlock(x,k,blockDir);
 if(kbhit()){
 int key = getch();
 
 if(KEY_UP == key){//變形
 block_dir_t nextDir = (block_dir_t)((blockDir+1)%4);
 if(rotatable(x,y+k,nextDir)){
  blockDir= nextDir;
 }
 }else if(KEY_DOWN == key){//鄉(xiāng)下加速
 curSpeed = 50;
 }else if(KEY_RIGHT == key){//右移動
 if(moveable(x,y+k+20,MOVE_RIGHT,blockDir)){
  x+=20;
 }
 }else if(KEY_LEFT == key){//左移動
 if(moveable(x,y+k+20,MOVE_LEFT,blockDir)){
  x-=20; 
 }
 }
 }
 k+=20;
 //繪制當前方塊
 drawBlock(x,y+k,BlockIndex,blockDir);
 wait(curSpeed);
 
 //方塊降落到底層的固化處理
 if(!moveable(x,y+k,MOVE_DOWN,blockDir)){
 mark(x,y+k,BlockIndex,blockDir);
 break;
 }
 }
}
void newblock(){
 //確定即將使用的方塊
 BlockIndex = NextIndex;
 //繪制方塊從頂部掉下來
 drawBlock(START_X,START_Y);
 //新出現(xiàn)的方塊等一下
 Sleep(100);
 //右上角繪制下一個方塊
 nextblock();
 //向下降落的動作
 move();
}

int main (void){
 welcome(); 
 initGameScene();
 //產生新方塊 
 nextblock();
 Sleep(500);
 memset(visit,0,sizeof(visit));
 while(1){
 newblock();
 //消除滿行,并更新分數(shù)和速度
 check();
 }
 
 system("pause");
 closegraph();
 
 return 0;
}

分析項目:

1.必須要有歡迎界面
2.搭建合理的邊界,就是游戲范圍
3.邏輯1:先出現(xiàn)右上方的方塊樣式,等待一段時間,將右上方的樣式在游戲區(qū)打印出
4.邏輯2,方塊降落,要擦除原先印記,將1改為0
5.邏輯3,熱鍵控制移動方向,暫停及變形,且不能移動出界,判斷方塊是否還能移動
6.邏輯4,方塊凝固在下方不出界
7.邏輯5,最下面一行方塊疊滿了,消去它并把上面的行都下移(分兩種情況),并且再次檢查這一行
8.邏輯6,計算消除行數(shù)次數(shù),統(tǒng)計分數(shù),控制休眠時間長度
9.邏輯7,每次移動先判斷是否能移動,默認結束程序,在合理游戲區(qū)返回false,結束界面

C++怎么實現(xiàn)俄羅斯方塊

C++怎么實現(xiàn)俄羅斯方塊

C++怎么實現(xiàn)俄羅斯方塊

以上是“C++怎么實現(xiàn)俄羅斯方塊”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

c++
AI