我写的那个经典的火焰算法的C++类,欢迎批评!

BinaryWorld 2003-05-13 07:28:07
// Fire.h: interface for the CFire class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FIRE_H__0029C0C9_6ACF_43BA_8F6D_51B74810ABF8__INCLUDED_)
#define AFX_FIRE_H__0029C0C9_6ACF_43BA_8F6D_51B74810ABF8__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CFirePlant
{
public:
unsigned char peRed;
unsigned char peGreen;
unsigned char peBlue;
};

class CFire
{
public:
BOOL DrawToDC();
BOOL StartFire();
BOOL SetFireScreen(int,int);
void Play();
CFire(CDC* pDC=NULL);
virtual ~CFire();

private:
BOOL _Play;
BYTE *m_pBuffers;
BYTE *m_pWords;
BOOL flag;
CDC* m_pDC;
void CreateBitmap();
int FireHeight;
int FireWidth;
public:
void FreeMem();
CBitmap m_pBitmap;
CFirePlant mypal[255];
};

#endif // !defined(AFX_FIRE_H__0029C0C9_6ACF_43BA_8F6D_51B74810ABF8__INCLUDED_)

// Fire.cpp: implementation of the CFire class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CFireShow.h"
#include "Fire.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFire::CFire(CDC* pDC/*=NULL*/)
{
m_pDC = pDC ;
FireHeight = FireWidth = 0 ;
m_pWords = NULL ;
m_pBuffers = NULL ;

_Play = FALSE ;

if ( pDC == NULL )
flag = FALSE ;
else
flag = TRUE ;

if ( flag )
{
int index = 0;

for (index=65;index<200;index++)
{
mypal[index].peRed = index+60;
mypal[index].peGreen = index+30;
mypal[index].peBlue = rand()%10;
}/*
for (index = 1; index < 35; index++)
{
mypal[index].peRed = index+25;
mypal[index].peGreen = rand()%10;
mypal[index].peBlue = rand()%10;
}*/
for (index = 0; index < 40; index++)
{
mypal[index].peRed = 0;
mypal[index].peGreen = 0;
mypal[index].peBlue = 0;
}
for (index = 40; index < 45; index++)
{
mypal[index].peRed = index;
mypal[index].peGreen = index-35;
mypal[index].peBlue = rand()%5;
}
for (index = 45; index < 65; index++)
{
mypal[index].peRed = index+75;
mypal[index].peGreen = index;
mypal[index].peBlue = rand()%5;
}
for(index = 200; index < 255; index++)
{
mypal[index].peRed = index;
mypal[index].peGreen = index-rand()%25;
mypal[index].peBlue = rand()%5;
}

mypal[0].peRed = 0;
mypal[0].peGreen = 0;
mypal[0].peBlue = 0;

}
}

CFire::~CFire()
{

}

BOOL CFire::SetFireScreen(int width,int height)
{
if ( width < 10 )
width = 10;
if ( height <10 )
height = 10;

if ( !flag )
return FALSE;

FireHeight = height ;
FireWidth = width ;


m_pWords = new BYTE[height * ( width * 3)];
m_pBuffers = new BYTE[height * width];

if ( m_pWords == NULL || m_pBuffers == NULL )
{
MessageBox(NULL,"矩形堆初始化失败","警告",MB_OK);
return FALSE;
}

CreateBitmap();

return TRUE;
}

void CFire::CreateBitmap()
{
LPBITMAPINFO lpbi;

lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biWidth = FireWidth;
lpbi->bmiHeader.biHeight = FireHeight;
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount = 24;
lpbi->bmiHeader.biCompression = BI_RGB;
lpbi->bmiHeader.biSizeImage = 0;
lpbi->bmiHeader.biXPelsPerMeter = 0;
lpbi->bmiHeader.biYPelsPerMeter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImportant = 0;

HBITMAP hBitmap = CreateDIBSection( m_pDC->m_hDC , lpbi, (UINT)DIB_RGB_COLORS, (void **)&m_pWords, NULL, 0 );

delete [] (BYTE *)lpbi;

ASSERT(hBitmap != NULL);
m_pBitmap.Attach( hBitmap ) ;

}

BOOL CFire::StartFire()
{
if ( !flag )
return FALSE ;

{
for(int x = 0; x < FireWidth; x+=(rand()%3))
{
if( rand()%2 )
m_pBuffers[( ( FireHeight - 1 ) * FireWidth ) + x] = 255 ;
else
m_pBuffers[( ( FireHeight - 1 ) * FireWidth ) + x] = 0 ;
}
}

_Play = TRUE ;
return _Play ;
}

