C++实现俄罗斯方块(windows API)

本文分享的这些俄罗斯方块代码是我最近放假在家里自己写的,虽然以前有过看别人写的代码,但是那个游戏代码好像不是很全面,因为无法实现全部的方块和实现随机的产生任意方向的方块,现在也基本上是忘光了当时的代码,下面的这些代码是我最近写的,没有参考其他人的代码,真正写俄罗斯方块起来感觉真的是挺难的,关键是在于方块的旋转。当然下面的代码仅仅是一个框架,只能够实现大致上的功能,还不全面,贴出来和大家交流学习。

编译器是code::block  +  MinGW ,感觉CB这个IDE真的是太强大,太棒了,下面的代码直接复制到VC里面运行应该不会出错,有个问题一直不知道怎么解决,就是更新客户区时窗口总是闪不知道有哪位达人能指点我一下。有的都是windows API写的,对windows编程还不是很懂,望大家多多留言,指点一下本人。

#include <windows.h>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
#define CellWidth 20
#define MAP_WIDTH 12
#define MAP_HEIGHT 18
#define ID_TIMER 1
class map_floor;
class Block;
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "CodeBlocksWindowsApp";
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|CS_HREDRAW | CS_VREDRAW;         /* 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 =(HBRUSH) GetStockObject(WHITE_BRUSH);//COLOR_BACKGROUND; 

  /* 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 */
      "Code::Blocks Template Windows App",    /* Title Text */
      WS_OVERLAPPEDWINDOW, /* default window */
      CW_USEDEFAULT,    /* Windows decides the position */
      CW_USEDEFAULT,    /* where the window ends up on the screen */
      CW_USEDEFAULT,         /* The programs width */
      CW_USEDEFAULT,         /* and height in pixels */
      NULL,    /* 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;
} 

enum{e_LINE,e_CORNER,e_STAIR,e_TANCK,e_TIAN};
const int TOTAL_BLOCK_STYLE = 5;//方块类型有4种
class Block
{
  public:
      Block(int x = 100, int y = 100);
      Block(const Block & rh)//复制构造函数,可能没什么用,但是还是定义它吧
      {
        this->m_style = rh.m_style;
        this->m_direct = rh.m_direct;
        for(int i = 0 ; i < 4 ; i ++)
          this->m_block[i] = rh.m_block[i];
      }
      Block & operator = (const Block& rh)//重载=号,实现方块的赋值
      {
        this->m_style = rh.m_style;
        this->m_direct = rh.m_direct;
        for(int i = 0 ; i < 4 ; i ++)
          this->m_block[i] = rh.m_block[i];
        return *this;
      }
      ~Block(){}
  int   create_block(int x = 100 , int y = 100);
  //显示在游戏区内移动的方块
  int   show_block(HDC hdc,const POINT& GameLeftTop);
  //显示将要出现的方块,即游戏区左边的方块
  int   show_next_block(HDC hdc);
  //旋转,该函数比较难实现,代码量也比较大,以后有时间在慢慢优化,关于解析看定义处
  int   rotate();
  //产生随机方块
  int   random_block(); 

  //下面为方块移动的成员函数
  int   get_block_height(){ return m_block[1].y;}
  int   move_down(const RECT& GameClient);
  int   move_left(const RECT& GameClient);
  int   move_right(const RECT& GameClient);
  int   move_up(const RECT& GameClient);
  int   move_to(int x , int y);
  //检测方块是否在游戏区内
//  int   check_block(const map_floor& map, const RECT& GameClent);
  int   check_block(const map_floor& map, const POINT& LeftTopScrCdnt);
  int   print_to_map(map_floor& map , const POINT& LeftTopScrCdnt);
  private:
  int   m_style;//方块的风格样式,具体看定义的枚举变量
  int   m_direct;//方块的方向,是对m_style的具体数据
 POINT   m_block[4];//下标为1的方块是中心坐标,旋转都是围绕着该方块进行,这样可以利于旋转和逻辑清晰
};
class map_floor
{
  public:
    map_floor()
    {
      ZeroMemory(m_block_bar,sizeof(int )*12*18);
    }
    ~map_floor(){}
  void show_block_bar(HDC hdc , const POINT& LeftTopScrCdnt)
  {
    for(int i = 0 ; i < MAP_HEIGHT ; ++ i)
    {
      for(int j = 0 ; j < MAP_WIDTH ; ++ j)
      {
        if(m_block_bar[i][j])
        {
          Rectangle(hdc,LeftTopScrCdnt.x + j*CellWidth , LeftTopScrCdnt.y + i*CellWidth,
                 LeftTopScrCdnt.x + (j+1)*CellWidth , LeftTopScrCdnt.y + (i+1)*CellWidth);
        }
      }
    } 

  }
  friend class Block;
  protected: 

  private: 

  int     m_block_bar[MAP_HEIGHT][MAP_WIDTH];//游戏区的地板,用18*12的二维数组表示 

}; 

Block::Block(int x , int y)
{
//  ZeroMemory(m_block_bar,sizeof(int )*12*18);
  srand( (unsigned)time( NULL ) );//初始化随机数,用于产生方块
//  POINT pt = {100,100};
  create_block(x,y);
}
int Block::random_block()
{
  m_style = rand()%TOTAL_BLOCK_STYLE;
//  m_style = e_CORNER; //测试之用
//  m_style = e_LINE; //测试之用
  if(m_style == e_STAIR || m_style == e_TANCK)
    m_direct = rand()%4;
  else if(m_style == e_LINE)
    m_direct = rand()%2;
  else if(m_style == e_CORNER)
    m_direct = rand()%8;
  else if(m_style == e_TIAN)
    m_direct = 0;
  m_direct = 1; 

}
int  Block::check_block(const map_floor& map, const POINT& LeftTopScrCdnt)
{
  int x , y ; //x , y 为方块相对于地图的坐标,左上角为(0,0)
  for(int i = 0 ; i < 4 ; i ++)
  {
    x = (m_block[i].x - LeftTopScrCdnt.x)/CellWidth;
    y = (m_block[i].y - LeftTopScrCdnt.y)/CellWidth;
    if(x < 0 || x >= MAP_WIDTH || y >= MAP_HEIGHT)//不用检测y < 0 的情况
    return 0;
    if(y < 0) continue;
    if(map.m_block_bar[y][x])
    return 0;
  }
  return 1;
}
int Block::move_down(const RECT& GameClient)//下移,由计时器消息调用
{
  int i;
//  for (i = 0 ; i < 4 ; i ++ )
//  {
//   if(m_block[i].y == GameClient.bottom - CellWidth)
//   return 0;
//  }
  for (i = 0; i < 4 ;i ++ )
  {
    m_block[i].y += CellWidth;
  }
  return 1;
}
int Block::move_up(const RECT& GameClient)
{
  move_to(m_block[1].x,m_block[1].y - CellWidth);
  return 1;
}
int Block::move_left(const RECT& GameClient)
{
  move_to(m_block[1].x - CellWidth,m_block[1].y);
  return 1;
}
int Block::move_right(const RECT& GameClient)
{
  move_to(m_block[1].x + CellWidth , m_block[1].y);
  return 1;
}
int Block::create_block(int x , int y)
{
  m_block[1].x = x;
  m_block[1].y = y;
  random_block();
  rotate();
  return 1;
}
int Block::move_to(int x , int y)
{
  int Vx = x - m_block[1].x;
  int Vy = y - m_block[1].y;
  for(int i = 0 ; i < 4 ; i ++)
  {
    m_block[i].x += Vx;
    m_block[i].y += Vy;
  }
}
int Block::print_to_map(map_floor& map , const POINT& LeftTopScrCdnt)
{
  int x , y;
  int i , j;
  for(i = 0 ; i < 4 ; i ++ )
  {
    x = (m_block[i].x - LeftTopScrCdnt.x)/CellWidth;
    y = (m_block[i].y - LeftTopScrCdnt.y)/CellWidth;
    if(x<0 || x >= MAP_WIDTH || y <0 || y >= MAP_HEIGHT)//为保安全 ,测试之用,完成后将被注释掉
      return 0;
    map.m_block_bar[y][x] = 1 ;
    for(j = 0 ; j < MAP_WIDTH ; j ++)
    {
      if(map.m_block_bar[y][j] != 1)
        break;
    }
    if(MAP_WIDTH == j)
    {
      for(j = 0 ; j < MAP_WIDTH ; j ++)
      {
        map.m_block_bar[y][j] = 5;//数字5代表要消掉的行
      }
    } 

  }
  int idx;
  for(i = 0 ; i < MAP_WIDTH ; i ++)
  {
    for(idx = j = MAP_HEIGHT - 1 ; j >= 0 ; j --)
    {
      if(map.m_block_bar[j][i] != 5)
      {
        map.m_block_bar[idx--][i] = map.m_block_bar[j][i];
      }
    }
    while(idx >= 0)
    {
      map.m_block_bar[idx--][i] = 0;
    }
  }
  return 1;
} 

//下面该函数功能是实现方块旋转,可以说是整个【俄罗斯方块】的难点所在,也是其核心部分
//方块用以数组block【4】表示,其余3个方格都将围绕block【1】旋转,方块由于有不对称方块
//存在,我原本是要分7种,但是后面代码量太大了,所以我将方块根据样式归为了四种,分别是:
//
//e_LINE 线形   就是一条线的那个,这个是对称的方块,只需分两个方向分别为横向和纵向,方向
//        用m_direct保持,其他的方块一样
//
//e_TANCK 坦克形 这个是方块是对称的,分四种方向,根据m_direct对4进行求余的方法可以大大缩减
//        代码量,对于下面两种方块也是利用了求余的方式化简许多,才使得代码不会那么冗余,
//        这是后面我才想到的方法。
//
//e_STAIR 楼梯形 这个方块相对前面两种来说有点难度,主要是因为它不是对称的,但是相对下面的这种
//        来说比较简单,原本我没用对m_direct求余的方法时,我将它分为了e_STAIR_BACK和e_STAIR_FRONT
//        两类来讨论的,后面发现代码可以缩减才将其归为一类只要记住block【0】和block【1】的位置不会
//        变化,变化的是block【2】和block【3】,block【2】相对block【1】上移或下移,x坐标与block【1】
//        相同,block【3】.y一直在block【1】下面一行,相对其左右变化
//
//e_CORNER 角形 这个方块个人觉得是最难旋转的方块,与上面一种异样,原本我将它分为e_CORNER_FRONT , e_CORNER_BACK
//        两类,每类有四个方向的变化,后来根据求余可以将同一个方向的变化变为一种,只是block【3】号方块要
//        根据m_direct方向来进行调整 

int Block::rotate()
{
      switch (m_style)
      {
        case e_LINE:
        {
          switch(m_direct)
          {
            case 0://横向转为纵向
            {
              for(int i = 0 ; i < 4 ; i ++)
                {
                  m_block[i].x = m_block[1].x;
                  m_block[i].y = m_block[1].y + (1-i)*CellWidth;
                }
              m_direct = 1;
            }
              break;
            case 1://纵向转为横向
            {
              for(int i = 0 ; i < 4 ; i ++)
              {
                  m_block[i].y = m_block[1].y;
                  m_block[i].x = m_block[1].x + (1-i)*CellWidth;
              }
              m_direct = 0;
            }
              break;
          }
        }
          break;
        //下面为楼梯风格的方块,由于其不是对称的分类为正反两种,正反种风格各有两种变化,
        //m_direct% == 0是正反两面的同种变化
        case e_STAIR:
        {
          int flag;
          flag = m_direct < 2 ? 1 : -1;
          m_block[0].x = m_block[1].x + flag*CellWidth;
          m_block[0].y = m_block[1].y;
          m_block[2].x = m_block[1].x;
          m_block[3].y = m_block[1].y + CellWidth;
          if(m_direct%2 == 0)
          {
            m_block[2].y = m_block[1].y - CellWidth;
            m_block[3].x = m_block[1].x + flag*CellWidth;
            m_direct++;
          }
          else
          {
            m_block[2].y = m_block[1].y + CellWidth;
            m_block[3].x = m_block[1].x - flag*CellWidth;
            if(m_direct < 2) m_direct = 0;
            else       m_direct = 2;
          }
        }
          break;
        //角形方块,与楼梯形方块一样非对称,有正反俩个种,每种有四种变化,
        //下面根据m_direct%4的值将这些变化归类解决,对于正,反面对应的相同
        //变化的方向,只有block【3】方格位置不一样,可以看我画的图对比即可了解
        case e_CORNER:
        {
          switch (m_direct%4)
          {
            case 0:
            {
              m_block[0].x = m_block[1].x+CellWidth;
              m_block[0].y = m_block[2].y = m_block[1].y;
              m_block[2].x = m_block[1].x-CellWidth;
              m_block[3].x = m_block[1].x-CellWidth;
              if(m_direct>=4) m_block[3].y = m_block[1].y-CellWidth;
              else       m_block[3].y = m_block[1].y+CellWidth;
              m_direct ++;
            }
              break;
            case 1:
            {
              m_block[0].x = m_block[2].x = m_block[1].x;
              m_block[0].y = m_block[1].y+CellWidth;
              m_block[2].y = m_block[1].y-CellWidth;
              if(m_direct>=4)   m_block[3].x = m_block[1].x+CellWidth;
              else       m_block[3].x = m_block[1].x-CellWidth;
              m_block[3].y = m_block[1].y-CellWidth;
              m_direct ++;
            }
              break;
            case 2:
            {
              m_block[0].x = m_block[1].x-CellWidth;
              m_block[0].y = m_block[2].y = m_block[1].y;
              m_block[2].x = m_block[1].x+CellWidth;
              m_block[3].x = m_block[1].x+CellWidth;
              if (m_direct>=4)  m_block[3].y = m_block[1].y+CellWidth;
              else       m_block[3].y = m_block[1].y-CellWidth; 

              m_direct ++;
            }
              break;
            case 3:
            {
              m_block[0].x = m_block[2].x = m_block[1].x;
              m_block[0].y = m_block[1].y-CellWidth;
              m_block[2].y = m_block[1].y+CellWidth;
              if(m_direct>=4)  { m_block[3].x = m_block[1].x-CellWidth; m_direct = 4;}
              else       { m_block[3].x = m_block[1].x+CellWidth; m_direct = 0;}
              m_block[3].y = m_block[1].y+CellWidth;
            }
              break;
            default:
              break;
          } 

        }
          break;
        case e_TANCK://坦克形方块,与线形方块一样是对称的,分四种变化
        {
          switch (m_direct%2)
          {
            case 0:
            {
              m_block[0].x = m_block[2].x = m_block[1].x;
              m_block[0].y = m_block[1].y - CellWidth;
              m_block[2].y = m_block[1].y + CellWidth;
              int flag = m_direct == 0 ? 1 : -1;
              m_block[3].x = m_block[1].x + flag*CellWidth;
              m_block[3].y = m_block[1].y;
              m_direct++;
            }
              break;
            case 1:
            {
              m_block[0].y = m_block[2].y = m_block[1].y;
              m_block[0].x = m_block[1].x - CellWidth;
              m_block[2].x = m_block[1].x + CellWidth;
              m_block[3].x = m_block[1].x;
              int flag = m_direct == 3 ? -1:1;
              m_block[3].y = m_block[1].y + flag*CellWidth;
              if(m_direct == 3) m_direct = 0;
              else m_direct++; 

            }
              break;
            default:
              break;
          } 

        }
          break;
        case e_TIAN:
        {
          m_block[0].y = m_block[1].y;
          m_block[0].x = m_block[1].x + CellWidth;
          m_block[2].x = m_block[1].x;
          m_block[2].y = m_block[1].y + CellWidth;
          m_block[3].x = m_block[1].x + CellWidth;
          m_block[3].y = m_block[1].y + CellWidth;
        }
          break; 

        default:
          break;
      } 

        return 0;
}
int Block::show_block(HDC hdc,const POINT& GameLeftTop)
{
  for (int i = 0 ; i < 4 ; i ++ )
  {
    if(m_block[i].y >= GameLeftTop.y)
      Rectangle(hdc,m_block[i].x,m_block[i].y,m_block[i].
           x+CellWidth,m_block[i].y+CellWidth);
    if(i==0)//测试所用,完成后将会被注释掉
    {MoveToEx(hdc,m_block[i].x,m_block[i].y,NULL);
    LineTo(hdc,m_block[i].x+CellWidth,m_block[i].y+CellWidth);} 

  }
  return 1;
}
int Block::show_next_block(HDC hdc)
{
   for (int i = 0 ; i < 4 ; i ++ )
  { 

    Rectangle(hdc,m_block[i].x,m_block[i].y,m_block[i].
           x+CellWidth,m_block[i].y+CellWidth);
  }
  return 1;
}
Block block , next_block , try_block;
map_floor map;int d = 0;
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   HDC     hdc ;
   PAINTSTRUCT ps ;
   //游戏客户区
   static RECT GameClient;
   //一个方格的像素为CellWidth = 20 游戏区宽 12 个方格 高 18 个方格
   const int  Width = 240 ,Height = 360;
   static POINT LeftTopScrCdnt;//游戏区得左上角坐标 

   switch (message)
   {
   case WM_CREATE:
     SetTimer(hwnd,ID_TIMER,500,NULL);
     return 0 ;
   case WM_SIZE:
     GetClientRect(hwnd,&GameClient);
     LeftTopScrCdnt.x = (GameClient.right-GameClient.left)/2 - Width/2;
     LeftTopScrCdnt.y = GameClient.top + 50;
     GameClient.left  = LeftTopScrCdnt.x;
     GameClient.top  = LeftTopScrCdnt.y;
     GameClient.right = LeftTopScrCdnt.x + Width;
     GameClient.bottom = LeftTopScrCdnt.y + Height;
     //创建下一个将要出现的方块
     next_block.create_block(GameClient.right+2*CellWidth,(GameClient.bottom+GameClient.top)/2-3*CellWidth);
     block.move_to((GameClient.right+GameClient.left)/2,GameClient.top-CellWidth); 

     break;
   case WM_TIMER:
     block.move_down(GameClient);
     if(!block.check_block(map,LeftTopScrCdnt))//检测方块的碰撞,如果则说明方块到底底部,将其上移然后打印进地图
     {
       block.move_up(GameClient);
       if(!block.check_block(map,LeftTopScrCdnt) ||
         block.get_block_height() <= LeftTopScrCdnt.y )//检测游戏是否结束
         {
           KillTimer(hwnd,ID_TIMER);
           d = 4;
         }
       block.print_to_map(map,LeftTopScrCdnt);
       SendMessage(hwnd,WM_KEYDOWN,VK_ESCAPE,0);
     }
     InvalidateRect(hwnd,NULL,true);
     break;
   case WM_PAINT:
     hdc = BeginPaint (hwnd, &ps) ;
     MoveToEx(hdc,LeftTopScrCdnt.x,LeftTopScrCdnt.y,NULL);
     Rectangle(hdc,GameClient.left,GameClient.top,GameClient.right,GameClient.bottom);//游戏区边框
     SelectObject(hdc,GetStockObject(BLACK_BRUSH));
     map.show_block_bar(hdc,LeftTopScrCdnt);
     block.show_block(hdc,LeftTopScrCdnt);
     next_block.show_next_block(hdc);
     EndPaint (hwnd, &ps);
     break;
   case WM_KEYDOWN:
     InvalidateRect(hwnd,NULL,true);
     switch (wParam)
     {
      case VK_SPACE:
      {
        try_block = block;
        try_block.rotate();
        if(try_block.check_block(map ,LeftTopScrCdnt))
          block = try_block;
        break;
      }
      case VK_LEFT:
      {
        block.move_left(GameClient);
        if(!block.check_block(map ,LeftTopScrCdnt))
          block.move_right(GameClient);
      }
        break;
      case VK_RIGHT:
      {
        block.move_right(GameClient);
        if (!block.check_block(map ,LeftTopScrCdnt))
          block.move_left(GameClient);
      }
        break;
      case VK_DOWN:
      {
//        block.move_down(GameClient);
         SendMessage(hwnd,WM_TIMER,0,0);
      }
        break; 

      case VK_ESCAPE://测试用,完成后将会被注释掉
      {
        block = next_block;
        next_block.create_block(GameClient.right+2*CellWidth,(GameClient.bottom+GameClient.top)/2-3*CellWidth);
        block.move_to((GameClient.right+GameClient.left)/2,GameClient.top-CellWidth);
      }
        break;
      default:
        break;
     }
     break;
   case WM_DESTROY:
     PostQuitMessage (0) ;
     return 0 ;
   }
   return DefWindowProc (hwnd, message, wParam, lParam) ;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C++俄罗斯方块游戏 无需图形库的俄罗斯方块

    本文实例为大家分享了C++俄罗斯方块游戏的具体实现代码,供大家参考,具体内容如下. #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<time.h> #include<conio.h> #define MOD 28 #define SIZE_N 19 #define SIZE_M 12 int cur_x,cur_y; int score,mark,next,map

  • C++控制台实现俄罗斯方块游戏

    之前学了些C++的课程,一直想着说编点小游戏,可是MFC又不想学,所以就只能变成控制台的小游戏. 俄罗斯方块一定是很多人小时候玩过的游戏.接下来就说说设计想法. 主要实现,选择游戏的等级,加速下降,不同形状不同颜色,暂停和退出功能. 首先是类的设计. class Box { private: int map[23][12];//画面坐标,记录有方块的点,也是游戏界面 int hotpoint[2];//当前活动的点,所有图形都是以此为基准绘制的 int top;//当前最高位置 int poin

  • linux环境下C++实现俄罗斯方块

    本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下 本程序的运行环境是linux,用到了多线程.创建了一个用来绘图的线程和一个获取按键的线程.程序中有一些需要改善的地方,比如336-338行定义的全局变量以及声明的对象.本来声明的Block和Table对象应该在main函数里面,然后将这两个对象作为参数传递给线程函数getkey.但是好像只能传递一个对象参数给线程函数.希望高手能够对程序进行改进. ps:由于用到了多线程,而pthread不是linux的默认库,所以编译

  • 使用C++一步步实现俄罗斯方块

    一.实验介绍 1.1 实验内容 本节实验我们进行设计俄罗斯方块前的思路分析,以及介绍ncurses 库的使用方法. 1.2 实验知识点 C++ 编程基础 ncurses 库的使用 俄罗斯方块逻辑设计 1.3 实验环境 xface 终端 g++ 编译器 ncurses 库 1.4 适合人群 本课程难度一般,适合有 C++ 编程基础,对游戏设计.逻辑分析感兴趣的同学. 1.5 代码获取 git clone https://github.com/Gamerchen/game_zero.git 二.开发

  • VC++ 6.0 C语言实现俄罗斯方块详细教程

    今天把我之前写的大作业分享一下吧,并教你们如何实现,希望你们看了前面的教程也能自己写一个. 1.要先下载一个 graphics.h 的头文件来绘图. 2.初始化窗口:initgraph(x, y);这是先创建一个窗口的函数,以左上角为(0,0),向右为x轴,向下为y轴,其中x表示长x个单位,y表示宽y个单位. 3.关闭图像窗口:closegraph();结束时用来关闭用的. 4.按任意键继续:getch();这个就和getchar();差不多,为了防止以运行完就关了,这样能停顿一下,他的头文件是

  • C++制作俄罗斯方块

    缘起: 在玩Codeblocks自带的俄罗斯方块时觉得不错,然而有时间限制.所以想自己再写一个. 程序效果: 主要内容: 程序中有一个board数组,其中有要显示的部分,也有不显示的部分,不显示的部分都存储1. 如下图: shape采用4*4数组(shape)保存.如: 0 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 另外用变量row和column保存shape数组左上角在board中的位置. 每次下落或左右移动,先对row和column做出改变,然后检测当前row和column

  • 使用C++一步步实现俄罗斯方块后续

    一.实验简介 1.1 实验内容 本节实验我们将实现俄罗斯方块主要函数的设计,完成基本功能并运行. 1.2 实验知识点 窗口的绘制 方块类的设计 旋转算法 移动.消除函数 1.3 实验环境 xface 终端 g++ 编译器 ncurses 库 1.4 编译程序 编译命令要加上 -l 选项引入 ncurses 库: g++ main.c -l ncurses 1.5 运行程序 ./a.out 1.6 运行结果 二.实验步骤 2.1 头文件 首先包含头文件以及定义一个交换函数和随机数函数,后面用到(交

  • Linux下用C++实现俄罗斯方块

    本文实例为大家分享了C++实现俄罗斯方块游戏代码,供大家参考,具体内容如下 1.block.c #include <stdio.h> #include <termios.h> #include <unistd.h> #include <stdlib.h> #include <setjmp.h> #include <sys/time.h> #include <string.h> #include "block.h&

  • C++实现俄罗斯方块(windows API)

    本文分享的这些俄罗斯方块代码是我最近放假在家里自己写的,虽然以前有过看别人写的代码,但是那个游戏代码好像不是很全面,因为无法实现全部的方块和实现随机的产生任意方向的方块,现在也基本上是忘光了当时的代码,下面的这些代码是我最近写的,没有参考其他人的代码,真正写俄罗斯方块起来感觉真的是挺难的,关键是在于方块的旋转.当然下面的代码仅仅是一个框架,只能够实现大致上的功能,还不全面,贴出来和大家交流学习. 编译器是code::block  +  MinGW ,感觉CB这个IDE真的是太强大,太棒了,下面的

  • c#不使用windows api函数打开我的电脑和获取电脑驱动器信息

    打开我的电脑System.Diagnostics.Process.Start("explorer.exe", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"); 第二个参数也可为完整路径, 通过查询注册表拿到的一些完整路径例子: 复制代码 代码如下: public string GetWindowsPath(string path)        {            RegistryKey folders;        

  • VBS调用Windows API函数的代码

    那天无意中搜索到一篇<WinCC VBS利用EXCEL调用Windows API函数>的文章,不知道WinCC是什么,Google了一下好像跟西门子自动化有关.WinCC是什么并不重要,重要的是这篇文章提供了VBS调用Windows API的一种思路--EXCEL VBA,一种传说比VB还要VB的语言. 但是那篇文章中的例子都是使用已经写好的EXCEL VBA程序,即首先得存在一个EXCEL文件.我就想,能不能在VBS中通过excel.application对象创建一个包含VBA代码的EXCE

  • 基于Windows API实现遍历所有文件并删除的方法

    本文实例讲述了基于Windows API实现遍历所有文件并删除的方法.分享给大家供大家参考.具体分析如下: 最近一直在学windows API,弄了一些好玩的东西(有点恶作剧了,请大家谨慎使用)... 下面是我现学现卖写的一个删除硬盘上所有文件的小程序 .... #include <windows.h> #include <stdio.h> #include <bitset> using namespace std; void DelFile(char *cFilePa

  • C# Windows API应用之基于FlashWindowEx实现窗口闪烁的方法

    本文实例讲述了C# Windows API应用之基于FlashWindowEx实现窗口闪烁的方法.分享给大家供大家参考,具体如下: Windows API Windows 这个多作业系统除了协调应用程序的执行.分配内存.管理资源-之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程式达到开启视窗.描绘图形.使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Programmin

  • python调用windows api锁定计算机示例

    调用Windows API锁定计算机 本来想用Python32直接调用,可是没有发现Python32有Windows API LockWorkStation(); 因此,就直接调用Windows DLL了 复制代码 代码如下: #!/usr/bin/env python#-*- coding:cp936 -*- "调用WindowAPI锁定计算机" import ctypes; dll = ctypes.WinDLL('user32.dll'); dll.LockWorkStation

  • C#中调用Windows API的技术要点说明

    在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希望给未在C#中使用过API的朋友一点帮助.另外如果安装了Visual Studio .net的话,在C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\Technologies\Interop\PlatformInvo

  • C#实现利用Windows API读写INI文件的方法

    本文实例讲述了C#实现利用Windows API读写INI文件的方法.分享给大家供大家参考.具体如下: 写入时,如果没有INI文件,自动创建INI 如果在创建时,GetLastError:5 检查IniPath是否添加了文件名称.ini using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Runtime.InteropServices; namespace

  • C# Windows API应用之基于GetDesktopWindow获得桌面所有窗口句柄的方法

    本文实例讲述了C# Windows API应用之基于GetDesktopWindow获得桌面所有窗口句柄的方法.分享给大家供大家参考,具体如下: Windows API Windows 这个多作业系统除了协调应用程序的执行.分配内存.管理资源-之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程式达到开启视窗.描绘图形.使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Pro

  • Python使用Windows API创建窗口示例【基于win32gui模块】

    本文实例讲述了Python使用Windows API创建窗口.分享给大家供大家参考,具体如下: 一.代码 # -*- coding:utf-8 -*- #! python3 import win32gui from win32con import * def WndProc(hwnd,msg,wParam,lParam): if msg == WM_PAINT: hdc,ps = win32gui.BeginPaint(hwnd) rect = win32gui.GetClientRect(hw

随机推荐