void AppView::ConstructL( const TRect& aRect )
{
CreateWindowL();
SetRect( aRect ); // Load in the bitmap images from the multi bitmap file
this->iBackgroundImage = CommonGraph::CreateBitmapL( KMultiBitmapFilename, 0 );
this->iSpriteImage = CommonGraph::CreateBitmapL( KMultiBitmapFilename, 1 );
this->iSpriteMask = CommonGraph::CreateBitmapL( KMultiBitmapFilename, 2 );
// Create the off screen bitmap and device / gc
this->iOffScreenBitmap = CommonGraph::CreateBitmapL( Rect().Size(),KColourDepth );
this->iOffScreenBitmapDevice = CommonGraph::CreateBitmapDeviceL( *this->iOffScreenBitmap );
this->iOffScreenBitmapGc = CommonGraph::CreateGraphicsContextL( *this->iOffScreenBitmapDevice );
this->iLines = new (ELeave) CArrayPtrFlat<CLine> ( LINE_COUNT );
this->iSprites = new (ELeave) CArrayPtrFlat<CSprite> ( SPRITE_COUNT );
for(TInt i = 0; i < SPRITE_COUNT; ++i)
{
CSprite* _sprite = CSprite::NewLC();
//Just dummy values
_sprite->SetXSpeed(2 + i);
_sprite->SetYSpeed(2 + i);
TInt xPos = i * 17;
//Check screen boundaries (176-17=159)
if(i >= 159)
xPos -= 159;
_sprite->Move( TPoint(xPos, i) );
this->iSprites->AppendL( _sprite );
CleanupStack::Pop( _sprite );
}
// Create a periodic timer but don't start it yet
this->iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
ActivateL();
}
void AppView::StartAnim(void)
{
if( !this->iTimer->IsActive() )
this->iTimer->Start( 1, 1, TCallBack(AppView::TimerCallBack, this) );
}
TInt AppView::TimerCallBack( TAny *aPtr )
{
((AppView*)aPtr)->MoveSprites();
return TRUE;
}
void AppView::MoveSprites(void)
{
--(this->iPeriod);
if(this->iPeriod < 0)
{
//Filter ticks
//If you set this to 1, it works.
this->iPeriod = 0;
for(TInt i = 0; i < SPRITE_COUNT; ++i)
{
CSprite* _sprite = this->iSprites->At(i);
//Move sprite
TPoint iPos = _sprite->Position();
iPos.iY += _sprite->YSpeed();
if(iPos.iY <= 0)
_sprite->SetYSpeed( Abs(_sprite->YSpeed()) );
if(iPos.iY >= 191)
_sprite->SetYSpeed( -1 * Abs(_sprite->YSpeed()) );
iPos.iX += _sprite->XSpeed();
if(iPos.iX <= 0)
_sprite->SetXSpeed( Abs(_sprite->XSpeed()) );
if(iPos.iX >= 159)
_sprite->SetXSpeed( -1 * Abs(_sprite->XSpeed()) );
_sprite->Move( iPos );
}
//Update display
CWindowGc& gc = SystemGc();
gc.Activate(*DrawableWindow());
this->UpdateDisplay();
gc.Deactivate();
}
}
void AppView::UpdateDisplay() const
{
CWindowGc& gc = SystemGc();
// Blit the background image onto the off screen bitmap at the top left position
iOffScreenBitmapGc->BitBlt( TPoint(0,0), this->iBackgroundImage );
// Blit the sprites on top of it using its mask to retain the background where necessary
for(TInt i = 0; i < SPRITE_COUNT; ++i)
{
//I forgot to copy the CommonGraph.h 😞
//Just replace with the BitBltMasked command. It's the same
CommonGraph::BitBltMaskedEntireBitmap( *this->iOffScreenBitmapGc, this->iSprites->At(i)->Position(), *this->iSpriteImage, *this->iSpriteMask );
}
// Blit the offscreen image onto the screen at the top left position
gc.BitBlt( Rect().iTl, this->iOffScreenBitmap );
}