Typing Tutorial Game on Windows Form.

marksquall

Active member
Joined
Oct 17, 2009
Messages
28
Programming Experience
3-5
Dear members and administrators,

Hello and a pleasant day.

I am working with simple typing game and I had a tutorial section on this game.

I have a String object like the one given below and show the content of the String in a Label:
VB.NET:
Dim message As String ="welcome to this typing game"
LblMessage.Text = message


I know I will use the Forms KeyPress Event to determine which letters had been pressed. But how would I change the color of each letter every time the player typed the letter correctly. For example, by default my LblMessage's ForeColor is black, but if the user press the "w" key, The letter "w" in the word "welcome" will change into bright color, like red for example.

Thank you for any ideas on how would I come up to this task.

Thank you and more power.

Warm regards,

Mark Squall
 
You wouldn't because a Label only supports a single colour. You could try drawing the text directly onto a control using GDI+, in which case you can use multiple colours to draw multiple Strings. I've also seen a custom Label control that supported multiple colours but I don't recall where now.
 
I should change other alternative to changing colors?

jmcilhinney,

Thank you for the information. I guess I will set that aside from now, and consider some "alternatives", I am thinking of something like instead of changing colors, the letters being typed will be "erased" one by one from the string. Again from the example code, if the user typed "w" from the "welcome to this typing game", the letter "w" will be gone from the string, followed by "e", then "l", and so forth until the String message will be equal to String.Empty.

Is there a trick on how to do that? Via Form's KeyPress Event?

Thank you.


Warm regards,

Mark Squall
 
You could handle the KeyPress event and het the KeyChar and then get the first Char from the String in the Label simply by indexing it like an array and test whether they are equal. If they are then you can use Substring to get all but the first character and then replace the original String with the result.
 
A RichTextBox set to ReadOnly will also provide text coloring.
 
Got it! But it lacks more...please help.

Hello JohnH and jmcilhinney,

Thank you for the idea, I think I (almost) got it, using RichTextBox and indexing the string (inside the RichTextBox), I tested this code and it works:

VB.NET:
Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress
      
        If e.KeyChar.ToString().Equals(Me.RichTextBox1.Text.Chars(0).ToString()) Then
            Me.RichTextBox1.SelectionStart = 0
            Me.RichTextBox1.SelectionLength = 0 + 1
            'Me.RichTextBox1.Select(RichTextBox1.Text.Length - i, RichTextBox1.Text.Length)
            Me.RichTextBox1.SelectionColor = Color.Red
        End If     

    End Sub

I put the string "programming" in the RichTextBox, when I press "p", the "p" is highlighted and it turns red. But I can't loop to the rest of string characters. If I put a For Loop between If statement like this:

VB.NET:
For i = 0 To (Me.RichTextBox1.Text.Length - 1)
            If e.KeyChar.ToString().Equals(Me.RichTextBox1.Text.Chars(i).ToString()) Then
                Me.RichTextBox1.SelectionStart = i
                Me.RichTextBox1.SelectionLength = i + 1
                'Me.RichTextBox1.Select(RichTextBox1.Text.Length - i, RichTextBox1.Text.Length)
                Me.RichTextBox1.SelectionColor = Color.Red
            End If
Next

The e.KeyChar value is always "p"c (in debug mode). How do I "reset" my e.KeyChar back to 0 or something then proceed to compare to the next character in RichTextBox, which is letter "r" in "programming".

