Tag Archives: Flash

IDAT204 – Progress

From my mockup done using processing I initially decided to switch to using Flash actionscript for the interface but ran into issues with porting my existing code. So I decided to go back to my prototype and implement proper object orientated programming so that I could then use it for the project itself in a language I am comfortable using. I also decided to abandon the use of spherical layout in favour of a cylindrical one. This removed an element of complexity from the application and allowed for infinite lists while retaining the core principles of the design.

From there progress has better then expected and the interface itself is near completion with only the server-side portion of the system presenting any remaining challenge.

Twiter logo circle thing ported to Flash

I have finally ported my twitter feed rotating logo thing into flash. So far it has been made in Processing, php GD generated GIF and flash and attempted in inconsistent HTML-CSS-JS. I have not yet decided what format to try to port to next, HTML5 canvas looks like a dead end for now based on what I have managed to find out and processing.js has some way to go till it supports all the necessary functions.

I have chosen to port this to various formats as practice of different languages without having to redo the core logic of the code that is to import the string, divide the string into each letter, measure the width of each for correct kerning, calculate the position and rotation around the circle, draw the character. This allows me to focus on the differences between the languages themselves.

I may release the source for some of these at some point in the future.

IDAT106- XML Parsing

After several hours I’ve managed to cobble together some actionscript 3 to parse the XML information outputted by the program we are using.

xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
xmlLoader.load(new URLRequest("data.xml"));

function LoadXML(e:Event):void {
xmlData = new XML(e.target.data);
Parse(xmlData);
}

This loads and reads the XML document and sends it to be Parsed.

This is the start of the code seeks out data by its tags and puts it into array. An if statement is used for each tag and i++; is used within the last if to cycle the array index.

var address = new Array(); ...

