Monday, 28 December 2009

How to Become an Animator - Free e-Book


I won't pretend it's not a marketing campaign from AnimationMentor.com, because that is exactly what it is. But if animation is what you like, and you think animation is where you want to end up, then you just may find this valuable.

It's taking about 40 minutes to download so no review of content at present. But at a price of FREE, I'm not complaining.

You can download it here: http://www.animationmentor.com/landing/becomeanimator/ebook.html

Meanwhile, I will add my review later when I have had a chance to read from it

Wednesday, 9 December 2009

Custom Snow Effect in Flash

Whether or not we get a white Christmas outside, I can make sure I get one in my Flash work any time I like.

Components add to the functionality of Flash, basically making more complex actionscripts available to those of us who lack the time or the knowledge to program them ourselves. The Adobe Exchange is a great place to find components for Flash from MX right through to CS4, some free, some you have to buy.

Free Snow Effect Component

The component I want to tell you about is the free Snow Flash Effect component from FlashWanted by Corso Ria.

Download it here (you will need to get a free Adobe Exchange account):

http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1278523

Once downloaded just double click the MXP file and it will automatically install into the Flash components panel.

This particular component works with Flash versions MX 2004, MX 2004 Pro, 8 and CS3 (and maybe CS4 but I haven't tested it), so if you don't have access to the latest version of Flash, this should still work for you. In fact i'll be using MX 2004 to show you how it works since I don't have CS3 on this machine and I can't be bothered to pull the laptop out - it's really easy.

Basic Snow

To kick off you need to open the Components panel, and then open the FlashWanted group. In there you will find a component called "sneg".

Drag "sneg" to the stage and scale it to cover the area you want to be snowy.

Then, with the instance of the "sneg" component you dragged onto the stage selected, you need to open the Component Inspector.

Most of the fields in the Component Inspector are pretty self explanatory, and a bit of experimenting with the settings will give you the effect you want. You can even make the background transparent by changing the alpha setting, allowing you to overlay the snow over other layers.

And that's it.

CTRL+ENTER to test the movie and the snow begins to fall.

Customising the Snow

By default the snow is made up of very small white dots, but you can use your own flake design by using a symbol from your library.

To do this you need to first make a MovieClip to use as a snowflake, and then set it to export for actionscript. Do this by right clicking the symbol in the Library, and choosing the Linkage option.

Then set the identifier, what you type here is what you will also type in the Library Symbol field in the Component Inspector. I used 'flake_mc' as the identifier in mine.

Feel free to test away.

Further Customisation

If you are like me you will always be curious about how far you can push the technology beyond its original or obvious intention. I have seen other snow effect components in use that had more than one type of snowflake and allowed the snowflakes to tumble, or turn, as they fell.

It seemed pretty logical that, if I am specifying a MovieClip as a snowflake, any actionscript within that MovieClip that refers to the clip itself, ought to work. And, I was right.

In the previous step we looked at how the component allowed us to specify a particular MovieClip to use as a snowflake, rather than its own default 'dot'. What this means is that we can actionscript our snowflake MovieClip to apply certain attributes to itself, and this actionscript will work independently for each flake the component places on our stage.

In other words we can make 'intelligent' snowflakes to make up for where the component lacks. While the component takes care of the snow falling, each flake takes care of its own turn speed and appearance etc.

Here's how.

Random Flake Appearance

I am going to cheat a little here, this script will not actually generate random flakes, but what it will do is randomly choose a snowflake design from a selection that you will make.

What I did was make 5 different snowflakes and place each one on a different keyframe within a MovieClip called 'snowflake_mc'. Don't forget to put a stop(); action on each of these keyframes or your flakes will keep cycling through the 5 designs as they fall (which doesn't happen in real life). It's also a good idea to make sure each snowflake on each frame is positioned over the 'centre point' in the middle of the MovieClip symbol.

So what I end up with is a MovieClip called 'snowflake_mc' containing 5 frames, each frame containing a different snowflake design and a stop(); action.

The next stage is to open the symbol we specified in the Component earlier - flake_mc. Inside flake_mc you need to swap the snowflake design with the MovieClip you just made containing 5 flakes. Give this the instance name of 'snowflake_mc'. So what we end up with is a symbol called 'flake_mc' that is set to export for actionscript that contains another symbol called 'snowflake_mc' that contains our 5 flake designs.

Now for the actionscript. This goes on the first frame of 'flake_mc':


/*randomly select which flake design to use */
var flakedes = Math.ceil(Math.random()*5);
/*set flake design to the one selected */
snowflake_mc.gotoAndStop(flakedes);

First we create a variable called 'flakedes' that is a randomly generated number between 1 and 5. we do this because we have 5 flake designs. This then acts as a random flake selector. We generate the number using Math.random, but this only gives us a number between 0 and 1. To turn this into a number between 1 and 5 I multiply it by 5 and then round it up using Math.ceil. (If I rounded down I would get a number between 0 and 4, rounding up guarantees between 1 and 5).

Then we tell the 'snowflake_mc' MovieClip (the one with 5 frames) to gotoAndStop at the frame number we just randomly generated. This then randomly displays on of our 5 flake designs.

Voila! As the component places a new flake on the stage the appearance of the flake is now randomly one of the 5 designs you made.

Flake Tumbling

This requires trickier actionscript (but still easy), but no extra graphics. A pure code solution to flake tumbling. This goes on the first frame of 'flake_mc' beliw the code we already have:

/*Generate a random small number of equal chang of being positive or negative. Positive equates to clockwise rotation, negative anti-clockwise */
var rotfactor = ((Math.random()*4)-2);
/* This function tells the snowflake_mc movieclip within the flake_mc clip to rotate by the rotfactor. */
function snowflakeroll () {
snowflake_mc._rotation += rotfactor;
}
/* this runs the above function every 40 milliseconds. */
setInterval(snowflakeroll, 40);

I wanted the flakes to tumble very slowly, all at different speeds of slowness, and in either direction. So the first part generates a small number, between -2 and 2. A negative number will equate to anti-clockwise tumbling, a positive number clockwise tumbling. We generate this number again using Math.random but this time we multiply the number by 4, to give us a random number between 0 and 4, but then we -2 from that number giving us a random number between -2 and 2.

We use this number as the variable 'rotfactor'.

What we then want to do is use the value of 'rotfactor' as the amount the snowflake will rotate each frame.

However within the MovieClip inside the component onEnterFrame doesn't work. So instead we approximate frames by using setInterval.

setInterval works by calling a function repeatedly, with an interval between each call. If we set the interval small enough it will be as good as calling each frame.

First then we have to write the function, then use setInterval to call the function.

Our function is very simple:

function snowflakeroll () {
snowflake_mc._rotation += rotfactor;
}

First we define the function and give it a name 'snowflakeroll', then we give the function its instructions which in this case is to tell the 'snowflake_mc' MovieClip to change its rotation value by 'rotfactor'. By using += rather than just = we add rotfactor to itself each time the function is called so it gets larger each time thereby increasing its angle of rotation with each call of the function.

Then we just need to call the function using setInterval:


setInterval(snowflakeroll, 40);


We call the function by name, and then we define the interval in milliseconds. In this case 40 milliseconds calls the function frequently enough to creat a smooth rotation animation.

And that's it

And that's it. You're done. You have now got a basic component that simply chucks snow out, to give you random flakes with random tumbling speeds both clockwise and anti-clockwise.

Given all that we have done, I think it safe to assume they don't have to be snowflakes. What other MovieClips could it chuck out, and how could these be scripted? Over to you.

Happy Christmas.

Wednesday, 18 November 2009

So... do ColorCode (Amber+Blue) 3D glasses work with LCD Projectors?

I said I would test it out, and the verdict is... yes.

At least, it did with the Dell projector I tried it on. While I initially found that there was more ghosting on the projector image when viewed through ColorCode (Amber+Blue) glasses, than my LCD monitor, at least it was 3D.

