• 水波纹特效的C++模拟


    简单的水波纹特效
    Wave-GitHub
    水波纹

    #include "WaterWaveEngine.h"
    
    int APIENTRY WinMain(HINSTANCE hInstance,
    					 HINSTANCE hPrevInstance,
    					 LPSTR     lpCmdLine,
    					 int       nCmdShow)
    {
    	IMAGE Buffer_In;
    	loadimage(&Buffer_In, L"IMAGE", L"BackgroundImage");
    
    	initgraph(Buffer_In.getwidth(), Buffer_In.getheight());
    
    	WaterWaveEngine Wave(&Buffer_In, nullptr);//将In作为输入,程序窗口作为输出
    
    	BeginBatchDraw();
    	for(;;)
    	{
    		//处理鼠标操作,投石头
    		while (MouseHit())
    		{
    			MOUSEMSG Msg = GetMouseMsg();
    			//滑动水波与点击水波分开
    			if(Msg.uMsg==WM_LBUTTONDOWN)
    				Wave.PushStone(Msg.x, Msg.y, 20, 700);
    			else if(Msg.mkLButton)
    				Wave.PushStone(Msg.x, Msg.y, 20, 50);
    		}
    
    		Wave.Updata();//更新数据
    
    		FlushBatchDraw();
    		Sleep(2);
    	}
    	EndBatchDraw();
    	closegraph();
    }
    

    WaterWaveEngine.h

    #pragma once
    #ifndef WATERWAVEENGINE_H
    #define WATERWAVEENGINE_H
    
    #include <easyx.h>
    class WaterWaveEngine
    {
    protected:
    	IMAGE*IMG_IN;
    	IMAGE*IMG_OUT;
    	DWORD *Buffer_In;
    	DWORD *Buffer_Out;
    	short *WaveBuff1;
    	short *WaveBuff2;
    	int Width;
    	int Height;
    
    	// 计算下一次波幅
    	void NextFrame()
    	{
    		for (int i = Width; i < Height*(Width - 1); ++i)
    		{
    			WaveBuff2[i] = ((WaveBuff1[i - Width] + WaveBuff1[i + Width] + WaveBuff1[i - 1] + WaveBuff1[i + 1]) >> 1) - WaveBuff2[i];
    			WaveBuff2[i] -= WaveBuff2[i] >> 5;// 波能衰减
    		}
    		short *ptmp = WaveBuff1;
    		WaveBuff1 = WaveBuff2;
    		WaveBuff2 = ptmp;
    	}
    	// 渲染
    	void Render(DWORD*Texture, DWORD*Target, short*AmplitudeList)
    	{
    		int Ptr = 0;
    		short Amplitude;
    		int TexX;
    		int TexY;
    		int TarX;
    		int TarY;
    		for (TarY = 0; TarY < Height; TarY++)
    			for (TarX = 0; TarX < Width; TarX++)
    			{
    				// 获得波幅
    				Amplitude = 1024 - AmplitudeList[Ptr];
    				// 计算偏移
    				TexX = (((TarX - (Width >> 1)) * Amplitude) >> 10) + (Width >> 1);
    				TexY = (((TarY - (Height >> 1)) * Amplitude) >> 10) + (Height >> 1);
    				// 边界处理
    				if (TexX >= Width)		TexX = Width - 1;
    				if (TexX < 0)			TexX = 0;
    				if (TexY >= Height)		TexY = Height - 1;
    				if (TexY < 0)			TexY = 0;
    				// 偏移 
    				Target[TarX + TarY * Width] = Texture[TexX + (TexY * Width)];
    				Ptr++;
    			}
    	}
    
    public:
    	// 更新数据
    	IMAGE&Updata()
    	{
    		NextFrame();				//计算波幅
    		Render(Buffer_In, Buffer_Out, WaveBuff1);	//渲染图片
    		return *IMG_OUT;
    	}
    	// 获得FPS
    	static double GetFPS()
    	{
    		const int FPS_COUNT = 8;
    		static int i = 0;
    		static DWORD LastTime = GetTickCount();
    		static double fps;
    
    		if (i > FPS_COUNT)
    		{
    			i = 0;
    			int CurrentTime = GetTickCount();
    			int PastTime = CurrentTime - LastTime;
    			fps = FPS_COUNT / (PastTime / 1000.0f);
    			LastTime = CurrentTime;
    		}
    		i++;
    		return fps;
    	}
    	// 投石头
    	void PushStone(int x, int y, int size, int weight)
    	{
    		// 突破边界不处理
    		if ((x >= (int)Width - size) ||
    			(x < size) ||
    			(y >= (int)Height - size) ||
    			(y < size))
    			return;
    		for (int posx = x - size; posx < x + size; posx++)
    			for (int posy = y - size; posy < y + size; posy++)
    				if ((posx - x)*(posx - x) + (posy - y)*(posy - y) < size*size)
    					WaveBuff1[Width*posy + posx] += weight;
    	}
    	
    	WaterWaveEngine() = delete;		// 删除默认构造函数
    	// 使用引用或指针构造
    	WaterWaveEngine(IMAGE&img_in, IMAGE&img_out) :
    		IMG_IN(&img_in),
    		IMG_OUT(&img_out)
    	{
    		Width = IMG_IN->getwidth();
    		Height = IMG_IN->getheight();
    		WaveBuff1 = new short[Width*Height]();
    		WaveBuff2 = new short[Width*Height]();
    		Resize(IMG_OUT, Width, Height);
    		Buffer_In = GetImageBuffer(IMG_IN);
    		Buffer_Out = GetImageBuffer(IMG_OUT);
    
    	}
    	WaterWaveEngine(IMAGE*pimg_in, IMAGE*pimg_out) :
    		IMG_IN(pimg_in),
    		IMG_OUT(pimg_out)
    	{
    		Width = IMG_IN->getwidth();
    		Height = IMG_IN->getheight();
    		WaveBuff1 = new short[Width*Height]();
    		WaveBuff2 = new short[Width*Height]();
    		Resize(IMG_OUT, Width, Height);
    		Buffer_In = GetImageBuffer(IMG_IN);
    		Buffer_Out = GetImageBuffer(IMG_OUT);
    	}
    
    	//重新绑定图片
    	void Bind(IMAGE&img_in, IMAGE&img_out)
    	{
    		IMG_IN = &img_in;
    		IMG_OUT = &img_out;
    		Width = IMG_IN->getwidth();
    		Height = IMG_IN->getheight();
    		delete[]WaveBuff1;
    		delete[]WaveBuff2;
    		WaveBuff1 = new short[Width*Height]();
    		WaveBuff2 = new short[Width*Height]();
    		Resize(IMG_OUT, Width, Height);
    		Buffer_In = GetImageBuffer(IMG_IN);
    		Buffer_Out = GetImageBuffer(IMG_OUT);
    	}
    	void Bind(IMAGE*pimg_in, IMAGE*pimg_out)
    	{
    		IMG_IN = pimg_in;
    		IMG_OUT = pimg_out;
    		Width = IMG_IN->getwidth();
    		Height = IMG_IN->getheight();
    		delete[]WaveBuff1;
    		delete[]WaveBuff2;
    		WaveBuff1 = new short[Width*Height]();
    		WaveBuff2 = new short[Width*Height]();
    		Resize(IMG_OUT, Width, Height);
    		Buffer_In = GetImageBuffer(IMG_IN);
    		Buffer_Out = GetImageBuffer(IMG_OUT);
    	}
    	virtual ~WaterWaveEngine()
    	{
    		delete[]WaveBuff1;
    		delete[]WaveBuff2;
    	}
    };
    #endif // !WATERWAVEENGINE_H
    
  • 相关阅读:
    ABP 框架第一篇 ABP框架入门
    SpringBoot+mybatis plus 框架搭建
    诺依框架 第一章 springboot+vue前后端分离版本部署
    常用Web Service汇总网页
    Singleton单例模式
    告别无止境的增删改查Java代码生成器
    Builder生成器模式
    细说Java IO相关
    AbstractFactory抽象工厂模式
    设计模式关于模式的一些很基本的知识点
  • 原文地址:https://www.cnblogs.com/that-boy/p/12310365.html
Copyright © 2020-2023  润新知