System: BeOS, Haiku, Zeta

To understand this tutorial you need to know and understand the first and second beginners tutorial.



Index

1. Prelog 6. The height score
2. The playing cards 7. The menu functions
3. The main structure 8. The complete source code
4. The playground 9. Epilogue
5. The game card functions 10. Download

 





1. We are create a game

In this Tutorial we will provide ourselves how to create a simple game. Here it goes not necessarily only around the game; we want to explain the complex structure behind a program like this. Naturally we will have an executable game at the end of this tutorial but we don’t add all aspects of ideas those are interesting of a game like this. Take it like a playground for your learning progress.

The Game is a conversion of the classic "Memory" game. Here it is valid to find all matching game cards, which lie covered before the player. The player search for pairs of game cards, if he found valid pairs they are get uncovered past this moment to the rest of the game. Only two cards may be uncovered at the same time. If the cards are not valid, they are covered again.

Before you are begin to write a game, you need to think over it exact. Simply to have the game before your eyes is not sufficient. Much dependence becomes only visible when trying out. Think about it is possible to create the game with the used programming language or about your knowledge of the programming language to do it. It often occurs that people discouraged and give up at the beginning.

Also this game, which we provided here for the Tutorial, get here exact range of the expirations developed only in the course of programming. This is a completely normal procedure, because you never know completely exactly what you must consider for a complex project like this. But we know that we can create a game like this with the language yab.

It is always helpful to paint the expirations as graphic, so you can control your development steps and status.

 

  • Representation of the program window with the game cards.
  • Selection of two game cards and its examination.
  • If the maps are identically these are permanently uncovered represented.
  • If the maps are differently these are again covered.
  • If all game cards are uncovered, the players information are queried.
  • The player data are stored.
  • Representation of the Hightscore.
  • If the User select the menu option "New Game", all stored information put back and the program window with the game cards displayed again.
  • If the User select the menu option "Hightscore" after the program starts the Hightscore will be represented.


If you look exactly, there is no option for calling the Hightscore from the Hightscore representation. This is for example one of the dependence, which were mentioned above. In addition this graphic does not contain information about further dependence like the numbers of play courses they are included into the Hightscore information.

But we don't want to discourage or deter you with these possibly arising problems, we only want to show you that to create a game is more complex as you think it.

back to Index

 




2. The Game cards

Before we begin to developing the game, we want to create the game cards. It is always easier to create the game cards first by a game like this, because we can not necessarily always hold our self the real size of these before eyes. It naturally also always depends thereby on the motives we want to use. If there is for example landscapes, which one would like to show on the game cards, these should be larger, so that these become effective also correctly.

To select the correct graphics for such a game is not simple, because we need for these Tutorial eight different motives. All this motives should be topic-referred. We cannot take simple any graphic we want, for example from the internet, because they can be copyrighted by anyone. Often these graphics are protected with water-marks, which cannot be seen without the right software.

In order to go such difficulties out of the way, we create our own graphics from our private photo albums. For the game cards we need two motives for each card. They are one for the front side and one for the back side. The front side should be for all the same motive, so the player does not find the correct motives too simple. We decided to take graphics of animals in a size of 100 pixels in the width and 100 pixels in the height:

    

 

 

 

 

We create a folder named gfx in the game folder for the graphics. Into this folder we put all play card graphics and number them from 0 to 8. Picture0 is the front side and Picture1 to Picture8 the back sides.

back to Index




3. The main scructure

We begin with the main structure of the game. The following source code includes some dark red informations in order to make it easier to include some source informations into t he program code during the tutorial. Comes, for example a request to include a case command, insert him past the entry //cases. This makes it easier for me to explain it your.

#!/boot/home/config/bin/yab

//get infos
D_Width = peek("desktopwidth")
D_Height = peek("desktopheight")

//yab info
if (peek("isbound")) then
   Programfolder$ = peek$("directory")
else
   Programfolder$=system$("pwd")
   Programfolder$ = left$(Programfolder$, len(Programfolder$)-1)
fi

//variable
Graphicfolder$=Programfolder$+"/gfx/"
clicks=0
gamecount=0
status=0

//program window

WINDOW OPEN D_Width/2-250,D_Height/2-250 to D_Width/2+250,D_Height/2+250, "Mainwindow", "Memory Game"
   WINDOW SET "Mainwindow", "Flags", "Not-Resizable,Not-Zoomable"
      MENU "File", "Quit", "Q", "Mainwindow"
      MENU "Game", "New Game", "N", "Mainwindow"
      MENU "Game", "Hightscore", "H", "Mainwindow"

//call function

//main loop
dim part$(1)
inloop = true
while(inloop)
   msg$ = message$
   if (split(msg$, part$(), ":|") > 2) then
      PartOne$=part$(1)
      PartTwo$ = part$(2)
      PartThree$ = part$(3)
   fi
   if (msg$ <> "") print msg$
   switch msg$

   //cases

   default:
   end switch
   if(window count<1) inloop = false
   sleep 0.1
