Flash ball vs ball game concept

This is a prototype sent me by Rory Kamminga.

It’s an unfinished game where you control a blue ball with arrow keys. Your aim is to kick a red ball out of the stage.

Obviously the red ball will try to do the same with you.

The interesting thing is that Rory took the studies of Raman Pfaff’s Physics of an Elastic Collision and its derivated tutorials such as Managing ball vs ball collision with Flash by myself and Elastic collisions by Marijn van Aerle and come out with a good prototype where the red ball is moved by AI.

That’s what Rory says:

Hi Emanuele, I’m a huge fan of your site, and I thought I’d make a contribution in the form of a concept game that’s still in its early stages.
Basically, you control the blue ball with the arrow keys and you have to knock the red ball off the edge. Clicking the mouse resets it.

and

I’m thinking of having several stages, including walls.
I want to have multiple AI balls, but I don’t know how.

So, if you have any clue about multiple AI balls, just give feedback.

The source code is well commented, for your understanding:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//functions
function findAnAngle(xthing, ything) {
	//very basic angle finder..returns value in degrees  
	term = Math.PI/180;
	//degree->radian
	if (xthing<0) {
		t = 180+Math.atan(ything/xthing)/term;
	} else if (xthing>0 && ything>=0) {
		t = Math.atan(ything/xthing)/term;
	} else if (xthing>0 && ything<0) {
		t = 360+Math.atan(ything/xthing)/term;
	} else if (xthing == 0 && ything == 0) {
		t = 0;
	} else if (xthing == 0 && ything>=0) {
		t = 90;
	} else {
		t = 270;
	}
	return t;
}
function doCollision(ball, ball2) {
	dx = ball._x-ball2._x;
	dy = ball._y-ball2._y;
	phi = Math.atan(dy/dx);
	//find the collision angle
	term = Math.PI/180;
	//degree->radian
	//find out the magnitude of the velocities of the two balls
	v1i = Math.sqrt(ball.vx*ball.vx+ball.vy*ball.vy);
	v2i = Math.sqrt(ball2.vx*ball2.vx+ball2.vy*ball2.vy);
	//find out the angle of the velocity vector
	ang1 = findAnAngle(ball.vx, ball.vy)*term;
	ang2 = findAnAngle(ball2.vx, ball2.vy)*term;
	//find the velocities in the new coordinate system
	v1xr = v1i*Math.cos(ang1-phi);
	v1yr = v1i*Math.sin(ang1-phi);
	v2xr = v2i*Math.cos(ang2-phi);
	v2yr = v2i*Math.sin(ang2-phi);
	//find the final velocities in the normal reference frame
	//the x velocities will obey the rules for a 1-D collision
	v1fxr = ((ball.mass-ball2.mass)*v1xr+(ball2.mass+ball2.mass)*v2xr)/(ball.mass+ball2.mass);
	v2fxr = ((ball.mass+ball.mass)*v1xr+(ball2.mass-ball.mass)*v2xr)/(ball.mass+ball2.mass);
	//the y velocities will not be changed
	v1fyr = v1yr;
	v2fyr = v2yr;
	//convert back to the standard x,y coordinates
	_root.ball.vx = Math.cos(phi)*v1fxr+Math.cos(phi+Math.PI/2)*v1fyr;
	_root.ball.vy = Math.sin(phi)*v1fxr+Math.sin(phi+Math.PI/2)*v1fyr;
	_root.ball2.vx = Math.cos(phi)*v2fxr+Math.cos(phi+Math.PI/2)*v2fyr;
	_root.ball2.vy = Math.sin(phi)*v2fxr+Math.sin(phi+Math.PI/2)*v2fyr;
}
//move ball
MovieClip.prototype.move = function() {
	this.onEnterFrame = function() {
		//check for collision with walls, done pretty quick
		//the balls might get stuck in the walls if they move too fast
		if ((ball._x<45) or (ball._x>579)) {
			bdead = true;
		}
		if ((ball._y<40) or (ball._y>424)) {
			bdead = true;
		}
		if ((ball2._x<45) or (ball2._x>579)) {
			b2dead = true;
		}
		if ((ball2._y<40) or (ball2._y>424)) {
			b2dead = true;
		}
		//move 
		this._x += this.vx;
		this._y += this.vy;
	};
};
_root.onLoad = function() {
	ball.mass = 20;
	ball.vx = 0;
	ball.vy = 0;
	ball.move();
	ball2.mass = 20;
	ball2.vx = 0;
	ball2.vy = 0;
	ball2.move();
	coll = 0;
	friction = 0.1;
	gws = 0;
	ba = 0.8;
	nmea = 0.8;
	radius = 15;
	bdead = false;
	b2dead = false;
};
_root.onEnterFrame = function() {
	//we check for collision using the distance between the two centre points of the balls
	//if that distance is smaller than two times the radius of the balls we have collision
	//the radius is hardcoded
	distance_x = Math.abs(ball._x-ball2._x);
	distance_y = Math.abs(ball._y-ball2._y);
	distance = Math.sqrt(distance_x*distance_x+distance_y*distance_y);
	//make sure the balls don't get stuck into eachother
	if (distance<=30 && coll == 0) {
		coll = 1;
		doCollision(ball, ball2);
	} else if (distance>30) {
		coll = 0;
	}
	//Player One controls 
	if (Key.isDown(Key.RIGHT) && ball.vx<10) {
		ball.vx += ba;
	}
	if (Key.isDown(Key.LEFT) && ball.vx>-10) {
		ball.vx -= ba;
	}
	if (Key.isDown(Key.UP) && ball.vy>-10) {
		ball.vy -= ba;
	}
	if (Key.isDown(Key.DOWN) && ball.vy<10) {
		ball.vy += ba;
	}
	//Friction 
	if (ball.vx>0) {
		ball.vx -= friction;
	} else if (ball.vx<0) {
		ball.vx += friction;
	}
	if (ball.vy>0) {
		ball.vy -= friction;
	} else if (ball.vy<0) {
		ball.vy += friction;
	}
	if (ball2.vx>0) {
		ball2.vx -= friction;
	} else if (ball2.vx<0) {
		ball2.vx += friction;
	}
	if (ball2.vy>0) {
		ball2.vy -= friction;
	} else if (ball2.vy<0) {
		ball2.vy += friction;
	}
	//Gravity well! 
	if (ball._x>320) {
		ball.vx -= gws;
	} else if (ball._x<320) {
		ball.vx += gws;
	}
	if (ball._y>240) {
		ball.vy -= gws;
	} else if (ball._y<240) {
		ball.vy += gws;
	}
	if (ball2._x>320) {
		ball2.vx -= gws;
	} else if (ball2._x<320) {
		ball2.vx += gws;
	}
	if (ball2._y>240) {
		ball2.vy -= gws;
	} else if (ball2._y<240) {
		ball2.vy += gws;
	}
	//Tracking AI 
	if ((ball2._x<ball._x) && ball2.vx<10) {
		ball2.vx += nmea;
	}
	if ((ball2._x>ball._x) && ball2.vx>-10) {
		ball2.vx -= nmea;
	}
	if ((ball2._y>ball._y) && ball2.vy>-10) {
		ball2.vy -= nmea;
	}
	if ((ball2._y<ball._y) && ball2.vy<10) {
		ball2.vy += nmea;
	}
	//Death 
	if (bdead == true) {
		ball.vx = ball.vx/3;
		ball.vy = ball.vy/3;
		ball2.vx = 0;
		ball2.vy = 0;
		if (ball._xscale>0) {
			ball._xscale -= 2;
			ball._yscale -= 2;
			ball._alpha -= 1;
		}
	}
	if (b2dead == true) {
		ball.vx = 0;
		ball.vy = 0;
		ball2.vx = ball2.vx/3;
		ball2.vy = ball2.vy/3;
		if (ball2._xscale>0) {
			ball2._xscale -= 2;
			ball2._yscale -= 2;
			ball2._alpha -= 1;
		}
	}
};
_root.onMouseDown = function() {
	ball.vx = 0;
	ball.vy = 0;
	ball2.vx = 0;
	ball2.vy = 0;
	ball._x = 245;
	ball._y = 170;
	ball2._x = 165;
	ball2._y = 222;
	bdead = false;
	b2dead = false;
	ball._xscale = 100;
	ball._yscale = 100;
	ball._alpha = 100;
	ball2._xscale = 100;
	ball2._yscale = 100;
	ball2._alpha = 100;
};

