带爆炸效果的扫雷(源码2)

Pygame小游戏:玩扫雷就在瞎点的,不止你一个人。 前言 《扫雷》是一款大众类的益智小游戏,于1992年发行。 游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个 雷即全盘皆输。 它是许多人接触到的第一款游戏,大概也是广大办公族和无网学生无聊时消遣的最佳游戏,是不是 每次见到戴上墨镜的小人很有成就感?在那些还没有网(被切断网)的岁月,扫雷曾陪伴无数人度 过了他们的童年。你的最佳纪录是多少?小编在工作间隙随手刷了一局30秒(囧????)。 那么?怎么才能通关呢?这,有生之年靠自己猜可能做不到了,BUT我 阅读详情

游戏中处理地图生成,绘制,单击处理等主要逻辑的类 map.h,所有格子放在20*20=400的一个数组中,即最大支持长宽各20个格子。每个格子用一个字节表示,低四位0表示空格,1~8表示数字,9表示雷。高四位bit7~bit4: bit7表示该格子是否打开,bit6表示是否已经标记,bit5表示是否要打叉(点错或标记错的时候)。说明:除了动画以外,所有的图形元素都是32*32像素。

简单的动画:与每个格子一一对应,也用20*20=400的一个数组表示,仍是一个字节表示。低四位表示帧数,bit7表示是否播放。时间间隔150ms,在窗口的初始化InitInstance()函数中启动定时器。图形大小48*48像素。

图形处理:先用一张黑白图与DC相“与”,将要显示的地方清零,再用图案相“或”。这个方法叫“去背”。这是动画效果中用的图:

附: map.h  map.cpp

 

//扫雷地图

#ifndef __MAP_H
#define __MAP_H

#include 
"queue.h"

#define G_NULL 0 //游戏未开始
#define G_END 1 //游戏结束

//表示雷
#define BOMB 9

//判断坐标是否合法的宏
#define INCLOSEAREA(x,y,xsize,ysize)  ((x)>=0 && (x)<=(xsize) && (y)>=0 && (y)<=(ysize))
#define INCLOSEINDEX(x,y)  ((x)>=0 && (x)<=(iWidth-1) && (y)>=0 && (y)<=(iHeight-1))

//取低4位
#define LOWBYTE(x) ((x) & 0x0f)
//取第i个bit(0~7)
#define GETBIT(x,i) ((x) & (1<<(i)))
#define IS1TO9(x) ((x)>=1 && (x)<=9)

class GameMap
{
public:
 GameMap();
 
~GameMap();

 
void Draw(void);
 
void DrawButton(void);
 
void SetMine(int iNum);
 
void SetMapSize(int w,int h);
 
int  CreateMap(void);
 
int CountBombNum(int x,int y);
 
int OpenGrid(int x,int y);//x,y是方格坐标0-8
 int Open8around(int x,int y);
 
void SetFlag(int x,int y);//作标记
 void ClearFlag(int x,int y);//作标记
 void SearchBlank(int x,int y);
 
int CheckWin(void);

 
//排行榜
 void LoadScore(void);
 
int IsNewScore(int l,int score);
 
void WriteScore(int l,char *pname, int time);
 
void GetName(int l, char *pname);
 
int GetTimeValue(int l);
 
void ResetScore(int iLevel);

 
void SetMap(int w,int h,int num);
 
void SetDC(HDC h);
 
void SetHWND(HWND h);
 
void SetHINSTANCE(HINSTANCE h);
 
void SetLevel(int l);
 
void LoadPic(void);

 
int GetHeight(void);
 
int GetWidth(void);
 
int GetNum(void);
 
int GetLevel(void);

 
//动画效果
 void DrawAnimation(void);

public:
 
int iState;
 
int iSubState;
 POINT button_pos;
 
int iFaceState;

private:
 
int iWidth;
 
int iHeight;
 
int iMineNum;
 
char pData[400];//map
 char pGray[400];
 
int nowx;
 
int nowy;
 
char info[100];
 
int iLevel;
  
 HDC hdc;
 HDC hdcmem;
 HWND hwnd;
 HINSTANCE hinstance;
 HBITMAP hbm_earth;
 HBITMAP hbm_number;
 HBITMAP hbm_bomb;
 HBITMAP hbm_mask;
 HBITMAP hbm_sign;
 HBITMAP hbm_face;
 HBITMAP hbm_flag;
 HBITMAP hbm_gray;
 HBITMAP hbm_back;

 BITMAP strBm;

 
//队列
 GQUEUE queue;

 
//score
 char scorename[80];
 
int scoretime[3];
}
;

#endif 

//////////////////////////////////////// map.cpp


#include 
"stdafx.h"
#include 
"resource.h"

#include 
"map.h"

//使用队列
#include "queue.h"

#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<time.h>

