| |||||||||||||||||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||||||||||||||||
Print This Article REALbasic University: Column 033
RBU Pyramid VILast week we got the Deck working, allowing the user to click on it to draw out a new card onto the temporary discard pile (moving any existing card on the temp discard to the main discard). But while we laid the groundwork for the Deck to reset when empty, we didn't actually implement the code to do this, so that will be our first task today.
Resetting the DeckOpen your RBU Pyramid project file and go to the resetDeck method inside gameWindow. Copy and paste in this code: dim i as integer The above is straightforward: we rebuild the empty gTheDeck array from the contents of the main and temporary discard piles. Then we erase the gTheDiscard array (since it's now empty) and set the contents of the two cardCanvas objects for the two discard piles to nothing (making them unclickable and non-selected). Note that we refresh those cardCanvas objects to make sure the new state is reflected in the display (i.e. if they were selected, we force a redraw to draw them as not selected). Simple eh? Run the program and click on the Deck until it runs out of cards and resets. Go ahead, try it. I'll wait. Uh oh. You encountered a problem, didn't you? The Deck didn't reset! What's going on? Relax, it's just a little oversight. There's nothing wrong with our code. It's just that last week we added a variable (property) that tells us if it's the first time through the Deck or not. Since we never initialized gFirstTimeThrough to true, it defaults to false, and therefore our resetDeck routine never gets called! The solution is simple: open globalsModule and go to the newGame method. Insert this code (don't erase what's already there): // Initialize game variables Now try running the program again: this time it should let you click through the Deck and display an "R" when the Deck is empty. Clicking on it again will refill the Deck from the discards (watch them go blank) and the Deck is now full of cards again. When you click to the bottom this time, however, it will display a "D" and be finished.
Fixing a Redraw FlawWhile testing the Deck just now, you may have noticed that the display of the Deck is flawed. There's little feedback for when you click on the Deck. But wait a second... didn't we include code for highlighting the Deck when it's click on? What happened to that? Run the program and watch carefully what happens when you click on the Deck. Depending on the speed of your computer, you may notice that the Deck does get highlighted: but the highlight is so quick it's erased almost before it happens! The solution is a simple delay between the initial highlight and the redraw. REALbasic doesn't have a delay command, so let's add our own. Within gameWindow add a new method (Edit menu, "New Method") like this: ![]() Put in this code: dim tt as integer The ticks command returns the number of ticks -- 60ths of a second -- since your computer was booted. Here we save the initial ticks value into tt and then do a loop that continually checks to see of our passed value of t ticks have passed. By subtracting the current ticks value with tt, we have the difference and that's what we compare to t.
Now we just need to add code to call this wait routine between the drawings of the Deck. Go to our deckAdvance method and find the code that begins with drawCard(index, true). After the subsequent if line, put this code: wait(6). The entire segment should look like this: drawCard(29, true) Try the program now: you should see a brief display of a black Deck before it redraws the gray card background. That's enough of feedback to let the user know they clicked on the Deck (and prevent it accidentally being clicked too many times).
Adding Sound FeedbackFixing that drawing flaw reminds me of the importance of feedback. One of the best kinds of feedback is audio: wouldn't it be nice if cards made a sound when you clicked on them? Let's do that. For today we'll just add sound for the clicking on the cards, but we'll set this up so it will be flexible enough to be easily modified for future sounds. Add a new method like this: ![]() Here's the code: select case kind This simply looks at the string passed and plays the appropriate sound. (I'm using the same sound for both the Deck click and a card click.) For this to work, you'll need to add a sound called "click" into your project file. I've included this sound within this week's project file, or you can use your own sound. Just drag the sound from the Finder into your project window.
If you run the program now, of course, it won't make any sounds. That's because we have never called the playSound routine! Go to the cardCanvas control and find the mouseDown event. After the first if cardCanvas(index).clickable and index <> 29 then line, put this: playSound("click"). In the deckAdvance method, insert playSound("deck") at the top (before any other code). Now you should have noise! If you would like the REALbasic project file for this week's tutorial (including the click sound), you may download it here.
Next WeekWe'll do more with sounds (adding a sound off control) and get a basic scoring system working.
LettersOur first letter is from Christopher Hunter, who has a question about arrays.
Ah, I see your problem, Chris. It's very simple: the property structure in your code is an array. In your above line of code you aren't giving it an index. The correct way to do it would be something like this, where i is a valid index:
That should solve your problem. Here's a little chart of error messages and what they mean:
Next, Kevin writes with a suggestion:
Hi Kevin! Glad you like the DVD project: I will consider your suggestion to use it as the subject for a future column. It's a little unpolished, and the XML aspect of it is a hack (it only supports a subset of "real" XML), but it is an interesting example program. I had thought of interrupting the RBU Pyramid tutorial at some point with a one column project: my DVD program might be a good example (though it does have some complicated aspects). As to your not wanting to use REALbasic's built-in database support, I concur. I've never used it, or had much of a need for it. I believe it's mostly there for connections to high-end database programs (something I have no experience with). For instance, you could write a REALbasic front-end to an Oracle database. Like you, I always owned the Standard edition of REALbasic (though I recently upgraded to the Professional version as I'm wanting to explore compiling for Windows). Also, a lot of the terminology in the RB help is database jargon I'm not familiar with, making learning how to use the database features difficult. As to your own database needs, just write your own! A database is nothing but a collection of data in a particular format. If you define the format, you can read and write the data in that format. If you're not planning on sharing the data with other software, the format of the database is entirely up to you. For instance, you could use a simple text file for your database. Each line of the database could be a record. You could divide the fields with a tab character (ASCII 9) or any other unique character that's not used in the data, so that you can separate the fields. For example:
The above format is easy to decode with the REALbasic nthField function: just pass it the current line, the delimiter you're using (in this case, chr(9)), and the field number you want. You can, of course, arrange the data in whatever order you want (and include whatever fields you'd like). The key is to be consistent: if the 5th field is the film's length, you cannot haphazardly insert in a new field after the director name. All records must have the same fields in identical order or you have chaos. You must insert blank fields if a particular movie doesn't have a field's information (with Brazil, in the above, I didn't include the year or length but the fields are still there) That's one of the reasons I chose to use XML for my DVD data. XML has the advantage of being extensible (that's what the X in the name means) because each field is named. With the above system you only know that the fifth field is the film length because it's the fifth field and you initially decided that it was the length. That forces you to use a strict structure. With XML, you can name each field and they can be in any order. Here's an excerpt from some of my data (note how each film does not necessarily have the same fields):
XML is more flexible, but it's also more complicated to decode, which takes time, and the data takes more space on disk (a problem for huge databases). For many databases having a fixed structure isn't a big problem -- I only did it this way for my DVD collection because I wasn't sure what fields I would need, and I wanted to play with XML. In many cases XML wouldn't appropriate for your actual database file, but you might include XML import and export routines in your program. There are a number of XML classes for REALbasic out there: while I haven't used it (it's a commercial product), Theodore H. Smith's XML Engine looks pretty good. Finally, we hear from Brett Cheng, with feedback from our new CSS format.
My goal was to highlight glossary items differently than standard links, but my original attempt (white text on blue background) made the entire item appear as white-on-white in non-CSS browsers (i.e. invisible). I compensated by making the text black, but you are correct that it's difficult to read. I've now modified it in a way that should work for everyone: yellow highlight with black underlined text. In browsers that don't support CSS at all or don't support the background color option, it appears as a standard underlined link. Keep those letters coming! I may not answer your question immediately, but I'll hopefully get around to it in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise I'll assume it's fair game.) About the Column REALbasic University is a weekly instructional column on programming with REALbasic and is brought to you by REALbasic Developer, the magazine for REALbasic programmers. Each week we answer select reader questions, and we're always open to ideas for future columns. Send your questions to . (Keep your questions simple and specific. General queries like "How do I write my own web browser?" will be neglected.) Your question won't be answered immediately, but will be answered in a future column. (If you don't want your correspondence published, just be sure to indicate that when you write. Otherwise it's fair game.) About the Author See the REALbasic University Archives
REALbasic University contents ©2001-2004 by Marc Zeedar and REALbasic Developer. All Rights Reserved.
|
. |
| |||||||||||||||||||||||||||||||||||||||||||