Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
Is anyone aware of a native Extension for Adobe AIR desktop that ties into Google's Speech API?
After a couple days of searching i have come across 2 ANE's but they both seem to be dependent on the Android OS. ie You must target and publish to an android based device for them to work
http://myappsnippet.com/google-speech-api-air-native-extension/
http://blog.immanuelnoel.com/2011/12/07/new-actionscript-native-extension-speech-recognition/
There is also this approach which works offline, but requires training and only works with 'pre canned' responses
http://www.bytearray.org/?p=1151
Here's a web example of Google's API
https://www.google.com/intl/en/chrome/demos/speech.html
I too tried the same thing for ios. But finally i found some FLAC file which integrates with Google API only. And this works a bit better for me in AIR too.
http://8byte8.com/blog/2012/07/voice-recognition-ios/
just go through that URL, you will get some idea.
And the class which i made is .
package com.gmail.nxhoaf
{
import com.adobe.audio.format.WAVWriter;
import com.adobe.serialization.json.JSONDecoder;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SampleDataEvent;
import flash.media.Microphone;
import flash.media.Sound;
import flash.net.FileReference;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.utils.ByteArray;
import flash.utils.Endian;
import cmodule.flac.CLibInit;
import fr.kikko.lab.ShineMP3Encoder;
//import mx.controls.Alert;
public class Recorder
{
public var CALL_BACK:Function;
private var bytes:ByteArray;
private var mic:Microphone;
private var mp3Encoder : ShineMP3Encoder;
private static const FLOAT_MAX_VALUE:Number = 1.0;
private static const SHORT_MAX_VALUE:int = 0x7fff;
public function Recorder()
{
}
public function setMicrophone (mic : Microphone) {
this.mic = mic;
}
public function getMicrophone () {
return mic;
}
public function startRecord() :void {
this.bytes = new ByteArray();
mic.gain = 100;
mic.rate = 44;
mic.setSilenceLevel(0,4000);
// Remove playback listener if any
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, onPlaying);
// Add record listener
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, onRecording);
}
public function stopRecord() :void {
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA,onRecording);
}
public function playback () :void {
if (bytes.length > 0) {
bytes.position = 0;
var sound:Sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA,onPlaying);
sound.play();
}
}
private function onRecording(event:SampleDataEvent):void {
while (event.data.bytesAvailable) {
var sample:Number = event.data.readFloat();
bytes.writeFloat(sample);
}
}
private function onPlaying(event:SampleDataEvent): void {
var sample:Number;
for (var i:int = 0; i < 8192; i++) {
if (!bytes.bytesAvailable) return;
sample = bytes.readFloat();
event.data.writeFloat(sample);
event.data.writeFloat(sample);
}
}
public function encodeToFlacAndSend() : void {
var flacCodec:Object;
flacCodec = (new cmodule.flac.CLibInit).init();
bytes.position = 0;
var rawData: ByteArray = new ByteArray();
var flacData : ByteArray = new ByteArray();
rawData = convert32to16(bytes);
flacData.endian = Endian.LITTLE_ENDIAN;
//flacData.endian = Endian.BIG_ENDIAN
flacCodec.encode( encodingCompleteHandler, encodingProgressHandler, rawData, flacData, rawData.length, 30);
function encodingCompleteHandler(event:*):void
{
trace(flacData.length.toString(),"FLACCodec.encodingCompleteHandler(event):", event);
//Alert.show(flacData.length.toString());
//var PATH:String = "https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-IN";
var PATH:String = "https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-IN";
var urlRequest:URLRequest = new URLRequest(PATH);
var urlLoader:URLLoader = new URLLoader();
//urlRequest.contentType = "audio/x-flac; rate=44000";
urlRequest.contentType = "audio/x-flac; rate=44000";
urlRequest.data = flacData;
urlRequest.method = URLRequestMethod.POST;
urlLoader.dataFormat = URLLoaderDataFormat.BINARY; // default
urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, IOErrorOccured);
urlLoader.addEventListener(ErrorEvent.ERROR, urlLoader_error);
urlLoader.load(urlRequest);
function urlLoader_complete(evt:Event):void {
trace("MORTYYYYYYYY",urlLoader.data);
var dc:JSONDecoder = new JSONDecoder(String(urlLoader.data),true);
var ob:Object = dc.getValue();
var test:Array = ob["hypotheses"];
if(CALL_BACK != null){
if (test.length >=1){
CALL_BACK(test[0]["utterance"]);
}else {
CALL_BACK(null);
}
}
}
function urlLoader_error(evt:ErrorEvent): void {
trace("*** speech to text *** " + evt.toString());
if(CALL_BACK != null){
CALL_BACK(null);
}
}
function IOErrorOccured(evt:IOErrorEvent): void {
trace("*** IO Error Occured *** " + evt.toString());
if(CALL_BACK != null){
CALL_BACK(null);
}
}
function onHTTPResponse(eve:HTTPStatusEvent):void{
trace("*** HTTP Error Occured *** " + eve.toString());
}
}
function encodingProgressHandler(progress:int):void {
// trace("FLACCodec.encodingProgressHandler(event):", progress);;
}
}
/**
* Converts an (raw) audio stream from 32-bit (signed, floating point)
* to 16-bit (signed integer).
*
* #param source The audio stream to convert.
*/
private function convert32to16(source:ByteArray):ByteArray {
// trace("BitrateConvertor.convert32to16(source)", source.length);
var result:ByteArray = new ByteArray();
result.endian = Endian.LITTLE_ENDIAN;
while( source.bytesAvailable ) {
var sample:Number = source.readFloat() * SHORT_MAX_VALUE;
// Make sure we don't overflow.
if (sample < -SHORT_MAX_VALUE) sample = -SHORT_MAX_VALUE;
else if (sample > SHORT_MAX_VALUE) sample = SHORT_MAX_VALUE;
result.writeShort(sample);
}
// trace(" - result.length:", result.length);
result.position = 0;
return result;
}
/**
* Save recorded audio stream to a specific audio format
* #param soundFormat: expected sound format
*/
/* public function saveAs(soundFormat: String) {
switch(soundFormat) {
case SoundFormat.WAV:
encodeToWav(bytes);
break;
case SoundFormat.MP3:
encodeToMp3(bytes);
break;
default:
encodeToWav(bytes);
break;
}
}*/
/**
* Encode recorded audio to .wav
* #param inputStream stream which we want to encode
*
*/
private function encodeToWav(bytes:ByteArray) : void {
var wav:WAVWriter = new WAVWriter();
wav.numOfChannels = 1;
wav.sampleBitRate = 16;
wav.samplingRate = 44100;
bytes.position = 0;
var wavData : ByteArray = new ByteArray();
wavData.endian = Endian.BIG_ENDIAN;
wav.processSamples(wavData,bytes,44100,1);
//wavData.position = 0;
(new FileReference()).save(wavData, ".wav");
}
/**
* Encode recorded audio to .mp3
* #param inputStream stream which we want to encode
*
*/
private function encodeToMp3(bytes:ByteArray) : void {
var wav:WAVWriter = new WAVWriter();
wav.numOfChannels = 1;
wav.sampleBitRate = 16;
wav.samplingRate = 44100;
bytes.position = 0;
var wavData : ByteArray = new ByteArray();
wavData.endian = Endian.BIG_ENDIAN;
wav.processSamples(wavData,bytes,44100,1);
wavData.position = 0;
mp3Encoder = new ShineMP3Encoder(wavData);
mp3Encoder.addEventListener(Event.COMPLETE, mp3EncodeComplete);
mp3Encoder.addEventListener(ProgressEvent.PROGRESS, mp3EncodeProgress);
mp3Encoder.addEventListener(ErrorEvent.ERROR, mp3EncodeError);
mp3Encoder.start();
function mp3EncodeProgress(event : ProgressEvent) : void {
}
function mp3EncodeError(event : ErrorEvent) : void {
// Alert.show(event.toString());
}
function mp3EncodeComplete(event : Event) : void {
// mp3Encoder.saveAs();
}
}
}
}
//import com.gmail.nxhoaf;
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've got a proprietary file format that works as an archive. It takes a folder full of files and packs them into a single file with no compression - the first X bytes of the files are dedicated to the "Table of contents" - the file paths, their size in bytes and their location (byte index) in the archive file. the remaining bytes are for the actual data of each file.
This format works and has been working for several years except in a few cases I am trying to debug. There are some cases where the files fail to unarchive properly In my experience this is typically on laptops which I presume have 5400 rpm hard drives. But sometimes it fail on SSD hard drives (like a Surface Book) Also the failure is not consistent. If I were to unarchive the same file 10 times on a "problem" machine it might only fail 1 or 2 times or not at all in some cases.
In the language that I am unarchiving this format (as3), the file stream reader has property 'readAhead' - which as the docs indicate is 'The minimum amount of data to read from disk when reading files asynchronously' . Could this value be affecting my unarchiving? My initial value for this was '8192' which I have now changed to 8192/4 to test on some new machines. Anyone have any thoughts on this? Is the readAhead value irrelevant?
I realize this is vague. I'm not looking for a specific solution just want to get some feedback from people who have more experience on how I could better diagnose and resolve this issue.
Here is the class in question. I've tried to remove anything unrelated to what I'm asking about:
/**
* ...
* #author Phil
*/
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class Archive extends EventDispatcher
{
public static const UNARCHIVING_COMPLETE:String = "unarchivingComplete";
public static const UNARCHIVING_PROGRESS:String = "unarchivingProgress";
public static const UNARCHIVE_CANCEL:String = "unarchiveCancel";
public static const ENDIAN:String = Endian.LITTLE_ENDIAN;
private var _inputFile:File;
private var _outputFile:File;
private var _inputStream:FileStream;
private var _outputStream:FileStream;
private var _files:Vector.<ArchiveItem>;
private var _readAheadValue:uint = 8192 / 4;
private var _maxTableSize:uint = 40960 * 30;
private var _tableData:ByteArray;
private var _curArchiveItem:ArchiveItem;
private var _currentArchiveItemBytesWritten:uint;
private var _pointerPosition:uint = 0;
private var _tableSize:uint = 0;
private var _totalSize:uint = 0;
private var _totalFiles:uint = 0;
public function Archive()
{
}
public function readArchive(archive:File, dest:File):void
{
_inputFile = archive;
_outputFile = dest;
createReadStream();
createTableData();
_inputStream.openAsync( _inputFile, FileMode.READ );
}
public function destroy():void
{
killStreams();
_inputFile = null;
_outputFile = null;
}
public function cancel():void
{
killStreams();
}
private function killStreams():void
{
killInStream();
killOutStream();
}
private function killInStream():void
{
if (!_inputStream) return;
_inputStream.removeEventListener(Event.COMPLETE, onFileReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onFileReadProgress);
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.removeEventListener(Event.CLOSE, onInputClosed);
_inputStream.removeEventListener(IOErrorEvent.IO_ERROR, onErrorReadingArchive);
_inputStream.close();
_inputStream = null;
}
private function killOutStream():void
{
if (!_outputStream) return;
_outputStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
_outputStream.removeEventListener(Event.CLOSE, onOutPutClosed);
_outputStream.close();
_outputStream = null;
}
private function createTableData():void
{
_files = new Vector.<ArchiveItem>();
_tableData = new ByteArray();
_tableData.endian = ENDIAN;
}
private function createReadStream():void
{
_inputStream = new FileStream();
_inputStream.endian = ENDIAN;
_inputStream.readAhead = _readAheadValue;
_inputStream.addEventListener(Event.CLOSE, onInputClosed);
_inputStream.addEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.addEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.addEventListener(IOErrorEvent.IO_ERROR, onErrorReadingArchive);
}
private function onErrorReadingArchive(e:IOErrorEvent):void
{
dispatchEvent( new Event(Event.CANCEL) );
}
private function onArhiveReadComplete(e:Event):void
{
if (_tableData.length < _maxTableSize)
{
onTableReadProgress( null, true);
}
}
private function onTableReadProgress(e:ProgressEvent, force:Boolean = false):void
{
if (_tableData.length < _maxTableSize && force == false)
{
_inputStream.readBytes( _tableData,_tableData.length );
}else {
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
populateTable( _tableData );
}
return;
if (_inputStream.bytesAvailable < _maxTableSize && force == false)
{
return;
}else {
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
var ba:ByteArray = new ByteArray();
ba.endian = ENDIAN;
_inputStream.readBytes(ba);
populateTable( ba );
}
}
private function populateTable(tableData:ByteArray):void
{
var a:ArchiveItem;
var offset:uint = 0;
var size:uint = 0;
var fileName:String;
if (tableData is ByteArray)
{
tableData.position = 0;
}
for (;;)
{
offset = tableData.readUnsignedInt();
size = tableData.readUnsignedInt();
fileName = tableData.readUTF();
if (fileName == "endTable")
{
_tableSize = tableData.position;
_totalFiles = _files.length;
_totalSize = _inputFile.size;
completeTableRead();
break;
}
a = new ArchiveItem();
a.filename = fileName;
a.offset = offset;
a.size = size;
_files.push(a);
}
}
private function completeTableRead():void
{
createFileOutputStream();
_inputStream.readAhead = _readAheadValue;
_inputStream.removeEventListener(Event.COMPLETE, onArhiveReadComplete);
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onTableReadProgress);
_inputStream.addEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.addEventListener(Event.COMPLETE, onArchiveReadProgress);
writeNextArchiveItemToFile();
}
private function onInputClosed(e:Event):void
{
completeUnarchiving();
}
private function completeUnarchiving():void
{
killStreams();
dispatchEvent( new Event(UNARCHIVING_COMPLETE) );
}
private function createFileOutputStream():void
{
_outputStream = new FileStream();
_outputStream.endian = ENDIAN;
_outputStream.addEventListener(Event.CLOSE, onOutPutClosed);
_outputStream.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
}
private function onOutPutClosed(e:Event):void
{
completeUnarchiving();
}
private function onIOError(e:IOErrorEvent):void
{
dispatchEvent( new Event(Event.CANCEL) );
}
private function writeNextArchiveItemToFile():void
{
if (_files.length == 0)
{
endWriting();
return;
}
_curArchiveItem = _files.shift();
_currentArchiveItemBytesWritten = 0;
var dest:File = new File();
dest.nativePath = _outputFile.nativePath + File.separator + _curArchiveItem.filename;
_outputStream.open(dest, FileMode.WRITE);
movePointer();
}
private function endWriting():void
{
_inputStream.removeEventListener(ProgressEvent.PROGRESS, onArchiveReadProgress);
_inputStream.removeEventListener(Event.COMPLETE, onArchiveReadProgress);
_outputStream.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
_outputStream.close();
_inputStream.close();
}
private function onOutputStreamCloseOnCompelte(e:Event):void
{
dispatchEvent( new Event(UNARCHIVING_COMPLETE) );
}
private function movePointer():void
{
_inputStream.position = _tableSize + _curArchiveItem.offset;
_pointerPosition = _inputStream.position;
if (_curArchiveItem.size == 0)
{
writeNextArchiveItemToFile();
}
}
private function onArchiveReadProgress(e:Event):void
{
if (_currentArchiveItemBytesWritten >= _curArchiveItem.size)
{
writeNextArchiveItemToFile();
return;
}
writeBytesToDisk();
}
private function writeBytesToDisk():void
{
var bytes:ByteArray = new ByteArray();
var bytesRemaining:uint = _curArchiveItem.size - _currentArchiveItemBytesWritten;
var bytesToWrite:uint = _inputStream.bytesAvailable;
if (bytesToWrite > bytesRemaining)
{
bytesToWrite = bytesRemaining;
}
_inputStream.readBytes(bytes, 0, bytesToWrite);
try {
_outputStream.writeBytes(bytes, 0, bytes.length); //This throws an error on large files.
}catch (e:Error)
{
dispatchEvent( new Event(Event.CANCEL) );
return;
}
_currentArchiveItemBytesWritten += bytes.length;
_pointerPosition = _inputStream.position;
dispatchEvent( new Event(UNARCHIVING_PROGRESS) );
if (_currentArchiveItemBytesWritten >= _curArchiveItem.size)
{
writeNextArchiveItemToFile();
}
}
}
}
class ArchiveItem
{
public var offset:uint;
public var size:uint;
public var filename:String;
public function ArchiveItem()
{
}
}
This was too long for comments..
Just my personal opinion but I think you've over-cooked a simple task. Your usage of .readAhead is confusing. For un-archive part why not have..
(1) On startup your app creates & fills an Object with entries parsed from table of contents (myself I'd just make & update 3 arrays noting file Names, Sizes and also the Indices within the archive file).
(2) For extracting say the 5th file in archive you just check dest_Name = fileNames[4]; for expected output name String, then also note expected dest_Size = size[4]; integer (length to extract).
(3) Now just read the archive file (on disk) and get that 5th file saved.
Archive_Stream.openAsync( URL_Archive_File, FileMode.READ );
Archive_Stream.position = dest_indexInArchive[4]; //starting index
The above would read bytes into a temp_BA which can then be saved (when READ is complete, the handler function does a WRITE to disk of that single extracted file). Now you can use temp_BA.clear(); to reset and clear it for a different file (or just reclaim memory used).
This is a bit difficult to explain, but I will try.
In my Main() class, let's say I have the main movieclip (bg_image) being created, and also some lines that create an instance of another class. (look at the code below)
var route = Route(Airport.return_Route);
This route instance, is then purposed to dynamically add sprite-childs to the main background from the Main() class.
I have tried to to this with the following line:
new_flight = new Flight(coordinates)
Main.bg_image.addChild(new_flight);
This seem to work pretty fine. Let's switch focus to the new_flight instance. At the Flight class, this line trace(this.parent) would return "[object Image]".I would consider this successful so far since my intention is to add the new_flight as child to bg_image, which I guess is an "object image".
The problem, however, occurs when trying to delete the "new_flight"-instance. Obviously the ideal way of doing this would be through bg_image with removeChild.
But, when my script reaches this line: Main.bg_image.removeChild(this), my script stops and returns ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller., at that line. I have also tried replacing Main.bg_image.removeChild(this) with this.parent.removeChild(this), with no luck.
I think the solution may be to use some sort of "EventDispatching"-method. But I haven't fully understood this concept yet...
The code follows. Please help. I have no idea how to make this work...
Main class:
package
{
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.text.TextField;
import fl.controls.Button;
import flash.display.DisplayObject;
import Airport;
public class Main extends Sprite
{
// ------------------------
// Buttons
public var create_new_route;
public var confirm_new_route;
// images
public static var bg_image:MovieClip;
public var airport:MovieClip;
//-------------------------------
public var routeArray:Array;
public static var airportDict:Dictionary = new Dictionary();
public static var collectedAirportArray:Array = new Array();
public function Main()
{
addEventListener(Event.ADDED_TO_STAGE, init);
create_new_route = new Button();
create_new_route.label = "Create new route";
create_new_route.x = 220;
create_new_route.y = 580;
this.addChild(create_new_route)
create_new_route.addEventListener(MouseEvent.CLICK, new_route)
confirm_new_route = new Button();
confirm_new_route.label = "Confirm route";
confirm_new_route.x = 220;
confirm_new_route.y = 610;
this.addChild(confirm_new_route)
confirm_new_route.addEventListener(MouseEvent.CLICK, confirm_route)
}
public function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
bg_image = new Image();
addChild(bg_image);
S_USA["x"] = 180.7;
S_USA["y"] = 149.9;
S_USA["bynavn"] = "New York";
S_Norway["x"] = 423.7;
S_Norway["y"] = 76.4;
S_Norway["bynavn"] = "Oslo";
S_South_Africa["x"] = -26;
S_South_Africa["y"] = 146;
S_South_Africa["bynavn"] = "Cape Town";
S_Brazil["x"] = 226;
S_Brazil["y"] = 431.95;
S_Brazil["bynavn"] = "Rio de Janeiro";
S_France["x"] = 459.1;
S_France["y"] = 403.9;
S_France["bynavn"] = "Paris";
S_China["x"] = 716.2;
S_China["y"] = 143.3;
S_China["bynavn"] = "Beijing";
S_Australia["x"] = 809.35;
S_Australia["y"] = 414.95;
S_Australia["bynavn"] = "Sydney";
// ----------------------------------------------------
airportDict["USA"] = S_USA;
airportDict["Norway"] = S_Norway;
airportDict["South Africa"] = S_South_Africa;
airportDict["Brazil"] = S_Brazil;
airportDict["France"] = S_France;
airportDict["China"] = S_China;
airportDict["Australia"] = S_Australia;
for (var k:Object in airportDict)
{
var value = airportDict[k];
var key = k;
startList.addItem({label:key, data:key});
sluttList.addItem({label:key, data:key});
var airport:Airport = new Airport(key,airportDict[key]["bynavn"]);
airport.koordinater(airportDict[key]["x"], airportDict[key]["y"]);
collectedAirportArray.push(airport);
airport.scaleY = minScale;
airport.scaleX = minScale;
bg_image.addChild(airport);
}
// --------------------------------------------
// --------------------------------------------
// -----------------------------------------------
}
private function new_route(evt:MouseEvent):void
{
Airport.ROUTING = true;
}
public function confirm_route(evt:MouseEvent):void
{
Airport.ROUTING = false;
trace(Airport.return_ROUTE);
var route = new Route(Airport.return_ROUTE); // ***
this.addChild(route); // **
Airport.return_ROUTE = new Array();
}
}
}
Airport class:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;
import flashx.textLayout.formats.Float;
public class Airport extends MovieClip
{
public static var ROUTING = false;
public static var return_ROUTE:Array = new Array();
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
protected var navn:String;
protected var bynavn:String;
// ----------------------------------------------------------------------------
public function Airport(navninput, bynavninput)
{
this.bynavn = bynavninput;
this.navn = navninput;
this.addEventListener(MouseEvent.CLICK, clickHandler);
this.addEventListener(MouseEvent.MOUSE_OVER, hoverHandler);
}
public function zoomHandler():void
{
trace("testing complete");
}
public function koordinater(xc, yc)
{
this.x = (xc);
this.y = (yc);
}
private function clickHandler(evt:MouseEvent):void
{
trace(ROUTING)
if (ROUTING == true)
{
return_ROUTE.push([this.x, this.y])
}
}
private function hoverHandler(evt:MouseEvent):void
{
if (ROUTING == true)
{
this.alpha = 60;
this.width = 2*this.width;
this.height = 2*this.height;
this.addEventListener(MouseEvent.MOUSE_OUT, awayHandler);
}
}
private function awayHandler(evt:MouseEvent):void
{
this.width = 13;
this.height = 13;
}
}
}
Route class
package
{
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.display.MovieClip;
import Main;
public class Route
{
public var income:Number;
public var routePoints:Array;
private var routeTimer:Timer;
private var new_flight:Flight;
public function Route(route_array:Array)
{
this.routePoints = route_array
routeTimer = new Timer(2000);// 2 second
routeTimer.addEventListener(TimerEvent.TIMER, route_function);
routeTimer.start();
}
private function route_function(event:TimerEvent):void
{
for (var counter:uint = 0; counter < routePoints.length - 1; counter ++)
{
trace("Coords: ", routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
new_flight = new Flight(routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
Main.bg_image.addChild(new_flight);
var checkTimer:Timer = new Timer(15);// 1 second
checkTimer.addEventListener(TimerEvent.TIMER, check_function);
checkTimer.start();
function check_function(event:TimerEvent):void
{
if (new_flight.finished = true)
{
checkTimer.stop();
}
}
}
}
}
}
Flight class
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.events.TimerEvent;
import flash.utils.Timer;
import fl.controls.Button;
import flash.display.DisplayObject;
public class Flight extends MovieClip
{
public static var speed:uint = 1
public var finished:Boolean = false;
protected var absvector:Number;
protected var vector:Array;
protected var myTimer:Timer;
//protected var parentContainer:MovieClip;
protected var utgangspunkt_x;
protected var utgangspunkt_y;
protected var destinasjon_x;
protected var destinasjon_y;
protected var vector_x;
protected var vector_y;
public function Flight(utgangspunkt_x, utgangspunkt_y, destinasjon_x, destinasjon_y):void
{
addEventListener(Event.ADDED_TO_STAGE, init);
this.utgangspunkt_x = utgangspunkt_x;
this.utgangspunkt_y = utgangspunkt_y;
this.x = utgangspunkt_x;
this.y = utgangspunkt_y;
this.destinasjon_x = destinasjon_x + 10;
this.destinasjon_y = destinasjon_y + 10;
this.vector_x = Math.abs(this.destinasjon_x-this.utgangspunkt_x);
this.vector_y = Math.abs(this.destinasjon_y-this.utgangspunkt_y);
this.height = 20;
this.width = 20;
}
public function init(evt:Event):void
{
trace(this.parent)
if (utgangspunkt_x < destinasjon_x)
{
this.rotation = -(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
else
{
this.rotation = 180-(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
absvector = Math.sqrt(Math.pow((destinasjon_x - utgangspunkt_x),2) + Math.pow((utgangspunkt_y - destinasjon_y),2));
vector = [(destinasjon_x - utgangspunkt_x) / absvector,(utgangspunkt_y - destinasjon_y) / absvector];
stage.addEventListener(Event.ENTER_FRAME, movement)
}
private function movement(evt:Event):void
{
if (this.vector_x > this.vector_y)
{
if (destinasjon_x>utgangspunkt_x)
{
if (this.x < destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
else if (destinasjon_x<utgangspunkt_x)
{
if (this.x > destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
}
else
{
if (destinasjon_y>utgangspunkt_y)
{
if (this.y < destinasjon_y)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
else if (destinasjon_y<utgangspunkt_y)
{
if (this.y > destinasjon_y)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
}
}
}
}
I am confused what your asking and what your trying to do, but I will give it my best shot.
this.addchild(new_class2)
This line adds your object to the display list. Adding another object to the display is done the same way you added the first. Flash adds objects in the sequentially, so the objects you want in the back need to be declared and added first.
This is probably what you want:
var new_flight:Flight = new Flight();
this.addchild(new_flight);
Also you forgot your type declaration for Class2:
var new_class2:Class2 = new Class2();
Try replacing:
Main.bg_image.addChild(new_flight);
with
Main(this.parent).bg_image.addChild(new_flight);
... assuming the 'main' class you refer to is infact named 'Main' and it has a named instance called 'bg_image'
Please leave a comment if it works, I can explain in more detail what is actually happening here.
Why you are adding new_flight to bg_image?
Anyway, if you are adding new_flight to bg_image, then you have bg_image already declared as public static (which I do not recommend),
Try removing the flight in your Flight class it-self like so,
Main.bg_image.removeChild(this) // *
You can also use Event Dispatching instead of declaring bg_image as static.
If you want to remove flight then dispatch event from Flight class to Route class and there you again dispatch event to main class.
And, inside main class capture this event and access the MovieClip.
Hi I am pretty new to AS3, i am trying to parse some data from php to a VO file, and then transfer the string of data into another .as file where it will put the data into boxes. I am stuck in how do i parse the data from the VO file into the other .as File(Pulling the data from php into BookVO, then parsing BookVO to VectorTest). I tried tracing the data in BookVO, it works ok, but i can't get the data from BookVO to VectorTest.
Please help, thanks
BookVO.as
package com.clark
{
import flash.display.*;
import flash.net.*;
import flash.events.*;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLLoaderDataFormat;
import flash.net.URLVariables;
public class BookVO
{
public var nobed1:String;
public var LoZip1:String;
public var rangelow1:String;
public var rangehigh1:String;
public var Bend:URLRequest;
public var variabless:URLVariables;
public var nLoader:URLLoader;
public function BookVO() {
Bend = new URLRequest("http://localhost/Autoresult.php");
Bend.method = URLRequestMethod.POST;
variabless = new URLVariables();
Bend.data = variabless;
nLoader = new URLLoader();
nLoader.dataFormat = URLLoaderDataFormat.TEXT;
nLoader.addEventListener(Event.COMPLETE,Jandler);
nLoader.load(Bend);
// handler for the PHP script completion and return of status
function Jandler(event:Event) {
var responseVariables: URLVariables = new URLVariables(event.target.data);
this.nobed1 = responseVariables.nobed1 ;
this.LoZip1 = responseVariables.LoZip1;
this.rangelow1 = responseVariables.rangelow1;
this.rangehigh1 = responseVariables.rangehigh1;
}
}
}
}
VectorTest.as
package com.clark
{
import flash.display.MovieClip;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.display.Sprite;
public class VectorTest extends MovieClip
{
public function VectorTest()
{
super();
var books:Vector.<BookVO> = new Vector.<BookVO>();
for (var i:int = 0; i < length; i++)
{
var book:BookVO = new BookVO();
book.nobed1 = "nobed1";
book.LoZip1 ="LoZip1";
book.rangelow1 = "rangelow1";
book.rangehigh1 ="rangehigh1";
books.push(book);
}
for (var j:int = 0; j < books.length; j++)
{
trace("Test", j, "has a name of", books[j].nobed1);
trace("Test", j, "Zip", books[j].LoZip1);
trace("Test", j, "ranglow", books[j].rangelow1);
trace("Test", j, "rangehigh", books[j].rangehigh1);
books[j].nobed1;
books[j].LoZip1;
books[j].rangelow1;
books[j].rangehigh1;
}
var currentY:int = 270;
for (var k:int = 0; k < books.length; k++)
{
var Bolder:Listing2 = new Listing2();
Bolder.x=80;
var tf:TextField = new TextField();
var tf1:TextField = new TextField();
tf1.width = 100;
var tf2:TextField = new TextField();
tf2.width = 100;
tf.defaultTextFormat = new TextFormat("Arial", 12, 0, null, null, null, null, null, TextFormatAlign.CENTER);
tf.width = 100;
tf.autoSize = TextFieldAutoSize.CENTER;
tf1.width = 100;
tf1.autoSize = TextFieldAutoSize.CENTER;
tf2.autoSize = TextFieldAutoSize.CENTER;
tf2.width = 100;
tf1.y= tf.height+5;
// Pulling the textfields content out from the current bookVO
tf2.text = books[k].nobed1;
tf1.text = books[k].rangelow1;
tf.text = books[k].rangehigh1;
tf1.x = (Bolder.height-tf.height)*.5
tf2.x = (Bolder.height-tf.height)*.5
tf.x = (Bolder.height-tf.height)*.5
tf.y = (Bolder.height-tf.height)*.15
Bolder.addChild(tf);
Bolder.addChild(tf1);
Bolder.addChild(tf2);
// position the object based on the accumulating variable.
Bolder.y = currentY;
addChild(Bolder);
currentY += Bolder.height + 35;
}
}
}
}
First off, good job on your classes. Much better than most people who say they're new to AS3. ;)
That said...
In VectorTest, you're calling super() on a MovieClip. You don't need this.
If you're not using the timeline of a MovieClip (which, I'd recommend not using anyway), extend Sprite instead; it's lightweight as it doesn't carry the timeline baggage MovieClip does.
Your first for loop in VectorTest Constructor loops to length... of no array.
You're overwriting the properties of BookVO in that loop, which should be populated by your URLLoader. This is superfluous.
Your second loop references the 4 properties of BookVO, neither reporting or setting the variables (ie., books[j].nobed1;). Might want to remove that.
In BookVO, you've written a nested function. Unless you're dealing with a massive number of variables and have issues with variable scope, don't do it. As it stands, the only variables Jandler() is accessing are already Class level globals.
Loading data is an asynchronous operation, meaning, data doesn't populate instantly (LoadRequest > Wait > ProgressEvent > Wait > LoadComplete). Because you're both instantiating BookVO and reading the properties in the same function, all you'll get are null properties. Unlike the VectorTest constructor, because Jandler() is called on Event.COMPLETE (asynchronously), it will have access to the variables you're looking for.
Try this instead...
You'll still need to address the length of how many books you want to instantiate, however, I've split out your reading of the properties from the constructor, and added a reference to the method to call when the loading is complete.
It will print out all the variables, and if it is the last book in your Vector, it'll call finish() which... um... does the rest of what you were doing. :)
-Cheers
BookVO Updated 2013.11.07 # 12:30 AM
package com.clark{
import flash.display.*;
import flash.net.*;
import flash.events.*;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLLoaderDataFormat;
import flash.net.URLVariables;
public class BookVO {
public var nobed1:String;
public var LoZip1:String;
public var rangelow1:String;
public var rangehigh1:String;
public var Bend:URLRequest;
public var variabless:URLVariables;
public var nLoader:URLLoader;
private var callMethod:Function;
public var data:Object;
public function BookVO(listener:Function = null) {
Bend = new URLRequest("http://localhost/Autoresult.php");
Bend.method = URLRequestMethod.POST;
variabless = new URLVariables();
Bend.data = variabless;
nLoader = new URLLoader();
nLoader.dataFormat = URLLoaderDataFormat.TEXT;
nLoader.addEventListener(Event.COMPLETE,Jandler);
nLoader.load(Bend);
if (listener != null) {
callMethod = listener;
}
}
public function Jandler(event:Event) {
// handler for the PHP script completion and return of status
var responseVariables:URLVariables = new URLVariables(event.target.data);
data = event.target.data;
report(data);
if (callMethod != null) {
callMethod(this);
}
}
private function report(obj:*, prefix:String = ""):void {
for (var k in obj) {
var type:String = getType(obj[k]);
if (type == "Array" || type == "Object" || type == "Vector") {
trace(prefix + k + ": (" + type + ") ¬")
report(obj[k], prefix + " ")
} else {
trace(prefix + k + ":" + obj[k] + " (" + type + ")")
}
}
}
private function getType(value:*):String {
// Returns the class name of object passed to it.
var msg:String = flash.utils.getQualifiedClassName(value);
if (msg.lastIndexOf("::") != -1) {msg = msg.split("::")[1];}
return msg;
}
}
}
VectorTest
package com.clark {
import flash.display.MovieClip;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.display.Sprite;
public class VectorTest extends MovieClip {
public var books:Vector.<BookVO>;
public function VectorTest() {
books = new Vector.<BookVO>();
for (var i:int = 0; i < length; i++) {
var book:BookVO = new BookVO(response);
books.push(book);
}
}
private function response(book:BookVO):void {
trace("Name: ", book.nobed1);
trace("Zip: ", book.LoZip1);
trace("ranglow: ", book.rangelow1);
trace("rangehigh: ", book.rangehigh1);
// call finish() if this is the last book.
if (books.indexOf(book) == books.length - 1) {
finish();
}
}
private function finish():void {
var currentY:int = 270;
for (var k:int = 0; k < books.length; k++) {
var Bolder:Listing2 = new Listing2();
Bolder.x=80;
var tf:TextField = new TextField();
var tf1:TextField = new TextField();
tf1.width = 100;
var tf2:TextField = new TextField();
tf2.width = 100;
tf.defaultTextFormat = new TextFormat("Arial", 12, 0, null, null, null, null, null, TextFormatAlign.CENTER);
tf.width = 100;
tf.autoSize = TextFieldAutoSize.CENTER;
tf1.width = 100;
tf1.autoSize = TextFieldAutoSize.CENTER;
tf2.autoSize = TextFieldAutoSize.CENTER;
tf2.width = 100;
tf1.y = tf.height+5;
// Pulling the textfields content out from the current bookVO
tf2.text = books[k].nobed1;
tf1.text = books[k].rangelow1;
tf.text = books[k].rangehigh1;
tf1.x = (Bolder.height-tf.height)*.5
tf2.x = (Bolder.height-tf.height)*.5
tf.x = (Bolder.height-tf.height)*.5
tf.y = (Bolder.height-tf.height)*.15
Bolder.addChild(tf);
Bolder.addChild(tf1);
Bolder.addChild(tf2);
// position the object based on the accumulating variable.
Bolder.y = currentY;
addChild(Bolder);
currentY += Bolder.height + 35;
}
}
}
}
I am having a really hard time getting a contextmenu or some sort of NativeMenu coming up on right click in my AIR app. Can someone point me in the right direction or provide a small bit of sample code so I clarify it in my mind?
Thanks!
This is nice example of context menu item in air application
Adobe air - add context menu on right click of tree node
Sure,
Take a look at this: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenu.html
Here is the example:
package {
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;
import flash.ui.ContextMenuBuiltInItems;
import flash.events.ContextMenuEvent;
import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
public class ContextMenuExample extends Sprite {
private var myContextMenu:ContextMenu;
private var menuLabel:String = "Reverse Colors";
private var textLabel:String = "Right Click";
private var redRectangle:Sprite;
private var label:TextField;
private var size:uint = 100;
private var black:uint = 0x000000;
private var red:uint = 0xFF0000;
public function ContextMenuExample() {
myContextMenu = new ContextMenu();
removeDefaultItems();
addCustomMenuItems();
myContextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, menuSelectHandler);
addChildren();
redRectangle.contextMenu = myContextMenu;
}
private function addChildren():void {
redRectangle = new Sprite();
redRectangle.graphics.beginFill(red);
redRectangle.graphics.drawRect(0, 0, size, size);
addChild(redRectangle);
redRectangle.x = size;
redRectangle.y = size;
label = createLabel();
redRectangle.addChild(label);
}
private function removeDefaultItems():void {
myContextMenu.hideBuiltInItems();
var defaultItems:ContextMenuBuiltInItems = myContextMenu.builtInItems;
defaultItems.print = true;
}
private function addCustomMenuItems():void {
var item:ContextMenuItem = new ContextMenuItem(menuLabel);
myContextMenu.customItems.push(item);
item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
}
private function menuSelectHandler(event:ContextMenuEvent):void {
trace("menuSelectHandler: " + event);
}
private function menuItemSelectHandler(event:ContextMenuEvent):void {
trace("menuItemSelectHandler: " + event);
var textColor:uint = (label.textColor == black) ? red : black;
var bgColor:uint = (label.textColor == black) ? black : red;
redRectangle.graphics.clear();
redRectangle.graphics.beginFill(bgColor);
redRectangle.graphics.drawRect(0, 0, size, size);
label.textColor = textColor;
}
private function createLabel():TextField {
var txtField:TextField = new TextField();
txtField.text = textLabel;
return txtField;
}
}
}