BACK TO THE VC DOODLE GAME


BACK TO THE VC++ DOODLE GAME

It's time to turn your attention back to the development of this chapter's game project, the VC++ Doodle game. The VC++ Doodle game is a drawing program. You will create it by following the five basic development steps that you've used to create all the previous game projects.

Designing the Game

The VC++ Doodle game runs in a single window and is made up of one form and the 11 controls listed in Table 10.3.

Table 10.3: Form Controls for the VC++ Doodle Game

Control Type

Control Name

Description

Panel1

pntControl

Displays controls for drawing and painting

Label1

lblControls

Identifies the location of the controls for the VC++ Doodle application

Label2

lblColor

Identifies the ComboBox control where the player makes color selections

Button1

btnRectangte

Initiates the process of drawing a rectangte

Button2

btnLine

Initiates the process of drawing a line

Button3

btnCircle

Initiates the process of drawing an ellipse

Button4

btnFillRectangle

Initiates the process of drawing a filled-in rectangle

Button5

btnFillCircle

Initiates the process of drawing a filled-in ellipse

Button6

btnDraw

Initiates the process of making a freehand drawing

Button7

btnClear

Initiates the clearing of the drawing area

ComboBox1

cbxColor

Lists the available color choices provided by the application

Step 1: Creating a New Visual C++ Project

To create the VC++ Doodle game, use Visual C++ to create a new project, as outlined here:

  1. If you have not already done so, start up Visual C++ 2005 Express and then click on File, New Project. The New Project dialog box appears.

  2. Select the Windows Application template.

  3. Type VC++ Doodle as the name of your new application in the Name field located at the bottom of the New Project window.

  4. Click on OK to close the New Project dialog box.

Visual C++ then creates a new project for you and displays a new form upon which to design the game's user interface.

Step 2: Creating the User Interface

The first step in designing the game's user interface is to add the appropriate controls to the form and then move and resize them to the right locations. Use Figure 10.11 as a reference as you go through each of the following steps to make sure that you know where each control should be placed and how to size it.

  1. Resize Form1 by setting its Size property to 586, 458.

  2. Add a Panel control to the left side of the form and resize it until it takes up approximately 25 percent of the available form space.

  3. Add and center a Label control on top of the Panel control.

  4. Add six Button controls under the Label control.

  5. Add a second Label control beneath the last button that you added to the Panel control.

  6. Add a ComboBox control under the second Label control.

  7. Finally, add one more Button control on the Panel control.

image from book
Figure 10.11: Completing the interface design for the VC++ Doodle game.

The overall layout of the VC++ Doodle game's user interface is now complete. The next step is to begin customizing form and control properties.

Step 3: Customizing Form and Control Properties

The VC Doodle game contains only a few properties to configure. To create the settings that the application needs, change the form properties listed in Table 10.4.

Table 10.4: Property Changes for FormI

Property

Value

Name

frmMain

BackColor

White

Cursor

Crosshair

FormBorderStyle

Fixed3D

Size

586, 458

StartPosition

CenterScreen

Text

VC++ Doodle

Next, modify the properties listed in Table 10.5 for the Panel control.

Table 10.5: Property Changes for Panel Control

Property

Value

Name

pnlControl

Anchor

Top, Bottom, Left

BackColor

LightGray

BorderStyle

FixedSingle

Size

130, 430

Trick 

Take special note of the Anchor property setting. It has been set so that the Panel control will automatically resize itself if the form is resized. This gives the player the flexibility to change the size of the drawing area by maximizing the form without affecting the size and appearance of the Panel control.

Next, modify the properties listed in Table 10.6 for the two Label controls.

Table 10.6: Property Changes for Label Controls

Control

Property

Value

Label1

Name

lblControls

 

Font.Bold

True

 

Text

Controls

Label2

Name

lblColor

 

Font.Bold

True

 

Text

Select Color:

Now modify the properties listed in Table 10.7 for the seven Button controls.

Table 10.7: Property Changes for Button Controls

Control

Property

Value

Button1

Name

btnRectangle

 

Text

Rectangle

Button2

Name

btnLine

 

Text

Line

Button3

Name

btnCircle

 

Text

Circle

Button4

Name

btnFillRectangle

 

Text

Fill Rectangle

Button5

