Bouncing an irregular shaped object? (AS2)

Hi,
I have a Flash movie where 2 objects fall from the top of the stage and bounce and then stop (using gravity etc). You can grab the objects and toss them around the stage and they bounce off the walls and off each other (i also added a double click function that opens an external web page). The code works great, but I noticed that it works based on a square bounding box around each object . . . this is fine when I have a square object or icon, but when i have an irregular shaped object, the code assumes and a square boundary around the movie clip. So the objects will bounce off each other, but not in a realistic way.

I would like to change the code so that I can use irregular shapes and even round objects and have them bounce off each other more realistically. I tried using hitTest, but this just caused problems with the gravity.

Any help or examples you can thnk of would be great and I totally appreciate it!

I’ve attached a zip file with a flash file in it . . . take a look!

here is the gravity actionscript that’s on the first frame of my movie:


var gravity:Number = 0.9; //Sets the rate of gravity that the ball falls at
var restitution:Number = 0.6; //Set the restitution, which is how much speed the ball retains after a collision (i.e. if the ball is traveling at 10 pixels per frame and hits the ground, it will then be traveling at 6 pixels per frame)
var friction:Number = 0.9; //Set how much speed the ball retains in the horizontal direction when it touches any other object. This pertains mainly to when it is sliding/rolling on the ground, etc.

stop(); //stop the movie here on the first frame

//look in the ball's and shape's actions for the bulk of the code

and here’s the actionscript on the movieclips themselves (it uses an array to determine which objects bounce off eachother etc) – this was started on the Kirupa forums by Cody who was a great help!:


///////////////////////////////////////////////////
//Bouncing Ball Example                          //
//By Cody/ShadowViper from the Kirupa.com forums //
///////////////////////////////////////////////////

