i have .fla and .as files.
.fla:
import test ;
var b:test = new test();
var myBitmap:BitmapData = new BitmapData(150, 150, true, 0x80FF3300);
var test:BitmapData = new BitmapData(150, 150, false, 0xFF0000);
var myImage:Bitmap = new Bitmap(test);
addChild(myImage);
and .as
package
{
import flash.display.*;
public dynamic class test extends flash.display.BitmapData
{
public function test(arg1:int=621, arg2:int=427)
{
super(arg1, arg2);
return;
}
}
}
But its not working, BitmapData must have the same name like loading .as (test.as), but i don't know how do that :|
If you will not add some functionality on top of the BitmapData why bother creating another class and extend the BitmapBata Class you can just use it directly.
as i understand you are not seeing anything on the screen, well this is normal because you're adding a blank bitmap to the stage ie: its BitmapData has nothing to deliver.
Maybe you need to link the Test class to an image imported into your fla so you'll get something to see on the screen.
Related
So having trouble making sound on keyboard press
I have the imports:
import flash.net.URLRequest;
import flash.media.Sound;
I have the variables
private var soundDownRequest:URLRequest = new URLRequest ("SoundDown.mp3");
private var downSound:Sound = new Sound (soundDownRequest);
and the event listener
private function keyDownHandler(evt:KeyboardEvent):void
{
if (evt.keyCode == 40)//ascii for down arrow
{
downSound.play();
}
}
The sound folder is in the same folder as the .as, its also in the library of the fla, yet it still doesn't work. Any idea why?
Thank you.
Update:
I got the sound to work but not using the external method I was trying to do above.
Had to do it internally.
so you need:
import flash.media.SoundChannel;
-Then you need to make sure your sound file is in your fla library.
once its in the library
-Right click > properties
-Select the Action Script Tab
-Check "export for action script"
-Give the class a name in accordance to the sound
-press ok
add this variable (your will be different):
private var downSound:TheDownSound = new TheDownSound();
downsound is the selected name of the variable, and TheDownSound is the name of the class (the one made earlier for the sound file)
then add this to where you want the sound to play:
var myDownSound:SoundChannel = downSound.play();
Do this if you cant get it working externally like me.
for a better explanation watch this guys youtube video:
https://www.youtube.com/watch?v=SZpwppe7yGs
Your code is working perfectly ok if you put your .mp3 file in the same folder as the output .swf, not near the class .as source file (because its the swf file loading the sound, so the path must be relative to it)
public class ASEntryPoint extends Sprite {
private var soundDownRequest:URLRequest = new URLRequest ("click.mp3");
private var downSound:Sound = new Sound (soundDownRequest);
public function ASEntryPoint() {
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
}
private function keyDownHandler(evt:KeyboardEvent):void{
if (evt.keyCode == 40) {
downSound.play();
}
}
}
You need to load the external file, which is asynchronous operation. Then you track the loading event and if it all goes normally you can play your loaded sound.
import flash.events.SecurityErrorEvent;
import flash.events.IOErrorEvent;
import flash.events.Event;
import flash.net.URLRequest;
import flash.media.Sound;
import flash.media.SoundChannel;
// Keep the sound loader from being garbage collected.
var soundLoader:Sound;
function loadSound(url:String):void
{
var aRequest:URLRequest = new URLRequest(url);
soundLoader = new Sound();
// Handle the normal loading.
soundLoader.addEventListener(Event.COMPLETE, onLoaded);
// Handle the error cases.
soundLoader.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 0, true);
soundLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError, false, 0, true);
soundLoader.load(aRequest);
}
var audioChannel:SoundChannel;
function onLoaded(e:Event):void
{
// Sound is available here for playback.
audioChannel = soundLoader.play();
}
function onError(e:Event):void
{
trace(e);
}
You can also handle your sound as a streaming audio, but I worked with that years ago in AS2 so I cannot help here. Still, internet suggests a link: http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d22.html
This topic has been raised before, but not one of the examples I've found online seem to work for me! I am trying to get starling to work with box2d, and also for the box2d debugdraw.
I have tried a bunch of different methods, and my code is now a bit of a mess due to commenting out to try different mixes of the "solution". Does anyone know how to do all this properly? I would be greatly in dept if someone could explain it.
Here is the last attempt I tried:
In my Startup class:
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
//import flash.events.Event;
import starling.core.Starling;
//import starling.display.Sprite;
import flash.events.Event;
[SWF(width="640", height="480", frameRate="60", backgroundColor="#000000")]
public class Startup extends Sprite {
public static var mStarling:Starling;
public static var debugSprite:Sprite;
public function Startup() {
//addChild ( new Stats() );
super();
//stage.align = StageAlign.TOP_LEFT;
//stage.scaleMode = StageScaleMode.NO_SCALE;
// create our Starling instance
mStarling = new Starling(Game, stage);
// set anti-aliasing (higher the better quality but slower performance)
mStarling.antiAliasing = 1;
mStarling.showStats = true;
// start it!
mStarling.start();
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContextCreated);
}
private function onContextCreated(e:Event):void{
////debug mode
// debugSprite=new Sprite();
// //addChild(debugSprite);
// Starling.current.nativeOverlay.addChild(debugSprite);
//var debugSprite:Sprite=new Sprite();
addChild(debugSprite);
(mStarling.stage.getChildAt(0) as Game).DebugDraw(debugSprite)
}
I call the debugdraw like this:
debugDraw(Startup.debugSprite);
Here is a heavily commented out debugdraw:
private function debugDraw(debugSprite:flash.display.Sprite):void {
/*var worldDebugDraw:b2DebugDraw=new b2DebugDraw();
//var debugSprite:flash.display.Sprite = new flash.display.Sprite();
var debugSprite:Sprite = new Sprite();
addChild(debugSprite);
//mStarling.current.nativeOverlay.addChild(debugSprite);
//worldDebugDraw.SetSprite(debugSprite);
//debugDraw.SetSprite(Starling.current.nativeOverlay); //DOESN'T SEEM TO WORK
worldDebugDraw.SetDrawScale(worldScale);
worldDebugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);
//worldDebugDraw.SetFillAlpha(0.0);
//worldDebugDraw.SetAlpha(0.0);
//visible
worldDebugDraw.SetFillAlpha(0.8); //for testing
worldDebugDraw.SetAlpha(1); //for testing
world.SetDebugDraw(worldDebugDraw);*/
var worldDebugDraw:b2DebugDraw = new b2DebugDraw();
worldDebugDraw.SetSprite(debugSprite);
world.SetDebugDraw(worldDebugDraw);
}
DebudDraw works with ONE classic Flash Sprite (you keep creating new ones for some reason). Only one b2DebugDraw should be created and set with that ONE Sprite.
Starling pretends to own the stage and all displaylist but it doesn't. Use simply your StartUp instance or even directly the stage itself without passing through Starling it will avoid some confusion.
The right way to do all this:
public var debugSprite:Sprite;//no static var
Starting what?
//don't start it!
mStarling.start();
You star something that cannot be started. At this point you are trying to create a valid Context3D so be patient. Remove that line.
Now in onContextCreated:
mStarling.start();//now you can start
debugSprite = new Sprite();//create your sprite
addChild(debugSprite);
var game:Game = mStarling.stage.getChildAt(0) as Game;//Game? somebody is following a tutorial ...
if(game)
{
game.setDebug(debugSprite);//this is a new public method to create in Game
}
In Game in method setDebug (with one parameter Sprite):
var worldDebugDraw:b2DebugDraw = new b2DebugDraw();
worldDebugDraw.SetSprite(myspriteparameter);
world.SetDebugDraw(worldDebugDraw);
That's it, don't create new Sprite, don't create new debugdraw, you are good to go that's all you need.
I know there are a lot of previous topics about preloaders and I've tried to follow every one of them but I still get the same problem (well they have helped me go from 80% -> 50%)
Right now it starts at 61450 / 125207 which is about 50%.
Here is my Main Document (default class file for the entire project) class:
public class MainDocument extends MovieClip
{
private var preloader:Preloader;
private var sB:startButton;
public function MainDocument()
{
preloader = new Preloader();
preloader.x = 300;
preloader.y = 400;
addChild(preloader);
loaderInfo.addEventListener(Event.COMPLETE,addStartButton,false,0,true);
}
private function addStartButton(e:Event):void
{
sB = new startButton();
sB.x = 300;
sB.y = 450;
sB.addEventListener(MouseEvent.CLICK,sMainMenu,false,0,true);
addChild(sB);
loaderInfo.removeEventListener(Event.COMPLETE,addStartButton);
}
private function sMainMenu(e:Event):void
{
sB.removeEventListener(MouseEvent.CLICK,sMainMenu);
removeChild(sB);
removeChild(preloader);
sB = null;
preloader = null;
var menuScreen = new MenuScreen();
addChild(menuScreen);
//I have heard that the following code might work better:
//var menuScreen:Class = getDefinitionByName("MenuScreen") as Class;
//addChild(new menuScreen() as DisplayObject);
}
}
And the Preloader that it attaches:
public class Preloader extends MovieClip
{
public function Preloader()
{
addEventListener(Event.ENTER_FRAME,Load);
}
private function Load(e:Event):void
{
//"bar" is a movieclip inside the preloader object
bar.scaleX = loaderInfo.bytesLoaded/loaderInfo.bytesTotal;
//"percent" is a dynamic text inside the preloader object
percent.text = Math.floor(loaderInfo.bytesLoaded/loaderInfo.bytesTotal*100)+"%";
trace(loaderInfo.bytesLoaded+" / "+loaderInfo.bytesTotal);
if (loaderInfo.bytesLoaded == loaderInfo.bytesTotal)
{
removeEventListener(Event.ENTER_FRAME,Load);
}
}
}
-> Nothing is set to Export on Frame 1 except for the Preloader
-> No objects exist on the first frame; the only code on first frame is stop();
-> I placed a copy of every single MovieClip in the second frame and when the startButton is clicked, a gotoAndStop(3); is run so no one ever sees frame 2.
If anyone knows of anything simple that I could have forgotten, please let me know!
Thanks!
You're tying to use a preloader in the file being preloaded. In that case, there is going to be bloat from the rest of the project's code and assets. The reason you are seeing your preloader seemingly delayed is because a swf must load completely before any code will execute. This includes all assets on stage regardless of what frame they are on, even if you have settings in place to export on something other than frame 1. Instead, try using a blank shell as your preloader. This shell will have nothing in it but the loader code and a preloader graphic or animation. When the load is finished, hide your preloader and add your loaded content to the stage of the shell, or a container movieclip in the shell.
All the following code goes in your shell, which is just another FLA file with nothing in it but this code, and a preloader bar. The dimensions of this file should be the same as the file you are loading into it, ie your original swf file you were trying to preload.
Use it by calling loadSwf( "mySwfNameOrURLToSwf.swf" );
The variable _percent will populate with the current load percentage, which you can correspond to your loading bar scale. Presuming the preloader bar is named "bar", the line bar.visible = false; in the onSwfLoaded function will hide it. addChild( _swf ) adds the loaded swf to the shell's stage. The line _swf.init(); references a function in the loaded swf you will need to add called init() that starts your loaded swf doing whatever it is its supposed to do. Have everything in the loaded swf start on the first frame now, including the init() function.
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.Bitmap;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.events.Event;
import flash.events.ProgressEvent;
var _swfLoader:Loader;
var _swf:DisplayObject;
var _percent:Number;
function loadSwf( swfURL:String ):void
{
_swfLoader = new Loader();
var req:URLRequest = new URLRequest( swfURL );
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.applicationDomain = ApplicationDomain.currentDomain;
loaderContext.checkPolicyFile = true;
_swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onSwfProgress);
_swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSwfLoaded);
_swfLoader.load(req, loaderContext);
}
function onSwfProgress( evt:Event ):void
{
_percent = Math.round( ( evt.target.bytesLoaded / evt.target.bytesTotal ) * 100 );
}
function onSwfLoaded( evt:Event ):void
{
_swfLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onSwfProgress);
_swfLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onSwfLoaded);
_swf = _swfLoader.content;
addChild( _swf );
bar.visible = false;
_swf.init();
_swfLoader = null;
}
your code looks ok.
when you are not on a http server, loading process are simulated.
After compiling, press crtl + B.
In menu you can choose the downloading speed and simulate a download by pressing again ctrl+enter.
it might help you to debug your preloader
#Lee Burrows What you said was right but would have been better if you looked at what I mentioned at the end of the code (three bold points)
The solution I used was:
-> I set everything to Export on Frame 2 on my 3 frame document.
-> Removed everything on Frame 2
-> Created a TextField via constructor and used drawRectangle for loading bar
-> No movieclips present on frame 1, and used
var menuScreen:Class = getDefinitionByName("MenuScreen") as Class;
addChild(new menuScreen() as DisplayObject);
instead of the previous code.
The reason why what I had originally didn't work because, as Lee Burrows mentioned, the Export for Actionscript hangs the loading if X = 1 in Export on Frame X, regardless if Export on Frame 1 was checked or not. Changing it to 2 or unchecking Export for Actionscript were the two solutions (except if it isn't exported for actionscript, then its code cant be referenced to).
Preloader starts at about 2% now.
I'm trying to create a custom class that will create a tile (a small rounded square) when requested, with a small image on it. I can successfully create the tile, as shown in the code below, but I don't know how to pass the class the pictures data.
Is it possible to do this using bitmapData, or by referancing it throught the library (if i store my picture in a movieclip in the library?
Here is my class so far:
package com{
import flash.display.MovieClip;
import fl.transitions.Tween;
import fl.transitions.easing.Strong;
public class tileCreator extends MovieClip{
public var tiled:MovieClip;
public var sourceImage:MovieClip = new MovieClip;
public function tileCreator() {
trace("tile creator");
tiled = new MovieClip;
tiled.graphics.beginFill(0x666666, 0.3);
tiled.graphics.drawRoundRect(-55/2, -55/2, 55, 55, 15, 15);
this.addChild(tiled);
}
}
}
yes, it's possible using BitmapData.
import an image to the library and right-click it to change "settings ...".
you have to check "export for actionscript" and put a name into the second textfield underneath the checkbox - let's say 'MyImage'. (flash automatically adds the base-class of type flash.display.BitmapData).
then you can create an instance of the image saying:
var myImage:MyImage = new MyImage();
it's a BitmapData object, because your MyImage class extends BitmapData.
then you just have to add the BitmapData to the constructor as an argument (rename your class to Tile, because it's not a creator but the tile itself you create. and use a capital letter!).
public class Tile extends MovieClip
{
public function Tile (img:BitmapData)
{
var bmp:Bitmap = new Bitmap(img);
addChild(bmp);
tiled = new MovieClip;
tiled.graphics.beginFill(0x666666, 0.3);
tiled.graphics.drawRoundRect(-55/2, -55/2, 55, 55, 15, 15);
addChild(tiled);
bmp.mask = tiled;
}
}
you need to do it in the folowin way:
function createBitmap ( yourMovieClipYouWantToBeAsImage : DisplayObject ) : Bitmap
{
var bitmapData:BitmapData = new BitmapData ( width, height );
bitmapData.draw ( yourMovieClipYouWantToBeAsImage );
var bitmap:Bitmap = new Bitmap ( bitmapData );
return bitmap; // do what ever you want with it but now as an image
}
You can create a "snapshot" of this using bitmapData. You can then pass this to any other class you want. Code is shown below.
//This code goes into your TileCreator-class
public function draw():BitmapData
{
//True and 0 at the end of creating this bitmap ensure transparancy
//for the transparant pixels (else these would be opaque)
var bmp:BitmapData = new BitmapData(width, height, true, 0);
bmp.draw(this);
return bmp;
}
Good morning friendly Flashers ;) So I've been trying since yesterday to just load a SWF file into my main movie. I've done this before just placing code inside a movieClip, but this time I'm working inside of Class files. I have my main class which calls a function inside of my sub class which contains the loader. My problem is that the swf will load (I can tell via traces) but I cannot see the loaded swf :(
Below is the code inside of my sub class
package src.howdinicurtain {
import flash.net.*;
import flash.display.*;
import flash.events.Event;
public class HowdiniFrame extends MovieClip {
//public var splashLoader;
public var introLoader:Loader = new Loader();
public var introContainer:MovieClip;
private var holdX:Number;
private var holdY:Number;
public function HowdiniFrame(url:String, loadX, loadY):void {
holdX = loadX;
holdY = loadY;
this.addChild(introLoader);
//this.addChild(introContainer);
introLoader.load(new URLRequest(url));
introLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,swfLoaded);
}
public function swfLoaded(e:Event):void {
introLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, swfLoaded);
introContainer = introLoader.content as MovieClip;
//introContainer = MovieClip(introLoader.contentLoaderInfo.content);
addChild(introContainer);
introContainer.x = holdX;
introContainer.y = holdY;
trace("holdX = "+holdX);
trace("holdY = "+holdY);
}
}
}
The code above will load the swf file, I can see the swf files trace statements from the start of the animation to the end, but I cannot actually see the swf file inside of the main swf.
Traces:
The SWF file is = intro.swf
Intro Movie Starts :)
contentLoaderInfo event removed
Intro Movie Ends :(
Here is the code in my main class that calls the sub class function that loads the movie:
var introPath:String = xmlOutput.intro;
trace("The SWF file is = "+introPath+"\r"+"\r");
hc = new HowdiniFrame(introPath, 0, 20);
I swear I throw my code into the first frame of a movieClip and it works fine, I see the animation in the loaded SWF play instantly, but when I have my code inside of Class files I cannot see my SWF at all :( thoughts? ideas? Thanks for any tips!
~ Leon
Always treat your children right. Don't forget to add them in everything you do or else you're a bad parent.
What is hc? Is that a MovieClip on the stage? What if you try:
hc.addChild(new HowdiniFrame(introPath, 0, 20));
or if hc is not a clip on the stage
hc = new HowdiniFrame(introPath, 0, 20);
addChild(hc);