GameMap::GameMap()
{
 iWidth
=9;
 iHeight
=9;
 iMineNum
=0;

 iState
=G_NULL;//游戏没有开始

 iFaceState
=0;//NORMAL 笑脸标志

 nowx
=0;//鼠标坐标索引
 nowy=0;

 button_pos.x
= 32*iWidth+50;//定义笑脸按钮的坐标
 button_pos.y= 20;

 
//提示字符串 
 memset(info,0,sizeof(info));

 
//初始化等级
 iLevel=0;

 
//初始化成绩
 memset(scorename,0,sizeof(scorename));
 memset(scoretime,
-1,sizeof(scoretime));
}


GameMap::
~GameMap()
{
 
//清除绘图句柄
 DeleteObject(hbm_earth);
 DeleteObject(hbm_number);
 DeleteObject( hbm_bomb);
 DeleteObject( hbm_mask);
 DeleteObject( hbm_sign);
 DeleteObject( hbm_face);
 DeleteObject( hbm_flag);
 DeleteObject( hbm_gray);
 DeleteObject( hbm_back);
}

void GameMap::Draw(void)
{
 
int iLeft=0;
 
int ivisible=0;
 
int xStart=0;
 
int yStart=0;
 
int i=0;
 
int j=0;
 
char temp[50]={0};
 
char igrid=0;
 RECT rect;
 
 iLeft
=iMineNum;//当前雷的数量

 yStart
=0;//绘图坐标
 for(j=0;j<iHeight;j++)
 
{
  xStart
=0;
  
for(i=0;i<iWidth;i++)
  
{
   igrid
=pData[j*iWidth+i];
   
//图形显示,字节(bit7~bit0)的bit7,1,已打开,0,没有打开
   if(GETBIT(igrid,7))
   
{
    
//先画地面背景
    SelectObject(hdcmem,hbm_earth);
    BitBlt(hdc,xStart,yStart,
32,32,hdcmem,0,0,SRCCOPY);

    
//bit3~bit0 表示周围雷的数量(1~8),9表示雷
    if(BOMB==LOWBYTE(igrid) )
    
{
     
//雷
     SelectObject(hdcmem,hbm_bomb);
     BitBlt(hdc,xStart,yStart,
32,32,hdcmem,0,32,SRCAND);
     BitBlt(hdc,xStart,yStart,
32,32,hdcmem,0,0,SRCPAINT);
    }

    
else if(IS1TO9(LOWBYTE(igrid)))
    
{
     
//数字
     SelectObject(hdcmem,hbm_number);
     BitBlt(hdc,xStart
+8,yStart,16,32,hdcmem,LOWBYTE(igrid)*16,32,SRCAND);
     BitBlt(hdc,xStart
+8,yStart,16,32,hdcmem,LOWBYTE(igrid)*16,0,SRCPAINT);
    }

    
else
    
{
     
//空格,什么都不画
    }


   }

   
else
   
{
    
//画默认的遮盖图像
    SelectObject(hdcmem,hbm_mask);
    BitBlt(hdc,xStart,yStart,
32,32,hdcmem,0,0,SRCCOPY);

    
//bit6表示是否标记过
    if(GETBIT(igrid,6))
    
{
     
//显示标记旗帜
     SelectObject(hdcmem,hbm_flag);
     BitBlt(hdc,xStart,yStart,
32,32,hdcmem,0,0,SRCCOPY);

     iLeft
--;
    }

   }

        
   
if(G_END == iState && GETBIT(igrid,5))
   
{
    
//显示叉
    SelectObject(hdcmem,hbm_sign);
    BitBlt(hdc,xStart,yStart,
32,32,hdcmem,0,32,SRCAND);
    BitBlt(hdc,xStart,yStart,
32,32,hdcmem,0,0,SRCPAINT);
   }

   

   xStart
+=32;
  }

  yStart
+=32;
 }


 sprintf(temp,
"剩余: %d 个        ",iLeft);
 TextOut(hdc,
32*iWidth+40,150,temp, strlen(temp));

 sprintf(info,
"w:%d,h: %d, num:%d",iWidth,iHeight,iMineNum);
 TextOut(hdc,
0,32*iHeight+10,info, strlen(info)); 
}


void GameMap::SetMine(int iNum)
{
 iMineNum
=iNum;
}


void GameMap::SetMapSize(int w,int h)
{
 
if(w<=0 || h<=0)
 
{
  
return;
 }


 iWidth
=w;
 iHeight
=h;
}


