📄 sprite.cpp
字号:
/* * * sprite.cpp * * Copyright (C) 2006 Michael H. Overlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact at poster_printer@yahoo.com */#include "sprite.h"#include "gdiutils.h"#include "mathutils.h"// ***************************************************************************************************// ** NextStateRegionSprite ************************************************************************// ***************************************************************************************************void NextStateRegionSprite::Update(IN OUT HDC hdc, OUT HRGN hrgnUpdate) { NextStateRegionSprite::UpdateRegions ur; this->CalculateRegions(ur); int nSaveDC = ::SaveDC(hdc); ::ExtSelectClipRgn(hdc, ur.hrgnErase, RGN_AND); this->Erase(hdc); ::RestoreDC(hdc, nSaveDC); this->Next(); this->Save(hdc, ur.hrgnSave); nSaveDC = ::SaveDC(hdc); ::ExtSelectClipRgn(hdc, ur.hrgnDraw, RGN_AND); this->Draw(hdc); ::RestoreDC(hdc, nSaveDC); if (hrgnUpdate != NULL) { ::CombineRgn(hrgnUpdate, ur.hrgnDraw, ur.hrgnErase, RGN_OR); }}// ***************************************************************************************************// ** CompositeNextStateRegionSprite ***************************************************************// ***************************************************************************************************// ****// **** public: class CompositeNextStateRegionSprite// ****CompositeNextStateRegionSprite::CompositeNextStateRegionSprite( const std::vector<PNextStateRegionSprite>& vSprite) : m_vSprite(vSprite), m_hrgnClip(NULL) {}CompositeNextStateRegionSprite::~CompositeNextStateRegionSprite() { for(uint ui = 0; ui < m_vSprite.size(); ++ui) { delete m_vSprite[ui]; } if (m_hrgnClip != NULL) { ::DeleteObject(m_hrgnClip); }}void CompositeNextStateRegionSprite::Erase(OUT HDC hdc) { int iSaveDC = 0; if (m_hrgnClip != NULL) { iSaveDC = ::SaveDC(hdc); ::ExtSelectClipRgn(hdc, m_hrgnClip, RGN_AND); } for(uint ui = 0; ui < m_vSprite.size(); ++ui) { m_vSprite[ui]->Erase(hdc); } if (m_hrgnClip != NULL) { ::RestoreDC(hdc, iSaveDC); }}void CompositeNextStateRegionSprite::Draw(OUT HDC hdc) { int iSaveDC = 0; if (m_hrgnClip != NULL) { iSaveDC = ::SaveDC(hdc); ::ExtSelectClipRgn(hdc, m_hrgnClip, RGN_AND); } for(uint ui = 0; ui < m_vSprite.size(); ++ui) { m_vSprite[ui]->Draw(hdc); } if (m_hrgnClip != NULL) { ::RestoreDC(hdc, iSaveDC); }}void CompositeNextStateRegionSprite::Save(IN HDC hdc, HRGN hrgnClip) { HRGN hrgnTemp = CreateRectRgn(0,0,0,0); ::CombineRgn(hrgnTemp, hrgnClip, NULL, RGN_COPY); if (m_hrgnClip != NULL) { ::CombineRgn(hrgnTemp, hrgnTemp, m_hrgnClip, RGN_AND); } for(uint ui = 0; ui < m_vSprite.size(); ++ui) { m_vSprite[ui]->Save(hdc, hrgnTemp); } ::DeleteObject(hrgnTemp);}void CompositeNextStateRegionSprite::Next(void) { for(uint ui = 0; ui < m_vSprite.size(); ++ui) { m_vSprite[ui]->Next(); }}void CompositeNextStateRegionSprite::CalculateRegions(OUT UpdateRegions& ur) { ur.hrgnDraw = ::CreateEmptyRgn(); ur.hrgnErase = ::CreateEmptyRgn(); ur.hrgnSave = ::CreateEmptyRgn(); for(uint ui = 0; ui < m_vSprite.size(); ++ui) { UpdateRegions urTemp; m_vSprite[ui]->CalculateRegions(urTemp); ::CombineRgn(ur.hrgnDraw, ur.hrgnDraw, urTemp.hrgnDraw, RGN_OR); ::CombineRgn(ur.hrgnErase, ur.hrgnErase, urTemp.hrgnErase, RGN_OR); ::CombineRgn(ur.hrgnSave, ur.hrgnSave, urTemp.hrgnSave, RGN_OR); } if (m_hrgnClip != NULL) { ::CombineRgn(ur.hrgnDraw, ur.hrgnDraw, m_hrgnClip, RGN_AND); ::CombineRgn(ur.hrgnErase, ur.hrgnErase, m_hrgnClip, RGN_AND); ::CombineRgn(ur.hrgnSave, ur.hrgnSave, m_hrgnClip, RGN_AND); }}// 7/6void CompositeNextStateRegionSprite::Scroll(IN const POINT& ptDelta) { for(uint ui = 0; ui < m_vSprite.size(); ++ui) { m_vSprite[ui]->Scroll(ptDelta); }}void CompositeNextStateRegionSprite::SetClipRgn(HRGN hrgnClip) { if (m_hrgnClip != NULL) { ::DeleteObject(m_hrgnClip); } m_hrgnClip = hrgnClip;}// ***************************************************************************************************// ** SolidColorSprite *****************************************************************************// ***************************************************************************************************SolidColorSprite::SolidColorSprite(const SIZE& szMax) : m_szMax(szMax){ m_state.bVisible = FALSE; m_stateNext.bVisible = FALSE; m_hbmpSave = NULL;}SolidColorSprite::~SolidColorSprite() { if (m_hbmpSave != NULL) { ::DeleteObject(m_hbmpSave); }}void SolidColorSprite::SetNextState(const State& state) { m_stateNext = state;}BOOL SolidColorSprite::HitTest(const POINT& pt) const { BOOL b = m_state.bVisible && ::PtInRect(& m_state.r, pt); return b;}void SolidColorSprite::Erase(OUT HDC hdc) { if (m_hbmpSave != NULL && m_state.bVisible) { HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmpOld = (HBITMAP) ::SelectObject(hdcMem, m_hbmpSave); ::BitBlt(hdc, m_state.r.left, m_state.r.top, RW(m_state.r), RH(m_state.r), hdcMem, 0, 0, SRCCOPY); ::SelectObject(hdcMem, hbmpOld); ::DeleteDC(hdcMem); }}void SolidColorSprite::Draw(OUT HDC hdc) { if (m_state.bVisible) { ::FillSolidColor(hdc, m_state.r, m_state.clr); }}void SolidColorSprite::Save(IN HDC hdc, IN HRGN hrgnClip) { if (m_state.bVisible) { if (m_hbmpSave == NULL) { m_hbmpSave = ::CreateCompatibleBitmap(hdc, m_szMax.cx, m_szMax.cy); } HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmpOld = (HBITMAP) ::SelectObject(hdcMem, m_hbmpSave); ::SelectClipRgn(hdcMem, hrgnClip); ::OffsetClipRgn(hdcMem, - m_state.r.left, - m_state.r.top); ::BitBlt(hdcMem, 0, 0, RW(m_state.r), RH(m_state.r), hdc, m_state.r.left, m_state.r.top, SRCCOPY); ::SelectObject(hdcMem, hbmpOld); ::DeleteDC(hdcMem); }}void SolidColorSprite::Next(void) { m_state = m_stateNext;}void SolidColorSprite::CalculateRegions(OUT UpdateRegions& ur) { if (m_state != m_stateNext) { ur.hrgnErase = (m_state.bVisible) ? ::CreateRectRgn(m_state.r) : ::CreateEmptyRgn(); ur.hrgnSave = (m_stateNext.bVisible) ? ::CreateRectRgn(m_stateNext.r) : ::CreateEmptyRgn(); ur.hrgnDraw = (m_stateNext.bVisible) ? ::CreateRectRgn(m_stateNext.r) : ::CreateEmptyRgn(); } else { ur.hrgnErase = ::CreateEmptyRgn(); ur.hrgnSave = ::CreateEmptyRgn(); ur.hrgnDraw = ::CreateEmptyRgn(); }}//7/6void SolidColorSprite::Scroll(IN const POINT& ptDelta) { ::OffsetRect(&m_state.r, ptDelta.x, ptDelta.y); //::OffsetRect(&m_}#if 0// ****************************************************************************************************// ** DebugBounceSprite *****************************************************************************// ****************************************************************************************************DebugBounceSprite::DebugBounceSprite(const SIZE& sz, const POINT& pt, COLORREF clr, const RECT& rBounce, const POINT& ptV) : SolidColorSprite(sz) { State st; ::SetRect(st.r, pt, sz); st.clr = clr; st.bVisible = TRUE; this->SetNextState(st); m_rBounce = rBounce; m_ptV = ptV;}void DebugBounceSprite::Next(void) { this->SolidColorSprite::Next(); State st = GetState(); RECT r = st.r; ::OffsetRect(&r, m_ptV.x, m_ptV.y); POINT pt = { r.left, r.top }; BOOL bSet = TRUE; if (pt.x < m_rBounce.left || pt.x >= m_rBounce.right) { m_ptV.x = - m_ptV.x; bSet = FALSE; } if (pt.y < m_rBounce.top || pt.y >= m_rBounce.bottom) { m_ptV.y = - m_ptV.y; bSet = FALSE; } if (bSet) { st.r = r; this->SetNextState(st); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -