Flash AS3 Pixel based circle collision engine
- February 13, 2010 by Emanuele Feronato
- Filed under Actionscript 3, Flash, Game design, Users contributions | 5 Comments
After seeing the Lineball video teaser I got some email asking me how did I make the hollow circle with Box2D, and how to get a smooth drawing using box primitives.
Well, I have to say I didn’t use Box2d, but another library called Collision Detection Kit.
I’ll publish some tutorial about it once I’ll complete the game, but it’s not the point of today’s post.
A reader from Argentina, Adolfo Chacon, sent me an AS3 basic engine to do the same thing (maybe even better) using the concepts I explained soooooo long ago in the Create a flash draw game like Line Rider or others series.
It’s a basic, uncommented script because it’s just a prototype… basically Adolfo took my old script, adjusted trigonometry and did the magic dividing the simulation in steps to manage slower speeds.
I resized it, changed variable names (translating from spanish) and some operators since the auto format option gave me errors when trying to format a<-b, forcing me to change into a<b*-1.
Now enjoy the script
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 | package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class pixel_engine extends Sprite { public var ball_radius:int; public var precision:int=120; public var degrees_to_radians:Number=0.0174532925; public var x_speed:Number=0; public var y_speed:Number=0; public var friction:Number=0.9; public var max_speed:int=15; public var gravity:Number=0.98; public var steps=2; public var ball:ball_mc = new ball_mc(); public var terrain:terrain_mc = new terrain_mc(); public function pixel_engine():void { addChild(ball); ball.x=250; ball_radius=ball.width/2; addChild(terrain); addEventListener(Event.ENTER_FRAME, update); stage.addEventListener(MouseEvent.MOUSE_DOWN, reverse_gravity); } private function reverse_gravity(event:MouseEvent):void { gravity*=-1; } public function update(e : Event):void { if (ball.y>400) { ball.y-=400; } if (ball.y<0) { ball.y+=400; } for (var j:int = 1; j<=steps; j++) { var number_of_collisions:int=0; var sum_x_collision:Number=0; var sum_y_collision:Number=0; if (x_speed>max_speed) { x_speed=max_speed; } else { if (x_speed<max_speed*-1) { x_speed=- max_speed; } } if (y_speed>max_speed) { y_speed=max_speed; } else { if (y_speed<max_speed*-1) { y_speed=- max_speed; } } ball.x=ball.x+x_speed/steps; ball.y=ball.y+y_speed/steps; y_speed=y_speed+gravity/steps; for (var i:int=1; i<=precision; i++) { var x_test:Number=ball.x+ball_radius*Math.sin(i*360/precision*degrees_to_radians); var y_test:Number=ball.y-ball_radius*Math.cos(i*360/precision*degrees_to_radians); if (terrain.hitTestPoint(x_test,y_test,true)) { number_of_collisions++; sum_x_collision=sum_x_collision+x_test; sum_y_collision=sum_y_collision+y_test; } } var average_x:Number=sum_x_collision/number_of_collisions; var average_y:Number=sum_y_collision/number_of_collisions; if (number_of_collisions>0) { var collision_angle:Number=Math.atan2(ball.x-average_x,ball.y-average_y)/degrees_to_radians*-1+90; var collision_x:Number = ball.x - ball_radius * Math.sin((collision_angle + 90) * degrees_to_radians); var collision_y:Number = ball.y + ball_radius * Math.cos((collision_angle + 90) * degrees_to_radians); var delta_x:Number = (collision_x - ball.x) / ball_radius * -1; var delta_y:Number = (collision_y - ball.y) / ball_radius * -1; var speed:Number=Math.sqrt(x_speed*x_speed+y_speed*y_speed)*friction; var bounce:Number=Math.atan2(x_speed,y_speed)/degrees_to_radians*-1; var ricochet:Number=2*collision_angle-bounce-180; x_speed=Math.sin(ricochet*degrees_to_radians)*speed; y_speed=- Math.cos(ricochet*degrees_to_radians)*speed; while (terrain.hitTestPoint(collision_x, collision_y,true)) { ball.x=ball.x+delta_x; ball.y=ball.y+delta_y; collision_x=ball.x-delta_x*ball_radius; collision_y=ball.y-delta_y*ball_radius; } } } } } } |
And play with the result… just watch the simulation and press left mouse button to reverse gravity.
Download the source code. Who said draw games are dead?
They can be easily customized to meet the unique requirements of your project.
5 Responses
Leave a Reply
- Una guida completa al gioco del poker online e una selezione dei migliori casino online.
- casino online
- migliori casino online
- BlackJack online
- casinò online
- Giochi casino

(3 votes, average: 4.33 out of 5)



Awsome!!! :D emanuele you rock
This is great!
Now the question is, does the ball keep bouncing when it stops or does it fall trough the lines then? Cant check it out right now cause I don’t have flash on this computer…
[...] Flash AS3 Pixel based circle collision engine [...]
Oh. It’s nice script, thanks