//返回0表示失败,非0表示成功
int GameMap::CreateMap(void)
{
 
int i=0;
 
int x=0;
 
int y=0;
 
int flag=0;
 
char temp[20]={0};

 
//根据地图大小,雷的个数生成一张地图
 if(iWidth<=1 || iHeight<=1)
 
{
  
return 0;
 }


 
if(iMineNum<=1)
 
{
  
return 0;
 }


 memset(pData,
0xff,iWidth*iHeight);

 
//在地图中放置雷
 srand((unsigned int)time(NULL));
 
for(i=0;i<iMineNum;i++)
 
{
  flag
=0;//当前没有布雷
  while(0==flag)
  
{
   
//随机生成x,y坐标
   x=rand()%iWidth;
   y
=rand()%iHeight;
   
   
if(pData[y*iWidth+x]!=BOMB)
   
{
    pData[y
*iWidth+x]=BOMB;
    flag
=1;
   }

   
else
   
{
    flag
=0;//雷的坐标重复,继续选择坐标
   }

  }

 }


 
//生成数字
 for(y=0;y<iHeight;y++)
 
{
  
for(x=0;x<iWidth;x++)
  
{
   
if(BOMB==pData[y*iWidth+x])
   
{
    
continue;
   }

   pData[y
*iWidth+x]=CountBombNum(x,y);
  }
 
 }


 
//灰度图初始化
 memset(pGray,0,400);
 
return 1;
}


int GameMap::CountBombNum(int x,int y)
{
 
//雷的计数
 
//0 1 2
 
//3   4 
 
//5 6 7
 int iNum[8]={0};
 
int iSum=0;
 
int i=0;

 
if(INCLOSEAREA(x-1,y-1,iWidth-1,iHeight-1))
 
{
  iNum[
0]=( pData[(y-1)*iWidth+x-1]==BOMB)?1:0;
 }


 
if(INCLOSEAREA(x,y-1,iWidth-1,iHeight-1))
 
{
  iNum[
1]=( pData[(y-1)*iWidth+x]==BOMB)?1:0;
 }


 
if(INCLOSEAREA(x+1,y-1,iWidth-1,iHeight-1))
 
{
  iNum[
2]=( pData[(y-1)*iWidth+x+1]==BOMB)?1:0;
 }


 
//第2层
 if(INCLOSEAREA(x-1,y,iWidth-1,iHeight-1))
 
{
  iNum[
3]=( pData[y*iWidth+x-1]==BOMB)?1:0;
 }


 
if(INCLOSEAREA(x+1,y,iWidth-1,iHeight-1))
 
{
  iNum[
4]=( pData[y*iWidth+x+1]==BOMB)?1:0;
 }


 
//第3层
 if(INCLOSEAREA(x-1,y+1,iWidth-1,iHeight-1))
 
{
  iNum[
5]=( pData[(y+1)*iWidth+x-1]==BOMB)?1:0;
 }


 
if(INCLOSEAREA(x,y+1,iWidth-1,iHeight-1))
 
{
  iNum[
6]=( pData[(y+1)*iWidth+x]==BOMB)?1:0;
 }


 
if(INCLOSEAREA(x+1,y+1,iWidth-1,iHeight-1))
 
{
  iNum[
7]=( pData[(y+1)*iWidth+x+1]==BOMB)?1:0;
 }



 
for(i=0;i<8;i++)
 
{
  iSum
+=iNum[i];
 }


 
return iSum;
}


void GameMap::SetDC(HDC h)
{
 hdc
=h;
}


void GameMap::SetHWND(HWND h)
{
 hwnd
=h;
}


void GameMap::SetHINSTANCE(HINSTANCE h)
{
 hinstance
=h;
}


void GameMap::LoadPic(void)
{
 
if(!hinstance)
 
{
  MessageBox(hwnd,
"Load Picture:instance is null","bitmap",MB_OK);
 }


 
//hbm_earth=LoadBitmap(hinstance,"pic/earth.bmp");
 hbm_earth=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_EARTH));
 hbm_number
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_NUMBER)); 
 hbm_bomb
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BOMB)); 
 hbm_mask
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_MASK)); 
 hbm_sign
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_SIGN));
 hbm_face
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_FACE));
 hbm_flag
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_FLAG));
 hbm_gray
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_GRAY));
 hbm_back
=LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BACK));

 hdc
=GetDC(hwnd);
 hdcmem
=CreateCompatibleDC(hdc);
 ReleaseDC(hwnd,hdc);
}