wend

//sub routines


As you can see, contain this source nothing new, because the same we learned to know in the two beginners tutorials.

  • We get the size of the Desktop at the area //get infos (D_Width$ = Desktop width and D_Height = Desktop height).
  • In the area //yab info we check out the program is bound or not.
  • We define some variables at //variable for using in the application.
  • At //program window we create the main window with a width of 500 pixel and a height of 500 pixel. We use the screen informations we get at //get info and place the window in the middle of the screen. To get the middle of the window, we take the variable D_Width$ and D_Height, divide them by two. Then we take the half of the wanted window size and subtract them to the divided value for the left position of the window. We do the same for the right side, but we don't subtract the value, we add the value from the D_Width$. So we have, between the added and subtracted values, the wanted width of the window. We make the same with the D_Height, we adding and subtracting the half of the wanted window size to/from the D_Height (left side= middle of the screen -250 | middle of the screen +250 = right side).
  • We adding three menu options. These are closing the program ("Quit") at the menu area "File". Start a New Game at the menu area "Game" and the menu option "Hightscore" at the menu area "Game" too.
  • When we see the Mainloop with the split options to get program commands.

back to Index

 
4. The Playground

Since this is to become a simple game we use a simple method to display the game cards. The dimpliest method to display the game cards is to use the Button command.

Enter following Code at //sub routines:

sub Program_Window()
   View$="GameTable"
   VIEW 0,15 TO 500, 495, "GameTable", "Mainwindow"
   VIEW 10,10 TO 120,120, "Button1", "GameTable"
   BUTTON IMAGE 5,5, "B_1", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button1"
   VIEW 130,10 TO 240,120, "Button2", "GameTable"
   BUTTON IMAGE 5,5, "B_2", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button2"
   VIEW 250,10 TO 360,120, "Button3", "GameTable"
   BUTTON IMAGE 5,5, "B_3", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button3"
   VIEW 370,10 TO 480,120, "Button4", "GameTable"
   BUTTON IMAGE 5,5, "B_4", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button4"
   VIEW 10,130 TO 120,240, "Button5", "GameTable"
   BUTTON IMAGE 5,5, "B_5", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button5"
   VIEW 130,130 TO 240,240, "Button6", "GameTable"
   BUTTON IMAGE 5,5, "B_6", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button6"
   VIEW 250,130 TO 360,240, "Button7", "GameTable"
   BUTTON IMAGE 5,5, "B_7", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button7"
   VIEW 370,130 TO 480,240, "Button8", "GameTable"
   BUTTON IMAGE 5,5, "B_8", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button8"
   VIEW 10,250 TO 120,360, "Button9", "GameTable"
   BUTTON IMAGE 5,5, "B_9", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button9"
   VIEW 130,250 TO 240,360, "Button10", "GameTable"
   BUTTON IMAGE 5,5, "B_10", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button10"
   VIEW 250,250 TO 360,360, "Button11", "GameTable"
   BUTTON IMAGE 5,5, "B_11", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button11"
   VIEW 370,250 TO 480,360, "Button12", "GameTable"
   BUTTON IMAGE 5,5, "B_12", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button12"
   VIEW 10,370 TO 120,480, "Button13", "GameTable"
   BUTTON IMAGE 5,5, "B_13", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button13"
   VIEW 130,370 TO 240,480, "Button14", "GameTable"
   BUTTON IMAGE 5,5, "B_14", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button14"
   VIEW 250,370 TO 360,480, "Button15", "GameTable"
   BUTTON IMAGE 5,5, "B_15", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button15"
   VIEW 370,370 TO 480,480, "Button16", "GameTable"
   BUTTON IMAGE 5,5, "B_16", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button16"
end sub
  • We create a variable View$ and save the name of the view into it ("GameTable")). I will explain more about it later.
  • We create a view named "GameTable" and place it on the main window.
  • On the view "GameTable" we create more views. For every game card one view. We use for this tutorial 2 x 8 game cards with a size of 100 x 100 pixels. We create all view 10 pixels bigger as the size of the game cards, because it looks better if we have some free space between the cards.
  • We create into every Views for the game cards an Image Button. Every Button gets the same graphic for the two display options. Why we use the same graphic for booth options? We use it, because it is the best way to display the game card without any display problems at pressing the button. We used before two graphics, the graphic for the covered and the graphic for the uncovered view. Every time we press on one of the buttons, the covered graphic switched to the uncovered graphic and back. So we get a bad effect, the uncovered graphic displayed every time two times before you see the uncovered card.


To display the playground we call at //call function the subroutine for it. Enter at this position the name of the subroutine Program_Window().

back to Index



5. The game card functions

Now next we come to the really interesting part of the game process. Here we need to compare the two game cards and determine needed informations for it. We need several informations, the name of the Views and the buttons, the position of the views and the number of the respective graphic.

Enter following code at //cases:

case "B_1|"
   BuView$="Button1"
   Button$="B_1"
   horizontal1=10
   vertical1=10
   horizontal2=120
   vertical2=120
   PictureNr=1
   PicSelection()
break
  • BuView$="Button1": n this variable we have the name of the Button View.
  • Button$="B_1": In this variable we have the name of the Button.
  • horizontal1=10: In horizontal1 we have the left position of the Button on the view.
  • horizontal2=120: In horizontal2 we have the right position of the Button on the view.
  • vertical1=10: In vertical1 we have the upper position of the Button on the view.
  • vertical2=120: In vertical2 we have the bottum position of the Button on the view.
  • PictureNr=1: We save into PictureNr the number of the graphic (Picture1 - Picture8)
  • PicSelection(): At the end of this code we call the sub routine PicSelection(). Here we work on the selected informations.

This is the first of sixteen Buttons, so we need to do the same for the other fifteen buttons. Get the needed informations from the playground (horizontal and vertical position, name of the view and Buttons, number of the picture).

We come now to the subroutine. Add following code at //sub routines:

 

sub PicSelection()
   VIEW REMOVE BuView$
   VIEW horizontal1,vertical1 TO horizontal2,vertical2, BuView$, "GameTable"
   err = DRAW IMAGE 5,5 TO 105,105, Graphicfolder$+"picture"+str$(PictureNr)+".png", BuView$
   clicks=clicks+1
   if(clicks=1)then
      Card1$="picture"+str$(PictureNr)+".png"
      Card_Button1$=Button$
      Card_horizontal1=horizontal1
      Card_vertical1=vertical1
      Card_horizontal2=horizontal2
      Card_vertical2=vertical2
      CardView1$=BuView$
   elseif(clicks=2)then
      Card2$="picture"+str$(PictureNr)+".png"
      Card_Button2$=Button$
      Card_horizontal3=horizontal1
      Card_vertical3=vertical1
      Card_horizontal4=horizontal2
      Card_vertical4=vertical2
      CardView2$=BuView$
   fi
   if(clicks=2)then
      if(Card1$=Card2$)then
         status=status+1
         gamecourse=gamecourse+1
         if(status=8)then
            window open D_Width/2-120,D_Height/2-70 to D_Width/2+120,D_Height/2+70, "Status", "Won"
            WINDOW SET "Status", "Look", "Modal"
            WINDOW SET "Status", "Flags", "Not-Resizable,Not-Zoomable"
            DRAW SET "system-bold", "Status"
            DRAW TEXT 10,15, "You have Won!!!", "Status"
            DRAW SET "system-plain", "Status"
            DRAW TEXT 10,45, "Rounds: "+str$(gamecourse), "Status"
            TEXTCONTROL 10,50 TO 230,40, "Player_Name", "Enter Name:", "", "Status"
            BUTTON 60,100 TO 180,110, "Save", "Save", "Status"
         fi
      else
         gamecourse=gamecourse+1
         wait 0.5
         VIEW REMOVE CardView1$
         VIEW REMOVE CardView2$
         VIEW Card_horizontal1,Card_vertical1 TO Card_horizontal2,Card_vertical2, CardView1$, "GameTable"
         BUTTON IMAGE 5,5, Card_Button1$, Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, CardView1$
         VIEW Card_horizontal3,Card_vertical3 TO Card_horizontal4,Card_vertical4, CardView2$, "GameTable"
         BUTTON IMAGE 5,5, Card_Button2$, Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, CardView2$
      fi
      clicks=0
   fi
end sub


We work on the information we defined at the buttons. We use at all button the same variable names so we can use these together also for all. Using this saves many lines of code, so the source will be more clearly. Try always to work like this.

  • We remove with VIEW REMOVE BuView$ the view with the selected button.
  • We recreate the VIEW... at the same position. He gets, using the define variables, the same names and position informations like the view we have removed.
  • When we draw with err = DRAW IMAGE...the graphic which indicated behind the button at the view. We use the before defined variables also at Graphicfolder$+"picture"+str$(PictureNr)+".png". This defines the target graphic with his file path and number. The name of the graphic builds itself up by ""picture" and the "PictureNr" together. Since "PictureNr" is a number variable we don't can add them to a text variable. Here we use the String str$(). o convert the number variable into a text variable output. At the end we add the suffix of the graphic file (.png).
  • With clicks=clicks+1 we counting the number of clicks on the buttons by the player. This is important, because so we get only the information then the player click on the second game card. If he has clicked on the second game card, we need to compare the graphic files behind this two buttons.
  • With the IF-Querie if(clicks=1)then we check the number variable "clicks". If the value of the number variable is 1 yab starts up the code between "if" and "else". Here we define some variables.
    -In Card1$ we save the path and name of the graphic file behind the first selected button.
    -In Card_Button1$ we save the name of the button the player select first.
    -With Card_horizontal1, Card_vertical1 und Card_horizontal2, Card_vertical2 we save the position of the button, later the game card.
    -In CardView1$ we save the name of the view there the first selected button placed.
  • With the ELSEIF Querie elseif(clicks=2)then we adding into the if querie an other possible command. If the value of the number variable is 2 yab saves likes the value 1, but this time we save the informations of the second selected button.
  • The IF Querie will be end at fi (you can use endif also).


