What should I use too pick random images from a folder and display it on the sage?
I know I will neeed:
1. Math.random thingy - to roll random numbers
2. XML file - which I don't know how to incorporate int the flash file
3. a folder with pictures, which I already have
Any ideas what else?
1.To placed image, fla as follows.
2.Try the following. below code is just a skeleton. you try more extended.
import flash.display.Bitmap;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.Loader;
var imgRequest:URLRequest;
var randCount:int = 6*Math.random();
function loadImage():void
{
for(var i:int = 0; i<randCount; i++)
{
var imgLoader:Loader = new Loader();
imgRequest = new URLRequest();
imgRequest.url = "img/img" + int(6*Math.random()) +".jpg";
trace(imgRequest.url);
imgLoader.load(imgRequest);
imgLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, unloadedImg);
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadedImg);
}
}
function onLoadedImg(e:Event):void
{
e.currentTarget.removeEventListener(Event.COMPLETE, onLoadedImg);
var bmp:Bitmap = e.currentTarget.content;
bmp.x = Math.random() * stage.stageWidth;
bmp.y = Math.random() * stage.stageHeight;
bmp.width = 200;
bmp.height = 200;
this.addChild(bmp);
}
function unloadedImg(e:IOErrorEvent):void
{
e.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, unloadedImg);
trace("load Failed:" + e);
}
loadImage();
You need to make an array of the images and then make the math random;
var selected:Array=[];//new array
while (selected.length<4) {
//myArray is the array with your pictures.
var si:int=Math.floor(Math.random()*_myArray.length);
if (selected.indexOf(si)==-1) selected.push(si);
}
trace(_myArray[selected[0]]); // first selected flag
trace(_myArray[selected[3]]); // fourth selected flag
Related
i'm building a flash desktop App where the user clicks on a button and opens a SWF file (a game) in a new window, i used a NativeWindow to achieve it, i did the folowing:
var windowOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
windowOptions.systemChrome = NativeWindowSystemChrome.STANDARD;
windowOptions.type = NativeWindowType.NORMAL;
var newWindow:NativeWindow = new NativeWindow(windowOptions);
newWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
newWindow.stage.align = StageAlign.TOP_LEFT;
newWindow.bounds = new Rectangle(100, 100, 2000, 800);
newWindow.activate();
var aLoader:Loader = new Loader;
aLoader.load(new URLRequest(path));
newWindow.stage.addChild(aLoader);
the result is this:
the game doesn't take the whole space available. When i change the "NO_SCALE" to "EXACT_FIT":
newWindow.stage.scaleMode = StageScaleMode.EXACT_FIT;
i got this:
it only shows the top-left corner of the game. I also tried "SHOW_ALL" and "NO_BORDER". I got the same result as "EXACT_FIT".
When i open the SWF file of the game separatly it's displayed normally:
any idea how can i display the SWF game as the image above?
The best solution for that is to have the dimensions of your external game in pixel. you have to stretch the loader to fit it in your stage. if you are try to load different games with different sizes to your stage, save the swf dimensions with their URL addresses.
var extSWFW:Number = 550;
var extSWFH:Number = 400;
var extURL:String = "./Data/someSwf.swf";
var mainStageWidth:Number = 1024;
var mainStageHeight:Nubmer = 768;
var aLoader:Loader = new Loader;
aLoader.load(new URLRequest(extURL));
newWindow.stage.addChild(aLoader);
aLoader.scaleY = aLoader.scaleX = Math.min(mainStageWidth/extSWFW,mainStageHeight/extSWFH);
It is not very difficult to figure dimensions of a loaded SWF because it is engraved into it's header, you can read and parse it upon loading. Here's the working sample:
package assortie
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.utils.ByteArray;
public class Dimensions extends Sprite
{
private var loader:Loader;
public function Dimensions()
{
super();
loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("outer.swf"));
}
private function onLoaded(e:Event):void
{
var aBytes:ByteArray = loader.contentLoaderInfo.bytes;
var aRect:Rectangle = new Rectangle;
var aRead:BitReader = new BitReader(aBytes, 8);
var perEntry:uint = aRead.readUnsigned(5);
aRect.left = aRead.readSigned(perEntry) / 20;
aRect.right = aRead.readSigned(perEntry) / 20;
aRect.top = aRead.readSigned(perEntry) / 20;
aRect.bottom = aRead.readSigned(perEntry) / 20;
aRead.dispose();
aRead = null;
trace(aRect);
}
}
}
import flash.utils.ByteArray;
internal class BitReader
{
private var bytes:ByteArray;
private var position:int;
private var bits:String;
public function BitReader(source:ByteArray, start:int)
{
bits = "";
bytes = source;
position = start;
}
public function readSigned(length:int):int
{
var aSign:int = (readBits(1) == "1")? -1: 1;
return aSign * int(readUnsigned(length - 1));
}
public function readUnsigned(length:int):uint
{
return parseInt(readBits(length), 2);
}
private function readBits(length:int):String
{
while (length > bits.length) readAhead();
var result:String = bits.substr(0, length);
bits = bits.substr(length);
return result;
}
static private const Z:String = "00000000";
private function readAhead():void
{
var wasBits:String = bits;
var aByte:String = bytes[position].toString(2);
bits += Z.substr(aByte.length) + aByte;
position++;
}
public function dispose():void
{
bits = null;
bytes = null;
}
}
I am trying to understand the values given back to me from the computeSpectrum method. I want to work with the lower frequencies pick out the bass drum of a track. The numbers I am getting back from the byteArray make no sense. For example, it says that the value is 0 when there is clearly a sound playing. What am I missing here...I do know beat detection is not easy and have looked at most of the posts here on the subject...It's just that the numbers that are returned to me make no sense, can somebody explain them to me? Thanks in advance.
My Code:
import flash.display.Graphics;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.display.MovieClip;
var snd: Sound = new Sound();
var req: URLRequest = new URLRequest("mySong.mp3");
snd.load(req);
var channel: SoundChannel;
channel = snd.play();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
const CHANNEL_LENGTH: int = 256;
const BUFFER_LENGTH: int = 512;
var bytes:ByteArray = new ByteArray();
function onEnterFrame(event: Event): void
{
SoundMixer.computeSpectrum(bytes, true, 0);
for (var i:int = 0; i < CHANNEL_LENGTH; i++) // channel_length = 256
{
var sampleValue:Number = bytes.readFloat() * 200;
var byteArrayIndex = bytes.position;
trace(byteArrayIndex, sampleValue);
}
}
function onPlaybackComplete(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
Nice to meet you again, I think I'm more understand your mind this time.
If you are going to check whether there exist a 'beat' at a specific time of the song;
I may suggest this method for reference:
import flash.events.Event;
var snd: Sound = new Sound();
var req: URLRequest = new URLRequest("mySong.mp3");
snd.load(req);
var channel: SoundChannel;
channel = snd.play();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
// I want to specify which region of byteData is passing to my check function.
// this two value help me to extract the sample I need.
var checkLength:int = 20;
var checkStart:int = 0;
var theshold:Number = 0.5; // How big the value should I determine it is the 'beat'.
const CHANNEL_LENGTH: int = 256;
const BUFFER_LENGTH: int = 512;
var myArray:Array;
var bytes:ByteArray = new ByteArray();
function onEnterFrame(event: Event): void
{
SoundMixer.computeSpectrum(bytes, true, 0);
myArray = [];
for (var i:int = checkStart; i < checkLength; i+=8) // extract the sample
{
var sampleValue:Number = bytes.readFloat();
myArray.push(sampleValue);
}
if( CheckBeat( myArray ))
{
trace("here maybe a beat!!", getTimer());
}
}
function CheckBeat(valueArray:Array):Boolean // check the whether 'beat' exist
{
var meanValue:Number = valueArray[0];
for(var i:int = 1; i < valueArray.length; i++)
{
meanValue = (meanValue + valueArray[i])/2;
}
return meanValue > theshold;
}
function onPlaybackComplete(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
But this method is just an Estimation, and not accurate enough at all.
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.text.StyleSheet;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.*
import flash.net.*
public class SpeechBox extends MovieClip{
public var textLoader:URLLoader = new URLLoader();
public var box:Sprite = new Sprite();
public var nextBox:Sprite = new Sprite();
private var nextText:TextField = new TextField();
private var textBox:TextField = new TextField();
private var speechText:String;
public var _speechBoxCheck:Timer = new Timer(1000);
public var clickedNext:Boolean = false;
public function SpeechBox()
{
textLoader.addEventListener(Event.COMPLETE, onLoaded);
textBox.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownScroll);
_speechBoxCheck.addEventListener(TimerEvent.TIMER, speechBoxCheck);
_speechBoxCheck.start();
//////////////////SPEECH BOX///////////////////
box.graphics.lineStyle(3.5,0xffffff);
box.graphics.beginFill(0x003366, .35);
box.graphics.drawRoundRect(0,0,650,145,20);
box.graphics.endFill();
box.x = 100;
box.y = 450;
addChild(box);
//////////////////SPEECH TEXT///////////////////
var speechFont = new DataText();
var textFormat:TextFormat = new TextFormat();
textFormat.font = speechFont.fontName;
textFormat.align = TextFormatAlign.LEFT;
textFormat.leading = 3;
textFormat.color = 0xFFFFFF;
textFormat.size = 16;
textBox.defaultTextFormat = textFormat;
textBox.width = 620;
textBox.height = 115;
textBox.x = box.x + 14;
textBox.y = box.y + 14;
textBox.multiline = true;
textBox.wordWrap = true;
textBox.selectable = false;
addChild(textBox);
//////////////////NEXT BUTTON///////////////////
nextBox.graphics.beginFill(0x000000, 0);
nextBox.graphics.drawRect(0,0,50,30);
nextBox.graphics.endFill();
nextBox.x = box.x + 600;
nextBox.y = box.y + 115;
nextText.defaultTextFormat = textFormat;
nextText.text = "Next";
nextText.textColor = 0xffffff;
nextText.autoSize = "left";
nextText.selectable = false;
nextText.mouseEnabled = false;
nextText.x = nextBox.x + 2
nextText.y = nextBox.y + 5
nextBox.buttonMode = true;
//nextBox.mouseEnabled = true;
nextBox.addEventListener(MouseEvent.MOUSE_DOWN, clickNext);
nextBox.addEventListener(MouseEvent.MOUSE_OVER, moveOver);
nextBox.addEventListener(MouseEvent.MOUSE_OUT, moveOut);
}
function onLoaded(e:Event):void {
trace(e.target.data);
textBox.text = e.target.data;
}
function mouseDownScroll(event:MouseEvent):void
{
textBox.scrollV+=4;
textBox.addEventListener(MouseEvent.MOUSE_UP,mouseup);
}
function mouseup(event:MouseEvent):void
{
if(textBox.scrollV == textBox.maxScrollV)
{
addChild(nextBox);
addChild(nextText);
}
}
function clickNext(event:MouseEvent):void
{
trace("click");
clickedNext = true;
_speechBoxCheck.stop();
(parent as Main).onTransition.start();
textBox.scrollV = 0;
textLoader.removeEventListener(Event.COMPLETE, onLoaded);
this.parent.removeChild(this);
}
function moveOver(event:MouseEvent):void
{
nextText.textColor = 0xffcc00;
}
function moveOut(event:MouseEvent):void
{
nextText.textColor = 0xffffff;
}
///////////////////////////////////////////////////////////////
function speechBoxCheck(event:TimerEvent)
{
if ((parent as Main).introduction == true)
{
textLoader.load(new URLRequest("Texts/LV1introduction.txt"));
trace("beginning");
(parent as Main).onTransition.stop();
}
if ((parent as Main).levelNum == 1)
{
textLoader.load(new URLRequest("Texts/LV1complete.txt"));
trace("go to lv 2")
(parent as Main).onTransition.stop();
}
if ((parent as Main).levelNum == 2)
{
textLoader.load(new URLRequest("Texts/LV2complete.txt"));
trace("go to lv 3")
(parent as Main).onTransition.stop();
}
}
}
}
EDIT: When the game starts, the LV1 introduction text starts. Once the scrollV equals maxScrollV, a next buttons appears. Click that, it will delete itself and the game starts. Once you beat stage one, levelNum automatically equals 2 and I add this class again from my main document class. However, it will show the same text over and over, regardless of what level.
So does the urlLoader always stay the same? If so, how can I change it?
URLLoader can be reused to load another data with new URLRequest instance. It is completely OK to reuse same URLLoader instance to load another file. Your problem is not in URLLoader, but in logics or somewhere else. You'd better try debuggers to make sure variable level has correct value of 2.
Why are you loading text file EVERY second? It would be ok to load them only level is changed.
does this textLoader instance have event listeners attached?
:::::::::EDITED:::::::::
You are removing event Listeners from textLoader in clickNext() call. textLoader will load file, but will not run onLoaded() to update textBox.text
Your speechBoxCheck() method is doing it wrong. 1. You must make only 1 load() call in speechBox() method. Your conditionals in the method are not exclusive, and it may cause trouble when multiple load() calls are made (previous loading operation will be canceled). consider "else if" chain.
it is not recommended to do something like loading files in this fashion. Unnecessary I/O operations, especially in runtime, should be avoided. Only load files when it is needed; In this case, it is when level changes.
Hello im with a doubt and need your help if its possible.
I have a class dish and i load 1 file ".swf", and i have a little game that works like this:
The dish moves in the x and y axis and i when i click in the dish it falls down.
But i want to have not only 1 dish i want have 10 different dishes with diferent images.
And i want that they appear in a random sequence.
But i dont have ideia how i cant do that...someone can give me "light"?
I use this variables to load my dish to the stage in my game project.
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest("dish.swf");
Here's an example of what you could do to get a random dish each time :
// whenever you need to create a new dish
var dishFilenames:Array = ['dish1.swf', 'dish2.swf', 'dish3.swf']; // etc etc
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
thank for the answer!
so i cant have all the dishes in the same "swf"?
I need to create swf as many as i need?
My class dish is like this until now:
I dont have other way to do that?(with only a swf that contains all the dishes)
package {
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.MouseEvent;
public class Dishe {
var velX: int;
var velY: int ;
var game:Game; //i have also a class game to control everyting
var broken_dish:URLRequest = new URLRequest("broken_dish.swf");
var gravity:int = 2;
var dishFilenames:Array = [ 'dish.swf','second_dish.swf'];
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
public function Dishe(e:Game, vX:int, vY:int)
{
velX = vX;
velY = vY;
load_dish.x = -180;
load_dish.y = randomBetween(250,-5);
load_dish.load(caminho);
game = e;
game.myStage.addChild(load_dishe);
load_dish.addEventListener(MouseEvent.CLICK, _shoot);
}
public function broken_dish(e:Event)
{
velY += gravity;
load_dish.y +=velY ;
if(load_dish.y >= game.myStage.stageHeight)
{
game.game_states(Game.state_playing);
}
}
public function _enterFrame(e:Event):void
{
if(load_dish.content!=null)
{
load_dish.x += velX;
load_dish.y += velY *(1 - (load_dish.x / game.myStage.stageWidth) * 2 );
if(load_dish.x > game.myStage.stageWidth)
{
load_dish.y = randomBetween(250,-5);
load_dish.x = -180;
}
}
}
public function _shoot(e:MouseEvent):void
{
trace("nice!!");
game.game_states(Game.state_stop);
load_dishe.load(broken_dish);
}
function randomBetween(a:int, b:int) : int {
return a + int(Math.round( (b-a)*Math.random() ));
}
}
}
I have done a simple code for a slideshow that dynamicly loads images from a subfolder, depending on what is listet in a text file.
the code:
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.display.Bitmap;
import flash.display.BitmapData;
public class slideshow extends MovieClip {
public var listLoader:URLLoader;
public var newImgList:Array;
public var imgX:int = 0;
public var container:MovieClip;
public function slideshow() {
container = new MovieClip();
stage.addChild(container);
listLoader = new URLLoader(new URLRequest("./slideshow.txt"));
listLoader.addEventListener(Event.COMPLETE, initImages);
}
public function initImages(event:Event):void {
var imgList:Array = listLoader.data.replace(/^\s+/,"").replace(/\s+$/,"").split(/\s+/);
newImgList = new Array();
for(var line:int = 0; line < imgList.length; line++ ) {
if(imgList[line].indexOf(".png") != -1 || imgList[line].indexOf(".jpg") != -1) {
newImgList.push(imgList[line]);
}
}
loadImage();
}
public function loadImage():void {
for(var loaderNum = 0; loaderNum < newImgList.length; loaderNum++) {
var imgLoader = new Loader();
imgLoader.load(new URLRequest("./slideshow/" + newImgList[loaderNum]));
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgInit);
}
}
public function imgInit(event:Event):void {
var imgBmp:BitmapData = event.target.content.bitmapData;
var img:Bitmap = new Bitmap(imgBmp);
img.height = 150;
img.scaleX = img.scaleY;
img.y = 0;
img.x = imgX;
imgX = (imgX + img.width + 10);
container.addChild(img);
}
}
well actually it works fine for me except for that the images are displayed in a almost random order.
i guess the code is loading some images too slow, so some of them are added to the movieclip although they are loaded after the one that should go next.
so what i mean :
1.png is loaded
1.png is added
2.png is loaded
3.png is loaded
3.png is added
2.png is added
so my question:
is there any other propper/better way to make that slideshow load images from a textfile where just the full names of the images ( that are in a subfolder ) are listet ?
thanks for any suggestions.
g.r.
Queue your image loading to have them ordered.
Rough example:
var queue:Array = []; // Populated from your text/whatever file.
// If you want the images to load from first to last you will need
// to use queue.reverse() once you get the filenames.
/**
* Beings loading the next image in queue.
* Ignored if the queue has no remaining items.
*/
function loadNext():void
{
if(queue.length > 0)
{
var imgSrc:String = queue.pop();
var ldr:Loader = new Loader();
ldr.load(new URLRequest(imgSrc));
ldr.addEventListener(Event.COMPLETE, _done);
}
}
/**
* Called once a Loader instance has finished loading a resource.
* #param e Event.COMPLETE.
*/
function _done(e:Event):void
{
e.target.removeEventListener(Event.COMPLETE, _done);
container.addChild(e.target as DisplayObject);
// Begin loading the next image in queue.
loadNext();
}