addEventListener ENTER_FRAME - actionscript-3

when I try to make a addEventListener I get an error:
Line 20 1046: Type was not found or was not a compile-time constant: Event.
package player {
import flash.media.Sound;
import flash.net.URLRequest;
public class Stream {
private var _Sound = null;
private var _Channel = null;
function Stream(){
this._Sound = new Sound();
}
public function play(url){
this._Sound.load(new URLRequest(url));
this._Channel = this._Sound.play();
this.addEventListener(Event.ENTER_FRAME, this.myFunction);
}
private function myFunction(e:Event){
}
}
}

import flash.events.Event; goes at the top under package player {.
You need to import the event before using it.
Update:
package player {
import flash.events.Event;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.display.Sprite;
public class Stream extends Sprite {
private var _Sound = null;
private var _Channel = null;
public function Stream(){
this._Sound = new Sound();
}
public function play(url){
this._Sound.load(new URLRequest(url));
this._Channel = this._Sound.play();
this.addEventListener(Event.ENTER_FRAME, this.myFunction);
}
private function myFunction(e:Event){
}
}
}
Use this code. Generally, you want to add an ENTER_FRAME event to a display object. The Sprite class is a display object. I'm making it a Sprite by using the extends keyword. Please note that you need to import the class you're extending, as I've done.

The instruction:
this.addEventListener(Event.ENTER_FRAME, this.myFunction);
uses this to self-reference the player instance, but this.myFunction is redundant since myFunction is already a method belonging to the player instance.
Instead use:
this.addEventListener(Event.ENTER_FRAME, myFunction);

Related

Actionscript 3 - Class Referring Errors

I a document class (Main) and a class connected to a symbol (MainMenu), and I get an error I just can't figure how to solve.. I get this error:
1136: Incorrect number of arguments. Expected 1.
it is reffering to "public var mainMenu = new MainMenu();" in my document class.
Anyways, here are my classes:
Main(document class):
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class Main extends MovieClip {
public var mainMenu = new MainMenu();
public function Main() {
// constructor code
startGame();
}
public function startGame(){
addChild(mainMenu);
}
public function initGame(event){
//Adding player and such..
}
}
}
MainMenu:
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class MainMenu extends MovieClip {
private var logo = new Logo();
public function MainMenu(main:Main) {
// constructor code
mainMenu = new MainMenu(this);
logo.addEventListener(MouseEvent.CLICK, main.initGame);
placeButtons(event);
}
public function placeButtons(event:Event){
logo.addEventListener(MouseEvent.CLICK, initGame);
logo.x = - logo.width/2;
logo.y = 50;
addChild(logo);
trace ("MainMenu added");
}
}
}
Thanks
A few pointers...
Be mindful of your indentation.
Datatype your variables, arguments, and function returns.
Your MainMenu class was self instantiating itself (that's an infinite loop)
If you really need direct access to another classes function, consider making the child class extend the parent class. Alternatively, you could make the specific function a static function and call the function directly off the class without passing variable references. For example: Main.initGame()
Here are your classes, with a potential solution...
Main:
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class Main extends MovieClip {
public var mainMenu:MainMenu;
public function Main() {
mainMenu = new MainMenu();
addChild(mainMenu);
}
public function initGame(e:Event):void {
//Adding player and such..
}
}
}
MainMenu:
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class MainMenu extends MovieClip {
private var logo:Logo;
public function MainMenu() {
// Wait for it to be added to the parent.
logo = new Logo();
addChild(logo);
addEventListener(Event.ADDED_TO_STAGE, placeButton);
}
private function placeButton(e:Event):void {
// We only need this to happen once, so remove the listener
removeEventListener(Event.ADDED_TO_STAGE, placeButton);
// Now that we've formed the connection, we can reference the function dynamically
logo.addEventListener(MouseEvent.CLICK, this["parent"].initGame);
logo.x = - logo.width/2;
logo.y = 50;
}
}
}
I've left the structure as similar to your original intent as possible, but the above function reference is poor form. As a general rule, children should not have connections to their parents as it's a potential memory leak. You might instead add the event listener from your Main class.

AS3: ReferenceError: Error #1069:

