Posts Tagged ‘actionscript’

Tracking the mouse outside Flash

Over the next few days let’s take a look at mousetracking in actionscript. My task was to make a movieclip ‘point’ to the location of the mouse. The primary problem, as scripters will be aware is that as soon as the mouse tracks away from the bounds of the flash movie, the position of the mouse can no longer be tracked. One way to get around this is javascript, which can communicate the position of the mouse to Flash. Another is to use an invisible movieclip which overlays as much of the browser or screen as possible. In anycase, as soon as this issue is addressed there is a bit of maths involved to work out where the movieclip would point. I shall look at this tomorrow.

Tracking the mouse outside Flash part II

Today, let’s look at how to get a movieclip to point towards the mouse from a fixed location. This is a lot easier when tracking in one direction. For example, on my site, the TV is able to track the horizontal (x) coordinates of the mouse separate to the vertical (y) coordinates. All that happens is that one movieclip is nested in the other, both have a timeline, and the actionscript calculates a frame proportional to the position of the mouse for both movieclips respectively.

In a more recent project, it was an flv video that needed to track the mouse. Therefore, both x and y had to be tracked simultaneously. To achieve this it became necessary to establish the orientation, or angle of the mouse pointer in relation to the target. If we were to draw an imaginary triangle we can calculate the angle.

The three points to use are the mouse position, the target’s position and the point where the x value of the mouse hits the y value of the target, forming a right angle triangle. We can then establish the length of the adjacent and opposite sides of this triangle and use trigonometry to calculate the angle. In actionscript, inverse tan can be achieved with Math.atan(opposite/adjacent); After this, a little tinkering around is necessary. The result is in radians and needs to be converted to degrees.

Then the position on the timeline has to be worked out using a formula like this: Math.round((360/number of frames) * result). A final sprig of easing is the final touch for a very cool effect.

Creating scrollbars

Creating scrollbars is simple, right? Well, building one from scratch requires some head scratching and a feeling of deja vu. The best advise is to do it once and never again. However, in a recent project, the graphics for the scrollbar were quite unique and didn’t easily fit into any prebuilt component. The thumb track was a fixed size and the gutter was a little bit…well… bendy.

The key thing in a scrollbar is to work out the ratio that is needed to move the target movieclip (which typically would sit underneath a mask with the same bounds of the scrollbox). This needs to account for the size of the scrollbox. When the thumb track is at the top of the box, we want the position to be relative to the top of the movieclip. However, when the thumb track is at the bottom of the scrollbox, we want it to be relative to the foot of the movieclip. So some maths is involved which I will run through tomorrow.

Creating scrollbars part II

Well shame on me. Tomorrow never comes. So now it’s time to catch up on the maths for a scrollbar. There are probably many ways of doing this, but this is my favourite because it’s easy, and this example uses a scroll track that is of no significant height. i.e. just a blob or something. Three bits of information are needed. Firstly, the height of the overhang from the movieclip that is being scrolled. So:

overhangHeight = movieclip._height – scrollbar._height;

The next piece of information is how far the scrollbar has been dragged. This is a percentage of the height of the scrollbar.

percentScrolled = (100/scrollbar._height) * distanceScrolledSoFar;

The final piece of information depends on the previous two and tells us the distance the main movieclip has to move to match the position of the scrollbar. I called it offset.

offset = (overhangHeight / 100) * percentScrolled;

So now we have the number we need to move the main movieclip. mc._y = (0 – offset);

Very simple but useful to have it written down, lest I ever have to try and remind myself again.

Where does Flash go now?

The design / development gap is widening and it’s industry wide. Traditional modes of working in Flash are fast disappearing in favour of a much more technical approach. There are massive benefits to this, not least the ability to build ever more exciting projects. Everything from data manipulation, user interaction, complex visuals and code management benefit from this way of working. However, let’s not forget the original appeal of Flash. When I first played around with Flash, my concept of it was Photoshop with interactions. It was a design tool. The freedom to start designing, and then code and design as I went was fun. What a great combination. It bridged a divide between the realms of creativity and technology, and anyone who wants to learn how to make really exciting user experiences without getting bogged down in theory can learn a lot from it. These days, however, there is less and less room for this type of working. Flash projects these days tend to require a great deal of traditional programming methodology to avoid becoming cumbersome and unprofitable. This makes a lot of sense, but something still niggles.

Why aren’t AS3, Flex and the other advances in Flash not intuitive to designers? Flash used to make this complex stuff easier for visual people, so why are increasingly technical minds required to understand it? What we need is some bright ideas for new ways of working. We want all the advances the technology offers, but we need to be fast enough to think of great concepts for working that maintains that spirit of creativity which Flash offers.


