Install Circle Chain on your iPhone for free and get the source code!! 645 downloads to go - last updated: April 21, 2012

Develop a Flash game like String Avoider – AS3 version – and more!

Let’s travel back in 2007, when mouse avoider games got played by some million people and rated with five stars out of five.

One of these games featured on this blog was String Avoider, at that time developed with AS2.

Today, I want to post the AS3 version of the prototype, since its gameplay can be extended with interesting features in my opinion, and I am also showing you a way to detect when the string intersects using the line-line intersection concept found on Wikipedia.

The code is not explained, but you can find anything you need in the original post.

I can explain the second script if you don’t find it clear, just leave a comment. I still have to explain the Angry Birds prototype, so be patient, I am in a mood of creation.

So this is the string 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
package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	public class Main extends Sprite {
		private var tailLenght:Number=1;
		private var tailNodes:Number=300;
		private var head:headMc=new headMc();
		private var tailCanvas:Sprite=new Sprite();
		private var nodes:Vector.<Point>=new Vector.<Point>();
		public function Main() {
			addChild(head);
			head.x=320;
			head.y=240;
			addChild(tailCanvas);
			for (var i:int=0; i<tailNodes; i++) {
				nodes[i]=new Point(head.x,head.y);
			}
			addEventListener(Event.ENTER_FRAME,update);
		}
		private function update(e:Event):void {
			head.x=mouseX;
			head.y=mouseY;
			tailCanvas.graphics.clear();
			tailCanvas.graphics.lineStyle(2,0x00ff00);
			tailCanvas.graphics.moveTo(head.x,head.y);
			nodes[0]=new Point(head.x,head.y);
			for (var i:int=1; i<tailNodes-1; i++) {
				var nodeAngle:Number=Math.atan2(nodes[i].y-nodes[i-1].y,nodes[i].x-nodes[i-1].x);
				nodes[i]=new Point(nodes[i-1].x+tailLenght*Math.cos(nodeAngle),nodes[i-1].y+tailLenght*Math.sin(nodeAngle));
				tailCanvas.graphics.lineTo(nodes[i].x,nodes[i].y);
			}
		}
	}
}

And this is the result:

Move the mouse to control the string/snake.

And this is the second examples, with collisions shown with black dots, and a less smooth string just to show you how it works:

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
package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	public class Main extends Sprite {
		private var tailLenght:Number=50;
		private var tailNodes:Number=10;
		private var head:headMc=new headMc();
		private var tailCanvas:Sprite=new Sprite();
		private var nodes:Vector.<Point>=new Vector.<Point>();
		public function Main() {
			addChild(head);
			head.x=320;
			head.y=240;
			addChild(tailCanvas);
			for (var i:int=0; i<tailNodes; i++) {
				nodes[i]=new Point(head.x,head.y);
			}
			addEventListener(Event.ENTER_FRAME,update);
		}
		private function update(e:Event):void {
			head.x=mouseX;
			head.y=mouseY;
			tailCanvas.graphics.clear();
			tailCanvas.graphics.lineStyle(2,0x00ff00);
			tailCanvas.graphics.moveTo(head.x,head.y);
			nodes[0]=new Point(head.x,head.y);
			for (var i:int=1; i<tailNodes-1; i++) {
				var nodeAngle:Number=Math.atan2(nodes[i].y-nodes[i-1].y,nodes[i].x-nodes[i-1].x);
				nodes[i]=new Point(nodes[i-1].x+tailLenght*Math.cos(nodeAngle),nodes[i-1].y+tailLenght*Math.sin(nodeAngle));
				if (i<tailNodes-2) {
					for (var j:int=i-1; j>=1; j--) {
						var p:Point=lineIntersection(nodes[j],nodes[j-1],nodes[i],nodes[i+1]);
						if (p!=null) {
							tailCanvas.graphics.beginFill(0x000000);
							tailCanvas.graphics.drawCircle(p.x,p.y,4);
							tailCanvas.graphics.endFill();
							tailCanvas.graphics.moveTo(nodes[i-1].x,nodes[i-1].y);
						}
					}
				}
				tailCanvas.graphics.lineTo(nodes[i].x,nodes[i].y);
			}
		}
		private function lineIntersection(p1:Point,p2:Point,p3:Point,p4:Point):Point {
			var x1:Number=p1.x;
			var x2:Number=p2.x;
			var x3:Number=p3.x;
			var x4:Number=p4.x;
			var y1:Number=p1.y;
			var y2:Number=p2.y;
			var y3:Number=p3.y;
			var y4:Number=p4.y;
			var px:Number=((x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4));
			var py:Number=((x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4));
			var segment1Len:Number=Math.pow(p1.x-p2.x,2)+Math.pow(p1.y-p2.y,2);
			var segment2Len:Number=Math.pow(p3.x-p4.x,2)+Math.pow(p3.y-p4.y,2);
			if (Math.pow(p1.x-px,2)+Math.pow(p1.y-py,2)>segment1Len) {
				return null;
			}
			if (Math.pow(p2.x-px,2)+Math.pow(p2.y-py,2)>segment1Len) {
				return null;
			}
			if (Math.pow(p3.x-px,2)+Math.pow(p3.y-py,2)>segment2Len) {
				return null;
			}
			if (Math.pow(p4.x-px,2)+Math.pow(p4.y-py,2)>segment2Len) {
				return null;
			}
			return new Point(px,py);
		}
	}
}

