doubleclick studio. access parent stage. AS3 - actionscript-3

Im working on a banner for google double-click studio. My parent swf loads a child swf and adds it to the stage. I need to get access to the parent swf stage from my child. How would i do that?
This is my parent code
import com.google.ads.studio.HtmlEnabler;
import com.google.ads.studio.events.StudioEvent;
import com.google.ads.studio.display.StudioLoader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.MovieClip;
var enabler:HtmlEnabler = HtmlEnabler.getInstance();
enabler.init(this);
var loadedHandler:Function = function(event:StudioEvent):void {
var myLoader:StudioLoader = new StudioLoader();
var req:URLRequest = new URLRequest("child.swf");
myLoader.load(req);
holder.addChild(myLoader);
}
My child swf has a document class where i want do access the stage.
the problem is:
_enabler = new ProxyEnabler();
stage.align = StageAlign.TOP_LEFT;
On stage i get: #1009: Cannot access a property or method of a null object reference.
Anyone know how to solve this?

this.parent.stage should do the trick. Make sure you use it after the child has been added to the parent/stage. Note: You could just move the stage.align = StageAlign.TOP_LEFT; to the parent if you don't need a different setting.

Wanted to give my own two cents on this piece. I tried the other answer but it didnt work. I got in touch with Doubleclick Support and they gave me an answer that worked out perfectly. In this example i am creating a stage mouseover and mouseout event handler.
In your example you would change
stage.align = StageAlign.TOP_LEFT;
to be
this.addEventListener(Event.ADDED_TO_STAGE, isAddedToStage);
function isAddedToStage(e){
stage.align = StageAlign.TOP_LEFT;
}
And here is my example with a stage mouseover and mouseout event handler.
this.addEventListener(Event.ADDED_TO_STAGE, isAddedToStage);
function isAddedToStage(e){
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoved);
}
function mouseMoved(evt:Event):void
{
//custom script here
mouseIsOver = true;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoved);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeft);
}
function mouseLeft(evt:Event):void
{
//custom script here
mouseIsOver = false;
stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeft);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoved);
}

Related

Unable to addChild on MouseCoordinations

What i am trying to do is, to place a new tower each time on MouseX and MouseY. but it seems it isn't working Any Idea guys?
or if you can create a tileMap array and add new child of PrototypeTower each time when we click on the Tower (on x=50, y=400) to select and place wherever we want. When i click the the box at x=50, y=400, the startDrag() doesn't work.
Main.as
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Mouse;
public class Main extends Sprite
{
private var pTower:PrototypeTower = new PrototypeTower;
private var zTower:PrototypeTower = new PrototypeTower;
private var fTower:PrototypeTower = new PrototypeTower;
public function Main()
{
pTower.x = 50;
pTower.y = 400;
addChild(pTower);
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
pTower.addEventListener(MouseEvent.CLICK, onClicked);
}
private function onClicked(e:Event):void
{
removeEventListener(MouseEvent.CLICK, onClicked);
zTower.x = mouseX;
zTower.y = mouseY;
addChild(zTower);
zTower.startDrag();
addEventListener(MouseEvent.CLICK, onPlaced);
}
private function onPlaced(e:Event):void
{
removeEventListener(MouseEvent.CLICK, onPlaced);
zTower.stopDrag();
fTower.x = mouseX
fTower.y = mouseY;
addChild(fTower);
}
}
}
PrototypeTower.as
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
public class PrototypeTower extends MovieClip
{
public function PrototypeTower()
{
this.graphics.beginFill(0x00FF00);
this.graphics.drawRect(this.x, this.y, 20, 20);
this.graphics.endFill();
}
}
}
Thank you, i am totally noob, wondering around from days!
Sorry this is just a schematic for now. I'll try to refine it later if you need. Hopefully this clears some things up for you though
When you click the tower, add a new tower at the x,y of the mouse and do some sort of startDrag(tower) on the new tower you just added. Then when you click on the stage, stop the drag and set the new X,y
edit
You might try getting rid of all your removeEventListener calls
I think your problem is you are removing the event listener that gets added in your main function. Keep in mind that the main function (class constructor) for the document class only gets called once, so you add an event listener for ADDED_TO_STAGE only once, and then you remove it the first time you try to add anything to the stage, and you never put it back. Just don't remove it in the first place.
You are calling zTower.startDrag() before you add it to the stage. Do addChild(zTower) and then zTower.startDrag()

Loading multiple external swf and navigate using buttons on child

