Monday, 27 July 2009

Sliding-Page Effect - Navigation in Flash

The other thing that http://www.fuelfugitives.com/ got me interested in was the way the navigation works. The wonder of Flash is that you don't load a new "page" when you click a "link" (or button). In fact anything can happen - make a noise, play a video, basically anything you can imagine and code. This means we are not constrained to the traditional ideas of navigation transitions from "page" to "page".

Fuel Fugitives utilises a nice idea I have seen a few times. Instead of simply changing to another "page" or screen, you slide gracefully from one place to another, as though all the "pages" are actually on the same sheet, you just change which part of the sheet you are looking at.

Well, unable to resist the challenge I decided to work out a way of getting the same effect myself, using Flash and AS2.

Let's get started







1. Create a new Actionscript 2 document and set the frame rate to 30fps.

2. Create an object on the stage, hit F8 and convert it into a MovieClip, with the registration set to the middle.

3. Create 3 more instances of the MovieClip (for a total of 4), space them out, and give them the instance names object1_mc, object2_mc, object3_mc, and object4_mc.

4. Select (using SHIFT) all of the instances of the MovieClip on the stage, then hit F8 and convert the group into a MovieClip with the registration set to the top left. This new MovieClip should contain all the other clips on the stage. Give this new MovieClip the instance name objholder_mc.

Once that's done it's time for the Actionscript.

The Actionscript

/* First we set a variable called currobj. This will store the name (or in this case number) of the movieclip we want centred on the stage. We will use it later to centre that movieclip if it is not already centred. */

var currobj = 1;


/* Now we need some easing to give the slide animation a bit of style */
var easing = 6;

/* Then we set variables to define the centrepoint we want to centre movieclips to. */

var hmiddle = Stage.width/2;
var vmiddle = Stage.height/2;

/* Then we create the function that moves the current movieclip (defined by currobj) to the centre (defined by hmiddle and vmiddle). */

onEnterFrame = function () {

/* Finding the difference between the object holder x and y and the centre x and y */
objh_v = _root.objholder_mc._y;
objh_h = _root.objholder_mc._x;
vdiff = vmiddle-objh_v;
hdiff = hmiddle-objh_h;

/* Finding the object x and y within object holder. By using the ["object"+currobj+"_mc"] the code works for every object, all we need to do is update the value of the currobj variable. This means that we can keep our code small and reusable. */

obj_h = _root.objholder_mc["object"+currobj+"_mc"]._x;
obj_v = _root.objholder_mc["object"+currobj+"_mc"]._y;

/* Finding the difference between the current object (currobj) x and y and the centre x and y */

finalvdiff = vdiff-obj_v;
finalhdiff = hdiff-obj_h;

/* Finally we get onto the animation. This basically tells the objholder x and y to move so that the currobj MovieClip inside objholder is centred. All the calculations up to now allowed us to find out exactly where objholder needed to move to for this to happen. So that we get the easing effect on the animation, objholder only moves just under half the actual distance to its destination on each frame (this is controlled by the easing variable). */

_root.objholder_mc._y += finalvdiff/easing;
_root.objholder_mc._x += finalhdiff/easing;
};

/* Making the objects act as links to the next object. I am working on a way to write this code only once for any number of objects, on the basis of telling Flash the total number of objects, but not there yet. meanwhile we need a function for each object manually telling it to go to the next by setting the currobj value to the next object. */

_root.objholder_mc.object1_mc.onPress = function () {
currobj = 2;
};
_root.objholder_mc.object2_mc.onPress = function () {
currobj = 3;
};
_root.objholder_mc.object3_mc.onPress = function () {
currobj = 4;
};
_root.objholder_mc.object4_mc.onPress = function () {
currobj = 1;
};

Over to you...

As you can see, the code is fairly straightforward (hopefully the comments explain how it works). But so far all we have is the mechanics, to be really effective you need to have good graphics to go with it. A good idea!

That's what Fuel Fugitives has, now over to you.

Controling Flash Navigation through the URL

Just came across this site http://www.fuelfugitives.co.uk/ which uses the URL in a really interesting way to allow you to access different parts of a Flash Movie depending on the URL. Even though it is the same Flash Movie, not different pages.

This is useful because it means you can bookmark or "add to favourites" a specific part of the Flash Movie. It also means you can use your browser back button to return to a previous part of the same movie (normally with Flash this would result in you leaving the page containing the embedded movie).

So how did they do it?

I'm still looking into that, but a quick view of the source code indicates that some cool javascript is the answer. Will investigate more later... meanwhile - gardening.

