Creation of a game like String Avoider tutorial

A really interesting “avoidance game” that was made in those days is String Avoider. The author of this “More than 1 million views” game in Newgrounds explains it in 12 words: “Avoid colliding with walls and guide your string through each unique level”.

String avoider

And that’s it. The aim of the game is guiding your string through some levels without touching the walls.

It’s very similar to the ball game I am discussing in this site, but this time the ball is controlled by the mouse and has a “tail” that responses in a very “real life” way.

Something very hard to code, you may say. It’s not that hard to reproduce a string movement in Flash, even if the built-in string class does not help us…

(laugh)

… but let’s start with the tutorial.

The string

A string is made of two objects: the head and the tail. The player will control the head, while the tail will follow the head. That’s it.

So, the first thing to do is the creation of the head. The picture below shows how to draw, position and link the head

head creation

Then in main scene first frame simply drop this actionscript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
tail_len = 2;
tail_nodes = 100;
nodes = new Array();
_root.attachMovie("the_head", "the_head", 1, {_x:250, _y:200});
_root.createEmptyMovieClip("the_tail", 2);
for (x=1; x<tail_nodes; x++) {
	nodes[x] = {x:the_head._x, y:the_head._y};
}
the_head.onEnterFrame = function() {
	this._x = _root._xmouse;
	this._y = _root._ymouse;
	the_tail.clear();
	the_tail.lineStyle(2, 0x00ff00);
	the_tail.moveTo(the_head._x, the_head._y);
	nodes[0] = {x:the_head._x, y:the_head._y};
	for (var x = 1; x<tail_nodes-1; ++x) {
		rotation = Math.atan2(nodes[x].y-nodes[x-1].y, nodes[x].x-nodes[x-1].x);
		pos_x = nodes[x-1].x+tail_len*Math.cos(rotation);
		pos_y = nodes[x-1].y+tail_len*Math.sin(rotation);
		nodes[x] = {x:pos_x, y:pos_y};
		the_tail.lineTo(pos_x, pos_y);
	}
};

Line 1: Defining tail_len variable at 2. What is tail_len? It’s the length in pixels of the fixed part between two nodes.

Line 2: Defining tail_nodes as the number of nodes that will contain the tail.

Time to give some explication: in real world, a string can bend in any of its points. In flash world, we do not want it because it will use too much computer resources and we do not need it because it’s just a game. So, if we want a string 200 pixels wide, we can use the “real world” method defining tail_len at 1 and tail_nodes at 200, or we can simplify computer’s work setting tail_len at 2 and tail_nodes at 100. Just remember that tail_nodes*tail_len = real tail length for high values of tail_nodes.

Line 3: Declaration of the array where will store all nodes positions

Line 4: Attaching the “head” movie on the stage positioning it in middle of it.

Line 5: Creation of an empty movie clip called “tail” that will contain the tail of the string

Lines 6-8: Cycle that creates all nodes positions. Their starting positions, defined as coordinates, at the beginning are equals to head’s _x and _y coordinates

Line 9: Function to be executed at every frame

Lines 10-11: Placing the head at current mouse x and y positions

Line 12: Clearing the tail movieclip

Line 13: Setting the line style of the tail movieclip with a stroke height of 2 filled with green. For more information about drawing and line styles, check this tutorial.

Line 14: Placing the “pen” that will draw the tail on the same head _x and _y positions

Line 15: Defining the first node coordinates (nodes[0]) and the same head _x and _y positions. The first node actually could be the head itself, but I wanted a bigger head so I designed it as a separate movieclip.

Line 16: Beginning of the main loop, that will scan all nodes except nodes[0]. In this case, nodes[1] to nodes[99]

Line 17: Obtaining the angle between the xth and the (x-1)th node. This is done using trigonometry. I wrote a tutorial about it here. You may notice that is a bit different than the atan formulas used in that tutorial, but I discovered atan2 is often more useful than atan in applications involving rotation by a specified amount, because it returns a positive beta for all angles between 0 and 180 degrees (even when x is negative).
Thus it eliminates the need for extra code to deal with different values in different quadrants of the circle.

Lines 18-19: Here trigonometry is involved to calculate new node[x] x and y positions according to its angle with node[x-1]

Line 20: New x and y positions are saved in node[x]

Line 21: Drawing a line from the previous pen position to new x and y positions

And that’s it! We have our moving string. Time to test for some collisions!