I'm trying to load and unload many external swf files into main blank swf. And use navigation buttons (next/back) that located on the externally loaded child pages to navigate (load and unload pages).
I tried to dispatch event from child to main to unload. It works fine only with the first page, as the dispatcher is bubbling only once.
I have a default page to be loaded and dispatcher listener at the main swf as follows:
var cont:Sprite= new Sprite();
var swfLoader:Loader = new Loader();
var swfFile:URLRequest = new URLRequest("Page1.swf"); //default page
addChild(cont);
swfLoader.load(swfFile);
cont.addChild(swfLoader);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoadedHandler);
function swfLoadedHandler(event:Event):void {
MovieClip(event.currentTarget.content).addEventListener("eventTriggered", removeLoader);
}
function removeLoader(event:Event):void {
SoundMixer.stopAll();
this.swfLoader.unloadAndStop();
this.removeChild(cont);
this.cont = null;
swfLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, swfLoadedHandler);
trace ("dispatched");
}
Also the next button code on child page1.swf is as follwos:
nxt_pg.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler_8);
function fl_MouseClickHandler_8(event:MouseEvent):void {
content_mc.gotoAndStop(1);
dispatchEvent(new Event("eventTriggered", true));
SoundMixer.stopAll();
//Code of Loading new page here
}
And the same code for back button.
So, I wonder if anyone could help me with code or better technique..Thanks in advance fore your help.
I worked around this by removing Next and Back buttons from child SWFs and put it on container inside movie clip and change its visibility as needed.
At index page (page0.swf) I simply set 'buttons_mc.visible = false;' and make it visible at rest of pages.
The most important thing here is using 'addChildAt(myLoader,0)' instead of 'addChild(myLoader)' to make the buttons movie clip on top of the loaded SWFs.
All this done only on container code and no need to do any extra coding with the external loaded SWFs.
Below is the code for the container swf:
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.MouseEvent;
var swfNumber=0;
var myLoader:Loader = new Loader();
var myRequest:URLRequest = new URLRequest("swf/"+"Page"+swfNumber+".swf");
buttons_mc.visible = false;
myLoader.load(myRequest);
addChildAt(myLoader,0);// will be added under the buttons layer
trace(getChildIndex(myLoader));
//==============
buttons_mc.nxt_pg.addEventListener(MouseEvent.CLICK, nextSwf);
function nextSwf(event:MouseEvent){
if(swfNumber<totalSwf){swfNumber++}
else (swfNumber=0);
reload();
trace("Next");
}
buttons_mc.prv_pg.addEventListener(MouseEvent.CLICK, previousSwf);
function previousSwf(event:MouseEvent){
if(swfNumber>1){swfNumber--}
else (swfNumber=0);
reload();
trace("Back");
}
//==============
function reload(){
if (swfNumber==0){buttons_mc.visible = false;}
else (buttons_mc.visible = true);
myLoader.unloadAndStop();
removeChild(myLoader);
myRequest= new URLRequest("swf/"+"Page"+swfNumber+".swf");
myLoader.load(myRequest);
addChildAt(myLoader,0);
}

How to make pre-loaded swf fill the browser?

Let me explain my question a bit.
I am creating a flash website and I am using a small external preloader swf to load in the main swf. I have been able to get my preloader swf to take up the whole browser window but as soon as it loads in the main swf it only displays in its normal dimensions that it was built in.
I do have a resize listener within the main flash application and as soon as I change the size of the browser the main swf then occupies the whole browser. But how can I get it to start out that way?
-I've tried using an ENTER_FRAME handler but that broke some of my animations.
-I've tried setting the width and height of my loader object in the preloader and that doesn't seem to work either.
-I've also tried adding an ADDED_TO_STAGE listener to the loader, but that doesn't seem to have changed anything.
-I also tried having the preloader be in one scene and the main application be in another so that I was only loading one swf, but that didn't seem to work and I don't prefer that method of pre-loading.
I haven't been able to find a solution anywhere. Is there something easy that I'm missing? Let me know what you all think. preloader code is as follows:
import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.Event;
import flash.events.ProgressEvent;
var request:URLRequest = new URLRequest("flashNew.swf");
var loader:Loader = new Loader();
loader.load(request);
this.addChild(loader);
function loadProgress(event:ProgressEvent):void
{
var percentLoaded:Number = event.bytesLoaded / event.bytesTotal;
var percentLoadedBar:Number = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
percentLoaded = Math.round(percentLoaded * 100);
this.percentLoaded.text = String(uint(percentLoaded)) + "%";
progressBar.width = percentLoadedBar * 3.36;
}
function loadComplete(event:Event):void
{
//loader.content.height = stage.stageHeight;
//loader.content.width = stage.stageWidth;
}
function setDimensions(event:Event):void
{
loader.width = stage.stageWidth;
loader.height = stage.stageHeight;
}
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadProgress);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
loader.contentLoaderInfo.addEventListener(Event.ADDED_TO_STAGE, setDimensions);
Is there a way I can change via javascript or something? I'm at a loss here and I've been stuck on this for hours. Any help would be appreciated. Thank you!
UPDATE
Here is my code for my resize function.
function resizeListener(e:Event):void
{
background_mc.width = stage.stageWidth;
background_mc.height = stage.stageHeight;
//The rest of the function is omitted. It is if's and else-if's that just reposition various elements.
//That's really all this function does is re-position elements with the exception of the above code which resizes the background.
}
Here is the event listener call.
stage.addEventListener(Event.RESIZE, resizeListener);
Try this:
removed this line of code: this.addChild(loader);
then tweak your loadComplete function to this:
function loadComplete(event:Event):void
{
addChild(loader.content);
loader.content.height = stage.stageHeight;
loader.content.width = stage.stageWidth;
}

