Contents
Articles
Behaviors
Books
Director News
Director Web Sites
FAQ
Games
Mailing Lists
News Groups
Project Examples
Reviews
Software
Tools
Useful Web Sites
Utilities
Xtras

Don't miss these
Imaging Lingo Basics
Prompt for Disk
Follow me
Indeo 5 Codec
TCP UDP Xtra
Spam and Faoul language filter for shockwave
Copy and Paste inside editable fields
Merge sort and Binary Search using Lingo
Saving Global Variables to a File
ShapeWindow Xtra
 

 

 

FAQ Tracking save attempts

Added on 4/3/2001

 

Compatibilities:

This item has not yet been rated

Author: DejanCicic

How can I track number of attempts and save game positions on users hard disk?

How can I track number of attempts and save game positions on users hard disk?

In case you need to save game position on user hard disk, the best way to track game states is to use lists. In my example (which you can modify very easy for your needs) there are 9 backgrounds (rooms) with 6 games on each. Each room have 6 button links to 6 games (tasks). Each game you can play only 3 times. After that, if game is not succesfully solved, button disapiers from room (off stage) and you can not try that game until you start game again.
The easiest way is to have list with 9 sublist, with 6 elements in each. Like this:
set CurrentList=[[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0],
[0,0,0,0,0,0]]

I used following notation to track game state:
I will write numbers in their positions-
1 – first try
2 –second try
3 – third try not solved
4 – game successfully solved

So, if you have sublist like this [0,1,2,3,1,0], 1 on second position means that second game you played once and you have 2 more tries, 3 on fourth pos means that you tried all three times and button link should be taken off from stage.

Main list which keeps track score and user name should look like this:
set mainList=[["dejan",CurrentList,0]]
MainList we will use only when we want to write new data on disk.


Each button to call games should have next behavior attached:

--*********************************************
--BUTTON CONTROL BEHAVIOR
--*********************************************
--gets values from main list and keeps track for number of tryings

property OffStage
property mySprite,myLocH
global currentlist
property gameNumber
property MyBackground

on beginsprite me
set offStage=-900
mySprite=sprite(the spriteNum of me)
myLocH=sprite(mySprite).locH
end

on exitframe me
--taking sublist
TryList=currentList[MyBackground]
--taking game state from sublist
TryNumber=TryList[gameNumber]

--action depends on game state, if try number is 3,4 or 5 ---button goes off stage
if tryNumber=3 or tryNumber=4 or tryNumber=5 then
sprite(mySprite).locH=offStage
else
sprite(mySprite).locH= myLocH
end if
end

on ShowMe me
sprite(mySprite).locH=myLocH
end
on hideMe me
sprite(mySprite).locH=offStage
end

