Tetris 小套路

本程序在 VS2003 下调试通过。

  1. 建立工程
    打开 VS2003 选择 文件->新建->项目->Visual C++ 项目->Win32->Win32 项目;项目名称:Tetris,点击确定。
    在弹出的 “Win32 应用程序向导” 对话框中,选择 “应用程序设置” -> “附加选项” -> “空项目”,点击完成。

  2. 新建 tetris.cpp 文件
    选择 “项目” -> “添加新项”,选择 “C++ 文件(.cpp)”,名称:tetris,点击打开。

  3. 编写 WinMain 入口函数

#include <windows.h>
int WINAPI WinMain(HINSTANCE, HINSTANCE, char *, int cmdShow)
{
}
  1. 建立程序框架
#include <windows.h>
#include <stdio.h>
/////////////////全局变量/////////////////////////////
HWND hwnd;          // 窗口句柄
/////////////////  函数  /////////////////////////////
LRESULT CALLBACK WndProc ( HWND,UINT,WPARAM,LPARAM );
int WINAPI WinMain(HINSTANCE, HINSTANCE, char *, int cmdShow)
{
  HINSTANCE hInstance=GetModuleHandle ( NULL );
  TCHAR szAppName[]=TEXT ( "teris" );
  MSG msg;
  WNDCLASS wc;
  wc.style=CS_HREDRAW|CS_VREDRAW;
  wc.lpfnWndProc=WndProc;
  wc.cbClsExtra=0;
  wc.cbWndExtra=0;
  wc.hInstance=hInstance;
  wc.hIcon=LoadIcon ( NULL,IDI_APPLICATION );
  wc.hCursor=LoadCursor ( NULL,IDC_ARROW );
  wc.hbrBackground= ( HBRUSH ) GetStockObject ( WHITE_BRUSH );
  wc.lpszMenuName=NULL;
  wc.lpszClassName=szAppName;
  if ( !RegisterClass ( &wc ) )
  {
    printf ( "RegisterClass occur errors!" );
    return 0;
  }
  hwnd=CreateWindow ( szAppName,TEXT ( "Teris Demo" ),
                      WS_OVERLAPPEDWINDOW,
                      0,0,0,0,
                      NULL,
                      NULL,
                      hInstance,
                      NULL );
  ShowWindow ( hwnd,SW_SHOW );
  UpdateWindow ( hwnd );
  while ( GetMessage ( &msg,NULL,0,0 ) )
  {
    TranslateMessage ( &msg );
    DispatchMessage ( &msg );
  }
  return msg.wParam;
}
LRESULT CALLBACK WndProc ( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
  HDC hdc;
  PAINTSTRUCT ps;
  switch ( message )
  {
  case WM_CREATE:
    MoveWindow ( hwnd,400,10,800,600,FALSE );
    return 0;
  case WM_PAINT:
    hdc=BeginPaint ( hwnd,&ps );
    EndPaint ( hwnd,&ps );
    return 0;
  case WM_DESTROY:
    PostQuitMessage ( 0 );
    return 0;
  }
  return DefWindowProc ( hwnd,message,wParam,lParam );
}
  1. 绘制面板
#define CELL 20
#define ROWS 25
#define COLS 15
void DrawPanel ( HDC hdc );   //绘制面板
LRESULT CALLBACK WndProc ( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
  HDC hdc;
  PAINTSTRUCT ps;
  switch ( message )
  {
  case WM_CREATE:
    MoveWindow ( hwnd,400,10,CELL*COLS+8,CELL*ROWS+32,FALSE );    //补齐宽度和高度
    srand ( time ( NULL ) );
    ExportBlock();
    return 0;
  case WM_PAINT:
    hdc=BeginPaint ( hwnd,&ps );
    DrawPanel ( hdc );      //绘制面板
    RefreshPanel ( hdc );    //刷新
    EndPaint ( hwnd,&ps );
    return 0;
  case WM_DESTROY:
    PostQuitMessage ( 0 );
    return 0;
  }
  return DefWindowProc ( hwnd,message,wParam,lParam );
}
void DrawPanel ( HDC hdc )    //绘制面板
{
  int x,y;
  RECT rect;
  for ( y=0; y<ROWS; y++ )
  {
    for ( x=0; x<COLS; x++ )
    {
      //计算方块的边框范围
      rect.top=y*CELL+1;
      rect.bottom= ( y+1 ) *CELL-1;
      rect.left=x*CELL+1;
      rect.right= ( x+1 ) *CELL-1;
      FrameRect ( hdc,&rect, ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) );
    }
  }
}
LRESULT CALLBACK WndProc ( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
  HDC hdc;
  PAINTSTRUCT ps;
  switch ( message )
  {
  case WM_CREATE:
    MoveWindow ( hwnd,400,10,800,600,FALSE );
    return 0;
  case WM_PAINT:
    hdc=BeginPaint ( hwnd,&ps );
    DrawPanel ( hdc );      //绘制面板
    EndPaint ( hwnd,&ps );
    return 0;
  case WM_DESTROY:
    PostQuitMessage ( 0 );
    return 0;
  }
  return DefWindowProc ( hwnd,message,wParam,lParam );
}
  1. 绘制方块