onClipEvent(load) { //onClipEvent(load) for the ball, used to initialize variables and functions.
	var dragging:Boolean = false; //boolean value that tells whether the ball is being dragged by the mouse, true = being dragged, false = not being draggged
	var vel:Object = { x: 0, y: 0 }; //an object that stores the balls x and y speeds
	var pos:Object = { x: _x, y: _y }; //object that stores the current calculated position of the ball
	var old:Object = { x: _x, y: _y }; //object that stores the old position of the ball
	var width:Number = this._width; //the ball's width
	var walls:Array = [_root.wallLeft, _root.wallTop, _root.wallRight, _root.wallBottom, _root.ball]
	//Above array stores the names of all the obstacles that the ball may collide with. Object names MUST BE PRECEDED BY _root.
	var wallsMouse:Array = [_root.wallLeft, _root.wallTop, _root.wallRight, _root.wallBottom, _root.ball]
	//Above array stores the names of all the obstacles that the ball may collide with **WHEN THE MOUSE IS DRAGGING IT**. Object names MUST BE PRECEDED BY _root.
	var maxSpeed:Number = 16; //The maximum amount the ball can move in one turn along EACH (x, y) axis
	
	function bBoxTest(wall){ //function to test whether the ball's bounding box is colliding with anything
		x1 = pos.x; //Left side of the bounding box
		y1 = pos.y; //Top of the bounding box
		x2 = pos.x + width; //Right side of the bounding box
		y2 = pos.y + width; //Bottom of the bounding box
		dir = 0; //set dir as a temporary value to store the calculated direction/side of impact
		if(x2>wall._x && x1<(wall._x+wall._width) && y2>wall._y && y1<(wall._y+wall._height)){ //check to see if the ball is hitting anything in general
		//Do more detailed hit detection
			if(vel.x!=0 || vel.y!=0){ //check whether ball is moving
			
			//if the X OR Y velocity is 0, then the ball is going in one of four directions:
				if(!dir && vel.x>0 && vel.y==0)dir = 1; //moving right, colliding with obstacle's left side
				if(!dir && vel.x==0 && vel.y>0)dir = 2; //moving down, colliding with obstacle's top side
				if(!dir && vel.x<0 && vel.y==0)dir = 3; //moving left, colliding with obstacle's right side
				if(!dir && vel.x==0 && vel.y<0)dir = 4; //moving up, colliding with obstacle's bottom side

				if(!dir && vel.x>0 && vel.y>0){ //check whether both X and Y velocities are greater than 0, ball is moving down and to the right, two options for collision, top and left.
					dx = wall._x - x2; //distance between wall's left side and ball's right side
					dy = wall._y - y2; //distance between wall's top and ball's bottom
					if(vel.y/vel.x<dy/dx)dir = 1; //if the ball is moving in a more predominately right direction or lower down than it is over, then it is colliding with the left side of the obstacle
					else dir = 2; //if it isn't colliding with the left side, then it must be colliding with the top
				}
				if(!dir && vel.x<0 && vel.y>0){ //check whether the X velocity is less than 0 and the Y is greater, ball is moving down and to the left, two options for collision, top and right.
					dx = wall._x+wall._width - x1; //distance between wall's right side and ball's left side 
					dy = wall._y - y2; //distance between wall's top side and ball's bottom side
					if(vel.y/vel.x>dy/dx)dir = 3; //if the ball is moving more up than over or the ball is positioned more up than over relative to the obstacle, it is colliding on the right side.
					else dir = 2; //if it isn't colliding on the right, the only other option is the top.
				}
				if(!dir && vel.x>0 && vel.y<0){ //check whether the X velocity is greater than 0 and the Y is less, ball is moving up and to the right, two options for collision, bottom and left.
					dx = wall._x - x2; //distance between wall's left side and ball's right side
					dy = wall._y + wall._height - y1; //distance between wall's bottom side and ball's top side
					if(vel.y/vel.x>dy/dx)dir = 1; //if the ball is moving more up than over or the ball is positioned more up than over relative to the obstacle, it is colliding on the left side.
					else dir = 4; //if it isn't colliding on the left, the only other option is the top.
				}
				if(!dir && vel.x<0 && vel.y<0){ //check whether the X velocity is less than 0 and the Y is less, ball is moving up and to the left, two options for collision, bottom and right.
					dx = wall._x+wall._width - x1; //distance between wall's right side and ball's left side 
					dy = wall._y + wall._height - y1; //distance between wall's bottom side and ball's top side
					if(vel.y/vel.x<dy/dx)dir = 3; //if the ball is moving more up than over or the ball is positioned more up than over relative to the obstacle, it is colliding on the right side.
					else dir = 4; //if it isn't colliding on the left, the only other option is the bottom.
				}
			}
		}
		return dir; //return the vallue of 'dir' to the caller of the function
	}
	
	
	function collisionReact() { //function to use the values taken from bBoxTest to move the ball
		x1 = pos.x; //Left side of the bounding box
		y1 = pos.y; //Top of the bounding box
		x2 = pos.x + width; //Right side of the bounding box
		y2 = pos.y + width; //Bottom of the bounding box 
		//this function tests for two dir values, dir1 and dir2, this is because if it were to only test for one 
		//collision, a ball colliding with two objects would ignore the second collision
		//the variables used in this function are:
		//dir1, dir2: denotes the side of the object that ball is colliding with in the first and second collisions, respectively
		//dir1Wall, dir2Wall: denotes which index of the object the ball is actually colliding with from the array 'walls'
		
		if( dir1 == 2 ) { //react to collision with the top of an object
			pos.y = walls[dir1Wall]._y-this.width; //set the ball's calculated Y position to be adjacent to the obstacle's top side
			vel.y *= -_root.restitution; //reverse the ball's Y velocity and slow it down some according to the restituion variable
			vel.x *= _root.friction; //apply friction to slow down the ball in the horizontal direction
		}
		else if( dir2 == 2 ) { //if the first collision isn't already a collision with the top of an object, react to collision with the top of an object
			pos.y = walls[dir2Wall]._y-this.width; //set the ball's calculated Y position to be adjacent to the obstacle's top side
			vel.y *= -_root.restitution; //reverse the ball's Y velocity and slow it down some according to the restituion variable
			vel.x *= _root.friction; //apply friction to slow down the ball in the horizontal direction
		}
		
		if( dir1 == 1 ) { //react to collision with the left of an object
			pos.x = walls[dir1Wall]._x-this.width; //set the ball's calculated X position to be adjacent to the obstacle's left side
			vel.x *= -_root.restitution; //reverse the ball's X velocity and slow it down some according to the restituion variable
		}
		else if( dir2 == 1 ) { //if the first collision isn't already a collision with the left of an object, react to collision with the left of an object
			pos.x = walls[dir2Wall]._x-this.width; //set the ball's calculated X position to be adjacent to the obstacle's left side
			vel.x *= -_root.restitution; //reverse the ball's X velocity and slow it down some according to the restituion variable
		}
		
		if( dir1 == 3 ) { //react to collision with the right of an object
			pos.x = walls[dir1Wall]._x+walls[dir1Wall]._width; //set the ball's calculated X position to be adjacent to the obstacle's right side
			vel.x *= -_root.restitution; //reverse the ball's X velocity and slow it down some according to the restituion variable
		}
		else if( dir2 == 3 ) { //if the first collision isn't already a collision with the right of an object, react to collision with the right of an object
			pos.x = walls[dir2Wall]._x+walls[dir2Wall]._width; //set the ball's calculated X position to be adjacent to the obstacle's right side
			vel.x *= -_root.restitution; //reverse the ball's X velocity and slow it down some according to the restituion variable
		}
		
		if( dir1 == 4 ) { //react to collision with the bottom of an object
			pos.y = walls[dir1Wall]._y+walls[dir1Wall]._height; //set the ball's calculated Y position to be adjacent to the obstacle's bottom side
			vel.y *= -_root.restitution; //reverse the ball's Y velocity and slow it down some according to the restituion variable
		}
		else if( dir2 == 4 ) {//if the first collision isn't already a collision with the bottom of an object, react to collision with the bottom of an object
			pos.y = walls[dir2Wall]._y+walls[dir2Wall]._height; //set the ball's calculated Y position to be adjacent to the obstacle's bottom side
			vel.y *= -_root.restitution; //reverse the ball's Y velocity and slow it down some according to the restituion variable
		}
	}		
	
	
	function mouseDragCollide(wall) {
		dir = 0; //set dir as a temporary value to store the calculated direction/side of impact
		oldx1 = old.x; //store old.x in a temporary variable, left side of bnounding box
		oldy1 = old.y; //store old.y in a temporary variable, top of bounding box
		oldx2 = old.x + width; //right side of bounding box
		oldy2 = old.y + width; //bottom of bounding box
		//temporary variables to hold how fast the ball is going, the reason .3 and .6 are used to make them smaller is so that the ball it self can travel faster without traveling straight through something due to it 'never colliding'.
		vely1 = vel.y*.3 
		vely2 = vel.y*.6
		velx1 = vel.x*.3
		velx2 = vel.x*.6
		
		//I'm not going to comment this section very heavily, it is essentially a modified version of the 
		//bBoxTest function. For more explanation, look at that function above.
		if(oldx1<wall._x+wall._width && oldx2>wall._x) {
			/////////////// DIR = 2 // Top Side /////////////////
			if(!dir && vel.y>0 && oldy1+2<wall._y) {
				if((oldy2+(vely1))>wall._y && (oldy2+(vely1))<(wall._y+wall._height)) dir = 2;break;
				if((oldy2+(vely2))>wall._y && (oldy2+(vely2))<(wall._y+wall._height)) dir = 2;break;
				if((oldy2+(vel.y))>wall._y && (oldy2+(vel.y))<(wall._y+wall._height)) dir = 2;break;
			}
			
			/////////////// DIR = 4 // Bottom Side /////////////////
			if(!dir && vel.y<0 && oldy2-2>wall._y+wall._height) {
				if((oldy1+(vely1))>wall._y && (oldy1+(vely1))<(wall._y+wall._height)) dir = 4;break;
				if((oldy1+(vely2))>wall._y && (oldy1+(vely2))<(wall._y+wall._height)) dir = 4;break;
				if((oldy1+(vel.y))>wall._y && (oldy1+(vel.y))<(wall._y+wall._height)) dir = 4;break;
			}
		}
		if(oldy1<wall._y+wall._height && oldy2>wall._y) {
			/////////////// DIR = 1 // Left Side /////////////////
			if(!dir && vel.x>0 && oldx1+2<wall._x) {
				if((oldx2+(velx1))<wall._x+wall._width && (oldx2+(velx1))>(wall._x)) dir = 1;break;
				if((oldx2+(velx2))<wall._x+wall._width && (oldx2+(velx2))>(wall._x)) dir = 1;break;
				if((oldx2+(vel.x))<wall._x+wall._width && (oldx2+(vel.x))>(wall._x)) dir = 1;break;
			}
			/////////////// DIR = 3 // Right Side /////////////////
			if(!dir && vel.x<0 && oldx2-2>wall._x+wall._width) {
				if((oldx1+(velx1))<wall._x+wall._width && (oldx1+(velx1))>(wall._x)) dir = 3;break;
				if((oldx1+(velx2))<wall._x+wall._width && (oldx1+(velx2))>(wall._x)) dir = 3;break;
				if((oldx1+(vel.x))<wall._x+wall._width && (oldx1+(vel.x))>(wall._x)) dir = 3;break;
			}
		}		
		return dir;
	}
	
	
	function mouseMove() {
		//I'm also not going to comment this function very heavily. It is essentially a
		//modified version of collisionReact. Look at that function above if you need clarification
		
		x1 = pos.x; 
		y1 = pos.y;
		x2 = pos.x + width;
		y2 = pos.y + width; 
		
		/////////////// DIR = 2 // Top Side /////////////////
		if( dir1 == 2 ) {
			pos.y = wallsMouse[dir1Wall]._y-this.width;
			vel.y *= -_root.restitution;
			vel.x *= _root.friction;
		}
		else if( dir2 == 2 ) {
			pos.y = wallsMouse[dir2Wall]._y-this.width;
			vel.y *= -_root.restitution;
			vel.x *= _root.friction;
		}
		else if( dir3 == 2 ) {
			pos.y = wallsMouse[dir3Wall]._y-this.width;
			vel.y *= -_root.restitution;
			vel.x *= _root.friction;
		}
		else if( dir4 == 2 ) {
			pos.y = wallsMouse[dir4Wall]._y-this.width;
			vel.y *= -_root.restitution;
			vel.x *= _root.friction;
		}
		else if( dir5 == 2 ) {
			pos.y = wallsMouse[dir5Wall]._y-this.width;
			vel.y *= -_root.restitution;
			vel.x *= _root.friction;
		}
		
		/////////////// DIR = 1 // Left Side /////////////////
		if( dir1 == 1 ) {
			pos.x = wallsMouse[dir1Wall]._x-this.width;
			vel.x *= -_root.restitution;
		}
		else if( dir2 == 1 ) {
			pos.x = wallsMouse[dir2Wall]._x-this.width;
			vel.x *= -_root.restitution;
		}
		else if( dir3 == 1 ) {
			pos.x = wallsMouse[dir3Wall]._x-this.width;
			vel.x *= -_root.restitution;
		}
		else if( dir4 == 1 ) {
			pos.x = wallsMouse[dir4Wall]._x-this.width;
			vel.x *= -_root.restitution;
		}
		else if( dir5 == 1 ) {
			pos.x = wallsMouse[dir5Wall]._x-this.width;
			vel.x *= -_root.restitution;
		}
		
		/////////////// DIR = 3 // Right Side /////////////////
		if( dir1 == 3 ) {
			pos.x = wallsMouse[dir1Wall]._x+wallsMouse[dir1Wall]._width;
			vel.x *= -_root.restitution;
		}
		else if( dir2 == 3 ) {
			pos.x = wallsMouse[dir2Wall]._x+wallsMouse[dir2Wall]._width;
			vel.x *= -_root.restitution;
		}
		else if( dir3 == 3 ) {
			pos.x = wallsMouse[dir3Wall]._x+wallsMouse[dir3Wall]._width;
			vel.x *= -_root.restitution;
		}
		else if( dir4 == 3 ) {
			pos.x = wallsMouse[dir4Wall]._x+wallsMouse[dir4Wall]._width;
			vel.x *= -_root.restitution;
		}
		else if( dir5 == 3 ) {
			pos.x = wallsMouse[dir5Wall]._x+wallsMouse[dir5Wall]._width;
			vel.x *= -_root.restitution;
		}
		
		/////////////// DIR = 4 // Bottom Side /////////////////
		if( dir1 == 4 ) {
			pos.y = wallsMouse[dir1Wall]._y+wallsMouse[dir1Wall]._height;
			vel.y *= -_root.restitution;
		}
		else if( dir2 == 4 ) {
			pos.y = wallsMouse[dir2Wall]._y+wallsMouse[dir2Wall]._height;
			vel.y *= -_root.restitution;
		}
		else if( dir3 == 4 ) {
			pos.y = wallsMouse[dir3Wall]._y+wallsMouse[dir3Wall]._height;
			vel.y *= -_root.restitution;
		}
		else if( dir4 == 4 ) {
			pos.y = wallsMouse[dir4Wall]._y+wallsMouse[dir4Wall]._height;
			vel.y *= -_root.restitution;
		}
		else if( dir5 == 4 ) {
			pos.y = wallsMouse[dir5Wall]._y+wallsMouse[dir5Wall]._height;
			vel.y *= -_root.restitution;
		}
	}
	
}

on(press){ //on(press) event, called when mouse button is pressd over the object
	//set all of the variables that hold the mouses coordinates to the mouse's current position
	oldMouseY = _root._ymouse;
	oldMouseY2 = _root._ymouse;
	oldMouseY3 = _root._ymouse;
	oldMouseX = _root._xmouse;
	oldMouseX2 = _root._xmouse;
	oldMouseX3 = _root._xmouse;
	
	dragging = true; //set dragging as true
}

on(release, releaseOutside){ //on(release, releaseOutside) event, called when mouse button is released over the object or outside of it
	dragging = false; //set dragging as false
	vel.x = ( _root._xmouse - ((oldMouseX+oldMouseX2+oldMouseX3)/3))*2; //subtract the avergage of the last three X positions of the mouse, multiply by 2 and assign as the ball's X velocity
	vel.y = ( _root._ymouse - ((oldMouseY+oldMouseY2+oldMouseY3)/3))*2; //subtract the avergage of the last three Y positions of the mouse, multiply by 2 and assign as the ball's Y velocity
	
	//make sure the ball isn't moving too fast in any direction
	//if it is moving too fast, slow it down along the axis that was moving too fast and then slow it down proportionally along the other axis
	if(vel.x > maxSpeed) { //check whether the X velocity is too high
		percDif = (vel.x-maxSpeed)/vel.x; //find the percentage of difference between the X velocity and the maxSpeed
		vel.x = maxSpeed; //set X velocity down to the maximum
		vel.y *= 1-percDif; //proportionally lower the Y velocity based on the percentage difference between the old X velocity and the maxSpeed
	}
	if(vel.x < -maxSpeed) { //check whether the X velocity is too low
		percDif = (vel.x+maxSpeed)/vel.x; //find the percentage of difference between the X velocity and the maxSpeed
		vel.x = -maxSpeed; //set X velocity up to the minimum
		vel.y *= 1-percDif; //proportionally lower the Y velocity based on the percentage difference between the old X velocity and the maxSpeed
	}
	if(vel.y > maxSpeed) { //check whether the Y velocity is too high
		percDif = (vel.y-maxSpeed)/vel.y; //find the percentage of difference between the Y velocity and the maxSpeed
		vel.y = maxSpeed; //set Y velocity down to the maximum
		vel.x *= 1-percDif; //proportionally lower the X velocity based on the percentage difference between the old Y velocity and the maxSpeed
	}
	if(vel.y < -maxSpeed) { //check whether the Y velocity is too low
		percDif = (vel.y+maxSpeed)/vel.y; //find the percentage of difference between the Y velocity and the maxSpeed
		vel.y = -maxSpeed; //set Y velocity up to the minimum
		vel.x *= 1-percDif; //proportionally lower the X velocity based on the percentage difference between the old Y velocity and the maxSpeed
	}
}

