Tuesday, 16 December 2014

Can't access Wamp from another PC at your location?

I was getting on fine browsing 'localhost' on the machine that held the WAMP installation, but even with the firewall off, the WAMP server 'online', I was getting 'permission denied' when browsing from other machines on my local network.

This was the solution for me:

Thursday, 4 December 2014

Embedding YouTube Videos in OpenCart Products

Sometimes the simplest solutions are the best.

Forget all the VQmods and Extensions.

Just go to the product description, hit the 'Source Code' button to reveal the HTML view in the editor. And paste the YouTube generated embed code right there.

Tips

YouTube embed code options are quite advanced. Don't merely take the default code, or even the default player sizes. Have a play, choose custom sizes, start the video from a particular time, all kinds of options are available.


Monday, 27 May 2013

The Secret to Success!

It's a theme as old as time itself, and in self help books, DVDs and seminars the topic is worth £ millions in turnover. In a former role, as a teacher, I worked for years helping young people develop this in themselves finding that the difference between a student succeeding and failing was more down to this than any kind of natural ability. But even so it took a while for me to understand that this is the real key. And what is 'this'?

Belief.

I have come to learn that belief is the key to personal success. For a long time I thought, and taught, that it was work, or effort, and though important I now know that belief comes first. Without belief the inclination to put in sufficient work and effort soon dies.

In a recent BBC article "From thought to profit: How ideas become viable businesses" Timothy Mitchell, a 27-year-old "eccentric genius", and former Microsoft director, who says he's cracked artificial intelligence (AI) with computer codes and programmes that actually have the ability to learn, says:
"I have seen thousands of ideas die on the vine, because the individuals that have them never get over that fear of failing".

Fear of failure, or failure to believe, essentially comes down to the same thing. You let your worry that it won't work talk you into not working at it. It becomes a self fulfilling prophecy.

In a very real way the battle for your personal success is won or lost in your head.

This understanding has been taught since ancient times. From the Christian ideal that "all things are possible to him that believeth" to Norman Vincent Peale's call to "Believe in yourself! Have faith in your abilities! Without a humble but reasonable confidence in your own powers you cannot be successful..." from The Power of Positive Thinking, the emphasis on belief remains.

We all have inherent abilities and talents, God given, and believing in them will unlock your success. That's the key, that's the start. That is where fear of failure is overcome.

More Reading

Using belief to overcome fear of failure is the theme of many resources on the subject, here are just a few:

The Power of Positive Thinking - Norman Vincent Peale

As a Man Thinketh - James Allen - FREE!

The Power of Concentration - Theron Q. Dumont - FREE!

The Seven Habits of Highly Effective People - Stephen R. Covey

The Secret

Monday, 22 October 2012

Mouse Wheel Animation Control with Easing

The previous post gives a simple ActionScript 2 solution for using the mouse wheel to control forward and backward play along the Flash timeline.

This example extends that to introduce an element of easing. When the user stops scrolling the mouse wheel, instead of coming to an immediate halt, the animation gently glides to a stop.

var damping = 0.95;
var accelerator = 0; //equivalent to movieclip frames per framerate frame

//detect mouse scroll
var mouseListener:Object = new Object();
mouseListener.onMouseWheel = function(delta)
{
accelerator += delta/3;
};
Mouse.addListener(mouseListener);

//manage the animation
onEnterFrame = function ()
{
accelerator = accelerator*damping;
framespeed = Math.round(accelerator);
moveframe = clip_mc._currentframe + framespeed;
clip_mc.gotoAndStop(moveframe);
};


And there you have it. Play a MovieClip animation with speed and direction determined by the direction the user scrolls the mouse wheel. And when the mouse wheel is released the animation slowly comes to a halt.

Happy days.

Controlling Flash Animation Frame, Direction and Speed with Mouse Scroll

Most animations just play, you set their frame rate, your press play, and away they go. But I have an interactive item that I want users to be able to play forwards, or backwards, at the speed they scroll their mouse.

I am using ActionScript 2 for this, and the code is blissfully simple:
var mouseListener:Object = new Object();
mouseListener.onMouseWheel = function(delta) {
     frame = (clip_mc._currentframe + delta);
     clip_mc.gotoAndStop(frame);
}
Mouse.addListener(mouseListener);

As you can see you just create a mouseListener object and then build a function that acts on the onMouseWheel event.

When the mouse is rolled the 'delta' (or the value of the mouse scroll, forward or backwards) is used to calculate a new position in a MovieClip's timeline based on the current frame. The function then moves the play head using gotoAndStop to that new position in the timeline.

And you're done... This can be used to control the speed and direction of animation play within a MovieClip. I have a few creative applications of this technique in mind for the future - I hope you find it helpful. Happy scrolling.

Sunday, 21 October 2012

3D Game Environment Modeling