Name

btnFillCircle

 

Text

Fill Circle

Button 6

Name

btnDraw

 

Text

Draw

Button7

Name

btnClear

 

Text

Clear

Next, change the properties listed in Table 10.8 for the ComboBox control.

Table 10.8: Property Changes for ComboBox Control

Property

Value

Name

cbxColor

Items

Red

 

Green

 

Blue

 

Black

 

Yellow

 

Purple

Text

Red

That's it. You have finished making all the design time property changes to the VC++ Doodle application's form and control properties.

Step 4: Adding a Little Programming Logic

The first step in coding the VC++ Doodle game is to define the objects to be used internally throughout the application. These are shown here:

 private:   /// <summary>   /// Required designer variable.   /// </summary>   //Handle to manage form's drawing functionality   System::Drawing::Graphics ^FormGraphic;   //Handle to manage drawing pen   System::Drawing::Pen ^pen;   //Handle to manage graphical brush   System::Drawing::SolidBrush ^brush;   //Variables to manage drawing coordinates   System::Drawing::Point ptStart, ptEnd;   //Values for possible drawing states   enum class DrawingMode: Int16 {     DRAWRECTANGE, DRAWLINE, DRAWCIRCLE, DRAWFILLRECTANGLE,     DRAWFILLCIRCLE, DRAWFREE, DRAWNONE   };   //Variables to track current drawing state   DrawingMode drmCurrentMode;   //Flag to determine if drawing is in progress   Boolean blnDrawing; 

The first declaration defines a handle to reference the Graphics class. Below that is the handle to manipulate an instance of a Pen class, which is used in drawing lines. That is followed by a similar declaration for a brush handle, which will control the way shapes are filled.

The code that follows is a declaration for two System::Drawing::Point objects. Both are used throughout the application to keep track of where the user is positioning the mouse cursor for drawing. The Point ptStart variable tracks the start of a drawing movement, whereas the ptEnd movement stores its end.

Hint 

A Point class is a member of the System::Drawing namespace. The Point class can be used as a mechanism for storing sets of coordinates.

This chapter game again uses an enum class, derived from the Int16 class. The unique values it enumerates (defines) specify the possible drawing modes that the player might have triggered. These are later used to drive functionality that determines how the program performs drawing. The class definition is immediately followed by a declaration of an instance of the DrawingMode, drmCurrentMode. The drmCurrentMode object is used throughout the program to control drawing behavior.

Finally, a Boolean variable, blnDrawing, is declared to act as a monitor for whether the user is currently engaged in drawing.

