I ran into a problem while working with Flare3D on a game. I was making a racing game, and the player drives through five areas. The problem was that each area the user drives through was a very detailed envirnment. About 4-10 megabytes a piece. Far too large for player to download up front.
So I decided to build a progressive preloader, that loads the levels as the player plays. At first I tried this using the Flare3DLoader class. In using it I encountered two problems, one of which was a fatal problem for the approach:
Problem 1:
The Flare3DLoader class will never fire a Complete event unless it is attached to a scene. It makes sense in a way, in that your model is not ready to be accessed through the Flare3D api until it has been parsed. But the downside is that you can’t know the load is complete unless add the loaded resource to the scene.
While I got this to work, it could easily cause problems as all these items get unpacked into your limited OpenGL memory. Another drawback is that you cannot re-load the asset either. Once you call dispose() on the loaded asset, its gone.
Problem 2:
When the asset finishes loading, the entire flash plugin freezes for a second or more while your model is parsed and written to the GPU. This was the deal-breaker for me, as the end result was that the game would hang for one or more seconds at an arbitrary point in time. I needed to have specific control over when the model gets parsed so that the user experience is not disrupted.
The solution:
The solution was two part. I realized that underneath the Flare3DLoader there must be a URLLoader that was loading the model file and then parsing it. So I loaded one up and tried to pass it to the Flare3DLoader constructor. After some trial and error I found that by setting the URLLoader dataFormat to Binary, this worked.
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
loader.addEventListener(Event.COMPLETE, onLoadComplete); |
The second part was using ByteArray to make a copy of the loaded data so that the level could be loaded more than once. This was crucial to being able to click “replay” on the game.
var data:ByteArray = new ByteArray();
// This line copies the loader.data.
data.writeObject(loader.data);
// reset the byte array to be read.
data.position = 0;
// pass the copy of the data into flare 3D as a loader.
var model:Flare3DLoader = new Flare3DLoader(data.readObject());
// Add the loader to the scene.
scene.addChild(model);
// You may want to listen for when you model is parsed and ready.
// In that case just add:
model.addEventListener(Scene3D.COMPLETE_EVENT, onModelLoaded); |