Setting the pace for my level 3 students... One of my teaching philosophies is to lead and show, not just explain. Doing this provides ample resource for students to see the entire process, and to aspire. Here's my example.

Thursday, 4 October 2012

A job well done!

It is with some emotion that I look back on the last few years spent working as a lecturer and teacher of graphics, interactive media and game design. But today more so as I received visits from two of my old students who have made a fantastic success of their lives since attending my classes.

Both recently graduated with Degrees and have successfully found work in the creative industries they trained for. One as an animator, the other in game design. Thanks for visiting me today you two, I could not be more happy for you. Thank you for bringing me news of your other friends who I also had the pleasure to teach. If you ever read this, I am proud of you, just as I am of all my other students progressing with their education or professional careers, buying their first houses, raising their children...

Right now, though, having visited today, you two represent everyone I have taught over the last 7 years, you are in many ways the symbols of what I hoped my career would be about. I wish you, and all my students every success. The future is bright it really is, it is in your hands, I know you can do it. And what made my day today was seeing that you know you can do it too.

Wednesday, 5 September 2012

Google Pulls Support for Unofficial Weather API

Well, it had to happen, it was never officially supported, and now it has. As Slashdot has reported, the Google Weather API is no more.

But... there are some alternatives, notably the Yahoo weather API - more details here:

http://dansinteractive.blogspot.co.uk/2011/03/finding-weather-with-yql-and-yahoo-api.html

And, if you don't get on with that, you might take a look at this alternative:

http://www.wunderground.com/weather/api/

Happy weather forecasting :-)

Saturday, 14 July 2012

Game Designers

You've heard of Alfred Hitchcock, Steven Spielberg, Ridley Scott, James Cameron? Sure. All film directors. Visionaries in the medium of film. Artists and creative geniuses every one of them. But what about the medium of the computer game? Who were and are the names in games?

Perhaps like me you also "wasted" many holidays, evenings and weekends, as a youth, playing computer games. The first game I remember was "Jet Set Willy". A friend had loaned their Sinclair Spectrum to my older brother (I must have been about 8 at the time) and after what seemed an age of waiting for it to load there before my eyes was the first computer game I ever saw working in my own home. Since then I have played many games on many systems. Over the years home I have lived in hosted various home computer and game platforms - ZX81, Spectrum 48k, Oric, Spectrum +2a, NES, Game Gear, Atari ST, Atari Lynx, Master System, Mega Drive, PS1, XBOX, XBOX 360 and the Wii. Not to mention more iterations of PCs than I can remember, and of course my old iPAQ PDA, and now my Android smart phone. I played games on them all, more games than I can possibly remember, and behind each game were clever, creative designers pouring their ingenuity into their creations like the Scotts and Camerons of the gaming world.

Having recently become acquainted (and in some cases re-acquainted) with the knowledge of some influential names in the game industry, I decided to do some homework to learn more about other important names that influenced my youth. In other words, who were the Hitchcocks and Spielbergs, the game designers, behind my favourite games, and what do they have in common that I can learn from?

Matthew Smith

While possibly not strictly a game designer by the current definition, Matthew Smith probably represented the nearest equivalent in 1983. Strictly Matthew was a programmer, but as often seems to be the case (the OS user interface and the WWW being prime examples) early uses of computer technology, including in games, were driven by programmers. Mathew is best known for his work on Manic Miner and Jet Set Willy, for the Sinclair ZX Spectrum. Both represented early examples of the platform game genre.

Matthew's games demonstrated that playability was of high importance along with an understanding of the capabilities of the destination platform and how theses can be harnessed in creative and innovative ways. One example of Matthew applying this is the use of in-game sound in Manic Miner, it was the first Spectrum game to include in-game sound by making clever use of alternating CPU attention between game and sound.

Paul Woakes

Paul Woakes gets the first developer and concept credit for probably the game I played the longest - Mercenary. I played it on the ZX Spectrum, but it was available for several platforms. Produced in 1985 Mercenary was the first full 3D game, and first open world game, I ever played. Conceptually and technically it pushed some boundaries (particularly on the Speccy), delivering a unique gaming experience that made it stand out from the flat linear game play that was more common at the time.

Looking purely at game play (and not at 1980s technology limited graphics) Mercenary implements several of the approaches we still see today in open world games, including interactions with NPCs that push the story along and direct the player. I see Paul as a pioneer of 3D open world games.

Robin and Rand Miller

One of the best games I never completed was MYST, designed by Robin and Rand Miller and released in 1993. From a technical point of view it made innovative use of what was in effect a system of hyperlinks, and overcame limitations in the real-time 3D capabilities of the time by making innovative use of pre-rendered static images and animated sequences. The visual design was fantastic and combined with the slowly unfolding story and interlinking puzzles results in an immersive believable 3D world. Although there is no threat of violence ever in the game, the haunting loneliness, ambience and surreal landscapes always had me "looking over my shoulder".

