How to make a class remove itself? - actionscript-3

I'm creating a game over screen and there is a retry button on it, when that button is clicked, the game over screen remove itself. I tried "this.visible = false;" but it doesn't seems to work. When I first restart the game, it works fine, the game over screen is gone. But when I restart the game for the second time, the game over screen is here again, it just keeps coming back after the first restart! So how to make the retry button to check the game over screen is on stage and if so then remove it? Any help is greatly appreciated!
package objects {
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.*
public class GameOverMenu extends BaseMenu {
public function GameOverMenu(stageRef: Stage = null) {
this.stageRef = stageRef;
btnRetry.addEventListener(MouseEvent.MOUSE_DOWN, returnSelectionMenu, false, 0, true);
}
private function returnSelectionMenu(e: MouseEvent): void {
unload(new SelectionMenu(stageRef));
this.visible = false;
}
}
}

Related

How do I load MovieClip containing FLV without stuttering

So I have var MC_1 which is Movieclip that contains FLV on its timeline. MC_1 is supposed to appear on screen when user presses SPACE. It is working, except that before MC_1 is done loading on screen, its almost played itself once, showing you last seconds and then starting its second loop.
How do I make it so that it plays itself only when it has done loading? Here's simplified code:
package comm {
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import flash.system.*;
import comm.*;
import comm.assets.*;
public class main {
public var MC_1:comm.assets.intro_video = new comm.assets.intro_video();
public var cutscene_container:Sprite = new Sprite();
public function main() {
addChild(cutscene_container);
stage.addEventListener(KeyboardEvent.KEY_DOWN, introstart_handler);
function introstart_handler(event:KeyboardEvent){
if(event.keyCode == 32){
cutscene_container.addChild(MC_1);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, introstart_handler);
}
}
}
}
}
I hope I explained my question clearly enough :P Cheers!
Came up with solution to my problem. Thought it nice to share if anyone else is having same problem:
package comm {
import flash.display.*;
import flash.events.*;
import flash.ui.*;
import flash.system.*;
import comm.*;
import comm.assets.*;
public class main {
public var MC_1:comm.assets.intro_video = new comm.assets.intro_video();
public var cutscene_container:Sprite = new Sprite();
public function main() {
addChild(cutscene_container);
cutscene_container.addChild(MC_1);
MC_1.visible = false;
MC_1.gotoAndStop(1);
stage.addEventListener(KeyboardEvent.KEY_DOWN, introstart_handler);
function introstart_handler(event:KeyboardEvent){
if(event.keyCode == 32){
MC_1.visible = true;
MC_1.gotoAndPlay(1);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, introstart_handler);
}
}
}
}
}
MC_1 is added to stage/container, stopped and invisible before it is needed. When it is needed (SPACE button press here) it is made visible and it will be played from frame 1.
Hope this helps if anyone else is having trouble with stuttering animation in form of FLV inside a MovieClip.
It surely did solve my problem.

Why should I use preloader in Flash

