YellowAfterlife

OpenFL-bitfive, alternative HTML5 backend for OpenFL, is now out!

Recommended Posts

bitfive.png

I've just released OpenFL-bitfive, an alternative backend for OpenFL' HTML5 target.

Similar to its older colleague, OpenFL-bitfive allows one to target HTML5 platform while utilizing the comfortable Flash-like API of OpenFL.
A difference is that bitfive is written specifically to pursue performance and compatibility in it's target sphere, being Canvas-driven games. This permits pleasant performance for games running on the backend, as well as mobile device compatibility.

Installation and usage are pretty straight-forward - get haxelib, add one line into XML of project you want to compile with backend. Add another line or two and OGG files for cross-browser audio.

Backend is compatible with HaxePunk and a number of smaller frameworks of this kind. "Plain" OpenFL projects should also work, depending on their configuration.

I believe that technologies of this kind (having Flash and HTML5 targets at once) can be pretty useful in terms of both compatibility and monetization. And what do you think?

Share this post


Link to post
Share on other sites

really interesting !

I made a game for iOS/Android using NME, and when I tried to compile it to HTML5 the performance was terrible, the way NME handles DisplayObject (one canvas per object) is a very bad approach.

I'll surely give bitfive a try when I have some time :)

If you are the author, i'll be awesome if you use Pixijs as HTML5 library for OpenFL

Share this post


Link to post
Share on other sites

This does sound very interesting.
I am just getting into all this html5 stuff and decided to use createJS instead of NME as I want it as simple as possible and don't plan on targeting flash too. But I certainly see that in my future and using NME would probably be the easiest way to get there.

 

Would like to ask, if I use the openFL's drawTiles or what it the name, will it use only 1 canvas? Will the performance be comparable to pure js with something like createjs/pixijs?

Edited by Antriel

Share this post


Link to post
Share on other sites

really interesting !

I made a game for iOS/Android using NME, and when I tried to compile it to HTML5 the performance was terrible, the way NME handles DisplayObject (one canvas per object) is a very bad approach.

I'll surely give bitfive a try when I have some time :)

If you are the author, i'll be awesome if you use Pixijs as HTML5 library for OpenFL

I've seen the NME approach. Here DOM is presented as actual HTML DOM (transformed DIVs primarily); Canvas elements are only used where appropriate (Graphics, BitmapData instances inside their according containers) and there are no overheads in drawing process. To further avoid common strange practices, Sprite-alike objects will only be given a Canvas if they actually have something drawn into their Graphics instance, making them a fairly universal container type.

I was considering Pixi for renderer, and someone else actually started making a backend based on that, but it didn't quite take off, it seems. I may introduce a WebGL-based renderer in future, but that will be a bit later - to avoid repeating common mistakes, you know :)

 

This does sound very interesting.

I am just getting into all this html5 stuff and decided to use createJS instead of NME as I want it as simple as possible and don't plan on targeting flash too. But I certainly see that in my future and using NME would probably be the easiest way to get there.

 

Would like to ask, if I use the openFL's drawTiles or what it the name, will it use only 1 canvas? Will the performance be comparable to pure js with something like createjs/pixijs?

Drawing functions themselves do not create new elements. If your game consists of a single Bitmap to which things are drawn, it will contain a single Canvas element under HTML5.

I'm currently in process of adding drawTiles support - function is demanded, but not particularly efficient outside WebGL canvas, since batching remains up to browser. Graphics objects themselves are already cached for performance though.

Other functions (copyPixels and draw) have performance comparable to raw JS - BitmapData.draw simply applies a matrix and globalAlpha (if needed) and draws the graphic via drawImage. BitmapData.copyPixels does a bit of math to minimize the drawing efforts and also draws via drawImage.

Update: Estimated delivery time for drawTiles is... tomorrow.

Edited by YellowAfterlife

Share this post


Link to post
Share on other sites

Didn't realize drawTiles isn't needed for canvas rendering. Sounds great, so I could just use this with HaxePunk and performance would be good, that does sound really great.

Only thing missing from my dream toolset would be ability to render swf vector data in html :D

Share this post


Link to post
Share on other sites

Hello YellowAfterlife,

 

I am really happy to try your engine. I've been using Openfl to try to build some quad-platform framework (html5,flash,ios,android). Immediately, I didn't like the html5 openfl solution with multiple canvases. In order to maximize my drawing routines I coded my own displaylist and handled parent-child transformations with custom matrices. I even have a bitmapFont renderer, so absolutely all visuals would be handled with drawTiles. However, drawTiles seemed to work best only on ios and android, in Flash still it wasn't optimal, so I rewrote the flash routines to use BitmapData.draw and copyPixels (wherever possible (no rotate and scale in transformation)).

 

I thought drawTiles (using the trans2x2 flag) was also optimal on html5 too, but when I tried it on mobile browser it was painfully slow - drawing a single 480x600 image was just 3-4fps :( . Since I could possible rewrite my html5 routine to use native canvas calls, could I ask you about which calls are the best when it comes to mobile browsers:

 

1.) Drawing a non-rotated, non-scaled bitmap (copyPixels html5?)

2.) Drawing a non-rotated, non-scaled bitmap with alpha

3.) Drawing a rotated,scaled bitmap

4.) Drawing a rotated,scaled bitmap with alpha

 

Is there are big performance loss if you have transformations like in flash, or is negligeable, like in OpenGL ...

 

Thank you a lot :)

Ozdy

 

EDIT: I think this might be a dumb question, but I can't install it :(

When I do 'haxelib install openfl-bitfive', it tells me ''No such Project : openfl-bitfive"

If I copy the openfl-bitfive-master into haxe\libs, I get Error: [file_contents,C:\HaxeToolkit\haxe\lib\openfl-bitfive/.current]

Share this post


Link to post
Share on other sites

Hello YellowAfterlife,

 

I am really happy to try your engine. I've been using Openfl to try to build some quad-platform framework (html5,flash,ios,android). Immediately, I didn't like the html5 openfl solution with multiple canvases. In order to maximize my drawing routines I coded my own displaylist and handled parent-child transformations with custom matrices. I even have a bitmapFont renderer, so absolutely all visuals would be handled with drawTiles. However, drawTiles seemed to work best only on ios and android, in Flash still it wasn't optimal, so I rewrote the flash routines to use BitmapData.draw and copyPixels (wherever possible (no rotate and scale in transformation)).

 

I thought drawTiles (using the trans2x2 flag) was also optimal on html5 too, but when I tried it on mobile browser it was painfully slow - drawing a single 480x600 image was just 3-4fps :( . Since I could possible rewrite my html5 routine to use native canvas calls, could I ask you about which calls are the best when it comes to mobile browsers:

 

1.) Drawing a non-rotated, non-scaled bitmap (copyPixels html5?)

2.) Drawing a non-rotated, non-scaled bitmap with alpha

3.) Drawing a rotated,scaled bitmap

4.) Drawing a rotated,scaled bitmap with alpha

 

Is there are big performance loss if you have transformations like in flash, or is negligeable, like in OpenGL ...

 

Thank you a lot :)

Ozdy

From calls you mentioned, performance order should be either 1>3>2>4 or 1>2>3>4, depending on browser's implementation and size of bitmap. What matters the most is the number of drawing calls. Even pretty low-end Android phones are "alright" with drawing an image that's of size of their screen, but only if its drawn in one piece. Splitting it into pieces grants you performance loss comparable to their number.

Of drawTiles, unfortunately it only wins you performance if there is hardware acceleration (such as on native platforms). In Flash and HTML5 drawTiles only gives you unnecessary memory management for keeping that array at right size.

In OpenFL-bitfive, copyPixels is the fastest-working function, similar to as it is in Flash. This is achieved by having automatic "clipping" of drawn area if it exceeds either source or destination rectangle. Then goes the draw() method (note: drawing non-transformed graphics at rounded positions helps a lot at mobile). And then there's drawTiles.

EDIT: I think this might be a dumb question, but I can't install it :(

When I do 'haxelib install openfl-bitfive', it tells me ''No such Project : openfl-bitfive"

If I copy the openfl-bitfive-master into haxe\libs, I get Error: [file_contents,C:\HaxeToolkit\haxe\lib\openfl-bitfive/.current]

You would have to use "haxelib git" to install the library, since it is currently isn't added to haxelibs.

Alternatively, process is as following:

* Create a folder called "openfl-bitfive" in haxe library folder

* Create a file called ".current" inside of folder.

* Add line "1.0.5" (or other text of your choice actually) into the file.

* Create a folder called "1.0.5" (same as text in file) alongside the ".current" file.

* Unpack repository contents into that folder, so that Readme.md would be accessible by path ".../haxe/lib/openfl-bitfive/1.0.5/README.md"

Then use as normal.

Share this post


Link to post
Share on other sites

Hi YellowAfterlife,

 

I managed to install it, but I can't compile, I get an error in my Input class:

 

flash.events.MouseEvent has no field stageX
flash.events.MouseEvent has no field stageY
 
I saw the source and indeed there are no such properties, how would you get the coordinates of clicks?
 
EDIT: I substituted my game logic to use TouchEvents rather than MouseEvents, but they don't register, I switched back to normal openfl and it was no problem with touch events.
 
EDIT2: Other than that, I ran some tests, and it really performs greatly! I can put over 100 sprites at 30fps (iphone 4s)! Great job!

Share this post


Link to post
Share on other sites

I've just updated the library with localX/Y and stageX/Y implementations in MouseEvent. Let me know if any issues arise with these.

While the two weren't in place before, DisplayObject.mouseX/Y were returned correctly, also happening to be the approach used in HaxePunk and HaxeFlixel.

Touch events are currently not being handled correctly due to difference between Flash and HTML5 approaches - while Flash dispatches an even per every touch, JS(HTML5) dispatches a single event for all touches, containing an array of "information" objects inside. This makes "legitimate" implementation slightly more problematic, since JS event must be split into series of OpenFL-compatible ones. I'll get to this part in near future.

Share this post


Link to post
Share on other sites

Bitfive MouseEvents work on desktop but don't work in mobile browser unfortunately. Maybe the original openfl somehow transfers the first touch event as a mouseevent so that it works in mobile ...

Taking a look at it, MOUSE_DOWN and MOUSE_UP events are dispatched correctly, but MOUSE_MOVE isn't. Were you referring to mouse move event specifically?

I also have a mobile game developed with framework and relying on MOUSE_DOWN (add listeners to stage) - ENTER_FRAME (get current mouseX/mouseY right from the instance and work with those) - MOUSE_UP (remove listeners) for handling "swipe" input and it have been working perfectly on both iOS and Android.

OpenFL-html5 is catching events at the Window and finds their "destinations" by iterating through whole DOM where appropriate. Such approach grants a more consistent behaviour but also requires a larger number of calculations, to the point where slowdown on larger scenes can be caused simply by number of interactive objects being polled upon user input (this problem also partially exists in Flash though). I would rather avoid this method, unless it would be the only option.

That said, I'll take a look at mouse-touch events soon. Probably will make certain types of mouse events also bind a touch event to ensure arrival. Hopefully not in overly strange way. Meanwhile, workaround [described above] can be used - mouse position reported via DisplayObject.mouseX/mouseY is already being detected with touch events in mind, so it is always reported correctly.

Share this post


Link to post
Share on other sites

For me no bitfive mousevents are dispatched at all in mobile (neither of the three). My setup is - add the event listeners to the main sprite (Main extends Sprite), then add a bitmap with bitmapdata as big as screen as child to main, then draw everything to that bitmapdata via draw() and copyPixels(). There are no problems on desktop. Dom looks like this:

 

2013-09-18_1148.png

Share this post


Link to post
Share on other sites

Nice, it works now.

Now I can have transparent bitmaps with bitmapdata.draw() - original openfl couldn't handle it in html5 :)

 

Minor issues that I worked around:

1.) Touch coordinates are tracked from 0,0 of html document, not containing div (I use to reposition the root div to be centered)

2.) Resize events don't fire at all, I'll resort to checking if height,width has changed each frame - resize events weren't too reliable anyway on some devices.

 

Thanks again, I'll continue to test the framework :)

Share this post


Link to post
Share on other sites

1.) Touch coordinates are tracked from 0,0 of html document, not containing div (I use to reposition the root div to be centered)

Indeed, it is intended for game to fill if not the whole page, then at least the top-left corner of it. Centering is normally done on the code side of game; Preloaders can be made to draw graphics at the center of the page also. I'll look if it's possible to make mouse coordinates relative without unwanted sacrifices.

2.) Resize events don't fire at all, I'll resort to checking if height,width has changed each frame - resize events weren't too reliable anyway on some devices.

Resize event upon size change of browser is being dispatched on Stage itself - listening at the Main would not work, for example. Resize events of objects are currently not implemented as these would require a fair of otherwise unnecessary event creation and dispatching. These will be likely implemented later, but have to be "done right", and are easy to simulate, so not that high of priority at the moment.

Share this post


Link to post
Share on other sites

Have you tested your framework on iPad1? My demo is getting stuck at loading screen with small white bar being empty.

 

ReferenceError: Can't find variable: DataView

 

...

,_nmeResizeBuffer: function(len) {		var oldByteView = this.byteView;		var newByteView = new Uint8Array(len);		if(oldByteView != null) {			if(oldByteView.length <= len) newByteView.set(oldByteView); else newByteView.set(oldByteView.subarray(0,len));		}		this.byteView = newByteView;		this.data = new DataView(newByteView.buffer); //<THIS LINE GIVES ERROR	} 

...

EDIT: I am using version IOS 4.2.1, and I can't update it, so this must be a problem.

Share this post


Link to post
Share on other sites

Hi again, YellowAfterLife,

 

I was really pleased to see that bitmapFills are working in your bitfive! There is an issue though, the matrix argument on draw() when using sprites with bitmapFills gets ignored. This argument works when I use draw() with bitmapdata.

Here is an example of the same code in Flash (left) and html5 bitfive (right):

 

2013-09-26_1815.png

 

The brick block is drawn with screenBitmapData.draw(sprite_with_bitmapFill, transformationMatrix); and the transformationMatrix is ignored in bitfive - bitmapFill sprite is at (0,0)

The green block is drawn with screenBitmapData.draw(blockBitmapData, transformationMatrix); and is working fine :)

Share this post


Link to post
Share on other sites

Hi again, YellowAfterLife,

 

I was really pleased to see that bitmapFills are working in your bitfive! There is an issue though, the matrix argument on draw() when using sprites with bitmapFills gets ignored. This argument works when I use draw() with bitmapdata.

Added in. Behaviour for drawing non-tiled fills relies on browser implementation (although standard states the expected behaviour), so can be inconsistent. Seeing that flash behaviour is also "stretch" (alike to Firefox), I don't think it is something that could be used to someone's advantage.

Have you tested your framework on iPad1? My demo is getting stuck at loading screen with small white bar being empty.

 

ReferenceError: Can't find variable: DataView

 

...

That is an interesting question.

Some of older devices don't support DataView. Some don't even support typed arrays. Ultimately one shouldn't rely on ByteArray for non-binary resource loading, but rather on URLRequests. There are some workarounds but they aren't extremely cross-browser either and in the end will primarily add some kilobytes to the output size. I'm planning to introduce a number of flags to adjust output size and compatibility, but that will be later.

Share this post


Link to post
Share on other sites

Added in. Behaviour for drawing non-tiled fills relies on browser implementation (although standard states the expected behaviour), so can be inconsistent. Seeing that flash behaviour is also "stretch" (alike to Firefox), I don't think it is something that could be used to someone's advantage.

 

The transformation matrix is still ignored for me. That's how I set it:

// set the flash.geom.matrix instance from custom Matrix class instance cmToDraw explicitlyDrawMatrix.tx = cmToDraw.m02;DrawMatrix.ty = cmToDraw.m12;DrawMatrix.a = cmToDraw.m00;DrawMatrix.b = cmToDraw.m10;DrawMatrix.c = cmToDraw.m01;DrawMatrix.d = cmToDraw.m11;//Draw flSprite, its x,y,rot, or flSprite.transform.matrix have never been set to anythingMain.instance.ScreenBMD.draw(flSprite,DrawMatrix,null,null,null,true);
EDIT: When I updated the library I saw that only three files are updated - Lib, DisplayObject, and Graphics, which is odd as the issue is with .draw() of BitmapData class.

Share this post


Link to post
Share on other sites

The transformation matrix is still ignored for me. That's how I set it:

// set the flash.geom.matrix instance from custom Matrix class instance cmToDraw explicitlyDrawMatrix.tx = cmToDraw.m02;DrawMatrix.ty = cmToDraw.m12;DrawMatrix.a = cmToDraw.m00;DrawMatrix.b = cmToDraw.m10;DrawMatrix.c = cmToDraw.m01;DrawMatrix.d = cmToDraw.m11;//Draw flSprite, its x,y,rot, or flSprite.transform.matrix have never been set to anythingMain.instance.ScreenBMD.draw(flSprite,DrawMatrix,null,null,null,true);
EDIT: When I updated the library I saw that only three files are updated - Lib, DisplayObject, and Graphics, which is odd as the issue is with .draw() of BitmapData class.
Oh. That was a separate issue, and not really related to BitmapFill itself. Fixed.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.