Having cleared nigh on 168 square feet of garden (and finding bricks, carpet, bags of clothes and all manner of rubbish buried there by previous owners) with the help of a brother, I have come back to find the answer, and after a bit of searching found if not the solution, a solution...

And the answer is...

http://www.asual.com/swfaddress/

To quote the website:

SWFAddress is a small, but powerful library that provides deep linking for
Flash and Ajax. It's a developer tool, allowing creation of unique virtual URLs
that can point to a website section or an application state. SWFAddress enables
a number of important capabilities which are missing in today's rich web
technologies including:

  • Bookmarking in a browser or social website
  • Sending links via email or instant messenger
  • Finding specific content with the major search engines
  • Utilizing browser history and reload buttons

There are some cool little demos too so you can see it in action, and sure enough, seems to be pretty much what I saw on http://www.fuelfugitives.co.uk/, the site that started me looking in the first place.

So that seems to be it. One more thing to add to my todo list, but I fully intend to put this to good use this holiday. I hope you find it useful as well.

Friday, 24 July 2009

Drag n' Drop (with momentum) in Flash



A few weeks ago I had the opportunity to attend a JISC e-learning event. A fair number of educational technology vendors were present promoting their latest products and services, but for a brief moment one thing caught my eye. The SMART Technologies SMART Table.

It wasn't so much the idea of the SMART Table that intrigued me but the interactivity it offered. The e-learning game running on the table at the time was a diagram of the human body on which the students would have to correctly identify the different body parts by dragging labels onto them from the edge of the screen. As they were dragged the labels would turn as though being pulled by little strings, then when released would continue on to a gentle stop as though they had their own momentum.

I thought that idea of dragging and dropping labels that had weight and momentum was really cool, and I immediately realised that you could do a similar thing using flash.

Well, now that the first evening of my holiday is here I have begun work and have a basic solution for the momentum part of it (I will add the turning and following part another day when that is done).

So here it is, drag and drop, with momentum, in Flash:

Here's it is







If you are not yet an AS3 whizz or using an older version of Flash, don't worry, this one uses AS2.

Let's get going.

1. Create a new AS2 document.

2. Create a shape on the stage, select it and hit F8, then turn it into a MovieClip

3. Give the new MovieClip the instance name of object_mc in the Properties panel.

And that's the easy bit done. Now for the ActionScript.

4. Create a new layer in the timeline and give it the name Actions.

5. Select the first frame of the Actions layer, then hit F9 to open the Actions panel.

5. Input the following code into the Actions panel (hopefully my comments will explain everything, if not, leave a comment):

/* set some variables we will use later */

var posBh = 0;
var posBv = 0;
var posAh = 0;
var posAv = 0;
var trajh = 0;
var trajv = 0;
var drag = 0;


/* sets the level of friction, the higher the number, the more friction.*/

var friction = 1.35;

/*We make the object draggable, and set the drag value to 1*/


object_mc.onPress = function() {
this.startDrag();
drag = 1;
};


/*We stop dragging and set the drag value to 0*/

object_mc.onRelease = function() {
this.stopDrag();
drag = 0;
};


/*This part controls the momentum of the drag on stopDrag()*/

onEnterFrame = function () {

/*If we are dragging the object (and we can tell we are because drag == 1) then we gather information on the trajectory of the drag for ready for when we stop drag. We do this by comparing the X and Y position of the object between frames and so finding out its X and Y velocity. This is stored in the variables trajh and trajv.*/

if (drag == 1) {

/* Calculate Y trajectory/velocity*/

posBv = posAv;
posAv = _ymouse;
trajv = posBv-posAv;


/* Calculate X trajectory/velocity*/

posBh = posAh;
posAh = _xmouse;
trajh = posBh-posAh;
}


/*If the object has stopped being dragged (and we can tell because drag == 0) we then apply some momentum so the object keeps moving after it is let go. We do this by telling the X and Y position of the object to keep moving each frame with the value of the X and Y velocity as stored in the variables trajh and trajv. However we also apply some friction by reducing the value of trajh and trajv a little on each frame. We do this by dividing the variables trajh and trajv by the friction value on every frame and then setting trajh and trajv to have this new value.*/

if (drag == 0) {
trajh = (trajh/friction);
trajv = (trajv/friction);
_root.object_mc._x -= (trajh);
_root.object_mc._y -= (trajv);
}
};


And that's your lot.

CTRL ENTER to test your movie. You will find you can click and drag the object on the stage and if you let go while moving it will carry on with momentum but come to a gradual halt.

You can increase or reduce the amount of friction the object encounters on release by changing the value of the friction variable. Remember, the more friction the quick it slows, the less friction further it travels (like on ice). Have fun experimenting.

Summary

Although this was inspired by my experience of the SMART Table, it won't ever be that versatile because while the SMART table can handle several kids all working at once, Flash will always be limited by the number of "mouse" type inputs your computer supports at once. Usually one.

But we interactive media types don't care for such trifling limitations. Inspiration is one thing, and application is another. I don't have to make a SMART Table clone.

I can still use my flash experiment in a variety of ways to spice up my interactive applications, so the inspiration and the experiment was worth it.

Wednesday, 3 June 2009

Creative COW - a real hidden gem...


I have been recieving emails from Creative COW for ages now but only just found time to really take a look at what they were about... and that was because they sent me an email telling me about Stereoscopic 3D (something bound to get my attention, and certainly of interest to a student of mine who produced an anaglyph 3D animation recently).

So I clicked on over to Creative COW only to be astonished that they actually publish a PDF magazine you can download for free, with excellent articles by real professionals about film and media production.

I immediately downloaded the latest issue, and then all back issues.

It is not often you find something so well produced totally FREE.

Mouse control for flash games

Another of my students hit me with a conundrum to solve, and as usual I can't resist the challenge.

They are constructing a flash game to help new computer users become more comfortable with using a mouse. The idea is to have a top down driving game in which the player must move the car side to side to avoid on coming traffic and bad guys.