//return 1: 打开了雷
int GameMap::OpenGrid(int x,int y)
{
 
int i;
 
 
if(GETBIT(pData[y*iWidth+x] , 7))
 
{
  
//已经打开的格子不处理
  return 0;
 }


 
if(GETBIT(pData[y*iWidth+x] , 6))
 
{
  
//已经标记的格子不处理
  return 0;
 }


 
//bit7 置1 ,表示打开
 pData[y*iWidth+x] |=0x80;
 
 
//动画效果
 pGray[y*iWidth+x] |=0x80;


 
if(BOMB==LOWBYTE(pData[y*iWidth+x]))
 
{
  iState
=G_END;
  iFaceState
=3;//笑脸标志,哭

  
//bit5置1,表示该雷被点击,要显示叉
  pData[y*iWidth+x] |=0x20;
  
  
//点中雷的界面处理  
  for(i=0;i<iWidth*iHeight;i++)
  
{
   
if(BOMB==LOWBYTE(pData[i]))
   
{
    
if( ! GETBIT(pData[i],6))
    
{
     
//还没有标记出的雷置为显示态
     pData[i]|=0x80;
    }
    
   }

   
else
   
{
    
if( GETBIT(pData[i],6) )
    
{
     
//不是雷的格子如果有标记,则要显示叉
     pData[i]|=0x20;
    }

   }

  }

  
return 1;
 }

 
else if(0==LOWBYTE(pData[y*iWidth+x]))
 
{
  
//空白格子搜索
  SearchBlank(x,y);
 }

 
return 0;
}


void GameMap::DrawButton(void)
{
 SelectObject(hdcmem,hbm_face);
 BitBlt(hdc,button_pos.x,button_pos.y,
32,32,hdcmem,iFaceState*32,0,SRCCOPY);
}


void GameMap::SearchBlank(int x,int y)
{
 
int tempindex[16]={-1, -1,  0, -1, 1, -1, 
                 
-1 ,0,          1, 0, 
        
-1, 1,   0, 1,  1, 1}
;              
 
int i;

 
//bit7: visible
 
//0 :earth
 
//9: bomb
 POINT temp;
 POINT temparound;
 
 
//表示可见
 pData[y*iWidth+x]|=0x80;
 temp.x
=x;
 temp.y
=y;
 
 queue.CreateQueue(iWidth
*iHeight);

 queue.InQueue(temp);
 
while(!queue.IsEmpty())
 
{

  temp
=queue.OutQueue();
  
if(temp.y>iWidth-1 || temp.x>iWidth-1)
  
{
   MessageBox(hwnd,
"index error","err",MB_OK);
   
return;
  }

  
//打开当前格子
  pData[temp.y*iWidth+temp.x] |= 0x80;
  
  
for(i=0;i<8;i++)
  
{
   
//判断周围8个格子
   temparound.x = temp.x+tempindex[i*2];
   temparound.y 
= temp.y+tempindex[i*2+1];

   
//判断坐标是否合法
   if ( INCLOSEINDEX(temparound.x, temparound.y))
   
{
    
//周围的格子是空格,并且没有打开
    if( (0== LOWBYTE(pData[temparound.y*iWidth+temparound.x]) )
     
&& !GETBIT(pData[temparound.y*iWidth+temparound.x],7) )
    
{
     
//该格子进队列
     queue.InQueue(temparound);
    }

    
//打开格子
    pData[(temparound.y)*iWidth + temparound.x ] |= 0x80;

    
//动画效果
    pGray[(temparound.y)*iWidth + temparound.x ] |=0x80;
   }

  }

 }
 
 queue.DeleteQueue();
}


void GameMap::SetFlag(int x,int y)
{
 
//已经打开的格子不允许置标记
 if( GETBIT(pData[y*iWidth+x],7) )
 
{
  
return;
 }


 
//bit6表示是否做标记,通过异或操作实现bit翻转
 pData[y*iWidth+x] ^= 0x40;
}

void GameMap::ClearFlag(int x,int y)
{
 
//清除标记
 pData[y*iWidth+x] &= (~0x40);
}


int GameMap::CheckWin(void)
{
 
int i;

 
for(i=0;i<iWidth*iHeight;i++)
 
{
  
if( BOMB ==LOWBYTE(pData[i]))
  
{
   
if(!GETBIT(pData[i],6))
   
{
    
//有一个雷未被标记
    return 0;
   }

  }

  
else if(!GETBIT(pData[i],7))
  
{
   
//不是雷的格子没有打开
   return 0;
  }

 }


 
//游戏结束
 iState=G_END;

 
return 1;
}


void GameMap::SetMap(int w,int h,int num)
{
 iWidth
=w;
 iHeight
=h;
 iMineNum
=num;
 
 
//1,2,3表示初级,中级,高级,4为无效值
 iLevel=4;

 button_pos.x
= 32*iWidth+50;
 button_pos.y
= 20;
}


int GameMap::GetHeight(void)
{
 
return iHeight;
}


int GameMap::GetWidth(void)
{
 
return iWidth;
}

int GameMap::GetNum(void)
{
 
return iMineNum;
}


