Dialog Box and Buttons
I wanted my next tutorial to be a game tutorial, but after all the effort I put into this particular aspect, I thought this deserved a tutorial all its own. I wanted to add a pop up dialog to show the instructions for a game. I came across a couple of problems that took a lot of research to get working. So what follows is a complete tutorial for creating a button and a pop up dialog box in Actionscript 3 using flex.
Here is the finished product:
The Button has a few key features and I hope that most of this is self explanatory. First we have our class in the Package “Demo.classes” I like sorting my classes like this. You can put them in their own packages and such, but for the small size of this tutorial, It works to have all the files in the same Package.
We extend the class from the Sprite class. We have a label property to hold the button label. In the constructor, we create the button using a TextField object give it a few key values. We give it a background color and border to create a button look. You can use some shapes or an externally loaded graphic for this. We set the “selectable” property to false so that when the mouse is over it, it has the arrow pointer rather than the text select pointer. Then we create a listener for Mouse roll over and roll out. These two events along with the Mouse Click event are the key events for a button. I handle the click event in the main class for the demo. The roll over and roll out events just change the background color of the button. You could do anything really.
package Demo.classes { import flash.display.*;��� import flash.text.*; import flash.events.*; public class button extends Sprite { private var label:TextField; public function button(txt:String):void { label = new TextField(); label.text = txt; label.autoSize = TextFieldAutoSize.CENTER; label.background = true; label.backgroundColor = 0X0000CC; label.textColor = 0Xffffff; label.border = true; label.borderColor = 0X000000; label.selectable = false; label.addEventListener(MouseEvent.ROLL_OVER, buttonRollOverHandler); label.addEventListener(MouseEvent.ROLL_OUT, buttonRollOutHandler); addChild(label); } private function buttonRollOverHandler(event:MouseEvent):void { label.backgroundColor = 0XCC00CC; } private function buttonRollOutHandler(event:MouseEvent):void { label.backgroundColor = 0X0000CC; } } } |
Next we have the dialog class. This one starts out similarly to the button class, but with one more import statement. We import the Demo.classes library. We only really need the button class for this, but I kept it as * in case I need to add further functionality later. This is a bad practice for large scale projects as you should only import those library classes you actually need to cut down on overhead.
This class has 3 properties, content (what text is going to display in the dialog), scrolling and scrollDirection. The last two are for the purposes of scrolling text that is too long for the dialog.
In the constructor, we create the background for the dialog. This is just a large rectangle. Next we create a TextField object and assign the passed in text to it, give it a set height and width that is slightly smaller than the background rectangle. We set wordWrap and multiLine to true so that as much text as possible is visible. We then create the up and down arrows for the purposes of scrolling (I will talk about these specifically in a moment). Finally we create a “close” button and give it an event listener for the Mouse Click event to close the dialog.
Specifically on the button issue. I learned the hard way, you cannot add an event to just a Shape object. Not sure why, but you can’t. You must first add that shape object to a Sprite object. This took me about an hour to figure out, so I want you to know this. So this is why the up and down arrows are structured the way they are.
Next we have the events for the up and down arrows. When the mouse button is pressed on them, they call their respective functions. The functions change the “scrollV” value of the TextField object. They also set the scrolling property of the class to true. This tells the class that we are scrolling the text. Without this, the text will only move one line with each click. We then add two event listeners to the stage for Mouse Up and Enter Frame. Mouse up simply turns off scrolling and gets rid of the stage listeners. the Enter frame listener checks to see if we are still scrolling, what direction and then scrolls once more in that direction.
Finally we have the function called when the close button is clicked. THis button removes this instance of the dialog object from the parent (stage) children list, thus closing the dialog.
package Demo.classes { import flash.display.*;��� import flash.text.*; import flash.events.*;��� import Demo.classes.*; public class dialog extends Sprite { private var content:TextField; private var scrolling:Boolean; private var scrollDirection:String; public function dialog(txt:String):void { var rect:Shape = new Shape(); rect.graphics.lineStyle(1); rect.graphics.beginFill(0Xffffff,1); rect.graphics.drawRect(0,0,300,300); addChild(rect); content = new TextField(); content.text = txt; content.x = 5; content.y = 5; content.width = 280; content.height = 260; content.wordWrap = true; content.multiline = true; addChild(content); var up:Sprite = new Sprite(); var upArrow:Shape = new Shape(); upArrow.graphics.beginFill(0X000000,1); upArrow.graphics.lineStyle(1); upArrow.graphics.moveTo(5,0); upArrow.graphics.lineTo(10,10); upArrow.graphics.lineTo(0,10); upArrow.graphics.lineTo(5,0); upArrow.graphics.endFill(); upArrow.x = 285; upArrow.y = 10; up.addChild(upArrow); up.addEventListener(MouseEvent.MOUSE_DOWN, scrollUp); addChild(up); var down:Sprite = new Sprite(); var downArrow:Shape = new Shape(); downArrow.graphics.beginFill(0X000000,1); downArrow.graphics.lineStyle(1); downArrow.graphics.lineTo(10,0); downArrow.graphics.lineTo(5,10); downArrow.graphics.lineTo(0,0); downArrow.graphics.endFill(); downArrow.x = 285; downArrow.y = 30; down.addChild(downArrow); down.addEventListener(MouseEvent.MOUSE_DOWN, scrollDown);� addChild(down); var close:button = new button("Close"); close.x = 100; close.y = 270; close.addEventListener(MouseEvent.CLICK, closeDialog); addChild(close); } private function scrollUp(e:MouseEvent):void { scrolling = true; scrollDirection = "up"; content.scrollV--; stage.addEventListener(MouseEvent.MOUSE_UP,stopScroll); stage.addEventListener(Event.ENTER_FRAME,checkButtons); } private function scrollDown(e:MouseEvent):void { scrolling = true; scrollDirection = "down"; content.scrollV++; stage.addEventListener(MouseEvent.MOUSE_UP,stopScroll); stage.addEventListener(Event.ENTER_FRAME,checkButtons); } private function stopScroll(event:MouseEvent):void { stage.removeEventListener(Event.ENTER_FRAME,checkButtons); stage.removeEventListener(MouseEvent.MOUSE_UP,stopScroll); scrolling = false; } private function checkButtons(event:Event):void { if (scrolling) { if (scrollDirection =="down") { content.scrollV +=1; } else if (scrollDirection == "up") { content.scrollV -=1; } } } private function closeDialog(e:MouseEvent):void { if (this.parent != null) { this.parent.removeChild(this); } } } } |
Here is the main class for the dialog demo. This one is pretty standard. Here we include all of Demo.classes because we need all the classes. We could change the other imports to the specifically needed libraries.
In the constructor, we create the stage. then we create a single button and add and event listener for Mouse Click. This calls the function that creates the dialog box. I added quite a bit of text to demonstrate the scrolling capabilities of the dialog box, but you could add as much or as little as you like. I am still messing with the positioning of the dialog box. Not really sure why it needs to be offset so much, but if I find out why, I will update.
package Demo { import flash.display.*; import flash.text.*; import flash.events.*; import Demo.classes.*; public class Demo extends Sprite { public function Demo():void { stage.stageHeight = 320; stage.stageWidth = 320; stage.scaleMode = StageScaleMode.NO_SCALE; stage.frameRate = 32; ��� var example:button = new button("Example Dialog"); example.x = 160; example.y = 160; example.addEventListener(MouseEvent.CLICK, showExample); addChild(example); } public function showExample(e:MouseEvent):void { var exampleDialog:dialog = new dialog("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse erat lacus, faucibus vitae feugiat non, condimentum scelerisque lacus. Fusce suscipit magna eu nisl placerat adipiscing. Mauris quam tellus, interdum eu condimentum eget, pharetra eu nisi. Integer sed leo nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean accumsan dictum dolor quis posuere. Phasellus pretium fringilla diam sit amet elementum. Aliquam eu porttitor lorem. Sed ante odio, gravida vel facilisis rutrum, tincidunt ut lorem. Integer id nunc justo, vitae laoreet augue. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non lobortis turpis. Nulla id lectus ipsum, in adipiscing urna. Suspendisse vel ultricies tellus. Nam lacinia hendrerit libero at viverra. Proin varius vehicula lectus, eu gravida magna fringilla at. Curabitur adipiscing interdum nisl, in porttitor odio vulputate eget. Cras ornare, nunc in accumsan auctor, ipsum libero elementum dolor, et venenatis nibh tellus non metus. Pellentesque enim nisi, semper vel lacinia vel, tincidunt eget massa. Mauris nisi metus, malesuada eu varius volutpat, suscipit non purus. Fusce interdum sapien accumsan velit varius non placerat purus semper. Mauris ultrices condimentum neque ac consectetur. Phasellus a lectus odio, ut tempor velit. Morbi ultricies turpis quis odio posuere semper. Mauris molestie ligula eu sapien viverra ornare. Praesent quis orci eu magna imperdiet aliquet. Nunc iaculis aliquet condimentum. Fusce nec sem id elit fringilla tristique eget ut tellus. Fusce leo risus, fringilla mattis mollis a, mattis porta lorem. Vestibulum molestie condimentum tortor, in faucibus nisl venenatis nec. Integer nec dui sem. "); exampleDialog.x = 100; exampleDialog.y = 30; addChild(exampleDialog); } } } |
So that’s it in a nut shell. These classes still leave a lot of room for improvement, customization and over all better programming. I hope that it at least gets you started in the right direction.