For me this game really stands out as an example of designers Robin and Rand Miller being able to think of absolutely everything while demonstrating a high level of creativity and originality - a complex story that must be revealed in parts, complex puzzles, visual style, architecture, game play, game mechanics, use of available technology... - and how it all must come together to make a seamless whole.

Common Attributes

There are some schools of thought that suggest it is possible to "bottle excellence". That if we knew the ingredients of excellence we could teach anyone to achieve it. What attributes then do these four game designers demonstrate that I can learn from?
  • Creativity - leading to originality
  • Understanding of the available technology - in order to innovate with it and to push its boundaries
  • A holistic view of the whole creation - seeing both the whole and the details and how they fit together
  • Never giving up - because nothing ever gets finished if you do
Thanks guys :-)


Tuesday, 10 April 2012

Getting creation event coordinates for Game Maker

I am currently getting into using Game Maker for games development, and am beginning to use 'timelines' to initiate the creation of 'enemy' object instances.

Two of the parameters needed in the object instance creation event are the X and Y coordinates for the object's creation. This is very easy to input, but only if you know the intended pixel coordinates off the top of your head, which is less easy to simply guess at, and for some games may need something more precise than a guess.

One way to find out these coordinates is to keep reverting back to the 'room' and hovering your mouse over the grid. As you do this some digits in the bottom left of the screen will tell you the nearest grid point X and Y to where your mouse is hovering. You could make a mental note, then revert back to the timeline and input the digits.

Personally, I find this annoying and fiddly.

So, to save me some annoyance, and speed up my development, I have produced a couple of game screen coordinate reference grids that help me. All you do is print them out and keep them handy.

My guess is that if they help me, they might help you, in which case you can download the game screen coordinate reference grids in PDF format here.

Please note these are released under a creative commons license.

Happy game developing.

Monday, 9 April 2012

Getting used to code free game development

Not too long ago I began a games design course to formalise and extend my knowledge and skill in this area of interactive media. The interactive media of my earlier career has evolved over the last decade into what I recognise are two distinct areas. While web design has been around for longer than that, it's earlier "1.0" incarnation was barely able to support what might be termed "interactive media", which back then was pretty much the sole domain of CD ROMs. With the development of Broadband, faster computers, and browser technology, what used to be delivered on CD or DVD is now easily obtained online - so that now interactive media = web design (to a great degree). The other direction of the interactive media industry then, still delivered on hard media, is Games. Since I know web design and Flash fluently, I decided to make the move in the direction of game.

The introductory part of the course, like many courses, assumes little or no knowledge. So we are using Yoyo's Game Maker as the initial authoring tool to learn basic development concepts. Powerful though Game Maker is, I do find the "code free" development slightly frustrating. I finally find myself at the other end of the ladder than I was 13 years ago. Back then I would have given anything to be able to build games, or any complex interactive media, without having to write a line of code. Since then I have got down to it and learned a great deal of ActionScript and such like over the years, and now find the coding aspect logical and sensible. Now I am forced to use a GUI to drag icons around to make "code" I find it frustrating, but am getting used to it.

Take this example for instance:


The visual equivalent took a bit more thought to drag together, than the ActionScript based syntax I am now used to. It's partly because of being unfamiliar with where to look for the draggable items, and partly because it would just be quicker to type.

I laugh to myself because now I finally understand what my coding whiz brother, and others like him, were thinking when I took delight in code free authoring environments all those years ago. They found them slow in comparison to coding by hand. And now... so do I.

Does this mean I have arrived?

Meanwhile, I am getting used to Game Maker, and I understand I am able to code by hand if I want to so I am happy to recommend this excellent product. Tally ho!

Friday, 3 February 2012

Normal Maps of Coins Part 2

In my last post I produced a normal map of the side of a British pound coin. It was an early attempt at following this normal map tutorial, and the results were passable. But on evaluating the results I also identified some fine tuning I could make to my own technique at the photograph stage to make the edges of the raised areas sharper. This was the result.



On this occasion I did increase the angle of the light, holding it higher above the coin to reduce the shadow length, and as you can see this results in much sharper edges. The benefits of a sharper normal map are instantly visible in the 3D render below.

Unlike the pound coins, which needed a grime effect adding to help define the grooves, the ten pence texture is a shiny metal, with details visible purely from the shape information held in the normal map. Every scratch, dent and line you see here is from the normal map, making it look much more real.

In this image the two pence coin uses the same photos the normal map was generated from, though put through a different process, to create dirty areas and reflective areas on the coin to mimic age and wear.


Full instructions in a future post (when I have more time).

Friday, 27 January 2012

Normal Maps from Photos

Normal mapping is a vital part of 3D modelling and rendering these days. In some cases it take hours off your modelling time, and in others hours off your rendering time (and sometimes both).

A while ago I came across this tutorial about making normal maps from photos. I finally got round to trying it.