My student is already aware that you can easily make the player character follow the mouse, but they were not happy with such instant precise movements for the game (cars, after all, just don't respond like that). So I have been looking at some code to add a dampening or easing effect on the car so there is a smoother response when the mouse is jerked.

Demo SWF







Easing with mouse chasing movieclips

To kick off, the frame rate of the movie is 30fps for nice smooth animation. Then chuck the following code into the first frame:

var easing = 0.1; //The higher the frame rate the lower this number must be

onEnterFrame = function () {
_root.player_mc._x += (_root._xmouse-_root.player_mc._x)*easing;
};

And it really is that simple. To tighten or loosen the easing just ammend the easing variable.

Then just whack a movie clip on the stage called player_mc and you're done.

Taking the game code further

It is too late at night to waffle about it now, but you may find the developed code helpful. I may even get round to finishing it:

/* Students are required to design and build a simple game that teaches mouse control. However one student complained that the mouse is too sensitive for his game idea (a topdown car game).

One solution to his problem is to have acar contolled onl
y along the X axis (left and right) andthat we do some simple algbra to dampen or ease the control ofthe player car.

Here goes.*/

/*First declare some variables */

var easing = 0.1;
/*easing sensitivity, the greater the frame rate the smaller this value needs to be.*/

var crashcount = 0;

/*Then we hide the mouse cursor so the user is not distracted and can focus on the player movie clip instead (which will be constrained to follow the mouse only on the X axis.*/

Mouse.hide();

/*Now a function to implement the easing and test for collisions with the enemy*/

onEnterFrame = function () {
/*Here's the easing*/
_root.player_mc._x += (_root._xmouse-_root.player_mc._x)*easing;

/*Because of limitation on Flash's hit test (whole bounding box or just a single point) the following code checks for collisions on 2 single points on the player, the top right, and the top left of the player. Because all collisions will be front on, this will be sufficient to see if the player collided with the enemy. We choose the single point method because it allows us to lump all the enemies into one movie clip and for us to weave between the gaps without raising a collision as we would if we used the bounding box.*/

if (_root.enemy_mc.hitTest(_root.player_mc._x+(_root.player_mc._width/2), _root.player_mc._y-(_root.player_mc._height/2), true)) {
crashcount += 1;
} if (_root.enemy_mc.hitTest(_root.player_mc._x-(_root.player_mc._width/2), _root.player_mc._y-(_root.player_mc._height/2), true)) {
crashcount += 1;
}
};

Thursday, 28 May 2009

Let's have some X3D support in browsers, please...

I have just been reading a very interesting article on the future of X3D by Ben Fancis on his blog. Ben suggests that while X3D is already mature as a standard, in terms of adoption it is still in its infancy, and that before it can fully mature we need to see some adoption of the X3D standard into mainstream browsers.

Since I have recently become interested again in Web3D and this time X3D (rather than VRML) I have been frustrated by the lack of support of web3D standards also. I left my own thoughts as a comment on Ben's blog, but just in case it doesn't make it past moderation I include them below for your consideration. It will make more sense if you read Ben's article first.

My Thoughts

I think Ben made some excellent observations on the factors surrounding adoption of X3D. I have been a fan of web based 3D for ages, but even since the VRML days the biggest block was browser support and now that X3D is here this still hasn't really changed.

But think that outside of browser support the other factor is getting the creative community on board. Too often I think that the software engineers and techies think they own the web and that it is all down to them. But in reality, the popularity (and usability) and growth of the internet in its importance with the general public has a lot to do with the creative application of the technology. It is a collaboration between creative designers and techies that will really bring it about. This brings me to the other missing factor for X3D to become popular - tools for designers.

Vivaty Studio (Formerly known as Flux Studio) is the closest to being a decent X3D authoring tool. It's pretty powerful, having used it myself, but still has room to develop in terms of accessibility for beginners. At present a designer familiar with flash and a 3D authoring program could probably figure it out without too much trouble, but the animation and interaction editing could do with some refining to make it easier to use, and the modelling tools could learn a lot from other programs. Having said all that generally it is really good and certainly the best X3D authoring tool I have come across.


Vivaty Studio Screenshot

Authoring tools won't be enough, as we learn from Axel - an excellent authoring tool (vivaty can learn a lot from their animation and interactivity implementation), but lacked plugin penetration. This is where other vendors like Adobe have already got it made.

What concerns me is that while proprietary software vendors like Adobe have their own 3D standard, and push it out to all their current Adobe users in software already familiar to most designers, and nice integration with other Adobe apps, X3D will have a hard time getting a look-in. I for one cannot imagine Microsoft adopting an open standard either, when they no doubt add 3D to their Expression suite in the future.

It is refreshing that Vivaty are using an open standard however (unlike so many others "second life" for instance), and it is decisions like this that are X3Ds greatest hope.

Outside of that, I totally agree, browser implementation is the next step for X3D to come of age. MS will be the last to get on board but Mozilla/Firefox could lead the way closely followed by Chrome or Safari.

What also might help if Vivaty put their plugin source code back into open source. The Flux player used to be Open Source, but a visit to sourceforge now will show that all source files have been removed. Maybe the investors that made Flux into Vivaty want to guard their investment closely (who can blame them), but one wonders if by holding everything too tight X3D might just as well be a proprietary format for all the market penetration it has - and without the customer base of Adobe or MS, Vivaty will slowly dissolve like Axel and nameless others. In my view a better strategy would be to open their plugin source, get it included into a Mozilla release and start seeing popular browsers with built in X3D support. Surely that will help Vivaty's larger business aim (no plugin required) in the longer term, and get them on the market with a good authoring tool. Who knows but Google will buy them out under those conditions and build X3D into Sketchup for some real Web3D competition with Adobe.

Wednesday, 8 April 2009

Recognising the value of design...

Chuck Green is one of those names (a bit like Chris Pirillo) that has been around, sharing their wisdom, since before the dot com bubble burst - I first came across Chuck Green in 1999 and even then he managed to make plain old HTML look pretty good.

Anyway, I have been recieving Chuck's emails for a while, but today's was so especially interesting that I have decided to share a chunk with you:

To those who don't recognize the value of graphic design... »

I got a plea for help the other day. A designer who frequents this blog had shared a recent post with an engineer friend and the reply was a bit condescending. The post, "The talent that makes a good designer great," points to an engineer who I thought was particularly innovative. My purpose in drawing attention to him was to emphasize the importance of the same type of innovative thinking to the field of graphic design.

The essence of the engineer's response was they saw little correlation between the skills of an engineer and those of a graphic designer. How could that type of innovation, they posed, have anything to do with a designer's sense of style, their ability to choose typefaces, their knowledge of color, and so on. After all, the subject of my post, the engineer asserted, was a PhD candidate.

I laughed out loud. Every designer has had (or will have) this conversation. At its root is the implication that devoting one's career to the design of communications and an interest in the aesthetic is somehow less of a calling than some other, more significant field of endeavor.

My response is this:

The ergonomics and aesthetics of design are to engineering what taste is to food.

Remove the aesthetic qualities (style, organization, presentation) of the clothing you wear, the book you are reading, the automobile you drive, the room in which you spend your time, and so on, and all you have left is...function.

It is important for every student of design (and engineering) to recognize and appreciate the importance of form to function and vice versa. And it is equally important to understand that to be a exceptional practitioner of either discipline requires out-of-the-ordinary instincts, curiosity, knowledge, craft, and so on.

Lots of people view art and science as a comfortable coexistence. But for those who are particularly attuned to one or the other, it is good to remember that the most debilitating form of blindness is to minimize the way in which others see. It is not only a sure way to limit your potential--it is a certain and swift strategy for diminishing your influence.

An example of substance without style... http://www.ideabook.com/substance_without_style.html

Reminds me of a conversation I had with an engineer on this very blog. Thankfully my engineer friend is open minded to the value of aesthetics, just as I see function as being fundamental too.