#include <time.h>
int cur_left,cur_top;          //记录方块当前的位置
int width_block,height_block;  //方块的宽带和高度
static byte *block=NULL;       //方块,方块为随机大小,采用动态分配内存方式,所以这里是指针变量
byte g_panel[ROWS][COLS]={0};
void RefreshPanel ( HDC hdc );     //刷新面板
bool ExportBlock();                //输出方块
void RefreshPanel ( HDC hdc )      //刷新面板
{
  int x,y;
  RECT rect;
  HBRUSH h_bSolid= ( HBRUSH ) GetStockObject ( GRAY_BRUSH ),
                   h_bEmpty= ( HBRUSH ) GetStockObject ( WHITE_BRUSH );
  if ( NULL==block ) return;
  //先刷屏
  for ( y=0; y<ROWS; y++ )
  {
    for ( x=0; x<COLS; x++ )
    {
      //为避免刷掉方块的边框,rect范围必须比边框范围小1
      rect.top=y*CELL+2;
      rect.bottom= ( y+1 ) *CELL-2;
      rect.left=x*CELL+2;
      rect.right= ( x+1 ) *CELL-2;
      if ( g_panel[y][x] )
        FillRect ( hdc,&rect,h_bSolid );
      else
        FillRect ( hdc,&rect,h_bEmpty );
    }
  }
  //再定位方块
  for ( y=0; y<height_block; y++ )
  {
    for ( x=0; x<width_block; x++ )
    {
      if ( * ( block+y*width_block+x ) )      //实心
      {
        rect.top= ( y+cur_top ) *CELL+2;
        rect.bottom= ( y+cur_top+1 ) *CELL-2;
        rect.left= ( x+cur_left ) *CELL+2;
        rect.right= ( x+cur_left+1 ) *CELL-2;
        FillRect ( hdc,&rect,h_bSolid );
      }
    }
  }
}
bool ExportBlock()      //输出方块
{
  int sel;
  if ( block )
  {
    free ( block );    //释放之前分配的内存
    block=NULL;
  }
  sel=rand() %7;
  switch ( sel )
  {
  case 0:    //水平条
    width_block=4;
    height_block=1;
    block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
    * ( block+0 ) =1;    //可以理解为*(block+0*width_block+0)=1,即第一行的第一个方格,下面同理
    * ( block+1 ) =1;    //*(block+0*width_block+1)=1
    * ( block+2 ) =1;    //*(block+0*width_block+2)=1
    * ( block+3 ) =1;    //*(block+0*width_block+3)=1
    cur_top=0-height_block;
    cur_left= ( COLS-width_block ) /2;
    break;
  case 1:    //三角
    width_block=3;
    height_block=2;
    block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
    * ( block+0 ) =0;    //可以理解为*(block+0*width_block+0)=0,即第一行的第一个方格,下面同理
    * ( block+1 ) =1;    //*(block+0*width_block+1)=1
    * ( block+2 ) =0;    //*(block+0*width_block+2)=0
    * ( block+3 ) =1;    //*(block+1*width_block+0)=1,第二行开始
    * ( block+4 ) =1;    //*(block+1*width_block+1)=1
    * ( block+5 ) =1;    //*(block+1*width_block+2)=1
    cur_top=0-height_block;
    cur_left= ( COLS-width_block ) /2;
    break;
  case 2:    //左横折
    width_block=3;
    height_block=2;
    block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
    * ( block+0 ) =1;    //可以理解为*(block+0*width_block+0)=1,下面同理
    * ( block+1 ) =0;    //*(block+0*width_block+1)=0
    * ( block+2 ) =0;    //*(block+0*width_block+2)=0
    * ( block+3 ) =1;    //*(block+1*width_block+0)=1
    * ( block+4 ) =1;    //*(block+1*width_block+1)=1
    * ( block+5 ) =1;    //*(block+1*width_block+2)=1
    cur_top=0-height_block;
    cur_left= ( COLS-width_block ) /2;
    break;
  case 3:    //右横折
    width_block=3;
    height_block=2;
    block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
    * ( block+0 ) =0;    //可以理解为*(block+0*width_block+0)=0,下面同理
    * ( block+1 ) =0;    //*(block+0*width_block+1)=0
    * ( block+2 ) =1;    //*(block+0*width_block+2)=1
    * ( block+3 ) =1;    //*(block+1*width_block+0)=1
    * ( block+4 ) =1;    //*(block+1*width_block+1)=1
    * ( block+5 ) =1;    //*(block+1*width_block+2)=1
    cur_top=0-height_block;
    cur_left= ( COLS-width_block ) /2;
    break;
  case 4:    //左闪电
    width_block=3;
    height_block=2;
    block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
    * ( block+0 ) =1;    //可以理解为*(block+0*width_block+0)=1,下面同理
    * ( block+1 ) =1;    //*(block+0*width_block+1)=1
    * ( block+2 ) =0;    //*(block+0*width_block+2)=0
    * ( block+3 ) =0;    //*(block+1*width_block+0)=0
    * ( block+4 ) =1;    //*(block+1*width_block+1)=1
    * ( block+5 ) =1;    //*(block+1*width_block+2)=1
    cur_top=0-height_block;
    cur_left= ( COLS-width_block ) /2;
    break;
  case 5:    //右闪电
    width_block=3;
    height_block=2;
    block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
    * ( block+0 ) =0;    //可以理解为*(block+0*width_block+0)=0,下面同理
    * ( block+1 ) =1;    //*(block+0*width_block+1)=1
    * ( block+2 ) =1;    //*(block+0*width_block+2)=1
    * ( block+3 ) =1;    //*(block+1*width_block+0)=1
    * ( block+4 ) =1;    //*(block+1*width_block+1)=1
    * ( block+5 ) =0;    //*(block+1*width_block+2)=0
    cur_top=0-height_block;
    cur_left= ( COLS-width_block ) /2;
    break;
  case 6:    //石头
    width_block=2;
    height_block=2;
    block= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
    * ( block+0 ) =1;    //可以理解为*(block+0*width_block+0)=1,下面同理
    * ( block+1 ) =1;    //*(block+0*width_block+1)=1
    * ( block+2 ) =1;    //*(block+1*width_block+0)=1
    * ( block+3 ) =1;    //*(block+1*width_block+1)=1
    cur_top=0-height_block;
    cur_left= ( COLS-width_block ) /2;
    break;
  }
  cur_top=10;
  return block!=NULL;
}
  1. 变换方块
