Archived

This topic is now archived and is closed to further replies.

jimothygu

bitmapped fonts among other things

Recommended Posts

Hiya, just had some questions about implementing bitmapped fonts. I''ve got a bitmap of fonts that is 16 X 2608, and it is a-Z 0-9 and all other special characters. Can I just implement this like I do the rest of my sprites, like say that each letter is 16x16, and I just make an array of where each letter is on the bitmap so I can then render it? Or is there an easier "font engine" that I can use\make that will make it easier to put together words for me. The game is a Worms Armageddon clone so the text is used mostly for health\names, and I noticed that Worms uses a standard white font as their bitmap, but then in-game it''s colored. Is there an easy way of coloring all of the white pixels of the font a certain color before it''s rendered on the screen? On another unrelated topic, I am currently using 800x600 maps with a 800x600 window, but how hard would it be to use bigger maps (say 1024x768) and have the mouse scroll the viewport around? Thanks!

Share this post


Link to post
Share on other sites
I draw the sprites like this:


//-----------------------------------------------------------------------------
// Name: drawSprite()
// Desc: Uses the sprite''s properties and current animation values to select
// the correct frame from the sprit''s bitmap, and then copies the
// bitmap data from the surface given, onto the display given.
//-----------------------------------------------------------------------------
HRESULT CSprite::drawSprite( CDisplay *pDisplay, CSurface *pSurface )
{
// This function draws the sprite''s next frame of animation by
// copying a rectangular region of bitmap data from pSurface
// onto a rectangular region of the back buffer held by pDisplay.
// The source surface will be a bitmap that contains the frames of
// animation necessary to produce an animated sprite and the
// destination surface will most likely be the back buffer surface
// where all the sprites will be copied to before being flipped with
// the primary surface. Information concerning the frame''s width and
// height, number of frames per row and possible frame offsets will
// be used to create a RECT structure that will specify the exact
// position of the next frame of animation within the bitmap.
// The sprite''s current x/y position on the screen will then be used
// to create a second RECT which will tell the Blt() function where
// to copy the frame to on the destination surface when the data
// is blitted.

HRESULT hr;

if( m_bActive == true )
{
RECT rcSource;
RECT rcDest;
DWORD dwFrameNumber;
DWORD dwNextNumber;

if( m_bSingleFrame == false )
{
dwFrameNumber = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame];
}
else
{
dwFrameNumber = 0;
m_nFramesAcross = 1;
}


// Create a source RECT that represents the section of the bitmap
// where the next frame of animation will be copied from during the blit.
rcSource.top = ( ( dwFrameNumber / m_nFramesAcross ) * m_nFrameHeight );
rcSource.left = ( ( dwFrameNumber % m_nFramesAcross ) * m_nFrameWidth );
rcSource.bottom = rcSource.top + m_nFrameHeight;
rcSource.right = rcSource.left + m_nFrameWidth;

// If an offset was used, (i.e. frame 0 is not be located in
// the upper left corner of the bitmap), the offset values
// must be applied or the frames will not be copied correctly.
if( m_nFrameOffset_x != 0 || m_nFrameOffset_y != 0 )
{
rcSource.top += m_nFrameOffset_y;
rcSource.left += m_nFrameOffset_x;
rcSource.bottom += m_nFrameOffset_y;
rcSource.right += m_nFrameOffset_x;
}

// Now, create a destination RECT that represents where the
// source RECT will be copied to on the destination surface.
rcDest.top = (long)m_dPosition_y;
rcDest.left = (long)m_dPosition_x;
rcDest.bottom = rcDest.top + m_nFrameHeight;
rcDest.right = rcDest.left + m_nFrameWidth;
rcDest.bottom += m_nHeightScaling;
rcDest.right += m_nWidthScaling;

hr = pDisplay->GetBackBuffer()->Blt( &rcDest,
pSurface->GetDDrawSurface(), &rcSource,
DDBLT_WAIT | DDBLT_KEYSRC, NULL );

if( m_bAutoAnimate == true && m_bSingleFrame == false)
{
// Check and see if the next frame number is a special control code!
dwNextNumber = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame+1];

if( dwNextNumber == LOOP_ANIMATION )
m_nCurrentFrame = -1;

if( dwNextNumber == GOTO_NEXT_ANIMATION )
{
m_nCurrentAnimation = m_nAnimations[m_nCurrentAnimation][m_nCurrentFrame+2];
m_nCurrentFrame = -1;
}

if( dwNextNumber == GO_INACTIVE )
{
m_bActive = false;
m_nCurrentFrame = -1;
}

if( dwNextNumber == MAINTAIN_LAST_FRAME )
return hr;

if( m_nFrameRateModifier == 0 )
{
++m_nCurrentFrame;
}
else
{
// Has the frame rate has been modified!
if( m_nFrameRateModifier < 0 )
{
// The frame rate for animations has been slowed!
// Keep skipping cycles until we can move on to
// the next frame
--m_nFrameSkipCount;

if( m_nFrameRateModifier == m_nFrameSkipCount )
{
++m_nCurrentFrame;
m_nFrameSkipCount = 0;
}
}
else
{
// The frame rate for animations has been speeded up!
// Skip ahead the number of frames given
// by nFrameRateModifier
for( int i = 0; i < m_nFrameRateModifier; ++i )
{
incFrame(false);
}
}
}
}
}

return hr;
}
[/CODE]

Share this post


Link to post
Share on other sites
Are you using D3D or DDraw? I''ll assume youre using D3D for now.

Basically, yes, you can draw your characters each as a sprite. There are also some things in D3D you could look at, ID3DXFont and the CD3DFont class.

If you have a lot of text to draw, then drawing each character seperately will start to get slow. You should batch them up so that you draw all characters using a particular font texture at once. I think the CD3DFont class does this, so you can look there for an idea.

You can colour the characters just by changing the vertex colour, or the material colour. Changing the vertex colour gives you more flexibility though. You can also change the vertex alpha to make characters fade over time.

Share this post


Link to post
Share on other sites