欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實(shí)現(xiàn)俄羅斯方塊

 更新時(shí)間:2020年01月15日 10:05:02   作者:acararduino  
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)俄羅斯方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了C++實(shí)現(xiàn)俄羅斯方塊的具體代碼,供大家參考,具體內(nèi)容如下

工具:vc++2010,圖庫(kù):EasyX

先看效果圖片

純手寫(xiě),沒(méi)有面向?qū)ο笏枷?看全部源碼

#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;//下一個(gè)方塊種類(lèi)
int BlockIndex = -1;//當(dāng)前方塊種類(lèi)
int score = 0;//分?jǐn)?shù)
int rank = 0;//等級(jí)
int visit[30][15];//訪問(wèn)數(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(){
 //初始化畫(huà)布
 initgraph(550,660);

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


 //設(shè)置文本字體樣式
 setfont(0,30,_T("微軟雅黑"));
 setcolor(YELLOW);
 outtextxy(150,200,_T("俄羅斯方塊"));
 setfont(0,10,_T("微軟雅黑"));
 outtextxy(175,300,_T("IT編程從俄羅斯方塊開(kāi)始"));
 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("下一個(gè)"));
 setcolor(RED);
 outtextxy(405,280,_T("分?jǐn)?shù)"));
 sprintf(str,"%d",score);
 outtextxy(415,310,str);
 outtextxy(405,375,_T("等級(jí)"));
 sprintf(str,"%d",rank);
 outtextxy(415,405,str);
 setcolor(LIGHTBLUE);
 outtextxy(390,475,"操作說(shuō)明");
 outtextxy(390,500,"↑:旋轉(zhuǎn)");
 outtextxy(390,525,"↓:下降");
 outtextxy(390,550,"→:向右");
 outtextxy(390,575,"←:向左");
 outtextxy(390,600,"空格:暫停");



}
void drawBlock(int x,int y){//右上角畫(huà)出方塊
 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){//按索引畫(huà)出什么方塊指定位置方塊指定方向
 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);//清除右上角方塊
 //隨機(jī)選擇一種方塊
 srand(time(NULL));//時(shí)間函數(shù)的返回值產(chǎn)生隨機(jī)數(shù)種子
 NextIndex = rand()%BLOCK_COUNT;
 drawBlock(391,71);//畫(huà)出方塊

}
//如果在指定位置可以向方向移動(dòng)
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(){//游戲是否結(jié)束
 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;
 }
 }
}//判斷當(dāng)前方向是否可以轉(zhuǎn)到指定方向
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,"■");
 }
 }
 }
 //清除最頂層那一行,就是行標(biāo)位0的哪一行
 setcolor(BLACK);
 for(int j = 0;j<15;j++){
 visit[0][j] = 0;
 outtextxy(20*j+minX,minY,"■");
 }
}
void updataGrade(){
//更新等級(jí)提示
//假設(shè):50分一級(jí)
 char str[10];
 rank = score/50;
 sprintf(str,"%d",rank);
 outtextxy(425,405,str);
 //更新速度,等級(jí)越高速度越快,speed越小
 //最慢是500,最快是50
 speed = 500-rank*50;
 if(speed<=0){
 speed = 50;
 }
}
void addScore(int lines){//更新分?jǐn)?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行沒(méi)有滿,即表示有空位,此時(shí)j<15
 //2.第i行已經(jīng)滿了,j就大于等于15
 if(j>=15){
 //此時(shí)第i行已經(jīng)滿了,就需要消除第i行
 clear_down(i);//清除第i行,并把上面的行都下移動(dòng)
 i++;
 clearLines++;
 }
 }
 //更新分?jǐn)?shù)
 addScore(clearLines);
 //更新等級(jí)
 updataGrade();
}
void move(){
 int x = START_X;
 int y = START_Y;
 int k = 0;
 int curSpeed = speed;
 block_dir_t blockDir = BLOCK_UP;

 //檢查游戲是否結(jié)束
 failCheck();
 while(1){
 if(kbhit()){
 int key = getch();
 if(KEY_SPACE == key){
 getch();
 }
 }
 //清除當(dāng)前方塊
 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){//右移動(dòng)
 if(moveable(x,y+k+20,MOVE_RIGHT,blockDir)){
  x+=20;
 }
 }else if(KEY_LEFT == key){//左移動(dòng)
 if(moveable(x,y+k+20,MOVE_LEFT,blockDir)){
  x-=20; 
 }
 }
 }
 k+=20;
 //繪制當(dāng)前方塊
 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;
 //繪制方塊從頂部掉下來(lái)
 drawBlock(START_X,START_Y);
 //新出現(xiàn)的方塊等一下
 Sleep(100);
 //右上角繪制下一個(gè)方塊
 nextblock();
 //向下降落的動(dòng)作
 move();
}

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

分析項(xiàng)目:

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

總結(jié):從界面開(kāi)始到完整的架構(gòu),功能后實(shí)現(xiàn),一步一步,邏輯嚴(yán)謹(jǐn),思路清晰,注釋在代碼里。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論