Introducing the fruits of my labours - this example of mine is the side of a well worn pound coin.


You don't need Photoshop to do this, and to prove it I used the GIMP image manipulation program to make the normal map, and then applied and rendered in Carrara below.


You can see from this render that it works, but some of the edges need to be sharper.

A brief critique of this attempt shows the angle of the light source was too low when photographing the coin, making long shadows, and positioning the light source slightly higher would shorten the shadows and give sharper less buttery results, but having tested it using the 3D preview mode in the GIMP Normal Map Filter, it isn't half bad, and much quicker than trying to build a high res mesh, or digitally painting a height map for conversion to a normal map using tools like the Nvidia Normal Map Filter.

For some objects you really should give this a try.

Of course, even this early attempt is usable if supported by other channels such as shine and highlight (specular) using a grayscale map based on the same photos as the normal map. I also used the same grayscale map to mix two shades of coin colour to show a diffrence where dirt gets ingrained and where it gets rubbed off and used the same map again to give two levels of reflection because dirt is not as reflective as metal. Combining all these with the normal map brings a whole different level of realism.


I'll explain how I used the same photos as the normal map to make the grayscale specular map that I also used for reflection and grime in a future post.

Tuesday, 18 October 2011

Game Development - High Score Leader Boards in Flash

One way of increasing the repeat appeal of a game, particularly for 1 player games, is to include a leader board of high scores. This gives the player an additional goal of beating their previous best score, allowing them to compete with themselves, and other players, even if the game has only 1 player mode.

As long as your game stores the player's score under the variable "score" this example should provide a good starting point for your own leader board or high score board.

In this example I am using ActionScript 2.0 in Flash.

The Code

The code for this is split into 3 parts. First we create a multidimensional array for keeping the scores and player signatures. Second, we store the score from the game, third we create the leader board that transfers data in and out of the array.

Part 1 - Create a Multidimensional Array

In my game the leader board only shows the top 10 scorers. For each one it displays the score and a 3 character signature from the player.

Before we can store data we need to create the place to store it. In this case I am using a multidimensional array. Multidimensional because I want to store 10 elements (1 for each of the top 10) with 2 data elements (score and signature) per player. Doing it this way allows me to sort them later based on score so I can display them from highest scorer to lowest scorer.

My approach was as follows:

/*NEW ARRAY*/
/*Make a new array object*/
var leaderboard_array:Array = new Array ();
/*'Push' data elements onto the array*/
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});
leaderboard_array.push ({initials:"---", score:"0"});

This code must run only once, run it again and you will add to the end of your array, eventually making it huge.

In effect we create an array of 10 elements, that each contain an array of 2 elements. An array within an array. Using the approach I have, where I have named each 'sub'-element "initials" and "score" means that later I can refer to these directly by name - which makes coding a bit easier to do and debug.

My new array includes pre-coded default values, this means something will display the first time and we don't get a blank leader board.

Part 2 - The Game

Your game is your own. The important thing is that you store the players "score" at the end of the game.

Because the my_array.sort(Array.NUMERIC)in Flash does not work correctly (see here), we cannot use strict datatyping  when we define our variables. So, when you first define the "score" variable, all you need to do is:

var score = 0;

Don't do:

var score:Number = 0;

Or the code won't work later, when we have to treat "score" as a string for sorting.

When the game is over, just make sure you store the player's score in the "score" variable, e.g.:

score = endgamescore;

Part 3 - The Leaderboard

At this point we have an array, and a "score". In this part of the program we need to do the following as essential elements.

a. Test whether the player's latest "score" is greater than the lowest score on the current leader board.
b. If it is, allow the player to input a 3 character signature and store it, along with the "score" in the array replacing the previous lowest score.
c. Sort the array by score so each one is listed in order of greatness.
d. Display the contents of the array in text box to show the leader board to the player.

There is more to it than that, especially since sorting numerically in Flash is not actually possible by direct means - I have gone into detail on that on another post - so much of the code is required to solve that problem.

The following code relies on the stage containing:

1. A text input box with the instance name "initials_txt"
2. A button with the instance name "button_btn"
3. A dynamic text box with the instance name "lb_txt"

The code is then as follows:

/* vars */
/* strict datatyping is off for score and sortscore in order to sort it due to restriction in Flash */
var sortscore = 0;
var initials:String = "";
/*set character limit on input text*/
_root.initials_txt.maxChars = 3;
/*PRE-POPULATE LEADERBOARD WITH CURRENT DATA FROM ARRAY*/
for (var i = 0; i < leaderboard_array.length; i++) {
    _root.lb_txt.text += leaderboard_array[i].initials + " " + leaderboard_array[i].score + "\n";
}
/*ADD NEW SCORE ON SUBMIT*/
_root.button_btn.onPress = function () {
    /* get player name value*/
    initials = _root.initials_txt.text;
    /*convert score to decimals ready for correct sorting*/
    sortscore = score / 10000;
    /*convert score values in array to decimals ready for correct sorting*/
    for (var i = 0; i < leaderboard_array.length; i++) {
        leaderboard_array[i].score = leaderboard_array[i].score / 10000;
    }

    /*sort current board by score - low to high*/
    leaderboard_array.sortOn ("score");
    /*if player score is higher than lowest score on board, replace it with player score and name*/
    if (sortscore > leaderboard_array[0].score) {
        _root.leaderboard_array[0].initials = initials;
        _root.leaderboard_array[0].score = sortscore;
    }
    /*sort again to position the new score and initials correctly in order compared to other scores in array*/
    leaderboard_array.sortOn ("score");
    /*convert all the 'decimaled' scores back again to real scores*/
    for (var i = 0; i < leaderboard_array.length; i++) {
        leaderboard_array[i].score = leaderboard_array[i].score * 10000;
    }
    /*reverse the order of the array to show scores from high to low*/
    leaderboard_array.reverse ();
    /*clear existing text from the leader board text box*/
    _root.lb_txt.text = "";
    /*print new array content to the leader board text box*/
    for (var i = 0; i < leaderboard_array.length; i++) {
        _root.lb_txt.text += leaderboard_array[i].initials + " " + leaderboard_array[i].score + "\n";
    }
};

That's the main thrust of it - read the comments in the code to see what each lump of code is doing. Of course there is scope to develop on this yourself, but I hope this helps. Happy leader board-ing.

Friday, 17 June 2011

Generating QR Codes from the Google Chart API

Quick Reference (QR) Codes are a type of Matrix Barcode capable of storing much more information than your normal stripy barcode.

Many organisations have taken to using QR codes as part of an integrated marketing campaign to store web page URLs, allowing users to capture the 'barcode' on their mobile phone cameras in order to visit the site in a quick and easy fashion.

QR Codes from Google Chart API

The Google Chart API has, among other things, the facility to generate QR codes of all types, encoding within them text, binary data or Kanji strings that you define - up to the maximum data limit of a QR code.

The Google Chart API is very simple to understand and returns a PNG file in response to the parameters you set.

Below I have a JavaScript/HTML implementation of the Google Chart API, that returns a QR code based on the text you input.

Generate a QR Code - JavaScript Implementation of Google Chart API











QR Code Generator Source

The source code for my JavaScript implementation above:



Happy QR Code Generating.

Saturday, 14 May 2011

Editing Vado HD Video With Premiere Elements 7

If like me you have had some frustration trying to get Premiere Elements to work with VADO HD video, without hanging on import, you may find this solution helpful.

When for a recent birthday I was the glad recipient of a new VADO HD pocket video camera, and a new sealed Premiere Elements 7, I was excited to get editing some footage. However I quickly ran into trouble - when importing the VADO footage into Elements it would either hang, or if it did import would apparently have no picture. Worse, because of the way the Elements video library previews video assets from all your projects by default, Elements would fail to start up and hang - purely because some VADO HD footage was in the library.

If Premiere Elements won't start because of a dodgy video file in the library

First, if Elements won't start, or hangs, because you have some incompatible footage in the library the simplest cure is to rename the suspect file, or rename the folder it is in, before you start elements. This will break the link Elements has to the file. Then Elements will start properly and give you a 'file not found' icon where the video thumbnail once was in the library. At this point you can simply click on it in the library and delete it.

Making Premiere Elements read VADO HD video files

In trying to solve this I have tried 2 conversion methods (one using Super, and another using Prism), but either of those means a laborious process of mass conversion, and you end up with duplicate files in different formats, and the converted files are either much larger than the originals, or a lower quality I found.

The best solution was simply to install the K-Lite Codec Pack. The installer checked for conflicting codecs as it went along, giving me the option to remove them automatically (which I did). I used the advanced installer option so I could choose what to install, and selected the "lots of stuff" option so I got pretty much everything - including the all important h.264.

Once installed I ran Premiere Elements, imported a native unconverted VADO HD video file and added it to the timeline with barely a pause in the action.

Forget laborious file conversion - try installing the K-Lite Codec Pack before you do anything else.

Still stuck?

If you still have problems you may find the following helpful:

Batch converting VADO HD
Handbrake Video Transcoder
Converting Video for Premiere

Friday, 29 April 2011

Convert Flash to HTML5 with Adobe Wallaby

.NET magazine reports this month that Adobe has released a "Flash-to-web-standards converter" called Wallaby, that basically takes your FLA file and spits out standards compliant HTML5 with accompanying JavaScript.

I must say I was waiting for Adobe to make a move like this ever since Apple got the mardies and decided to not support the Flash Player on its mobile devices. But I thought it might be a feature of CS6, I didn't expect it to be a free Adobe AIR app that I could download today.