BOOL CFire::DrawToDC()
{
if ( !_Play )
return FALSE;

for( int x = ( FireWidth * FireHeight - 1 ); x >= 0; x--)
{
int temp = m_pBuffers[(FireWidth * FireHeight - 1 - x)];

m_pWords[3*x+2] = mypal[temp].peRed;
m_pWords[3*x+1] = mypal[temp].peGreen;
m_pWords[3*x] = mypal[temp].peBlue;
}

return StartFire();
}

void CFire::Play()
{
for( int y = 1; y < FireHeight; y++)
{
for( int x = 1; x < FireWidth; x++)
{
int xy = ( y * FireWidth ) + x;

int xyvalue;
xyvalue = ( m_pBuffers[xy + 1] + m_pBuffers[xy - 1]
+ m_pBuffers[xy + FireWidth] + m_pBuffers[xy - FireWidth]
+ m_pBuffers[xy + FireWidth + 1]
+ m_pBuffers[xy + FireWidth - 1]
+ m_pBuffers[xy - FireWidth + 1]
+ m_pBuffers[xy - FireWidth - 1] ) / 8;

if ( xyvalue != 0 )
{
xyvalue--;
m_pBuffers[xy - FireWidth] = xyvalue;
}

}
}
}

void CFire::FreeMem()
{
if ( flag )
{

if ( m_pBuffers != NULL)
delete m_pBuffers;

m_pDC = NULL;
flag = _Play = FALSE;
}
}

dlg类代码
// CFireShowDlg.cpp : implementation file
//

#include "stdafx.h"
#include "CFireShow.h"
#include "CFireShowDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCFireShowDlg dialog

CCFireShowDlg::CCFireShowDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCFireShowDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCFireShowDlg)
//}}AFX_DATA_INIT
m_pFire = NULL;
}

void CCFireShowDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCFireShowDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCFireShowDlg, CDialog)
//{{AFX_MSG_MAP(CCFireShowDlg)
ON_WM_PAINT()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCFireShowDlg message handlers

BOOL CCFireShowDlg::OnInitDialog()
{
CDialog::OnInitDialog();

GetClientRect(rect);

MemDC = new CDC;
MemDC->CreateCompatibleDC(NULL);

m_pFire = new CFire(MemDC);
if ( m_pFire->SetFireScreen(320,103) )
{
if ( m_pFire->StartFire() )
SetTimer(1,10,NULL);
}

return TRUE;
}

void CCFireShowDlg::OnPaint()
{

CPaintDC dc(this); // device context for painting

if ( m_pFire->DrawToDC() )
{
MemDC->SelectObject(&(m_pFire->m_pBitmap));
MemDC->SetBkMode(0);
CRect rect(0,85,320,100);
MemDC->SetTextColor(RGB(0,0,0));
MemDC->DrawText("Gemini",rect,DT_RIGHT);
dc.BitBlt( 0, 0, 320,103, MemDC, 0, 0, SRCCOPY );
m_pFire->Play();
}

CDialog::OnPaint();
}


void CCFireShowDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
InvalidateRect(rect,FALSE);
CDialog::OnTimer(nIDEvent);
}

BOOL CCFireShowDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
KillTimer(1);
m_pFire->FreeMem();
delete(MemDC);
delete(m_pFire);

return CDialog::DestroyWindow();
}

感觉我写的CFire类的FreeFire函数总感觉有点不舒服,但写成别的形式都抱撮,哥哥姐姐叔叔阿姨,帮忙看看,对了,这个的效率很高采用24位真彩色显示,可以在 塞样800HZ 128SDR WINXP上支持到1毫秒一次刷新的速度,速度应该可以了吧?
...全文
99 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
BinaryWorld 2003-06-12
  • 打赏
  • 举报
回复
UP
sujinzhao 2003-05-22
  • 打赏
  • 举报
回复
请问可以在哪儿下载这个火焰的程序??
HuWenjin 2003-05-19
  • 打赏
  • 举报
回复
mark
willa 2003-05-19
  • 打赏
  • 举报
回复
没有注释, 有些地方一时未能理解
unrise 2003-05-19
  • 打赏
  • 举报
回复
mark
alphasun 2003-05-19
  • 打赏
  • 举报