Here is the result:

Again, move the string with the mouse.

Get the source code and tell me which kind of game would you develop out of it.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (17 votes, average: 4.76 out of 5)
Loading ... Loading ...
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.
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 21 comments

  1. NateJC

    on October 13, 2011 at 7:25 pm

    Great example! (Note: misspelling on “tailLenght”)

  2. Vladimir

    on October 13, 2011 at 7:29 pm

    I think that I’ll make a game out of this :D

  3. Danny Phantom

    on October 13, 2011 at 7:30 pm

    AWESOME. I Loved The Effect. :O

  4. Rennan

    on October 13, 2011 at 10:56 pm

    Great!
    I liked it a lot Emanuele.
    What comes next?

  5. Ste

    on October 13, 2011 at 11:10 pm

    Hi mate, firstly great stuff as always. Im attempting to move over from PHP to actionscript 3….Well not really move over, more like use both together. Im really struggling to pick up actionscript and to be honest I usually struggle to get your code working. eg on the above code I get an error on line 8….Am I just being stupid, am I missing something obvious?

  6. Emanuele Feronato

    on October 14, 2011 at 12:25 am

    probably you did not create the headMc object which is the head of the string. Check the library window in the downloadable source code at the end of this post

  7. Ben Reynolds

    on October 14, 2011 at 6:23 am

    Awesome effect! I can think of a bunch of cool uses for this mechanic.

  8. Scott

    on October 14, 2011 at 10:14 pm

    How would you get the collision to register with the smooth version?

  9. Emanuele Feronato

    on October 14, 2011 at 10:17 pm

    it’s the same thing, just with much smaller segments

  10. Mark

    on October 16, 2011 at 9:29 pm

    Wow very cool demo, interesting peace of code too. Question; I don’t understand how you managed that if I move the mouse left, and then back to the right, the lines move back too (second example). How exactly does that work, what makes that happen?

  11. Emanuele Feronato

    on October 16, 2011 at 9:45 pm

    the trigonometry functions at lines 29-30

  12. Matt

    on October 16, 2011 at 10:06 pm

    How would you get it so the nodes hang due to gravity, if you added velocity i guess

  13. Pushkar

    on October 18, 2011 at 11:09 am

    Hi Emanuele, when I increase the length of string in 2nd example. It slow my system.

  14. Chris Taylor

    on October 20, 2011 at 11:50 pm

    I love this and think it’s awesome. I love Trig, but at least in AS3, the Math functions tend to pretty slow. Trig can also over complicate things which breaks my heart a little bit. So out of an exercise curiosity I thought I’d try it without Trig and check the performance difference. When I replaced the Trig on lines 29-30 with the Vector approach of:

    var deltaVector:Point = new Point(nodes[i].x – nodes[i-1].x, nodes[i].y – nodes[i-1].y);
    deltaVector.normalize(tailLenght);
    nodes[i] = new Point(nodes[i-1].x + deltaVector.x, nodes[i-1].y + deltaVector.y);

    I was getting about a .3-.5ms per frame performance increase. For those that don’t know Trig, this might even be easier to understand. This is absolutely not a criticism, just showing how math can be beautiful in how it allows so many solutions to the same problem. Also showing my disappointment with the AS3 Math class! :(

  15. Cool Stuff with the Flash Platform - 10/24/2011 | Remote Synthesis

    on October 24, 2011 at 9:30 pm

    [...] had several good Flash game development posts this week (as usual). The first shows you how to develop a game like String Avoider including the AS3 source. The next continues his series of posts on building an Angry Birds-like [...]

  16. Astraport

    on October 29, 2011 at 3:10 pm

    Hi Emanuele!

    Thank you very much for your lessons. It helps me to learn actionscript 3.
    I’d like to see lessons about the creation of tower deffence games. Particularly interesting to calculate the path of the enemy movements, missile trajectory of the towers to the enemies, a level editor, etc.

    And a request to give the source in CS5, not everyone has the CS5.5;)
    Well, better without Flash IDE in pure AS3.

  17. Janitha

    on December 6, 2011 at 8:44 am

    How would you recommend we do collision detection? I’m trying to develop a game with this concept and when I do tailCanvas.hitTestObject(collide_mc)) the game slows down a lot. I can’t even think about having more than one object on the stage to do collision detection with.

  18. Davide

    on December 15, 2011 at 5:05 am

    Like someone asked for AS2 version :D…Does somebody have idea of how edit the code to make the tail (last node of the string) stationary / fixed at a certain x,y coordinate?
    It would be nice to have the string starting from a determined point and follow the head but without “moving” from it’s starting point (and being limited to total tail lenght, too).
    Any idea ? :D

  19. lIon

    on December 19, 2011 at 10:34 am

    How to color fill only closed loops?

  20. lIon

    on December 19, 2011 at 10:38 am

    ok. did it.
    btw thrs lot of kewl stuff on ur site.

  21. aldrin

    on February 8, 2012 at 4:49 am

    can you please send tell me how to deduct live from a dynamic text. i mean i’ve already done the part when the head will deduct lives(but in text).the problem is that it deducts 2 points and it deducts pretty fast that a single touch from the wall will give you zero.