//左右键同时单击某个格子
int GameMap::Open8around(int x,int y)
{
 
char temp[20]={0};
 
int value=0;
 
int sign_num=0;
 
int tempindex[16]={-1, -1,  0, -1, 1, -1, 
                 
-1 ,0,          1, 0, 
        
-1, 1,   0, 1,  1, 1}
;   
 
int i;

 memset(info,
0,sizeof(info));

 
if( ! GETBIT(pData[y*iWidth+x],7))
 
{
  strcpy(info,
"not open");  
  
//没有打开
  return 0;
 }


 value
=LOWBYTE(pData[y*iWidth+x]);
 
if(value ==0 || value ==BOMB )
 
{
  strcpy(info,
"not number");
  
//不是数字
  return 0;
 }


 
//周围的雷是否都已标记
 for(i=0;i<8;i++)
 
{
  
//下标合法
  if( INCLOSEINDEX(x+tempindex[i*2], y+tempindex[i*2+1]) )
  
{
   
//bit6是否标记出
   if(  GETBIT(pData[(y+tempindex[i*2+1])*iWidth + x+tempindex[i*2]],6))
   
{
    sprintf(temp,
"(%d)%d,%d:%x; ", i, 
     x
+tempindex[i*2],y+tempindex[i*2+1],
     pData[(y
+tempindex[i*2+1])*iWidth + x+tempindex[i*2]]);
    strcat(info,temp);
    sign_num
++;     
   }

  }

 }


 
//雷的个数和该格子的数字不等,没有标记出周围所有的雷
 if(sign_num != value)
 
{
  
//sprintf(info,"not equal ",sign_num, value);
  return 0; 
 }


 
//打开周围的格子
 for(i=0;i<8;i++)
 
{
  
//下标合法
  if( INCLOSEINDEX(x+tempindex[i*2], y+tempindex[i*2+1]) )
  
{
   
//没有打开的格子
   if(! GETBIT(pData[(y+tempindex[i*2+1])*iWidth + x+tempindex[i*2]], 7 ))
   
{
    
//没有标记的格子
    if(! GETBIT(pData[(y+tempindex[i*2+1])*iWidth + x+tempindex[i*2]], 6 ))
    
{
     
//pData[(y+tempindex[i*2+1])*iWidth + x+tempindex[i*2]] |= 0x80;
     OpenGrid(x+tempindex[i*2], y+tempindex[i*2+1]);
    }

   }

  }

 }


 
return 1;
}


void GameMap::SetLevel(int l)
{
 iLevel
=l;
 
 
switch(iLevel)
 
{
 
case 0:
  iWidth
=9;
  iHeight
=9;
  iMineNum
=10;
  
break;
 
case 1:  
  iWidth
=15;
  iHeight
=15;
  iMineNum
=36;
  
//MessageBox(hwnd,"set level 1","set",MB_OK);
  break;
 
case 2:
  iWidth
=20;
  iHeight
=20;
  iMineNum
=50;
  
break;
 
default:
  
break;
 }


 button_pos.x
= 32*iWidth+50;
 button_pos.y
= 20;
}


int GameMap::GetLevel(void)
{
 
return iLevel;
}


void GameMap::LoadScore(void)
{
 FILE 
*f;
 f
=fopen("D:/score.dat","r");
 
 
if(!f)
 
{
  fopen(
"D:/score.dat","w");
  
return;
 }


 fread(scorename,
sizeof(char),80,f);
 fread(scoretime,
sizeof(int),3,f);
 fclose(f);
}


void GameMap::GetName(int l,char *pname)
{
 
if(l>=0 && l<=2)
 
{
  
if( strlen(scorename+20*l) )
  
{
   strcpy(pname, scorename
+20*l);
  }

 }

}


void GameMap::WriteScore(int l,char *pname,int time)
{
 FILE 
*f;

 
if( strlen(pname)>=20)
 
{
  
return;
 }


 strcpy( scorename
+l*20, pname);
 scoretime[l]
=time;

 
//写到文件中
 f=fopen("D:/score.dat","w");
 
 
if(!f)
 
{
  
return;
 }


 fwrite(scorename,
sizeof(char),80,f);
 fwrite(scoretime,
sizeof(int ), 3,f);
 fclose(f);
}


int GameMap::GetTimeValue(int l)
{
 
if(l>=0 && l<=2)
 
{
  
if (0<=scoretime[l] && scoretime[l]<=999)
  
{
   
return scoretime[l];
  }

 }

 
return 999;
}


void GameMap::ResetScore(int l)
{
 FILE 
*f;

 memset(scorename
+l*20, 0, 20);
 scoretime[l]
=999;

 
//写到文件中
 f=fopen("D:/score.dat","w");
 
 
if(!f)
 
{
  
return;
 }

 fwrite(scorename,
sizeof(char),80,f);
 fwrite(scoretime,
sizeof(int ), 3,f);
 fclose(f);
}