I have not yet had success with Cyan+Red at all on a projector.

Changing "Video Mode" improves image

The Dell projector I used allowed me to change the "video mode", which is basically a bunch of different colour level presets. I found that in "game mode" the ghosting pretty much vanished even on the projector.

So there you have it.

ColorCode (Amber+Blue) can work with a projector.

Tuesday, 10 November 2009

Channel-4 3D Week

I was at Sainsbury's today (unusual, but I happened to be near one) and came across a big point-of-sale bin thing with loads of FREE 3D glasses in it. Apparently Channel-4 is hosting a 3D week, which according to my 3D glasses arm will feature "never-seen-before archive footage and continue[s] through the week with loads of awesome 3D films and concerts to enjoy".

Anaglyph TV

Now, the image below (from the C4 website) doesn't look like anything special to the naked eye, but when viewed through the special Sainsbury's glasses will take on a 3D appearance. It is an anaglyph.


To view anaglyphs you need special "3D glasses" that have coloured filters. But there are several different colour combinations around, and you have to make sure you get the right one for what you are watching. You can get Red Blue, Red Cyan (the most popular), Red Green and, as I learned today, Blue Ochre (sometimes called Blue Amber, or Blue Brown).

And guess which ones Channel-4 have opted for?

Blue Ochre of course - which means you probably don't have an old pair of 3D glasses hanging round the house which will work for 3D week. Your "Journey to the Centre of the Earth" glasses will not work, and neither will your "Shark Boy and Lava Girl" pair.

Better get yourself down to Sainsbury's and get some Blue Ochre.

But what's with all the different types?

Why not just stick to one type and have done with it? Simply put, different colour combinations have different benefits. Red Cyan is probably the most popular because it allows the creation of both colour and B&W anaglyphs (as does Red Green). Red Blue only allows B&W and the images are very dark.

But more information on the different types can be found here:
http://nzphoto.tripod.com/sterea/anaglyphs.htm

However, and this was news to me until today, Blue Ochre when viewed in a dark room, has better colour transmission than the others. So this is probably why Channel-4 opted for it. After all, if you want people to think that 3D is more than just a gimmick, it needs to look good.

Blue Ochre not free but very clever

While all the other anaglyph colour methods are pretty much public domain, the Blue Ochre combination is apparently patented. Not the idea of the anaglyph - that has been around for too long, you can't patent that - but according to this website it is the method for converting an image for Blue Ochre is patented:

What makes it patentable (the "secret sauce") is the mathematical formula that modifies the luminance of the right eye record and the luminance and chrominance of the left eye record to best transmit the colour information. The darker brown is necessary for balance, because blue is low luminance.

Whilst I haven't read the patent (http://www.patentstorm.us/patents/6687003/fulltext.html) thoroughly, their process doesn't seem to attempt to determine which point in each image represents each point in the three dimensional scene, so it seems to me that they are effectively presenting a luminance-based stereoscopic pair combined with a flat chrominance image based on the average of the two views.