on getPropertyDescriptionList
set description = [:]
addProp description,#myBackground,
[#default:1, #format:#integer, #comment:"Background Number:",#range:[#min:1,#max:9]]
addProp description,#gameNumber,
[#default:1, #format:#integer, #comment:"Game Number:",#range:[#min:1,#max:15]]
return description
end

This behavior keeps track of number of trying and if finds number 3,4 or 5 in some game position, button take himself off stage.

You need two more behaviors which should be applied inside each game, in gameWin frame and gameLoose frame. So, each game should have two ends, one for showing win message and there you can apply gameWin behavior, and one for “sorry you loose” message, where you will apply gameLoose behavior.
Here is gameWin behavior:
--*************************
--gameWin beahavior
--************************
property mySprite
global currentlist
global currentscore
property gameNumber
property MyBackground
PROPERTY MyPoints
on beginsprite me
mySprite=sprite(the spriteNum of me)
--geting trynumber from list
TryNumber=getat(getAt(currentList,myBackground),gameNumber)
case tryNumber of
0:
--if first try we will write back 4 and get maximum points
setat(currentList[myBackground],gameNumber,4)

1:
--we solve the game in second try and we will write
--back 4, and get few points less
setat(currentList[myBackground],gameNumber,4)
if mypoints=10 then
myPoints=myPoints-5
else
myPoints=myPoints-10
end if
2:
--we solve the game in second try and we will write
--back 4, and get more points less

setat(currentList[myBackground],gameNumber,4)
if mypoints=10 then
myPoints=myPoints-8
else
myPoints=myPoints-20
end if
end case

set the text of member "MainScore" to string(myPoints)
--updating global currentscore
set currentscore=currentscore+myPoints
end
on getPropertyDescriptionList
set description = [:]
addProp description,#myBackground,
[#default:1, #format:#integer, #comment:"Background Number:",#range:[#min:1,#max:9]]
addProp description,#gameNumber,
[#default:1, #format:#integer, #comment:"Game Number:",#range:[#min:1,#max:15]]
addProp description,#MyPoints,
[#default:30, #format:#integer, #comment:"Number of Points:",#range:[#min:1,#max:100]]
return description
end
This behavior updates TryNumbers and writes back 4 at the same place in list. When Button behavior reads 4 from any place, he forces button off stage.
WinLoose behavior does not deal with points, and just update TryNumbers and if TryNumber is less then 3 it increments tryNumber by 1. If this was the 3rd attempt it writes back 4 and button will be taken off stage.

--*******************
--gameLoose behavior

--*******************

--gets values from main list and keeps track for number of tryings

property mySprite
global currentlist
property gameNumber
property MyBackground
on beginsprite me
mySprite=sprite(the spriteNum of me)
sendAllSprites(#TimeElapsed,0)
TryNumber=getat(getAt(currentList,myBackground),gameNumber)
TryNumber= TryNumber+1
setat(currentList[myBackground],gameNumber,tryNumber)
end
on getPropertyDescriptionList
set description = [:]
addProp description,#myBackground,
[#default:1, #format:#integer, #comment:"Background Number:",#range:[#min:1,#max:9]]
addProp description,#gameNumber,
[#default:1, #format:#integer, #comment:"Game Number:",#range:[#min:1,#max:15]]
return description
end


Now, when we created control system which keeps track of how many times we played each game, we only need to create save/load feature.
In all 9 rooms we have to create link to save/load movie in MIAW.
We need to have one “Save”, on “Load” and one “Delete name” button. Also we need one editable field where user can type his name, and we need one scrolling field for loading procedure, where user can select saved game name, and after pressing load button MainList will be loaded from user hard disk and all buttons with number 4 in list will be taken off stage and score will be updated.

But lets go first with “Save” procedure. We need only one editable field and one “Save” button. On editable field you can attach some behavior for restricting some characters, this is optional but recommended.
On “Save” button attach following behavior:
--*************************
--Save button behavior

--**************************

property mySprite,NewUser,myText
global MainList,currentList, CurrentScore,level
on beginSprite me
set mySprite=the spriteNum of me
ReadGlist me
end
on mouseUp me
NewUser=the text of member ("InputNewUser")

if newUser="" then
alert "Please input your name"
exit
end if
if char 1 of newUser=" " then
alert "First char can not be space."
set the text of member ("InputNewUser")=""
exit
end if
--adding spaces if user typed in word with less chars then 6
if length(NewUser)<6 then
repeat with i=length(NewUser) to 5
newUser=newUser&" "
end repeat
end if
--ACTION adding new user to existing list read from
--HardDisk

append(MainList,[newUser,currentList,CurrentScore])
sendAllSprites(#updateText)
set myText=string(glist)
set filepath=ensurePathSep(getOsdirectory())&"())&"ListSavedOnHardDisk.txt "
writeToFile mytext,filepath
set the text of member ("InputNewUser")=""
end

on ReadGlist me
set filepath=ensurePathSep(getOsdirectory())&"ListSavedOnHardDisk.txt"
-- put filepath
Filefound=fileexists(filepath)
if FileFound then
--read list from text file on hard disk and store text in myText
set myText= readFromFile(filePath)
set the text of member "ShowList"=string(myText)
set glist=value(myText)
end if
end


ReadFromFile, ensurePathSep, fileexists and WriteToFile are utilities in movieScript:
--************************************************
--write/Read utilities
--***********************************************
on writeToFile outputText, saveFilePath -- Use -1 to indicate a failure
set resultFlag = -1
set fileXtra = new (xtra "FileIO")
if not objectP(fileXtra) then
alert "FileIO Xtra not Installed"
return resultFlag
end if
--Attempt to create the file

createFile (filextra, saveFilePath)
case (status (fileXtra)) of
0 : -- Successful file creation , nothing
-122 : -- File already exists. -- Delete and recreate it -- So that it is not mixed with old data in file
openFile (fileXtra, saveFilePath, 0)
delete (fileXtra)
createFile (fileXtra, saveFilePath)
if status (fileXtra) <> 0 then
put "Error:" && error (fileXtra, status (fileXtra))
return resultFlag
end if
otherwise:
put "Error:" && error (fileXtra, status (fileXtra))
return resultFlag
end case
-- Open the file with ReadlWrite Access`! -- ualid modes: 0=reacUwrite, 1=read, 2=write
openFile (fileXtra, saveFilePath, 0) -- Check if it succeeded
if status (fileXtra) = 0 then -- Record the data passed in
writeString (fileXtra, outputText)
setFinderInfo (fileXtra, "TEXT ttxt")
closeFile (fileXtra)
return 1 -- Success code else
put "Error occurred" && error (fileXtra, status (fileXtra))
return resultFlag
end if
end writeToFile




on readFromFile readFilePathset
resultFlag = -1
fileXtra = new (xtra "FileIO")
if not objectP(fileXtra) then
return Void
end if
openFile (fileXtra, readFilePathset, 1)
set resultCode = status (fileXtra) -- Check if it saocceededit resultCode = 0 then
if resultCode = 0 then
set returnData = readFile (fileXtra)
closeFile (fileXtra)

return returnData
else

put "Error occurred" && error(fileXtra, status(fileXtra))
return Void
end if
end readFromFile

--syntax
--set filepath=ensurePathSep(getOsdirectory())&"jaco.txt"

on ensurePathSep inPath
set PathSep=the last char of the pathname
set temppath=inPath
if the last char of tempPath<>pathsep then
put pathsep after temppath
end if
return temppath
end ensurePathsep



on appendToFile myfile

if objectP(myFile) then set myFile = 0 -- Delete the instance if it already exists

set theFile = the text of field "myfield" -- Put some text into a variable

set myFile = new(xtra "fileio") -- Create an instance of FileIO

if the moviePath = "" then

alert "No moviePath! Please save your movie and try again."

else

openFile(myfile, the moviepath&"textfile.txt",0) --Open the file with R/W access

setPosition(myfile,getLength(myFile)) -- Set position to end of file

writeString(myFile, theFile) -- Append text to the file

alert "Status: "&error(myFile,status(myFile)) -- display error message

end if

closeFile (myfile) -- Close the file

set myFile = 0 -- Dispose of the instance

end

on deleteFile myfile

if objectP(myFile) then set myFile = 0 -- Delete the instance if it already exists

set myFile = new(xtra "fileio") -- Create and instance of FileIO

if the moviePath = "" then --

alert "No moviePath. Please save your movie and try again."

else

openFile (myFile, the moviepath&"textfile.txt",0) -- Open the file

delete (myFile) -- Delete the file

alert "Status:"& error(myFile,status(myFile)) -- display error message

end if

closefile (myfile) -- Close the file

set myFile = 0 -- Dispose of the instance

end

on fileExists filename
set fileObj=new(xtra "fileIO")
if objectP(FileObj) then
openfile(fileObj,filename,1)
set result=status(fileObj)
if result=0 then
set found=true
else
put error (fileobj,result)
set found=false
end if
closefile(fileobj)
set fileObj=0
return found
end if
end fileExists

--*****************************************
--end of utilities
--*****************************************

Now we need to create load feature for our project.
We need one scroll field and two buttons, one “Load” and one “Delete” button.

Here is behavior attached to scroll field:
--SHOW NAMES from file
global MainList
property mySprite,myMember,myUser,MyPoints,mytext,LineNum
on beginSprite me
set mySprite=the spriteNum of me
set myMember=the member of sprite mySprite
set myText=""
updateText Me
end

on updateText Me
set myText=""
--show users and their score
repeat with i=2 to count(MainList)
set myUser=getat(getat(MainList,i),1)
set myPoints=getat(getat(MainList,i),3)
set myText=myText&return&myUser&" "&myPoints
end repeat

set the text of member myMember=myText
end
on mouseUp me
--highlite clicked line
hilite line the mouseLine of member myMember
-- get clicked lineNum
set LineNum=the mouseline
--send to all buttons clicked user name
sendAllSprites(#OpenClickedUser,LineNum)
sendAllSprites(#DeleteUser,LineNum)
end


When names are stored in scrolled field, when user on some name to load game, information is send to all buttons.

Here is a Load button behavior:
property ItemNum
global MainList,CurrentList,Currentscore,level
on mouseUp me
set filepath=ensurePathSep(getOsdirectory())&"ListSavedOnHardDisk.txt"
--Read list from file on disk
set myText= readFromFile(filePath)
set the text of member "ShowList"=myText
set glist=value(myText)
if itemNum>1 then
currentList=getat(getAt(Mainlist,ItemNum),2)
Currentscore=getat(getAt(Mainlist,ItemNum),3)
itemnum=0
end if


end
on openClickedUser me,ItemN
ItemNum=ItemN
end

Delete user button is very simmilar:

global gList,CurrentList,level
property deleteflag,whichUser
on beginsprite me
set deleteflag=false
end
on mouseUp me
--set glist=[]
if deleteflag then
set filepath=ensurePathSep(getOsdirectory())&"())&"ListSavedOnHardDisk.txt"
set myText= readFromFile(filePath)
set the text of member "ShowList"=myText
set glist=value(myText)

if count(glist)>1 then
deleteAt glist, whichUser
-- put glist
itemnum=0
deleteFlag=false
sendAllSprites(#updateText)
end if


set myText=string(glist)
set filepath=ensurePathSep(getOsdirectory())&"())&"ListSavedOnHardDisk.txt"
writeToFile mytext,filepath
--go to 1
end if

end
on deleteUser me,ItemNum
set deleteflag=true
set whichUser=ItemNum
end

So, we created system with several behaviors. All behaviors can be modified very easy and also we can add features to create multilevel game system. We can even add time check to see how many secs player are dealing with game, and if, lets say, user stays more than 10 secs in one game we can treat this like one try.

I have applied this system on my latest commercial CD-ROM title for kids, and I added also information on one map about which game I have played and how may times, so kid have complete control over game.

For any additional information please feel free to contact me.

 


Contact

MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA

Send e-mail