Download Manager

Download Manager is a native extension to manage the download of big files. When a game requires a significant amount of assets, it’s wide to download them separately to keep the application size smaller (often a requirement for it to be published). The classic Flash APIs can help with downloads, but they are very limited. For instance downloads are not resumable  and they are fetched using only one download channel .

The Download Manager extension fully automates the process, allowing a developer to download big files as fast as possible by downloading the data in chunks. Additionally it is possible to resume a download in case of anything goes wrong, which is something that users expect to happen. A developer can also decide what sections/chunks to download, manage queue for downloads, start more than one download at a time and read download status.

Sample

private var _ex:DownloadManager = new DownloadManager();
private var _currDownloadId:int;

// add the required listeners to know how the download progress goes
_ex.addEventListener(DownloadManagerEvent.ERROR, onError);
_ex.addEventListener(DownloadManagerEvent.CONNECTION_LOST, onConnectionLost);
_ex.addEventListener(DownloadManagerEvent.PROGRESS, onProgress);
_ex.addEventListener(DownloadManagerEvent.PAUSED, onPaused);
_ex.addEventListener(DownloadManagerEvent.COMPLETE, onComplete);

// there's also the following listener which outputs a lot of other information about your download tasks. please study this listener on your own time:
// _ex.addEventListener(DownloadManagerEvent.STATUS, onStatus);
// private function onStatus(e:DownloadManagerEvent):void
// {
//   trace("download id: " + e.param.id, "download state: " + e.param.state) // refer to DownloadStates class to know what download states mean.
// }

// setup the download manager default values
_ex.setupLib(null, 5);

// introduce a new download task
_currDownloadId = _ex.setupDownload("http://myappsnippet.com/downloads/AIR_EXTENSIONS/dm/dm_AIR.zip", "dm_AIR", DownloadManager.PRIORITY_HIGH, null, 0, false);
trace("Download id = " + _currDownloadId);

// start the download
_ex.start(_currDownloadId);

// pause the download like this:
// _ex.pause(_currDownloadId);

// get status of a task like this
var obj:Object = _ex.getStatus(_currDownloadId);
for (var name:String in obj) {
    trace(name + " = " + obj[name])
}

private function onError(e:DownloadManagerEvent):void {
    trace(e.param.msg)
}

private function onConnectionLost(e:DownloadManagerEvent):void {
    trace("connection lost for id: " + e.param.id)
}

private function onProgress(e:DownloadManagerEvent):void {
    trace("id: " + e.param.id, "    %" + e.param.perc + "   bytes: " + e.param.loadedBytes)
}

private function onPaused(e:DownloadManagerEvent):void {
    trace("paused for id: " + e.param.id)
}

private function onComplete(e:DownloadManagerEvent):void {
    trace("Completed for id: " + e.param.id)
}
Commercial
3 Comments

PlayHaven

PlayHaven is a native extension to use PlayHaven services. PlayHaven is a mobile game LTV-maximization platform to help with the business of games. It target to acquire, retain, re-engage, and monetize players with the help of a marketing platform. Once integrated the service can be used to analyze in-game promotions and monetization in real-time through PlayHaven’s web-based dashboard.

PlayHaven services are able to add the placements, widgets, rewards, content, and Virtual Goods Promotion items that a developer wants to use. It’s possible to take note of the tokens, keys,and placement tags of an app.

Sample

if(PlayHaven.isSupported()) {
    PlayHaven.create("your_token","your_secret","your_gcm_project_number");
} else {
    trace("extension works on iOS And Android only.");
}

PlayHaven.create("your_ios_token","your_ios_secret","your gcm project number", "your_android_token","your_android_secret");
PlayHaven.playhaven.reportGameOpen();
PlayHaven.playhaven.preloadContentRequest("your_placement_id");

// set up event listeners for content overlays
PlayHaven.playhaven.addEventListener(PlayHavenEvent.CONTENT_OVERLAY_DISMISSED,onContentDismissed);
PlayHaven.playhaven.addEventListener(PlayHavenEvent.CONTENT_OVERLAY_DISPLAYED,onContentDisplayed);
PlayHaven.playhaven.addEventListener(PlayHavenEvent.CONTENT_OVERLAY_FAILED,onContentFailed);

// start the content request
PlayHaven.playhaven.sendContentRequest("more_games");

function onContentDisplayed(e:PlayhavenEvent):void {
    // an overlay is showing - pause for now...
    pauseGame();
    stopSounds();
}

funnction onContentDismissed(e:PlayHavenEvent):void {
    // overlay is closed - resume the game
    resumeGame();
    resumeSounds();

    // the event's contentDismissalReason property holds a value
    // from the ContentDismissalReason constants class- indicating
    // the reason the view was dismissed:
    switch(e.contentDismissalReason) {
        case ContentDismissalReason:USER_CONTENT_TRIGGERED: trace("the user or content unit closed the window."); break;
        case ContentDismissalReason:USER_BUTTON_CLOSED: trace("the close button was pushed."); break;
        case ContentDismissalReason.APP_BACKGROUNDED: trace("the app was sent to the background."); break;
        case ContentDismissalReason:NO_CONTENT_AVAILABLE: trace("no content was found for the placement."); break;
    }
}
2 Comments

iBeacon

iBeacon ANE is a native extension to use iBeacon on Android devices. It can be used to monitor iBeacon signals and setup a device to act as a virtual iBeacon. Based on Estimote SDK, it’s able to check the state of the device’s bluetooth (powered on, off or unsupported) and start/stop the monitoring of iBeacons (it scans for all major and minor values). When a device is found, it triggers a local notification.

Sample

import com.compass.ibeacon.DeviceController;

private var _ibeaconAND:DeviceController = DeviceController.instance;
private const _ibeaconUDIDs:Array = ["B9407F30-F5F8-466E-AFF9-25556B57FE6D"];

//add listener
_ibeaconAND.addEventListener(iBeaconEvent.IBEACON_FOUND, ibeaconANDHandler);
_ibeaconAND.registerBeaconsForScanning(_ibeaconUDIDs);

private function ibeaconANDHandler(e:iBeaconEvent):void{
  if(e.ibeacons){
    var iBeaconList:Array = e.ibeacons;
    for(var i:uint=0;i<iBeaconList.length;i++){
      trace('Name: ' + $list[i].name + '\n');
      trace('UUID: ' + $list[i].uuid + '\n');
      trace('Range: ' + $list[i].range + '\n');
      trace('RSSI: ' + $list[i].rssi + ' dB' + '\n');
      trace('Major: ' + $list[i].major + '\n');
      trace'Minor: ' + $list[i].minor + '\n');
      trace('Accuracy: ' + $list[i].accuracy + '\n');
    }
  }else{
    trace(“ibeacon no found”);
  }
}
Commercial
3 Comments

solMailBox

solMailBox is a swf-to-swf and swf-to-server communication system that facilitates async passing of messages. It works pretty much like email: participants can send messages which are then new / pending / read / deleted. A use case is when users of an e-learning AIR app, for instance, have the capacity to keep notes within the application. It would be inefficient to be constantly sending updates to the remote server.

SolMailBox keeps the notes locally at a short interval – 1 second, and a remote-connecting service grabs them periodically (1 minute) and sends them to the server. Saving locally ensures that if the user quits the program between 1 minute remote-saves their notes are saved locally and can be uploaded next time.

Sample

var solData:Object = {};                  
var mailMessageVO:MailMessageVO;  
var readMessages:Vector. = new [];

var iLength:uint = totalItems;

for (var i:int = 0; i < iLength; i++) {
  mailMessageVO = new MailMessageVO();
  mailMessageVO.body = "some text";
  mailMessageVO.id = i+1;
  mailMessageVO.link = (i+1) % 10;
  mailMessageVO.status = "READ";
  mailMessageVO.dateTimeStamp = new Date(); 
  readMessages[readMessages.length] = mailMessageVO;
}

solData.readMessages = readMessages;
solData.newMessages = new [];
3 Comments

as3hx

as3hx is a tool to convert AS3 sources to their Haxe equivalent. The tool works in the command line and receives a directory as input. The output can be directed to any folder in the filesystem and it will contain the converted Haxe files. There are many configuration options to choose how the Haxe code is generated. Despite a few edge cases, the tool is completely capable of converting AS3 code to Haxe. Regarding those edge cases, after the conversion the developer must inspected the generated Haxe code looking for any inconsistencies.  Currently the edge cases that are not working are the use of delete keyword, E4X syntax and some variable initialization in for loops. Sample

as3hx test/ out/
MIT
6 Comments

Beaver

Beaver is a logging application and lib for flex/flash applications. It is able to store logs to a LSO, send logs to a Beaver AIR app, generates a log report, can opt in or out of sending to flash console i.e. trace, uses a unique key for all handshakes and offers a channel to handle Error/Fatal events within the application. Regarding the log report generation, any application can perform that task by connecting to Beaver and reading the logs identified by a unique key.

In order to use the logger, a developer must create a unique key starting with an underscore i.e. _123456. After that, it necessary to send a reference to the app instance to assign a handler for dispatched ERROR/FATAL events. Finally create a class to send the logs.

Sample

public class BeaverLog {

    /**
     * Constructor expects a unique key for the application
     * and a flag to send all output to the flash console.
     *
     * @param key:String
     * @param app:Object
     * @param outputToConsole:Boolean (default = true)
     */
    private static var trunk:BeaverTrunk = new BeaverTrunk("_123456", Example.root);

    public static function send(message:String, sender:Object, level:int = 4):void {
        trunk.saveNewLog(message, sender, level);
    }
}

BeaverLog.send("Gnaw a log or two", this);
BeaverLog.send("The whole tree fell!", this, LogEventLevel.FATAL);
MIT
3 Comments

flashsnes

flashsnes is a SNES emulator that runs on Flash Player. It is a port of SNES9x, a portable, freeware Super Nintendo Entertainment System (SNES) emulator. The project is coded using AS3 and C, which is compiled using the Alchemy compiler. The AS3 part of the app has the integration logic for SNES9x video, sound and events (implemented in C).

Some of the AS3 files are generated by a script that uses some C files and input. After all files have been generated, it’s possible to compile an SWC containing code for SNES9X. Using that SWC, a developer can instantiate an Emulator class and start playing SNES rooms in Flash. This class handles everything from rendering to audio and input.

Sample

// Emulator
var emulator:Emulator = new Emulator( romLoader.data, stage );
var screen:Bitmap = emulator.screen;

// Performance Adapter
var adapter:PerformanceAdapter = new PerformanceAdapter;
adapter.wrapEmulator(emulator);

// Interface
var playerControls:PlayerControls = new PlayerControls( emulator );
var performance:Performance = new Performance();

// Show
addChild( screen );
10 Comments

Codebot devlog 003 – editor preferences

This post is part of a series describing the development of Codebot, an open-source IDE focused on game development. Check out the other posts of the series here.

I took a break from fixing and closing issues in Codebot’s TODO list and decided to focus on a few pending things. Since I’m using Codebot to develop Codebot, I had to smooth some of its rough edges to make it more usable.

As a result, I’ve fixed lots of small annoyances that were getting in my way, such as the ability to save a tab when Cmd+S is pressed or a visual indicator highlighting tabs with unsaved content. While doing that, I spent some time adding love to the layout. Codebot is in alpha state, but it doesn’t mean it must be ugly =) The layout still requires a lot of work, but it will be something to do in the future.

After fixing all those small things, I started working on issue #22 (application preferences). It’s about Codebot remembering how the user wants it to be, such as tab sizes, if the current line should be highlighted, etc. Below is a screenshot of the current preferences panel:

codebot_devlog_003_preferences

The editor preferences will be available from the “brain button” (the little cogs at the bottom-right corner in the image). By clicking there a developer will be able to fully customize/tweak Codebot to their needs. Right now the preference panel has a white background, but it will be dark in the near future, such as the following image (from Webflow website):

dialog

I also worked on internal APIs, such as the one that controls editors. It is used by Codebot to decide what to use to edit a specific file extension. Right now it only has a single editor (Ace) which is used to open everything, but soon I will add an image visualizer.

I am pretty happy with my develop so far. The API is getting better (after re-factoring small pieces occaisonally) and mature enough to receive some cool features, like a slide panel about SFX or assets. I did some research on that and nodejs is packaged with several HTTP libs, which will be useful to implement that panel. My upcoming goals are the preferences panel and, after that, any sliding panel (maybe a OpenGameArt one).

codebot gamedev IDE
4 Comments

as3-psd-parser

as3-psd-parser is a lib to parse PSD (Photoshop) files. It works by instantiating the PSDParser class, then calling the parse method passing the content of a PSD file in byte array format. The parsing is synchronous so after that line, you will already have all the file/layers info available. A loaded and parsed file will have their original layers, with their blend modes, visibility , lock, alpha , layer effect etc. Regarding the PSD file, the lib is able to parse canvas width x height, file color information (number of color channels, color depth, color mode), file’s composite bitmap snapshot and all layers and layer folders.

The lib is able to parse the following layers info: bitmap data, bounds and position, name, ID, blend mode, colour channels, alpha, filter, extra properties (e.g. isLocked, isVisible, clipping applied) and type (normal, folder).

Sample

var psdParser :PSDParser = PSDParser.getInstance();
psdParser.parse(file.data);	

var layersLevel :Sprite = new Sprite();
this.addChild(layersLevel);

for (var i : Number = 0;i < psdParser.allLayers.length; i++) {
    var psdLayerm :PSDLayer = psdParser.allLayers[i];
    var layerBitmap_bmp :BitmapData = psdLayer.bmp;
    var layerBitmap :Bitmap = new Bitmap(layerBitmap_bmp);
    layerBitmap.x = psdLayer.position.x;
    layerBitmap.y = psdLayer.position.y;
    layerBitmap.filters	= psdLayer.filters_arr;
    layersLevel.addChild(layerBitmap);
}

var compositeBitmap:Bitmap = new Bitmap(psdParser.composite_bmp);
layersLevel.addChild(compositeBitmap);
Apache 2.0
13 Comments

Application Rater

Application Rater is a native extension to ask the user to rate the applications by displaying a native feedback dialog. According to the platform the application is running on, the extension asks the user to rate the application in the proper application store. When the user agrees to rate the application they are taken to the applications page in the store.

Among its features it’s a native interface to ask a user to rate the application, which enhances the user’s trust on the action. The extension also has a range of conditions to automatically display the dialog, including customisable labels and condition. It’s also possible to use a reminder code to ask the user to rate at a later point if the user clicked the “remind me later” option.

Sample

ApplicationRater.init( DEV_KEY );
ApplicationRater.service.setApplicationId( "air.com.distriqt.test", ApplicationRater.IMPLEMENTATION_ANDROID );
ApplicationRater.service.setApplicationId( "552872162", ApplicationRater.IMPLEMENTATION_IOS );
ApplicationRater.service.applicationLaunched();

ApplicationRater.service.setDialogTitle("Rate the app!"):void
ApplicationRater.service.setDialogMessage("Please rate the app.");
ApplicationRater.service.showRateDialog();
Commercial
6 Comments

as3-lib-subtitle

as3-lib-subtitle is a library to load subtitle using some common formats. The lib has built-in support for the .srt and .sub formats, allowing developer to load those subtitle files and parse them. After the parsing is complete, it’s possible to retrieve the subtitle text by line or by time. The lib also has a display package with a subtitle viewer, a class that abstracts and encapsulate the process of displaying subtitles on the screen.

Two events are available to monitor the lib work. One is fired when a new subtitle is loaded, the other one is fired when it’s time to display a new line. Every text/line in the subtitle is handled as an item containing several information, such as its index, start/end time, duration and text.

Sample

var srt:SRTResource;
srt = new SRTResource();
srt.parse("1\n00:00:15,431 --> 00:00:16,898\nHere goes the subtitle lines...");

var strTime:String = "00:00:15,431";
SRTResource.getTimeStamp(strTime); // Returns 15431

var findedsubitem:SubTitleItem = srt.getByTime(9999999);
trace(findedsubitem.index);
trace(findedsubitem.duration);
trace(findedsubitem.startTime);
trace(findedsubitem.endTime);

// Load external subtitle file
var subtitle:SRTResource = new SRTResource();
subtitle.load("fixtures/bigbang.srt");
subtitle.addEventListener(SubtitleEvent.LOADED_SUBTITLE, function(e:Event):void{
    trace(subtitle.length);
    trace(subtitle.lines[0].duration);
});
3 Comments

PDF Reader

PDF Reader is a native extension to display a PDF reader that allows users to read and browse PDF contents. Using a singleton, a developer can display the PDF reader at any time by calling the showPDF() method. It receives two parameters, one is the PDF file path and the other is a password that will be used to read the file. If the PDF is not password-protected, the second parameter can be an empty string.

While reading the PDF file, the user can click an email button, which will open en email dialog. The extension allows a developer to specify the subject and content of that e-mail before the user opens it. The viewer used by the extension is built on top of  VFR Reader, a library to visualize PDF files.

Sample

// Initialise the extension
PDFReader.init(DEV_KEY);

// Show a PDF
var path:String = File.applicationDirectory.nativePath + File.separator + "Reader.pdf";
PDFReader.service.showPDF(path);
Commercial
Comments Off on PDF Reader

Full Screen

Full Screen is a native extension to offer users a true full screen experience in apps for Android. Using Android 4.0+ it’s possible to use true full screen in “lean mode”, which is used by apps like YouTube to expand the app right to the edges of the screen, hiding the status and navigation bars until the user next interacts. This is ideally suited to video or cut-scene content.

In Android 4.4+, however, you can now enter true full screem, fully interactive immersive mode. In this mode, the app will remain in true full screen until the user chooses otherwise; users can swipe down from the top of the screen to temporarily display the system UI. This extension can be used with Starling.

Sample

// Is this ANE supported?
AndroidFullScreen.isSupported;
// Is immersive mode supported?
AndroidFullScreen.isImmersiveModeSupported; 
// Hide system UI until user interacts
AndroidFullScreen.hideSystemUI(); 
// Show system UI
AndroidFullScreen.showSystemUI(); 
// Extend your app underneath the system UI (Android 4.4+ only)
AndroidFullScreen.showUnderSystemUI(); 
// Hide system UI and keep it hidden (Android 4.4+ only)
AndroidFullScreen.immersiveMode(); 
// Hide system UI until user swipes from top (Android 4.4+ only)
AndroidFullScreen.immersiveMode(false); 

if (!AndroidFullScreen.immersiveMode()) {
    stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}

if (!AndroidFullScreen.hideSystemUI()) {
    stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}
BSD
4 Comments

CoreMobile

CoreMobile is a native extension to easy access to core mobile features (e.g gyroscope) in a seamlessly way on iOS and Android. It has an advanced Gyroscope API, which monitors the device’s built-in gyroscope, in combination with hints from its other available sensors, to compute accurate orientation readings. The API and results are exactly the same, whether the game is running on iOS or Android. The measurement is made using synchronous access to the device’s current roll. The local notifications API allows a developer to send a message to the current user only after a given delay.

The network connection monitoring can determine if the internet connection is available using a single function call. In case real-time updates are required, it’s possible to listen for the connection being lost or gained with one simple event. The vibration API adds tactile feedback to games by triggering the vibration on the user’s mobile phone. Finally the native UI provide native modal dialogs to alert the user to an important event, ask a question, collect simple input, or get login information.

Sample

function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void;
function cancelAllLocalNotifications():void;
function cancelLocalNotification(id:int):void;
function create():CoreMobile;
function futureTimeSeconds(secondsFuture:Number):Number;
function getDeviceMotionData():DeviceMotionData;
function isDeviceMotionAvailable():Boolean;
function isNetworkReachable():Boolean;
function isSupported():Boolean;
function scheduleLocalNotification(id:int, timeSeconds:Number, title:String, message:String, alertLabel:String = null, extraData:Object = null):void;
function showModalConfirmationDialog(title:String, message:String, buttonLabel:String):CMDialogDispatcher;
function showModalCredentialsDialog(title:String, message:String, confirmButtonLabel:String, cancelButtonLabel:String = null):CMDialogDispatcher;
function showModalInputDialog(title:String, message:String, confirmButtonLabel:String, defaultPrompt:String, cancelButtonLabel:String = null):CMDialogDispatcher;
function showModalYesNoDialog(title:String, message:String, yesButtonLabel:String, noButtonLabel:String):CMDialogDispatcher;
function startMonitoringDeviceMotion():void;
function stopMonitoringDeviceMotion():void;
function vibrate(duration:Number = 1):void;
Commercial
7 Comments

Flurry SDK

Flurry SDK is a native extension to use the services of  Flurry analytics. Using its API a developer is able to get some insights about how the app is used by creating events, which are unique actions that users complete in the app. Events are easy to set-up and it’s possible to track anything relevant to the app context such as when a consumer makes a purchase, completes a level or uses a key feature. Additionally parameters can be added to events for much finer detail.

The extension was created to be as identical as possible to how the Flurry SDK works. A set of easy to use methods is available for use, such as a methods to start/end a user session, log an event (using a single string or an array of properties) or report errors. The SDK also has a set of properties that can be used to make the report more specific, e.g. inform the user gender, id or age.

Sample

// initialize the extension
var _ex:Flurry = new Flurry();
_ex.flurryAgent("flurryApiKeyHere", true);

// if you want to receive location information,
// you should set this property to 'true' after starting your session with flurry
_ex.reportLocation = true;

// to know about the user's age
_ex.age = 23;

// for tracking your users, you may have specified a user id for them,
// if so, you may send this ID using this property
_ex.userId = "AvFgasd192168247612";

// use this property to specify if your user is male 'true' or female 'false'
_ex.gender = true;

// set this property to 'true' if you want your app to connect to flurry
// using https protocol
_ex.useHttps = true;

// set the timeout for expiring a Flurry session
_ex.continueSessionTime = 10;

// use this property to specify a version name for your app
_ex.versionName = "myApp";

// set this property to 'true' to enable or 'false' to disable the
// internal logging for the Flurry SDK
_ex.logEnabled = true;

// set the log level of the internal Flurry SDK logging.
_ex.logLevel = 2;

// use this property to specify if you want the event logging
// to be active or not
_ex.setLogEvent = true;

// after setting the properties, use this method to start your
// flurry session
_ex.startSession();

// when you are finished with your flurry session terminate it
// with this method
_ex.endSession();

// use this property to know about the current flurry session
trace("status : " + _ex.status);

// you may use flurry to log errors, use this method and pass
// your Error ID and message
_ex.onError("ErrorID", "Error msg");

// use this method to send an Event ID
_ex.logEvent("eventID");

// end a timed event.
 _ex.endTimedEvent("eventID");

// you may also send log events in form of an array of objects like below.
var obj1:Object = {event1:"value1"};
var obj2:Object = {event2:"value2"};
var obj3:Object = {event3:"value3"};
var logEvent:Array = [obj1,obj2,obj3];

_ex.logEventArray("EventID", logEvent);

// Use this method whenever you want to know your app page views.
_ex.onPageView();

// use this property to know the flurry SDK version used in this extension.
trace("flurrySdkVersion >> " + _ex.flurrySdkVersion);
Commercial
2 Comments