.NET quotes senior product manager at Flash Professional as saying "Wallaby's initial focus is on converting banner ads and simple animations to HTML5, to cater for iOS, but that future development will be driven by consumer requirements..." buy .NET for more info.

So, while not expecting great shakes for some of my more advanced Flash work, I can't wait to see what it can do... I'm going to have a play.

Saturday, 9 April 2011

Experimenting with Sound in Flash - DJ Music Mixer


As soon as I realised the possibilities available with Sound Objects in Flash I realised that you could write a simple sound mixing app using ActionScript.

I started this experiment ages ago, but ran into a problem with the sound I couldn't solve straight away. 18 months later I remember it exists and blow the dust off to find the problem still waiting for me.

Just in case any one else has struggled with the same problem... I now have the solution, or at least know why that particular approach wouldn't work and have an alternative.

Once you set up a Sound Object you can either use attachSound to connect an embedded sound from your document Library, or you can use loadSound to load in an external MP3 file. But... and this is where I went wrong... you can't do both. In other words, if the first time you initialise the sound object you use attachSound you can't later change the sound using loadSound and expect it to behave normally. At least that was my experience.

My experimental app was a 2 channel audio mixer that used 2 Sound Objects, one for each channel. The mixing was done very simply by reducing the volume of one Sound Object while simultaneously increasing the volume of the other. So far so good.

However, for the Sound Objects to properly initialise, (and therefore the volume control code work properly) they needed to have a sound loaded into them straight away. The most obvious solution to me was to use attachSound to connect a sound embedded in the movie. So I made a couple of MP3s of 0 second duration and used those embedded within the app. Fine, the Objects initialised OK.

However, to be useful you need to be able to load external MP3s in, or it's only a 2 song show. And that's where the problem arose, because I would need switch from using attachSound to loadSound after the object initialised, and all of a sudden the volume control stops working as expected.

And that's what stumped me. It was only coming back with fresh eyes that allowed me to spot this discrepancy.

So, how to overcome it?

Simples - use loadSound from the first, but get Flash to load a non-existent sound by getting it to load nothing (e.g. ""). Sure, Flash will error, and complain it can't find the file, but the Sound Object will still initialise correctly - and the error is only visible when you test the movie from within the authoring software, not once exported.

Hey presto, when I load an external sound it all works, because I used loadSound all along and didn't change method later on. My music mixing app finally works.

It's possible there are other factors or other solutions - happy to hear about them, but that's how I got round it.

If it helps, happy to help.

Saturday, 2 April 2011

Graphically Displaying Yahoo Weather API Data in Flash



In my last post I looked at querying the Yahoo GEO and Weather APIs from within flash in order to return an XML file containing weather and forecast information.

Last time I simply pulled out the location and the weather condition text that gave a general description of the current weather. But actually the XML contains many more items than that. One of which is the prevailing temperature of the location being queried.

Displaying the temperature as text is relatively easy but you can also be more graphic, as in my virtual thermometer above.

In this prototype I am simply using the temperature data, which Yahoo provides as an integer, to determine the length of the 'mercury' in the thermometer.

How it was done

The Graphics