onClipEvent(enterFrame){ //onClipEvent(enterFrame) for the ball, used to run the meat of the code. Runs every frame.
	//reset dir1, dir2 to 0: denotes the side of the object that ball is colliding with in the first and second collisions, respectively
	dir1  = 0; 
	dir2  = 0;
	
	//reset dir1Wall, dir2Wall to 0: denotes which index of the object the ball is actually colliding with from the array 'walls'
	dir1Wall = 0;
	dir2Wall  = 0;
	
	vel.y += _root.gravity; //add gravity to the ball's Y velocity
	pos.x += vel.x; //add the ball's X velocity to it's calculated X position
	pos.y += vel.y; //add the ball's Y velocity to it's calculated Y position
	
	//run a loop which goes through all of the obstacles and checks for collisions
	for(i = 0; !dir1; i++) {
		if(bBoxTest(walls*)) { //if there is a collision, assign values to dir1 and dir1Wall to tell collisionReact how to handle the collision
			dir1 = bBoxTest(walls*); 
			dir1Wall = i;
		}
		if(i > walls.length) break; //if the loop goes past the length of 'walls' (number of obstacles) stop it
	}
	
	//run a second loop which goes through all of the rest of the obstacles and checks for collisions
	for(i = dir1Wall+1; !dir2; i++) {
		if(bBoxTest(walls*)) { //if there is a collision, assign values to dir2 and dir2Wall to tell collisionReact how to handle the collision
			dir2 = bBoxTest(walls*);
			dir2Wall = i;
		}
		if(i > walls.length) {break} //if the loop goes past the length of 'walls' (number of obstacles) stop it
	}
	
	//NOTE: If you get to have too many objects that may be colliding at once, you either 
	//need to add more loops to detect collisions or use a different method.
	
	
	if( !dragging ) { //handle the ball when it ISN'T being dragged
		collisionReact(); //react to previously detected collisions
		
		_x = pos.x; //assign the calculated x position to the actual _x value of the object
		_y = pos.y; //assign the calculated y position to the actual _y value of the object
		
	} else { //handle the ball if it IS being dragged
		vel.x = ((_root._xmouse-width/2)-pos.x)/2; //set the ball's X velocity so that it will move to the mouse's current X position
		vel.y = ((_root._ymouse-width/2)-pos.y)/2; //set the ball's Y velocity so that it will move to the mouse's current Y position
		
		//make sure the ball isn't moving too fast, otherwise it could move straight through things
		if(vel.x>20) {
			vel.x = 20;
		}
		if(vel.x<-20) {
			vel.x = -20;
		}
		if(vel.y>20) {
			vel.y = 20;
		}
		if(vel.y<-20) {
			vel.y = -20;
		}

		old.x = pos.x; //store the current calculated x position as the old x position
		old.y = pos.y; //store the current calculated y position as the old y position
		
		pos.x += vel.x; //add the ball's X velocity to it's calculated X position
		pos.y += vel.y; //add the ball's Y velocity to it's calculated Y position	
		
		_x = pos.x; //assign the calculated x position to the actual _x value of the object
		_y = pos.y; //assign the calculated y position to the actual _y value of the object
		
		//reset dir1, dir2 to 0: denotes the side of the object that ball is colliding with in the first and second collisions, respectively
		dir1  = 0; 
		dir2  = 0;
		
		//reset dir1Wall, dir2Wall to 0: denotes which index of the object the ball is actually colliding with from the array 'walls'
		dir1Wall = 0;
		dir2Wall  = 0;
		
		//run a loop to see if the ball is colliding with anything
		for(i = 0; !dir1; i++) {
			mDC = mouseDragCollide(wallsMouse*); //assign the result of mouseDragCollide(wallsMouse*) to a temporary variable
			if(mDC) { //if mouseDragCollide detects no collision, 0 is returned. This means that if there WAS a collision, mDC would be true and this code would be executed
				dir1 = mDC;
				dir1Wall = i;
			}
			if(i > wallsMouse.length) break;
		}
		
		//same as above loop only for the remaining obstacles
		for(i = dir1Wall+1; !dir2; i++) {
			mDC = mouseDragCollide(wallsMouse*);
			if(mDC) {
				dir2 = mDC;
				dir2Wall = i;
			}
			if(i > wallsMouse.length) {break}
		}
		
		//calculate the mouses new position
		mouseMove();
		
		_x = pos.x; //assign the calculated x position to the actual _x value of the object
		_y = pos.y; //assign the calculated y position to the actual _y value of the object
		
		//cycle the mouse values so the oldMouseX2 becomes oldMouseX3, etc. oldMouseY and oldMouseY become _root._xmouse and _root._ymouse, respectively
		oldMouseX3 = oldMouseX2;
		oldMouseY3 = oldMouseY2;
		oldMouseX2 = oldMouseX;
		oldMouseY2 = oldMouseY;
		oldMouseX = _root._xmouse;
		oldMouseY = _root._ymouse;
		
		//clear the velocity values so that they are ready to be set next frame.
		vel.x = 0;
		vel.y = 0;
	}
}

// this is the code for addign a double click web-link . . . change the URL to whatever you want
on (release) {
if(getTimer()-lastClick < 500){
getURL('http://www.google.com');
}
lastClick=getTimer();
}

Thanks!! I look forward to getting help fixing this!

Hondo311