TabbedViewNavigator from Actionscript - actionscript-3

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.

Related

want to change the code actionscript2 to actionscript3?

i am newbie to flash.i need to change the below actionscript code to actionscript 3.0 code.
i am currently working on drag and drop. so i want to duplicate the movieclip while dragging i found the code on internet but it is actionscript 2.0 so please convert it to as3. the box is a instance name of a movieclip.
the code blocks are:
var num:Number = 0
box.onPress = function(){
num++
duplicateMovieClip(box ,"box"+num, _root.getNextHighestDepth())
_root["box"+num].startDrag();
}
box.onReleaseOutside = function(){
trace(_root["box"+num])
stopDrag();
}
If you dont want to use seperate .as file, follow this steps:
1- assign AS linkage to box movieClip (in library panel):
2- Select frame 1 on the timeline, and paste this code in the Actions panel:
var boxes:Array=[];
//var box:Box=new Box();
//addChild(box);
box.addEventListener(MouseEvent.MOUSE_DOWN,generateBox);
function generateBox(e:MouseEvent):void{
var newBox:Box=new Box();
newBox.x = e.target.x;
newBox.y = e.target.y;
newBox.startDrag();
newBox.addEventListener(MouseEvent.MOUSE_UP,stopD);
newBox.addEventListener(MouseEvent.MOUSE_DOWN,startD);
boxes.push(newBox);
addChild(newBox);
}
function startD(e:MouseEvent):void{
e.target.startDrag();
}
function stopD(e:MouseEvent):void{
e.target.stopDrag();
}
Unfortunately, there's no duplicateMovieClip analog in AS3, so you'll have to create a Class for your box movieClip template. Let's say it will be called BoxTemplate. (You can google how to create Classes for your library object). Add a Class with this name and add this code (event subscription in the constructor and a private event listener). You'll get something like this:
package
{
public class BoxTemplate
{
public function BoxTemplate()
{
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
}
private function onMouseUp(e:MouseEvent):void
{
stopDrag();
}
}
Leave your present instance of this symbol on the stage. This is your code in the frame:
import flash.event.MouseEvent
box.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void
{
var newBox:BoxTemplate = new BoxTemplate();
newBox.x = e.target.x;
newBox.y = e.target.y;
addChild(newBox);
newBox.startDrag();
}
It will allow you to infinitely clone your boxes. Of course, you can add all of them in the array to keep the references.

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.

AS3: Add layer overlay on top of everything?

I want to add some extra texturing for my current game, let's say an overlayed grunge texture on top of everything.
My entire project (except background image) is set on a Main Class.
Is it Possible? How?
Screenshot:
Sure, just disable any mouse input on the overlay and it will be like its not even there.
public function LuckyHitBeta()
{
...
var overlay:Sprite = new Sprite();
overlay.addChild( /* your texture goes here as a Bitmap */ );
overlay.mouseEnabled = false;
overlay.mouseChildren = false;
addChild(overlay);
}
Cant entirely remember the correct syntax but couldn't you just do:
import flash.display.Stage;
public class GlobalStage extends MovieClip
public static var theStage:Stage;
public static var theRoot:MovieClip;
public function GlobalStage() {
theStage = this.stage;
theRoot = this.root;
}
var grunge:MovieClip = new Grunge();
var topDepth:uint = theStage.numChildren()-1;
theStage.addChildAt(grunge, topDepth)

how do I access the main class's stage? + Can I pass functions as arguments like this?

There are two files in my actionscript project named "TestAPP", TestAPP.as and Draggable.as
TestAPP.as:
package {
import flash.display.Sprite;
import flash.display.Stage;
public class TestAPP extends Sprite
{
var _mainStage:Stage;
public function TestAPP()//This is where we test the UI components.
{
var sp:Sprite = new Sprite();
_mainStage = stage;
_mainStage.addChild(sp);
sp.graphics.beginFill(0x00FF00);
sp.graphics.drawCircle(0,0,10);
sp.graphics.endFill();
sp.x = 50;
sp.y = 50;
var draggable1:Draggable = new draggable(sp,_mainStage,limitingfunc);
}
public function limitingfunc(x:Number,y:Number):int{
return 0;
}
}
}
And for the draggable.as:
package
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.MouseEvent;
public class Draggable
{
private var _limitingFunc:Function;
private var _which:Sprite;
private var _MouseSavedX:Number;
private var _MouseSavedY:Number;
private var _stage:Stage;
public function Draggable(which:Sprite,stage:Stage,limitingfunc:Function)
{
_limitingFunc = limitingfunc;
_which = which;
_stage = stage;
_which.addEventListener(MouseEvent.MOUSE_DOWN,begin_drag);
}
//limiting func: returns 0 when the object is free to move that place.
//returns -1 when the user wants to block X coordinate changes (but maintain Y free)
//returns -2 when the user wants to block Y ...
//returns -3 or less when the user wants to block both X and Y from changing.
//returns
private function Return_0(x:Number = 0,y:Number = 0):int{
return 0;
}
private function begin_drag(ev:MouseEvent):void{
var xTo:Number = _stage.mouseX - _MouseSavedX + _which.x;
var yTo:Number = _stage.mouseY - _MouseSavedY + _which.y;
var limitingFuncReturnValue:int = _limitingFunc(xTo,yTo);
if(limitingFuncReturnValue == 0){//free to move.
_which.x = xTo;
_which.y = yTo;
}
else if(limitingFuncReturnValue == -1){//free to move Y
_which.y = yTo;
}
else if(limitingFuncReturnValue == -2){
_which.y = yTo;
}
//else:do nothing.
}
}
}
In "my actionscript theory", I'm supposed to see a circle that follows the mouse when I click it. (The draggable is not fully implemented) But the circle doesn't even budge :(
...I've been trying to figure out how to access the main class's stage property. I've googled for it, but still no progress.
Please help this helpless newb!!! I'll really appreciate your help:)
Thank you!
You're implementing your 2nd class as "draggable", when you named it (and it has to be named) "Draggable" with an upper case. Change it and see if that works. You seem to be passing in the parent classes stage correctly though.
If TestAPP is your document class. You can access to the stage thru the stage property (like your are doing in your example).
If TestAPP is not the document class, you should listen first to the ADDED_TO_STAGE event and then access to the stage property.
There is no need to add _mainStage property because you already have the stage property.
In order to move objects around, you need to use the ENTER_FRAME event.
You can access the main class' stage property the same way you do it for any DisplayObject on the stage: Use this.stage.
So just this should be enough:
var sp:Sprite = new Sprite();
stage.addChild(sp);
You could then pass the sprite and the main class' stage as a parameter, the way you did - but I would recommend creating a subclass Draggable extends Sprite and instantiate the whole thing using new Draggable() instead.
The new object will automatically have its own reference to stage as soon as it is added to the display list, and limitingFunc could be a member of Draggable, as well.
Also, you can use the startDrag() and stopDrag() methods, no need to implement your own: You can specify a Rectangle as a parameter to startDrag() to limit the permitted movement.
if you need it so much you may:
private static var _instance: TestAPP;
//...
public function TestAPP(){
_instance = this;
//...
}
public static function get instance():TestAPP{
return _instance;
}
public static function set instance(newVal: TestAPP):void{
_instance = newVal;
}
and you'll be able to reference its stage from any class where your TestAPP will be imported just with TestAPP.instance.stage.
but _instance is a property of the class TestAPP itself, not its instances

Using the Loader display object to load X jpegs, then resize each of the images differently while they're on the stage

Hey there, I was wondering if this is possible to do
I am able to load the image in and have it displayed easily enough by using addChild(myLoader); where myLoader is in the classWide private scope.
The problem is, whenever I call my function inside that class which adds the loader to the stage, it clears the old one and puts this new one in even if I add a bit where I change myLoader.name to something related to how many images it has completed.
This is a serious hinderance as I can't do anything besides KNOW how many images I will need to load and write the code X times. The problem being is that the urls are read from an XML file.
My main desire was to have a classWide private Array which contained my loaders and I would assign them using myArray.push(myLoader) each time the load had completed. There is a problem which is that it compiles but they never get displayed
it would work as this is written
public class Images extends Sprite
{
private var imagesLoaded = 0;
private var myLoader:Loader;
...
public function Images():Void
{
myLoader = new Loader;
//loop calling a myLoader.load(imageURL) for a bunch of urls
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
}
public function imageLoaded
{
myArray[imagesLoaded] = myLoader;
trace("does\'nt get to here!!");
addChild(myArray[imagesLoaded]);
imagesLoaded++;
}
}
You could create multiple Loaders to load your multiple files:
public class Images extends Sprite
{
private var imagesLoaded = 0;
private var myArray:Array;
...
public function Images():Void
{
myArray = [];
for each (var url:String in myBunchOfURLS)
loadURL(url);
}
private function loadURL(url:String):void
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
loader.load(new URLRequest(url));
// you'll need to add the loader to the display list to see anything!
addChild(loader);
}
private function imageLoaded(event:Event):void
{
var info:LoaderInfo = LoaderInfo(event.currentTarget);
info.removeEventListener(Event.COMPLETE, imageLoaded);
var loader:Loader = info.loader;
myArray[imagesLoaded++] = loader;
// or you could add the loader to the display list here instead?
}
}
If you have to have one loader, then you'll need to wait for each load to complete, get the bitmap data out of the loaded bitmap, add it to a new bitmap, then start loading the next image. That's a bit more of a pain - I'd stick to this approach if I were you.