#pragma once //#include #include #include struct XMiniMap { struct DrawInfo { int x, y; ///< 인덱스 size_t from_x, from_y; ///< 어디서 size_t from_width, from_height; ///< 얼만큼을 size_t to_x, to_y; ///< 어디다 size_t to_width, to_height; ///< 얼마나 그려야 하는지의 정보. }; XMiniMap() { } void Init( int tile_width, ///< 타일 한장당 가로길이 int tile_height, ///< 타일 한장당 세로길이 size_t image_width, ///< 타일 이미지의 가로크기 size_t image_height ///< 타일 이미지의 세로크기 ) { m_TileWidth = tile_width; m_TileHeight = tile_height; m_ImageWidth = image_width; m_ImageHeight = image_height; } void GetDrawInfo( int left, int top, int width, int height, size_t target_width, size_t target_height, std::vector< DrawInfo > & vInfo ) { if( width < 1 || height < 1 ) return; int map_width = width - left; int map_height = height - top; DrawInfo info; memset( &info, 0, sizeof(info) ); float mx = 0; float my = 0; int sx = 0; int sy = 0; for( int y = top; y < top + height + m_TileHeight; y+=m_TileHeight ) { mx = 0; for( int x = left; x < left + width + m_TileWidth; x+=m_TileWidth ) { int ix = ( x / m_TileWidth ); int iy = ( y / m_TileHeight ); if( x < 0 ) ix--; if( y < 0 ) iy--; int tix = ix; int tiy = iy; if( x < 0 ) { if( !(( 0 - x ) % m_TileWidth) ) tix--; } if( y < 0 ) { if( !(( 0 - y ) % m_TileHeight) ) tiy--; } // 그려야되는 좌표 int fx = x; int fy = y; if( fx > left ) fx = ( tix ) * m_TileWidth; if( fy > top ) fy = ( tiy ) * m_TileHeight; int tx = ( tix + 1 ) * m_TileWidth; int ty = ( tiy + 1 ) * m_TileHeight; if( tx > left + width ) tx = left + width; if( ty > top + height ) ty = top + height; /* if( fy > ty ) continue; if( fx > tx ) continue; */ // 그려야되는 크기 sx = tx - fx; sy = ty - fy; if( sx < 0 || sy < 0 ) continue; float fWidthRatio = (m_ImageWidth )/(float)m_TileWidth; float fHeightRatio = (m_ImageHeight )/(float)m_TileHeight; // 시작좌표는 x, y 크기는 sx, sy info.x = ix; info.y = iy; info.from_x = ( fx - ix * m_TileWidth ) * fWidthRatio; info.from_y = ( fy - iy * m_TileHeight ) * fHeightRatio; info.from_width = sx * fWidthRatio; info.from_height = sy * fHeightRatio; if( m_ImageWidth == info.from_x + info.from_width + 1 ) info.from_width++; if( m_ImageHeight == info.from_y + info.from_height + 1 ) info.from_height++; int prev_to_y = info.to_y; int prev_to_height = info.to_height; info.to_x = mx; info.to_y = my; mx += ((float)sx * target_width / width); info.to_width = (int)(mx+0.5f) - info.to_x; info.to_height = ((float)sy * target_height / height + ( my - (float)info.to_y ) ); if( info.to_x + info.to_width > target_width ) continue; if( info.to_y + info.to_height > target_height ) continue; vInfo.push_back( info ); } my = info.to_y + info.to_height; //my += ((float)sy * target_height / height); } } protected: size_t m_ImageWidth, m_ImageHeight; int m_TileWidth, m_TileHeight; }; struct XSmoothMiniMap { void Init( size_t tile_width, size_t tile_height, size_t tile_image_width, size_t tile_image_height, size_t minimap_width, size_t minimap_height, size_t minimap_texture_width, size_t minimap_texture_height ) { m_nChangeTime = 0; m_nMiniMapImageWidth = minimap_texture_width; m_nMiniMapImageHeight = minimap_texture_height; m_nCurrentMiniMapWidth = m_nTargetMiniMapWidth = m_nMiniMapWidth = minimap_width; m_nCurrentMiniMapHeight = m_nTargetMiniMapHeight = m_nMiniMapHeight = minimap_height; m_MiniMap.Init( tile_width, tile_height, tile_image_width, tile_image_height ); } void ChangeMiniMapSize( size_t minimap_width, size_t minimap_height ) { m_nMiniMapWidth = m_nCurrentMiniMapWidth; m_nMiniMapHeight = m_nCurrentMiniMapHeight; m_nTargetMiniMapWidth = minimap_width; m_nTargetMiniMapHeight = minimap_height; m_nCurrentMiniMapWidth = m_nMiniMapWidth; m_nCurrentMiniMapHeight = m_nMiniMapHeight; m_nChangeTime = GetSafeTickCount(); } void GetDrawInfo( int x, int y, std::vector< XMiniMap::DrawInfo > & vInfo ) { int m_nCurrentTime = GetSafeTickCount(); if( m_nChangeTime ) { if( m_nChangeTime + 500 > m_nCurrentTime ) { float fRatio = 1.0f - ( ( m_nChangeTime + 500 ) - m_nCurrentTime ) / 500.0f; if( fRatio < 0.0f || fRatio >= 1.0f ) { m_nCurrentMiniMapWidth = m_nMiniMapWidth = m_nTargetMiniMapWidth; m_nCurrentMiniMapHeight = m_nMiniMapHeight = m_nTargetMiniMapHeight; m_nChangeTime = 0; } else { int nWidthDiff = ( (int)m_nTargetMiniMapWidth - (int)m_nMiniMapWidth ) * fRatio; int nHeightDiff = ( (int)m_nTargetMiniMapHeight - (int)m_nMiniMapHeight ) * fRatio; m_nCurrentMiniMapWidth = m_nMiniMapWidth + nWidthDiff; m_nCurrentMiniMapHeight = m_nMiniMapWidth + nHeightDiff; } } else { m_nCurrentMiniMapWidth = m_nMiniMapWidth = m_nTargetMiniMapWidth; m_nCurrentMiniMapHeight = m_nMiniMapHeight = m_nTargetMiniMapHeight; m_nChangeTime = 0; } } m_MiniMap.GetDrawInfo( x - m_nCurrentMiniMapWidth/2 , y - m_nCurrentMiniMapHeight/2, m_nCurrentMiniMapWidth, m_nCurrentMiniMapHeight, m_nMiniMapImageWidth, m_nMiniMapImageHeight, vInfo ); } bool IsZooming() const { return m_nChangeTime != 0; } bool TranslateCoordinate( const int center_x, const int center_y, const int x, const int y, int *tx, int *ty ) { int left = center_x - m_nCurrentMiniMapWidth/2; int top = center_y - m_nCurrentMiniMapHeight/2; int right = left + m_nCurrentMiniMapWidth; int bottom = top + m_nCurrentMiniMapHeight; if( x < left || x > right || y < top || y > bottom ) return false; *tx = ( ( x - left ) * m_nMiniMapImageWidth ) / m_nCurrentMiniMapWidth; *ty = ( ( y - top ) * m_nMiniMapImageWidth ) / m_nCurrentMiniMapHeight; return true; } const size_t GetMapImageWidth() { return m_nMiniMapImageWidth; } const size_t GetMapImageHeight() { return m_nMiniMapImageHeight; } protected: size_t m_nMiniMapImageWidth; size_t m_nMiniMapImageHeight; size_t m_nTargetMiniMapWidth; size_t m_nTargetMiniMapHeight; size_t m_nMiniMapWidth; size_t m_nMiniMapHeight; int m_nCurrentMiniMapWidth; int m_nCurrentMiniMapHeight; int m_nChangeTime; XMiniMap m_MiniMap; };