We use the IF Querie to get all needed informations to compare the two selected game cards. The following If Querie is to decide the next step. If are the game cards identically they will be viewable for the rest of the game. If they are not identically the graphics will be covered again.

  • The IF Querie will be activate then the variable clicks have the value 2 (if(clicks=2)then).
  • Into this IF Querie begins a second IF Querie: if(clicks=2)then. Here we compare the two card variables. If the variable clicks are identically to 2, this code will be active.
  • If the player finds a compatible card pair the number variable statuswill be increased by one status=status+1.
  • With the number variable gamecourse=gamecourse+1 we count the numbers of game courses (we need it for the Hightscore).
  • The followingIF Querie check the number variable status. Is the value of this variable 8 if(status=8)then the player have found all card pairs and won the game. Into this if querie we open a new window. Into this window the player can enter his name fort he height score. We close this if querie also with fi. More about the height sore later.
  • But back to the if querie if(Card1$=Card2$)then. If the information of the text variable card1$ is not the same as card2$ the else command will be activated.
  • If else is activated the game course will be count too. The views of the two selected buttons will be closed and rebuild. On these views we recreate the two buttons with the covered game card view.
  • We have never more then two clicks, so we change the value of the number variable clicks to 0 (clicks=0).
  • Also this IF Querie if(clicks=2)then will be ended with fi.
  • Finaly we close the subroutine with end sub.

Back to Index

6. The Hightscore

We come back to that briefly addressed IF Querie at The game card functions. Here starts the querie then the number variable status has the value 8:

if(status=8)then
   window open D_Width/2-120,D_Height/2-70 to D_Width/2+120,D_Height/2+70, "Status", "Won"
   WINDOW SET "Status", "Look", "Modal"
   WINDOW SET "Status", "Flags", "Not-Resizable,Not-Zoomable"
   DRAW SET "system-bold", "Status"
   DRAW TEXT 10,15, "You have won!!!", "Status"
   DRAW SET "system-plain", "Status"
   DRAW TEXT 10,45, "Rounds: "+str$(gamecourse), "Status"
   TEXTCONTROL 10,50 TO 230,40, "Player_Name", "Enter Name:", "", "Status"
   BUTTON 60,100 TO 180,110, "Save", "Save", "Status"
fi


If this is the case, a new window in the middle of the screen is opened. Here again the two variables (D_Width and D_Height) are used for the window position. On this view we draw a text and add a Textcontrol and a Button. Here the player is requested to enter his name into the Textcontrol in order to save it using the Save button into the height score. You know this from the beginners tutorial.

To make the button useable, add following code at //cases:

case "Save|"
   Player_Name$ = TEXTCONTROL GET$ "Player_Name"
   write=open(Programfolder$+"/Hightscore.data", "a")
      print #anlegen str$(gamecource)+";"+Player_Name$
   close(write)
   Output$=System$("sort -g "+Programfolder$+"/Hightscore.data > "+Programfolder$+"/Hightscore.temp")
   Output$=System$("rm "+Programfolder$+"/Hightscore.data")
   Output$=system$("cp "+Programfolder$+"/Hightscore.temp "+Programfolder$+"/Hightscore.data")
   Output$=System$("rm "+Programfolder$+"/Hightscore.temp")
   WINDOW CLOSE "Status"
   VIEW REMOVE "GameTable"
   Hightscore()
