# Build a Classic Snake Game in AS3

In this tutorial I would like to show you how easy it is to create a classic "Snake" game in Flash. I will try to explain everything easily, step by step, so that you can develop the game further to your needs! The Game will be developed in AS3 and I will use the FlashDevelop IDE.

## Introduction

The game won't be complex. Whenever we hit a wall, it will restart the game. After eating an apple the snake will grow, and a 'new' Apple will appear. (Actually, it will be the same apple, but I'll explain this later.)

One of the most important aspects of the game is the code's reaction to KEY_DOWN events. The snake will only then change its direction after a tick has passed, not immediately after a keypress. This means that, if the snake is going right, and you press down and left very fast, the snake will go down, not down AND left. Without this 'feature' the snake would allow us to go left while we are going right, which would mean it hit itself.

## Let's Look at the Game Already!

Let's take a look at the final result we will be working towards:

## Step 1: Creating the Project

In FlashDevelop, create a new Project, and inside the 'src' folder create a 'com' folder. In the 'com' folder create a new class, and call it 'Element.as'.

Set the dimensions of the project to 600x600px.

## Step 2: Wait... What's an Element?

The snake is make up of blue squares, which I call elements. We will create an Element Class, which draws the element. The red apple is going to be an element too, so we will extend the code with a few more lines.

Therefore we won't create a new class for the apple. (But if you really want to, you can.)

## Step 3: Writing the Element Class

The Element class creates a square. It doesn't draw it on the stage, it just creates it. The registration point of the element - the position referred to by its x- and y-coordinates - is in the top-left.

After opening the Element.as you will see something like this:

 1 2 package com  3 {  4  /**  5  * ...  6  * @author Fuszenecker Zsombor  7  */  8  public class Element  9  {  10   11  public function Element()  12  {  13   14  }  15   16  }  17 } 