Collisions

I created a movieclip linked as wall and placed it on the stage.

Then the actionscript is:

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
tail_len = 2;
tail_nodes = 100;
nodes = new Array();
_root.attachMovie("the_head", "the_head", 1, {_x:250, _y:200});
_root.createEmptyMovieClip("the_tail", 2);
_root.attachMovie("wall", "wall", 3, {_x:250, _y:200});
for (x=1; x<tail_nodes; x++) {
	nodes[x] = {x:the_head._x, y:the_head._y};
}
the_head.onEnterFrame = function() {
	this._x = _root._xmouse;
	this._y = _root._ymouse;
	the_tail.clear();
	the_tail.lineStyle(2, 0x00ff00);
	the_tail.moveTo(the_head._x, the_head._y);
	nodes[0] = {x:the_head._x, y:the_head._y};
	for (var x = 1; x<tail_nodes-1; ++x) {
		rotation = Math.atan2(nodes[x].y-nodes[x-1].y, nodes[x].x-nodes[x-1].x);
		pos_x = nodes[x-1].x+tail_len*Math.cos(rotation);
		pos_y = nodes[x-1].y+tail_len*Math.sin(rotation);
		nodes[x] = {x:pos_x, y:pos_y};
		if (wall.hitTest(pos_x, pos_y, true)) {
			the_tail.lineStyle(2, 0xff0000);
		}
		the_tail.lineTo(pos_x, pos_y);
	}
};

Line 6: Placing the wall on stage

Line 22: Hit test between pos_x, pos_y coordinates and the wall

Line 23: If the test is positive, then change the line color to red. In this way you can view where you collided.