int GameMap::IsNewScore(int l,int score)
{
 
if (! (l>=0 && l<=2))
 
{
  
return 0;
 }


 
if(  (unsigned)score < (unsigned)scoretime[l] )
 
{
  
//已经破了该等级的纪录
  return 1;
 }

 
return 0;
}


void GameMap::DrawAnimation(void)
{
 
int xStart=0;
 
int yStart=0;
 
int i=0;
 
int j=0;
 
char temp[50]={0};
 
char igrid=0;
 
char iAnimation=0;
 
 yStart
=-8;//绘图坐标
 for(j=0;j<iHeight;j++)
 
{
  xStart
=-8;
  
for(i=0;i<iWidth;i++)
  
{
   igrid
=pGray[j*iWidth+i];
   
//动画显示,字节(bit7~bit0)的bit7,1,显示动画,0,没有
   if(GETBIT(igrid,7))
   
{
    iAnimation 
= LOWBYTE(igrid);
    
//先画地面背景
    SelectObject(hdcmem,hbm_gray);
    BitBlt(hdc,xStart,yStart,
48,48,hdcmem,iAnimation*48,48,SRCAND);
    BitBlt(hdc,xStart,yStart,
48,48,hdcmem,iAnimation*48,0,SRCPAINT);

    iAnimation
++;
    
if(iAnimation>2)
    
{
     
//清除播放标志bit7,恢复成0
     pGray[j*iWidth+i]=0;
    }

    
else
    
{
     
//改变动画帧,置播放标志
     pGray[j*iWidth+i]=iAnimation;
     pGray[j
*iWidth+i] |=0x80;
    }

   }

   xStart
+=32;
  }

  yStart
+=32;
 }

}

AI扫雷有多牛?他国纷纷来求师学艺(附完整教程) 前文 大家好!我是梨子同学! 希望大家多多支持我!哈哈 为了感谢每一个关注我的小可爱:????每篇文章的项目源码都是无偿分享滴????见文末! 很多csdn的功能还在研究中,还有小编的文笔不好勿怪,会慢慢进步跟大家一起学习的 小编也一直在学习编程,如果代码小程序出现错误欢迎大家评论区留言哈! 最后——如果文章有帮助到你,记得“关注”、“点赞”、“评论”三连哦~ 前言 《扫雷》是一款大众类的益智小游戏,于1992年发行。 游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同 阅读详情

相关推荐

C#编扫雷源码 一2008年03月23日

把以前写的东西存下来 嘿嘿 转载http://hi.baidu.com/activezfj/blog/item/31cd4b3499f6eb4a241f14b7.html(此博客已无情被关,近3000多篇原创呀,说出来都是泪) 源代码: [Form1.CS] using System; using System.Drawing; using System.Collect

关中游侠 854

带爆炸效果的扫雷(源码1)

 这个程序是以前写的,编码水平一般,规范性、命名还可以,待改进的地方有很多,大家拷下来自己玩吧。第一次把我写的代码贴出来。ok,开始,先来个截图:当鼠标单击的时候,有一个爆炸效果将格子炸开。程序简单说明:包含了计时,等级设置(含自定义),帮助对话框,排行榜。技术上没有用MFC,纯SDK做的。使用了两个定时器,一个表示成绩,一个播放动画。算法:如果单击的是空白格子,那么周围所有相

programking的快乐生活 1350

HTML在线扫雷游戏网页源码

HTML在线扫雷游戏网页源码是一款基于HTML+CSS+JavaScript开发的在线扫雷小游戏单页源码,为用户提供了一个无需安装即可在浏览器中直接玩的扫雷游戏。该游戏的源码不仅包含了完整的游戏逻辑,还具备丰富的界面设计和用户交互功能,可以作为前端毕业设计项目参考。

专注于与编程相关的知识内容分享 980

带爆炸效果的扫雷(后记)

对话框资源,和图片素材就不贴了。想做一个横版过关的游戏,或者一个简单的45度样例,终究要写一个3D的,《星际2》,《暗黑》,还有《魔兽世界》,真是电影级的水准。《魔兽争霸》的过场动画已经是电影级的了,人家这技术才称的上“探索”二字。我这个程序,只是让各路大侠看看,以后还有别的游戏。

programking的快乐生活 920

Java写的经典扫雷游戏,带音效和成绩记录,双击就能玩

用Java开发的完整扫雷游戏,源码清晰、结构规范,直接双击1.bat即可运行,无需额外配置。界面采用GIF图标(start.gif、lei.GIF、qi.GIF)实现按钮与雷区可视化,内置三种音频资源:点击音效(ding.wav)、爆炸音效(bob.wav)和背景音乐(music.mid),增强操作反馈和游戏氛围。成绩自动保存到record.txt文件,历史记录存放在O纪录文件夹,支持本地持久化。项目包含全部源文件(saolei.java)和编译后字节码(saolei.class),.gitignore和.

