国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

C++制作俄羅斯方塊

2020-05-23 14:05:01
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
俄羅斯方塊寫過(guò)好幾次了,每次的感覺(jué)都不一樣,都有新的收獲。就像達(dá)芬奇畫(huà)雞蛋一樣,雖然都是畫(huà)同樣的雞蛋,但是每次都有不同的收獲。 
 

緣起:

  在玩Codeblocks自帶的俄羅斯方塊時(shí)覺(jué)得不錯(cuò),然而有時(shí)間限制。所以想自己再寫一個(gè)。

程序效果:

C++,俄羅斯方塊

主要內(nèi)容:

  程序中有一個(gè)board數(shù)組,其中有要顯示的部分,也有不顯示的部分,不顯示的部分都存儲(chǔ)1。

  如下圖:

C++,俄羅斯方塊

  shape采用4*4數(shù)組(shape)保存。如:

    0 0 0 0
    0 1 0 0 
    1 1 1 0
    0 0 0 0

  另外用變量row和column保存shape數(shù)組左上角在board中的位置。

  每次下落或左右移動(dòng),先對(duì)row和column做出改變,然后檢測(cè)當(dāng)前row和column下,shape是否重合了為1的格子,如果有重合,就說(shuō)明shape出界了或者到達(dá)下落最低點(diǎn),則要恢復(fù)row和column值。另外,如果是下落,還要將shape放在board上,并產(chǎn)生新的shape。

  旋轉(zhuǎn)時(shí),先對(duì)shape數(shù)組進(jìn)行旋轉(zhuǎn)操作,然后檢測(cè)重合,如果有重合,則反向旋轉(zhuǎn)回來(lái)。

代碼:

