Not Quite a Magic Ball

 Download CD Content

In this chapter, we continue looking at the entertainment aspects of Tablet PC development as we create a 'Magic Ball,' which answers any questions we give it. You are probably familiar with the general ideas of the application, which gives generic answers to any question we ask it.

  Note 

The source code for the projects are located on the CD-ROM in the PROJECTS folder. You can either type them in as you go or you can copy the projects from the CD-ROM to your hard drive for editing.

Starting the Project

Let's start a new VB Windows Forms application and begin this project by constructing the GUI, which consists of a couple of PictureBox controls, a ListBox control, and a Button control. You can see their properties in the Table 27.1 and their respective locations in Figure 27.1.

Table 27.1: Adding controls to the application

Type

Name

Location

Size

PictureBox

picDest

8,8

400,400

PictureBox

PictureBox1

n/a

n/a

ListBox

ListBox1

n/a

n/a

Button

Button1

425,375

80,25

Timer

tmrSpin

   

Figure 27.1: The GUI for our application is complete.

With the GUI in place, we can concentrate on the programming aspects of the project. Begin by adding the following variable declarations:

Private SourceBm As Bitmap Private SourceWid As Integer Private SourceHgt As Integer Private SourceCx As Single Private SourceCy As Single Private SourceCorners As PointF() Private DestWid As Integer Private DestHgt As Integer Private DestCx As Single Private DestCy As Single Private DestBm As Bitmap Private DestBackColor As Color Dim Positive As Boolean Dim txtAnswer As String Dim PicTop As Integer

The first section of these variables handles the source image we are going to load. This is an image of the ball, which is located in the Projects folder on the CD-ROM in the Chapter 27 directory. This image is loaded into PictureBox1 as a way of getting it into the application. This PictureBox is never visible, nor will the end user ever be aware of its existence.

We can load the image into the PictureBox in the Form_Load event. The code for this part of the event, which loads the image and sets some of its properties, has been used several times, so it's not worth repeating at this late stage in the book:

Me.BackColor = Color.White picDest.SizeMode = PictureBoxSizeMode.CenterImage PictureBox1.Image = Image.FromFile(System.Windows.Forms.Application.StartupPath & "all.bmp") SourceBm = New Bitmap(PictureBox1.Image) SourceWid = SourceBm.Width SourceHgt = SourceBm.Height SourceCx = SourceWid / 2 SourceCy = SourceHgt / 2 SourceCorners = New PointF() { _ New PointF(0, 0), _ New PointF(SourceWid, 0), _ New PointF(0, SourceHgt), _ New PointF(SourceWid, SourceHgt)}

The only thing that would be different to you in the previous code deals with the corners of the image. We use the points to rotate the image, which appears to give it some basic animation. The next step is to load the image into the destination variables, which are the second set of the original variables. This is the variable that will be manipulated and ultimately loaded into the picDest picture box. We also need to translate the corners to center the box at origin:

DestWid = Math.Sqrt(SourceWid * SourceWid + _ SourceHgt * SourceHgt) DestHgt = DestWid DestCx = DestWid / 2 DestCy = DestHgt / 2 DestBm = New Bitmap(DestWid, DestHgt) Dim i As Long For i = 0 To 3 SourceCorners(i).X -= SourceCx SourceCorners(i).Y -= SourceCy Next i

The remaining portion of the procedure sets some additional properties, such as setting the Interval of the timer to 100 and its Enabled property to False, initializing stop_time to Now, setting the text of Button1 to "Spin", and setting the text of the form to "Not Too Magic Ball". Additionally, we add items to the ListBox, which are the answers the ball gives us when we stop it from spinning.

Here is the remaining code for the procedure:

DestBackColor = picDest.BackColor tmrSpin.Interval = 100 tmrSpin.Enabled = False Button1.Text = "Spin" ListBox1.Items.Add("No") ListBox1.Items.Add("Could be") ListBox1.Items.Add("Possible") ListBox1.Items.Add("Don't Know") ListBox1.Items.Add("Try Again") ListBox1.Visible = False PictureBox1.Visible = False Me.Text = "Not Too Magic Ball" PicTop = picDest.Top

