BREW Breakout - 5 / 9 -
Drawing Images and Characters
The racket and ball need to be frequently drawn and removed (they are removed by drawing them the same color as the backround).
A special function is required to carry out these actions. In this function, if the flag argument is true, the function draws the object with its original color, if the argument is false, then it draws it with the background color.
Draw Block (Draw Rectangle)
The DrawBlock function below, is for drawing blocks.
Void Block::DrawBlock(SInt16 n, Bool flag) { if (n < 0) { // Draw all blocks for (SInt16 i = 0; i < BLOCK_H_NUM * BLOCK_V_NUM; i++) { DrawBlock(i); } return; } if (!flag) { // Remove _pgraphics->ClearRectangle(_blocks[n].block); } else { if (_blocks[n].type != BLOCK_TYPE_NONE && _blocks[n].type != BLOCK_TYPE_INVISIBLE) { // Draw // Paint image _pgraphics->SetFillMode(true); // Border line is white _pgraphics->SetForeColor(SFXRGBColor(255, 255, 255, 0)); // Block color _pgraphics->SetFillColor(_blocks[n].color); // Actual drawing _pgraphics->DrawRectangle(_blocks[n].block); } } }
In order to specify the border line of the blocks, they are drawn in white and the inside is filled with the original color.
First, enable the region fill mode.
_pgraphics->SetFillMode(true);
Then set the border line color to white.
_pgraphics->SetForeColor(SFXRGBColor(255, 255, 255, 0));
Set the block color.
_pgraphics->SetFillColor(_blocks[n].color);
Finally, draw the block.
_pgraphics->DrawRectangle(_blocks[n].block);
So, the idea is to set the color first by SetForeColor() and SetFillColor(), then invoke DrawRectangle() afterwards. But the screen will not be updated just by drawing it.
To remove the blocks, paint them with the background color.
_pgraphics->ClearRectangle(_blocks[n].block);
Draw Racket (FillRoundRectangle)
The raquet is drawn as a rectangle with rounded corners, but a standard rectangle is used for collision detection.
This is the code for drawing the racket.
Void Block::DrawRacket(Bool flag) { if (!flag) { // remove _pgraphics->ClearRectangle(_racket.racket); } else { // draw _pgraphics->FillRoundRectangle(_racket.racket, SFXSize(RACKET_CORNER, RACKET_CORNER), _racket.color); } }
The definition of the FillRoundRectangle() code is the following.
Void FillRoundRectangle( SFXRectangleConstRef rectangle, //Stadard rectangle SFXSizeConstRef size, //Height and width of oval //for rounded corner SFXRGBColorConstRef color //Color );
The corner part of the rectangle, specified by size, will be replaced by an oval with size.GetWidth() and size.GetHeight() as its width and height.
This rectangle does not look like normal rectangles, but it is still considered one. To remove the racket, use the same procedure used to remove the blocks.
Draw Ball (FillCircle)
Drawing the ball is similar to drawing blocks and rackets.
Create the ball as an SFXCircle object, then pass it as an argument to the DrawCircle member function or FillCircle member function of SFXGraphics class.
This is the actual code.
Void Block::DrawBall(Bool flag) { if (!flag) { // Remove SFXRGBColor BGColor = _pgraphics->GetBackColor(); _pgraphics->FillCircle(_usingBall.ball, BGColor); } else { // Draw _pgraphics->FillCircle(_usingBall.ball, _usingBall.color); } }
The difference with the previous 2 chunks of codes (drawing blocks and rackets) is the "remove ball" part. There is no such thing as a ClearRectangle() function (function to paint the rectangle with background color) for a circle.
SFXRGBColor BGColor = _pgraphics->GetBackColor();
Obtain the background color.
_pgraphics->FillCircle(_usingBall.ball, BGColor);
Then draw a circle filled with the background color.
Drawing Characters
Drawing characters in the game is done by a set of overloaded functions.
- Void Block::DrawMessage(SFXWideStringConstRef msg)
- Void Block::DrawMessage(Void)
DrawMessage(Void) will convert current score stored in Block::_score to a string, then invoke DrawMessage(SFXWideStringConstRef msg) by using score as an argument.
The number of remaining balls are displayed on the bottom right as icons. But when the score is updated, they will disappear because the score will over paint the area with background color.
Therefore, DrawMessage() redraws icons after redrawing the strings.
There are also conversions in this function. The first is from integers to strings ( BREW wide strings, to be precise). This method can be used for other conversions.
There is static member function, Format( ACharConstPtr format, ...) in the SFXWideString class.
This function works just like the printf function in C. It is for obtaining formatted data as SFXWideString by writing from one format to another. The format can be writen in ASCII strings. *
* Some overlaoding exists in this function, and the format is in the BREW WideString.
In Breakout, this function is used in this way.
SFXWideString msg = SFXWideString::Format("Score: %d", _score);
By using this code, the value in _score can be displayed in msg in "Score: (score)" format.
Now that the integer data has successfully been converted to a string, lets display it on the screen. Use the SFXGraphig::DrawText for this purpose.
There are several overloads in this function. The following 3 are most frequently used are:
Void DrawText( SFXWideStringConstRef string, // Drawn string SFXGridConstRef grid, // Coordinates SFXRectangleConstRef rectangle, // Rectangle border UInt32 align = IDF_ALIGN_NONE // Alignment ); Void DrawText( SFXWideStringConstRef string, // Drawn string SFXRectangleConstRef rectangle, // Rectangle border UInt32 align = IDF_ALIGN_NONE // Alignment ); Void DrawText( SFXWideStringConstRef string, // Drawn string SFXGridConstRef grid, // Coordinates UInt32 align = IDF_ALIGN_NONE // Alignment );
This code is for displaying the msg string in _messageArea.
_pgraphics->SetFont(AEE_FONT_NORMAL); _pgraphics->SetForeColor(MESSAGE_COLOR); _pgraphics->DrawText(msg, _messageArea, IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE | IDF_RECT_FILL);
The point is to assign the font and its color before invoking the DrawText() function.
Here are the meanings of the alignments used in the code.
Alignment | Meaning |
---|---|
IDF_ALIGN_CENTER | Horizontal center of _messageArea |
IDF_ALIGN_MIDDLE | Vertical center of _messageArea |
IDF_RECT_FILL | Paint it with back ground color _messageArea |
Update screen
Although we have been drawing shapes and characters, they won't be updated on the screen until this code is executed.
_pgraphics->Update();
The Update function should not be invoked every time a shape is drawn. So screen update is only done in Void Block::CreateStage(SInt16 n) and Void Animate(VoidPtr pData).