Android Tutorial Tick-Tack-Toe: working with arrays of views

Discussion in 'Tutorials & Examples' started by Erel, Mar 31, 2011.

  1. Erel

    Erel Administrator Staff Member Licensed User

    This is an example of a Tick-Tack-Toe game.
    This game demonstrates two concepts. The first is an example of working with multiple views without duplicating code. In this case it is 9 buttons, however similar code can easily handle any number of views.
    The second concept is the handling of Activity_Pause and Activity_Resume events to keep the game state during the activity life cycle.

    The test it you just need to rotate the device. During the orientation change the activity is paused, created again and eventually resumed.
    The game should continue from the previous state.

    [​IMG]

    The following code creates the 9 buttons, puts each button in the correct place and stores a reference to this button in the Buttons array (two dimensions array):
    Code:
    For x = 0 To 2
            
    For y = 0 To 2
                
    Dim b As Button
                b.Initialize(
    "button"'All buttons share the same event sub
                b.TextSize = 30
                
    Activity.AddView(b,offsetX + x * (width + 10dip), offsetY + y * (width + 10dip), width, width)
                Buttons(x, y) = b 
    'store a reference to this view
            Next
        
    Next
    Later in Sub Button2_Click we find the button that raised the event with the help of Sender keyword:
    Code:
    Sub Button_Click
        
    'Using Sender we find the button that raised this event
        Dim b As Button
        b = 
    Sender
        
    If b.Text <> "" Then Return 'Already used button
        ...
    Saving the game state is done by using a process global variable. Unlike regular global variables, these variables are kept even when the activity is recreated.
    Code:
    Sub Activity_Resume
        
    'restore the previous state when the activity resumes
        For x = 0 To 2
            
    For y = 0 To 2
                Buttons(x, y).Text = ButtonsText(x, y)
            
    Next
        
    Next
    End Sub
    Sub Activity_Pause (UserClosed As Boolean)
        
    If UserClosed Then
            
    'If the user pressed on the back key we cancel the current game
            NewGame
        
    End If
        
    'save the current state when the activity is paused.
        For x = 0 To 2
            
    For y = 0 To 2
                ButtonsText(x, y) = Buttons(x, y).Text
            
    Next
        
    Next
    End Sub
    Note that the Buttons array cannot be declared as a process global variable. Only non-UI objects can be declared in Sub Process_Globals.

    The code is available here: http://www.basic4ppc.com/android/files/tutorials/TickTackToe.zip
     
    pesquera, koaunglay, hibrid0 and 3 others like this.
  2. myriaddev

    myriaddev Active Member Licensed User

    Who was pushed from an array stand point ?

    Who was pushed from an array stand point ? I love
    the generic approach using "b = Sender", but how
    do you translate that info to which item in the array
    was pushed ? Could you use "b.Tag" to store array
    index info and how ?
    Thanks, Jerry
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    You have two options. You can iterate over the array and check for equality.
    Or you can use the Tag property to store the array index.
    In this case there are two values so you need to declare your own type:
    Code:
    Sub Globals
     
    Type indices(x as int, y as int)
    End  Sub
    ...
    For y = 0 To 2
                
    Dim b As Button
                b.Initialize(
    "button"'All buttons share the same event sub
                b.TextSize = 30
                
    Activity.AddView(b,offsetX + x * (width + 10dip), offsetY + y * (width + 10dip), width, width)
                Buttons(x, y) = b 
    'store a reference to this view
                Dim i as indices
                i.initialize 
    'Not really necessary in this case
                i.x = x
                i.y = y
                b.Tag = i
            
    Next
    ...
    Sub Button_Click
        
    'Using Sender we find the button that raised this event
        Dim b As Button
        b = 
    Sender
       
    Dim i as indices
        i = b.Tag
     
  4. myriaddev

    myriaddev Active Member Licensed User

    With all the FAST help, my project done in half time

    Thanks Erel !
     
  5. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    I just came across this thread while searching for something else.
    I believe that the above code should be in Activity_Create, not Activity_Resume.

    As you noted in this post:

    And that Activity_Resume should [only] be used for...

    ...since code in Activity_Resume is run every time the app is started, even if the
    device was just turned on, and every time you leave the app and come back
    even if Android didn't kill the app and its data/states are still in memory.
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    You are correct. Putting the code in Activity_Resume is correct but less optimized.
     
  7. Peter Simpson

    Peter Simpson Expert Licensed User

    Thank you for this code

    Hello Erel,
    Thank you for putting this code in the forum.

    I'm already writing an app but I've just started writing another app that uses MySQL DB with dynamically generated buttons.

    This code hit the sweet spot :)
     
  8. ukimiku

    ukimiku Active Member Licensed User

    Erel,

    thanks for the code that shows how to programmatically add views. It (as many other things) now is very easy, esprecially when compared to other development environments. I think you are very good at making things simple (yet flexible) without oversimplifying.

    Regards,
     
  9. LouFromDetroit

    LouFromDetroit Member Licensed User

    Nice Demo - I made update if anyone interested

    Hi All,

    I am new to the B4A forum but I like what I see so far. I started with this demo to test out my system. I added a feature so you can play the computer /android option. If anyone is intersted I can post. I can't promise excellent code writing, but it works.

    Thanks to Erel for the demo.
     
  10. paolofi

    paolofi Member Licensed User

    I tried to use Panels array to create panels grid but I receive an error when try to retrieve the tag id:

    java.lang.RuntimeException: Object should first be initialized (Panel).

    Code:
    Sub Globals
        
    Dim ImgPanel(12As Panel
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    Dim r As Int
        
    Dim c As Int
        
    Dim sx As Int
        
    Dim sxInc As Int
        
    Dim a As Int
        
    Dim aInc As Int
        r=
    0
        c=
    0
      
        
    For i = 0 To ImgPanel.Length - 1
            
    Dim p As Panel
            p.Initialize(
    "ImgPanel")
            
    Activity.AddView(p, sx+(c*sxInc), a+(r*aInc), 130dip130dip'add the panel to the layout
      
            p.Tag=i
          
            ImgPanel(i)=p
          
            c=c+
    1
      
            
    If c>3 Then
                r=r+
    1
                c=
    0
            
    End If
        
    Next
    End Sub

    Sub ImgPanel_Click
        
    'Using Sender we find the panel that raised this event
        Dim p As Panel
        
    Dim Id As Int
      
        p = 
    Sender
        
    Id=p.Tag '**** HERE I RECEIVE THE ERROR: java.lang.RuntimeException: Object should first be initialized (Panel).
      
    End Sub
    Some suggest?

    Thanks in advance

    Lenny
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    Please start a new thread for this question.
     
  12. aarondc

    aarondc Member Licensed User

    Useful, thanks.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice