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

📄 perfectparticledlg.cpp

📁 这是一款游戏中的粒子系统
💻 CPP
字号:
// PerfectParticleDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "PerfectParticle.h"
#include "PerfectParticleDlg.h"
#include ".\perfectparticledlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

////////////////全局信息//////////////////////////
DWORD WINAPI RenderThread( LPVOID lpParam ); 
bool g_sendMessage=true;
bool g_run=true;
HWND g_hWnd=NULL;
bool g_canRender=true;



CPerfectParticleDlg::CPerfectParticleDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPerfectParticleDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CPerfectParticleDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, ID_PSNum, m_PS);
	DDX_Control(pDX, ID_LifeBase, m_LifeBase);
	DDX_Control(pDX, ID_LifeVar, m_LifeVar);
	DDX_Control(pDX, ID_SizeBase, m_SizeBase);
	DDX_Control(pDX, ID_SizeVar, m_SizeVar);
	DDX_Control(pDX, ID_PosX, m_PosX);
	DDX_Control(pDX, ID_PosY, m_PosY);
	DDX_Control(pDX, ID_PosZ, m_PosZ);
	DDX_Control(pDX, ID_ColorAB, m_ABase);
	DDX_Control(pDX, ID_ColorAV, m_AVar);
	DDX_Control(pDX, ID_ColorRB, m_RBase);
	DDX_Control(pDX, ID_ColorRV, m_RVar);
	DDX_Control(pDX, ID_ColorGB, m_GBase);
	DDX_Control(pDX, ID_ColorGV, m_GVar);
	DDX_Control(pDX, ID_ColorBB, m_BBase);
	DDX_Control(pDX, ID_ColorBV, m_BVar);
	DDX_Control(pDX, ID_DirXB, m_DirXBase);
	DDX_Control(pDX, ID_DirXV, m_DirXVar);
	DDX_Control(pDX, ID_DirYB, m_DirYBase);
	DDX_Control(pDX, ID_DirYV, m_DirYVar);
	DDX_Control(pDX, ID_DirZB, m_DirZBase);
	DDX_Control(pDX, ID_DirZV, m_DirZVar);
	DDX_Control(pDX, ID_Speed, m_Speed);
}