function Parse(Input:XML):void {
var Children:XMLList = Input.item.children();

for each (var Info:XML in Children) {

if (Info.name() == "address") {
address[i] = Info;
}
...

Inorder to load date information which comes in this form: 4/03/2010 11:53:33, into a form the times can be compared to find the greatest and lowest of all of them I used substring to extract them and then joined the data back together.

Fdetect[i] = temp.substring(11,13) + temp.substring(14,16) + temp.substring(17,19);

if (Fdetect[i] <>
style="font-size:78%;">Earliest = Fdetect[i];
}

If the current value is less then the stored lowest value then it replaces it. This allows me to automatically find the earliest and latest time for all of the data which is useful for visually representing it.

IDAT102 – Flash Game 0036-0040

In another separate .fla I experimented with XML importing and parsing.

I decided to use this BBC weather feed as a source of information to be brought into my game.

I using the example we were given I eventually created this:

//Plymouth temperature finder
var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
xmlLoader.load(new URLRequest("http://newsrss.bbc.co.uk/weather/forecast/13/ObservationsRSS.xml"));
function LoadXML(e:Event):void {
xmlData = new XML(e.target.data);
parseXML(xmlData);
}
function parseXML(xmlInput:XML) :void{
var weather:String = xmlInput.channel.item.description;
temp = weather.substring(13,14);
}

The second to last line places the contents of the description tags within the item tags within the channel tags in the XML document. The last line finds the 14th and 15th character of it, which should be the temperature.

I added a function to calculate the frequency the bonus balls appear:

function bonusRate():void {
if(temp < 4){
intervalBONUS = (Math.random() * 20000) + 5000;
}else{
intervalBONUS = (Math.random() * 30000) + 5000;
}
interval1 = setInterval(ballGenBONUS,intervalBONUS);
}

So if the temperature in Plymouth falls below 4 degrees centigrade then the frequency is more likely to be greater.

This code was later moved to the first frame to allow it to load before the bonusRate() function runs.

When testing the game on my server I encountered another error. Flash does not allow referencing data from different domains then the one the .swf is hosted on.

http://kb2.adobe.com/cps/142/tn_14213.html

A suggested workaround was to use a simple PHP proxy by creating a .php file with:

$dataURL = "http://newsrss.bbc.co.uk/weather/forecast/13/ObservationsRSS.xml";
readfile($dataURL);
?>

and by changing the new URLRequest link to point at the .php file hosted on my server. This solves the problem. For the hand in the game must work independently so I have made the code more resilient by defaulting the temp variable to 10.

Also making use of the temp data I have:

var dotsNumGOOD = 40 + parseInt(temp);
var dotsNumBAD = 8 + Math.ceil(parseInt(temp)/4);

So the hotter the temperature the more balls that can spawn. I took care not to unbalance the game to greatly.

In the first frame I also played around with dates.

var currentDate:Date = new Date();
var Year = currentDate.getFullYear();
if(Year > 2012){
messageTxt.text = "Looks like we made it"
}

IDAT102 – Flash Game 0030-0035

The biggest complaint I got back from people who play tested the game was that bad balls could spawn underneath the player which is unfair. So to prevent this I modified the ballGenBad function to include:

randomX = Math.random() * 800;
randomY = Math.random() * 600;
while((randomX > (ballP1.x - 100))&&((ballP1.x + 100) > randomX)){
randomX = Math.random() * 800;
}
while((randomY > (ballP1.y - 100))&&((ballP1.y + 100) > randomY)){
randomY = Math.random() * 600;
}

If the random number is in the immediate area around the player it will generate a new number until it isn’t.

In addition to this there were a number of other refinements such as seperating the hit tests for each ball type into seperate functions.

IDAT102 – Flash Game – 0026-0030

I first added sounds here but encountered a problem. Whenever a sound was played it would cause the player movement to freeze for a fraction of a second. This negatively impacted gameplay significantly. After attempting many different solutions I eventually found the problem. For some reason when a sound is first played the player must load something inorder to play sounds. Immediatly after finishing playing that sound it stops it. By running a continuous sound loop in the background this never stops, removing the freezing problem.

IDAT102 – Flash Game – 0015-0025

After creating the code for random ball generator, removeral and hit detection it was relatively simple to replicate the code for each of the three types of ball I have decided to use. The variables used had to be changed to prevent conflicts between the various parts of the code.

I added code to freeze the game once the timer reaches zero:

if ((count)-myTimer.currentCount == 0){
finalscoreTxt.text = "You scored " + String(score);
gameState = "finished";
ballP1.alpha = 0.5;
}

The frequency of which the code generates different types of balls was balanced:

setInterval(ballGenGOOD,100);
setInterval(ballGenBAD,500);
setInterval(ballGenBONUS,10000);

The interval time for the bonus ball was later randomised and effected by an external rss feed.

A play again button was added which is moved from outside of the stage once the timer reaches zero:

function playagain(event:MouseEvent):void {
countTxt.text = time;
againTxt.y = 700;
finalscoreTxt.text = "";
ballP1.alpha = 1;
gameState = "started"
score = 0;

var count:Number = time;
var myTimer:Timer = new Timer(1000,count);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
function countdown(event:TimerEvent):void{
countTxt.text = String((count)-myTimer.currentCount);
}

IDAT102 – Flash Game – Hit Detection 0010-0015

I first inter grated simple collision detection into my masterLoop function.

for (var loop2=lag; loop2
if (ballP1.hitTestObject(getChildByName("myBall" + loop2))) {
trace('HIT');
}
}

An error occurred whenever it was testing against a ball that doesn’t exist. I fixed this by adding “if (getChildByName((“myBall” + loop2)) != null)” so that it would only hit test against objects if it could find them.

for (var loop2=lag; loop2
if (getChildByName(("myBall" + loop2)) != null) {
if (ballP1.hitTestObject(getChildByName("myBall" + loop2))) {
trace('HIT');
}
}
}

Later the trace was replaced with:

var currentBall = getChildByName("myBall" + loop2).name;
removeChild(getChildByName(currentBall));

As well as this scoring was added.

IDAT102 – Flash Game – Ball generation S2-0001-0009

I decided to use a separate .fla for this part and to only add it to the main version when it was working properly. For this part to be complete I wanted to be able to address, identify and remove each individual ball separately and for them to automatically expire after a set time period.

I started with simply producing movieclips with the following code:

function mainFunc():void {
var clips;
var newMC:mc = new mc();
addChild(newMC);
newMC.x= Math.random() * 550;
newMC.y= Math.random() * 400;
clips = newMC;
var size:Number = (Math.random() * 20) + 20;
var transp:Number = 1;
clips.height = size;
clips.width = size;
clips.alpha = transp;
}

I then experimented with some code that I had found:

function SelfDelete()
{
rt = new Timer(100, 50);
rt.addEventListener(TimerEvent.TIMER, fadeMe);
rt.addEventListener(TimerEvent.TIMER_COMPLETE, deleteMe);
rt.start();
}
function deleteMe(event:TimerEvent)
{
parent.removeChild(this);
}
function fadeMe(event:TimerEvent):void
{
this.alpha -= 0.01;
}

This function applied to every ball at exactly the same time so I needed to give each ball a unique name so I replaced everthing with:

function mainFunc():void {
var clips:Number;
var myBall:mc = new mc();
addChild(myBall).name = "myBall" + i;
myBall.x= Math.random() * 550;
myBall.y= Math.random() * 400;
var size:Number = (Math.random() * 20) + 20;
myBall.height = size;
myBall.width = size;
myBall.alpha = Math.random() + 0.3;
j = i - 5;
a = "myBall" + int(j);


if (i > 4) {
removeChildAt(j);
trace(i);
}
i = i + 1;
}

This seemed to work at first but then began to continuously output errors.

“RangeError: Error #2006: The supplied index is out of bounds.”

I eventually solved this problem by using getChildByName(“name”) when deleting the ball movieclip.

To fade the balls before deleting them I used:

if (i >= 5){getChildByName("myBall" + (i - 5)).alpha = 0.9;}
if (i >= 6){getChildByName("myBall" + (i - 6)).alpha = 0.8;}
if (i >= 7){getChildByName("myBall" + (i - 7)).alpha = 0.7;}
if (i >= 8){getChildByName("myBall" + (i - 8)).alpha = 0.6;}
if (i >= 9){getChildByName("myBall" + (i - 9)).alpha = 0.5;}
i = ++i;

I later converted this into a loop:

for (var z:Number = 5; z <>= z){getChildByName("myBall" + (i - z)).alpha = ((dotsNum - z)/dotsNum) ;}
}
i = ++i;

After this I was ready to merge the two .fla files.

IDAT102 – Flash Game – Movement 2 – 0007

While testing the player movement system I discovered that the player, when moving diagonally, exeeded the set speed. This was due to Pythagoras’ theorem. For example, if the horizontal and vertical speed was 10 then the diagonal speed would be 14.14, the square root of 10 squared plus 10 squared.

To resolve this I created 2 new variables, startSpeed to contain the desired speed and diagSpeed to contain the calculated speed that will result in the startSpeed when moving diagonally.

var startSpeed = 15;
var speed = startSpeed;
var diagSpeed = (Math.sqrt((startSpeed * startSpeed)*2))/2;

Into the masterLoop I added:

if ((leftIsPressed && upIsPressed)
(leftIsPressed && downIsPressed)
(rightIsPressed && upIsPressed)
(rightIsPressed && downIsPressed))
{speed = diagSpeed;}else{speed = startSpeed}

It detects if the player is moving diagonally and changes the speed to diagSpeed, if the player isn’t then it stays at or reverts to the startSpeed.