The button is used to start and stop the ball from spinning. It is within its Click event that we set this up using an If...Then statement. When the user clicks the button, the If...Then checks to see if tmrSpin is enabled. If it is, then we know that the ball is spinning and we need to stop it, change the Text property of the button to "Spin", and produce an answer. If it is not enabled, we can start the spinning, change the text of the button to "Stop", and set the answer to an empty string.

Here is the entire procedure:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim answer As Integer If tmrSpin.Enabled Then tmrSpin.Enabled = False Button1.Text = "Spin" picDest.Image = PictureBox1.Image.Clone answer = CInt(Rnd(1) * 4) txtAnswer = ListBox1.Items(answer) Else tmrSpin.Enabled = True Button1.Text = "Stop" txtAnswer = "" End If End Sub

There are two remaining procedures we need to work with, the first of which is the Paint event of picDest. We can use this Paint event to provide the ability to draw text on a picture box programmatically. This is how the answer will be drawn, and why we have to set it to an empty string whenever we are spinning the ball.

Here is the code for the Paint event:

Private Sub picDest_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles picDest.Paint Dim g As Graphics = e.Graphics g.DrawString(txtAnswer, Me.Font, New SolidBrush(Color.Black), 170, 185) End Sub

The final procedure we need to work with is the tmrSpin elapsed procedure. Within this procedure, we are going to perform the calculations for rotating and moving the picture so that it appears to be somewhat animated. The first lines of code begin by testing to see if we have a positive or negative value stored in the Boolean variable called Positive. This variable is used to go from positive to negative, negative to positive, and so on and so forth. By going back and forth with random values, it appears as if the ball is being twisted back and forth.

Here is the code for the beginning part of the tmrSpin elapsed procedure:

Dim dtheta = (Rnd(10) * 10) * Math.PI / 180.0 If Positive Then dtheta = -dtheta Positive = False Else Positive = True End If Static theta As Single = 0 theta += dtheta Dim corners() As PointF = SourceCorners ReDim Preserve corners(2)

To rotate the image, we use the built-in Sin and Cos functions, translate to center the results of the destination image, and then display the results using picDest. picDest is also moved, which simply adds to the illusion of movement, by changing its Top property. When the button is clicked to stop the procedure, picDest is returned to its starting point and the original image is loaded back into it so that the ball appears exactly as it started. This also makes rendering the answer much easier.

Here is the code:

Dim sin_theta As Single = Math.Sin(theta) Dim cos_theta As Single = Math.Cos(theta) Dim X As Single Dim Y As Single Dim i As Long For i = 0 To 2 X = corners(i).X Y = corners(i).Y corners(i).X = X * cos_theta + Y * sin_theta corners(i).Y = -X * sin_theta + Y * cos_theta Next i For i = 0 To 2 corners(i).X += DestCx corners(i).Y += DestCy Next i Dim gr_out As Graphics = Graphics.FromImage(DestBm) gr_out.Clear(DestBackColor) gr_out.DrawImage(SourceBm, corners) If Positive Then picDest.Top = picDest.Top - Rnd(10) Else picDest.Top = PicTop End If picDest.Image = DestBm

This actually finishes the application, which can now be saved and tested. When you run it, make sure the ball rotates back and forth as in Figures 27.2 and 27.3. You can also verify that you receive an answer similar to the one seen in Figure 27.4.

Figure 27.2: The ball rotates one direction to start an animation.

Figure 27.3: The ball moves the opposite direction to simulate back and forth movement.

Figure 27.4: The animation is stopped and the answer is displayed.

Summary

In this chapter, we created another entertainment style of application. Although the Tablet PC is such a new platform, it appears that simple types of games are probably best suited for its hardware as mobility and battery power are an issue. That said, users of a Tablet PC might like to play games when they have power connected to their machine or when they know they can recharge their systems before they need to use it again for serious business purposes. Like the PDA market, the Tablet PC is poised for great growth in the area of entertainment and game development. With that in mind, we move our focus back to these topics, including 3D rendering with OpenGL and DirectX, in Chapter 29, 3D Rendering with OpenGL and DirectX 9. In Chapter 28, Storing Ink in a Database, we go back to the world of ink and look at how we can store ink in a database.

Категории