First we need this to extend the Shape class, so we can use the graphics object to draw the square. After this, create two variables: one for the direction (if it's part of the snake), and one for the score value (if it's an apple), and then change the parameters of the constructor function:

 1 2 package com  3 {  4  import flash.display.Shape;  5   6  public class Element extends Shape  7  {  8  protected var _direction:String;  9  //IF IT IS AN APPLE ->  10  protected var _catchValue:Number;  11   12  //color,alpha,width,height  13  public function Element(_c:uint,_a:Number,_w:Number,_h:Number)  14  {  15 16  }  17  }  18 } 

Now fill the function with some code:

 1 2 package com  3 {  4  import flash.display.Shape;  5   6  public class Element extends Shape  7  {  8  protected var _direction:String;  9  //IF IT IS AN APPLE ->  10  protected var _catchValue:Number;  11   12  //color,alpha,width,height  13  public function Element(_c:uint,_a:Number,_w:Number,_h:Number)  14  {  15  graphics.lineStyle(0, _c, _a);  16  graphics.beginFill(_c, _a);  17  graphics.drawRect(0, 0, _w, _h);  18  graphics.endFill();  19   20  _catchValue = 0;  21  }  22  }  23 } 

Now, whenever we create an element, it will draw a rectangle and set the score value of the element to 0 by default. (It won't put the rectangle on stage, it just draws it within itself. Notice that we have not called the addChild() function.)

Let's finish this class and then we can finally test how much we have done already:

 1 2 package com  3 {  4  import flash.display.Shape;  5   6  public class Element extends Shape  7  {  8  protected var _direction:String;  9  //IF IT IS AN APPLE ->  10  protected var _catchValue:Number;  11   12  //color,alpha,width,height  13  public function Element(_c:uint,_a:Number,_w:Number,_h:Number)  14  {  15  graphics.lineStyle(0, _c, _a);  16  graphics.beginFill(_c, _a);  17  graphics.drawRect(0, 0, _w, _h);  18  graphics.endFill();  19   20  _catchValue = 0;  21  }  22   23  //ONLY USED IN CASE OF A PART OF THE SNAKE  24  public function set direction(value:String):void  25  {  26  _direction = value;  27  }  28  public function get direction():String  29  {  30  return _direction;  31  }  32   33  //ONLY USED IN CASE OF AN APPLE  34  public function set catchValue(value:Number):void  35  {  36  _catchValue = value;  37  }  38  public function get catchValue():Number  39  {  40  return _catchValue;  41  }  42  }  43 44 } 

We created four functions to change the directions and the value of the apple. We achieved this by using setters and getters. More about Setters/Getters in this article!

## Step 4: Testing the Element Class

Open Main.as now.

Import the com.Element class and create an Element in the init() function:

 1 2 package  3 {  4  import flash.display.Sprite;  5  import flash.events.Event;  6  import com.Element;  7   8  public class Main extends Sprite  9  {  10  public function Main()  11  {  12  if(stage)  13  addEventListener(Event.ADDED_TO_STAGE, init);  14  else  15  init();  16  }  17   18  private function init(e:Event = null):void  19  {  20  var testElement:Element = new Element(0x00AAFF, 1, 10, 10);  21  testElement.x = 50;  22  testElement.y = 50;  23  this.addChild(testElement);  24   25  }  26   27  }  28 } 

First we create the testElement variable which holds our element. We create a new Element and assign that to our testElement variable. Note the arguments we passed: first we give it a color, then the alpha, width and height. If you look in the Element class's Element function, you can see how it uses this data to draw the rectangle.

After creating the Element, we position it and put it on the stage!

## Step 5: Setting Up the Variables

Look at the following code. I wrote the functions of the variables next to them (notice that we imported the necessary classes too):

 1 2 package  3 {  4  import flash.display.Sprite;  5  import flash.text.TextField;  6  import flash.utils.Timer;  7  import flash.events.TimerEvent;  8  import flash.ui.Keyboard;  9  import flash.events.KeyboardEvent;  10  import flash.events.MouseEvent;  11  import flash.events.Event;  12   13  import com.Element;  14   15  public class Main extends Sprite  16  {  17   18  //DO NOT GIVE THESE VARS A VALUE HERE!  19  //Give them their values in the init() function.  20  private var snake_vector:Vector.; //the snake's parts are held in here  21  private var markers_vector:Vector.

The most important variable is the snake_vector. We will put every Element of the snake in this Vector.

Then there is the markers_vector. We will use markers to set the direction of the snake's parts. Each object in this Vector will have a position and a type. The type will tell us whether the snake should go right, left, up, or down after 'hitting' the object. (They won't collide, only the position of the markers and the snake's parts will be checked.)

As an example, if we press DOWN, an object will be created. The x and y of this object will be the snake's head's x and y coordinates, and the type will be "Down". Whenever the position of one of the snake's Elements is the same as this object's, the snakes elements direction will be set to "Down".

## Step 6: Writing the attachElement() Function

The attachElement() function will take four parameters: the new snake element, the x and y coordinates, and the direction of the last part of the snake.

 1 2 private function attachElement(who:Element,lastXPos:Number = 0,lastYPos:Number = 0,dirOfLast:String = "R"):void  3 {  4 5 } 

Before we put the element on the stage we should position it. But for this we need the direction of the snake's last element, to know whether the new element has to be above, under, or next to this.

After checking the direction and setting the position, we can add it to the stage.

 1 2 private function attachElement(who:Element,lastXPos:Number = 0,lastYPos:Number = 0,dirOfLast:String = "R"):void  3 {  4  if (dirOfLast == "R")  5  {  6  who.x = lastXPos - snake_vector[0].width - space_value;  7  who.y = lastYPos;  8  }  9  else if(dirOfLast == "L")  10  {  11  who.x = lastXPos + snake_vector[0].width + space_value;  12  who.y = lastYPos;  13  }  14  else if(dirOfLast == "U")  15  {  16  who.x = lastXPos;  17  who.y = lastYPos + snake_vector[0].height + space_value;  18  }  19  else if(dirOfLast == "D")  20  {  21  who.x = lastXPos;  22  who.y = lastYPos - snake_vector[0].height - space_value;  23  }  24  this.addChild(who);  25 } 

Now we can use this function in the init() function:

 1 2 for(var i:int=0;i ]  10  attachElement(snake_vector[i],0,0,snake_vector[i].direction)  11  snake_vector[0].alpha = 0.7;  12  }  13  else  14  {  15  attachElement(snake_vector[i], snake_vector[i - 1].x, snake_vector[i - 1].y, snake_vector[i - 1].direction);  16  }  17 } 

We create the first 10 Elements, and set the direction of them to 'R' (right). If it is the first element, we call attachElement() and we change its alpha a bit (so the "head" is a slightly lighter color).

If you wish to set the position somewhere else, then please keep the following in mind: the snake has to be placed on a grid, otherwise it would look bad and would not work. If you wish to change the x and y position you can do it the following way:

Setting the x position: (snake_vector[0].width+space_value)*[UINT], where you should replace [UINT] with a positive integer.

Setting the y position: (snake_vector[0].height+space_value)*[UINT], where you should replace [UINT] with a positive integer.

Let's change it to this:

 1 2 if (i == 0)//first snake element  3 {  4  //you have to place the first element on a GRID. (now: 0,0)  5  //[possible x positions: (snake_vector[0].width+space_value)*]  6  attachElement(  7  snake_vector[i],  8  (snake_vector[0].width+space_value)*20,  9  (snake_vector[0].height+space_value)*10,  10  snake_vector[i].direction  11  );  12  snake_vector[0].alpha = 0.7;  13 } 

And the snake's first element is set onto the 20th space in the x-grid and 10th space in the y-grid.

This is what we've got so far:

 1 2 package  3 {  4  import flash.display.Sprite;  5  import flash.text.TextField;  6  import flash.utils.Timer;  7  import flash.events.TimerEvent;  8  import flash.ui.Keyboard;  9  import flash.events.KeyboardEvent;  10  import flash.events.MouseEvent;  11  import flash.events.Event;  12   13  import com.Element;  14   15  public class Main extends Sprite  16  {  17   18  //DO NOT GIVE THEM A VALUE HERE! Give them a value in the init() function  19  private var snake_vector:Vector.; //the snake's parts are held in here  20  private var markers_vector:Vector.

## Step 7: Writing the placeApple() Function

This function does the following:

1. It checks whether the apple was caught. For this we will use the caught parameter, and set its default value to true, in case we don't pass any value as parameters in the future. If it was caught, it adds 10 to the apple's score value (so the next apple is worth more).
2. After this the apple has to be repositioned (we don't create new apples) at a random grid position.
3. If it is placed on the snake, we should place it somewhere else.
4. If it is not on the stage yet, we place it there.

 1 2 private function placeApple(caught:Boolean = true):void  3 {  4  if (caught)  5  apple.catchValue += 10;  6   7  var boundsX:int = (Math.floor(stage.stageWidth / (snake_vector[0].width + space_value)))-1;  8  var randomX:Number = Math.floor(Math.random()*boundsX);  9   10  var boundsY:int = (Math.floor(stage.stageHeight/(snake_vector[0].height + space_value)))-1;  11  var randomY:Number = Math.floor(Math.random()*boundsY);  12 13  apple.x = randomX * (apple.width + space_value);  14  apple.y = randomY * (apple.height + space_value);  15   16  for(var i:uint=0;i

There will be some math here, but if you think it through you should understand why it is so. Just draw it out on some paper if necessary.

• boundsX will hold how many elements could be drawn in one row.
• randomX takes this boundsX, multiplies it with a Number between zero and one, and floors it. If boundsX is 12 and the random Number is 0.356, then floor(12*0.356) is 4, so the apple will be placed on the 4th spot on the x-grid.
• boundsY will hold how many elements can be drawn in one column.
• randomY takes this boundsY, multiplies it with a Number between zero and one, and floors it.
• Then we set the x and y position to these numbers.

In the for loop, we check whether the apple's new x and y positions are identical to any of the snake_vectors elements. If so, we call the placeApple() function again (recursive function), and set the parameter of it to false. (Meaning that the apple was not caught, we just need to reposition it)

(apple.stage) returns true if the apple is on the stage. we use the '!' operator to invert that value, so if it is NOT on the stage, we place it there.

The last thing we need to do is call the placeApple() function at the end of the init() function.

 1 2 private function init(e:Event = null):void  3 {  4  /*  5  .  6  .  7  .  8  */  9   10  placeApple(false);  11 } 

Notice that we pass false as the parameter. It's logical, because we didn't catch the apple in the init() function yet. We will only catch it in the moveIt() function.

Now there are only three more functions to write: the directionChanged(), moveIt() and the gameOver() functions.

## Step 8: Starting the moveIt() Function

The moveIt() function is responsible for all of the movement. This function will check the boundaries and check whether there is an object at the x and y position of the snake's head. It will also look for the apple at this position.

For all of this, we will use our timer variable.

Add two more lines in the end of the init() function:

 1 2 timer.addEventListener(TimerEvent.TIMER,moveIt);  3 timer.start(); 

Look at the comments in the sourcecode, to see which block of code does what.

 1 2  private function moveIt(e:TimerEvent):void  3  {  4  if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)  5  {  6  //This code runs if the snakes heads position and the apples position are the same  7  }  8   9  if (snake_vector[0].x > stage.stageWidth-snake_vector[0].width || snake_vector[0].x < 0 || snake_vector[0].y > stage.stageHeight-snake_vector[0].height || snake_vector[0].y < 0)  10  {  11  //This block runs if the snakes head is out of the stage (hitting the walls)  12  }  13   14   15  for (var i:int = 0; i < snake_vector.length; i++)  16  {  17  /*  18  START OF FOR BLOCK  19  This whole 'for' block will run as many times, as many elements the snake has.  20  If there are four snake parts, this whole for cycle will run four times.  21  */  22   23  if (snake_vector[i] != snake_vector[0] && (snake_vector[0].x == snake_vector[i].x && snake_vector[0].y == snake_vector[i].y))  24  {  25  //If the snakes heads position is the same as any of the snake parts, this block will run (Checking the collision with itself).  26  }  27   28  if (markers_vector.length > 0)  29  {  30  //if there are direction markers, this code runs  31  }  32   33   34  var DIRECTION:String = snake_vector[i].direction; //getting the direction of the current snake element.  35  switch (DIRECTION)  36  {  37  //Sets the new position of the snakes part  38  }  39   40  /*  41  END OF FOR BLOCK  42  */  43  }  44   45  } 

Now we need to code the movement. For this we jump into the switch block, which will run on every snake part, because of the for loop.

First we need to check the direction of the current element.

 1 2  switch (DIRECTION)  3  {  4  case "R" :  5  //Here we need to set the new x position for the current part  6  break;  7  case "L" :  8  //Here we need to set the new x position for the current part  9  break;  10  case "D" :  11  //Here we need to set the new y position for the current part  12  break;  13  case "U" :  14  //Here we need to set the new y position for the current part  15  break;  16  } 

When the direction of the part is set to "R", for instance, we need to add something to its current X position (the space_value plus the width of the snake part).

With this in mind, we can fill it out:

 1 2  switch (DIRECTION)  3  {  4  case "R" :  5  snake_vector[i].x += snake_vector[i].width + space_value;  6  break;  7  case "L" :  8  snake_vector[i].x -= snake_vector[i].width + space_value;  9  break;  10  case "D" :  11  snake_vector[i].y += snake_vector[i].height + space_value;  12  break;  13  case "U" :  14  snake_vector[i].y -= snake_vector[i].width + space_value;  15  break;  16  } 

After testing the code, you should see that the snake is moving, and going off the stage and never stops. (You may need to refresh the page - or just click here to load it in a new window.)

So we need to stop the snake

## Step 9: Writing the gameOver() Function

This function is going to be the shortest. We just clear the stage and restart it:

 1 2 private function gameOver():void  3 {  4  dead = true;  5  timer.stop();  6  while (this.numChildren)  7  this.removeChildAt(0);  8  timer.removeEventListener(TimerEvent.TIMER,moveIt);  9  init();  10 } 

That's it. We set the dead variable to true, stop the movement with the timer, remove every child of the class and call the init() function, like we just started the game.

Now, let's get back to the moveIt() function.

## Step 10: Continuing the moveIt() Function

We will use the gameOver() function in two places. The first is when we check if the head is out of bounds, and the second is when the snake hits itself:

 1 2  private function moveIt(e:TimerEvent):void  3  {  4  if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)  5  {  6  //This code runs if the snakes heads position and the apples position are the same  7  }  8   9  if (snake_vector[0].x > stage.stageWidth-snake_vector[0].width || snake_vector[0].x < 0 || snake_vector[0].y > stage.stageHeight-snake_vector[0].height || snake_vector[0].y < 0)  10  {  11  gameOver();  12  }  13   14   15  for (var i:int = 0; i < snake_vector.length; i++)  16  {  17  /*  18  START OF FOR BLOCK  19  This whole 'for' block will run as many times, as many elements the snake has.  20  If there are four snake parts, this whole for cycle will run four times.  21  */  22   23  if (snake_vector[i] != snake_vector[0] && (snake_vector[0].x == snake_vector[i].x && snake_vector[0].y == snake_vector[i].y))  24  {  25  //If the snakes heads position is the same as any of the snake parts, this block will run  26  gameOver();  27  }  28   29  if (markers_vector.length > 0)  30  {  31  //if there are direction markers, this code runs  32  }  33   34   35  var DIRECTION:String = snake_vector[i].direction; //getting the direction of the current snake element.  36  switch (DIRECTION)  37  {  38  case "R" :  39  snake_vector[i].x += snake_vector[i].width + space_value;  40  break;  41  case "L" :  42  snake_vector[i].x -= snake_vector[i].width + space_value;  43  break;  44  case "D" :  45  snake_vector[i].y += snake_vector[i].height + space_value;  46  break;  47  case "U" :  48  snake_vector[i].y -= snake_vector[i].width + space_value;  49  break;  50  }  51   52  /*  53  END OF FOR BLOCK  54  */  55  }  56   57  } 

This is the code we have now:

 1 2 package  3 {  4  import flash.display.Sprite;  5  import flash.text.TextField;  6  import flash.utils.Timer;  7  import flash.events.TimerEvent;  8  import flash.ui.Keyboard;  9  import flash.events.KeyboardEvent;  10  import flash.events.MouseEvent;  11  import flash.events.Event;  12   13  import com.Element;  14   15  public class Main extends Sprite  16  {  17   18  //DO NOT GIVE THEM A VALUE HERE! Give them a value in the init() function  19  private var snake_vector:Vector.; //the snake's parts are held in here  20  private var markers_vector:Vector.

## Step 11: The directionChanged() Function

We want to listen to the keyboard, so we can actually control the snake. For this we need to put some code into the init() function and the gameOver() function.

Put this at the end of the init() function (setting up the listener function):

 1 2 stage.addEventListener(KeyboardEvent.KEY_DOWN,directionChanged); 

And this at the end of the gameOver() function:

 1 2 stage.removeEventListener(KeyboardEvent.KEY_DOWN,directionChanged); 

Now create a new function:

 1 2 private function directionChanged(e:KeyboardEvent):void  3 {  4  var m:Object = new Object(); //MARKER OBJECT  5  //this will be added to the markers_vector, and have the properties x,y, and type  6  //the type property will show us the direction. if it is set to right, whenever a snake's part hits it,  7  //the direction of that snake's part will be set to right also  8   9  if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT)  10  {  11  //If we pressed the LEFT arrow,  12  //and it was not the last key we pressed,  13  //and the last key pressed was not the RIGHT arrow either...  14  //Then this block of code will run  15  }  16  markers_vector.push(m); //we push the object into a vector, so we can acces to it later (in the moveIt() function)  17 } 

What goes into the if block?

• The direction of the head should be rewritten.
• The marker object has to be set correctly.
• The last_button variable should be set to the last button pressed.

 1 2 if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT && flag)  3 {  4  snake_vector[0].direction = "L";  5  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"L"};  6  last_button_down = Keyboard.LEFT;  7 } 

Repeat this three more times, and we will have this:

 1 2 private function directionChanged(e:KeyboardEvent):void  3  {  4  var m:Object = new Object(); //MARKER OBJECT  5 6  if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT)  7  {  8  snake_vector[0].direction = "L";  9  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"L"};  10  last_button_down = Keyboard.LEFT;  11  }  12  else if (e.keyCode == Keyboard.RIGHT && last_button_down != e.keyCode && last_button_down != Keyboard.LEFT)  13  {  14  snake_vector[0].direction = "R";  15  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"R"};  16  last_button_down = Keyboard.RIGHT;  17  }  18  else if (e.keyCode == Keyboard.UP && last_button_down != e.keyCode && last_button_down != Keyboard.DOWN)  19  {  20  snake_vector[0].direction = "U";  21  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"U"};  22  last_button_down = Keyboard.UP;  23  }  24  else if (e.keyCode == Keyboard.DOWN && last_button_down != e.keyCode && last_button_down != Keyboard.UP)  25  {  26  snake_vector[0].direction = "D";  27  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"D"};  28  last_button_down = Keyboard.DOWN;  29  }  30  markers_vector.push(m);  31  } 

We need one more thing to test it. In the moveIt() function we have something like this:

 1 2  if (markers_vector.length > 0)  3  {  4  //if there are direction markers, this code runs  5  } 

Here we need another for loop, to check every snake's part against every marker on the stage, and check whether they collide. If they do, we need to set the snake's part's direction to the marker's type. If it's the last snake part which collides with the marker, we need to remove the marker from the markers_vector, too, so the snake parts don't collide with it any more.

 1 2  if (markers_vector.length > 0)  3  {  4  for(var j:uint=0;j < markers_vector.length;j++)  5  {  6  if(snake_vector[i].x == markers_vector[j].x && snake_vector[i].y == markers_vector[j].y)  7  {  8  //setting the direction  9  snake_vector[i].direction = markers_vector[j].type;  10  if(i == snake_vector.length-1)  11  {  12  //if its the last snake_part  13  markers_vector.splice(j, 1);  14  }  15  }  16  }  17  } 

Now if you play with it it looks okay, but there is a bug in there. Remember what i said at the beginning of the tutorial?

For instance, if the snake is going to the right and you press the down-left combo very fast, it will hit itself and restart the game.

How do we correct this? Well it's easy. We have our flag variable, and we will use that for this. We will only be able to change the directions of the snake when this is set to true (Default is false, check the init() function for that).

So we need to change the directionChanged() function a little. The if blocks' heads should be changed: add a && flag clause at the end of every 'if'.

 1 2  private function directionChanged(e:KeyboardEvent):void  3  {  4  var m:Object = new Object(); //MARKER OBJECT  5 6  if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT && flag)  7  {  8  snake_vector[0].direction = "L";  9  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"L"};  10  last_button_down = Keyboard.LEFT;  11  flag = false;  12  }  13  else if (e.keyCode == Keyboard.RIGHT && last_button_down != e.keyCode && last_button_down != Keyboard.LEFT && flag)  14  {  15  snake_vector[0].direction = "R";  16  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"R"};  17  last_button_down = Keyboard.RIGHT;  18  flag = false;  19  }  20  else if (e.keyCode == Keyboard.UP && last_button_down != e.keyCode && last_button_down != Keyboard.DOWN && flag)  21  {  22  snake_vector[0].direction = "U";  23  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"U"};  24  last_button_down = Keyboard.UP;  25  flag = false;  26  }  27  else if (e.keyCode == Keyboard.DOWN && last_button_down != e.keyCode && last_button_down != Keyboard.UP && flag)  28  {  29  snake_vector[0].direction = "D";  30  m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"D"};  31  last_button_down = Keyboard.DOWN;  32  flag = false;  33  }  34  markers_vector.push(m);  35  } 

If you test it now, it won't work because the flag is always false.

When do we need to set it to true then?

After a move/tick we can allow the users to change directions, we just don't want to change it twice in one tick. So put this at the very end of the moveIt() function:

 1 2 flag = true; 

Now test it, and there is no bug any more.

## Step 12: Finishing the Game

Now the only thing we need to do is the 'apple-check'

Remember this at the very beginning of the moveIt() function?

 1 2  if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)  3  {  4  //This code runs if the snake's head's position and the apple's position are the same  5  } 

This is what we need to do in there:

• Call the placeApple() function. (We don't set the parameter to false; we leave it as it is. The default is true.)
• Show the current score
• Attach a new element to the snake's last part.

 1 2  if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)  3  {  4  //calling the placeApple() function  5  placeApple();  6  //show the current Score  7  score += apple.catchValue;  8  score_tf.text = "Score:" + String(score);  9  //Attach a new snake Element  10  snake_vector.push(new Element(0x00AAFF,1,10,10));  11  snake_vector[snake_vector.length-1].direction = snake_vector[snake_vector.length-2].direction; //lastOneRichtung  12  //attachElement(who,lastXPos,lastYPos,lastDirection)  13  attachElement(snake_vector[snake_vector.length-1],  14  (snake_vector[snake_vector.length-2].x),  15  snake_vector[snake_vector.length-2].y,  16  snake_vector[snake_vector.length-2].direction);  17  } 

Now everything should work fine. Try it out:

Here is the whole Main class again:

 1 2  package  3 {  4  import flash.display.Sprite;  5  import flash.text.TextField;  6  import flash.utils.Timer;  7  import flash.events.TimerEvent;  8  import flash.ui.Keyboard;  9  import flash.events.KeyboardEvent;  10  import flash.events.MouseEvent;  11  import flash.events.Event;  12   13  import com.Element;  14   15  public class Main extends Sprite  16  {  17  //DO NOT GIVE THEM A VALUE HERE! Give them a value in the init() function  18  private var snake_vector:Vector.; //the snake's parts are held in here  19  private var markers_vector:Vector.

## Step 13: Summing It All Up

Congratulations! You have just created a nice game. Now you can develop it further, and create a super apple or something. For that I recommend using another function called placeSuperApple() and a new class named SuperApple. Whenever you catch a super apple, the snakes parts could lengthen by three elements, perhaps. This could be set with setters/getters in the SuperApple` class.

If you wish to do this, and you get stuck somewhere, just leave me a comment here.