#if defined(UNICODE) && !defined(_UNICODE)#define _UNICODE#elif defined(_UNICODE) && !defined(UNICODE)#define UNICODE#endif#include <tchar.h>#include <windows.h>#include <pthread.h>#include <stdio.h>#include <time.h>/*-----------------宏定義--------------------------------------------------------*/#define WIDTH 180#define HEIGHT 400#define LONG_SLEEP 300#define BKCOLOR RGB(238,238,238)//背景色/*-----------------變量----------------------------------------------------------*/static int shapes[7][4][4];//存儲(chǔ)7個(gè)形狀static int high_score[4]= {0,0,0,0};//前三個(gè)元素存儲(chǔ)最高分,最后一個(gè)元素存儲(chǔ)此次得分static int **shape;//當(dāng)前形狀static int **board;static int M=15;//顯示的列數(shù)static int N=30;//顯示的行數(shù)static int MM=M+8;//board的列數(shù)static int NN=N+4;//board的行數(shù)static int LEFT=4;//顯示的最左一列static int RIGHT=LEFT+M-1;//顯示的最右一列static int TOP=0;//顯示的最上一列static int BOTTOM=N-1;//顯示的最下一列static int score=0;static int row=0;//形狀所在行static int column=MM/2;//形狀坐在列static bool is_pause=false;static HBRUSH grey_brush =CreateSolidBrush (RGB(210,210,210));static HBRUSH white_brush =CreateSolidBrush (RGB(130,130,130));static HBRUSH bk_brush =CreateSolidBrush (BKCOLOR);static HPEN hPen = CreatePen(PS_SOLID,1,RGB(147,155,166));static int lattices_top=40;//上面留白static int lattices_left=20;//左側(cè)留白static int width=WIDTH/M;//每個(gè)格子的寬度static int height=(HEIGHT-lattices_top)/N;//每個(gè)格子的高度/*-----------------函數(shù)-----------------------------------------------------------*/void add_score() ;bool check_is_lose() ;void clear_up() ;//消除沒(méi)有空格子的行void* down_thread_function(void * args) ;//形狀下落進(jìn)程要執(zhí)行的函數(shù)void exit_game(HWND hwnd) ;void give_new_shape() ;//隨機(jī)生成一個(gè)新形狀int handle_key(HWND hwnd,WPARAM wParam) ;int init_down_thread(HWND hwnd) ;//初始化形狀下落進(jìn)程int init_game(HWND hwnd) ;//初始化游戲程序void init_play() ;//初始化游戲數(shù)據(jù)bool is_legel() ;//檢測(cè)形狀在當(dāng)前位置是否合法(即是否重合了非空的格子)int load_scores(int* a) ;//讀取游戲最高分?jǐn)?shù)據(jù)int load_shape() ;//從文件中加載7個(gè)形狀void lose_game(HWND hwnd) ;int move_down(HWND hwnd) ;//形狀下落int move_lr(HWND hwnd,int lr) ;//形狀左右移動(dòng)void paint_lattice(HDC hdc,int x,int y,int color) ;//顯示一個(gè)格子void paint_UI(HDC hdc) ;//畫(huà)界面void reset_rc() ;void rerotate_matrix(int mn) ;//順時(shí)針旋轉(zhuǎn)一個(gè)行列數(shù)為mn的方陣void rotate_matrix(int mn) ;//逆時(shí)針旋轉(zhuǎn)一個(gè)行列數(shù)為mn的方陣int rotate_shape(HWND hwnd) ;//旋轉(zhuǎn)當(dāng)前形狀并更新界面bool save_score(HWND hwnd) ;//保存最高分?jǐn)?shù)據(jù)void shape_to_ground() ;//當(dāng)前形狀落地之后,更新boardbool sort_scores(int* a) ;//對(duì)最高分和此次得分排序,若創(chuàng)造新紀(jì)錄則返回truevoid update_UI(HWND hwnd) ;//更新界面,僅更新Rect區(qū)域(形狀所在的那幾行)內(nèi)void update_UI_all(HWND hwnd) ;//更新界面,更新整個(gè)界面int write_scores(int* a) ;//寫最高分?jǐn)?shù)據(jù)/* Declare Windows procedure */LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);/* Make the class name into a global variable */TCHAR szClassName[ ] = _T("Tris");int WINAPI WinMain (HINSTANCE hThisInstance,          HINSTANCE hPrevInstance,          LPSTR lpszArgument,          int nCmdShow) {  HWND hwnd;        /* This is the handle for our window */  MSG messages;      /* Here messages to the application are saved */  WNDCLASSEX wincl;    /* Data structure for the windowclass */  /* The Window structure */  wincl.hInstance = hThisInstance;  wincl.lpszClassName = szClassName;  wincl.lpfnWndProc = WindowProcedure;   /* This function is called by windows */  wincl.style = CS_DBLCLKS;         /* Catch double-clicks */  wincl.cbSize = sizeof (WNDCLASSEX);  /* Use default icon and mouse-pointer */  wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);  wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);  wincl.hCursor = LoadCursor (NULL, IDC_ARROW);  wincl.lpszMenuName = NULL;         /* No menu */  wincl.cbClsExtra = 0;           /* No extra bytes after the window class */  wincl.cbWndExtra = 0;           /* structure or the window instance */  /* Use Windows's default colour as the background of the window */  wincl.hbrBackground =bk_brush;  /* Register the window class, and if it fails quit the program */  if (!RegisterClassEx (&wincl))    return 0;  /* The class is registered, let's create the program*/  hwnd = CreateWindowEx (        0,          /* Extended possibilites for variation */        szClassName,     /* Classname */        _T("Tris"),    /* Title Text */        WS_OVERLAPPEDWINDOW, /* default window */        CW_USEDEFAULT,    /* Windows decides the position */        CW_USEDEFAULT,    /* where the window ends up on the screen */        WIDTH+200,         /* The programs width */        HEIGHT+70,         /* and height in pixels */        HWND_DESKTOP,    /* The window is a child-window to desktop */        NULL,        /* No menu */        hThisInstance,    /* Program Instance handler */        NULL         /* No Window Creation data */      );  /* Make the window visible on the screen */  ShowWindow (hwnd, nCmdShow);  /* Run the message loop. It will run until GetMessage() returns 0 */  while (GetMessage (&messages, NULL, 0, 0)) {    /* Translate virtual-key messages into character messages */    TranslateMessage(&messages);    /* Send message to WindowProcedure */    DispatchMessage(&messages);  }  /* The program return-value is 0 - The value that PostQuitMessage() gave */  return messages.wParam;}//從文件中加載7個(gè)形狀int load_shape() {  FILE* f=fopen("shapes.txt","rb");  if(f==NULL) {    return -1;  }  for(int i=0; i<7; i++) {    for(int j=0; j<4; j++) {      for(int k=0; k<4; k++) {        if(fscanf(f,"%d",&shapes[i][j][k])!=1) {          return -1;        }      }    }  }  fclose(f);  return 0;}//隨機(jī)生成一個(gè)新形狀void give_new_shape() {  int shape_num=rand()%7;  for(int i=0; i<4; i++) {    for(int j=0; j<4; j++) {      shape[i][j]=shapes[shape_num][i][j];    }  }}void add_score() {  score+=100;}//消除沒(méi)有空格子的行void clear_up() {  for(int i=row; i<=row+3; i++) {    if(i>BOTTOM)continue;    bool there_is_blank=false;    for(int j=LEFT; j<=RIGHT; j++) {      if(board[i][j]==0) {        there_is_blank=true;        break;      }    }    if(!there_is_blank) {      add_score();      for(int r=i; r>=1; r--) {        for(int c=LEFT; c<=RIGHT; c++) {          board[r][c]=board[r-1][c];        }      }    }  }}//檢測(cè)形狀在當(dāng)前位置是否合法(即是否重合了非空的格子)bool is_legel() {  for(int i=0; i<4; i++) {    for(int j=0; j<4; j++) {      if(shape[i][j]==1&&board[row+i][column+j]==1) {        return false;      }    }  }  return true;}//逆時(shí)針旋轉(zhuǎn)一個(gè)行列數(shù)為mn的方陣void rotate_matrix(int mn) {  int** a=shape;  int s=0;  for(int n=mn; n>=1; n-=2) {    for(int i=0; i<n-1; i++) {      int t=a[s+i][s];      a[s+i][s]=a[s][s+n-i-1];      a[s][s+n-i-1]=a[s+n-i-1][s+n-1];      a[s+n-i-1][s+n-1]=a[s+n-1][s+i];      a[s+n-1][s+i]=t;    }    s++;  }}//順時(shí)針旋轉(zhuǎn)一個(gè)行列數(shù)為mn的方陣void rerotate_matrix(int mn) {  int** a=shape;  int s=0;  for(int n=mn; n>=1; n-=2) {    for(int i=0; i<n-1; i++) {      int t=a[s+i][s];      a[s+i][s]=a[s+n-1][s+i];      a[s+n-1][s+i]=a[s+n-i-1][s+n-1];      a[s+n-i-1][s+n-1]=a[s][s+n-i-1];      a[s][s+n-i-1]=t;    }    s++;  }}//顯示一個(gè)格子void paint_lattice(HDC hdc,int x,int y,int color) {  if(x<TOP||x>BOTTOM||y<LEFT||y>RIGHT) {    return ;  }  x-=TOP;  y-=LEFT;  int left=lattices_left+y*width;  int right=lattices_left+y*width+width;  int top=lattices_top+x*height;  int bottom=lattices_top+x*height+height;  MoveToEx (hdc,left,top, NULL) ;  LineTo (hdc,right,top) ;  MoveToEx (hdc,left,top, NULL) ;  LineTo (hdc,left,bottom) ;  MoveToEx (hdc,left,bottom, NULL) ;  LineTo (hdc,right,bottom) ;  MoveToEx (hdc,right,top, NULL) ;  LineTo (hdc,right,bottom) ;  SelectObject(hdc, grey_brush);  if(color==0) {    SelectObject(hdc, white_brush);  }  Rectangle(hdc,left,top,right,bottom);}//更新界面,僅更新Rect區(qū)域(形狀所在的那幾行)內(nèi)void update_UI(HWND hwnd) {  static RECT rect;  rect.left=lattices_left;  rect.right=lattices_left+M*width+width;  rect.top=lattices_top+(row-1)*height;  rect.bottom=lattices_top+(row+4)*height;  InvalidateRect (hwnd,&rect, false) ;}//更新界面,更新整個(gè)界面void update_UI_all(HWND hwnd) {  InvalidateRect (hwnd,NULL, false) ;}//畫(huà)界面void paint_UI(HDC hdc) {  SetBkColor(hdc,BKCOLOR);  SelectObject(hdc,hPen); //選用畫(huà)筆  char score_str[20];  sprintf(score_str,"Score:%d",score);  TextOut(hdc,10,10,score_str,strlen(score_str));  sprintf(score_str,"Highest Scores:");  TextOut(hdc,WIDTH+50,50,score_str,strlen(score_str));  for(int i=0; i<3; i++) {    sprintf(score_str,"%d",high_score[i]);    TextOut(hdc,WIDTH+50,50+(i+1)*20,score_str,strlen(score_str));  }  for(int i=TOP; i<=BOTTOM; i++) {    for(int j=LEFT; j<=RIGHT; j++) {      paint_lattice(hdc,i,j,board[i][j]);    }  }  for(int i=0; i<4; i++) {    for(int j=0; j<4; j++) {      if(shape[i][j]==1)        paint_lattice(hdc,row+i,column+j,shape[i][j]);    }  }}//旋轉(zhuǎn)當(dāng)前形狀并更新界面int rotate_shape(HWND hwnd) {  int mn=4;  rotate_matrix(mn);  if(!is_legel()) {    rerotate_matrix(mn);  }  update_UI(hwnd);}void reset_rc() {  row=0;  column=MM/2-2;}//讀取游戲最高分?jǐn)?shù)據(jù)int load_scores(int* a) {  FILE* f=fopen("scores.txt","r");  if(f==NULL)return -1;  fscanf(f,"%d%d%d",&a[0],&a[1],&a[2]);  return 0;}//初始化游戲數(shù)據(jù)void init_play() {  load_scores(high_score);  for(int i=0; i<NN; i++) {    for(int j=0; j<MM; j++) {      board[i][j]=0;    }  }  for(int i=0; i<N; i++) {    for(int j=0; j<LEFT; j++) {      board[i][j]=1;    }  }  for(int i=0; i<N; i++) {    for(int j=RIGHT+1; j<MM; j++) {      board[i][j]=1;    }  }  for(int i=BOTTOM+1; i<NN; i++) {    for(int j=0; j<MM; j++) {      board[i][j]=1;    }  }  reset_rc();  score=0;  give_new_shape();  is_pause=false;  return ;}bool check_is_lose() {  if(row==0)return true;  return false;}//對(duì)最高分和此次得分排序,若創(chuàng)造新紀(jì)錄則返回truebool sort_scores(int* a) {  int temp=a[3];  for(int i=0; i<4; i++) {    for(int j=0; j<3; j++) {      if(a[j]<a[j+1]) {        int t=a[j];        a[j]=a[j+1];        a[j+1]=t;      }    }  }  if(temp>a[3])return true;  return false;}//寫最高分?jǐn)?shù)據(jù)int write_scores(int* a) {  FILE* f=fopen("scores.txt","w");  if(f==NULL)return -1;  fprintf(f,"%d/n%d/n%d/n",a[0],a[1],a[2]);  return 0;}//保存最高分?jǐn)?shù)據(jù)bool save_score(HWND hwnd) {  high_score[3]=score;  bool made_record=sort_scores(high_score);  if(write_scores(high_score)!=0) {    MessageBox(hwnd,"Write file error.Program will exit.","Error",NULL);    DestroyWindow(hwnd);  }  return made_record;}void lose_game(HWND hwnd) {  if(is_pause)return ;  is_pause=true;  char message[200]="You lose the Game./n";  char title[50]="Game Over";  if(save_score(hwnd)) {    strcat(message,"You have made a new record./n");    char score_str[100];    sprintf(score_str,"The Highest Scores:/n%d/n%d/n%d/n",high_score[0],high_score[1],high_score[2]);    strcat(message,score_str);  }  strcat(message,"/nPlay again?/n");  if(MessageBox(hwnd,message,title,MB_YESNO)==IDYES) {    init_play();    update_UI_all(hwnd);  } else {    exit(0);  }}void exit_game(HWND hwnd) {  is_pause=true;  char message[200]="";  char title[50]="Exit";  if(save_score(hwnd)) {    strcat(message,"You have made a new record./n");    char score_str[100];    sprintf(score_str,"The Highest Scores:/n%d/n%d/n%d/n",high_score[0],high_score[1],high_score[2]);    strcat(message,score_str);    MessageBox(hwnd,message,title,NULL);  }  exit(0);}//當(dāng)前形狀落地之后,更新boardvoid shape_to_ground() {  for(int i=0; i<4; i++) {    for(int j=0; j<4; j++) {      board[row+i][column+j]=shape[i][j]==1?1:board[row+i][column+j];    }  }}//形狀下落int move_down(HWND hwnd) {  row++;  if(!is_legel()) {    row--;    if(check_is_lose()) {      lose_game(hwnd);      return 0;    }    shape_to_ground();    clear_up();    update_UI_all(hwnd);    reset_rc();    give_new_shape();  }  update_UI(hwnd);}//進(jìn)程參數(shù)結(jié)構(gòu)體struct thread_arg {  HWND arg_hwnd;};//形狀下落進(jìn)程要執(zhí)行的函數(shù)void* down_thread_function(void * args) {  thread_arg *arg=(thread_arg*)args;  HWND dhwnd=arg->arg_hwnd;  while(true) {    if(is_pause) {      Sleep(300);      continue;    }    move_down(dhwnd);    Sleep(LONG_SLEEP);  }}//初始化形狀下落進(jìn)程int init_down_thread(HWND hwnd) {  int ret;  pthread_t t;  thread_arg *argp=new thread_arg;  argp->arg_hwnd=hwnd;  ret=pthread_create(&t,NULL,down_thread_function,argp);  delete argp;  if(ret!=0) {    return -1;  }  return 0;}//初始化游戲程序int init_game(HWND hwnd) {  board=new int*[NN];  for(int i=0; i<NN; i++) {    board[i]=new int[MM];  }  shape=new int*[4];  for(int i=0; i<4; i++) {    shape[i]=new int[4];  }  srand(time(0));  if(load_shape()!=0) {    MessageBox(hwnd,"Read file error.Program will exit.","Error",NULL);    exit(-1);  }  init_play();  update_UI_all(hwnd);  if(init_down_thread(hwnd)!=0) {    MessageBox(hwnd,"Thread error.Program will exit.","Error",NULL);    exit(-1);  }  return 0;}//形狀左右移動(dòng)int move_lr(HWND hwnd,int lr) {  int temp=column;  if(lr==0)column--;  else {    column++;  }  if(!is_legel()) {    column=temp;  }  update_UI(hwnd);}int handle_key(HWND hwnd,WPARAM wParam) {  if(wParam==VK_ESCAPE) {//ESC退出    exit_game(hwnd);  }  if(wParam==VK_SPACE) {//空格暫停    is_pause=!is_pause;  }  if(is_pause==true) {    Sleep(300);    return 0;  }  if(wParam==VK_UP) {    rotate_shape(hwnd);  }  if(wParam==VK_DOWN) {    move_down(hwnd);  }  if(wParam==VK_LEFT) {    move_lr(hwnd,0);  }  if(wParam==VK_RIGHT) {    move_lr(hwnd,1);  }  return 0;}/* This function is called by the Windows function DispatchMessage() */HWND hwnd;LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {  static HDC hdc;  static HDC hdcBuffer;  static HBITMAP hBitMap;  static PAINTSTRUCT ps ;  switch (message) {        /* handle the messages */  case WM_CREATE:    init_game(hwnd);    break;  case WM_KEYDOWN:    handle_key(hwnd,wParam);    break;  case WM_DESTROY:    exit_game(hwnd);    PostQuitMessage (0);    /* send a WM_QUIT to the message queue */    break;  case WM_PAINT:    hdc = BeginPaint (hwnd, &ps) ;    paint_UI(hdc);    EndPaint (hwnd, &ps) ;    break;  default:           /* for messages that we don't deal with */    return DefWindowProc (hwnd, message, wParam, lParam);  }  return 0;}


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 罗定市| 桦川县| 达州市| 武鸣县| 从江县| 益阳市| 陆良县| 金乡县| 临江市| 图们市| 龙海市| 万盛区| 盐池县| 博野县| 江永县| 云龙县| 孟村| 清水县| 德惠市| 石家庄市| 南平市| 定日县| 大冶市| 洞头县| 乾安县| 横峰县| 博客| 涿州市| 淮安市| 泊头市| 星子县| 黔西县| 台南县| 清水河县| 确山县| 阿鲁科尔沁旗| 海宁市| 汕头市| 娱乐| 塔河县| 孝感市|