ActionScript - Global Custom Events? - actionscript-3

up until now, the way i've been needing to handle my own custom events is by adding an event listener to the object that was dispatching the custom event. while this method of event handling works just fine, i've come to the point where i would like my custom events to be globally accessible, where the listening object does not need to be the same object that is dispatching the event.
in this example, my main Controller class is instantiating and adding to the display list 2 sprite classes: Square and Triangle. the 4th and final class is a custom event called ColorChangeEvent.
i'm attempting to dispatch a new ColorChangeEvent from the Square class, which uses a timer to dispatch a new random color once every second, while Triangle will listen for the dispatched event and change its fill color to the color that was dispatched by Square.
Controller.as:
package
{
import flash.display.Sprite;
public class Controller extends Sprite
{
public function Controller()
{
var sq:Square = new Square();
sq.x = sq.y = 100;
var tr:Triangle = new Triangle();
tr.x = tr.y = 250;
addChild(sq);
addChild(tr);
}
}
}
Square.as:
package
{
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Square extends Sprite
{
public function Square()
{
graphics.beginFill(0x999999);
graphics.drawRect(0, 0, 100, 100);
graphics.endFill();
var myTimer:Timer = new Timer(1000);
myTimer.addEventListener(TimerEvent.TIMER, dispatchNewColor);
myTimer.start();
}
private function dispatchNewColor(evt:TimerEvent):void
{
var randomColor:Number = Math.random() * 0xFFFFFF;
trace("Square Class Dispatched: " + randomColor);
dispatchEvent(new ColorChangeEvent(ColorChangeEvent.CHANGE, randomColor));
}
}
}
Triangle.as:
package
{
import flash.display.Sprite;
import flash.geom.ColorTransform;
public class Triangle extends Sprite
{
public function Triangle()
{
graphics.beginFill(0x999999);
graphics.moveTo(0, 0);
graphics.lineTo(100, 50);
graphics.lineTo(-50, 150);
graphics.endFill();
addEventListener(ColorChangeEvent.CHANGE, changeColor);
}
private function changeColor(evt:ColorChangeEvent):void
{
var ct:ColorTransform = new ColorTransform;
ct.color = evt.color;
transform.colorTransform = ct;
trace("Triangle Class Received: " + evt.color);
}
}
}
ColorChangeEvent.as:
package
{
import flash.events.Event;
public class ColorChangeEvent extends Event
{
public static const CHANGE:String = "change";
public var color:Number;
public function ColorChangeEvent(type:String, color:Number)
{
super(type);
this.color = color;
}
override public function clone():Event
{
return new ColorChangeEvent(type, color);
}
}
}
needless to say, this isn't working.
of course, i could add the event listener to the Square instance in the Controller class, who's event handler could pass that value to Triangle via a public function to change the color, but this is exactly the kind of limitation i'm trying to avoid.
it's not always easy to access and pass a value to a class from where the custom event is dispatched, which is why i'm looking for an actual global solution to handling custom events.

