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

📄 ripple.cpp

📁 最好的水波特效代码
💻 CPP
字号:
// Ripple.cpp : Defines the entry point for the application.
//

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

#include <cmath>

inline void SAFE_RELEASE(LPDIRECTDRAW7 lpdd)
{
	if(lpdd)
	{
		lpdd->Release();
		lpdd = NULL;
	}
}

inline void SAFE_RELEASE(LPDIRECTDRAWSURFACE7 lpdds)
{
	if(lpdds)
	{
		lpdds->Release();
		lpdds = NULL;
	}
}

inline BOOL KEYDOWN(int vk)
{
	return GetAsyncKeyState(vk) & 0x80000000;
}
//color function
#define _RGB16BIT565(r,g,b) ((b%32) + ((g%64) << 5) + ((r%32) << 11))
inline int GetRValue565(UINT color){ return (color >> 11) & 0x1f; }
inline int GetGValue565(UINT color){ return (color >> 5) & 0xef;}
inline int GetBValue565(UINT color){ return color & 0x1f; }
inline int RGB16BIT565(int r, int g, int b){ return ((r%32) <<11) + ((g%64) << 5) + b%32; }

// Global Variables:
HINSTANCE hInst;								// current instance
HWND main_window_handle;
const TCHAR szTitle[] = "DXTest-Ripple";								// The title bar text
const TCHAR szWindowClass[] = "DXTest-Class";	// The title bar text
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int COLORBPP = 16;

//ripple object
const double DXPI = 3.1415926;
const int WAVE_LENGTH = 12;
const int PRECISION = 1000;
int disp_index; //wave center displacement index;
int	disp[12];	//pixel displacement
int dist[600][800]; //distance to center
Bitmap* pBmpBack;

//ripple function
inline void Build_Disp_Matrix()
{
	for(int i = 0; i < 12; ++i)
		disp[i] = static_cast<int>(sin((double)i*30*DXPI/360)*PRECISION);
}

void Create_Ripple(int center_x, int center_y, int force, int damp, int wave_length = 12);
void Render_Ripple(LPDIRECTDRAWSURFACE7 lpdds);

//dx objects
LPDIRECTDRAW7 lpdd;
LPDIRECTDRAWSURFACE7 lpddsprimary;
LPDIRECTDRAWSURFACE7 lpddsback;

// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);

//game function
int Game_Init(LPVOID params = NULL, int num_Params = 0);
int Game_Main(LPVOID params = NULL, int num_params = 0);
int Game_Shutdown(LPVOID params = NULL, int num_params = 0);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.
	MSG msg;

	// Initialize global strings
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	//initial game
	Game_Init();

	// Main message loop:
	while (TRUE)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if(WM_QUIT == msg.message) break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}else{
			Game_Main();
		}
	}

	Game_Shutdown();

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_RIPPLE);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_RIPPLE;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      0, 0, 0, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }
   main_window_handle = hWnd;

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

int Game_Init(LPVOID params, int num_params)
{
	HRESULT hr;
	hr = DirectDrawCreateEx(NULL, (void**)&lpdd, IID_IDirectDraw7, NULL);
	if(FAILED(hr))
	{
		return FALSE;
	}
	
	hr = lpdd->SetCooperativeLevel(main_window_handle, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
	if(FAILED(hr))
	{
		return FALSE;
	}

	hr = lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, COLORBPP, 0, 0);
	if(FAILED(hr))
	{
		return FALSE;
	}

	DDSURFACEDESC2 ddsd = {sizeof(ddsd)};
	ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
	ddsd.dwBackBufferCount = 1;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
	hr = lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL);
	if(FAILED(hr))
	{
		return FALSE;
	}

	ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
	hr = lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback);
	if(FAILED(hr))
	{
		return FALSE;
	}

	//init ripple object
	disp_index = 11;
	Build_Disp_Matrix();
	Create_Ripple( 500, 410, 30, 0);
	pBmpBack = new Bitmap( lpdd, 800, 600);
	pBmpBack->LoadBitmap("back.bmp", 0, 0);
	pBmpBack->SetColorKey();
	
	return TRUE;
}



int Game_Main(LPVOID params, int num_params)
{
	int start_count = GetTickCount();
	if(KEYDOWN(VK_ESCAPE))
		SendMessage(main_window_handle, WM_DESTROY, 0, 0);

	Render_Ripple(lpddsprimary);
//	pBmpBack->Draw(lpddsprimary, 0, 0);

//	while((GetTickCount() - start_count) < 50) Sleep(0);
	return 0;
}

int Game_Shutdown(LPVOID params, int num_params)
{
	delete pBmpBack;
	SAFE_RELEASE(lpddsback);
	SAFE_RELEASE(lpddsprimary);
	SAFE_RELEASE(lpdd);
	return TRUE;
}

void Create_Ripple(int center_x, int center_y, int force, int damp, int wave_length)
{

	for(int i = 0 ; i < wave_length; ++i)
	{
		disp[i] = force * disp[i] / PRECISION;
	}

	int dist_x, dist_y;
	for(i = 0; i < SCREEN_HEIGHT; ++i)
	{
		for(int j = 0; j< SCREEN_WIDTH; ++j)
		{
			dist_y = i - center_y;
			dist_x = j - center_x;
			dist[i][j] = static_cast<int>(sqrt(dist_x*dist_x +
				dist_y*dist_y) + 0.5) % wave_length;
		}
	}
		
}

void Render_Ripple(LPDIRECTDRAWSURFACE7 lpdds)
{
	DDSURFACEDESC2 ddsd = { sizeof(ddsd) };

	if(disp_index < 0) disp_index = 12;

	--disp_index;

	lpdds->Lock(NULL,&ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL);
	short* lpSrcBuffer = static_cast<short*>(
		pBmpBack->GetBitmapBuffer());
	
	int pitch = (ddsd.lPitch) >> 1;

	short* lpBuffer = static_cast<short*>(ddsd.lpSurface);

	int left,right,bottom,top;
	int k = 0,l = 0;
	int index_x,index_y;
	int x_off,y_off;
	int pos1,pos2;
	for(int i = 1; i < SCREEN_HEIGHT - 2; ++i)
		for( int j = 1; j < SCREEN_WIDTH - 2; ++j)
		{	
			left = right = bottom = top = disp_index;

			left += dist[i][j -1];
			if(left > 12) left -= 12;
			right += dist[i][j+1];
			if(right >12) right -= 12;
			bottom+=dist[i+1][j];
			if(bottom > 12) bottom -= 12;
			top += dist[i-1][j];
			if(top >12 ) top -= 12;

			x_off = disp[left] - disp[right];
			y_off = disp[top] - disp[bottom];

			index_x = j + x_off;
			index_y = i + y_off;
			
			pos1 = i*pitch +j;
			pos2 = index_y * 800 + index_x;
			if(pos2 < 0 || pos2 > 479999) break;

			lpBuffer[pos1] = lpSrcBuffer[pos2];
		}
	
	pBmpBack->ReleaseBuffer();
	lpdds->Unlock(NULL);
}

⌨️ 快捷键说明

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