⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ripple.cpp

📁 C++写的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        return FALSE;
    return TRUE;
}

//******************************************************************
//函数:WinMain()
//功能:应用程序入口
//******************************************************************
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
{
    MSG         msg;
	hInst=hInstance;

	//初始化主窗口
	if ( !InitWindow( hInstance, nCmdShow ) )
		return FALSE;

	//初始化DirectDraw环境
	if ( !InitDDraw())
	{
		MessageBox(fullscreen ? hwndwin:hwndful, "初始化DirectDraw过程中出错!", "Error", MB_OK );
		FreeObjects();
		return FALSE;
	}
    snake.init();  //初始化蛇类的数据
	//进入消息循环
	while(1)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
			TranslateMessage(&msg); 
			DispatchMessage(&msg);
		}
		else if(bActive)
		{
			UpdateFrame();
		}
		else WaitMessage();
	}
    return msg.wParam;
} 

//******************************************************************
//函数:InitSurfaces()
//功能:初始化页面图象
//******************************************************************
BOOL InitSurfaces( void )
{
    DDReLoadBitmap(lpDDSPic1, MAKEINTRESOURCE(IDB_BITMAP1));
    DDReLoadBitmap(lpDDSGame, "yqp.bmp");
    buf1 = new short[BACKWIDTH*BACKHEIGHT];
	buf2 = new short[BACKWIDTH*BACKHEIGHT];
	ZeroMemory(buf1, BACKWIDTH*BACKHEIGHT*sizeof(short));
	ZeroMemory(buf2, BACKWIDTH*BACKHEIGHT*sizeof(short));

    return TRUE;
}

//*******************************************************
//计算波能数据缓冲区
//*******************************************************
void RippleSpread()
{
	for (int i=BACKWIDTH; i<BACKWIDTH*BACKHEIGHT-BACKWIDTH; i++)
	{
		//波能扩散
		buf2[i] = ((buf1[i-1]+
					buf1[i+1]+
					buf1[i-BACKWIDTH]+
					buf1[i+BACKWIDTH])
					>>1)
					- buf2[i];
		//波能衰减
		buf2[i] -= buf2[i]>>5;
	}

	//交换波能数据缓冲区
	short *ptmp =buf1;
	buf1 = buf2;
	buf2 = ptmp;
}

//*******************************************************
//根据波能数据缓冲区对离屏页面进行渲染
//*******************************************************
void RenderRipple()
{
	//锁定两个离屏页面
	DDSURFACEDESC ddsd1, ddsd2;
	ddsd1.dwSize = sizeof (DDSURFACEDESC);
	ddsd2.dwSize = sizeof(DDSURFACEDESC);
	lpDDSPic1->Lock(NULL, &ddsd1, DDLOCK_WAIT, NULL);
	lpDDSPic2->Lock(NULL, &ddsd2, DDLOCK_WAIT, NULL);

	//取得页面象素位深度,和页面内存指针
	int depth=ddsd1.ddpfPixelFormat.dwRGBBitCount/8;
	BYTE *Bitmap1 = (BYTE*)ddsd1.lpSurface;
	BYTE *Bitmap2 = (BYTE*)ddsd2.lpSurface;
	
	//下面进行页面渲染
	int xoff, yoff;
	int k = BACKWIDTH;
	for (int i=1; i<BACKHEIGHT-1; i++)
	{
		for (int j=0; j<BACKWIDTH; j++)
		{
			//计算偏移量
			xoff = buf1[k-1]-buf1[k+1];
			yoff = buf1[k-BACKWIDTH]-buf1[k+BACKWIDTH];

			//判断坐标是否在窗口范围内
			if ((i+yoff )< 0 ) {k++; continue;}
			if ((i+yoff )> BACKHEIGHT) {k++; continue;}
			if ((j+xoff )< 0 ) {k++; continue;}
			if ((j+xoff )> BACKWIDTH ) {k++; continue;}

			//计算出偏移象素和原始象素的内存地址偏移量
			int pos1, pos2;
			pos1=ddsd1.lPitch*(i+yoff)+ depth*(j+xoff);
			pos2=ddsd2.lPitch*i+ depth*j;

			//复制象素
			for (int d=0; d<depth; d++)
				Bitmap2[pos2++]=Bitmap1[pos1++];
			k++;
		}
	}
	//解锁页面
	lpDDSPic1->Unlock(&ddsd1);
	lpDDSPic2->Unlock(&ddsd2);
}

//********************************************************
//更新屏幕
//********************************************************
void UpdateFrame( void )
{

	GetInput();

    static int NewCount, OldCount=0;
	NewCount=GetTickCount(); 
	if (NewCount > OldCount+snake.level*100)
	{
		OldCount = NewCount;
		snake.nextstatus(); //计算下一步动作
		DropStone(snake.place[snake.head].x*STEP,snake.place[snake.head].y*STEP+STEP/2,3,128);
	}
	RippleSpread();//计算波能数据缓冲区
	RenderRipple();//页面渲染

	//将离屏页面图象Blit到主页面
	RECT Window;
	POINT pt;
	GetClientRect(ChooseWnd(), &Window);
	pt.x=pt.y=0;
	ClientToScreen(ChooseWnd(), &pt);
	OffsetRect(&Window, pt.x, pt.y);
	Draw(NULL);
	lpDDSPrimary->Blt(&Window, lpDDSPic2, NULL, DDBLT_WAIT, NULL);
}

void MakeRect(RECT *rect, short left, short top, short width, short height)
{
	rect->left=left;
	rect->top=top;
	rect->right=left+width;
	rect->bottom=top+height;
}