First I made all the pretty graphics in Fireworks (but you could use Photoshop, Paint.net, PhotoPlus etc.), and imported the assets into Flash. The important thing is that your scale (that's the Celcius and Farenheit rulers are correctly in line with each other, and the increments are spaced evenly on each scale).

To do this you need to understand the following:

-40C is the same as -40F (that's where the two scales meet)
0C is the same as +32F
+50C is the same as +122F

On that basis you should be able to construct C and F scales that line up the way they should. I did it by making two the same and then scaling the F scale smaller vertically so that -40 F and 122 F lined up with -40 C and 50 C respectively.

I also chose to run my scales from -40C to +50C because using the Yahoo Weather API I needed a scale that would reasonably take all global temperatures. I figure that somewhere might get close to -40C and somewhere might get up to +50C. If it turns out my scale isn't big enough I can always ammend it.

The 'Mechanics'

Once the graphics are in Flash I create a small red rectangle for the 'mercury' and turn it into a MovieClip (press F8) with the registration point at the bottom left, and with the instance name "liquid_mc". Then I create a transparent rectangle for the tube in which the 'mercury' travels and turn it into a MovieClip with the instance name "tube_mc" - this needs to be exactly the same height as the distance between the lowest temperature on your graphical scale (in my case -40C) and the highest temperature (in my case +50C) - for me this turned out to be 360 pixels, but it will vary depending on the size and shape of your graphical representation of the scale.

I place the two MovieClips on top of the graphic in the right place at the bottom of the graphical glass tube so when the the 'mercury' grows it will grow up from the bottom.

Then I select the graphic, the "tube_mc" and the "liquid_mc" and turn them all into a MovieClip with the instance name "thermometer_mc", so that "tube_mc" and "liquid_mc" are inside "thermometer_mc".

Finally, create a button, and add it to the stage with the instance name "submit_btn". Users will need to press this to run the query of the Yahoo API and display the result.

The Code

Then I create a new layer, give it the name 'actions' (so all my code is neatly in one place), and put in the following actionscript. Read my comments in the code to see what is happening:


stop ();
/*Thermometer*/
/*calculate the pixel height of 1 degree c by dividing the height of the thermometer tube by the number of degrees c it covers*/
var degree:Number = _root.thermometer_mc.tube_mc._height / 90;
/*calculate zero - because our thermometer starts at -40C we use this to ensure future calculations take account of this fact*/
var zero:Number = degree * 40;
/*Accessing the Yahoo API to find out the weather in any location using postcode and country code*/
/*set the search terms as variables, you can pull these from user input with some different ActionScript */
_root.submit_btn.onPress = function () {
var zip = "SW1A 1AA";
var country = "UK";
/*Find the WOEID*/
woeidXml = new XML ();
woeidXml.ignoreWhite = true;
/* run the loadWoeid function when the XML file loads that contains Yahoo's reply to our query below*/
woeidXml.onLoad = loadWoeid;
/* ASK QUESTION 1 - query the Yahoo API using YQL and the search terms above */
woeidXml.load ("http://query.yahooapis.com/v1/public/yql?q=select%20woeid%20from%20geo.places%20where%20text%3D%22" + zip + "%2C" + country + "%22&diagnostics=true");
/* this function will run when the XML file loads that contains Yahoo's reply to our query */
function loadWoeid () {
/*parse the XML response and store the woeid value as a variable in Flash called 'woeid'*/
woeid = woeidXml.childNodes[0].childNodes[1].childNodes[0].childNodes[0].childNodes[0];
/*find the WEATHER from the WOEID just gathered*/
/* we nest this function for question 2 within the function for question 1 because doing it this way means that question 2 is not asked until question 1 has an answer*/
weatherXml = new XML ();
weatherXml.ignoreWhite = true;
/* run the loadWeather function when the XML file loads that contains Yahoo's reply to our query below*/
weatherXml.onLoad = loadWeather;
/* ASK QUESTION 2 - query the Yahoo Weather API using the woeid we found out in question 1 above */
weatherXml.load ("http://weather.yahooapis.com/forecastrss?w=" + woeid + "&u=c");
/* this function will run when the XML file loads that contains Yahoo's reply to our query */
function loadWeather () {
/*parse the XML response and store the current temperature condition value as a variable in Flash called 'temp_xml'*/
temp_xml = weatherXml.childNodes[0].childNodes[0].childNodes[12].childNodes[5].attributes.temp;
/*set current temperature variable from XML*/
var temp_c:Number = temp_xml;
/*set height of the thermometer liquid_mc graphic based on the temperature extracted from the XML*/
_root.thermometer_mc.liquid_mc._height = (temp_c * degree) + zero;
}
}
};


As you will see, this is virtually the same code as in my previous post, the main difference is how we use the extracted data to change the height of a MovieClip that represents the 'mercury' in the thermometer. To find the temperature of a different location simply change the values of zip and country on lines 10 and 11.

I went a bit further (not explained in this post) and put in some text input fields so that the user can define their own location (maybe I will get time to explain that in a future post).

Meanwhile, happy temperature... er... displaying.

Monday, 21 March 2011

Finding the Weather with YQL and the Yahoo API

I spent some of this weekend examining the potential of the Google API for finding out the weather in my area. My long term aim is to include some nod to local weather in a Flash app I am working on. While the Google API was easy to tap into (see here) it is not very well documented and apparently unofficial and may change or vanish without warning (see discussion here) - which wouldn't bode well for inclusion in an app.

It was Jason Emerick's blog that pointed me towards the Yahoo API as an alternative with better documentation and official support. Now I have always been a fan of Google over Yahoo, but needing reliability I sloped over to Yahoo and revived my dormant account. It wasn't long before I was utterly convinced that Yahoo have an excellent API with excellent support, and a terrific console to help you try out your queries and test the results.

Differences between getting Google weather and Yahoo weather

While powerful, the Yahoo API didn't give me the weather information I was after with quite the same ease as the Google API. With the Google API all you needed to do is call the API URL and append your location to the end:

http://www.google.com/ig/api?weather=london,uk

The results are XML you can parse using your chosen language (in my case ActionScript).

Yahoo on the other hand isn't quite as straightforward (though much better once you get the hang of it). This is because you can't directly query Yahoo's weather API using your chosen location as you can with Google. Yahoo instead requires you to specify the WOEID (Yahoo's proprietary "Where On Earth ID") of the location you want to know the weather for.

Once you know the WOEID of the location, finding the weather for that location is as simple as:

http://weather.yahooapis.com/forecastrss?w=44418&u=c

WOEIDs appear to be an invention of Yahoo for identifying locations. Actually they are a really good idea, as it means your query will always work, even when places and names change.

The challenge is, of course, that most people won't know what the WOEID for their location is and so won't be able to use it to find out the weather in their area. I don't know my WOEID, that's for sure.

So we have to first find out our WOEID from our known location. You can do that like this:

http://query.yahooapis.com/v1/public/yql?q=select%20woeid%20from%20geo.places%20where%20text%3D%22SW1A%202AA%2Cuk%22&diagnostics=true

The Yahoo API console is very helpful in letting you experiment with the queries, and producing URLs like the one above for you to call in your code.

So knowing that with 2 questions I can still get the information I need from Yahoo, I felt more confident pressing ahead with the Yahoo API with its better documentation and promise to give 6 months notice to any changes. A far cry from Google's relative silence on the issue with their unofficial weather API.

Using ActionScript to query the Yahoo geo and weather APIs

So ultimately I have to ask 2 questions of Yahoo with my ActionScript. First - what is the WOEID for my location given as postcode, country? Second - what is the weather forecast for this WOEID?

For question 1 my ActionScript will use this query via the Yahoo YQL API to find out the location's WOEID:

http://query.yahooapis.com/v1/public/yql?q=select%20woeid%20from%20geo.places%20where%20text%3D%22SW1A 2AA%2Cuk%22&diagnostics=true

For question 2 my ActionScript will simply reference Yahoo's weather API using the WOEID from question 1 as a query term, resulting in an XML file containing weather information for the location represented by that WOEID:

http://weather.yahooapis.com/forecastrss?w=26355493&u=c

The trick with the ActionScript is to ask the questions in the right order, and to write your code so question 2 is not asked until it has the answer to question 1 (else you won't get a proper reply and your ActionScript won't get the XML it is expecting and will return 'undefined' where you were expecting the weather status).

Here's my solution, read the comments to see what I am doing there:


/*Accessing the Yahoo API to find out the weather in any location using postcode and country code*/
/*set the search terms as variables, you can pull these from user input with some different ActionScript */
var zip = "SW1A 2AA";
var country = "uk";
/*Find the WOEID*/
woeidXml = new XML ();
woeidXml.ignoreWhite = true;
/* run the loadWoeid function when the XML file loads that contains Yahoo's reply to our query below*/
woeidXml.onLoad = loadWoeid;
/* ASK QUESTION 1 - query the Yahoo API using YQL and the search terms above */
woeidXml.load ("http://query.yahooapis.com/v1/public/yql?q=select%20woeid%20from%20geo.places%20where%20text%3D%22" + zip + "%2C" + country + "%22&diagnostics=true");
/* this function will run when the XML file loads that contains Yahoo's reply to our query */
function loadWoeid () {
/*parse the XML response and store the woeid value as a variable in Flash called 'woeid'*/
woeid = woeidXml.childNodes[0].childNodes[1].childNodes[0].childNodes[0].childNodes[0];
/*test the value we have stored with a trace*/
trace (woeid);
/*find the WEATHER from the WOEID just gathered*/
/* we nest this function for question 2 within the function for question 1 because doing it this way means that question 2 is not asked until question 1 has an answer*/
weatherXml = new XML ();
weatherXml.ignoreWhite = true;
/* run the loadWeather function when the XML file loads that contains Yahoo's reply to our query below*/
weatherXml.onLoad = loadWeather;
/* ASK QUESTION 2 - query the Yahoo Weather API using the woeid we found out in question 1 above */
weatherXml.load ("http://weather.yahooapis.com/forecastrss?w=" + woeid + "&u=c");
/* this function will run when the XML file loads that contains Yahoo's reply to our query */
function loadWeather () {
/*parse the XML response and store the current weather condition value as a variable in Flash called 'condition_xml'*/
condition_xml = weatherXml.childNodes[0].childNodes[0].childNodes[12].childNodes[5].attributes.text;
/*parse the XML response and store the current weather place name value as a variable in Flash called 'place_xml'*/
place_xml = weatherXml.childNodes[0].childNodes[0].childNodes[6].attributes.city;
/*test the values we have stored with a couple of traces*/
trace (condition_xml);
trace (place_xml);
}
}


And that's a wrap. Ideally I wanted to get a single answer from Yahoo by linking the 2 questions in their API, but that proved difficult using just YQL because Yahoo would not provide weather data using YQL unless you knew the location (another apparently random code different again to the woeid) or you provided a US zip code (so no good to us Europeans). So I settled on this 2 stage solution that works for me.

Bugs or traits include being able to swap where I input a postcode with the name of a city, and you still get working results from Yahoo provided it has heard of the city.

Anyway, I know how I will use this, so if you have a use for this happy coding.

Addendum

Here's an implementation of the above code that takes user input and delivers the result.