I do not have quite knowledge about preloaders but I have read couple of articles and Adobe instructions. So I am confused about preloaders using in Flash applications.
I am planning to call all MovieClips, sounds, and etc. from library and nothing will be on the stage. For this situation, is it logical to apply preloader, if so which approach will be the most suitable one (even with smaller swf sizes)?
It's impossible to tell you which approach is the best when you're not telling the context of your application.
For banners and smaller swf ( <100k) etc I shouldn't use any sort of a preloader. Flash will handle the loading itself (only without showing a visual loader)
For bigger swf games I normally let one small swf loads the main swf.
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
[SWF(width="992", height="768", frameRate="30", backgroundColor="0x000000")]
public class Preloader extends Sprite
{
private var percent:Number;
private var loader:Loader;
public function Preloader()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var movieurl:String = loaderInfo.parameters.movieurl;
loader = new Loader();
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
var loaderContext : LoaderContext = new LoaderContext(false,new ApplicationDomain(null));
loader.load( new URLRequest("main.swf" + version),loaderContext);
}
private function progressHandler(event:ProgressEvent):void
{
percent = ((event.bytesLoaded / event.bytesTotal)*100);
trace ("laoded": percent)
}
private function completeHandler(event:Event):void{
//removeChild(progressBar);
addChild(loader);
}
}
}
If your application must exist of 1 swf. You could use a Preloader class
main swf class
[Frame(factoryClass="Preloader")]
[SWF(width = "950", height = "600")]
public class Main extends Sprite
{
// do your coding
}
preloader swf class
package {
import erasmus.simulation.LoaderFC;
import flash.display.DisplayObject;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.UncaughtErrorEvent;
import flash.utils.getDefinitionByName;
public class Preloader extends MovieClip {
public function Preloader(){
if (stage){
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
}
addEventListener(Event.ENTER_FRAME, checkFrame);
loaderInfo.addEventListener(ProgressEvent.PROGRESS, progress);
loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError);
}
private function progress(e:ProgressEvent):void {
var progress : Number = e.bytesLoaded / e.bytesTotal;
trace ("loader progress")
}
private function checkFrame(e:Event):void {
if (currentFrame == totalFrames){
stop();
loadingFinished();
}
}
private function loadingFinished():void {
removeEventListener(Event.ENTER_FRAME, checkFrame);
loaderInfo.removeEventListener(ProgressEvent.PROGRESS, progress);
loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioError);
var mainClass:Class = getDefinitionByName('Main') as Class; // class must be a string reference
this.stage.addChild(new mainClass(this) as DisplayObject);
}
}
}
Nothing will be on stage - by that I assume you're using Flash IDE with timeline?
In this case (as well as other cases, in fact) you must use the preloader. There is a possibility (even when running locally) that when you try to access something from the library, it will not be fully loaded yet.
In Flash IDE a preloader can be first two frames in the timeline: some progress sprite or just a TextField that spans two frames, first frame does nothing, second frame checks bytesLoaded vs. bytesTotal and goes to first frame if the movie is not fully loaded yet. The third frame is where all main code starts.
Note that all your library assets must be set for 'export in Frame 3', i.e. not in any of frames where loader is active.
Alternately, you can use single frame with event-based loader.
When using FlashDevelop, there is a ready-made template for a project with a preloader.
There is a common mistake when people use some of their library classes or assets in the preloader to show a nice progress indicator. In that case, all that data has to be loaded first, and preloader cannot work immediately. It looks like empty screen with long pause and no preloader, and then the application is 100% loaded at once. So the preloader becomes pointless, it can't show any progress to the user.

Starling library - When I try and change cursor to image...it doesn't work (and a sprite element dissapears from stage)