Continuing on from my last post, it seems Adobe are already on the case after my colleague pointed me towards Thermo. Previously I pointed out that Adobe’s latest offerings were leaving designers out in the dark. Perhaps this new project will buck the trend.

Asking a computer to make a value judgment

The value judgment in question is what is the best way to layout a series of similarly sized elements on the screen to get it, in that hazy sense, to look ‘right’?

ie. distributing items on the screen dynamically.

Scenario: I have a random number of items, maybe being pulled in from xml, and I want to place movieclips on the screen in a grid which are placed evenly in columns. Thing is, how many rows and how many columns do I need? Especially as the height and width of my movieclip may not be square.

To distribute mcs of lampposts you’re likely to have more mcs running horizontally than vertically – as opposed to distributing mcs of snakes, which you are more likely to want to stack vertically.

Well the most effective way of doing this I could muster was to get the square root of the total number of items and then multiply that by a suitable aspect ratio.

For example. Let’s say I want to distribute to a square stage 500 x 500.

I have 36 items. So, I get the square root which is 6.

var array = [0,1,2 … , 35];
var sqrt = Math.sqrt(array.length);

Next I’ll add these together to get a total 12.
var total = (sqrt + sqrt);

Now I want to multiply this by an aspect ratio to work out the distribution. If the mcs are twice as wide as they are high, the aspect ratio is 2 and an ideal distribution would be 4 columns and 8 rows. 4×2 = 8 and 8×1 = 8… width and height match.

So my total, 12 needs to be somehow split into 4 and 8.

My approach is to divide 12 by height and length ratios, i.e. 1(h) + 2(w) = 3.
var ratiodiff = (total/(ratio+1));

Then multiply the result (4) by the ratio 2, so 4 * 2 = 8.
var ratiodiff = (total/(ratio+1)) * ratio;

Now I can use this for my number of rows, and the remainder for the number of columns.
var cols = total – ratiodiff;
var rows = total – cols;

Now, instead of 32, if i was using scraggly odd numbers like 73 or 113, I can apply the same maths to get an approximation. For 73, the result for the number of columns is 5.7 which is no use… we need a whole number.

Therefore I’ll use the ceiling of the number, 6. Then I’m assured of having enough space for all the movieclips .. although there’ll be some gaps at the bottom. I’ll be treating my columns like buckets.

var cols = Math.ceil(total – ratiodiff);

Since cols is now an approximation I need to calculate the rows differently to make sure I’ve got all the items from the original array.

var rows = Math.ceil(array/cols);

Wow. That was intense. I’m sure there are other approaches to this problem, and many of them maybe better than this, but this works and it’ll suit me for now.

Game development

Recent projects have highlighted some of the most challenging and interesting issues in Flash development I’ve had to solve. For gaming, one key aspect is speed and memory management. Developers who are used to movieclips and tweening, which normally lend themselves so well to animation, soon discover how unwieldy these can become in a realtime game, like Meowcenaries.

In that game, not only are there over a dozen separate animated game objects moving around on screen at any time, but the speed of their movement is important. Add to this the fact that several of the levels are huge, which means lots of information stored at runtime, and the slowdown becomes apparent very quickly.

For Meowcenaries the solutions were varied, but key to maintaining the speed was ‘flattening’ the nested movieclip structure, and using the BitmapData class to copy flat images onto the screen. The advantage is that all the memory that would usually be reserved to store all those movieclips is released.

We also discovered that tweening, especially transformations, such as colour or transparency caused significant slowdown. This was due to the additional maths required for Flash to calculate the overall required colour for any given pixel where semi-tranparent colours are overlayed. We found the best way to keep the cool animations without the memory overhead was to pre-render them or ‘trick’ the eye. For instance, some animations are not tweened, they consist instead of a staggered set of keyframes representing the different states of the tween.

Also, the game was built in AS3 which introduces the issue of memory leaks – a problem that Flash developers, including me, did not really have to worry about in AS2. It soon became apparent that memory leaks could crop up in the unlikeliest places making debugging a serious issue.

After much hair-pulling a solution was found to speed up debugging. This was to use Flash CS4 to create a movie loading environment. Using the System.totalMemory property we could monitor the memory usage at any given time. A button could be pressed to load and unload the flash movie being tested. When the movie was unloaded System.gc() was called, which is only available in CS4. The advantage of this technique is that after a number of times hammering this button, it would become apparent if something was stuck in memory. Testing different modules of code made it much quicker to pinpoint where the problem was.

In summary, game development brings up many new challenges, some which seem to take you deeper and deeper into the rabbit hole. Luckily, the end result is very rewarding – improving gameplay is a very satisfying job.

└ Tags: , ,