(http://www.dvinfo.net/forum/archive/index.php/t-128661.html)

Apparently this method was invented at the Technical University of Denmark, and has been branded as ColorCode. More information can be found here: http://www.colorcode3d.com/.

What makes it so clever, and therefore worth paying for perhaps, is explained on their website:

The ColorCode 3-D system is the only in the world to reproduce high quality 3-D Stereo images and movies with full color- and depth information on all display types.

(http://www.colorcode3d.dk/group.asp?group=39)

And I can't argue with this claim. I know from experience that Red Cyan may work on a CRT or TFT monitor, but utterly fail on a projector. You can also get a fair amount of ghosting. If ColorCode (Blue Ochre) can crack this, it will be worth the license fees for TV companies who want good quality 3D without a trace of gimmick.

I will test my new Sainsbury's ColorCode glasses on the LCD projector at work, and if the result is good I will be very impressed and let you know.

Monday, 9 November 2009

Flash Projects #7 - Making a Flash MP3 Player

Finally here is the solution. It turns out you can use NetConnect and NetStream to make an MP3 player in Flash, but only if you encapsulate all your MP3s as FLV files. Not really very helpful since it means converting your MP3 files - it just makes more work.

And busy designers really don't want the job to take longer.

However there is another way to make an MP3 player in Flash, that still gives us all the control we need, but the pausing and playing is just a tad more complicated. But nothing you can't handle I am sure.

The Code

First, here's the code, then I will explain it:


//set default starting position for playback in seconds
var playpoint = 0;
//create sound object
var audio_sound:Sound = new Sound();
//play button
this.play_btn.onPress = function() {
//play the mp3 from the point defined in the variable playpoint
audio_sound.start(playpoint);
};
//pause button
this.stop_btn.onPress = function() {
//define the variable playpoint as the same as the current position, this is given in milliseconds so we divide it by 1000 to convert it into seconds
playpoint = (audio_sound.position/1000);
//stop the playback
audio_sound.stop();
};
this.m1_btn.onPress = function() {
audio_sound.loadSound("track1.mp3", false);
//true = streaming and therefore autoplay, false = not streaming and therefore just sets the file for when you hit the play button.
};
this.m2_btn.onPress = function() {
audio_sound.loadSound("track2.mp3", false);
};


The Explanation

Here goes. First, instead of using NetConnect and NetStream as we did for the video player, we are going to use loadSound. This still gives us a fair amount of control, in some ways more than the NetStream would give us, but it doesn't automatically pause when you play something that is already playing, as NetStream does. So while the rest is no more difficult, just different, pausing and then playing again is slightly more complicated using loadSound.

As with any program, we can only work with the information available, or that we can find out. With the loadSound approach we can find out one very important thing that will help us make a pause/play mechanism - we can find out our current position in the MP3 as it plays. In the code above we do this as follows:


audio_sound.position


Not hard, but on its own it is not a pause/play mechanism. We make it into a pause/play by storing the current position as a variable called playpoint at the time of pause. In effect we remember where we got up to. Then, when we play, we tell it to play from where we left off by asking the variable playpoint to tell us where we got to. As follows:

When pausing:


this.stop_btn.onPress = function() {
playpoint = (audio_sound.position/1000);
audio_sound.stop();
};


First we set the variable playpoint to store our current position. This is actually given in milliseconds so we divide it by 1000 to convert it to seconds - and that's what you see being done here. Then we tell it to stop.

When resuming playing:


this.play_btn.onPress = function() {
//play the mp3 from the point defined in the variable playpoint
audio_sound.start(playpoint);
};

We simply tell it to start, but include the start position as playpoint so it resumes from where we left off.

Isn't that what pausing/playing really is? Stopping, and then starting from where you left off?

The other code is effectively a menu, allowing you to choose which track to listen to. The term false on the end means the track won't play straight away, but will wait for you to press play as well. Change the false into a true and just clicking on the menu will make the track start as well.

Have fun.

Monday, 28 September 2009

eLearning Business Game (Arrays in action)

My last post was all about my array sorting problem. But I thought you might want to see the final product.

It was actually a game I put together to help my new students relax and get to know each other, but then I tweaked it and made it available for anyone to download.

Available here: http://digitalarena.co.uk/teach/markettraders/

The array was used in the part of the game that displays the team's performance as a graph. I needed to find a way to make the graph always fit in the available space. That meant finding the highest score and then working out a scale ratio that I could apply as the graph drew, so it always fit in the graph space.

So what has this to do with arrays? Well... finding out the absolute highest score of each team's highest score meant storing them all in an array and then sorting them (lowest to highest). Then I just had to retrieve the last item in the array to get the highest.

Friday, 25 September 2009

Sorting Numeric Arrays with Actionscript

Just lately I have been having fun with arrays. Of course, I say "having fun", what I mean is having problems. Especially with sorting numerically.

Arrays are really useful, they allow you to store data, select data, order it, etc. You can create them from strings and other variables, and turn them into strings and other variables. All in all, they can be very handy.

I found them handy as part of a game I was writing a couple of days ago. As part of my code I needed to find the number with the highest value out of a choice of 3 numbers. The logical solution was to put all 3 numbers into an array, then sort them numerically, then retrieve the last item in the array (this should, after sorting, be the one with the highest value).

Numeric sorting is not numeric

Let's say we start with the following array:

var my_array:Array = [650,12,86];

Then we sort them numerically:

my_array.sort(Array.NUMERIC); //doesn't work correctly

After this command you might expect flash to order the array as:

12, 86, 650

But what you actually get is:

12, 650, 86

This is because, as the Flash documentation explains, 'Numeric fields are sorted as if they were strings, so 100 precedes 99, because “1” is a lower string value than “9”. '

In other words, the Numeric sort does not sort numerically at all. It sorts alphabetically. Odd sort of numeric, but it can't be helped, we have to find a solution.

Prepending 0s so all values have the same number of digits

Of course this only happens because not all the values had the same number of digits. If the lower values began with a 0 then a numeric (alphabetical) sort would work correctly. So my initial plan was to use an if statement in a for loop to check for 1 digit, 2 digit and 3 digit numbers and prepend (put in front) 0s to make them all the same number of digits as follows:


for (var i = 0; i<finalscores_array.length; i++) {

if (finalscores_array[i]<=9) {

finalscores_array[i] = "000"+finalscores_array[i];

} else if (finalscores_array[i]<=99) {

finalscores_array[i] = "00"+finalscores_array[i];

} else if (finalscores_array[i]<=999) {

finalscores_array[i] = "0"+finalscores_array[i];

} else {

finalscores_array[i] = finalscores_array[i];

}

}


With for loops we can repeat a peice of code until a condition is met. This loop repeats for the length of the array (that's the number of items in the array). It starts by checking how many digits the first array item has. Then depending on how many digits the code prepends 3, 2, 1 or no 0s. On the next repetition it checks the next array item, and so on until all array items have been checked and had the required number of 0s prepended so that they all have the same number of digits, and then the loop ends.

The result is that the original values:

650, 12, 86

become

0650, 0012, 0086.

Now when we sort them numerically, it does put them in the right order:

0012, 0086, 0650.

Leading 0s alter the value (it's a decimal v. octal thing)

Wouldn't it be great if that was the end of your troubles?

The problem is that if we then want to do anything with the values afterwards, like doing anything other than displaying them, we need to remove the 0s we just added. And it is not nearly as easy taking off, as putting on.

The reason we have to remove the leading 0s is because Flash, like lots of other programs, does not treat numbers beginning with 0 as decimal numbers. It treats them as octal. This means that 0650 does not have the same value as plain old 650 (without the leading 0).

0650, as octal, actually has the decimal value of 424.

0650 is in fact a totally different number to 650.

So while prepending leading 0s solves our array sorting problem, it actually changes our values. just because a leading 0 in Flash means it is an octal value, not a decimal value.

Leading 0.0 do not alter the value (it's a less than 1 thing)

But then I realised. Hang on a minute says I (yes, programming problems really can have you doing a good Ben Gunn impression). Hang on a minute says I, Flash handles numbers begining with a 0 all the time. What about 0.1, 0.2 etc. It has no problems with decimal values of less than 1.

And here is my solution. Instead of using my for loop to prepend just 0s, I will use it to prepend 0.0s, as follows:


for (var i = 0; i<finalscores_array.length; i++) {

if (finalscores_array[i]<=9) {

finalscores_array[i] = "0.000"+finalscores_array[i];

} else if (finalscores_array[i]<=99) {

finalscores_array[i] = "0.00"+finalscores_array[i];

} else if (finalscores_array[i]<=999) {

finalscores_array[i] = "0.0"+finalscores_array[i];

} else {

finalscores_array[i] = "0."+finalscores_array[i];

}

}


The result is that the original values:

650, 12, 86

become

0.0650, 0.0012, 0.0086.

Now when we sort them numerically:

my_array.sort(Array.NUMERIC);

It does put them in the right order:

0.0012, 0.0086, 0.0650.

OK, I know that doing this has changed the values too, but at least they are still decimals (not a totally different numbering base). Because they are still decimals it is easily rectified, it's just a case of shifting the decimal point a few places. And we can do this by very simple multiplication...

...just multiply them by 10,000.

0.0012 x 10000 = 12
0.0086 x 10000 = 86
0.0650 x 10000 = 650

So, to finish off, now we have prepended 0.0s to our original values, then sorted them, all I need to do to get the highest value is retrieve the last item from the array, and multiply it by 10000.

var highestscore:Number = (my_array[my_array.length-1])*10000;

The Faster Way

Having made this wonderful discovery, it is good to know that all the code required to debug and investigate the problem is not necessarily needed to apply the solution. Pre-pending using the IF and ELSE IF is only necessary if you want to pre-pend digits to a String (as in converting 650 to 0650). Now that we have discovered that only decimals (as in 0.650) will sort correctly there is a much simpler way to achieve this.

Simply - divide the original number by 10000 (after all, we convert them back by multiplying them by 10000).

for (var i = 0; i<finalscores_array.length; i++) {

finalscores_array[i] = finalscores_array[i] / 10000;
}

I count that as 7 lines fewer code, than the pre-pending method.

That's the difference between what we do to understand a problem and what we do to apply a solution.

And there we have it. Hopefully some of you will find this helpful. Frankly I don't know why numeric sorting doesn't just work. But since it doesn't, here is a cheap and cheerful workaround - in summary:

1. Divide them all by 10000 (so that every number begins "0.")
2. Sort them
3. Multiply them all by 10000 (so you get the original values back)

Happy sorting.

Wednesday, 16 September 2009

Design industry calls for "More Rounded" design graduates

This is always one issue that concerns me about my students. You get the creative ones who hate computers, then you get the computer geeks who think knowing the software will somehow make up for their lack of creativity.

They are both wrong. Where interactive media is concerned anyway.

Design Week reports that the D&AD Xchange conference for tutors once again highlighted the "mismatch between the kind of graduates design colleges are providing and what consultancy creative heads require".

And what do design consultancies require in new graduates? In their own words "More rounded" graduates. By this they mean more creatively rounded - more understanding of creativity, more understanding of design. Rather than a 2 or 3 year higher education in design some have even suggested a 3 year foundation course in design (allowing design students to experience a wide variety of creative disciplines while developing their creativity) followed by only one year of specialisation.

For some of my students that would mean not getting into the web design and interactive media technology for another 3 years - and meanwhile, they learn to be creative designers in many different media.

Oddly perhaps for art & design (though not so odd perhaps for a wanabee web designer) many of my students seem to resist the creative development required to be an effective designer. Many are focused so much on learning the technology, they are in danger of being technically good, but creatively stunted - able to use technology, but not to solve design problems.

As Neville Brody puts it: "We imagine to be able to do anything, and our software helps us believe we can... But we must move beyond the 'how' to reconsider the 'what' and the 'why'."

This is my greatest fear for some of my design students. They are most interested in learning how to do something, but ignore the important business of learning how to decide what they should produce and why.

Those who persist in making this mistake may well regret it. Leaders from the industry have spoken, they want creative people, not just technitians.

If they resist the creative development aspect of their education, they may get what they want in the short term, but in the process fail to become what their employer wants.

Saturday, 5 September 2009

FREE eBook - The Principles of Successful Freelancing


Whether you are a Freelance, Student or work within a studio, you will probably find Sitepoint's latest offer an interesting if not valuable read.

It's a 200 page eBook on The Principles of Successful Freelancing.

It normally costs about $30 but Sitepoint are giving it away FREE for the next 8 days.

To get the book you must either follow them on Twitter or submit your email address to their mailing list.

Sitepoint often give away selected chapters from their books as tasters, but this is the first time I have seen them give away an entire book. Clearly a good strategy for increasing their Twitter following (currently 49,662) and mailing list sign-up - we could all learn a trick there.




Monday, 31 August 2009

Help for BlueOnyx Server Maintenance

My last post looked at setting up a testing server for web designers. One of the options included building your own server running BlueOnyx for easy set-up and easy server management.

The thing that makes server management so easy is the web based interface. Originally the interface was only available for Sun Cobalt hardware, but once Cobalt was discontinued Sun Microsystems released the source code as open source. Since then others have developed it to work with any hardware (great news for us) and is most currently available as BlueOnyx.

PDF Manual

Because the BlueOnyx server management interface is based heavily on the sourceode for the Cobalt RaQ 550 the old RaQ 550 manual still contains some useful instruction on managing the system, and you can download it in PDF format here:


Comparisons

The great thing about the BlueOnyx (and Cobalt RaQ) is how easy the server management interface made server management for non-techies.

Server managment after all was traditionally done through a shell interface (not unlike the windows command prompt). Setting up a web site involved manually creating users and folders, manually setting permissions and quotas, and manually editing several config files without making mistakes.

What the BlueOnyx interface does (and what the Cobalt RaQ interface did) is turn this process into an interface. You simply fill in the blanks and press "go" and scripts automatically create the folders and permissions and update the config files. Happiness.

There are other web based server management systems such as Plesk or Webmin.

Plesk is perhaps the easiest (it really is aimed at hosting companies, providing an interface for customers), but it costs money.

Webmin, is secure and powerful and popular with techies, but IMHO much more difficult to use than BlueOnyx because you still have to do many things manually. You still need to create the folders, set the permissions etc... albeit through a browser rather than a command prompt. And that requires a fair amount of technical knowledge.

BlueOnyx arranges things differently. It assumes you have limited technical know-how, but that you do know what you want at the end, and arranges the interface into tasks rather than tools. So much easier.

Setting Up Your Own Testing Server

Call it what you like, a "testbed", a "testing server", a "sandbox server", it all amounts to the same thing - a server for testing your sites, scripts, databases before you "go live".

When it comes to web design I prefer to use Dreamweaver (in conjunction with Flash, Fireworks and occasionally Photoshop). And when it comes to static websites that's all fine, you can test them in Dreamweaver by hitting F12 and getting a preview in your browser. But for more advanced sites this will not do...

3 good reasons why you need a testing server

Going beyond static sites, to sites that include server-side scripts (such as PHP or Perl (CGI)) or database connections such as discussion forums, content management systems or shopping carts, it is really useful having a place to test before you "go live". Having your own server allows you to regularly test as you develop without long upload times, and without your client getting glimpses of half finished work.

It's also great for designers wanting to learn or improve their dynamic web skills. So you want to learn some PHP? So you want to learn how to get Flash to talk to a database? So you want to practice setting up and customising a content management system or shopping cart? You're going to need a server - it's a handy place to practice without needing to buy webspace.

Finally, if you want to use Dreamweaver's testing server facility when you set up your site in the "manage sites" window... you need a testing server.

Admittedly, if you have a website of your own you could use your own website host for testing and practice by shoving it in a folder separate from the rest of your site. But this is far from ideal, since your testing site will be running from a folder below the web root, when you intend to run it from the web root when you "go live". Much better is to test it as it will run when live.

Relax

I confess that if I had not learned what I now know, the whole idea of setting up a server would be enough to send me back to bed for another couple of hours. It sounds complex, but some very clever and generous people have made it much easier than it used to be - read on.

Before we go any further - LAMP or WAMP?

Before we go further let me introduce the server platforms I will be discussing today - LAMP and WAMP.

L - Linux
A - Apache
M - MySQL
P - PHP

or

W - Windows
A - Apache
M - MySQL
P - PHP

You will already be aware that Linux and Windows are operating systems, and really that is the only major distinction between the platforms above.

Apache is FREE open source web server software.

MySQL is FREE open source database server software.

PHP is a FREE open source server-side scripting language/engine.

Loads of websites run on LAMP or WAMP. Loads of web hosting companies use LAMP or WAMP to host websites commercially. In fact, last time I checked, Apache was the most installed web server in the world.

Loads of free web software runs on LAMP or WAMP too:

PhpBB
Zen Cart
Joomla
Drupal
Moodle
To name but a few...

All free and all running on free server software. At some point I guarantee you will want to install at least one of these for a client or for your own use, you need some practice, you will need to test it as you "skin" or "theme" it, you need a testing server running Apache, MySQL and PHP.

(Although I am not going to explain commercial alternatives in this post, you should be aware that you don't have to use FREE open source server software, a popular proprietary alternative would be Microsoft's Internet Information Server (IIS), MSSQL a database server and ASP or ASP.NET for server-side scripting. The drawback is that this all requires a commercial license. the other drawback it that I won't be explaining these today.)

A couple of approaches

There are probably many approaches you can take, but I am going to discuss what are to me 2 of the easiest options:

1. Install a server on your development computer
2. Set-up a server using an old computer

Let's start with the first...

Install a server on your development computer - WAMP

This is my least favourite of the two options, but if you want something quick, and you don't have an old computer kicking around it's a good alternative. I use a Windows XP machine for web design and development, so this solution is effectively a WAMP solution.

The easiest way is to get a pre-configured bundle of Apache, MySQL and PHP and install it as an application onto your Windows machine. There are several free options, but I recommend:


or


Setting-up

Download the installer, run it, and voila, you are done.

The installer sets up all the server software you need, and creates a web root folder. To test your site all you need to do is copy the files into the web root folder and start browsing. Your new installation of Apache, MySQL and PHP will process files in or below the web root folder as though they were on a web server (in fact they are on a web server at this point).

Couldn't be simpler.

Although I have used this type of approach many moons ago with Apache Triad, and while it is quick and easy, I recently built a server on a totally separate computer, rather than installing it on my development machine, and I prefer it - I guess I just don't like to clutter my graphics workstation up with too much other software (it's sucking my resources dry man, I can feel it) - just a little harmless paranoia. Which brings me to...

Set-up a server using an old computer - LAMP - the "real deal"

I did this just last week as the culmination of sporadic research over several months. You might think that setting up your own server hardware and software is the stuff of IT technitians and not the realm of designers, and depending on the type of designer you are, or your background you may still want to leave it to your techie friend. But I managed it so I urge you to read on.

And of course the great thing about this approach is that you are not making a simulation of a web server, you will end up with an actual web server in every sense. Stick it in a datacentre and you really could use it to host yours and your clients websites and email (if you wanted), this is the "real deal".

And being the "real deal" it has several advantages:

1. More than one person can use it as a testing server simultaneously - which makes it ideal for web design studios with several designers, and ideal for schools/colleges/universities/education allowing more than one student to upload and test their projects.

2. Each user can have their own login and testing server space. In fact each project can have it's own server space and login.

3. FTP, HTTP, HTTPS, PHP and MySQL all work the way they should.

As a testing server it is ideal because it is a real server.

There are loads of LAMP options out there, but being designers, not technitians we want one that is:

1. Easy to set-up
2. Easy to operate once set-up
3. Free - we're on a budget

Which, after my research and experience, leaves me with one option that ticks all boxes:


It is described as a turnkey solution (meaning it is as easy as turning a key to get up and running) and it really is straightforward.

Setting-up

1. Is your network suitable?

Before we go any further you need to check that you are the right kind of network to have a server. Answer the following questions with a "YES" and you can go ahead:

Do you have a network hub or router with a spare LAN socket?
Do your other computers connect to the hub or router using ethernet cable or wireless?
Does the router connect to your broadband connection?

If you answered "YES" to all 3 questions, then you can go ahead. Hoorah.

2. Get your machine

First you need an old computer that works, but which you no longer need. the computer should have at least the following:

Processor (CPU): Reasonable speed
RAM: At least 256Mb
HDD (at least 40Gb)
Graphics Card: (spec irrelevant)
Network Card: 10/100 Mbps
Other Drives: Floppy, CD ROM

The higher the spec the better, but don't worry too much, I am running a working testing server with BlueOnyx on the following very low spec machine:

Processor: PII 266MHz
RAM: 256Mb
HDD: 80Gb
Graphics: 8Mb
Network Card: 10/100 Mbps
Other Drives: Floppy, CD ROM
Sound: None

And it all works like a dream. The fact is that my testing server doesn't have to put up with much load. It won't be experiencing thousands of visitors, only me, and in most situations a testing server probably won't have more simulaneous users than the number of designers using it. Obviously, the more users the the better your computer needs to be but the main areas of concern are:

HDD - Improve this to hold more files

RAM and Processor - Improve these to handle more simultaneous visitors

Web servers DO NOT need a good graphics card, they spend most of their time without a monitor plugged in because they are managed over the web via a web browser or shell client. Nor do they need a sound card.

3. Check you don't need it

Make sure you really don't need the machine for anything else.

Make sure you don't need any of the information on the Hard Drive. What we do next will wipe it completely. You will lose all data, software, downloads, accounts information, everything.

If you are using an old windows machine with an OEM Windows XP sticker on it, you need to know that we will be wiping Windows off the machine, and you won't be able to transfer the Windows licence to another machine. OEM licenses stay with the machine.

Are you sure you can spare this machine?

OK, let's move on.

4. Set up the machine for install

For installation you need to temporarily hook up a monitor and keyboard to the computer you plan to use. Make sure it has power but don't turn it on yet. Make sure it is connected to your network hub via the ethernet port in the network card.

5. Download and burn the BlueOnyx server set-up disk

The BlueOnyx set-up disc needs downloading as an ISO file and then burning to a blank CD.

Download the ISO file here:


Once downloaded you need to burn the ISO to a blank CD.

If you don't have software to burn the ISO to a blank CD, I recommend:


Burn baby burn.

6. Install the server software

This is the really exciting bit. Your old computer becomes useful again as a testing server.

Open the CD ROM drawer and insert the set-up disc.

Reboot the machine.

Booting from CD :-)

In most cases your computer will check the CD drive first, to see if it can boot from CD. If this is the case follow the on-screen prompts until installation is complete.

MAKE SURE you write down or remember usernames, passwords and IP addresses you put in during installation. You will need them later.

Not booting from CD :-(

You will know if the computer does not boot from CD if you see Windows starting up, or nothing happens and it complains it cannot boot. If this is the case you need to make sure the computer boots from the CD ROM drive before it boots from HDD by changing the "boot order" or "boot priority" in the BIOS.

Do this by pressing reset or restarting the machine, then hitting the F8 or F10 keys as soon as it starts booting up (a note on the screen should tell you which key).

Then the BIOS menu will appear and you need to hunt around for the "boot order" or "boot priority" and set CD or Optical Drive to be FIRST.

I would show you in detail but all BIOS menus are different (get your techie friend to help if you are not sure).

7. After installation

Once the server has finished installing (you will know because it will reboot and tell you to remove the CD) it is ready to begin acting like a server.

At this point you can unhook the monitor and then find a place where it won't get in anybody's way and plug it into the network there and switch it back on.

After a few minutes it will have booted up and you will be able to access the server via the web browser of any computer on the network and finish the set-up.

To do this simply input the IP address you gave to the server into your web browser.

You will then get lovely web interface to the server and be able to finish setting up.

And that's a wrap

At this point you have a web server. Look out for a future post on how to set-up "sites" on the server so you can test your work.

If you want to have a go on your own. Check my next post.

Monday, 24 August 2009

Descartes Day


In these modern times with such a rapid pace of progress we often mistake old or antiquated as meaning irrelevant. But we couldn't be more wrong.

I learned yesterday, from a child's book, that major principles on which much of my Actionscript is based were invented (or discovered) 372 years ago in the year 1637. The man we have to thank for bothering to write his discovery (or invention) down is the mathematician and philosopher Rene Descartes (pronounced day-cart).

And what was this great principle? What we now take for granted, the Cartesian Coordinate System (what we refer to as X and Y coordinates).

Allow me to quote that kid's book:

"Graphs turn pairs of numbers represented by x and y into meaningful shapes. This idea was invented by the French philosopher Rene Descartes, who is perhaps more famous for saying "I think, therefore I am." It allowed people to solve geometric problems with algebra and algebraic problems with geometry."
(Bridgman, R, 1000 Inventions and Discoveries, Dorling Kindersley Limited,
2002, pp 90)

If Descartes hadn't invented the system no doubt someone else would at some point - such is human ingenuity - so I don't for one minute suggest that _xmouse or _root.movieclip._y would not be possible without him. But the fact that Descartes was at least one of the independent inventors, and could be bothered to record and share his invention way back in 1637, deserves him some credit. So, today I briefly doff my cap to Descartes for his coordinate system (in much the same way I might tip my hat to Sir Tim Berners-Lee (inventor of the WWW) or Thomas Knoll (a founder developer of Photoshop) were I to pass them on the street).

The Wikipedia article on Cartesian Coordinates is an excellent introduction, and even gives formulas for transformation, reflection and rotation of geometry (all of which could form the basis of some useful Actionscript).

Just remember that with Flash the (0,0) point of the cartesian coordinate system is the top left hand corner (not the bottom left hand corner as it is with graphs).

Moving on...

Wednesday, 12 August 2009

Mouse Control for Flash Games - Part 2 - (Top Down Driving Game with Steering)

A couple of months ago I posted a solution for getting a MovieClip to follow the mouse, with easing. It was a quick solution for controlling the 'player' in a top-down car game.

Since then I have revised the code to also make the 'player' rotate in the direction of travel, to simulate the effect of the car steering.

Take a look:

Original Movie (without steering) - Demo SWF







Modified Code (with steering) - Demo SWF







As you can see the rotation produced by the modified code offers more realistic looking game play, allowing the 'player' car to appear to swerve as the player moves the mouse, and making the 'player' car straighten up as it comes to the end of its movement.

The Code

The code is actually remarkably simple, much simpler than I expected. As I look back through my development versions it gets progressively simpler as I cut out all the redundant code and am left with only what matters.

I will give you the code below, the comments explain how it works. Just paste it into your Flash Actionscript panel, and click the format button to make it nice and easy to read:

/* Includes code from http://dansinteractive.blogspot.com http://www.digitalarena.co.uk */
/* This code works best if your movie is set to run at 30fps. */

/* The higher the frame rate the lower this number must be. */

var easing = 10;

/* Influences how far the player_mc rotates in response to the mouse distance from the player_mc. The lower the number the greater the rotation. */

var rotatefactor = 4.5;

/* This function animates the player_mc in response to mouse moving. */

onEnterFrame = function () {

/* Works out the current distance between the X coordinate of the mouse and the X coordinate of the player_mc */

mousediff = _root._xmouse-_root.player_mc._x;

/* Moves the player_mc along the X axis towards the location of the mouse with easing to provide some delay and smooth movement. */

_root.player_mc._x += mousediff/easing;

/* Rotates the player_mc towards the mouse. The amount of rotation is determined by the difference between the player_mc location and the mouse location along the X axis, and the rotation factor defined in the variable at the top. The closer they are together the smaller the amount of rotation, the further apart the larger the rotation.
With the _rotation method a negative number means anti-clockwise (counter-clockwise) and a positive number means clockwise. Even so, we do NOT need to test which side of the player_mc the mouse is on to determine whether the angle of rotation should be positive or negative. This is because we base the rotation on the distance between the mouse and the player_mc, and if the mouse is to the left of the player_mc this code will return a negative number which in turn will give us a negative rotation factor. Cool.*/

_root.player_mc._rotation = mousediff/rotatefactor;
};


As you can see, the whole affect is achieved without trigonometry. As such it simulates the visual appearance of the 'player' car steering, but is not a mathematically accurate model of steering. But it is only intended to provide user mouse control of a car for a simple top-down driving game - accurate physics are not necessary.

The thing I am most pleased about (apart from the cool effect) is how little code it takes. Without comments, it is a mere 7 lines long. And yet it provides so much more engaging game play (I think so anyway). If you find it helpful, leave a comment.

Later.

Monday, 10 August 2009

Now Includes Demo SWF Files

I have a fair number of posts on here that describe funky uses of actionscript, but without showing examples of what I am talking about.

The good news is that I have now started adding demo SWFs to previous blog posts, and all future posts will include working examples by default.

Hopefully this will make it that little bit easier to see if my code is doing the thing you are needing help with.

What fun.

Friday, 7 August 2009

Manipulating Colour in Flash - #4 - Building an Interactive Colour Mixer

Now we are beginning to see the end result of all my experiments with manipulating colour using Actionscript. Using the techniques from my previous posts, and a few others to get a working interface, this post explains how to make a simple RGB colour mixer that gives a preview of the colour and the hexadecimal value in a form that can be copy and pasted.

Demo SWF







The Interface

While it is very tempting for those with a graphics background to want to start by designing a groovy interface (including me), it is sometimes a good idea to get just a basic prototype working so you can get the bugs out of the code - and that's what you see here.

The demo above shows my basic interface. Before we can go much further you will need to lay out something similar on your stage. The items in the demo above are labelled, check the key below:

KEY:

A = MovieClip, instance name 'colourspot_mc'
B = Input Text, instance name 'red_txt', variable 'red'
C = Input Text, instance name 'green_txt', variable 'green'
D = Input Text, instance name 'blue_txt', variable 'blue'
E = Dynamic Text, variable 'displayhex'
F = MoveiClip, instance name 'redpointer_mc'
G = MovieClip, instance name 'redclicker_mc'
H = MoveiClip, instance name 'greenpointer_mc'
I = MovieClip, instance name 'greenclicker_mc'

J = MoveiClip, instance name 'bluepointer_mc'
K = MovieClip, instance name 'blueclicker_mc'


Once you have set up your objects on the stage as above, you are ready to start coding.

The Code

I won't go into long and drawn out explanations of everything this time. The colour manipulation is explained in previous posts on this blog, and other things are explained within the code as comments.

NOTE: For some reason blogger is not treating this code very well. When you dump it into Flash make sure you hit the 'Format' button so it looks as it should.



/* set default values for R, G and B */
var red = 0;
var green = 0;
var blue = 0;
/* Create colour object to control colourspot_mc */
var my_color:Color = new Color(colourspot_mc);
/* Button triggers conversion of RGB into hex, then applies it to the colour object */
onEnterFrame = function() { /*This enables colour to be constantly updated */
/* ensures that only values between 0 and 255 can be used for red */
if (red>255) {
red = 255;
}
if (red<0) {
red = 0;
}
/* convert red decimal into hex */
var decred = new Number(red);
hexred = decred.toString(16);
if (decred<=15) {
hexredfinal = "0"+hexred;
} else {
hexredfinal = hexred;
}
/* ensures that only values between 0 and 255 can be used for green */
if (green>255) {
green = 255;
}
if (green<0) {
green = 0;
}
/* convert green decimal into hex */
var decgreen = new Number(green);
hexgreen = decgreen.toString(16);
if (decgreen<=15) {
hexgreenfinal = "0"+hexgreen;
} else {
hexgreenfinal = hexgreen;
}
/* ensures that only values between 0 and 255 can be used for blue */
if (blue>255) {
blue = 255;
}
if (blue<0) {
blue = 0;
}
/* convert blue decimal into hex */
var decblue = new Number(blue);
hexblue = decblue.toString(16);
if (decblue<=15) {
hexbluefinal = "0"+hexblue;
} else {
hexbluefinal = hexblue;
}
/* build the final 6 digit hex figure and prepend with 0x as needed by Flash */
hex = "0x"+hexredfinal+hexgreenfinal+hexbluefinal;
/* build the final 6 digit hex figure and prepend with # as needed by HTML */
displayhex = "#"+hexredfinal+hexgreenfinal+hexbluefinal;
/* set the colour property of the colour object controlling the MovieClip */
my_color.setRGB(hex);
/* Update the location of the pointers */
_root.redpointer_mc._x = ((_root.redclicker_mc._width/256)*red)+_root.redclicker_mc._x;
_root.greenpointer_mc._x = ((_root.greenclicker_mc._width/256)*green)+_root.greenclicker_mc._x;
_root.bluepointer_mc._x = ((_root.blueclicker_mc._width/256)*blue)+_root.blueclicker_mc._x;
};
/* Set the red decimal value with a clicker */
_root.redclicker_mc.onPress = function () {
redleft = _root.redclicker_mc._x;
clickpos = _xmouse;
clickval = clickpos-redleft;
clickprop = (clickval/_root.redclicker_mc._width)*256;
red = Math.floor(clickprop);
/*moving the pointer
_root.redpointer_mc._x = clickpos;
}
/* Set the green decimal value with a clicker */
_root.greenclicker_mc.onPress = function () {
redleft = _root.greenclicker_mc._x;
clickpos = _xmouse;
clickval = clickpos-redleft;
clickprop = (clickval/_root.greenclicker_mc._width)*256;
green = Math.floor(clickprop);
/*moving the pointer */
_root.greenpointer_mc._x = clickpos;
}
/* Set the blue decimal value with a clicker */
_root.blueclicker_mc.onPress = function () {
/*Getting the zero point on the clicker bar */
redleft = _root.blueclicker_mc._x;
/*Capturing the location of the click on the clicker bar */
clickpos = _xmouse;
/*Calculating how far along the clicker bar the click was made */
clickval = clickpos-redleft;
/*Calculating the proportional distance along the bar at which the click was made as a figure between 0 and 1, then converting that into a value between 0 and 256. */
clickprop = (clickval/_root.blueclicker_mc._width)*256;
/*Converting the figure to an integer by rounding DOWN to the nearest whole number. Rounding DOWN ensures we can get 0 at the bottom and 255 rather than 256 at the top. */
blue = Math.floor(clickprop);
/*moving the pointer object to the position clicked on the clicker bar */
_root.bluepointer_mc._x = clickpos;
}


And there we have it.

Solving Issues as You Go

It is always interesting to solve some issues as you go. For instance, I hadn't quite decided whether I wanted users to be able to type RGB values, or just limit them to using the colour bars.

When I decided that some users might want to be able to type them (as it might be easier and faster in some situations) I realised that some users might enter a value greater than 255 - which would then give inaccurate results. So, at the last minute I included the code that converts any number higher than 255 into 255 and any number lower than 0 into 0. Like I say, always interesting.

Another implication was with the pointers on the colour bars (items F, H and J in my diagram). Making the RGB numbers updatem depending on where the user clicked, and moving the pointers to the place the user clicked was one thing. But now we had to also work it the other way, and get the pointers to move to the place on the colour bar representing the value the user typed. It wasn't difficult, just a case of working the equation the other way, but it needed doing.

Sometimes seemingly small decisions about user experience can have a significant impact on our code. That doesn't mean we shouldn't put the user first, but it does mean we should be prepared to modify our code when needed. After all, our interactive applications need to actually do what the user wants, if we want any users to use them.

Thursday, 6 August 2009

Google Advantages with Blogger


I have been using Blogger since August 2007 very happily. And though everyone has their favourite blog system, and although I have even been recommended that Wordpress is better, there is something that some bloggers may not be aware of - really fast Google indexing for Blogger posts.

I don't know how long it takes for someone using Wordpress to have their blog posts begin appearing in Google. No doubt it will vary depending on the rating the blog has under the highly secret Google algorithms. But as a Blogger user I can honestly say that I have had a blog post appear in the Google search results within 2 hours of posting - this very day - and not buried pages deep either.

Less than 2 hours after publishing this post:

http://dansinteractive.blogspot.com/2009/08/converting-decimal-rgb-values-into-6.html


I found it on the number 1 spot on Google (out of about 13,300 results) under this search term:

convert 2 digit hex actionscript

Of course this is obviously related to the fact that Google owns Blogger, but the reasons are less important than the results. I almost don't care what other features other blog systems may have. Until they can beat me into the Google index I will stick with Blogger.

Converting Decimal RGB Values Into a 6 Digit Hexadecimal

Recent posts have looked at the Actionscript required to convert decimal numbers into hexadecimal strings. And if we don't look any deeper everything looks hunkydory for mixing any colour we like using RGB values, and then convert to a hexadecimal number you might use to define a colour in HTML.

But we still have a problem to solve.

Low Numbers v. High Numbers

HTML and Flash can both use hexadecimal values to define colours, but the hexadecimal values must be defined as a 6 digit number - 3 pairs representing the 3 colour channels Red, Green and Blue. For example:

White: Decimal Red 255 + Green 255 + Blue 255 = Hexadecimal FFFFFF

In most cases this won't present a problem, after all decimal 255 equates to hexadecimal FF. The problem comes when the decimal value drops below 16. Lets take a look:

Decimal 255 = hex FF
Decimal 16 = hex 10
Decimal 15 = hex F
Decimal 1 = hex 1
Decimal 0 = hex 0

Notice that as soon as the decimal value drops below 16 the hexadecimal value drops into single digits. Lets see what this means in practice:

Black: Decimal Red 0 + Green 0 + Blue 0 = Hexadecimal 000

This is a problem because to convey colour values to HTML or Flash consistently we need a 6 digit hexadecimal number, but what we have here is only a 3 digit number.

To solve the problem we need to remember how hex counts. As an example let's count to thirty in hex:

0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E

In this example values 16 and above all have 2 digits in hex. We need to find a way of making the lower numbers all have 2 digits too. This is actually very easy, in fact we do this all the time, most commonly when we write the date. Take for example 1st January 2009 written numerically - 01/01/09. We can turn a single digit number into a 2 digit number, without changing its value, very easily by placing a '0' (zero) in front (this is called prepending), like so:

1 becomes 01
2 becomes 02

All we have to do then is prepend single digit hex values with a '0' (zero), like so:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

If we do this we can display black as a 6 digit hex number after all:

Black: Decimal Red 0 + Green 0 + Blue 0 = Hexadecimal 000000

But how do we do this in Flash with Actionscript?

Prepending Single Digit Hexadecimal Numbers With '0' Using Actionscript

I am sure there are many and varied ways to do this, but I prefer the following method. First I will give you the code, then I will explain how it works.

/* R is defined as a value between 0-255 in a text input field by the user */

_root.calc_but.onPress = function() {
var decimalred = new Number(R);
hexred = decimalred.toString(16);
if (decimalred<=15) {
hexredfinal = "0"+hexred;
} else {
hexredfinal = hexred;
}

}

Here's how it works:

1. First we take the user inputted value (a number between 0 and 255) and pass it to 'decimalred' specifically defining it as a number.

2. Then we convert the 'decimalred' number into a hexadecimal string and pass the result to 'hexred'.

3. Then we test to see if the original value inputted by the user was 15 or less. We do this because we already know that any decimal between 0 and 15 will convert to a single digit hex number.

4. If the original value inputted by the user was 15 or less, then we use Actionscript to prepend a '0' to the converted 'hexred' value like so:

hexredfinal = "0"+hexred;

Then we pass the result to 'hexredfinal'.

5. If the original value inputted by the user was not 15 or less, then we don't prepend anything, we just pass the 'hexred' value straight to 'hexredfinal' untouched.


In this way we can make sure that in the conversion from decimal to hexadecimal, all values between 0 and 255 are shown as 2 digit hex numbers. This allows us to produce the 6 digit numbers required in HTML and by Flash.

What fun.

Manipulating Colour in Flash - #3 - Successfully Converting Decimal to Hexadecimal Using the toString Method (even with user defined variables)

My last two posts looked at how you can use Actionscript to change the colour of a MovieClip, and to convert decimal colour values into hexadecimal.

Teething Trouble

But as I work towards harnessing these techniques to make a simple colour mixer in Flash I suddenly ran into difficulty converting decimal to hexadecimal when the user defines the decimal values in text input fields.

I must confess that to begin with I spent a while being stumped by this. As I Googled around for a solution there were similar questions, but no answers. Anyway, I am happy to say, there is a solution.

No doubt some of you will have a similar problem, so let me talk you through the problem I experienced and then the solution (I hope it helps).

The Problem

In my tests the toString method easily converted a decimal defined as a variable in a keyframe to a hexadecimal as follows:

/* This works */
var R = 255;

mybutton_but.onPress = function () {
hex = R.toString(16);
trace(hex); //Returns FF
}

However, when the value of R was defined by the user through a text input box it suddenly stopped working, as follows:

/* This DOESN'T work */
/* value of R is defined as 255 in a text input field by the user */


mybutton_but.onPress = function () {
hex = R.toString(16);
trace(hex); //Returns 255
}


For some reason, when the value of R was defined in the keyframe the toString method successfully converted the decimal value 255 and returned FF, but when the value of R was defined in a text input field the toString method failed to perform any conversion on the decimal value 255 and returned 255.

Preparing to Find a Solution

When I struggle with solving these niggly little problems I often find that taking some time out and doing something else gives the mind time to unwind (and also mull over the problem without having to try out every idea instantly). The brain is a fantastic problem solver, if it is given the right conditions. As a college lecturer I know that the ideal conditions come when an individual is relaxed but alert. So, if needed, take a break, unwind, get some sleep or remove distractions. I spent the morning cutting the grass and sorting out the chickens, then in the afternoon found the solution.

The Solution

As I said before, none of my Googling revealed an answer to my problem, but as I hunted around for anything I could find that might give me a hint, or prompt an idea I came across this snippet on WikiBooks.org:

var i = new Number(555);
trace(i.toString());

I must have seen several similar examples yesterday evening and got nothing from them (too tired no doubt). But having taken a break from the problem since then, and relaxed, my brain was ready to spot the significant detail that was the solution:

var i = new Number(555);

And there it was, staring out at me. Something I had not yet tried. So I modified my code as follows:

/* This DOES work */
/* value of R is defined as 255 in a text input field by the user */

mybutton_but.onPress = function () {
var decimalred = new Number(R);
hexred = decimalred.toString(16);
trace(hexred); //Returns FF
}

Why it Works

So why didn't it work before, and what's the big difference that makes it work this time?

I suspect that the reason it did not work before was because the user defined variable 'R' was already being treated by Flash as a string and so using the toString method to convert to a string did nothing, because it was already a string to start with.

Result: 255 (string) in, 255 (string) out.

The solution is really hidden within the problem (as are so many design solutions). We are converting a decimal value (representing a colour channel intensity) into its hexadecimal equivalent. We want to do this using the toString method. However, the toString method is for datatype conversion. This means converting one datatype to another datatype, in this case a non-string into a string. For this to work we need to force Flash to treat the user input 'R' as a number so that we can use toString to convert it into a string in hex format.

The script above does this by passing the user defined decimal value 'R' to a new variable 'decimalred' - with 'decimalred' specifically defined as being a new Number. This forces Flash to treat the user defined value as a number datatype thereby allowing toString to work as expected and convert the decimal number value to a hexadecimal string.

Result: 255 (number) in, FF (string) out.

And that's a wrap.

It is precisely this kind of problem that I see as being the drawback of having come to Flash and Actionscript from a graphic design, rather than a programming background. Nevertheless, I hope that by posting my solution I have helped at least one other poor designer get to grips with with one small area of Actionscript. If my Googling is anything to go by, this may well be the only explanation of this problem on the web (at time of posting of course).

Happy coding.

Tuesday, 4 August 2009

Manipulating Colour in Flash - #2 - Dynamically Changing MovieClip Colour

Converting decimal colour values into hexadecimal is one part of the puzzle, but then we have to use the result to dynamically change the colour of a MovieClip.

One of the inconsistent(?), and certainly annoying things about Flash is the way you modify the colour of a MovieClip with Actionscript. We already know you can modify various attributes of a MovieClip such as _height, _width, _x, _y, _rotation... but there is no attribute for colour.

The Colour Object

What you have to do instead is create a create a colour Object which in turn controls the colour of the MovieClip. It's not difficult, take this as an example:

var my_color:Color = new Color(MovieClipName_mc);

In this code we call the object 'my_color' and in the parenthesis we specify the instance name of the MovieClip the colour object will be controlling the colour of, in this case a MovieClip called 'MovieClipName_mc' - you can of course name your MovieClip differently, provided you specify its name in the parenthesis as above.

Changing the Colour

We know the name of the colour object - 'my_color' - so now we can tell Flash the colour value of that object in hexadecimal (just as we would specify a colour in HTML). Here's the code:

my_color.setRGB(0xFFFFFF);

In HTML we prefix a hexadecimal colour value with '#' as in '#FFFFFF'. In Actionscript we prefix with '0x' as above '0xFFFFFF'.

FFFFFF of course represents the colour White (if white is a colour), if you change this value in the script above the MovieClip specified in the colour object will adopt the same colour.

Practical Use

That explains the principles of how we can use a colour object to control the colour of a MovieClip, but how about a practical example...

1. Create an object on the stage, select it and hit F8 to turn it into a MovieClip. Give the MovieClip the instance name of 'colourthing_mc'.

2. Create a new layer, name it 'Actions', then select the first frame of the layer.

3. Now create a Dynamic Text Box of the Input variety on the stage. In the properties panel set the variable to be '_root.usercolour', the reason for this will be explained in my comments below.

4. Now create a Button on the stage and give it the instance name 'calc_but'.

And that's the easy bit, now for the easy code:

/* This is one of those really silly things about Flash. Instead of having a colour attribute like they have _width and _height attributes, you have to create a colour Object which in turn controls the colour of a specified MovieClip. Here's how you do it: */

var my_color:Color = new Color(colourthing_mc);

/* This next step sets up for allowing the user to specify the colour of the MovieClip. */

/* First we create the user controlled variable */

var usercolour = "000000";

/* Then we create another variable that is the result of formatting 'usercolour' as required for Flash to understand it as a hexadecimal value by pre-pending it with '0x' */

var hexusercolour = "0x"+usercolour;

/* Then we setRGB of 'my_color' to that hexadecimal value */

my_color.setRGB(hexusercolour);

/* All that remains is to create a dynamic text box that allows the user to input their own hex value for the 'usercolour' variable and a button that will update the 'my_color' value with the user value from the text box, whenever it is clicked.

The important thing to remember when setting up the text input box, is to se the variable very precisely. If the variable it is updating is in the root timeline, then you must define the variable in the text box as '_root.variablename' not simply 'variablename'. In this case the variable for the text box must be '_root.usercolour'. */

/* This code then makes the button update the colour object with the user specified value. */

_root.calc_but.onPress = function () {
var hexusercolour = "0x"+usercolour;
my_color.setRGB(hexusercolour);
}

And that should be it.

Now we have been able to change the colour of an object through user input of the hex value. This could be developed further to allow the user to change the value by using sliders. This will require us to change 0-255 values into hex values on the fly. But knowing what we know from my previous post, this shouldn't be too hard.

Monday, 3 August 2009

Manipulating Colour in Flash - #1

Following on from my previous post, I have begun to look into how I can use Actionscript to work with colour.

This experiment looks at how we can convert decimal RGB values into hexadecimal using Actionscript.

It's very simple...

The Code

/* First we set the RGB values as decimal integers (whole numbers) from 0-255, as you would see them defined in any graphics program. This example would reproduce white, but you can change the values to be anything you like between 0-255. */

var R = 255;
var G = 255;
var B = 255;

/* Then we convert the RGB decimals to their hexadecimal equivalents. The toString method is the easiest way I have found of doing it (thanks to Colin Moock). This script takes the value of each of the variables and converts the datatype from a numeric value
(in this case 255) into a string using '16' as the radix argument of the method. As a result 255 becomes FF, the hexadecimal equivalent. The code below then simply stitches the converted values of the R, G and B variables together to form a 6 digit hex number for the colour. */

trace(R.toString(16)+G.toString(16)+B.toString(16)); //Returns FFFFFF


What I like about this method is its simplicity. It would form the basis of a very simple colour mixer program, since the R, G and B values could easily be set by sliders, or the user keying in decimal values for each of the channels.

Over to you... meanwhile, I play with colour some more.

Thoughts on Colour

Colour is a fascinating thing. As a child there was always that wonder of discovery that went with mixing colours to make new colours... always resulting in that grimy brown in the end.

I have since learned that as a child I was playing with subtractive colour, the mixing of pigments to subtract from white and make black. Meanwhile your computer monitor uses additive colour, mixing light to add to black and make white.

It gets even more interesting when you introduce colour wheels and start to notice the relationships between primary, secondary and tertiary colours. Or the difference between tint, hue and shade, or complementary colours and colours in common.

16 Million +

Computers make mixing colours so easy, in fact, with the right tools it becomes less about art or aesthetics and more about mathematics. Did you know for instance that the 16 million or so colours your monitor can display are made up of just 3 colours, red, green and blue? Each of these is called a channel, a red channel, a green channel and a blue channel. In fact your computer can display 256 increments (levels of colour strength) on each channel and by mixing those colours in different amounts you get all the colours available to your monitor.

Just think about it, 3 colour channels, 256 increments of each to mix:

256 x 256 x 256 = 16,777,216 possible colours

Decimal v. Hexadecimal

In decimal we count from 0 to 9 before starting over, giving us 10 increments. like so:

0 1 2 3 4 5 6 7 8 9

Using decimal to define colour we start with 0 as the lowest colour value, and end with 255 as the highest, giving 256 increments.

However, HTML (and at times Flash) prefers hexadecimal which differs from decimal in that we count from 0 to 15 before starting over, giving us 16 increments. Like so:

0 1 2 3 4 5 6 7 8 9 A B C D E F

Using hexadecimal to define colour we start with 00 as the lowest colour value, and end with FF as the highest, giving 256 increments also.

We can say that a decimal 255 and a hexadecimal FF are of equal value. They represent the same number. Likewise a decimal 0 and a hexadecimal 00 are also equal.

Defining Colour Values Numerically

A present we are looking at specifying RGB colour, that is colour defined by the amounts of Red, Green and Blue in their makeup.

When defining RGB colour numerically, it is vital to remember the order of the colour channels. It is always Red, then Green, then Blue. Take the following decimal example:

255,192,128

Knowing the order of the colour channels means we can understand that this means the Red channel is on full blast at 255, the green channel is at three-quarter strength at 192 and the blue channel is at about half strength at 128.

Using hexadecimal we would write the same colour as:

FFC080

The first 2 digits are the red channel, the second 2 digits the green channel and the last 2 digits the blue channel.

Fascinating stuff.

Anyway, as a result of my interest in digital colour, I have decided to take the plunge and see how Flash can be used to manipulate colour. From my initial reading an understanding of the above will be vital to colour manipulation with Actionscript.