The next step in building the VC++ Doodle program is to add the code shown in the next listing:

 private: System::Void Form1_Load(System::Object^ sender,\ System::EventArgs^ e) {      FormGraphic = this->CreateGraphics();      pen = gcnew System::Drawing::Pen( \          System::Drawing::Color::FromName( cbxColor->Text ) );      brush = gcnew System::Drawing::SolidBrush( \            System::Drawing::Color::FromName( cbxColor->Text ) );     //Set the default drawing coordinates to center screen     ptStart.X = this->Size.Width / 2;     ptStart.Y = this->Size.Height / 2;     ptEnd.X = this->Size.Width / 2;     ptEnd.Y = this->Size.Height / 2;     //Set default drawing mode     drmCurrentMode = DrawingMode::DRAWNONE;     blnDrawing = false; } 

As you can see, the first step that this function takes is to obtain access to its own CreateGraphics method, using this->CreateGraphics(). Then both pen and brush handles are instantiated, each using the color listed in the application's color combo box.

By default, the drawing coordinates are set to the center of the screen. This ensures that they start with some nonrandom value. (Zero would be just as acceptable, but for testing purposes would have started any graphical output under the application's panel on the upper-left side.) The application also sets its drawing mode defaults, indicating that no drawing mode has been selected and that drawing is not currently taking place.

To add functionality that causes the VC++ Doodle game to switch drawing modes when the appropriate buttons are clicked, you must double-click each control so that Visual C++ generates the necessary related code. The code to add to each control is quite simple. The sole task of each is to assign the enumerated object drmCurrentMode with contents corresponding to the appropriate button. Because each click event handler contains only one line, I've grouped the code for the controls next:

 private: System::Void btnRectangle_Click(System::Object^ sender, System::EventArgs^ e) {       drmCurrentMode = DrawingMode::DRAWRECTANGE;   } private: System::Void btnLine_Click(System::Object^ sender, System::EventArgs^ e) {       drmCurrentMode = DrawingMode::DRAWLINE;   } private: System::Void btnCircle_Click(System::Object^ sender, System::EventArgs^ e) {       drmCurrentMode = DrawingMode::DRAWCIRCLE;   } private: System::Void btnFillRectangle_Click(System::Object^ sender, System::EventArgs^  e) {       drmCurrentMode = DrawingMode::DRAWFILLRECTANGLE;   } private: System::Void btnFillCircle_Click(System::Object^ sender, System::EventArgs^  e) {       drmCurrentMode = DrawingMode::DRAWFILLCIRCLE;   } private: System::Void btnDraw_Click(System::Object^ sender, System::EventArgs^  e) {       drmCurrentMode = DrawingMode::DRAWFREE;   } 

The next step involves updating the application's current drawing color. If the user selects a new color, you must adjust the pen and brush colors accordingly. To create the event handler, double-click on the cbxColor ComboBox control and add the code shown here:

 private: System::Void cbxColor_SelectedIndexChanged(System: :Object^ sender, System::EventArgs^ e) {      //Set pen and brush colors      pen->Color = \         System::Drawing::Color::FromName( cbxColor->Text );      brush->Color = \           System::Drawing::Color::FromName( cbxColor->Text );   } 

This function uses the FromName() method of the Color object located in the System:: Drawing namespace. The method accepts as an argument the current text string in the ComboBox control. It translates this to a value that the Pen and Brush objects understand.

To allow the user to clear the form, double-click the Clear button and add the following code to the click event function that Visual C++ defines:

 private: System::Void btnClear_Click(System::Object^ sender, \ System::EventArgs^ e) {       //Clear the form to the background color       FormGraphic->Clear( this->BackColor );   } 

The Clear method of the System::Graphic class (in the instance of FormGraphic in this case) accepts a color and sets the surface of the form to that color. Controls or other elements on the form are unaffected because each has its own foreground and background color data in most cases. The form's current background color is obtained by using this to point to the class that the code is running within (the application's form).

No matter what kind of drawing operation the player wants to perform, such as drawing a circle, line, or freehand image, everything begins when the player clicks on the mouse button to set the starting point for whatever shape is being drawn. Therefore, you need to capture mouse events.

Hint 

A mouse event occurs whenever the user performs any action with the mouse that an application can recognize, such as clicking, moving the mouse, or dragging and dropping an item.

Visual C++ doesn't give you a control you can use to capture the mouse events. Instead, you must switch back to Design view, select the application's form, and investigate the options under the Properties window. By default, this window displays the properties of all the controls. To switch to the event handlers attached to the controls, click an icon that represents events (shown as a lightning bolt).

Locate the MouseUp entry. In the text field next to it, enter HandleMouseUp. Just as it does when you double-click a form, this causes Visual C++ to generate code that executes each time the form is clicked. Add the following code to this event handler function:

 private: System::Void HandleMouseUp(System::Object^ sender, \ System::Windows::Forms::MouseEventArgs^ e) {      blnDrawing = false;      //Stop drawing if current mode is freehand drawing      if( drmCurrentMode = DrawingMode::DRAWFREE )         return;      //Draw shape      if( drmCurrentMode != DrawingMode::DRAWNONE )      {        //If the current mode is a line, draw it        if( drmCurrentMode == DrawingMode::DRAWLINE )        {         FormGraphic->DrawLine( pen, ptStart, ptEnd );         return;        }        //Current mode is a shape        //Create a rectangle to represent shape extents        //  Height and width are composed of absolute      // value difference between the two x and y      // coordinates      System::Drawing::Rectang1e shapeRect(        ptStart.X, ptStart.Y,        Math::Abs( ptEnd.X - ptStart.X ),        Math::Abs( ptEnd.Y - ptStart.Y ) );      //Draw the shape      DrawShape( shapeRect );    } } 

This code is activated when the user releases the mouse button, but only if he's over the form. It does not trigger when the user clicks a control or the panel. Each control or form within an application can be given its own mouse click event handler, allowing you to customize mouse behavior to a high level.

The code within the HandleMouseUp event handler sets the drawing mode to false because the mouse is released only when drawing is complete. If the user is in freehand drawing mode, this function has no more to do and returns. If the user is in the process of drawing a shape or line, however, the release of the mouse button signifies that the shape or line should draw from the starting to the ending point. Drawing a line is straightforward, but if the user is in the process of drawing a shape, the program must translate the starting and ending coordinates into a rectangular region. This is done by creating an instance of a shape and initializing it with the x and y properties of ptStart and ptEnd.

Take special note of the call made to Math::Abs. The System::Drawing::Rectang1e class accepts an x and y location as its first two parameters, but it does not for the last two. Instead, any Rectangle object needs a height and a width. You can obtain this by subtracting the two x and y properties of ptStart and ptEnd, respectively, but you must make sure that the math does not produce a negative number. This is why you should use the Abs() method. Finally, after you determine the shape extents, the handler calls a function to draw the shape.

The next mouse events that the application needs to capture are mouse moves. Switch to Design view and add a handler called HandleMouseMove to the form's MouseMove category. When you type the name, Visual C++ generates code just as it did for the HandleMouseUp handler. Supply the handler with the following code:

 private:  System::Void HandleMouseMove(System::Object^ \ sender,  System::Windows::Forms::MouseEventArgs^  e) {       if( blnDrawing == true )       {       ptEnd.X = e->X;       ptEnd.Y = e->Y;       if( drmCurrentMode == DrawingMode::DRAWFREE )       {         //Offset the current coordinates so that         //  a small line can be drawn to represent         //  the current point         ptStart.X = e->X + 1;         ptStart.Y = e->Y + 1;         FormGraphic->DrawLine( pen, ptStart, ptEnd );       }    } } 

This event handler captures instances of the mouse moving over the application's form. It must first determine whether drawing is currently in process. Testing for this condition prevents the application from drawing lines or shapes accidentally when the user is moving the mouse over the form but has not started drawing.

If drawing is in progress, the application saves the current mouse coordinates. These are provided through e->X and e->Y. When you are drawing freehand, the current location is offset slightly so that a line can be drawn.

Finally, the application requires an event handler to capture each mouse down event. In Design view, add the handler by locating the MouseDown event entry and typing HandleMouseDown. Add the following code to the event handler that Visual C++ generates:

 private:  System::Void HandleMouseDown(System::Object^\ sender, System::Windows::Forms::MouseEventArgs^ e) {      if(  drmCurrentMode != DrawingMode::DRAWNONE )      {        //Now drawing, set starting coordinates        ptStart.X = e->X;        ptStart.Y = e->Y;        b1nDrawing = true;     } } 

This event handler captures the mouse click that initiates drawing. If a drawing mode has been selected, it saves the starting coordinates. It also toggles the variable tracking the drawing mode, blnDrawing, to true.

The VC++ Doodle game requires one final function to control which shape is drawn. The function must be created by hand, as shown here:

 private: System::Void DrawShape( \ System::Drawing::Rectangle rect ) {       //Set a default shape rectangle       switch( drmCurrentMode )       {         case DrawingMode::DRAWRECTANGE :           FormGraphic->DrawRectangle( pen, rect );           break;         case DrawingMode::DRAWCIRCLE :           FormGraphic->DrawEllipse( pen, rect );           break;         case DrawingMode::DRAWFILLRECTANGLE :           FormGraphic->FillRectangle( brush, rect );           break;         case DrawingMode::DRAWFILLCIRCLE :           FormGraphic->FillEllipse( brush, rect );           break;       }   } 

This function uses a switch statement to determine whether to draw a rectangle, circle, filled rectangle, or filled circle. After you've added this code, you can test the game.

Step 5: Testing the Execution of the VC++ Doodle Game

Okay. That's it. The VC++ Doodle game is now ready to run. Go ahead and run the game by pressing F5, and make sure that everything works like it's supposed to. If you run into problems, go back and double-check your typing.




Microsoft Visual C++ 2005 Express Edition Programming for the Absolute Beginner 2006
Microsoft Visual C++ 2005 Express Edition Programming for the Absolute Beginner 2006
ISBN: 735615381
EAN: N/A
Year: 2005
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net