www.pudn.com > GameEngine_src.rar > CPictureGroup.cpp
#include "CPictureGroup.h" #include "BaseUtil.h" #include "normal.h" #include "CMap.h" #includeextern PEASYDRAW g_pEasyDraw; extern CMap theMap; struct EPGFILEHEADER { DWORD epgType; //文件类型EPG DWORD epgNumPicture; //文件中所含图片总数 DWORD epgNumShadow; //阴影图片数(为0则没有阴影) DWORD epgNumDirection; //方向数 DWORD epgNumHoldCell; //占据的CELL总数 DWORD epgNumBaseCell; //基CELL数,1或4 DWORD epgDelayTime; //动画间隔时间 DWORD epgOffsetHoldCell; //从文件头到占位CELL数据的偏移 }; const DWORD EPG = 'EPG'; //*********************************************CPictureGroup类定义**************************************************** //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// CPictureGroup::CPictureGroup() { m_DelayTime = 0; m_Direction = 1; } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// CPictureGroup::~CPictureGroup() { Free(); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::FreeSurface() { for ( int i = 0; i < m_SurfaceArray.GetLength(); ++i ) g_pEasyDraw->DeleteSurface( m_SurfaceArray[i] ); m_SurfaceArray.Free(); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// bool CPictureGroup::Init() { m_DelayTime = 0; m_Direction = 1; bool b = m_SurfaceArray.Init( 64 ); b &= m_BaseOffsetArray.Init( 64 ); return b; } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::Free() { FreeSurface(); m_BaseOffsetArray.Free(); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::Clear() { FreeSurface(); m_SurfaceArray.Clear(); m_BaseOffsetArray.Clear(); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::GetRenderPoint( int frame, const POINT &base, POINT &render ) { render.x = base.x - m_BaseOffsetArray[frame].x; render.y = base.y - m_BaseOffsetArray[frame].y; } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::UpdateFrame( int &frame, unsigned int &LastTick ) { unsigned int this_tick = timeGetTime(); if ( this_tick - LastTick >= m_DelayTime ) { LastTick = this_tick; frame++; frame = frame % m_SurfaceArray.GetLength(); } } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::GetRect( int frame, const POINT &base, RECT &rc ) { rc.left = base.x - m_BaseOffsetArray[frame].x; rc.top = base.y - m_BaseOffsetArray[frame].y; rc.right = rc.left + m_SurfaceArray[frame]->GetWidth(); rc.bottom = rc.top + m_SurfaceArray[frame]->GetHeight(); } //////////////////////////////////////////////////////////////////////// //更新活动精灵, 包括更新精灵的当前帧, 计时器, 包围矩形框 //////////////////////////////////////////////////////////////////////// int CPictureGroup::UpdateAliveSprite( bool bNextFrame, int &frame, int direction, const POINT &base, POINT &render, RECT &rc ) { //确定方向,注意精灵逻辑方向都是八方向的,而实际动画有四或八方向 if ( m_Direction == 4 ) direction = ( direction - 1 ) / 2; else direction -= 1; if ( bNextFrame ) { frame++; frame = frame % m_FramePerDirection; } int pg_frame = direction * m_FramePerDirection + frame; rc.left = base.x - m_BaseOffsetArray[pg_frame].x; rc.top = base.y - m_BaseOffsetArray[pg_frame].y; rc.right = rc.left + m_SurfaceArray[pg_frame]->GetWidth(); rc.bottom = rc.top + m_SurfaceArray[pg_frame]->GetHeight(); render.x = rc.left; render.y = rc.top; theMap.MapToClient( render ); return pg_frame; } //////////////////////////////////////////////////////////////////////// //更新静态精灵, 包括更新精灵的当前帧, 计时器, 包围矩形框 //与活动精灵不同的是,这里不用转换方向和帧,即逻辑帧==实际帧 //////////////////////////////////////////////////////////////////////// void CPictureGroup::UpdateStaticSprite( int &frame, unsigned int &LastTick, const POINT &base, POINT &render, RECT &rc ) { unsigned int this_tick = timeGetTime(); if ( this_tick - LastTick >= m_DelayTime ) { LastTick = this_tick; frame++; frame = frame % m_SurfaceArray.GetLength(); } rc.left = base.x - m_BaseOffsetArray[frame].x; rc.top = base.y - m_BaseOffsetArray[frame].y; rc.right = rc.left + m_SurfaceArray[frame]->GetWidth(); rc.bottom = rc.top + m_SurfaceArray[frame]->GetHeight(); render.x = rc.left; render.y = rc.top; theMap.MapToClient( render ); } //////////////////////////////////////////////////////////////////////// //更新天空或地面魔法精灵 //////////////////////////////////////////////////////////////////////// int CPictureGroup::UpdateMagicSprite( bool bNextFrame, int &frame, const POINT &base, POINT &render, RECT &rc ) { if ( bNextFrame ) { frame++; frame = frame % m_SurfaceArray.GetLength(); } rc.left = base.x - m_BaseOffsetArray[frame].x; rc.top = base.y - m_BaseOffsetArray[frame].y; rc.right = rc.left + m_SurfaceArray[frame]->GetWidth(); rc.bottom = rc.top + m_SurfaceArray[frame]->GetHeight(); render.x = rc.left; render.y = rc.top; theMap.MapToClient( render ); return frame; } //////////////////////////////////////////////////////////////////////// //frame是动画的实际帧,不是逻辑的帧 // x_client, y_client 是窗口工作区的坐标 //////////////////////////////////////////////////////////////////////// void CPictureGroup::DrawFrame( int frame, int x_client, int y_client ) { m_SurfaceArray[frame]->DrawAutoClip( x_client, y_client ); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::DrawShadow( int frame, const POINT &base ) { POINT render; render.x = base.x - m_BaseOffsetArray[frame].x; render.y = base.y - m_BaseOffsetArray[frame].y; theMap.MapToClient( render ); m_SurfaceArray[frame]->DrawAlphaShadow( render.x, render.y ); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::DrawFrame( int frame, const POINT &base ) { POINT render; render.x = base.x - m_BaseOffsetArray[frame].x; render.y = base.y - m_BaseOffsetArray[frame].y; theMap.MapToClient( render ); m_SurfaceArray[frame]->DrawAutoClip( render.x, render.y ); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// void CPictureGroup::DrawContour( int frame, int x, int y ) { m_SurfaceArray[frame]->DrawContour( x, y ); } //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// bool CPictureGroup::LoadEPG( char *filename, bool isFromFile, CPictureGroup *pSPG, CELL **ppCell, int *NumHoldCell ) { Free(); if ( isFromFile ) { //open file FILE *fp = fopen( filename, "rb" ); if ( fp == 0 ) return false; //read file header; EPGFILEHEADER efh; fread( &efh, sizeof(efh), 1, fp ); if ( efh.epgType != EPG ) { fclose(fp); return false; } m_DelayTime = efh.epgDelayTime; m_Direction = efh.epgNumDirection; //load surface int offset; for ( int i = 0; i < efh.epgNumPicture; ++i ) { fseek( fp, sizeof(efh) + i * 4, SEEK_SET ); fread( &offset, 4, 1, fp ); POINT base; PSURFACE surf = g_pEasyDraw->CreateSurfaceFromEPG( fp, offset, &base ); m_SurfaceArray.Add( surf ); m_BaseOffsetArray.Add( base ); } //num fo frame per directon m_FramePerDirection = m_SurfaceArray.GetLength() / m_Direction; //load shadow if ( pSPG != 0 ) { pSPG->Free(); pSPG->m_DelayTime = efh.epgDelayTime; pSPG->m_Direction = efh.epgNumDirection; for ( int j = 0; j < efh.epgNumShadow; ++j ) { fseek( fp, sizeof(efh) + (i + j) * 4, SEEK_SET ); fread( &offset, 4, 1, fp ); POINT base; PSURFACE surf = g_pEasyDraw->NewSurface(); debug_assert( surf != NULL ); debug_assert( efh.epgNumPicture == efh.epgNumShadow ); surf->CreateEcpSurfaceHelp( fp, offset, &base, true ); pSPG->m_SurfaceArray.Add( surf ); pSPG->m_BaseOffsetArray.Add( base ); } pSPG->m_FramePerDirection = pSPG->m_SurfaceArray.GetLength() / pSPG->m_Direction; } if ( ppCell != 0 && efh.epgNumHoldCell > 0 ) { *ppCell = new CELL[ efh.epgNumHoldCell ]; fseek( fp, efh.epgOffsetHoldCell, SEEK_SET ); fread( *ppCell, efh.epgNumHoldCell * sizeof(CELL), 1, fp ); } if ( NumHoldCell != 0 ) *NumHoldCell = efh.epgNumHoldCell; fclose(fp); } else //load it from memory { BYTE *buf = (BYTE *)filename; BYTE *old_buf = buf; EPGFILEHEADER efh; efh = READ_MEMORY( buf, EPGFILEHEADER ); buf += sizeof(EPGFILEHEADER); m_DelayTime = efh.epgDelayTime; m_Direction = efh.epgNumDirection; if ( efh.epgType != EPG ) return false; //load surface int offset; for ( int i = 0; i < efh.epgNumPicture; ++i ) { buf = old_buf + sizeof(EPGFILEHEADER) + i * 4; offset = READ_MEMORY( buf, int ); buf = old_buf + offset; POINT base; PSURFACE surf = g_pEasyDraw->NewSurface(); surf->CreateEcpSurfaceFromMemory( buf, false, &base ); m_SurfaceArray.Add( surf ); m_BaseOffsetArray.Add( base ); } m_FramePerDirection = m_SurfaceArray.GetLength() / m_Direction; //load shadow if ( pSPG != 0 ) { pSPG->FreeSurface(); pSPG->m_DelayTime = efh.epgDelayTime; pSPG->m_Direction = efh.epgNumDirection; for ( int j = 0; j < efh.epgNumShadow; ++j ) { buf = old_buf + sizeof(EPGFILEHEADER) + (i+j) * 4; offset = READ_MEMORY( buf, int ); buf = old_buf + offset; POINT base; PSURFACE surf = g_pEasyDraw->NewSurface(); #ifdef ALPHA_SHADOW surf->CreateEcpSurfaceFromMemory( buf, false, &base ); #else surf->LoadEcpShadowFromMemory( buf, &base ); #endif pSPG->m_SurfaceArray.Add( surf ); pSPG->m_BaseOffsetArray.Add( base ); } pSPG->m_FramePerDirection = pSPG->m_SurfaceArray.GetLength() / pSPG->m_Direction; } //load cell if ( ppCell != 0 && efh.epgNumHoldCell != 0 ) { *ppCell = new CELL[ efh.epgNumHoldCell ]; buf = (BYTE *)filename + efh.epgOffsetHoldCell; memcpy( *ppCell, buf, efh.epgNumHoldCell * sizeof(CELL) ); } if ( NumHoldCell != 0 ) *NumHoldCell = efh.epgNumHoldCell; } return true; } //////////////////////////////////////////////////////////////////////// //此处已改成求最高的高度 //////////////////////////////////////////////////////////////////////// int CPictureGroup::GetMaxHeight() { int result = 0; for ( int i = 0; i < m_BaseOffsetArray.GetLength(); ++i ) result = ( result > m_BaseOffsetArray[i].y ? result : m_BaseOffsetArray[i].y ); return result; }