Flash and XML[c] A Developer[ap]s Guide
So far we have applied labels to buttons, which is nice. The buttons click nicely , too. But nothing happens. By adding functionality to the buttons , we can extend interest in our little game beyond the first few seconds. There are several strategies by which this can be done. A bit of code might examine the AnswerOption to see if it is the correct one. If that code were in the base movie it might have a local variable where the clicked option leaves its name : ActionScript
_parent.clicked = _name; // code in the AnswerOption Then it might examine the variable to decide whether it is a win or a loss: ActionScript
if( clicked eq "answer2" ) { // code in the base movie This is an adequate but not optimal design. There is a bit of fragility in recording the correct answer as the name of the interface object to which it is attached. For one thing, a change to the order of the questions requires changing the name of the correct choice, which invites error. A second concern is the scattering of information between the child object and its parent. Better design would involve smarter AnswerOptions . These objects should each know whether they are correct or not. This design also makes it easy to have multiple correct choices or none and even to have choices that are not exactly wrong or right but offer partial credit. Whether such a feature would be fun is a game design issue, not a technical issue. But it is always good to create systems that do not preclude this kind of flexibility. The effort of realizing the feature is usually made only after interest in it has been demonstrated. Let us then assume that each object contains not only the text of the answer but also a score variable. For the moment, we will assume that a positive value means a correct answer. But we will start building this with a simple view of the world: Everybody is always wrong. Clicking the AnswerButton will ultimately cause the base movie to go to the Lose state we built in Chapter 1. Between the button and the base movie is the AnswerOption object, and this is where we want to build the logic. First we give the object two states : a waiting state and a thinking state. Each is represented by a keyframe. Unlike our experience earlier, these simple states do not require labeled keyframes (though that might have documentation value). The first frame is the waiting state. Waiting is easy. Just instruct Flash to stop (Figure 3.1). How do we know the waiting is over? A button is clicked. Open the Object (not Frame) Actions panel for the button, and simply have it play when it is clicked. This will get past the stop in struction on the first frame ( waiting ) and advance to the second frame ( thinking ; Figure 3.2). In fact, very little thought is required. Since everyone is always wrong (at this stage), the thinking frame merely directs its parent (the base movie) to advance to its Lose state (Figure 3.3). Figure 3.1. The Waiting State
Figure 3.2. Waiting Ends
Figure 3.3. The Thinking State
ActionScript
_parent.gotoAndPlay("Lose"); Try it out. It is somewhat discouraging because everyone always loses. But otherwise it works. Making it work better is a simple matter of improving the thinking state. If the object looks into itself and examines its own score variable, it will know whether Win or Lose is appropriate: ActionScript
if( score>0 ){ _parent.gotoAndPlay ("Win"); } else{ _parent.gotoAndPlay ("Lose"); } Of course, this code will not work unless we have set the score variable ”at least for the one option that holds the correct answer. The others, being uninitialized variables , have a value of 0. Normally, we would want to assure that there was no score value already there, as would happen if answer 3 was the correct answer to a previous question. In this case, we know that between questions, these buttons will go out of scope. Whenever we are setting the score variable values, all the variables are fresh and valueless. We can do this at the same time that we are applying the labels, in the first frame of the base movie on the Code layer. ActionScript
answer0.text="William the Conqueror"; answer1.text="William the Bastard"; answer2.text="William the Bald"; answer2.score=1; answer3.text="William the Duke of Normandy"; stop (); Now when the movie plays, it plays correctly. |