I'm trying to load a sound file into my Flash project. I keep getting this error however.
ReferenceError:
Error #1069: Property COMPLETE not found on flash.events.Event and there is no default value. at LoadSND/soundLoaded()[C:\Users\Admin\Desktop\Final Project\LoadSND.as:38]
The relevant code:
package {
import flash.events.*;
import flash.media.*;
import flash.net.URLRequest;
public class LoadSND {
//declare variables
private var sndTrack: Sound;
private var sndChannel: SoundChannel;
private var sndVolume: Number;
private var newTrack: String;
private var canRepeat: Boolean;
public function LoadSND(myTrack: String, myRepeat: Boolean = true) {
// constructor code
// set a default volume and track
sndVolume = 0.5;
setTrackData(myTrack, myRepeat);
}
private function loadSound(): void {
// first stop all old sounds playing
SoundMixer.stopAll();
// create a new sound for the track and a new sound channel
sndTrack = new Sound();
sndChannel = new SoundChannel();
// load the required sound
sndTrack.load(new URLRequest(newTrack));
// when loaded – play it;
sndTrack.addEventListener(Event.COMPLETE, soundLoaded);
}
private function soundLoaded(Event): void {
// finished with this listener so remove it
sndTrack.removeEventListener(Event.COMPLETE, soundLoaded);
// call the play sound function
playSound();
}
private function playSound(): void {
// assign music to the musicChannel and play it
sndChannel = sndTrack.play();
// setting the volume control property to the sound channel
sndChannel.soundTransform = new SoundTransform(sndVolume, 0);
// but add this one to make repeats
sndChannel.addEventListener(Event.SOUND_COMPLETE, playAgain);
}
private function playAgain(Event): void {
// remove this listener and repeat playSound()
sndChannel.removeEventListener(Event.SOUND_COMPLETE, playAgain);
playSound();
}
private function setTrackData(myTrack: String, myRepeat: Boolean): void {
// update the new track information
newTrack = myTrack;
canRepeat = myRepeat;
// and load it
loadSound();
}
private function setVolumeLevel(Number): void {
}
} //end class
} //end package
Loading a default track through my Main.as
package {
import flash.display.MovieClip;
import flash.text.TextField;
import flash.display.SimpleButton;
import flash.utils.Dictionary;
import flash.text.TextFormat;
import flash.net.*;
import flash.events.*;
import fl.controls.*;
import flash.media.*;
import fl.events.ComponentEvent;
import fl.managers.StyleManager;
import fl.data.DataProvider;
import fl.data.SimpleCollectionItem;
import fl.managers.StyleManager;
import fl.events.ComponentEvent;
import flash.events.Event;
import flash.net.SharedObject;
import LoadSWF;
import GameButton;
import LoadSND;
public class Main extends MovieClip {
//Sound Variables
private var MAX_TRAX: int = 7;
private var MAX_SFX: int = 9;
private var sndPath: String;
private var sndTrack: LoadSND;
private var isMuted: Boolean;
private var canRepeat: Boolean;
private var sndVolume: Number;
public function Main() {
// constructor code
sndPath = "musicSFX/Fury.mp3";
isMuted = false;
sndTrack = new LoadSND(sndPath, canRepeat);
}
Any help is appreciated :) Thanks
The problem lies in the definition of soundLoaded function. You put just class in there instead of argument with type declaration. It should be solved if you adjust definition of the soundLoaded function in the following way:
private function soundLoaded(event:Event): void
By the way same problem is in functions playAgain and setVolumeLevel.

Using stage.addEventListener inside a class is returning a null object reference during runtime

I want to add an event listener to the stage from inside a class called "ChoiceBtn".
I get the error "1009: Cannot access a property or method of a null object reference". I understand that this is because the object is not yet instantiated.
Here is my code:
My main document code:
import ChoiceBtn;
var op1:ChoiceBtn = new ChoiceBtn("display meee", answer, 1, "a)", "4.jpg");
op1.x = 250;
op1.y = 60;
stage.addChild(op1);
My Class file:
package {
import AnswerEvent;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.events.*;
import flash.ui.Mouse;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.net.URLRequest;
import flash.display.Stage;
public class ChoiceBtn extends Sprite{
public var path:String;
public var choiceText:String;
public var choiceLabel:String;
private var answer:Answer;
private var choiceNum:uint;
private var textFormat:TextFormat = new TextFormat();
private var choiceLabelHwd:TextField = new TextField();
private var choiceTextHwd:TextField = new TextField();
private var boundingRect:Sprite = new Sprite;
private var hitAreaWidth = 255;
private var hitAreaHeight = 45;
private var pic:Loader = new Loader;
public function ChoiceBtn(choiceText:String, answer:Answer, choiceNum:uint, choiceLabel:String = "a)", picPath:String = null) {
//path - must be the path to a picture
//choiceText - the text to be displayed
//choiceLabel - the prefix selector such as answers '1' or 'a)' etc.
// constructor code
this.answer = answer;
this.choiceNum = choiceNum;
this.choiceLabel = choiceLabel;
this.choiceText = choiceText;
//add childs
addChild(this.choiceTextHwd);
addChild(this.choiceLabelHwd);
addChild(this.boundingRect); //must be added last so is on top of everything else
//add Listeners
//stage.addEventListener(AnswerEvent.EVENT_ANSWERED, update); //doesn't work
stage.addEventListener(AnswerEvent.EVENT_ANSWERED, this.update); //doesn't work either
}
public function update(e:Event):void {
trace("in choice fired");
}
}
}
I don't understand why it doesn't work even when I use this before the function. How can I create the eventlistener on the stage in this classes constructor code and reference a function inside this class.
Wait for the ADDED_TO_STAGE event to fire first:
public function ChoiceButton():void
{
// your code.. etc..
addEventListener(Event.ADDED_TO_STAGE,addListeners);
}
private function addListeners(event:Event):void
{
stage.addEventListener(AnswerEvent.EVENT_ANSWERED, update);
}

AS3 I don't understand the different treatment of an extended movieclip class vs extended simplebutton class

I recently discovered the custom classes in actionscript 3. I started using them in my latest project but I find it hard to bend my brain around how it all works.
I created two different classes to test.
One is an extended movieclip called "Persoon" and the other is an extended simplebutton called "SpeakerBtn".
package {
import flash.display.Sprite;
public class Persoon extends Sprite {
public function Persoon(xPos:Number, yPos:Number, naam:String) {
var persoon:Sprite = new Sprite;
persoon.graphics.beginFill(0x000000,1);
persoon.graphics.drawCircle(xPos, yPos, 2);
persoon.graphics.endFill();
this.addChild(persoon);
trace ("hij heet " + naam);
}
}
}
package {
import flash.display.SimpleButton;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
public class SpeakerBtn extends SimpleButton {
public var snd:Sound;
public var cnl:SoundChannel = new SoundChannel();
public function SpeakerBtn(xp:Number,yp:Number,naam:String) {
var speaker:SimpleButton = new SimpleButton();
speaker.name = naam;
speaker.x = xp;
speaker.y = yp;
speaker.addEventListener(MouseEvent.CLICK, playSnd);
//this.addChild(speaker);
}
public function playSnd (event:MouseEvent) : void {
trace ("ping");
}
}
}
Then I have my main:
package {
import flash.display.MovieClip;
import SpeakerBtn;
import flash.display.SimpleButton;
import Persoon;
public class Main extends MovieClip {
var sp:SpeakerBtn;
var ps:Persoon;
public function Main() {
sp = new SpeakerBtn(50,50,"donna");
addChild(sp);
ps = new Persoon(300,300,"wilf");
addChild(ps);
}
}
}
Persoon wilf works like I expected, displays fine and traces correctly.
SpeakerBtn donna does not display and does not trace correctly. I commented out the addChild in the SpeakerBtn package because if I turn it on, I get the error 1061: Call to a possibly undefined method addChild through a reference with static type SpeakerBtn
I noticed that when I define the x and the y and addChild in Main for the speakerBtn it does work. But I don't want to have to define all that in Main, I want my SpeakerBtn to do all that.
I checked this question but it does not provide me with an answer. Can someone explain to me what is happening, or alternatively link me to a comprehensible tutorial (one not too heavy on techspeak, more like an explain-it-to-me-like-I'm-5-years-old)? Thanks!
Update
I forgot to add a button with the class SpeakerBtn to my library, so there was nothing to display. Fixed that now, and with this code the button does appear on the stage, only the x and y values are not registered and it appears on 0,0. Also, the event playSnd does not trigger the trace and I assume is not working.
Solution
With help of Cherniv's information I came to the following solution for my SpeakerBtn.
Main does this:
package {
import flash.display.MovieClip;
import SpeakerBtn;
import flash.display.SimpleButton;
public class Main extends MovieClip {
var sp:SpeakerBtn;
public function Main() {
sp = new SpeakerBtn("donna", 300, 50);
addChild(sp);
}
}
}
And SpeakerBtn does this:
package {
import flash.display.SimpleButton;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
public class SpeakerBtn extends SimpleButton {
private var snd:Sound;
private var cnl:SoundChannel = new SoundChannel();
private var _naam:String;
private var _x:Number;
private var _y:Number;
public function SpeakerBtn(naam:String, xp:Number, yp:Number) {
_naam = naam;
_x = xp;
_y = yp;
addEventListener(Event.ADDED_TO_STAGE, addBtn);
}
private function addBtn (event:Event) : void {
this.x = _x;
this.y = _y;
this.name = _naam;
snd = new Sound(new URLRequest("mp3/" + _naam + ".mp3"));
addEventListener(MouseEvent.CLICK, playSnd);
}
private function playSnd (event:MouseEvent) : void {
cnl = snd.play();
}
}
}
So what I did was add an EventListener for when the button was added to the stage and then set all the variables like x-position, y-position and name.
That's because of inheritance. Your SpeakerBtn doesn't inherits the addChild method from his ancestors , because as we can see in SimpleButton's documentation it is inheritor of DisplayObject and not of DisplayObjectContainer , which do have a addChild method and passes it to all his inheritors including MovieClip and Persoon.

Event listener on button not working

So, my menu for my game is in a separate .fla file and I have used a loader like so to load the menu into my game:
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.ui.Mouse;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.system.LoaderContext;
import flash.display.Sprite;
import flash.net.Socket;
import caurina.transitions.Tweener;
public class Main extends MovieClip {
public static var gameLayer:Sprite = new Sprite;
public static var endGameLayer:Sprite = new Sprite;
public static var menuLayer:Sprite = new Sprite;
public var gameTime:int;
public var levelDuration:int;
public function Main()
{
addChild(gameLayer);
addChild(endGameLayer);
addChild(menuLayer);
var myMenu:Loader = new Loader();
var url:URLRequest = new URLRequest("Menu.swf");
myMenu.load(url);
myMenu.contentLoaderInfo.addEventListener(Event.COMPLETE, menuLoaded);
function menuLoaded(event:Event):void
{
menuLayer.addChild(myMenu.content);
}
playBtn.addEventListener(MouseEvent.CLICK, startGame);
}
public function startGame(e:Event)
{
// Code to remove the menu (menuLayer.removeChild?)
// Code here to start timers etc
}
I set instance names for my buttons but when I try to do something like menuLayer.playBtn.addEventListener(MouseEvent.CLICK, startGame);, I get messages saying Access of undefined property playBtn.
Now, I double checked on my Menu.fla and I definitely gave the button an instance name of playBtn but it's not working. Any help please? Might be something really obvious I've missed but I'm not sure what.
EDIT: Trying it another way (Converting the menu to a movieclip) but not 100% sure how to do it exactly. The code I have is:
public class Main extends MovieClip {
var mainMenu:menuMain = new menuMain;
// Other variables
public function Main()
{
addChild(gameLayer);
addChild(endGameLayer);
addChild(menuLayer);
menuLayer.addChild(mainMenu);
mainMenu.addEventListener(Event.COMPLETE, menuLoaded);
}
function menuLoaded(event:Event):void
{
//var mainMenu:LoaderInfo = event.currentTarget as LoaderInfo;
//var menuInstance:MovieClip = menuLayer.getChildAt(0) as MovieClip;
// now you can actually add the listener, because the content is actually loaded
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
}
public function startGame(e:Event)
{
// Code to execute timers etc.
}
My guess is that you think that when you go menuLayer.addChild(myMenu.content) that menuLayer suddenly becomes an instance of menu.swf That is not the case. It becomes a child of menuLayer.
Try this :
menuLayer.addChild(myMenu.content);
var menuInstance:MovieClip = menuLayer.getChildAt(0) as MovieClip;
trace (menuInstance.playBtn);
This code assumes that you have nothing else added to menuLayer and in that case your menu.swf content would be the only child on the display list of menuLayer.
I am also assuming that menu.swf's contents are a MovieClip.
If my assumptions are wrong, this may not work.
I also noticed that you have your menuLoaded method inside your constructor. Not a good idea. Especially since the next line is expecting playBtn to exist and the menu hasn't even been loaded.
Try something like this :
public function Main()
{
addChild(gameLayer);
addChild(endGameLayer);
addChild(menuLayer);
var myMenu:Loader = new Loader();
var url:URLRequest = new URLRequest("Menu.swf");
myMenu.load(url);
myMenu.contentLoaderInfo.addEventListener(Event.COMPLETE, menuLoaded);
}
function menuLoaded(event:Event):void
{
var myMenu:LoaderInfo = event.currentTarget as LoaderInfo;
menuLayer.addChild(myMenu.content);
var menuInstance:MovieClip = menuLayer.getChildAt(0) as MovieClip;
// now you can actually add the listener, because the content is actually loaded
menuInstance.playBtn.addEventListener(MouseEvent.CLICK, startGame);
}
public function startGame(e:Event)
{
// Code to remove the menu (menuLayer.removeChild?)
// Code here to start timers etc
}