VC写一个荣光医院修补弹坑游戏助手

来源:互联网 发布:网络视频会议设备价格 编辑:程序博客网 时间:2024/04/28 19:10

荣光医院和种草及动物园游戏,近来玩者甚众,小生也不能免俗,忙中抽闲,小玩了一把.可惜技艺不精,级数较低,刚到中央区,人就被拉的惨不忍睹,有些还能回拉,遇到有些高级玩家,一回拉,竟然赏我了两个弹坑,实在影响医院美观.据说弹坑只有两个办法修补,一个是花钱买道具修补,一个是玩修补弹坑游戏过关也能修补,系统一般会概率性的出现修补弹坑游戏.咱这穷人,只能盼着系统出现这样的游戏了.不过这个游戏还真不容易通过,一是出现的时间短,二是修补的块会变色,手动抓图基本上是跟不上变化.除非眼快手快加大脑而那个弹坑也真的是影响市容,所以就想通过编程来帮助这个游戏过关.原理其实很简单,就是使用快捷键抓图.只抓与游戏有关的一小块区域,抓到后把图像内容从上到下刷到屏幕左边,左边刷满刷右边,只留下中间用来做游戏.

网上搜了一下,发现VCKBASE上作者Rover的文章<抓图程序开发实践>与我的需求非常接近,打算采用拿来主义对该程序作一些改造,有关抓图原理和快捷键用法,请参考Rover同志的文章.ROVER的文章是把图像保存为BMP,我这里不保存,直接贴到屏幕上.

http://www.vckbase.com/document/viewdoc/?id=263

 

打开Rover同志的代码,找到SaveBmp函数,该函数主要功能是实现抓图并保存,我们对这个函数进入手术加工.首先我们定义两个变量,用来计算贴图的位置,int x_i = 0, y_i = 0;然后我们修改该函数中抓图区域,定义四个变量x,y, width, height,后来为了防止贴图时超出屏幕,又定义了两个变量SWidth,SHeight:

#if 0
 int Width=GetSystemMetrics(SM_CXSCREEN);
 int Height=GetSystemMetrics(SM_CYSCREEN);
#elif (0)
 int x = 500;
 int y = 400;
 int Width = 500;
 int Height = 400;

 int SWidth=GetSystemMetrics(SM_CXSCREEN);
 int SHeight=GetSystemMetrics(SM_CYSCREEN);

#endif

这四个变量的值x,y, width, height,是我根据自己电脑上游戏的显示区域设置的,根据需要自己修改吧.其实我最早时使用的是下面的代码来获取窗口,但是不知道什么原因,无法获取网页FLASH的对话框,后来不得已,抓图区域写死了,就成了上面的状态.精通的朋友指点一下为什么下面的代码无法获取网页的对话框.

 CWnd* pWnd = GetActiveWindow();   //CWnd::GetForegroundWindow();
 RECT rc;
 
 pWnd->GetWindowRect(&rc);
 int x = rc.left;
 int y = rc.top;
 int Width= rc.right-x;
 int Height=rc.bottom - y;

能用就行,不管那么多,然后我们修改他的抓图代码,变成我们自己的,并添加刷屏代码,原来的代码是从(0,0)开始,抓整个屏幕,改后从(x,y)开始,抓Width,Height大小的区域,然后计算贴图位置,刷到DC上:

#if 0
 tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
#else
 tdc.BitBlt(0,0,Width,Height,&dc,x,y,SRCCOPY);
 if ((y_i+100) > SHeight)
 {
  y_i = 0;

if (x_i != 0)

{

x_i = 0;

}

else

{
  x_i = SWidth - 100;

}
 }
    dc.BitBlt(x_i,y_i,Width,Height,&tdc,0,0,SRCCOPY);
    y_i += 100;
#endif

这样手术完成,一个抓图程序成了一个小小的游戏助手.最后整个函数变成如下内容:

int x_i = 0, y_i = 0;
void CCaptureDlg::SaveBmp()
{
 CDC dc;
 //创建设备dc
 dc.CreateDC("DISPLAY",NULL,NULL,NULL);

 CDC tdc;
 //创建与设备dc兼容的内存DC
 tdc.CreateCompatibleDC(&dc);

 CBitmap bm;
#if 0
 int Width=GetSystemMetrics(SM_CXSCREEN);
 int Height=GetSystemMetrics(SM_CYSCREEN);
#elif (0)
 int x = 500;
 int y = 400;
 int Width = 500;
 int Height = 400;
#elif (1)
 int x = 500;
 int y = 400;
 int Width = 500;
 int Height = 100;
 int SWidth=GetSystemMetrics(SM_CXSCREEN);
 int SHeight=GetSystemMetrics(SM_CYSCREEN);

#else
 CWnd* pWnd = GetActiveWindow();
 RECT rc;
 
 pWnd->GetWindowRect(&rc);
 int x = rc.left;
 int y = rc.top;
 int Width= rc.right-x;
 int Height=rc.bottom - y;
#endif
//创建与dc兼容的BMP
 bm.CreateCompatibleBitmap(&dc,Width,Height);

 CBitmap *pOld=tdc.SelectObject(&bm);
#if 0
 tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
#else
 tdc.BitBlt(0,0,Width,Height,&dc,x,y,SRCCOPY);
 if ((y_i+100) > SHeight)
 {
  y_i = 0;
  x_i = SWidth - 100;
 }
    dc.BitBlt(x_i,y_i,Width,Height,&tdc,0,0,SRCCOPY);
    y_i += 100;
#endif
 tdc.SelectObject(pOld);

 BITMAP btm;
 bm.GetBitmap(&btm);
 DWORD size=btm.bmWidthBytes*btm.bmHeight;
 LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size);
/////////////////////////////////////////////
 BITMAPINFOHEADER bih;
 bih.biBitCount=btm.bmBitsPixel;
 bih.biClrImportant=0;
 bih.biClrUsed=0;
 bih.biCompression=0;
 bih.biHeight=btm.bmHeight;
 bih.biPlanes=1;
 bih.biSize=sizeof(BITMAPINFOHEADER);
 bih.biSizeImage=size;
 bih.biWidth=btm.bmWidth;
 bih.biXPelsPerMeter=0;
 bih.biYPelsPerMeter=0;
///////////////////////////////////
 GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
// bm.GetBitmapBits(size,lpData); //此函数在处理5-5-5模式的16位色下会出现颜色混乱
//////////////////////////////
 static int filecount=0;
 CString name;
 name.Format("pict%04d.bmp",filecount++);
 name=m_Path+name;
 BITMAPFILEHEADER bfh;
 bfh.bfReserved1=bfh.bfReserved2=0;
 bfh.bfType=((WORD)('M'<< 8)|'B');
 bfh.bfSize=54+size;
 bfh.bfOffBits=54;
 CFile bf;
 if(bf.Open(name,CFile::modeCreate|CFile::modeWrite)){
  bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
  bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));
  bf.WriteHuge(lpData,size);
  bf.Close();
  nCount++;
 }
 GlobalFreePtr(lpData);
 if(nCount==1)
  m_Number.Format("%d picture captured.",nCount);
 else
  m_Number.Format("%d pictures captured.",nCount);
 UpdateData(FALSE);
}