And now you’re ready to create some string game… download the source code and send me your works!

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (10 votes, average: 5.00 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 36 comments

  1. Jerm

    on July 12, 2007 at 4:53 pm

    Awesome!

  2. Mousey

    on July 12, 2007 at 5:09 pm

    nice but what is the code so when it hits the wall it goes back to the begning position! And same for exit it goes to end

    thanks

  3. Flash Prayer

    on July 12, 2007 at 8:12 pm

    heelo emanuele, i have posted a link to this tutorial at http://www.beedigital.net/blog I hope you don´t mind…

    Nice blog you have here, great tutorials….

    See you around.

  4. Michael

    on July 12, 2007 at 8:15 pm

    Awesome, cannot believe how simple you make it seem, lol.

    To Mousey:
    Simply reset the head’s X and Y to wherever your start is inside the hitTest.

    if(wall.hitTest(pos_x, pos_y, true)){
    this._x = 250;
    this._y = 200;
    }

  5. abhilash

    on July 13, 2007 at 11:36 am

    Cooool!!!

  6. eblup

    on July 14, 2007 at 3:16 am

    good but what abount a second to youre platform game linke have enemys but good tut

  7. Samuel

    on July 17, 2007 at 12:16 am

    I apologize, but in my mind this isn’t your best tutorial… I have no clue about how the string actually follows the mouse as it does, when the tail snail it’s way like it does. Could you post a part 2 that explains the calculations? :)

  8. And Mar

    on July 17, 2007 at 2:16 pm

    Let me try to explain the trigonometry, Emanuele will correct me if I’m wrong:

    1.rotation = Math.atan2(nodes[x].y-nodes[x-1].y, nodes[x].x-nodes[x-1].x);

    Finds the angle(direction) between the current node and the previous

    node. This happens because the position of each node depends on the position of

    the previous node. This way, the nodes remain tail_len pixels apart.
    _
    nodes[x-1]->(_)
    \
    \
    \ (_)

    ———————————————————————–
    _
    (_)_____
    \ |
    \ |

  9. And Mar

    on July 17, 2007 at 6:56 pm

    Man, my comment was cut if half.
    Let me try again.

  10. And Mar

    on July 17, 2007 at 7:55 pm

    Let me try to explain the trigonometry, Emanuele will correct me if I’m wrong:

    1.rotation = Math.atan2(nodes[x].y-nodes[x-1].y, nodes[x].x-nodes[x-1].x);

    Finds the angle(direction) between the current node and the previous
    node. This happens because the position of each node depends on the position of

    the previous node. This way, the nodes remain tail_len pixels apart.
                                _
                   nodes[x-1]->(_)
                                 \
                                  \
                                   \ <— angle of this line from the
                                    \     horizontal is calculated
                                     \
                                      \_
                          nodes[x]—>(_)

    ———————————————————————–
                                _
                               (_)_____
                                 \     |
                                  \    | <– distance equals tail_len
                                   \   |
                                    \__|
    nodes[x] will be moved here ____/\
    so that the distance remains      \_
    tail_len                          (_)

    =======================================================================

    2.pos_x = nodes[x-1].x tail_len*Math.cos(rotation);

    Calculates the x position of the current node after it has been moved.

                 ___length of this line equals
              _  | _tail_len * Math.sin(rotation)
             (_)__(_)
               \   |\
                \  | currently, the node would be moved
                 \ | here
                  \|
                   \
                    \

    =======================================================================

    3.pos_y = nodes[x-1].y tail_len*Math.sin(rotation);

    Calculates the y position of the current node after it has been moved.

             _
            (_)___
              \   |
               \  |<— length of this line equals
                \ |     tail_len * Math.cos(rotation)
                 \|
                 (_) <— this is where the node finally ends up
                   \
                     <— As you can see, the node just
                          moves straight towards the previous node

    =======================================================================

    4.nodes[x] = {x:pos_x, y:pos_y};

    Updates the nodes[x] coordinates

    =======================================================================

    5.the_tail.lineTo(pos_x, pos_y);

    Draws a line (tail_len long) from current pen position

    (nodes[x-1].x,nodes[x-1].y), to the current nodes position
    (nodes[x].x,nodes[x].y or pos_x,pos_y)

    =======================================================================

    Hope this helps you out. Why the sin and cos statements work are
    explained in the tutorial Emanuele mentioned

  11. imworlds

    on July 19, 2007 at 12:44 am

    Do these files work in Flash MX? I can’t get any of these to work. If not, is there a quick fix to make them work in Flash MX? I’d love to try these out…

  12. s0daplayer

    on July 19, 2007 at 11:19 pm

    I’ve been looking how to make a game like this. Thanks.

  13. s0daplayer

    on July 20, 2007 at 2:32 am

    I noticed that actually there will be one less node than defined. What is causing this.

  14. s0daplayer

    on July 20, 2007 at 2:38 am

    Ok sorry for posting this question since it’s explained already. But if you want the same amount of nodes you defined, in line 16, remove the “-1″

  15. s0daplayer

    on August 6, 2007 at 7:27 pm

    I created a game where the nodes would actually go where the node in front of it in the last frame. Though I’m wordering how to convert it so it will be like the nodes in this tutorial instead of manually making each mode.

    _root.attachMovie(“node”,”node1″,1,{_x:20, _y:100})
    _root.attachMovie(“node”,”node2″,2,{_x:275, _y:200})
    _root.attachMovie(“node”,”node3″,3,{_x:375, _y:300})
    _root.createEmptyMovieClip(“line1″,4)
    _root.createEmptyMovieClip(“line2″,5)
    _root.createEmptyMovieClip(“line3″,6)
    Mouse.hide()
    onEnterFrame = function() {
    node1._x = _xmouse
    node1._y = _ymouse
    node2._x = pos_x1
    node2._y = pos_y1
    node3._x = pos_x2
    node3._y = pos_y2
    line1.clear()
    line2.clear()
    line1.lineStyle(10, 0xabcdef)
    line2.lineStyle(10, 0xabcdef)
    line1.moveTo(node1._x,node1._y)
    line2.moveTo(node2._x,node2._y)
    line1.lineTo(node2._x,node2._y)
    line2.lineTo(node3._x,node3._y)
    pos_x1 = node1._x
    pos_y1 = node1._y
    pos_x2 = node2._x
    pos_y2 = node2._y
    }

  16. web design

    on August 19, 2007 at 7:14 pm

    I tried in the first time as u said in the turorial…but seems somewhere i m not doing the correct coding or misspelled something ….anyways..nice tutorial..!!

  17. beatalize

    on September 20, 2007 at 12:54 pm

    it doesnt work!!
    when i apply the first script it doesnt work y?

  18. 123

    on September 20, 2007 at 1:08 pm

    wow this tuturial is nice!!!

    guyz can anyone tell me how can i make the tail become red when the head touch my own tail?

  19. fwe

    on September 27, 2007 at 9:43 pm

    I made String Avoider :D
    Nice tutorial

  20. Flávio

    on October 22, 2007 at 3:11 pm

    Hi! I liked this tutorial very much – as like all the rest of your tutorials…
    Anyway, I’ve been trying to make something similar to the string you made here, but waht I want was not a string, but a text following the mouse, and then I found this:
    http://www.a-to-s.co.uk/home.php
    click on N and you’ll see… would you please help me? I need this for a graduation project =)
    thanks in advance
    Flavio

  21. konishama

    on November 18, 2007 at 11:21 am

    what action script is this?

  22. kam

    on November 21, 2007 at 1:20 am

    Hi Guys, i have this working, i have a timer also set, but everytime i get the game to move to a diff “scene” in Flash the sting allways appears to start from the centre, i have only added a “gotoandplay” function and this just carrys on the action script for the string creation..can you please help me with how to stop this script from being carried over to the other “scene’s” in flash
    thank you

  23. bob mcshamusBdiddely

    on November 24, 2007 at 6:12 pm

    to make the line follow the mouse without the head, just make the colour of the heads alpha 0%. This will make it invisible

  24. Goinginsane

    on December 5, 2007 at 9:17 pm

    Could anyone post something for color codes?
    I can make the tail black, otherwise it is a hit and miss situation.

  25. blahblah

    on December 28, 2007 at 10:48 pm

    i need a action script to make the wall move
    —————–
    blahblah

  26. josh

    on January 27, 2008 at 10:04 pm

    i am willing to help, i am sorry if i am too late, but what do you want to happen exactly?

  27. Nathan

    on March 22, 2008 at 11:47 pm

    I’m making a game with this code
    http://dev.mrnat.com/bomb_sorter.swf
    It’s not done yet, but do you want me to credit you?

  28. Emanuele Feronato

    on March 23, 2008 at 1:03 am

    it would be very kind…

  29. Nathan

    on March 29, 2008 at 12:33 am

    Are you sure I can use it?

    I really don’t like copying other people’s work…

  30. reece

    on June 5, 2008 at 8:02 pm

    hey how do you keep the wall not moving with the mouse but so it stays in one place

  31. Eekie

    on June 12, 2008 at 11:35 pm

    Does anyone know the code to make the tail (last node of the string) stationary (fixed) at a certain x,y coordinate? I want the string to follow the head but be limited to the tail_len… I am also trying to have the head drag rather than follow the mouse.

    Is this possible?

    Thanks!

    PS: Great tutorial…

  32. alex

    on August 17, 2008 at 10:19 pm

    hey I put it all in and got a problem with the actionscript for the wall this is what it says

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 1: Statement must appear within on/onClipEvent handler
    tail_len = 2;

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 2: Statement must appear within on/onClipEvent handler
    tail_nodes = 100;

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 3: Statement must appear within on/onClipEvent handler
    nodes = new Array();

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 4: Statement must appear within on/onClipEvent handler
    _root.attachMovie(“the_head”, “the_head”, 1, {_x:250, _y:200});

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 5: Statement must appear within on/onClipEvent handler
    _root.createEmptyMovieClip(“the_tail”, 2);

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 6: Statement must appear within on/onClipEvent handler
    _root.attachMovie(“wall”, “wall”, 3, {_x:250, _y:200});

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 7: Statement must appear within on/onClipEvent handler
    for (x=1; x<tail_nodes; x++) {

    Scene=Scene 1, Layer=Layer 1, Frame=1: Line 10: Statement must appear within on/onClipEvent handler
    the_head.onEnterFrame = function() {

    please email me the answer

  33. Robin

    on September 19, 2008 at 1:51 pm

    Does someone know how to convert this code to AS3?? I’m struggling with it for the whole week now but can’t get a clue out of it! please help!

  34. Gustav

    on January 18, 2009 at 2:26 am

    I’m so sorry if this comment is a bit late but there was one thing, it’s my own personal project but, how do you place the ”string” behind the head? It’s bugging my brain. Please respond if you have time. :)

  35. Creation of a game like String Avoider | Tutorial Collection

    on July 2, 2009 at 3:14 am

    [...] View Tutorial No Comment var addthis_pub="izwan00"; BOOKMARK This entry was posted on Thursday, July 2nd, 2009 at 6:44 am and is filed under Adobe Flash Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. [...]

  36. Flash Game Tutorial Roundup Part 2 | VapvaruN | Wp Experts

    on November 18, 2011 at 8:35 am

    [...] Creation of a game be fond of String Avoider tutorial [...]