bean的博客 268

java课程设计大作业写的 扫雷小游戏(带音效)

java课程设计大作业写的 扫雷小游戏(带音效) java课程设计大作业写的 扫雷小游戏(带音效)

扫雷游戏(整体游戏架构分析+源码分析)

1.此游戏完成了我童年的梦2.锻炼了我在函数和数组这方面的知识复习3.而外掌握“缓冲区”,随机函数,时间戳等知识。

2402_84849509的博客 1033

【文章阅读+代码复现】Point-GNN

Brief 在3D点云语义分割方法中,GNN已经做了很多可用的方案,但是在目标检测上依旧是采用比较传统的CNN和稀疏卷积的组合,这一篇文章是研究了图卷积在3D检测的中的用法。来自卡内基梅隆大学。已经被CVPR2020接收. 这里是 paper 这里是 code Abstruct 一个采用GNN设计的3D目标检测框架 过程是先将点云场景编码成图结构,随后设计了一个叫point-GNN的网络结构,在...

有所为,有所成长 1万+

扫雷游戏开发教程:从零打造精美像素扫雷

通过本教程,你已经学会了如何开发一个功能完整的扫雷游戏。记住,游戏开发就像扫雷一样——需要耐心、策略和一点冒险精神!当你遇到"地雷"(bug)时,不要灰心,标记它、分析它,然后优雅地解决它。

代数的博客 1395

U8-固定资产月末结账报错:BOF或EOF中有一个是真

度了下,发现此问题一般是由于fa_Vtsobject表缺少对应月份的记录导致,补上即可,但是查看发现此表记录正常。 跟踪后发现定位到以下语句: select * from AccInformation where cSysID = N'FA' and cName =N'bVoucherApply'上述语句执行后没有任何记录显示,但是在正常的账套执行是有记录的,那有可能就是记录丢失导致,执行以下

guizhouakun的博客 5917

Python爬取拼多多商品数据保姆级教程(附源码及效果图)

本文介绍了使用Python爬取拼多多商品数据的完整教程。通过DrissionPage库模拟浏览器操作,利用正则表达式提取嵌入在HTML中的商品数据(关键步骤是从window.rawData变量获取),解析后转换为结构化数据并导出Excel。教程包含八大步骤:环境配置、浏览器初始化、网络监听、搜索模拟、数据提取(核心是正则匹配JSON)、数据验证、字段解析和Excel导出,最后提供了封装好的函数可直接调用。该方法特别适合课程作业或毕业设计获取电商数据,能爬取商品名称、价格、销量等关键信息,处理了价格单位转换等

weixin_46449236的博客 2077

带爆炸效果的扫雷(源码4)

 计时器:由于需要暂停/恢复计时、绘图,所以专门作了一个类。 其中用了三个状态#define T_CLOSE 0#define T_START 1#define T_PAUSE 2应该可以优化。附 mytimer.h  mytimer.cpp//定时器#ifndef __MYTIMER_H#define __MYTIMER_H#define T_CLOSE 0#define T_S

programking的快乐生活 921

Yolov8-pose关键点检测:loss优化 | LRM loss困难样本挖掘,提升难样本、遮挡物等检测精度

LRM loss应用到能够大幅提升pose遮挡物性能

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1715

两分钟教你用C++修改"扫雷"游戏的设置,有源码哦!

C++ 6.0 修改"扫雷"游戏的设置,可以对扫雷游戏的界面进行设置,设置 黑白界面和彩色界面,可修改扫雷游戏英雄榜级别、英雄名称和所用时间,可设置是否添加对扫雷游戏中引爆地雷发出爆炸声。 源码结构截图: 主要源码展示: 这个小程序可以实现自动扫雷,只是娱乐和学习之用,没别的用途,大家勿骂。 我没有改变计时器,想必大家都知道系统自带一个方便扫雷的功能就是“XY...

1284

还原 Windows 环境变量的默认值

有时候,我们可能需要还原环境变量的默认值,以修复可能的配置问题或恢复系统的正常运行。如果您只想还原某个特定的环境变量,可以跳过删除其他变量的步骤,仅删除需要还原的变量即可。在“环境变量”对话框中,继续向下滚动到“系统变量”部分。请注意,在执行以下步骤之前,您应该备份当前的环境变量设置,以便在需要时可以还原。在删除所有需要还原的环境变量后,点击“确定”按钮关闭“环境变量”对话框。在“用户变量”部分,选择需要还原的变量,然后点击“删除”按钮。在“高级”选项卡下方的“环境变量”部分,点击“环境变量”按钮。

PvDeveloper的博客 6342

Qemu开发ARM篇-5、buildroot制作根文件系统并挂载启动