BEGIN_MESSAGE_MAP(CPerfectParticleDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_MESSAGE(M_RENDER,Render)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
	ON_COMMAND(ID_Center, OnCenterForce)
	ON_COMMAND(ID_Axis, OnAxisForce)
	ON_COMMAND(ID_CreatePos, OnCreatepos)
	ON_COMMAND(ID_Export, OnExportConfig)
	ON_BN_CLICKED(IDC_Create, OnBnClickedCreate)
	ON_BN_CLICKED(IDC_Delete, OnBnClickedDelete)
	ON_CBN_SELCHANGE(IDC_ComBox, OnCbnSelchangeCombox)
	ON_WM_TIMER()
END_MESSAGE_MAP()


BOOL CPerfectParticleDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	SetIcon(m_hIcon, TRUE);    //设置大图标
	SetIcon(m_hIcon, FALSE);

	SetCursor(NULL);

	m_IsChange=false;
	//初始化本窗口的参数
	path="";
	m_affect=NULL;
	CRect rect;
	m_device=new CInitEnviroment(m_hWnd,800,600,true);
	m_camera=new CCamera(CCamera::Land);
	g_canRender=true;
	g_hWnd=m_hWnd;

	GetClientRect(&rect);
	m_renderRect.left=rect.left;
	m_renderRect.top=rect.top;
	m_renderRect.bottom=rect.bottom	;
	CRect rt;
	GetDlgItem(ID_Divide)->GetWindowRect(&rt);
	ScreenToClient(&rt);
	m_renderRect.right=rt.left;

	m_comBox.Create(CBS_DROPDOWNLIST|WS_VSCROLL|WS_CHILD|WS_VISIBLE,
		CRect(rt.right+7,12,rt.right+7+150,112), this, IDC_ComBox);
	////////////////////////////////////控件初始化/////////////////////////////////////
	m_PS.SetRange(0,100);
	m_LifeBase.SetRange(0,10);
	m_LifeVar.SetRange(0,10);
	m_SizeBase.SetRange(0,10);
	m_SizeVar.SetRange(0,10);
	m_PosX.SetRange(0,100);
	m_PosY.SetRange(0,100);
	m_PosZ.SetRange(0,100);

	m_PosX.SetPos(50);
	m_PosY.SetPos(50);
	m_PosZ.SetPos(50);

	m_ABase.SetRange(0,255);
	m_AVar.SetRange(0,255);
	m_RBase.SetRange(0,255);
	m_RVar.SetRange(0,255);
	m_GBase.SetRange(0,255);
	m_GVar.SetRange(0,255);
	m_BBase.SetRange(0,255);
	m_BVar.SetRange(0,255);

	m_DirXBase.SetRange(0,20);
	m_DirYBase.SetRange(0,20);
	m_DirZBase.SetRange(0,20);

	m_DirXVar.SetRange(0,20);
	m_DirYVar.SetRange(0,20);
	m_DirZVar.SetRange(0,20);

	m_DirXBase.SetPos(10);
	m_DirYBase.SetPos(10);
	m_DirZBase.SetPos(10);

	m_DirXVar.SetPos(10);
	m_DirYVar.SetPos(10);
	m_DirZVar.SetPos(10);
	m_Speed.SetRange(0,100);
	m_centerForce=new CCreateCenterForce();
	m_axisForce=new CCreateAxisForce();
	m_boxCreator=new CCreateBoxCreator();

	m_forceParam.RemoveAll();
	m_box.RemoveAll();
	m_vecList.RemoveAll();
	///////////////////////////////////////////////////////////////////////////////////
	m_sys=new CParticleSystem(m_device->p_D3dDevice);
	m_sys->SetPosition(D3DXVECTOR3(0,-8,0));

	------------------------------------------------------------------------
		m_emitter=NULL;
	HANDLE hThread;
	DWORD threadID , dwThrdParam ;
	hThread = CreateThread( NULL,0,RenderThread ,&dwThrdParam,	0,&threadID ) ;
    
	return TRUE;  
}

DWORD WINAPI RenderThread(LPVOID lpParam){
	while(g_run){
		if(g_sendMessage&&g_canRender){
			::SendMessage(g_hWnd,M_RENDER,0,0);
		}
	}
	return 0;
}

LRESULT CPerfectParticleDlg::Render(WPARAM w,LPARAM l){

	g_sendMessage=false;
	//设置渲染区域
	static DWORD currenttime=0;
	static DWORD lasttime=0;
	currenttime = ::timeGetTime();
	float fCurrentFrameTime = ((float)( currenttime - lasttime )) * 0.001f;
	lasttime = currenttime;
    
	//设置参数
	 ControlToParameter();
	////////////////////////////////////
	m_device->p_D3dDevice->BeginScene();
	m_device->p_D3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER ,D3DCOLOR_XRGB(0,0,0) ,1.0f,0);

	m_camera->Set3DCamera(m_device->p_D3dDevice,(float)(m_renderRect.right-m_renderRect.left),(float)(m_renderRect.bottom-m_renderRect.top),1,1000,1000);
	m_sys->Update( fCurrentFrameTime );
	m_sys->Render(m_camera);

	m_device->p_D3dDevice->EndScene();
	m_device->p_D3dDevice->Present(NULL,&m_renderRect,NULL,NULL) ;
	g_sendMessage=true;
	return 0;
}

