Action Script 3 - Events between Spark and Custom Components - actionscript-3

We are building an interface for a game.
The interface has a tabbed menu at the bottom of the screen, with each tab displaying different aspects of an object (called a node).
When you click on one of these parts, it becomes the focus, and we download it's details in XML, including all it's sub-nodes and parent nodes and then update the tab display accordingly, or at least that's what we'd like to happen.
What we have:
MainInterface.mxml
<s:Application...
<fx:Script>
<![CDATA[
public var currentNode:Node = new Node();
protected function selectNodeHandler(event:Event):void
{
loader = new URLLoader(new URLRequest(ourWebSite + event.target.id + ".xml"))
//the xmlDownloaded function below is what changes the contents of currentNode
loader.addEventListener(Event.COMPLETE, xmlDownloaded);
...
<s:SkinnableContainer id="dashBoard"..
<mx:TabNavigator...
<s:NavigatorContent...
<s:SkinnableDataContainer ...
dataProvider="{currentNode.children}"
itemRenderer="renderers.NodeRenderer">
Node.as (valueObjects.Node)
...
[Bindable] public var id:String;
[Bindable] public var name:String;
[Bindable] public var children:ArrayCollection = new ArrayCollection();
[Bindable] public var parents:ArrayCollection = new ArrayCollection();
...
NodeRenderer.mxml (renderers.NodeRenderer)
<s:ItemRenderer ... click="nodeRenderer_clickHandler(event)">
<fx:Script>
<![CDATA[
protected function nodeRenderer_clickHandler(event:MouseEvent):void
{
var eventObject:Event = new Event ("nodeSelected");
dispatchEvent(eventObject);
}
...
<s:Label text = "{data.name}"/>
We tried adding an event listener for "selectNode" to the dashBoard:SkinnableContainer you see see above, but it didn't seem to want to take. We suspect this is because dashBoard is from a spark component and the dispatcher for "selectNode" is on of our own custom components, but we weren't sure... in any case that's what the code assist seemed to indicate as we had to write it in by hand.
We're not sure how to pick up the Events in FlashBuilder 4's debugger, so we're having trouble working out where it's going wrong. Basically, when someone clicks on the label of a child or parent node (that is displayed by the itemRenderer), we want a URLRequest sent to our website, with the url specific to the node clicked on. We then want a URLLoader listening for the return which will update public variable 'currentNode' when xmlDownloaded is called by the loader.
If you could clarify how the click event should be dispatched, what should be listening for it then sending the URLRequest and where the URLLoader that is listening for the xml data to return should be that would solve our problems. Alternatively, if there is a better (more conventional) way to be doing what we're trying to do that would also help, as we're relatively new to actionscript and flex.

protected function selectNodeHandler(url:String):void
{
loader = new URLLoader(new URLRequest(url));
//consider identifying the loader, for instance
loader.name = url; // you could also pass a second parameter
//to the function and assign it to the name property of the loader.
//the xmlDownloaded function below is what changes the contents of currentNode
loader.addEventListener(Event.COMPLETE, xmlDownloaded);
}
protected function nodeRenderer_clickHandler(event:MouseEvent):void
{
var url:String = ourWebSite + event.currentTarget.id + ".xml";
selectNodeHandler( url );
}
protected function xmlDownloaded( event:Event ):void
{
//identify the target here with the name property
var id:String = event.target.name;
}

Related

how to choose one object from a sprite as3

How to choose one object(picture that loaded by file) from a sprite when it is several object on that?
I want to drag one that mouse clicked.
private var spstage1:Sprite = new Sprite();
private var vecpic1:Vector.<String> = new Vector.<String>();
private var iconpic1:iconpic=new iconpic();
spstage1.graphics.beginFill(0xcccccc);
spstage1.graphics.drawRect(250,100,450,668);
stage.addChild(spstage1);
spstage1.addChild(iconpic1);
iconpic1.addEventListener(MouseEvent.CLICK, picclicked);
function picclicked(event:MouseEvent):void {
var txtFilter:FileFilter = new FileFilter("picture", "*.jpg;*.png");
//root.browseForOpen("Open", [txtFilter]);
file = new File();
currentload="pic";
file.addEventListener(Event.SELECT, dirSelected);
file.browseForOpen("Select a picture",[txtFilter]);
//
/*file.browse();
file.addEventListener(Event.SELECT,onselect);*/
}
protected function dirSelected(e:Event):void {
var re1:URLRequest=new URLRequest(file.nativePath);
loader=new Loader();
loader.load(re1);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadCompletepic);
}
function loadCompletepic(event:Event):void{
var pic:BitmapData=new BitmapData(loader.width,loader.height,false);
pic.draw(loader);
bitmap=new Bitmap(pic);
spstage1.addChild(bitmap);
bitmap.x=ix;
bitmap.y=iy;
vecpic1.push(bitmap.name);
}
Add MOUSE_DOWN event listener to spstage1.
In the listener handler, check:
function clickHandler(evt:MouseEvent):void {
if (evt.target is Bitmap) {
// here you decide what you have clicked on.
(evt.target as DisplayObject).startDrag(); // do the stuff for dragging etc.
}
}
Here evt.target will be the object that is clicked.
All you have to do is to determine if it is the right object. In this example, it is just checked to be of the Bitmap type. If you have other Bitmaps in the container that don't need to be clicked, use other means, for example store the loaded object somewhere and then compare the target against all the stored objects. Or check for bitmap.name which you seem to already have, etc.

Action Script 3.0 Mouse Event in a class package

am having problem with using mouse click event inside a class, i am an absolute beginner to Action Script.
what i want is that if i click the btn_MClick button it should run the script, but everytime i click it i get error message that btn_MClick is undefined.
btn_MClick is on stage and with the instance name if btn_MClick
public class gunShip1 extends MovieClip
{
var moveCount = 0;
public function gunShip1()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveGunShip1);
stage.addEventListener(KeyboardEvent.KEY_DOWN, ShootGunShip1)
btn_MClick.addEventListener(MouseEvent.MOUSE_DOWN.KEY_DOWN, ShootGunShip1);;
}
function ShootGunShip1(evt: MouseEvent)
{
var s_Bullet:survBullet = new survBullet();
var stagePos:Point = this.localToGlobal (new Point(this.width / 2-10, this.height));;
s_Bullet.x = stagePos.x;
s_Bullet.y = stagePos.y;
parent.addChild(s_Bullet);
//play sound
var gun_sound:ricochetshot = new ricochetshot();
gun_sound.play();
}
}
Please, i have absolutely no idea what to do, and somehow it feels like the whole process is wrong.
Your class gunShip1 does not have the property btn_MClick, the root, or document class does.
Basically what's happening is that you've placed your button on the stage, which makes it an instance that belongs to the root container. At the moment, you're trying to refer to the button as a property of gunShip1.
What you should really do here is have the button click managed separately to gunShip1, and have that separate code invoke methods of gunShip1. For example, you could have this in your document class:
public class Game extends MovieClip
{
private var _ship:gunShip1;
public function Game()
{
_ship = new gunShip1();
// The Document Class will have reference to objects on the stage.
btn_MClick.addEventListener(MouseEvent.CLICK, _click);
}
private function _click(e:MouseEvent):void
{
_ship.shoot();
}
}
And then your updated shoot method in gunShip1:
public function shoot():void
{
var s_Bullet:survBullet = new survBullet();
var stagePos:Point = this.localToGlobal (new Point(this.width / 2 - 10, this.height));
s_Bullet.x = stagePos.x;
s_Bullet.y = stagePos.y;
parent.addChild(s_Bullet);
var gun_sound:ricochetshot = new ricochetshot();
gun_sound.play();
}
The idea is that the gunShip1 should not be responsible for dealing with user input (mouse, keyboard, etc). Instead, that should be a separate class which informs gunShip1 that it should do something.

my dynamically added movieclips have a name of "instance XX"

There are a couple things going on here that I dont fully understand. I have created a custom class that extends MovieClip to give some custom properties and create a geometric shape inside of the created MovieClip
package com.hyatt
{
import flash.display.*;
import flash.geom.*;
public class mapPin extends MovieClip
{
public var spirit:String;
public var callName:String;
public var hotelName:String;
public var city:String;
public var s:String;
public var zip:String;
public var country:String;
public var brand:String;
public var featured:Boolean;
public var horizon:Boolean;
private var _mc1:MovieClip = new MovieClip();
public function mapPin(_brand:String)
{
brand = _brand;
switch (_brand)
{
case "Andaz":
pinCircle(0xff0000);
break;
case "Grand Hyatt":
pinCircle(0x0000ff);
break;
case "Hyatt":
pinCircle(0x4600f0);
break;
}
}
private function pinCircle(color:uint):void
{
_mc1.graphics.beginFill(color);
_mc1.graphics.drawCircle(0,0,20);
this.addChild(_mc1);
_mc1.graphics.endFill();
}
}
}
Then I'm adding an couple instances of the mapPin class to a container movieclip on my stage and adding an event listener to that container clip.
var myTest1:mapPin = new mapPin("Andaz");
myTest1.brand = "Andaz";
container_mc.addChild(myTest1);
myTest1.name = "myTest1" //this is added purely for testing the "instance xx", same result
myTest.x = 100;
myTest.y = 100;
var myTest2:mapPin = new mapPin("Hyatt");
container_mc.addChild(myTest2);
myTest2.brand = "Hyatt";
myTest2.x = 400;
myTest2.y = 400;
container_mc.addEventListener(MouseEvent.CLICK, pinClicked);
finally I'm trying to be able to access the properties (the only one set thusfar is "brand") of the mapPin that is clicked.
function pinClicked(e:MouseEvent):void
{
trace(e.target.name); // traces "instance xx" instead of "myTest1"
trace(e.target.brand); // traces "undefined"
}
I can add the mapPin instances, and adjust their x and y though i cannot reference the custom class properties like "brand" and their name becomes a generic instance name. What am I missing? There are going to be upwards of 500 of these items added and I want to be able to pull information from them based upon a users click.
I'd have to see your mapPin class to be sure, but I think that the DisplayObject that is dispatching the event, is a child of mapPin.
To fix this, inside your mapPin class constructor add this line :
mouseChildren = false;
That will specify that children shouldn't receive clicks/dispatch mouse events.
currentTarget is the most recent object to dispatch an event and target is the object that originally dispatched it
It's not. AS3 doc says :
currentTarget :
The object that is actively processing the Event object with an event listener. For example, if a user clicks an OK button, the current target could be the node containing that button or one of its ancestors that has registered an event listener for that event.
target : The event target. This property contains the target node. For example, if a user clicks an OK button, the target node is the display list node containing that button.

AS3 Serialization

What I'm trying to do:
-Have objects in a toolbar, drag and dropable onto a movieclip (they then become a child of the movieclip). Once this is done, I want to be able serialize this object, so I can save it to a file. Then, I can reload this file, and continue draging/dropping things onto/off of this movieclip.
How I'm doing it:
public class Serialization {
public static function serializeToString(value:Object):String{
if(value==null){
trace("null isn't a legal serialization candidate");
}
var bytes:ByteArray = new ByteArray();
bytes.writeObject(value);
bytes.position = 0;
var be:Base64Encoder = new Base64Encoder();
be.encode(bytes.readUTFBytes(bytes.length));
return be.drain();
}
public static function readObjectFromStringBytes(value:String):Object{
var dec:Base64Decoder=new Base64Decoder();
dec.decode(value);
var result:ByteArray=dec.drain();
result.position=0;
return result.readObject();
}
}
This is where call the function/write it to the file:
var fr:FileReference = new FileReference;
fr.addEventListener(Event.COMPLETE, success);
var txtString:String = new String();
txtString = save.Serialization.serializeToString(pagePic);
trace(txtString);
fr.save(txtString, "test.txt");
Unfortunately, txtString appears to be blank. Am I approaching this wrong?
Side notes:
This is being developed for a mobile platform.
Unfortunately MovieClips, Sounds, and other resources cannot be serialized. My solution is to create a custom class that will store all my properties and reassign them upon loading, or just write to/parse a text file when saving/loading.

TabbedViewNavigator from Actionscript

How can I instantiate a TabViewNavigator from actionscript for the playbook? Currently, I add the necessary spark frameworks and have this piece of code in the Main of my actionscript project:
[SWF(width="1024", height="600", backgroundColor="#ffffff", frameRate="30")]
public class Main extends Sprite
{
private var waitDialog:BaseDialog = new BaseDialog ();
public function Main()
{
super ();
var next:LabelButton = new LabelButton ();
next.label = "Next";
next.addEventListener(MouseEvent.CLICK,showTabs);
this.addChild(next);
}
private function showTabs (event:MouseEvent):void{
var temp:Stage = this.stage;
temp.removeChild(this);
var bar : TabbedViewNavigator = new TabbedViewNavigator();
var tab1:ViewNavigator = new ViewNavigator();
tab1.label = "Test";
bar.addItem(tab1);
temp.addChild(bar);
}
}
When the button is clicked, the button disappears as you would expect but the tab navigator is not added/does not appear. I tried without removing the Main class but that does not work either. What do I need to do to set up a tab interface. I can get similar code working through Flex and MXML but not in actionscript.
temp.removeChild(this); - this is the problem you just remove the movie clip form the stage. There is no sense in this row.