//*****************************************************
//增加波源
//*****************************************************
void DropStone(int x,//x坐标
			   int y,//y坐标
			   int stonesize,//波源半径
			   int stoneweight)//波源能量
{
	//判断坐标是否在屏幕范围内
	if ((x+stonesize)>BACKWIDTH || 
		(y+stonesize)>BACKHEIGHT||
		(x-stonesize)<0||
		(y-stonesize)<0)
		return;

	for (int posx=x-stonesize; posx<x+stonesize; posx++)
		for (int posy=y-stonesize; posy<y+stonesize; posy++)
			if ((posx-x)*(posx-x) + (posy-y)*(posy-y) < stonesize*stonesize)
				buf1[BACKWIDTH*posy+posx] = -stoneweight;
}

void ShowAbout(void)
{
	char temp[]="\n"
		"               贪食蛇0.1"
		"\n\n"
		" 贪食蛇代码由 游戏程序员  姚秋鹏编写!\n\n"
		" 水波代码由 DirectX工作室 王正盛编写!\n"
		"\n"
		"        主页 : yqp.126.com\n"
		"        Email: yqp@126.com\n"
		;
	
	MessageBox(ChooseWnd(), temp, TITLE, MB_OK);
}

HWND ChooseWnd()
{
	return fullscreen ? hwndful:hwndwin;
}

//调整窗口大小
void AdjustWindowSize(HWND hwnd)
{
	RECT rect;
	MakeRect(&rect, 0, 0, BACKWIDTH, BACKHEIGHT );
	AdjustWindowRectEx( &rect,
						GetWindowStyle(hwnd),
						GetMenu(hwnd)!=NULL,
						GetWindowExStyle(hwnd));
	MoveWindow( hwnd,
		(GetSystemMetrics(SM_CXFULLSCREEN)-(rect.right-rect.left))/2,
		(GetSystemMetrics(SM_CYFULLSCREEN)-(rect.bottom-rect.top))/2,
		rect.right-rect.left,
		rect.bottom-rect.top,
		TRUE);
}

//初始化预览窗口
BOOL InitPreviewWindow( HINSTANCE hInstance, int nCmdShow )
{
    WNDCLASS	wc3;	//窗口类结构

	//填充窗口类结构
    wc3.style = 0;
    wc3.lpfnWndProc = WinProc;
    wc3.cbClsExtra = 0;
    wc3.cbWndExtra = 0;
    wc3.hInstance = hInstance;
    wc3.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(ID_APP)); 
    wc3.hCursor = LoadCursor( NULL, IDC_ARROW);
    wc3.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc3.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
	wc3.lpszClassName = "preview";

	//注册窗口类
    RegisterClass( &wc3 );
    
	return TRUE;
}

void Draw(int gamestatus)
{
	char temp[50];

   int i;
   RECT srect;
   for (i = 0; i < MAX; i++ )
   {
      
      if ( (snake.place[i].st) && (!snake.place[i].c) &&
		  (i != snake.head) && ( i != snake.tear ) )
	  {
		  MakeRect(&srect,(snake.place[i].dir-1)*STEP,STEP,STEP,STEP);
		  lpDDSPic2->BltFast(snake.place[i].x*STEP,snake.place[i].y*STEP,lpDDSGame,&srect,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
	  }
	  if ( (snake.place[i].st)&&(snake.place[i].c) && ( i != snake.tear ) )
	  {
		  MakeRect(&srect,(snake.place[i].c-1)*STEP,STEP*2,STEP,STEP);
		  lpDDSPic2->BltFast(snake.place[i].x*STEP,snake.place[i].y*STEP,lpDDSGame,&srect,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
	  }
   }
   MakeRect(&srect,(snake.place[snake.head].dir-1)*STEP,0,STEP,STEP);
   lpDDSPic2->BltFast(snake.place[snake.head].x*STEP,snake.place[snake.head].y*STEP,lpDDSGame,&srect,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);

   MakeRect(&srect,(snake.place[snake.tear].dir-1)*STEP,60,STEP,STEP);
   lpDDSPic2->BltFast(snake.place[snake.tear].x*STEP,snake.place[snake.tear].y*STEP,lpDDSGame,&srect,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
   
   MakeRect(&srect,0,80,STEP,STEP);
   lpDDSPic2->BltFast(snake.babyx*STEP,snake.babyy*STEP,lpDDSGame,&srect,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
   if(snake.game == GAMEOVER)
   {
   HDC hdc;
		lpDDSPic2->GetDC(&hdc);
		SetBkMode(hdc, TRANSPARENT);
		SetTextColor(hdc, RGB(255,0,0)); 
		sprintf(temp,"你的最后得分是:%d",snake.score);
		TextOut(hdc, 70, 70, temp, strlen(temp));
		sprintf(temp,"[回车]开始新游戏");
		TextOut(hdc, 70, 100, temp, strlen(temp));
		lpDDSPic2->ReleaseDC(hdc);
   }
}

void GetInput( void )
{
	if ( GetAsyncKeyState(VK_UP) )
	{
		if( (snake.control != 2)&& !snake.keydown)
		snake.control = 1;
		snake.keydown = TRUE;
	}
	if ( GetAsyncKeyState(VK_DOWN) )
	{
		if( (snake.control != 1)&& !snake.keydown)
		snake.control = 2;
		snake.keydown = TRUE;
	}
	if ( GetAsyncKeyState(VK_LEFT) )
	{
		if( (snake.control != 4)&& !snake.keydown)
		snake.control = 3;
		snake.keydown = TRUE;
	}
	if ( GetAsyncKeyState(VK_RIGHT) )
	{
		if( (snake.control != 3)&& !snake.keydown)
		snake.control = 4;
		snake.keydown = TRUE;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -