Loading different assets for desktop and mobile

Hi,
first of all, how can I understand if the application is being loaded by a desktop browser or a mobile one?
At that point, how can I decide to (download and) load and use the assets to use for my app?
I could distinguish the 2 cases directly in the browser, and load an app instead of the other, but I would be forced to maintain 2 separate projects.

You can use keywords, something like this:

#if windows 
//..load assets for windows 
#elseif html5
//..load assets for browser 
#elseif mobile
//..load assets for mobiles 
#end

You can use another keywords as: windows, linux, mac, desktop, cpp

I guess it’s more a Javascript question, and don’t know exactly how to build this detection into your haxe project.
But I’m not sure this separation by platform is relevant neither !

Nowadays desktops can have touch inputs, and a mobile phone can be in full HD.
It’s tempting to build a light-weighted verison for mobile, but what if your user has a retina screen ?

I think you should build something scalable, even responsive, that fits everywhere…

@dmitryhryppa this detection occurs while producing a build, I guess GiG would like to detect that in-browser (desktop browser, or mobile browser).

@Gildas: yes, I need to do the distinction in-browser, keeping the two possible versions in code. I absolutely need to use different assets for desktop and mobile, because after a lot of testing I understood that mobile is a lot “less stable”: resources are often limited and my app neither starts. And well, Retina screen is nothing more than a good i.e. Galaxy screen, it is just marketing :wink:

But how do I load the assets? In the project.xml file I have listed the assets folders to load, and the files are downloaded altogether, how can I tell the application to avoid loading everything and choose what I need to load later with conditional compilation or by xml or remote service request?

Wouldn’t know !
Easily done in pure Javascript, but I never loaded assets with OpenFL AFTER the application launched…
I guess you could start looking around the openfl.Assets class.

Another way around would be : "How do I call native javascript inside an openfl application ?"
I don’t know the answer but it could solve the detection process and the secondary loading at the same time… and I guess it can be done.

I’m interested to know how too !

I just found a post that explains how you can embed native Javascript code in your .hx files.
It seems promising, as you can even use extrernal libs (like jQuery).

With or without jQuery, it’ll be easy to detect if the app is played on desktop or mobile browser.
There are lots of way to do it, even if none is perfect (it’s always possible to cheat with the browser’s agent information).
But I guess you’ll find what you want here.

Still, I don’t know how you could update assets then, and populate them with your javascript loaded assets…
but after all, when your project is built, it’s full-javascript !
So you should be able to reach the Assets javascript objects and interact with it.

Keep us posted, very interesting topic !

@Gildas
Exploring… I already detected browser brand by

Browser.navigator.userAgent

Looks like I can use it for browser type too… now testing…

This function should do what I need:

public static function getBrowserType(): String {
	var browserType: String = "Undefined";
	
	var browserAgent : String = Browser.navigator.userAgent;
	
	if (browserAgent != null) {
		
		if	(	browserAgent.indexOf("Android") >= 0
			||	browserAgent.indexOf("BlackBerry") >= 0
			||	browserAgent.indexOf("iPhone") >= 0
			||	browserAgent.indexOf("iPad") >= 0
			||	browserAgent.indexOf("iPod") >= 0
			||	browserAgent.indexOf("Opera Mini") >= 0
			||	browserAgent.indexOf("IEMobile") >= 0
			) {
			browserType = "MOBILE";
		}
		else {
			browserType = "DESKTOP";
		}
	}
	
	return browserType;
}

For what concerns the different assets for mobile or desktop I think an example will better explain what I need:

I have several assets folders

assets/defaultGFX
assets/mobileGFX
assets/desktopGFX
assets/defaultSFX
assets/mobileSFX
assets/desktopSFX

Normally in my project.xml I should add

<assets path="..." />

for each folder, but in this case I’d like to add

assets/defaultGFX
assets/defaultSFX

only, and load

assets/mobileGFX
assets/mobileSFX

if I detect a mobile device, or

assets/desktopGFX
assets/desktopSFX

in all other situations.
In this example I have splitted the mobile and desktop assets completely in different folders, it would be the better solution to keep things clear, but I would accept to mix the assets in the same folder too, if I had the possibility to load specific files from it.

I have to consider Flash target too, because it is the main target for development, and it needs to embed all assets statically, I don’t care if it embeds both mobile and desktop assets, even if it would be correct embedding the latter ones only.

Noone knows if and how it is possible to do this?

You can use “if” and "unless in the asset tags to include different files or compile conditionals like #if desktop within your Haxe code :slight_smile:

Using if and unless I create separate versions of the same program, one using desktop assets and the other one the mobile assets, not a single program that behaves differently when running on a desktop or a mobile device.
If possible I’d like to avoid having 2 versions of all programs, I’d prefer a single version loading different assets on different situations.

I think OpenFL preloads all images in the assets folder at startup (please correct me if I’m wrong) so including two graphics sets will double the download size for all versions. Maybe look into loading only the required graphics using Loaders?

Or if you’re ok with the increased file size then set up a string somewhere that is set at startup using the browser detection and then use it to make up your file names when using the Assets class.

e.g.

var bmp : BitmapData = Assets.getBitmapData( "assets/" + currentPlatformType + "GFX/image.png");

Yes, I could use loaders, but the default preloader would become useless.
I could create my preloader to run after the default one, but I think it would become a bit messy to manage all the resources that way.

well, no, loading the 2 assets is what I want to avoid.

I think in this case you’ll need your own loaders. You can override the default preloader (not sure how - you’d have to Google, I think it’s an option in your project xml) so you could work something with that to filter out assets you don’t want?

Sadly I have no time to do this, I am searching for a fast way to handle 2 different asset sets without penalizing the download time and device memory.

<assets path="assets" embed="false" />
Assets.loadBitmapData ("image.png", function (_) {
    trace ("image loaded");
}

@singmajesty I think a good feature request for OpenFL / Lime is asset packs. Maybe in a similar way to Flambe. Then in situations like this you wouldn’t need to load each image individually but would instead somehow define a set of assets and just have one callback when it’s all ready to use.

It sounds like you’re suggesting to load each file manually: if this is true, how do I know when the download is complete?
Anyway, I hope this is not the only possible method.