void CPerfectParticleDlg::OnPaint() 
{

	if (IsIconic())
	{
		CPaintDC dc(this);

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
    ::SendMessage(g_hWnd,M_RENDER,0,0);
}

HCURSOR CPerfectParticleDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CPerfectParticleDlg::OnDestroy()
{
	m_comBox.DestroyWindow();
	CDialog::OnDestroy();
}

///////////////////////////////////控件操作/////////////////////////////////////////
void CPerfectParticleDlg::OnBnClickedButton1()
{
	static char BASED_CODE szFilter[] = "Texture (*.tga;*.jpg;*.bmp;*.png)|*.tga;*.jpg;*.bmp;*.png|All Files (*.*)|*.*||";
	CFileDialog dlg(true,NULL,NULL ,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL);
	
	if(dlg.DoModal()==IDOK)
	{
		path=dlg.GetPathName();

		path=path.MakeReverse();
		int idx=path.Find('\\');
		path=path.Left(idx);
		path=path.MakeReverse();
        SetDlgItemText(ID_Texture,path);
	}
}


void CPerfectParticleDlg::ControlToParameter(){
	if(m_IsChange==true){
		return;
	}
	CString value;
	CParticleSystem::EmitParameter *emit=NULL;
	m_emitter=NULL;
	bool have=false;
	if(m_comBox.GetDroppedState()==false){
		CString str;
		m_comBox.GetWindowText(str);
        m_emitter=m_sys->GetEmitter(str.GetBuffer());
		for (int i=0;i<(int)(m_sys->m_ParameterVector.size());i++)
		{
			CParticleSystem::EmitParameter parame=m_sys->m_ParameterVector.at(i);
			if(strcmp(parame.name._Myptr(),str.GetBuffer())==0)
			{
				emit=&m_sys->m_ParameterVector.at(i);
				have=true;
				break;
			}
		}
	}
	if(m_emitter==NULL||have==false)
		return;

	emit->productPS=m_PS.GetPos();

	emit->life=(float)(m_LifeBase.GetPos());
	emit->lifeVar=(float)(m_LifeVar.GetPos());

	emit->size=(float)(m_SizeBase.GetPos());
	emit->sizeVar=(float)(m_SizeVar.GetPos());

	emit->relativePos.x=(float)(m_PosX.GetPos()-50);
	emit->relativePos.y=(float)(m_PosY.GetPos()-50);
	emit->relativePos.z=(float)(m_PosZ.GetPos()-50);
	
	emit->speed=(float)(m_Speed.GetPos());

	emit->speedDir.x=((float)(m_DirXBase.GetPos()-10)/10)*m_Speed.GetPos();
	emit->speedDir.y=((float)(m_DirYBase.GetPos()-10)/10)*m_Speed.GetPos();
	emit->speedDir.z=((float)(m_DirZBase.GetPos()-10)/10)*m_Speed.GetPos();

	emit->speedDirVar.x=((float)(m_DirXVar.GetPos()-10)/10)*m_Speed.GetPos();
	emit->speedDirVar.y=((float)(m_DirYVar.GetPos()-10)/10)*m_Speed.GetPos();
	emit->speedDirVar.z=((float)(m_DirZVar.GetPos()-10)/10)*m_Speed.GetPos();

	emit->color=D3DCOLOR_ARGB(m_ABase.GetPos(),m_RBase.GetPos(),m_GBase.GetPos(),m_BBase.GetPos());
	emit->colorVar=D3DCOLOR_ARGB(m_AVar.GetPos(),m_RVar.GetPos(),m_GVar.GetPos(),m_BVar.GetPos());
    
	GetDlgItemText(ID_Texture,path);
	emit->texture=path;
}

void CPerfectParticleDlg::ResetAffector(){
	//设置粒子池的外力效果
	if(m_comBox.GetDroppedState()==false){
		CString str;
		m_comBox.GetWindowText(str);
		m_emitter=m_sys->GetEmitter(str.GetBuffer());
	}

	if(m_emitter==NULL)
		return;

	m_emitter->m_AffectorVector.clear();

	//向心外力影响子
	int i=0;
	for(i=0;i<m_forceParam.GetCount();i++){
		CenterForce data=m_forceParam.GetAt(m_forceParam.FindIndex(i));
		m_affect= new CCenterForceLogic(m_emitter);
		m_affect->SetParamFloat(0,data.force);
		m_affect->SetParamFloat(1,data.nr);
		m_affect->SetParamFloat(2,data.fr);
		m_affect->SetParamFloat(3,data.cut);
		m_emitter->AddAffector(m_affect);
	}
	//轴向外力影响子
	for(i=0;i<m_vecList.GetCount();i++){
		m_affect= new CAxisForceLogic(m_emitter);
		m_affect->SetParamVector(0,m_vecList.GetAt(m_vecList.FindIndex(i)));
		m_emitter->AddAffector(m_affect);
	}
	//发射区域影响子
	for(i=0;i<m_box.GetCount();i++){
		BoxForce data=m_box.GetAt(m_box.FindIndex(i));
		m_affect= new CBoxCreator(m_emitter);
		m_affect->SetParamVector(0,data.one);
		m_affect->SetParamVector(1,data.two);
		m_emitter->AddAffector(m_affect);
	}

}
void CPerfectParticleDlg::OnCenterForce()
{
	m_centerForce->DoModal(this);
	ResetAffector();
}

void CPerfectParticleDlg::OnAxisForce()
{
	m_axisForce->DoModal(this);
	ResetAffector();
}

void CPerfectParticleDlg::OnCreatepos()
{
	m_boxCreator->DoModal(this);
	ResetAffector();
}

void CPerfectParticleDlg::OnExportConfig()
{
	static char BASED_CODE szFilter[] = "Particle (*.PS)|*.PS||All Files (*.*)|*.*||";
	CFileDialog dlg(FALSE,NULL,NULL ,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL);
	CString path;
	if(dlg.DoModal()==IDOK)
	{
		path=dlg.GetPathName();
		CString fullPath=path;
		CString last=path.Right(3);
		if(last!=".PS")
		   fullPath.Format("%s%s",fullPath,".PS");
		m_sys->ExportConfigFile(fullPath.GetBuffer());
	}
}

//把参数显示到控件
void CPerfectParticleDlg::ParameterToControl()
{
	int idx=m_comBox.GetCurSel();
	CString str;
	m_comBox.GetLBText(idx,str);
	CParticleSystem::EmitParameter *emit=NULL;
	m_emitter=NULL;
	m_emitter=m_sys->GetEmitter(str.GetBuffer());
	bool have=false;
	for (int i=0;i<(int)(m_sys->m_ParameterVector.size());i++)
	{
		CParticleSystem::EmitParameter parame=m_sys->m_ParameterVector.at(i);
		if(strcmp(parame.name._Myptr(),str.GetBuffer())==0)
		{
			emit=&m_sys->m_ParameterVector.at(i);
			have=true;
			break;
		}
	}
	if(m_emitter==NULL||have==false){
		m_IsChange=false;
		return;
	}
	////////////////上面是获取粒子池的参数////////////////////////////////////
    m_PS.SetPos((int)(emit->productPS));
    
	m_LifeBase.SetPos((int)(emit->life));
	m_LifeVar.SetPos((int)(emit->lifeVar));

	m_SizeBase.SetPos((int)(emit->size));
	m_SizeVar.SetPos((int)(emit->sizeVar));

	m_PosX.SetPos((int)(emit->relativePos.x)+50);
	m_PosY.SetPos((int)(emit->relativePos.y)+50);
	m_PosZ.SetPos((int)(emit->relativePos.z)+50);

    m_Speed.SetPos((int)(emit->speed));
    int speed=(int)(emit->speed);
	if(speed==0)
		speed=1;

	m_DirXBase.SetPos((int)((emit->speedDir.x*10)/speed+10));
	m_DirYBase.SetPos((int)((emit->speedDir.y*10)/speed+10));
	m_DirZBase.SetPos((int)((emit->speedDir.z*10)/speed+10));

	m_DirXVar.SetPos((int)((emit->speedDirVar.x*10)/speed+10));
	m_DirYVar.SetPos((int)((emit->speedDirVar.y*10)/speed+10));
	m_DirZVar.SetPos((int)((emit->speedDirVar.z*10)/speed+10));

	int color=emit->color;
	int colorVar=emit->colorVar;

	int a=(0xff000000&color)>>24;
	int r=(0x00ff0000&color)>>16;
	int g=(0x0000ff00&color)>>8;
	int b=(0x000000ff&color);
    
	m_ABase.SetPos(a);
	m_RBase.SetPos(r);
	m_GBase.SetPos(g);
	m_BBase.SetPos(b);

	a=(0xff000000&colorVar)>>24;
	r=(0x00ff0000&colorVar)>>16;
	g=(0x0000ff00&colorVar)>>8;
	b=(0x000000ff&colorVar);

	m_AVar.SetPos(a);
	m_RVar.SetPos(r);
	m_GVar.SetPos(g);
	m_BVar.SetPos(b);

	SetDlgItemText(ID_Texture,emit->texture._Myptr());
	m_IsChange=false;
	//////////////////////////////////////////////////////////////////////////

}

void CPerfectParticleDlg::OnCbnSelchangeCombox()
{
	m_IsChange=true;
	int idx=m_comBox.GetCurSel();
	CString str;
	m_comBox.GetLBText(idx,str);
	CParticleSystem::EmitParameter *emit=NULL;
	m_emitter=NULL;
	m_emitter=m_sys->GetEmitter(str.GetBuffer());
	bool have=false;
	for (int i=0;i<(int)(m_sys->m_ParameterVector.size());i++)
	{
		CParticleSystem::EmitParameter parame=m_sys->m_ParameterVector.at(i);
		if(strcmp(parame.name._Myptr(),str.GetBuffer())==0)
		{
			emit=&m_sys->m_ParameterVector.at(i);
			have=true;
			break;
		}
	}
	if(m_emitter==NULL||have==false){
		m_IsChange=false;
		return;
	}
    m_forceParam.RemoveAll();
	m_vecList.RemoveAll();
	m_box.RemoveAll();
	for ( int i = 0 ; i < (int)m_emitter->m_AffectorVector.size() ; ++i )
	{ 
		if(m_emitter->m_AffectorVector[i]->GetType()==CParticleAffector::Center)
		{
			CenterForce data;
			data.force=m_emitter->m_AffectorVector[i]->GetParamFloat(0);
			data.nr=m_emitter->m_AffectorVector[i]->GetParamFloat(1);
			data.fr=m_emitter->m_AffectorVector[i]->GetParamFloat(2);
			data.cut=m_emitter->m_AffectorVector[i]->GetParamFloat(3);
			m_forceParam.AddTail(data);
		}
		if(m_emitter->m_AffectorVector[i]->GetType()==CParticleAffector::Box)
		{
			BoxForce data;
			data.one=m_emitter->m_AffectorVector[i]->GetParamVector(0);
			data.two=m_emitter->m_AffectorVector[i]->GetParamVector(1);
			m_box.AddTail(data);
		}
		if(m_emitter->m_AffectorVector[i]->GetType()==CParticleAffector::Axis)
		{
			D3DXVECTOR3 vec=m_emitter->m_AffectorVector[i]->GetParamVector(0);
			m_vecList.AddTail(vec);
		}
	}
	ParameterToControl();
}

//创建粒子池
void CPerfectParticleDlg::OnBnClickedCreate()
{
	CPreInfo dlg;
	dlg.DoModal();
	if(dlg.m_succ){
		m_sys->PushEmitter(dlg.name,dlg.number,0,0,0,0);
		m_comBox.AddString(dlg.name);
	}
}

//删除粒子池
void CPerfectParticleDlg::OnBnClickedDelete()
{
	if(m_comBox.GetDroppedState()==false&&m_comBox.GetCurSel()>=0){
		CString str;
		m_comBox.GetWindowText(str);

	    m_sys->RemoveEmitter(str.GetBuffer());

		CParticleSystem::ParameterVector::iterator it=m_sys->m_ParameterVector.begin();
		for (int pos=0;it != m_sys->m_ParameterVector.end()&&
			pos<(int)(m_sys->m_ParameterVector.size());++it,pos++ )
		{
		    if(strcmp(m_sys->m_ParameterVector.at(pos).name._Myptr(),str.GetBuffer())==0)
			{
				m_sys->m_ParameterVector.erase(it);
			}
		}
	    m_comBox.DeleteString(m_comBox.GetCurSel());
		m_comBox.SetCurSel(-1);
	}
}

⌨️ 快捷键说明

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