在上一篇中,我们编译了kernel,并在qemu上进行了运行,但到最后,在挂载根文件系统时候,挂载失败,这是因为我们还没有根文件系统,在本章中,我们将制作根文件系统。rootfs制作方式有很多方式,如busyBoxbuildrootYocto等,在该篇章中,我们使用buildroot来制作根文件系统,主要考虑到busyBox制作完还需要手动首改一些启动配置比较繁琐,而Yocto如果电脑配置不是很好,编译时间过长,比较麻烦。

sinat_33909696的博客 2465

经典扫雷游戏开发全解析:HTML+CSS+JavaScript实现

本教程将完整呈现如何用原生前端三剑客(HTML+CSS+JavaScript)实现经典扫雷游戏。该实现包含以下核心功能: 2. 视觉设计(CSS) 亮点特性: 3. 游戏逻辑(JavaScript) 核心算法流程图:左键点击右键点击是否初始化游戏生成雷区计算相邻雷数渲染棋盘玩家操作揭示格子标记旗帜是否触雷?游戏失败检查胜利条件 三、功能亮点详解 1. 雷区生成算法 2. 递归展开算法 四、游戏操作指南 左键点击:揭示格子 右键点击:标记/取消标记地雷 新游戏按钮:重置游戏 胜利条件:正确标记所有地雷并

TengMMVP的博客 2156

经典的YOLOv3和YOLOV5算法详解及代码复现

yolov3和yolov5算法详解及代码复现

hasakie的博客 770

C语言实现扫雷游戏(含展开、含标记)---完整源码与分析!!!

本次我们利用C语言实现了扫雷游戏,包含标记功能,0位展开功能,对于各个模块进行了细致的分析与分模块代码的讲解,最后再文章附有完整的源码,欢迎大家学习。

m0_56399733的博客 384

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【Pygame小游戏】复刻经典游戏扫雷,你能玩到最后吗?

扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。它是许多人接触到的第一款游戏,大概也是广大办公族和无网学生无聊时消遣的最佳游戏,是不是每次见到戴上墨镜的小人很有成就感?那么?怎么才能通关呢?这,有生之年靠自己猜可能做不到了,BUT我们可以靠一靠我们的Python自动扫雷的嘛!不要慌呢~我们正式开始吧!

zhang120529的博客 757

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Python扫雷游戏

pygame开发的扫雷小游戏

xiejijun的博客 676

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

VC6.0仿Windows自带扫雷程序

昔日旧作,发上来共享交流下! 源码及程序下载地址:VC6.0仿Windows自带扫雷程序(附源码) 程序运行截图: mine 扫雷程序编程及在过程中遇到的问题的解决 一、对扫雷程序的分析(Windows自带版) 这个阶段的工作要基于对扫雷的充分了解,所以就要反复的玩这个游戏了。基本上可以说,一个扫雷程序写下来,一名扫雷高手也就诞生了。 (1)外观分析 游戏主窗口——

靠谱-ing 3404

复刻经典游戏扫雷,你能玩到最后吗?【Python小游戏】

扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。它是许多人接触到的第一款游戏,大概也是广大办公族和无网学生无聊时消遣的最佳游戏,是不是每次见到戴上墨镜的小人很有成就感?那么?怎么才能通关呢?这,有生之年靠自己猜可能做不到了,BUT我们可以靠一靠我们的Python自动扫雷的嘛!不要慌呢~我们正式开始吧!借助这样一个机会记录一下如何使用Conda进行环境的创建、管理以及软件包的安装、升级和卸载等操作。

Python_HUHU的博客 548

c# emnu 获取注释_C#编写扫雷游戏【源码下载在文末】

翻看了下以前大学学习的一些小项目,突然发现有个项目比较有意思,觉得有必要把它分享出来。当然现在看来,里面有很多的不足之处,但因博主现在已经工作,没有时间再去优化。这个项目就是利用C#编写一个Windows系统下的扫雷小游戏。首先讲下扫雷小游戏的玩法:(1)扫雷就是要把所有非地雷的格子揭开即胜利;踩到地雷格子就算失败。(2)当点开的格子不是地雷区域的时候,该格子会显示一个数字,该数字表示的...

weixin_34286711的博客 200

C语言+EasyX实战:从零打造图形化扫雷游戏(附完整源码与避坑指南)

本文详细介绍了如何使用C语言和EasyX图形库从零开发一款图形化扫雷游戏。通过完整的源码示例和避坑指南,帮助初学者快速掌握图形界面开发技巧,包括雷区数据结构设计、递归展开算法、鼠标交互处理等核心功能实现。特别适合刚学完C语言想进阶图形化开发的学习者。

weixin_30448603的博客 347
上一篇: 带爆炸效果的扫雷(源码1)
下一篇: 带爆炸效果的扫雷(源码3)
programking
博客等级 码龄23年 450粉丝 140原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值