回复
内存分配得不够,导致数组溢出,内存数据结构破坏。
jvsun 2003-05-19
  • 打赏
  • 举报
回复
建议再看看bmp文件格式 , 凑成4的倍数都没有做 。 把你那个320改成333或者任何一个不是4的倍数 , 火焰斜了,而且边上有条纹 , 这也是导致你 "但如果再执行delete [] m_pWords 就会出错,我不知道这究竟应该怎么解释。"
alphapaopao 2003-05-19
  • 打赏
  • 举报
回复
建议你采用 BoundsChecker 检查一下,我怀疑你的代码在运行的时候有内存覆盖,导致内存分配信息被覆盖,所以在释放内存的时候出现崩溃。
maohbao 2003-05-19
  • 打赏
  • 举报
回复
CFireShowDlg.h的代码内容呢?
BinaryWorld 2003-05-19
  • 打赏
  • 举报
回复
TO jvsun(雷曼) ;我想我这里并不需要,我看过了位图的一些东东。
我这里的是一个象素占据3个BYTE,应该不需要对齐吧?,直接填充颜色,条纹是
for (index = 40; index < 45; index++)
{
mypal[index].peRed = index;
mypal[index].peGreen = index-35;
mypal[index].peBlue = rand()%5;
}
这个里面的颜色,会形成一个颜色过渡,看起来像是一个条纹。

TO alphasun(巨老的炮炮)

你的说法,我也感觉到了,但能说的具体点吗?
simahao 2003-05-18
  • 打赏
  • 举报
回复
up
BinaryWorld 2003-05-18
  • 打赏
  • 举报
回复
在我的这个SetFireScreen(int width,int height)函数里,里面有对两个指针动态开辟内存的指令:
m_pWords = new BYTE[height * ( width * 3)];
m_pBuffers = new BYTE[height * width];
因为我从事的是24位位图的着色,所以,前一个的长度是后一个的3倍。
但在我的释放资源的函数里:
void CFire::FreeMem()
{
if ( flag )
{
if ( m_pBuffers != NULL)
delete m_pBuffers;

m_pDC = NULL;
flag = _Play = FALSE;
}
}
我试了很多种方法:delete [] m_pBuffers是可以删除的,但如果再执行delete [] m_pWords
就会出错,我不知道这究竟应该怎么解释。
对于new delete,delete [],我一直都有点头晕,能给个详细点的解释吗?我没有MSDN的,所以,想寻求哥哥姐姐叔叔阿姨弟弟妹妹帮帮忙谢谢
BinaryWorld 2003-05-18
  • 打赏
  • 举报
回复
UP.GEGEJIEJIEBANGMANGLA
BinaryWorld 2003-05-17
  • 打赏
  • 举报
回复
UP
DangerousWang 2003-05-17
  • 打赏
  • 举报
回复
up
BinaryWorld 2003-05-17
  • 打赏
  • 举报
回复
UP
BinaryWorld 2003-05-17
  • 打赏
  • 举报
回复
在我的这个SetFireScreen(int width,int height)函数里,里面有对两个指针动态开辟内存的指令:
m_pWords = new BYTE[height * ( width * 3)];
m_pBuffers = new BYTE[height * width];
因为我从事的是24位位图的着色,所以,前一个的长度是后一个的3倍。
但在我的释放资源的函数里:
void CFire::FreeMem()
{
if ( flag )
{
if ( m_pBuffers != NULL)
delete m_pBuffers;

m_pDC = NULL;
flag = _Play = FALSE;
}
}
我试了很多种方法:delete [] m_pBuffers是可以删除的,但如果再执行delete [] m_pWords
就会出错,我不知道这究竟应该怎么解释。
对于new delete,delete [],我一直都有点头晕,能给个详细点的解释吗?我没有MSDN的,所以,想寻求哥哥姐姐叔叔阿姨弟弟妹妹帮帮忙谢谢
BinaryWorld 2003-05-17
  • 打赏
  • 举报
回复
To: cielsoft(非典型性程序)

把你的那个MP3修改注册信息的发出了看看吧,对位操作,在下还是有点控制不住的感觉。学习学习
lizmei001 2003-05-16
  • 打赏
  • 举报
回复
if (p == 0)
{
printf("%s","Error: 不能在堆上开辟100的连续内存区域");
}
weasea 2003-05-16
  • 打赏
  • 举报
回复
up
加载更多回复(15)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