I’ve been supplied a 2D sketch of what my 3D world (PaperVision3D) will look like. The hardest part was matching the perspective by carefully positioning the camera. Having no other way than trial and error and a total of 7 different parameters, I quickly went nuts. This is a time consuming task: changing the values, recompiling, testing.
I wrote a tiny utility that allows you to position/rotate/zoom the camera visually, saving hours and possibly days of tweaking.
How to code it
Easily. Pass the camera object to the constructor and add the whole thing to your display list:
var cameraControl:pv3dCameraControl = new pv3dCameraControl(_camera);
addChild(cameraControl);
How to use it
Click and drag the desired text field and your camera will move, updating text field’s value. Once satisfied with the result, write down the numbers!
Also position objects
A second, similar utility I wrote allows to position objects in the viewport.
var objectControl:pv3dObjectControl = new pv3dObjectControl(viewport);
addChild(objectControl);
Click on an object in the viewport, then drag the desired text field.
Have fun.
pv3dCameraControl.as
pv3dObjectControl.as
I had an interesting Flex bug to solve a day before the project deadline. I was showing a progress bar while some images were preloading in the background. The application was only allowed to fire applicationComplete event once these images have finished loading.
The client complained that the progress bar stalls the first time you run the app in the browser. Refreshing the page causes the application to start immediately, as if everything has been loaded. I reproduced the bug with bandwidth throttling. That made me think: “the assets are being fully loaded, but the progress bar doesn’t seem to care”.
With further investigation, I realized that I solved the same problem over a year ago. When one creates Loaders on the fly, such as in a loop, one often does not keep any reference to these Loaders outside of the scope of the function. Since it is a good habit to make event listeners weak, it is possible for the garbage collector to flag these Loaders for removal before they even have a chance to fire their complete event.
So to make sure that the progress bar does not stall, I needed to keep a reference to the Loader that I create within my loop. I simply pushed every Loader to an array. Once everything finished loading and the application started, I cleared the array to allow the garbage collector to take care of the rest.
Problem
Progress bar stalls while preloading images.
Cause
Loaders with weak event listeners and no references to them within the application.
Solution
Use an array to store references to the Loaders until all of them have finished loading.
I experiemented with PaperVision3D and JigLib last week. Since JigLib had a plugin specifically designed for PaperVision3D, making the two work together was a breeze. The only thing that really bothered me is the fact that when I applied a force on a body, it rolled instead of gliding smoothly along the surface. I’m used to 2D physics engines, so that was unexpected for me.
I found that the documentation for JigLib was pretty limited. There is only an API without any explanation as to what the methods do and a few tutorials. Oh yes, and my physics knowledge is limited, so many terms don’t mean much to me.
I spent sleepless nights in the source code, trying to figure out what everything does by myself (since nobody answered my e-mails). I stumbled upon a very nice class named “JConfig”. This was the jackpot. It had a nice property “limitAngVelocities”, which was set to 10. I set it to 0 and voilà! My objects glided nicely along the surface, colliding with each other, maintaining their initial rotation.
I hope that this will save some sleepless nights to others.
I had to read the source code for LinkBar and its parent NavBar to understand why my LinkBar wasn’t highlighting the clicked item. Turns out, it’s because I use an ArrayCollection as a dataProvider. According to the documentation and the source code, it is possible to use an IList (such as an ArrayCollection), a String (that refers to a ViewStack in the current document) or an actual ViewStack object. But, when a selection occurs, LinkBar makes sure that we supplied a ViewStack before allowing the highlight.
Why, I have no idea. All I know is that I want to use an ArrayCollection as my dataProvider and still highlight clicked elements. I extended the LinkBar component with a tiny workaround. Feel free to use it as you wish.
StacklessLinkBar – forgive me if you find the name unoriginal.
There are 2 main ways to add non-UIComponents to a Flex Container.
1. You may add the object to a SWFLoader, which does not require its children to extend UIComponent.
2. You may add the object to Container.rawChildren.
You have to be careful with the 2nd one. First of all, know that whatever is contained in Container.rawChildren is not sized, positioned or rendered automatically. You cannot, for example, put a button in there. Another thing is that anything added to Container.rawChildren is NOT contained in the Container.children, but the contrary is true. Relying on indices to remove from the display list might be tricky.Here’s what I mean:
- You add 5 objects using Container.addChild()
- You add 5 objects using Container.rawChildren.addChild()
- You want to remove the last child of Container.rawChildren, and will use index 9 instead of 4, because rawChildren returns all 10 children.
The reason for Container.rawChildren is to add skins, not actual content. Container.getChildren() returns only elements that were added using Container.addChild(), not elements that were added using Container.rawChildren.addChild().
So my suggestion to you would be to use rawChildren only if you do not intend to remove these children later, like skins. If you wish to add interactive elements and other content, create a SWFLoader and add them to it. And if you have a UIComponent, always add it to the Container using Container.addChild().
Recent comments