Category Archives: Flashgame

IDAT102 – Flashgame tweaking

There were a number of things with my flash game that I wasn’t completely satisfied with. One was the music which over time got annoying and inflated the filesize, this was a big problem on my current hosting so I have replaced the audio with a looping 10 second clip of silence so that the workaround still functions and I can re-add music later with ease along with a preloader.

In addition to this I also fixed a bug with the weather feed reading component in which it could not work with negative temperatures or temperatures above 9 degrees by enlarging the range for the substring part and using parseInt. I also updated it to use my new domain.

temp = weather.substring(13,15);
temp = parseInt(temp);

For its continued use I decided to make it so that the effect of temperature could be enabled or disabled by editing the Boolean value of a single variable.

var tempSwitch = false;

if (tempSwitch) {
//temperature finder stuff
} else {
temp = 10;
}

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.

IDAT102 – Flash Game – Timer and play button 0004-0006

Next I added a timer using the code:

var time = 120;
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);
}

This counts down from 120 displaying the current time remaining in countTxt.#

I then created a separate frame for a splash screen at the start of the game. To prevent the game simply playing through the frames as it would an animation, I started the actionscript with stop();. After this I added a button which becomes lighter on mouseover and onclick runs nextFrame();.

I experienced an error when transitioning between frames which I eventually determined to be because of the event listeners on the first frame persisting. To fix this I used:

btnPlay.removeEventListener(MouseEvent.MOUSE_OVER, hoverON);
btnPlay.removeEventListener(MouseEvent.MOUSE_OUT, hoverOFF);

IDAT102 – Flash Game – Movement 0001-0003

To start my flash game I decided to use a simple but effective movement system. The system starts by declaring variables for up, down, left and right which are either true or false. Three event listeners are used to run three functions. The first is masterLoop which runs on the enter frame event; this continually loops at the framerate which has been set, in this case 30. The other functions and corresponding event listener is atKeyDown and atKeyUp which use KeyboardEvent.KEY_DOWN and KeyboardEvent.KEY_UP. Within both of these functions if statements detect if matching keycodes have been pressed and sets the variables to either true or false. The masterloop contains if statements so that if leftIsPressed is true then the new X position of the player becomes the old X position minus the value of the speed variable.

I then added an additional if statement for each to prevent the player being able to exit the stage.
eg:

if (rightIsPressed) {
if(carP1.x < (800 - ballDiameter)){
carP1.x = carP1.x + speed;}
}

The ballDiameter variable offsets the distance preventing any of the player from overlapping the stage.

In later versions the above code is shortened to.

if (rightIsPressed)&&(carP1.x < (800 - ballDiameter)) {
carP1.x = carP1.x + speed;
}

The numbers in the heading of each post such as “0001-0003” indicate the version numbers the post covers.