And this is the result:

Take a look, download the source code and let me know if you can turn this prototype into a blockbuster

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 3.33 out of 5)
Loading ... Loading ...
If you found this post useful, please consider a small donation.
» Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.

11 Responses

  1. David says:

    first post!

    interesting tutorial. are you going to make this into a game?

  2. styxtwo says:

    very nice idea for a game, nees some more coding however:
    when nor moving the ball after pressing the mouse butting the other ball lays on top of the other.

    ow and is it ok if i experiment with the code a little bit, maybe i can improbe it a bit =)

  3. Frederik J says:

    Wow.. That’s addicting and nice. I’ve always wondered how the enemy, was computer controlled. Very nice, I may give it a look, when i get time, and try to understand the code. Thanks for sharing it with us.

    //Frederik

  4. Patrik TG says:

    Well I think that this is a better game consept then gobble, if you just would make a story and some different levels ;)

  5. And Mar says:

    This will be difficult to make into a game with walls without a better way to determine a collision between a ball and a wall

  6. shiv1411 says:

    It looks like a pretty good game concept and
    still it needs some more improvements.

    Making AI for a ball….

    good concept however…!

    :)

  7. Monkios says:

    @ And Mar :
    I think this is more a proof of concept. It is made to show how things can work togeter without having to make the big code things.

  8. s0d4player says:

    This would be useful for an enemy AI.

  9. oran says:

    why won’t it work when theres two frames?

  10. Josh says:

    sometimes if you dont hit anything the balls overlap and stop on each other with no collision.
    hopefully something you can fix.

  11. David says:

    how would you use the existing code to allow the computer to control two balls?

Leave a Reply