Create a flash draw game like Line Rider or others – A different approach

Talking about Line Rider game, Flash and Users contributions.

April 21st update: part 2 released
June 15th update: part 3 released

Some days ago I received a very very interesting email from Kevin W. (for Kevin: I can give you more credits if you send me some information about you).

It refers to the Line Rider game creation, with a different approach.

Read carefully:

——

I was reviewing parts three and four of your line rider tutorials today because I had never tried out your collision and reaction techniques for myself, when I found some things I didn’t like.

Mostly, the practice of combining and extracting angles constantly using trig, and therefore the need to compensate for the differences between degrees and radians. I didn’t want to do this because I’ve had a lot of bad luck with my own experiments.

I was reminded of a book on Flash MX game design I saw a few months ago. I remembered the author talking about using vectors exactly for this purpose which eliminates the need for taxing trigonometry functions.

The idea is to keep the x and y speeds separate, and use normalization and scalars to determine the resultant speed.

I think the result is somewhat more efficient and basically keeps track of the ball’s momentum which would lead well into the concepts of sliding required for a sled-based game.

I haven’t yet incorporated your fixes for the ball sticking in the terrain and losing energy, but I would like to know what you think of my approach to this problem.

I hope you take this as gratitude on my part for your tutorials. I started in January of this year using just your blog.

By the way, I am Izy who commented on your posts, the one who made the rocket game with the missile.

—–

Kevin sent a fully commented actionscript too, here it is:

//lineRider_ideas//
//////////////////////////
//Initialize all variables to be used//
//and attach all movieclips.////////////////
//M is the ball, T is the terrain, F is a textfield.
//////////////////////////////////////////////////////////
var m:MovieClip = _root.attachMovie("ball", "ball", 1, {_x:125});
var t:MovieClip = _root.attachMovie("terrain", "terrain", 2, {_x:0});
var f:TextField = _root.createTextField("textfield", 20, 100, 25, 300, 25);
var precision:Number = 1;
var radius:Number = m._height/2;
var sum_x:Number = 0;
var sum_y:Number = 0;
var collisions:Number = 0;
var normal_x:Number = 0;
var normal_y:Number = 0;
var vector_length = 0;
var go:Boolean = true;
//////////////////////////////////////////////////////////
//Create an object to hold speed information and gravity//
//////////////////////////////////////////////////////////
var speed:Object = {x:0, y:0, g:0.25};
/////////////////////////////
//Position certain elements//
/////////////////////////////
m._y = m._height;
t._y = 400;
f.text = "Click and drag to reposition the ball.";
///////////////////////////////
//Allow the ball to be positioned//
///////////////////////////////
_root.onMouseDown = function() {
	go = false;
	speed.x = 0;
	speed.y = 0;
	m._x = _root._xmouse;
	m._y = _root._ymouse;
	m.startDrag();
};
_root.onMouseUp = function() {
	m.stopDrag();
	go = true;
};
////////////////////////////////
//The main part of the code.////
////////////////////////////////
_root.onEnterFrame = function() {
	//Reset variables each frame.
	sum_x = 0;
	sum_y = 0;
	collisions = 0;
	if (go) {
	//Check for collisions by generating points in a slightly different//
	//manner than in your tutorials./////////////////////////////////////
		for (var i:Number = 1; i<360; i += precision) {
			var angle = (i*precision)*(Math.PI/180);
			var spot_x = m._x+radius*(Math.sin(angle));
			var spot_y = m._y-radius*(Math.cos(angle));
			if (t.hitTest(spot_x, spot_y, true)) {
				collisions++;
				sum_x += spot_x;
				sum_y += spot_y;
			}
		}
		if (collisions>0) {
			//Here's the real key to my approach.//////////////
			//First, I find the magnitude of the speed vector//
			//to use as a scalar.//////////////////////////////
			var total_speed = Math.sqrt(Math.pow(speed.x, 2)+Math.pow(speed.y, 2));
			spot_x = (sum_x/collisions)-m._x;
			spot_y = (sum_y/collisions)-m._y;
			//Next, I find the length of a the vector that is the line//
			//between the point of collision and the center of the object.//
			//This is equal to the radius of the circle and so could be replaced
			//by a constant instead.//////////////////////////////////////////////
			vector_length = Math.sqrt(spot_x*spot_x+spot_y*spot_y);
			//Here I normalize the component of the vector by dividing their magnitude
			//by the total length of the two vectors, thereby creating another vector
			//with a magnitude of exactly one.///////////////////////////////////////
			normal_x = spot_x/vector_length;
			normal_y = spot_y/vector_length;
			//Finally, I multiply the normalized vector by the scalar to proportionally
			//achieve the final speed of the ball./////////////////////////////////////
			speed.x += -(normal_x*total_speed);
			speed.y += -(normal_y*total_speed);
		}
		//Add gravity to the speed object and then add the speed to the ball's position.//
		speed.y += speed.g;
		m._x += speed.x;
		m._y += speed.y;
	}
};

Then, Kevin fixed another problem… read:

—–

I noticed that if you change the code

speed.x += -(normal_x*total_speed);
speed.y += -(normal_y*total_speed);

to

speed.x = -(normal_x*total_speed)*friction;
speed.y = -(normal_y*total_speed)*friction;

it will behave almost identically to your part four code without the sticking bug.

—–

What to say? First, I want to thank Kevin for this precious feedback… then, I am going to study this code and eventually use it in future updates of this tutorial.

Here it is his working final movie

And this is the source code.

Any comment?