Thanks guys. Anyway, I am using the good ol VB .NET 2003 (that's my requirement, so I stick to this IDE).

Warm regards,

Mark Squall
 
Why would you want to loop to the rest of the characters if you already found the one you were looking for? All you need to do is create a index-tracker variable.

It will always be equal to 0 in the beginning so:

Dim tIndex As Integer
   Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress

      If e.KeyChar.ToString().Equals(Me.RichTextBox1.Text.Chars(tIndex).ToString()) Then
         Me.RichTextBox1.SelectionStart = tIndex
         Me.RichTextBox1.SelectionLength = 1
         Me.RichTextBox1.SelectionColor = Color.Red
         tIndex += 1
      End If

   End Sub


PS, don't forget to handle the possibility of a user typing keys even when all have been typed.. try it yourself and see.
 
Eureka...I got It!

Hello guys,

Finally, I got it...feels so good solving this by myself with the idea of others. :tennis:

I just want to share this code (maybe it would come in handy in the future).

First, I "break down" the String content inside the RichTexBox and put it in Form's Load event:

VB.NET:
[COLOR="#0000FF"]Private[/COLOR] characters [COLOR="#0000FF"]As Char[/COLOR]()
[COLOR="#0000FF"]Private[/COLOR] iPos [COLOR="#0000FF"]As Integer[/COLOR]=0
[COLOR="#0000FF"]Private Sub[/COLOR] Form1_Load([COLOR="#0000FF"]ByVal[/COLOR] sender [COLOR="#0000FF"]As[/COLOR] System.Object, ByVal e As System.EventArgs) [COLOR="#0000FF"]Handles MyBase[/COLOR].Load
        
        characters = [COLOR="#0000FF"]Me[/COLOR].RichTextBox1.Text.ToCharArray

        [COLOR="#008000"]'This code below underlines the first letter in the RichTextBox[/COLOR]
        [COLOR="#0000FF"]Me[/COLOR].RichTextBox1.SelectionStart = iPos
        [COLOR="#0000FF"]Me[/COLOR].RichTextBox1.SelectionLength = 1
        RichTextBox1.SelectionFont = [COLOR="#0000FF"]New[/COLOR] Font(RichTextBox1.SelectionFont.Name, RichTextBox1.SelectionFont.Size, FontStyle.Underline)
        RichTextBox1.SelectionColor = Color.GreenYellow
        RichTextBox1.SelectionAlignment = HorizontalAlignment.Center
 [COLOR="#0000FF"]End Sub[/COLOR]

  • "All you need to do is create a index-tracker variable." --- 22-degrees
  • "A RichTextBox set to ReadOnly will also provide text coloring." ---JohnH
  • "You could handle the KeyPress event and hit the KeyChar and then get the first char from the String in the Label simply by indexing it like an array and test whether they are equal. If they are then you can use Substring to get all but the first character and then replace the original String with the result." ---jmcilhinney

Using the variable iPos as the index-tracker, here is now the code for the Form's KeyPress Event, still using RichTextBox as the control that will show the string/words:

VB.NET:
[COLOR="#0000FF"]Private Sub[/COLOR] Form1_KeyPress([COLOR="#0000FF"]ByVal[/COLOR] sender [COLOR="#0000FF"]As[/COLOR] Object, [COLOR="#0000FF"]ByVal[/COLOR] e [COLOR="#0000FF"]As[/COLOR] System.Windows.Forms.KeyPressEventArgs) [COLOR="#0000FF"]Handles MyBase[/COLOR].KeyPress
    [COLOR="#0000FF"]Try[/COLOR]
            [COLOR="#0000FF"]Dim[/COLOR] key [COLOR="#0000FF"]As Char[/COLOR] = e.KeyChar
            [COLOR="#0000FF"]If[/COLOR] key.ToString().Equals(characters(iPos).ToString()) [COLOR="#0000FF"]Then[/COLOR]
                
                [COLOR="#008000"]'This code below will "remove" the underline on the "currently focused" letter in the RichTextBox[/COLOR]
                RichTextBox1.Select(iPos, 1)
                RichTextBox1.SelectionFont = [COLOR="#0000FF"]New[/COLOR] Font(RichTextBox1.SelectionFont.Name, RichTextBox1.SelectionFont.Size, FontStyle.Regular)
                RichTextBox1.SelectionColor = Color.Black
                
                [COLOR="#008000"]'This code below will  underline the NEXT letter in the RichTextBox[/COLOR]
                Me.RichTextBox1.SelectionStart = iPos + 1
                Me.RichTextBox1.SelectionLength = 1
                RichTextBox1.SelectionFont = New Font(RichTextBox1.SelectionFont.Name, RichTextBox1.SelectionFont.Size, FontStyle.Underline)               
                RichTextBox1.SelectionColor = Color.GreenYellow
                iPos = iPos + 1
                              
                [COLOR="#008000"]'Maybe play a sound here If you want to tell the user he typed the correct letter?[/COLOR]

                e.Handled = [COLOR="#0000FF"]True[/COLOR]
            [COLOR="#0000FF"]Else[/COLOR]
                [COLOR="#008000"]'Maybe play an error sound here If you want to tell the user he typed the wrong letter?[/COLOR]

                e.Handled = True
            [COLOR="#0000FF"]End If[/COLOR]
        [COLOR="#0000FF"]Catch[/COLOR] ioore[COLOR="#0000FF"] As[/COLOR] IndexOutOfRangeException

        [COLOR="#0000FF"]End Try[/COLOR]        

    [COLOR="#0000FF"]End Sub[/COLOR]

If my coding is bad and needs improvement, please inform and share your code improvements, I'll love to consider it.

Thank you so much.


Warm regards,

Mark Squall
 
Glad you got sorted.. the only comments I have are regarding sending data to variables and then calling the variables to retrieve the data again when you can just get the data you need directly as you were originally doing.

Unless you intend to use the "characters" array for a different purpose outside of these 2 subs then i dont think it is necessary to have it included. And the variable "key" again is not necessary either in my opinion.
 
Back
Top