Control loaded swish animation in AS 3.0

I'm developing an AS 3.0 wrapper to add some extra stuff that has to load some old and plain frame to frame SwishMax 3 animations and then be able to stop them, play them, and so...
Here is my code:
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.events.*;
[SWF(backgroundColor="#ffffff", frameRate="17", width="300", height="250")]
public class SwishMaxWrapper extends Sprite {
function SwishMaxWrapper() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
addChild(loader);
var request:URLRequest = new URLRequest("swishy.swf");
loader.load(request);
}
private function completeHandler(event:Event):void {
var movie:MovieClip = event.target.content;
movie.stop();
}
}
}
The animation load works as expected but the movie.stop() doesn't. What is wrong?
I tested your code and it works on my machine. The SWF that I loaded had its animation in the main timeline. Is it possible that the swishy.swf has animation that is not on the main timeline? Perhaps the animation is in another symbol instead, and an instance of that symbol is on the stage. Anyway, when you call stop() in your code above, it's just telling the main timeline to stop, but other movie clips on the stage will keep on going.
I think that's what Simsoft was pointing out.
I tested your code using a SWF that had a symbol on the stage that had animation in it, and I got the problem that you are describing. I fixed it by modifying completeHandler() as follows:
public function completeHandler(event:Event):void {
var movie:MovieClip = event.target.content;
movie.stop(); //doesn't work - main timeline is only one frame long
for(var i:int = 0; i<movie.numChildren; i++) {
var child:MovieClip = movie.getChildAt(i) as MovieClip;
if(child) { //need this test - if the cast to MovieClip fails, child will be null
child.stop(); //works
}
}
}
Hopefully you don't have more animations nested at deeper layers. If that's the case, you'll have to modify this to keep peering into the children of each child and trying to stop their timelines as well.
Anyway, hope that helps. Good luck!
stop() isn't recurive, I think the problem is here.
function ruleThemAll(target : DisplayObjectContainer, doStop : Boolean = true) : void
{
for(var i : uint = 0; i < target.childNum; ++i)
{
var child : DisplayObject = target.getChildAt(i);
// If it's a container, go into to stop children
if(child is DisplayObjectContainer)
ruleThemAll(child as DisplayObjectContainer, doStop);
if(child is MovieClip)
{
if(doStop)
MovieClip(child).stop();
else
MovieClip(child).play();
}
}
}

ActionScript Retrieving Width/Height Of Loader Image

i'm trying to access the width and height of an image that is added to the stage via a custom LoadImage class. the trace results are 0 even though the image displays correctly. what is the problem?
//frame script
var image:LoadImage = new LoadImage("myImage.jpeg");
addChild(image);
trace(image.width); //returns 0
//-------------------------
package
{
import flash.display.Sprite;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
public class LoadImage extends Sprite
{
public function LoadImage(imageURL:String)
{
//Load Image
var imageLoader:Loader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageHandler);
imageLoader.load(new URLRequest(imageURL));
}
private function imageHandler(evt:Event):void
{
addChild(evt.target.content);
}
}
}
If you're trying to access it right after you instantiate it, you don't have access to it's properties. You will have to make it event driven:
class LoadImage loads image
frame script listens for a complete event from LoadImage
LoadImage loads the image, once it has it's hands on it it dispatches the event
frame script works with the data
you need to make an event in LoadImage and once done in imageHandler, dispatch that. When you make your new LoadImage, set up the listener
var image:LoadImage = new LoadImage("myImage.jpeg");
image.addEventListener("complete", loadedImage); //or whatever you call the event
function loadedImage(evt:Event) {
addChild( evt.target );
trace(evt.target.content.width); //returns 0
}
you're trying to get the width and height before the image is completely loaded? see this question for more detail.