I have been using this class for some time now. To use it you would do this in square:
data.EventManager.instance.publish("someName", randomColor);
and then in your Triangle:
data.EventManager.instance.subscribe("someName", handleColorChange);
private function handleColorChange(color:Number):void {
// implementation here
}
You can even pass the ColorChangeEvent instead of just the color.
data.EventManager.instance.publish(ColorChangeEvent.CHANGE, new ColorChangeEvent(ColorChangeEvent.CHANGE, randomColor);
And then
data.EventManager.instance.subscribe(ColorChangeEvent.CHANGE, handleColorChange);
private function handleColorChange(colorChangeEvent:ColorChangeEvent):void {
// implement here
}
I removed a lot of code that is specific to my projects, so I am not 100% it is usable exactly as-is. But, you should be able to modify it to get it working correctly. If not, let me know and I can try to work it out with you.
This class handles additional things that I will not go into, though you are free to explore. Be aware, however, that anything that subscribes for event notification has a strong reference by the EventManager. That means that if you want to destroy something for garbage collection, you need to call EventManager.instance.cancel(ColorChangeEvent.CHANGE, handleColorChange) before the Triangle instances can be collected.
package data {
import flash.utils.*;
public class EventManager extends Object {
private var _subscribers:Dictionary;
private var _calls:Dictionary;
private var _feeds:Dictionary;
private var _requests:Dictionary;
private var _notify:Dictionary;
private var _services:Dictionary;
private static var __instance:EventManager;
public function EventManager() {
if (__instance) {
trace("EventManager is a Singleton class which should only be accessed via getInstance()");
}
_feeds = new Dictionary(true);
_subscribers = new Dictionary(true);
_requests = new Dictionary(true);
_services = new Dictionary(true);
_notify = new Dictionary(true);
}
public function getFeedData($name:String) {
if (_feeds[$name]) {
return _feeds[$name];
}
return undefined;
}
public function unpublish($name:String) {
var _post:* = _feeds[$name];
delete _feeds[$name];
return _post;
}
public function cancel($name:String, $subscriberFunc:Function, ...args): void {
var _cnt:Number;
var _subscriberArray:Array;
if (_subscribers[$name]) {
for (_cnt = 0; _cnt < _subscribers[$name].length; _cnt++) {
if (_subscribers[$name][_cnt] == $subscriberFunc) {
_subscribers[$name].splice(_cnt, 1);
}
}
}
if (_requests[$name]) {
_subscriberArray = _requests[$name];
_cnt = _subscriberArray.length;
while (_cnt > 0) {
if (_subscriberArray[_cnt] == $subscriberFunc) {
_subscriberArray.splice(_cnt, 1);
}
_cnt--;
}
}
}
public function subscribe($name:String, $subscriber:Function, ...args): void {
var _funcArray:Array;
var _func:Function;
if (_feeds[$name]) {
$subscriber(_feeds[$name]);
}
if (! _subscribers[$name]) {
_subscribers[$name] = new Array();
}
_subscribers[$name].push($subscriber);
if (_notify[$name]) {
_funcArray = _notify[$name];
for each (_func in _funcArray) {
_func();
}
delete _notify[$name];
}
}
public function request($name:String, $feedFunction:Function): void {
var _requestArray:Array;
var _request:Function;
if (! _feeds[$name]) {
if (! _requests[$name]) {
_requests[$name] = new Array();
}
_requests[$name].push($feedFunction);
} else {
$feedFunction(_feeds[$name]);
}
if (_notify[$name]) {
_requestArray = _notify[$name];
for each (_request in _requestArray) {
_request();
}
delete _notify[$name];
}
}
public function publish($name:String, $data:*, $args:Object = null): void {
var _subscriberArray:Array;
var _func:Function;
var cnt:Number = 0;
_feeds[$name] = $data;
if (_subscribers[$name] != undefined) {
_subscriberArray = _subscribers[$name].slice();
_cnt = 0;
while (_cnt < _subscriberArray.length) {
_func = _subscriberArray[_cnt] as Function;
if ($args) {
_func($data, $args);
}else {
_func($data);
}
_cnt++;
}
}
if (_requests[$name]) {
_subscriberArray = _requests[$name].slice();
delete _requests[$name];
_cnt = 0;
while (_cnt < _subscriberArray.length) {
if (_subscriberArray[_cnt] != null) {
_subscriberArray[_cnt]($data);
}
_cnt++;
}
}
}
public function notify($name:String, $subscriber:Function): void {
if (_requests[$name] || _subscribers[$name]) {
$subscriber();
}else {
if (! _notify[$name]) {
_notify[$name] = new Array();
}
_notify[$name].push($subscriber);
}
}
public static function getInstance(): EventManager {
if (! __instance) {
__instance = new EventManager();
}
return __instance;
}
public static function get instance(): EventManager {
return getInstance();
}
}
}

I got this to work by creating a singleton: EventDispatchSingleton that extends EventDispatcher. It's basically an empty singleton that provides the dispatchEvent and add/removeEventListener methods (these are automatically provided by extending EventDispatcher).
Anywhere I want to dispatch an event I import EventDispatchSingleton and then call EventDispatchSingleton.instance.dispatchEvent(<someEvent>);.
Then, wherever I want to listen to that event, I just import EventDispatchSingleton and call EventDispatchSingleton.instance.addEventListener(eventName, callback);

You should look into event bubbling, specificly I think you will find the Capturing phase of the event propagation useful. Take a read of Event propagation from Adobe LiveDocs. It's in the Flex docs, but it is about AS3 Events.
Also Senocular has a good post on Flash Event Bubbling.

Related

Accessing object parameters from another object actionscript3

in the following video:
http://tv.adobe.com/watch/actionscript-11-with-doug-winnie/communicating-between-classes-episode-52/
he have two instances of object communicating together, both objects were created from Flash profession, and they simply "talk" by using the dot notation.
my program creates the objects dynamically, how can I communicate from one class to another from within the created instances? the creation may be from the main .as file or from within an object created from Main,
is this even possible?
If you can't keep object reference, you may need a third class to be the bridge between the objects.
Here is an example
public class NotifyMgr
{
private static var _instance:NotifyMgr = new NotifyMgr();
public static function getInstance():NotifyMgr
{
return _instance;
}
//send a message
public function sendMessage(msgType:String, data:*):void
{
var observers:Vector.<IObserver> = notifies[msgType] as Vector.<IObserver>;
if (observers == null)
{
return;
}
for each (var obj:IObserver in observers)
{
obj.notify(msgType, data);
}
}
private var notifies:Dictionary = new Dictionary();
//regiter a observer by msgType
public function register(msgType:String, obj:IObsever):void
{
if (notifies[msgType] == null)
{
notifies[msgType] = new Vector.<IObserver>();
}
var observers:Vector.<IObserver> = notifies[msgType] as Vector.<IObserver>;
if (obj != null && observers.indexOf(obj) == -1)
{
observers.push(obj);
}
}
public function unRegister(msgType:String, obj:IObserver):void
{
}
}
/**
*Your object should implement this interface
*/
public interface IObserver
{
function notify(msgType:String, data:*):void;
}
So you could create object A and b that both implement interface IObserver, and register A in NotifyMgr, call NotifyMgr.sendMessage in B,then A will know it.
In this example, Main is your Document Class, and Die is an extension of the Sprite Class. You can call its rollDie() method from within the Main Class because the access modifier is set to public
package{
import flash.display.Sprite;
import flash.events.MouseEvent;
public class Main extends Sprite{
public var die:Die;
public function Main()
{
//create a die
this.die = new Die();
addChild(die);
var button:MovieClip = new MovieClip();
addChild(button);
button.addEventListener(MouseEvent.CLICK, onButtonClick);
}
private function onButtonClick(e:MouseEvent):void
{
this.die.rollDie();
}
}
/**
* Die inherits from Sprite
*/
public class Die extends Sprite {
public function Die() {}
public function rollDie():void
{
var result:int = Math.ceil( Math.random()*6 );
trace("rolling die: " + result);
}
}
}

as3 addEventListner on a function in another class

I have a class calling a function in another class. I want to know
if we can add an Event Listener to know if that function has fired and is finished etc.
Here is the section of the code that is relevant.
myMC = new pictures();
addChild(myMC);
myMC.loadImages("Joyful",1)
// Add Event Listener here to let me know loadImages was called and worked.
As you can see the function is called loadImages() and it is located in a class called pictures.as
Can I add an event listener to this?
Here is a new issue. I am using a similar method and I used your example below and it did not work. Am I missing an import or something? I am only showing the functions that pertain and not my whole script.
Main.class
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.*;
import flash.filesystem.*;
import com.greensock.*;
import com.greensock.easing.*;
import flash.system.System;
// Ed's Scripts
import com.*;
import com.views.*;
public class iRosaryMain extends MovieClip
{
/// (Get Main Doc flow) this creates an instace of the main timeline
/// and then I send it
private static var _instance:iRosaryMain;
public static function get instance():iRosaryMain
{
return _instance;
}
/// Declaring Vars
var audio:audioPrayers;
/// Loading Images
//public var theImages:pictures = new pictures();
/// Movie Clips
public var myMary:beautifulMary;
public var myMC:MovieClip;
public var myPic:MovieClip;
public var myFlags:MovieClip;
public static var mt:MovieClip;
var vars:defaultVars = new defaultVars();
public function iRosaryMain()
{
// (Get Main Doc flow) Here I send the an instacne of iRosaryMain to defaultVars.as
_instance = this;
vars.getMainDoc(_instance);
// Sets timeline to mt :) I hope
mt = _instance;
audio = new audioPrayers();
trace("Jesus I trust in you!");// constructor code
audio.sayHailMary();
if (stage)
{
init();
}
}
public function moveLanguages()
{
/// File to languages folder
var checkLanguageFolder:File = File.applicationStorageDirectory.resolvePath("Languages");
///// CHECK LANGUAGES FOLDER - if not in App Storage move it
if (! checkLanguageFolder.exists)
{
var sourceDir:File = File.applicationDirectory.resolvePath("Languages");
var resultDir:File = File.applicationStorageDirectory.resolvePath("Languages");
sourceDir.copyTo(resultDir, true);
trace( "Moved Language!");
}
}
//// MAIN FUNCTIONS IN iRosaryMainClass
function init()
{
//loadFlags();
moveLanguages();
//addChild(theImages);
intro();
}
public function loadFlags()
{
myFlags.addEventListener("MyEvent", eventHandler);
myFlags = new viewLanguages();
addChild(myFlags);
myFlags.x = stage.stageWidth / 2 - myFlags.getBounds(this).width / 2;
function eventHandler()
{
trace("yes loaded");
TweenMax.fromTo(myMary,3, {alpha:1}, {alpha:0, ease:Quint.easeOut, onComplete: closePic} );
}
}
function intro()
{
myMary = new beautifulMary();
addChild(myMary);
loadFlags();
}
public function closePic()
{
removeChild(myMary);
}
public function languageLoaded(lang:String)
{
trace("YES... " + lang);
homeIn();
}
public function homeIn()
{
if (myFlags)
{
TweenMax.fromTo(myFlags,1, {x:myFlags.x}, {x:0-myFlags.width, ease:Quint.easeInOut, onComplete:unloadMyFlags} );
}
function unloadMyFlags()
{
trace("Called Ease out");
if (myFlags is MovieClip)
{
//trace("CURRENT DISPLAY " + currentDisplayScreen);
trace("CURRENT mc " + myFlags);
removeChild(myFlags);
System.gc();
myFlags = null;
trace("CURRENT mc " + myFlags);
}
}
if (! myMC)
{
myMC = new viewHome();
myMC.name = "Home";
myMC.x = stage.stageWidth / 2 - myMC.width / 2;
addChild(myMC);
}
theEaseIn(myMC);
//Home.B1.addEventListener(MouseEvent.CLICK, theEaseOut(Home));
}
public function loadLanguage(Language:String):Function
{
return function(e:MouseEvent):void ;
{
trace("Did it work? " +Language);
vars.loadButtonVars(Language);;
};
//TweenMax.fromTo(EnglishButton,1, {x:EnglishButton.x}, {x:0-EnglishButton.width, ease:Quint.easeOut} );
}
public function loadView(screen:String)
{
trace("Received " + screen);
if (screen=="Home")
{
myMC = new viewHome();
addChild(myMC);
theEaseIn(myMC);
//Home.B1.addEventListener(MouseEvent.CLICK, theEaseOut(Home));
}
if (screen=="PrayTheRosary")
{
myMC = new viewPrayTheRosary();
addChild(myMC);
theEaseIn(myMC);
//Home.B1.addEventListener(MouseEvent.CLICK, theEaseOut(Home));
}
if (screen=="Options")
{
myMC = new viewOptions();
addChild(myMC);
theEaseIn(myMC);
}
if (screen=="Downloads")
{
myMC = new viewDownloads();
addChild(myMC);
theEaseIn(myMC);
}
if (screen=="beautifulMary")
{
myMC = new beautifulMary();
addChild(myMC);
theEaseIn(myMC);
}
if (screen=="Flags")
{
myFlags = new viewLanguages();
addChild(myFlags);
theEaseIn(myFlags);
}
if (screen=="Joyful" || screen=="Sorrowful" || screen=="Glorious" || screen=="Luminous")
{
myPic = new pictures();
addChild(myPic);
myPic.addEventListener( "ImagesLoaded", doTheEaseIn);
myPic.loadImages(""+screen+"",1);
function doTheEaseIn()
{
theEaseIn(myPic);
}
}
}
public function theEaseIn(mc:MovieClip)
{
if (myMC)
{
TweenMax.fromTo(mc,1, {x:stage.stageWidth+mc.width}, {x:stage.stageWidth/2 - mc.width/2, ease:Quint.easeInOut} );
}
}
public function theEaseOut(mc:MovieClip,nextMC:String):Function
{
return function(e:MouseEvent):void ;
{
loadView(nextMC);
/// Tweens out view on screen
TweenMax.fromTo(mc,1, {x:mc.x}, {x:0-mc.width, ease:Quint.easeInOut, onComplete:unloadMC} );
function unloadMC();
{
trace("Called Ease out");
if(mc is MovieClip);
{
//trace("CURRENT DISPLAY " + currentDisplayScreen);
trace("CURRENT mc " + mc);
removeChild(mc);
System.gc();
myMC = null;
trace("CURRENT mc " + mc);
};
};
};/// end return
}
////////////
}/// End iRosaryMain
}// End Package
viewLanguages.as
package com.views
package com.views
{
import flash.display.MovieClip;
import flash.filesystem.File;
import com.roundFlag;
import flash.events.*;
import flash.display.*;
public class viewLanguages extends MovieClip
{
var Flag:MovieClip;
//public static const FLAGS_LOADED:String = "flagsLoaded";
public function viewLanguages()
{
getLang();
}
function numCheck(num:int):Boolean
{
return (num % 2 != 0);
}
/// Get for App Opening
public function getLang()
{
/// When Live
var folderLanguages:File = File.applicationStorageDirectory.resolvePath("Languages");
var availLang = folderLanguages.getDirectoryListing();
var Lang = new Array();
var LangPath = new Array();
var fl:int = 0;
for (var i:uint = 0; i < availLang.length; i++)
{
if (availLang[i].isDirectory)
{
//flag = new Loader();
//flag.load(new URLRequest(File.applicationStorageDirectory.url + "Languages/" + Lang[i] + "/roundFlag.png"));
Lang.push(availLang[i].name);
LangPath.push(availLang[i].nativePath);
Flag = new roundFlag(availLang[i].name);
Flag.name = availLang[i].name;
if (numCheck(i)==false)
{
Flag.y = fl;
Flag.x = 0;
}
else
{
Flag.y = fl;
Flag.x = Flag.width + 33;
fl = fl + Flag.height + 33;
}
Flag.btext.text = availLang[i].name;
addChild(Flag);
trace(availLang[i].nativePath);// gets the name
trace(availLang[i].name);
}
}
trace("Get Lang Called");
dispatchEvent(new Event("MyEvent"));
}
}
}
Yes, you can. Considering you are adding your clip to the display list I assume it extends either Movieclip or Sprite, both of which extend EventDispatcher. In your pictures class you can simply use dispatchEvent(new Event("MyEvent"); to dispatch an event. Then you could add myMC.addEventListener("MyEvent", eventHandler); to react to it.
You should also not use strings for events like I wrote above. It would be better if you declared a public static const IMAGES_LOADED:String = "imagesLoaded"; in your pictures class. Then you should use this constant by dispatching and by listening to it.
EDIT: Here how it would look with the constant:
//your class
package {
import flash.events.Event;
import flash.display.Sprite;
public class Pictures extends Sprite {
public static const IMAGES_LOADED:String = "imagesLoaded";
public function Pictures() {
}
public function onAllImagesLoaded():void {
dispatchEvent(new Event(IMAGES_LOADED));
}
//rest of your methods
}
}
//you would call it like this:
var myMc:Pictures = new Pictures();
myMc.addEventListener(Pictures.IMAGES_LOADED, onImagesLoaded);
myMc.loadImages();
function onImagesLoaded(e:Event):void {
//...etc
}
You have to create custom event class for this to work. Like:
package com.some
{
import flash.events.Event;
public class SomeEvent extends Event
{
// Loading events
public static const MAINDATA_LOADING:String = "onMainDataLoading";
// Other event
public static const SOME_LOADING:String = "onSomeLoading";
public var params:Object;
public function SomeEvent($type:String, $params:Object, $bubbles:Boolean = false, $cancelable:Boolean = false)
{
super($type, $bubbles, $cancelable);
this.params = $params;
}
public override function clone():Event
{
return new SomeEvent(type, this.params, bubbles, cancelable);
}
}
}
Add event dispatch inside wanted class (Pictures) and pass wanted params to event (this or any else)
dispatchEvent(new SomeEvent(SomeEvent.IMAGES_LOADED, this));
Handle event listening:
var myMc:Pictures = new Pictures();
myMc.addEventListener(SomeEvent.IMAGES_LOADED, onImagesLoaded);
myMc.loadImages();
function onImagesLoaded(e:SomeEvent):void {
// handle event.
var picts:Pictures = (e.params as Pictures);
}

Trying to essentially push details through classes

I am working on a game that creates three circles" red, green, and blue who have 3,2,1 health respectively. They get removed from the stage after their health reaches 0 and it is decremented by 1 per click. I am using a Main.mxml file then I have a Target.as file, as well as RedTarget.as, GreenTarget.as, and BlueTarget.as. My question is that I would like to set everything up in my Target.as file, then push the details such as color, health, and if they are dead or not through those functions. I am having trouble doing that though because I am not sure what I would need in the Target.as and then what I would need to code in each of the colored target files.
Here is my Target.as file:
package com.multiClicker {
//import the needed classes
import flash.display.Shape;
import flash.events.MouseEvent;
import spark.components.Image;
public class Target extends Image {
public function Target() {
//add event listeners
this.addEventListener(MouseEvent.CLICK, onClick);
}
//sets the hp of the target
public function hp():Number {
return hp;
}
//get function that returns false if alpha is <= 0
public function dead():Boolean {
if(alpha <= 0){
return false;
}
return true;
}
//subtracts one from targets HP when clicked
public function onClick(e:MouseEvent = null):void {
//subtracts one from hp each click
hp --;
if(hp <=0) {
this.addEventListener(onEnterFrame);
}
}
//subtracts .1 from the classes alpha
public function onEnterFrame():void{
this.alpha =- .1;
}
//draws the target
public function drawTarget(color):void {
var circle:Shape = new Shape();
circle.graphics.beginFill(color);
circle.graphics.drawCircle(0,0,30);
}
}
}
and then my RedTarget.as file, which is the same as blue and green, except for that they are labeled as such in the variables:
package com.multiClicker {
import flash.events.MouseEvent;
public class RedTarget extends Target{
private var redHP:Number = 3;
private var redDead:Boolean = false;
private var redColor:String = "red";
public function RedTarget()
{
redHP = hp;
redDead = dead;
redColor = color;
//include the super function
super();
}
//subtracts one from targets HP when clicked
override public function onClick(e:MouseEvent=null):void {
super.onClick(e);
//push all to super
}
}
}
Any help on the issue would be great. I have been trying to figure it out throughout the day but have not figured it out.
Are you just asking how to pass variables in when you create the Target object?
public class Target extends Image {
public function Target(hp:Number, dead:Boolean, color:String) {
this.hp = hp;
this.dead = dead;
this.color = color;
}
}
Then you instantiate each target like this:
var redTarget:Target = new Target(3, false, "red");
var greenTarget:Target = new Target(2, false, "green");
etc...

How to call a function from a Class AS3

I'm studying to be a Game Designer, and right now I'm having some issues with my flash game.
the game has a Counter Class, with a Score Class that extends Counter. and it is added to the stage in my PlayScreenA Class.
The Timer starts with a number and decreases every 24frames. but in my Hero Class I can pick up some coins and that coins are going to increase the Time on my Score.
The question is: How I can say in my Hero Class to execute the addToValue function inside the Counter Class?
Pieces of Code:
Creating my score in the PlayScreenA Class:
private var myTime:Score = new Score();
private function create_time (){
myTime.x = 800;
myTime.y = 50;
addChild(myTime);
}
Counter Class:
package
{
import flash.display.MovieClip;
public class Counter extends MovieClip
{
public var currentValue:Number;
public function Counter()
{
reset();
}
public function addToValue( amountToAdd:Number ):void
{
currentValue = currentValue + amountToAdd;
updateDisplay();
}
public function subToValue( amountToSub:Number ):void
{
currentValue = currentValue - amountToSub;
updateDisplay();
}
public function reset():void
{
currentValue = 20;
updateDisplay();
}
public function updateDisplay():void
{
}
}
}
Score Class:
package
{
import flash.text.TextField;
import flash.events.Event;
public class Score extends Counter
{
protected var _timeCounter:int;
public function Score()
{
super();
addEventListener(Event.ENTER_FRAME, onUpdate);
}
override public function updateDisplay():void
{
super.updateDisplay();
scoreDisplay.text = currentValue.toString();
}
protected function onUpdate(e:Event):void
{
_timeCounter++;
trace(currentValue);
if (_timeCounter == 24)
{
this.subToValue( 1 );
_timeCounter = 0;
}
}
}
}
Piece of my Hero Class where I need to Call the function:
for(var i:int; i<collisionList.length;i++)
{
var $collision:platform_tile = collisionList[i];
if($hasCollided = hitbox.hitTestObject($collision.hitBox) && $collision.alpha<0.8 && $collision.alpha>0.6)
{
$collision.alpha=0;
$collision.visible = false;
//Here is where I want to call my subToValue function!
break;
}
since addToValue and subToValue are instance methods, you should provide a reference (an instance variable) to the counter object in your hero object, then call its addToValue or subToValue methods.
var theCounter:Counter;
you should either initiate this in your hero object, or assign a pre-existing counter object through getter/setters. then you can call:
theCounter.addToValue();
I assume you are trying to access the object of Score class created initially in the PlayerScreenA class...
If that is the case then you either derive a relationship between the two classes to pass this object or you could keep a static class keeping track of the function at a global level...
public class AppRefrences
{
public static var addToValueFunc:Function;
}
In Player A Class,
private var myTime:Score = new Score();
private function create_time (){
myTime.x = 800;
myTime.y = 50;
addChild(myTime);
// This is where you set the function
Apprefrences.addToValueFunc = myTime.addToValue;
}
In Hero Class,
for(var i:int; i<collisionList.length;i++)
{
var $collision:platform_tile = collisionList[i];
if($hasCollided = hitbox.hitTestObject($collision.hitBox) && $collision.alpha<0.8 && $collision.alpha>0.6)
{
$collision.alpha=0;
$collision.visible = false;
// This is where you call the function
if(AppRefrences.addToValueFunc != null)
AppRefrences.addToValueFunc(0);
break;
}
Try using getter & setters to control the update of the static variable. I didn't include it for the sake of clarity.

Definition fl.video.FLVPlayback could not be found

I'm stumped. I have two flash files I'm authoring.
File A has a MovieClip on stage that has a linkage to a class in which I import fl.video.FLVPlayback
File B also attempts to import fl.video.FLVPlayback.
File B throws a COMPILE TIME error that it cannot locate the definition for fl.video.FLVPlayback. I'm noticing that my FlashDevelop also offers no syntax highlighting for that line.
Both are exporting for the same version of FlashPlayer (10). Both are being authored on the same platform, the same software (CS4).I have not messed with any Publish settings, other than that File B is associated with a Document Class.
Of interest may be that File A will eventually be loaded into File B, into the context of File B.
What is up? I have no idea where to even start looking.
Thanks in advance.
If you're not using the FLVPlayback component (dragged from the component library onto the stage), then Flash does not have access to the fl package out of the box for publishing.
You would have to include either the component source folder or .swc on your class path (source folder would go in the "Source Path" tab of your as3 publish settings, .swc in the "Library Path" tab) in order for your class to work.
The source folder is:
C:\Program Files (x86)\Adobe\Adobe Flash CS4\Common\Configuration\Component Source\ActionScript 3.0\FLVPlayback
The .swc is in the directory:
C:\Program Files (x86)\Adobe\Adobe Flash CS4\Common\Configuration\Components\Video
The swc is probably easier to include as you can copy and paste the .swc directly into your project folder if you like.
Building on Sapptime's answer, I would like to add that you can create different profiles under Publish Settings.
So you can make a profile which includes the FLVPlayback component by importing the .swc file and use that profile when you need to work with the FLVPlayer. Adds about 100 KB to the project.
This way you don't need a FLVPlayback component in your library or on your stage. Instead, you can import the FLVPlayback class like any other class in your project and make instances of FLVPlayback in your actionscript code.
//import:
import fl.video.FLVPlayback;
//Instantiate:
private var player:FLVPlayback = new FLVPlayback();
I have added a Videoplayer.as class (because I can't find a way to attach it) I made for a project and stripped it quick and dirty for some additional content, but it should work :) Feel free to use it as is, modify it or get some inspiration.
Put Videoplayer.as in the src folder of your project and make a new instance of it. Use the setters to control it.
//Instantiate
var MyPLayer:Videoplayer = new Videoplayer();
//Use setters
MyPLayer.SetVideopath = path to flv file;
MyPLayer.SetVideoAutoplay = true; // or false
//... and so on
// add to displaylist
this.addChild(MyPlayer);
// Load video
MyPlayer.Load();
// start playing
MyPlayer.Play();
and here is the Videoplayer class...
package {
import fl.video.*;
import flash.events.*;
import flash.display.Sprite;
import flash.display.Shape;
public class Videoplayer extends Sprite {
// VIDEO
private var player:FLVPlayback = new FLVPlayback();
private static var videoPath:String="";
private var w:Number = 1280;
private var h:Number = 720;
private var vol:Number = 0;
private var autoplay:Boolean = false;
private var autorewind:Boolean = false;
private var Loop:Boolean = false;
private var bgcolor:uint = 0x000000;
private var HasError:Boolean=false;
private var playerid:Number;
private var SeekSecToStop:Number=0;
private var BufferTime:Number=0;
private var videoBG:Shape;
// ===============================================================================================
// CONSTRUCTOR
// ===============================================================================================
public function Videoplayer() {
super();
trace("Videoplayer");
this.addChild(player);
player.addEventListener(VideoEvent.STATE_CHANGE, VidState, false, 0, true);
player.addEventListener(VideoEvent.READY, VidReady, false, 0, true);
player.addEventListener(VideoEvent.AUTO_REWOUND, VidRewinded, false, 0, true);
player.addEventListener(VideoEvent.STOPPED_STATE_ENTERED, VidStopped, false,0,true);
}
// ===============================================================================================
// SET VIDEO PROPS
// ===============================================================================================
private function setVidProps():void {
player.name = "player";
player.skinBackgroundColor = getVideoBGcolor;
player.skinBackgroundAlpha = 0;
player.registrationX = 0;
player.registrationY = 0;
player.setSize(getVideoWidth,getVideoHeight);
player.scaleMode = "maintainAspectRatio"; // exactFit, noScale, maintainAspectRatio
//player.fullScreenTakeOver = false;
player.isLive = false;
player.bufferTime = BufferTime;
player.autoRewind = getVideoAutorewind;
player.volume = vol;
}
// ===============================================================================================
// LOAD
// ===============================================================================================
public function Load():void {
trace("Load");
setVidProps();
player.source = getVideopath;
}
// ===============================================================================================
// PLAY
// ===============================================================================================
public function Play():void {
player.playWhenEnoughDownloaded();
UnMute();
}
public function Pause():void {
player.pause();
}
public function Stop():void {
//player.seek(SeekSecToStop);
player.stop();
//player.pause();
}
public function SeekAndStop():void {
player.seek(SeekSecToStop);
player.pause();
}
public function SeekAndPlay(n:Number=0):void {
player.seek(n);
Play();
}
public function Fullscreen():void {
//player.fullScreenTakeOver = true;
//player
}
public function Mute():void {
player.volume = 0;
}
public function UnMute():void {
player.volume = 1;
}
public function Volume(n:Number):void {
player.volume=n;
}
// ===============================================================================================
// VidReady
// ===============================================================================================
private function VidReady(e:Event):void {
trace("VidReady");
//player.removeEventListener(VideoEvent.READY, VidReady);
player.fullScreenTakeOver = false;
if (autoplay) {
player.autoPlay = autoplay;
Play();
} else {
player.play();
SeekAndStop();
}
dispatchEvent(new VideoEvent(VideoEvent.READY));
}
// ===============================================================================================
// VidStopped
// ===============================================================================================
private function VidStopped(e:Event):void {
trace("VidStopped");
//dispatchEvent(new VideoEvent(VideoEvent.STOPPED));
if(Loop) {
//SeekAndPlay();
Play();
} else {
dispatchEvent(new VideoEvent(VideoEvent.STOPPED_STATE_ENTERED));
}
}
// ===============================================================================================
// VidRewinded
// ===============================================================================================
private function VidRewinded(e:Event):void {
trace("VidRewinded");
}
// ===============================================================================================
// VidState
// ===============================================================================================
private function VidState(e:Event):void {
var flvPlayer:FLVPlayback = e.currentTarget as FLVPlayback;
//Log("VideoState 1 : "+flvPlayer.state);
if (flvPlayer.state==VideoState.CONNECTION_ERROR) {
trace("FLVPlayer Connection Error! -> path : "+flvPlayer.source);
//dispatchEvent(new VideoEvent(VideoEvent.CONNECTION_ERROR));
HasError=true;
//CleanUp();
} else if (flvPlayer.state==VideoState.BUFFERING) {
trace("BUFFERING");
} else if (flvPlayer.state==VideoState.DISCONNECTED) {
trace("DISCONNECTED");
} else if (flvPlayer.state==VideoState.LOADING) {
trace("LOADING");
} else if (flvPlayer.state==VideoState.PAUSED) {
trace("PAUSED");
} else if (flvPlayer.state==VideoState.RESIZING) {
trace("RESIZING");
} else if (flvPlayer.state==VideoState.REWINDING) {
trace("REWINDING");
} else if (flvPlayer.state==VideoState.SEEKING) {
trace("SEEKING");
} else if (flvPlayer.state==VideoState.PLAYING) {
trace("PLAYING");
} else if (flvPlayer.state==VideoState.STOPPED) {
trace("STOPPED");
//flvPlayer.pause();
} else if (flvPlayer.state==VideoState.RESIZING) {
trace("RESIZING");
}
}
// ===============================================================================================
// SETTERS & GETTERS
// ===============================================================================================
public function set SetPlayerId(n:Number):void {
playerid=n;
}
public function get getPlayerId():Number {
return playerid;
}
public function set SetSeekSecToStop(n:Number):void {
SeekSecToStop=n;
}
public function get getSeekSecToStop():Number {
return SeekSecToStop;
}
public function set SetVideoLoop(b:Boolean):void {
Loop = b;
}
public function get getVideoLoop():Boolean {
return Loop;
}
public function set SetVideoAutorewind(b:Boolean):void {
autorewind = b;
}
public function get getVideoAutorewind():Boolean {
return autorewind;
}
public function set SetVideoAutoplay(b:Boolean):void {
autoplay = b;
}
public function get getVideoAutoplay():Boolean {
return autoplay;
}
public function set SetVideopath(s:String):void {
videoPath = s;
}
public function get getVideopath():String {
return videoPath;
}
public function set SetVideoWidth(n:Number):void {
w = n;
}
public function get getVideoWidth():Number {
return w;
}
public function set SetVideoHeight(n:Number):void {
h = n;
}
public function get getVideoHeight():Number {
return h;
}
public function set SetVideoBGcolor(n:uint):void {
bgcolor = n;
}
public function get getVideoBGcolor():uint {
return bgcolor;
}
public function get getPlayerState():String {
return player.state;
}
public function get GetHasError():Boolean {
return HasError;
}
}
}
You need to make sure that the FLVPlayback component is present in you library and exported for ActionScript (which should be the default setting).
To add it to the library, simply open the Components panel (Window -> Components) and expand the group named Video and drag FLVPlayback in your library. No need to put it on the stage.
It should be exported by default as "fl.video.FLVPlayback".
Cheers