void DoRedirection ( HDC hdc );  //改变方向
LRESULT CALLBACK WndProc ( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
  HDC hdc;
  PAINTSTRUCT ps;
  switch ( message )
  {
  case WM_CREATE:
    MoveWindow ( hwnd,400,10,CELL*COLS+8,CELL*ROWS+32,FALSE );    //补齐宽度和高度
    srand ( time ( NULL ) );
    ExportBlock();
    return 0;
  case WM_PAINT:
    hdc=BeginPaint ( hwnd,&ps );
    DrawPanel ( hdc );      //绘制面板
    RefreshPanel ( hdc );    //刷新
    EndPaint ( hwnd,&ps );
    return 0;
  case WM_KEYDOWN:
    hdc=GetDC ( hwnd );
    switch ( wParam )
    {
    case VK_UP:                //转向
      if ( !isPause ) DoRedirection ( hdc );
      break;
    }
    ReleaseDC ( hwnd,hdc );
    return 0;
  case WM_DESTROY:
    PostQuitMessage ( 0 );
    return 0;
  }
  return DefWindowProc ( hwnd,message,wParam,lParam );
}
void DoRedirection ( HDC hdc )    //改变方向
{
  int i,j;
  byte * temp=NULL;
  if ( NULL==block ) return;
  if ( cur_top<0 ) return;    //方块完整显示前不能转向
  temp= ( byte * ) malloc ( sizeof ( byte ) *width_block*height_block );
  for ( i=0; i<width_block; i++ )
  {
    for ( j=0; j<height_block; j++ )
    {
      * ( temp+i*height_block+j ) =* ( block+ ( height_block-j-1 ) *width_block+i );
    }
  }
  //给方块重新定位
  int incHeight=width_block-height_block;
  int incWidth=height_block-width_block;
  int temp_cur_top=cur_top-incHeight/2;
  int temp_cur_left=cur_left-incWidth/2;
  //判断当前空间是否足够让方块改变方向
  int max_len=max ( width_block,height_block );
  //防止下标访问越界
  if ( temp_cur_top+max_len-1>=ROWS||temp_cur_left<0||temp_cur_left+max_len-1>=COLS )
  {
    free ( temp );    //退出前必须先释放内存
    return;
  }
  for ( i=0; i<max_len; i++ )
  {
    for ( j=0; j<max_len; j++ )
    {
      //转向所需的空间内有已被占用的实心方格存在,即转向失败
      if ( g_panel[temp_cur_top+i][temp_cur_left+j] )
      {
        free ( temp );    //退出前必须先释放内存
        return;
      }
    }
  }
  //把临时变量的值赋给block,只能赋值,而不能赋指针值
  for ( i=0; i<height_block; i++ )
  {
    for ( j=0; j<width_block; j++ )
    {
      * ( block+i*width_block+j ) =* ( temp+i*width_block+j );
    }
  }
  //全局变量重新被赋值
  cur_top=temp_cur_top;
  cur_left=temp_cur_left;
  //交换
  i=width_block;
  width_block=height_block;
  height_block=i;
  free ( temp );    //释放为临时变量分配的内存
  RefreshPanel ( hdc );
}
  1. 控制方向