I am using Starling to make a really, really, really easy game - I am just trying to add a stationary sprite to the stage...and make it so that when the mouse touches the sprite...the game "stops" and a score is sent. I haven't tried implementing hitTest yet for the collision, but I have run into a sort of conflict problem where, when I comment out the line(s) that is supposed to change the cursor image (see Startup.as - stage.addEventListener(TouchEvent.TOUCH, touchHandler); and createCustomeCursor), the instance of AvatarEnemy (see enemy in Game.as) does what it should, and is placed in the center of the screen. When I comment in the line that is supposed to change the cursor: a). the cursor doesn't change, and b.) the enemy sprite disappears. When I comment out the same lines - the enemy sprite reappears (but obviously, the cursor doesn't work - not that it was working in the first place). Why is this happening? My code is below - someone mentioned something about not doing things before Starling is initialized here (a question I asked, which is a precursor to this one) - but I'm not sure what they meant because it at least seems like all my code is in the right place.
Game.as
package
{
import Classes.AvatarEnemy;
import starling.display.Sprite;
public class Game extends Sprite
{
//private var juggler:Juggler = Starling.juggler;
private var enemy:AvatarEnemy;
public function Game()
{
enemy = new AvatarEnemy();
addChild(enemy);
}
}
}
Startup.as
package
{
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.geom.Point;
import starling.core.Starling;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.display.DisplayObject;
import flash.display.BitmapData;
import flash.ui.MouseCursorData;
import flash.ui.Mouse;
[SWF(width="500", height="500", frameRate="30", backgroundColor="#FFFFFF")]
public class Startup extends Sprite
{
private var mStarling:Starling;
[Embed(source="Classes/Avatarpic.png")]
private const Cursor:Class;
public var cursor:DisplayObject;
public function Startup()
{
// Create a Starling instance that will run the "Game" class
mStarling = new Starling(Game, stage);
mStarling.start();
// These settings are recommended to avoid problems with touch handling
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
createCustomCursor();
stage.addEventListener(TouchEvent.TOUCH, touchHandler);
}
private function touchHandler(event:TouchEvent):void
{
var touch:Touch = event.getTouch(cursor);
if(touch.phase){
{
var localPos:Point = touch.getLocation(cursor);
trace("Touched object at position: " + localPos);
}
}
}
public function createCustomCursor():void
{
var cursorBitmaps:Vector.<BitmapData> = new Vector.<BitmapData>();
cursorBitmaps.push((new Cursor() as Bitmap).bitmapData);
var mouseCursorData:MouseCursorData = new MouseCursorData();
mouseCursorData.data = cursorBitmaps;
mouseCursorData.frameRate = 30;
mouseCursorData.hotSpot = new Point(0, 0);
Mouse.registerCursor("customCursor", mouseCursorData);
Mouse.cursor = "customCursor";
}
}
}
Any help would be greatly appreciated (if you need a copy of the code (it's an Adobe Flash Builder 4.7 project - I have made a git repo - just comment if you want the link).
UPDATE
I realized I wasn't registering the image as the cursor - I updated my Startup.as file to reflect changes (take a look at createCustomCursor function) - the cursor still isn't working, and the sprite that is supposed to appear is still not appearing.
Also - just in case you want to see where AvatarEnemy is coming from:
AvatarEnemy.as
package Classes
{
import starling.display.Image;
import starling.display.Sprite;
import starling.textures.Texture;
public class AvatarEnemy extends Sprite
{
[Embed(source='Enemypic.png')]
private static var Enemypic:Class;
private var texture:Texture = Texture.fromBitmap(new Enemypic());
private var image:Image = new Image(texture);
public function AvatarEnemy()
{
image.x = 0;
image.y = 200;
addChild(image);
}
}
}
UPDATE
I resolved why the sprite was disappearing - I needed to put the starling initialize code (mStarling.start() and mStarling = new Starling(Game, stage);) above all the stage.something lines. I edited code to reflect what I did in Startup.as. I still need help with the cursor though.
I have been practicing with your code and it all seems fine, but ive been using a different image, so that must be the problem.
Make sure the size of the image is below 32x32, thats the max size of an cursor image, otherwise the OS won't accept it.

1180: Call to a possibly undefined method gotoAndPlay

I have this AS3 script that worked so far...
stop();
b1.addEventListener(MouseEvent.CLICK, Info001);
function Info001(event:MouseEvent):void {
gotoAndPlay(2);
}
X.addEventListener(MouseEvent.CLICK, Exit001);
function Exit001(e:MouseEvent) {
NativeApplication.nativeApplication.exit();
}
then, I added a class in the .fla file...
package
{
import flash.system.System;
import flash.system.Capabilities;
import flash.display.Sprite;
import flash.events.Event;
import flash.desktop.NativeApplication;
import flash.utils.setTimeout;
import com.hdi.nativeExtensions.NativeAds;
import com.hdi.nativeExtensions.NativeAdsEvent;
public class Main extends Sprite
{
public var na : NativeApplication;
private var admobId:String = 'a1514b5ef85e336';
public function Main()
{
na = NativeApplication.nativeApplication;
na.addEventListener('exiting',exit,false,0,true);
na.addEventListener('deactivate',exit,false,0,true);
if ( stage ){
stage.scaleMode = 'noScale';
stage.align = 'TL';
}
if ( loaderInfo ){
loaderInfo.addEventListener( Event.INIT, init, false, 0, true );
} else {
init(null);
}
}
(the class is not complete here...)
and the buttons stopped working... :-/
I tried adding
import flash.events.MouseEvent;
but that's not enough... how can you make it work?
If you're trying to run gotoAndPlay in Main, it will throw that error because Sprites don't have a timeline. If so, try extending MovieClip instead.

ActionScript play audio

I am just trying to make a simple .swf file that plays a piece of audio when it loads. This compiles but when I bring it up into the browser nothing happens. I could only find sprite based tutorials so I took a stab that you can extend Sound the same way as you would extend Sprite. The final version is going to be headless and called my Java Script to play audio on Events.
package {
import flash.media.Sound;
import flash.net.URLRequest;
public class typeRight extends Sound {
public function HelloWorld( ) {
load(new URLRequest('./sound.mp3'));
play();
}
}
}
I am NOT working in Flash so please no GUI advice ; )
Rather than subclassing the Sound class, create a document class like this that contains a Sound class in it:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
public class SoundPlayer extends Sprite
{
protected var _sound : Sound;
protected var _channel : SoundChannel;
public function SoundPlayer()
{
_sound = new Sound();
_sound.addEventListener(Event.COMPLETE, soundLoadCompleteHandler);
_sound.addEventListener(IOErrorEvent.IO_ERROR, loadError);
_sound.load(new URLRequest("./sound.mp3"));
}
protected function soundLoadCompleteHandler(evt : Event) : void
{
// Use the _channel object to control sound properties such as pan and volume.
_channel = _sound.play();
}
protected function loadError(evt : IOErrorEvent) : void
{
trace ("ERROR :: " + evt);
// You could try recovering from the error here.
}
}
}