break
  • With Player_Name$ = TEXTCONTROL GET$ "Player_Name" lwe read out the textcontrol Player Name nd save them into the variable Player_Name$.
  • We open with write=open(Programfolder$+"/Hightscore.data", "a") a text file in order to write informations into it. If the text does not exists this command will create it. The file named Hightscore.data placed into the program folder stored into the variable Programfolder$ of the game. The a is a command to write into a file without creating a new file (only it does not exists. The name of the number variable write can be selected freely; it is not a system variable.
  • We write with print #write str$(gamecource)+";"+Player_Name$ the informations of the two variables into the file Hightscore.data. To do that we need to convert the number variable into a text variable (Here we use the String str$() again). We write an ";" sign between the two values of the variables in order to use it for splitting later.
  • We close with close(write) the saving progress.

If you stores the data by this way, all saved informations of the players will be back added. But we want to store all saved data in alphabetical order. One of the simplest methods to make this is to use the Shell command sort.

  • The sort Command needs following informations: sort -g /Path/to/SourceFile > /Path/to/TargetFile
  • We use for the "/Path/to/SourceFile" the varialbe Programfolder$ ("/Path/to/programfolder"). We add on this variable the Hightscore.data file we create at finishing the game: Programfolder$+"/Hightscore.data".
    Then we add the sign for export file of the sort Command: "≶" and the path to the export file Hightscore.temp.
    After this we use the Shell command rm (remove) and remove with him the Hightscore.data file: "rm /Path/to/Target file".
    Then we copy the "Hightscore.temp" file with the Shell command cp (copy) as "Hightscore.data" file to the program folder: "cp /Path/to/SourceFile /Path/to/TargetFile".
    Finally we remove the "Hightscore.temp" file using the rm command again.
  • Then we close the "Status" window and remove the "GameTable" view.
  • After this we call the sub routine Hightscore(). Add following code at the area //sub routines:
sub Hightscore()
   View$="Hightscore"
   MENU SET "Game", "Hightscore", "Disable", "Mainwindow"
   VIEW 0,15 TO 500, 495, "Hightscore", "Mainwindow"
   DRAW SET "system-bold", "Hightscore"
   DRAW TEXT 20,50, "Hightscore", "Hightscore"
   DRAW SET "system-plain", "Hightscore"
   Spielstaende$=Programfolder$+"/Hightscore.data"
   x=0
   auslesen=open(Spielstaende$, "r")
   while (not EOF(auslesen))
      line input #auslesen b$
      dim elements$(1)
      numElements = split(b$, elements$(), ";")
      for i = 1 to numElements
         x=x+1
         dim d$(x)
         d$(x) = elements$(i)
      next i
   wend
   close(auslesen)
   height=100
   aa=1
   for a = 1 to x/2
      DRAW TEXT 20,height, d$(aa), "Hightscore"
      aa=aa+2
      height=height+20
   next a
   height=100
   bb=2
   for b = 1 to x/2
      DRAW TEXT 120,height, d$(bb), "Hightscore"
      bb=bb+2
   height=height+20
   next b
end sub
  •  We save again the name of the used view in the varialbe View$ (View$="Hightscore").
  • With MENU SET "Game", "Hightscore", "Disable", "Mainwindow" we deactivate the menu option"Hightscore". This is useful, because we are already in the hight score.
  • We create a new view with the name "Highscore" on the "Mainwindow". We want to display the informations of the Highscore on this View with the command DRAW TEXT. We use the text format "bold" to show special parts of the High score as bold. To do this we need to activate the text format using the DRAW TEXT command and write the text with DRAW TEXT. The DRAW TEXT command is so long activated past you change it again. We change the text format for the Heading to "system-bold" and then we change the text format back to "system-plain".
  • We create a variable Gamecources$=Programfolder$+"/Hightscore.data" and save into it the path to the Hightscore.data file: Gamescores$=Programfolder$+"/Hightscore.data". This makes it easier to use these informations, because we only need to call the variable.
  • We set in the following expiration a number variable to 0 (x=0). We make this, so that with the repetitive call of the High score no wrong values are used.
  • Similarly as with writing a file we read a file into the system. We do this with readout=open(Gamecources$, "r"). The name of the number varialbe "readout" is not a system variable, so you can name it as you like.
  • We start a WHILE loop which runs so long we read out the file stored into the variable Gamescores$. Therefore is in while (not EOF(readout)) the EOF() added (EOF knows "End of File").
  • Every time the loop turns, we save with the actual line of the file into the variable b$.
  • We create an Array, because we don’t can save more then one line into a variable. We do this with dim elements$(1).
  • Then we split the variable b$ at every ; sign and add every spitted line into the Array elements$(): (numElements = split(b$, elements$(), ";")). With numElements we count the number of lines of the Array.
  • When we call a FOR loop with for i = 1 to numElements. This loops runs so long the value of iis the same as the value of numElemtens.
  • Every time the for loop turns we count the number of turns with x=x+1.
  • We create a second Array named d$ and dimension it with the number variable x (dim d$(x)). You can surely select a more meaningful name for this Array but when you program longer time you will take often short names.
  • With d$(x) = elements$(i) we add the contents of the Array elements$(i) into the Arrays d$(x).
  • If next i s called the loop of the for loop turns back to the beginning.
  • The WHILEloop turns back with wend.
  • We close the read out process withclose(readout).

The first step is done for representing the Hightscore. Subsequently we need to display the content of the Array elements$() on the View "Hightscore" to represent. The most important informations we need for this are the position of the text on the view. Here you need to try out the right position before you find the best look for the text:

  • With height=100 we setup the height of the first line.
  • With a new number variable named aa (yes I know it is not a creative name) with a size of 1 (aa=1) we count the number of added lines. Here we only want to use the oddly numbers.
  • We use a FOR loop to add the informations (for a = 1 to x/2). To do this we create a number variable a and runs the loop so long the value of a is the same as the number of value x divided through 2.
  • We write the content of the Arrays d$() with the command DRAW TEXT 20,height, d$(aa), "Hightscore" . Here we set up the left position of the text on the view to 20 and the horizontal position with height. We take the text out of the Array d$(aa). To get the right line of the Array we use the number variable aa.
  • We want to write the height score values first, so we need to take every second entry of the Array. We need to do this because the entry of the Array looks like this: Value:Player name. We do this with aa=aa+2.
  • Also the height must be extended automatically otherwise the numbers stand one above the other. Therefore we increase the height by 20 pixels (height=height+20).
  • With next a we turn back the loop.
  • Now we need to write the value of the number variable height back to 100 again in order to get the same horizontal position fort he height score values.
  • We create a new number variable named bb (This is not a creative name too) with a size of 2 (bb=2). This time we need only the straight numbers.
  • We use again a FOR loop to write the informations (for b = 2 to x/2). We create a number variable b and runs the loop so long the value of b is the same as x divided through 2.
  • We write again the content of the Arrays d$() with the command DRAW TEXT 20,height, d$(bb), "Hightscore" on the View "Heightscore". This time we set up the left position of the text on the view to 120 and the horizontal position with height. We take the text out of the Array d$(bb). To get the right line of the Array we use the number variable bb
  • Here we need to take every second entry of the Array again. This time we want to write the name of the Players. We do this with bb=bb+2.
  • We need to extend the height of the text automatically again. We increase the height by 20 pixels again: (height=height+20).
  • With next b we turn back the loop.
  • We close the sub routine with end sub.


Back to Index

 

7. Menu options

Now we want to make the menu options executable. Add following code at the area //cases:

case "Mainwindow:Game:Hightscore|"
   VIEW REMOVE "GameTable"
   Hightscore()
break

case "Mainwindow:Game:New Game|"
   MENU SET "Game", "Hightscore", "Enable", "Mainwindow"
   VIEW REMOVE View$
   clicks=0
   gamecource=0
   status=0
   Program_Window()
break

We have two Cases. Where are an option to call the Heightscore and another one to start a new game.

  • To open the height score is easy. We only need to remove the actual view with VIEW REMOVE "GameTable". Then we call the Subroutine Hightscore().


Then the player select the option for a new game we need to put back some number variables and activating the inactive menu options:

  • We activate the menu option Heightscore using the command MENU SET "Game", "Hightscore", "Enable", "Mainwindow".
  • Then we need to put back all number variables we need for the game play. These are the clicks, the font color="darkblue">gamecourses

and the status.

  •  At the end we call the Subroutine Program_Window().

Back to Index


8. The complete Sourcecode

#!/boot/home/config/bin/yab

D_Width = peek("desktopwidth")
D_Height = peek("desktopheight")

if (peek("isbound")) then
   Programfolder$ = peek$("directory")
else
   Programfolder$=system$("pwd")
   Programfolder$ = left$(Programfolder$, len(Programfolder$)-1)
fi

Graphicfolder$=Programfolder$+"/gfx/"

clicks=0
Gamecourse=0
status=0

WINDOW OPEN D_Width/2-250,D_Height/2-250 to D_Width/2+250,D_Height/2+250, "Mainwindow", "Memory Game"
   WINDOW SET "Mainwindow", "Flags", "Not-Resizable,Not-Zoomable"
      MENU "File", "Quit", "Q", "Mainwindow"
      MENU "Game", "New Game", "N", "Mainwindow"
      MENU "Game", "Hightscore", "H", "Mainwindow"

Program_Window()

dim part$(1)
inloop = true
while(inloop)
   msg$ = message$
   if (split(msg$, part$(), ":|") > 2) then
      PartOne$=part$(1)
      PartTwo$ = part$(2)
      PartThree$ = part$(3)
   fi
   if (msg$ <> "") print msg$
   switch msg$

case "Mainwindow:File:Quit|"
   WINDOW CLOSE "Mainwindow"
break

case "Mainwindow:_QuitRequested|"
   WINDOW CLOSE "Mainwindow"
break

case "B_1|"
   BuView$="Button1"
   Button$="B_1"
   horizontal1=10
   vertical1=10
   horizontal2=120
   vertical2=120
   PictureNr=1
   PictureSelected()
break
case "B_2|"
   BuView$="Button2"
   Button$="B_2"
   horizontal1=130
   vertical1=10
   horizontal2=240
   vertical2=120
   PictureNr=2
   PictureSelected()
break
case "B_3|"
   BuView$="Button3"
   Button$="B_3"
   horizontal1=250
   vertical1=10
   horizontal2=360
   vertical2=120
   PictureNr=3
   PictureSelected()
break
case "B_4|"
   BuView$="Button4"
   Button$="B_4"
   horizontal1=370
   vertical1=10
   horizontal2=480
   vertical2=120
   PictureNr=4
   PictureSelected()
break
case "B_5|"
   BuView$="Button5"
   Button$="B_5"
   horizontal1=10
   vertical1=130
   horizontal2=120
   vertical2=240
   PictureNr=5
   PictureSelected()
break
case "B_6|"
   BuView$="Button6"
   Button$="B_6"
   horizontal1=130
   vertical1=130
   horizontal2=240
   vertical2=240
   PictureNr=6
   PictureSelected()
break
case "B_7|"
   BuView$="Button7"
   Button$="B_7"
   horizontal1=250
   vertical1=130
   horizontal2=360
   vertical2=240
   PictureNr=7
   PictureSelected()
break
case "B_8|"
   BuView$="Button8"
   Button$="B_8"
   horizontal1=370
   vertical1=130
   horizontal2=480
   vertical2=240
   PictureNr=8
   PictureSelected()
break
case "B_9|"
   BuView$="Button9"
   Button$="B_9"
   horizontal1=10
   vertical1=250
   horizontal2=120
   vertical2=360
   PictureNr=8
   PictureSelected()
break
case "B_10|"
   BuView$="Button10"
   Button$="B_10"
   horizontal1=130
   vertical1=250
   horizontal2=240
   vertical2=360
   PictureNr=7
   PictureSelected()
break
case "B_11|"
   BuView$="Button11"
   Button$="B_11"
   horizontal1=250
   vertical1=250
   horizontal2=360
   vertical2=360
   PictureNr=6
   PictureSelected()
break
case "B_12|"
   BuView$="Button12"
   Button$="B_12"
   horizontal1=370
   vertical1=250
   horizontal2=480
   vertical2=360
   PictureNr=5
   PictureSelected()
break
case "B_13|"
   BuView$="Button13"
   Button$="B_13"
   horizontal1=10
   vertical1=370
   horizontal2=120
   vertical2=480
   PictureNr=4
   PictureSelected()
break
case "B_14|"
   BuView$="Button14"
   Button$="B_14"
   horizontal1=130
   vertical1=370
   horizontal2=240
   vertical2=480
   PictureNr=3
   PictureSelected()
break
case "B_15|"
   BuView$="Button15"
   Button$="B_15"
   horizontal1=250
   vertical1=370
   horizontal2=360
   vertical2=480
   PictureNr=2
   PictureSelected()
break
case "B_16|"
   BuView$="Button16"
   Button$="B_16"
   horizontal1=370
   vertical1=370
   horizontal2=480
   vertical2=480
   PictureNr=1
   PictureSelected()
break

case "Save|"
   Player_Name$ = TEXTCONTROL GET$ "Player_Name"
   anlegen=open(Programfolder$+"/Hightscore.data", "a")
      print #anlegen str$(Gamecourse)+";"+Player_Name$
   close(anlegen)
   Output$=System$("sort -g "+Programfolder$+"/Hightscore.data > "+Programfolder$+"/Hightscore.temp")
   Output$=System$("rm "+Programfolder$+"/Hightscore.data")
   Output$=system$("cp "+Programfolder$+"/Hightscore.temp "+Programfolder$+"/Hightscore.data")
   Output$=System$("rm "+Programfolder$+"/Hightscore.temp")
   WINDOW CLOSE "Status"
   VIEW REMOVE "GameTable"
   Hightscore()
break

case "Mainwindow:Game:Hightscore|"
   VIEW REMOVE "GameTable"
   Hightscore()
break

case "Mainwindow:Game:New Game|"
   MENU SET "Game", "Hightscore", "Enable", "Mainwindow"
   VIEW REMOVE View$
   clicks=0
   Gamecourse=0
   status=0
   Program_Window()
break

   default:
   end switch
   if(window count<1) inloop = false
   sleep 0.1
wend

sub Program_Window()
   View$="GameTable"
   VIEW 0,15 TO 500, 495, "GameTable", "Mainwindow"
   VIEW 10,10 TO 120,120, "Button1", "GameTable"
   BUTTON IMAGE 5,5, "B_1", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button1"
   VIEW 130,10 TO 240,120, "Button2", "GameTable"
   BUTTON IMAGE 5,5, "B_2", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button2"
   VIEW 250,10 TO 360,120, "Button3", "GameTable"
   BUTTON IMAGE 5,5, "B_3", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button3"
   VIEW 370,10 TO 480,120, "Button4", "GameTable"
   BUTTON IMAGE 5,5, "B_4", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button4"
   VIEW 10,130 TO 120,240, "Button5", "GameTable"
   BUTTON IMAGE 5,5, "B_5", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button5"
   VIEW 130,130 TO 240,240, "Button6", "GameTable"
   BUTTON IMAGE 5,5, "B_6", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button6"
   VIEW 250,130 TO 360,240, "Button7", "GameTable"
   BUTTON IMAGE 5,5, "B_7", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button7"
   VIEW 370,130 TO 480,240, "Button8", "GameTable"
   BUTTON IMAGE 5,5, "B_8", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button8"
   VIEW 10,250 TO 120,360, "Button9", "GameTable"
   BUTTON IMAGE 5,5, "B_9", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button9"
   VIEW 130,250 TO 240,360, "Button10", "GameTable"
   BUTTON IMAGE 5,5, "B_10", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button10"
   VIEW 250,250 TO 360,360, "Button11", "GameTable"
   BUTTON IMAGE 5,5, "B_11", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button11"
   VIEW 370,250 TO 480,360, "Button12", "GameTable"
   BUTTON IMAGE 5,5, "B_12", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button12"
   VIEW 10,370 TO 120,480, "Button13", "GameTable"
   BUTTON IMAGE 5,5, "B_13", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button13"
   VIEW 130,370 TO 240,480, "Button14", "GameTable"
   BUTTON IMAGE 5,5, "B_14", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button14"
   VIEW 250,370 TO 360,480, "Button15", "GameTable"
   BUTTON IMAGE 5,5, "B_15", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button15"
   VIEW 370,370 TO 480,480, "Button16", "GameTable"
   BUTTON IMAGE 5,5, "B_16", Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, "Button16"
end sub

sub PictureSelected()
   VIEW REMOVE BuView$
   VIEW horizontal1,vertical1 TO horizontal2,vertical2, BuView$, "GameTable"
   err = DRAW IMAGE 5,5 TO 105,105, Graphicfolder$+"picture"+str$(PictureNr)+".png", BuView$
   clicks=clicks+1
   if(clicks=1)then
      Card1$="picture"+str$(PictureNr)+".png"
      Card_Button1$=Button$
      Card_horizontal1=horizontal1
      Card_vertical1=vertical1
      Card_horizontal2=horizontal2
      Card_vertical2=vertical2
      CardView1$=BuView$
   elseif(clicks=2)then
      Card2$="picture"+str$(PictureNr)+".png"
      Card_Button2$=Button$
      Card_horizontal3=horizontal1
      Card_vertical3=vertical1
      Card_horizontal4=horizontal2
      Card_vertical4=vertical2
      CardView2$=BuView$
   fi
   if(clicks=2)then
      if(Card1$=Card2$)then
         status=status+1
         gamecourse=gamecourse+1
         if(status=8)then
            window open D_Width/2-120,D_Height/2-70 to D_Width/2+120,D_Height/2+70, "Status", "Won"
            WINDOW SET "Status", "Look", "Modal"
            WINDOW SET "Status", "Flags", "Not-Resizable,Not-Zoomable"
            DRAW SET "system-bold", "Status"
            DRAW TEXT 10,15, "You have Won!!!", "Status"
            DRAW SET "system-plain", "Status"
            DRAW TEXT 10,45, "Rounds: "+str$(Gamecourse), "Status"
            TEXTCONTROL 10,50 TO 230,40, "Player_Name", "Enter Name:", "", "Status"
            BUTTON 60,100 TO 180,110, "Save", "Save", "Status"
         fi
      else
         Gamecourse=Gamecourse+1
         wait 0.5
         VIEW REMOVE CardView1$
         VIEW REMOVE CardView2$
         VIEW Card_horizontal1,Card_vertical1 TO Card_horizontal2,Card_vertical2, CardView1$, "GameTable"
         BUTTON IMAGE 5,5, Card_Button1$, Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, CardView1$
         VIEW Card_horizontal3,Card_vertical3 TO Card_horizontal4,Card_vertical4, CardView2$, "GameTable"
         BUTTON IMAGE 5,5, Card_Button2$, Graphicfolder$+"picture0.png", Graphicfolder$+"picture0.png", Disabled$, CardView2$
      fi
      clicks=0
   fi
end sub

sub Hightscore()
   View$="Hightscore"
   MENU SET "Game", "Hightscore", "Disable", "Mainwindow"
   VIEW 0,15 TO 500, 495, "Hightscore", "Mainwindow"
   DRAW SET "system-bold", "Hightscore"
   DRAW TEXT 20,50, "Hightscore", "Hightscore"
   DRAW SET "system-plain", "Hightscore"
   Spielstaende$=Programfolder$+"/Hightscore.data"
   x=0
   auslesen=open(Spielstaende$, "r")
   while (not EOF(auslesen))
      line input #auslesen b$
      dim elements$(1)
      numElements = split(b$, elements$(), ";")
      for i = 1 to numElements
         x=x+1
         dim d$(x)
         d$(x) = elements$(i)
      next i
   wend
   close(auslesen)
   height=100
   aa=1
   for a = 1 to x/2
      DRAW TEXT 20,height, d$(aa), "Hightscore"
      aa=aa+2
      height=height+20
   next a
   height=100
   bb=2
   for b = 1 to x/2
      DRAW TEXT 120,height, d$(bb), "Hightscore"
      bb=bb+2
   height=height+20
   next b
end sub

Back to Index


9. Epilog

Now we have an completely functioning MEMORY game. But we have a big failure into this game. It is not a failure that makes the game not playable but something you can make better.

The game card displayed covered but they are every time on the same place. Here the game needs a random function to place the covered graphics every time the game starts on another position.

How to do this is not part of this tutorial. I don’t plan an extension of this tutorial at the moment.

Back to Index



10. Download

Here you can download the game in compiled version..

Back to Index


 

Translation by Christian Albrecht (Lelldorin) April 2009
Tutorial by Christian Albrecht (Lelldorin) December 2007
Made available by BeSly, the BeOS, Haiku and Zeta knowledge base.