void DoDownShift ( HDC hdc );    //下移
void DoLeftShift ( HDC hdc );    //左移
void DoRightShift ( HDC hdc );    //右移
void DoAccelerate ( HDC hdc );    //加速
LRESULT CALLBACK WndProc ( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
  HDC hdc;
  PAINTSTRUCT ps;
  switch ( message )
  {
  case WM_CREATE:
    MoveWindow ( hwnd,400,10,CELL*COLS+8,CELL*ROWS+32,FALSE );    //补齐宽度和高度
    srand ( time ( NULL ) );
    ExportBlock();
    return 0;
  case WM_PAINT:
    hdc=BeginPaint ( hwnd,&ps );
    DrawPanel ( hdc );      //绘制面板
    RefreshPanel ( hdc );    //刷新
    EndPaint ( hwnd,&ps );
    return 0;
  case WM_KEYDOWN:
    hdc=GetDC ( hwnd );
    switch ( wParam )
    {
    case VK_LEFT:              //左移
      DoLeftShift ( hdc );
      break;
    case VK_RIGHT:              //右移
      DoRightShift ( hdc );
      break;
    case VK_UP:                //转向
      DoRedirection ( hdc );
      break;
    case VK_DOWN:              //加速
      DoAccelerate ( hdc );
      break;
    }
    ReleaseDC ( hwnd,hdc );
    return 0;
  case WM_DESTROY:
    PostQuitMessage ( 0 );
    return 0;
  }
  return DefWindowProc ( hwnd,message,wParam,lParam );
}
void DoDownShift ( HDC hdc )      //下移
{
  if ( NULL==block ) return;
  cur_top++;
  RefreshPanel ( hdc );
}
void DoLeftShift ( HDC hdc )      //左移
{
  int x,y;
  if ( NULL==block ) return;
  if ( 0==cur_left ) return;
  if ( cur_top<0 ) return;  //方块没有完整显示前,不能左移
  for ( y=0; y<height_block; y++ )
  {
    for ( x=0; x<width_block; x++ )      //从左边开始扫描,获取该行最左边的实心方格块
    {
      if ( * ( block+y*width_block+x ) )
      {
        //判断当前方格在面板上面左边一个方格是否为实心,是就代表不能再左移
        if ( g_panel[cur_top+y][cur_left+x-1] ) return;

        break;    //只判断最左边的一个实心方格,之后直接扫描下一行
      }
    }
  }
  cur_left--;
  RefreshPanel ( hdc );
}
void DoRightShift ( HDC hdc )      //右移
{
  int x,y;
  if ( NULL==block ) return;
  if ( COLS-width_block==cur_left ) return;
  if ( cur_top<0 ) return;    //方块完整显示前不能右移
  for ( y=0; y<height_block; y++ )
  {
    for ( x=width_block-1; x>=0; x-- )    //从右边开始扫描,获取该行最右边的实心方格块
    {
      if ( * ( block+y*width_block+x ) )
      {
        //判断当前方格在面板上右边一个方格是否为实心,是就代表不能再右移
        if ( g_panel[cur_top+y][cur_left+x+1] ) return;

        break;    //只判断最右边的一个实心方格
      }
    }
  }
  cur_left++;
  RefreshPanel ( hdc );
}
void DoAccelerate ( HDC hdc )      //加速
{
  if ( NULL==block ) return;
  cur_top++;
  RefreshPanel ( hdc );
}
  1. 让方块往下落
    ExportBlock函数里,最后面 cur_top = 10; 这句代码去掉。
#define ID_TIMER 1
UINT timer_id=0;          //保存计时器ID
int level=0;              //级数
int interval_unit=25;     //随级数递增的时间间隔增量
int interval_base=300;    //时间间隔基量
LRESULT CALLBACK WndProc ( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
  HDC hdc;
  PAINTSTRUCT ps;
  switch ( message )
  {
  case WM_CREATE:
    MoveWindow ( hwnd,400,10,CELL*COLS+8,CELL*ROWS+32,FALSE );    //补齐宽度和高度
    srand ( time ( NULL ) );
    ExportBlock();
    timer_id=SetTimer ( hwnd,ID_TIMER,interval_base-level*interval_unit,NULL );
    return 0;
  case WM_TIMER:
    hdc=GetDC ( hwnd );
    DoDownShift ( hdc );
    ReleaseDC ( hwnd,hdc );
    return 0;
...
}
  1. 让方块触底后停住,并生成新的方块落下
bool IsTouchBottom ( HDC hdc );      //判断是否到达底部
void DoDownShift ( HDC hdc )      //下移
{
  if ( NULL==block ) return;
  //判断是否到达底部
  if ( IsTouchBottom ( hdc ) )    //到底部
  {
    //消行处理
    ClearRow ( hdc );
    ExportBlock();    //输出下一个方块
  }
  cur_top++;
  RefreshPanel ( hdc );
}
void DoAccelerate ( HDC hdc )      //加速
{
  if ( NULL==block ) return;
  if ( IsTouchBottom ( hdc ) )
  {
    //消行处理
    ClearRow ( hdc );
    ExportBlock();
  }
  cur_top++;
  RefreshPanel ( hdc );
}
bool IsTouchBottom ( HDC hdc )
{
  int x,y;
  int i,j;
  if ( NULL==block ) return false;
  if ( ROWS==cur_top+height_block )
  {
    //固定方块
    for ( i=0; i<height_block; i++ )
    {
      for ( j=0; j<width_block; j++ )
      {
        if ( * ( block+i*width_block+j ) ) g_panel[cur_top+i][cur_left+j]=1;
      }
    }
    return true;
  }
  for ( y=height_block-1; y>=0; y-- )      //从底行开始扫描
  {
    //判断第一个实心方块在面板上邻接的下方方格是否为实心,是就代表已经到达底部
    for ( x=0; x<width_block; x++ )
    {
      if ( * ( block+y*width_block+x ) )
      {
        if ( cur_top+y+1<0 ) return false;
        if ( g_panel[cur_top+y+1][cur_left+x] )
        {
          //判断是否gameover
          if ( cur_top<=0 )
          {
            if ( timer_id )
            {
              KillTimer ( hwnd,ID_TIMER );
              timer_id=0;
            }
            MessageBox ( hwnd,TEXT ( "游戏结束" ),TEXT ( "MSG" ),MB_OK|MB_ICONEXCLAMATION );
            SendMessage ( hwnd,WM_CLOSE,0,0 );
          }
          //
          //固定方块
          for ( i=0; i<height_block; i++ )
          {
            for ( j=0; j<width_block; j++ )
            {
              if ( * ( block+i*width_block+j ) ) g_panel[cur_top+i][cur_left+j]=1;
            }
          }
          return true;
        }
      }
    }
  }
  return false;
}
  1. 消除方块,累积积分
#define SCORE_LEVEL_INC 80   //升级所需分数值
int score=0;        //分数
void ClearRow ( HDC hdc );      //消行
void DoDownShift ( HDC hdc )      //下移
{
  if ( NULL==block ) return;
  //判断是否到达底部
  if ( IsTouchBottom ( hdc ) )    //到底部
  {
    //消行处理
    ClearRow ( hdc );
    ExportBlock();    //输出下一个方块
  }
  cur_top++;
  RefreshPanel ( hdc );
}
void DoAccelerate ( HDC hdc )      //加速
{
  if ( NULL==block ) return;
  if ( IsTouchBottom ( hdc ) )
  {
    //消行处理
    ClearRow ( hdc );
    ExportBlock();
  }
  cur_top++;
  RefreshPanel ( hdc );
}
void ClearRow ( HDC hdc )          //消行
{
  int i,j,k;
  int count=0;    //消行次数
  bool isFilled;
  //消行处理
  for ( i=ROWS-1; i>=0; i-- )
  {
    isFilled=true;
    for ( j=0; j<COLS; j++ )
    {
      if ( !g_panel[i][j] )
      {
        isFilled=false;
        break;
      }
    }
    if ( isFilled )
    {
      for ( j=0; j<COLS; j++ )
      {
        g_panel[i][j]=0;
      }
      //所有方块往下移
      for ( k=i-1; k>=0; k-- )
      {
        for ( j=0; j<COLS; j++ )
        {
          g_panel[k+1][j]=g_panel[k][j];
        }
      }
      i=i+1;
      count++;
    }
  }
  //最高级别为9级,所以分数极限为(9+1)*SCORE_LEVEL_INC-1
  if ( score>=10*SCORE_LEVEL_INC-1 ) return;
  //加分规则:消除行数,1行加10分,2行加15分,3行加20分,4行加30分
  switch ( count )
  {
  case 1:
    score+=10;
    break;
  case 2:
    score+=15;
    break;
  case 3:
    score+=20;
    break;
  case 4:
    score+=30;
    break;
  }
  int temp_level=score/SCORE_LEVEL_INC;
  if ( temp_level>level )
  {
    level=temp_level;
    //撤销当前计时器,然后重设
    if ( timer_id ) KillTimer ( hwnd,ID_TIMER );
    timer_id=SetTimer ( hwnd,ID_TIMER,interval_base-level*interval_unit,NULL );
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,706评论 4 366
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,002评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,462评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,375评论 0 216
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,763评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,849评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,033评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,768评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,490评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,734评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,204评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,566评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,227评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,137评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,934评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,926评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,774评论 2 274

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,663评论 0 33
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile丽语阅读 3,808评论 0 6
  • 1. tab列表折叠效果 html: 能源系统事业部 岗位名称: 工作地点 岗位名...
    lilyping阅读 1,764评论 0 1
  • 各种纯css图标 CSS3可以实现很多漂亮的图形,我收集了32种图形,在下面列出。直接用CSS3画出这些图形,要比...
    剑残阅读 9,181评论 0 8
  • 有家长跟我说发现中国的孩子。做事情没有自信。性格上唯唯诺诺的。 由于中国大多数父母采用的是批评式教育,你是说孩子不...
    陈志玮阅读 375评论 0 0