How to make a snake game in flash with Actionscript 3

I’ve written a basic snake game to show you how this can be done in AS3. You can open up flex builder, paste the code in a new actionscript class and run it right away. (Get the class file here).

You’ll probably notice that the game doesn’t check for collisions with the snake itself or the border. Maybe I’ll do a part 2 where I complete the game a bit more.

Anyway, here’s the code for the basic functionality:

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
package {
 
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.events.TimerEvent;
	import flash.ui.Keyboard;
	import flash.utils.Timer;
 
	[SWF(width='430', height='430', frameRate='30')]
 
	public class Snake extends Sprite{
 
		private const SPEED : uint = 60;//lower = faster
		private const DIM : int = 15; //keep this number uneven to have the snake starting in the middle
		private const INITIAL_SIZE : int = 3; //keep this lower then DIM/2
 
		private var left : Boolean;
		private var right : Boolean;
		private var up : Boolean;
		private var down : Boolean;
		private var size : Number;
		private var food : Sprite;
		private var tmr : Timer;
		private var curI : Number;
		private var curJ : Number;
		private var snake : Array;
		private var grid : Array;
 
		public function Snake(){
			size = stage.stageWidth / DIM;
			curI = curJ = Math.floor(DIM * 0.5);
 
			initSnake();
			fillGrid();
			placeFood();
 
			tmr = new Timer(SPEED);
			tmr.addEventListener(TimerEvent.TIMER,move);
			tmr.start();
 
			stage.addEventListener(KeyboardEvent.KEY_DOWN,changeDir);
		}
 
		private function fillGrid():void{
			grid = Make2DArray();
 
			for (var i:uint = 0; i < DIM; i++){
				for (var j:uint = 0; j < DIM; j++){
					var sp:Sprite = new Sprite();
					sp.graphics.beginFill(0xF0F0F0);
					sp.graphics.lineStyle(1,0xF5F5F5);
					sp.graphics.drawRect(0, 0, size  - 1, size - 1);
					sp.x = i * size;
					sp.y = j * size;
					addChild(sp);
					grid[i][j] = sp;
				}
			}	
		}
 
		private function Make2DArray():Array{
			var a:Array = new Array(DIM);
			for(var i:uint = 0; i < a.length; i++){
			    a[i] = new Array(DIM);
			}	
			return a;
		}
 
		private function initSnake():void{
			var center:Number = Math.floor(DIM * 0.5) * size;
 
			snake = new Array(INITIAL_SIZE);
 
			for (var i:uint = 0; i < INITIAL_SIZE; i++){
				var sp:Sprite = makeItem();
				sp.x = center;
				sp.y = center + i * size;
				addChild(sp);
				snake[i] = sp;
			}
 
			snake.reverse();
		}
 
		private function makeItem(c:uint = 0):Sprite{
			var s:Sprite = new Sprite();
			s.graphics.beginFill(c);
			s.graphics.lineStyle(2,0x333333);
			s.graphics.drawRect(0, 0, size, size);
			return s;
		}
 
		private function placeFood():void{
			var rndI:uint = Math.floor(Math.random() * DIM);
			var rndJ:uint = Math.floor(Math.random() * DIM);
 
			var rndX:Number = grid[rndI][rndJ].x;
			var rndY:Number = grid[rndI][rndJ].y;
 
			if (food != null) removeChild(food);
 
			food = makeItem(Math.random() * 0xFFFFFF);// random color
			food.x = rndX;
			food.y = rndY;
 
			addChild(food);
 
			//redo if the food is on the snake itself
			for (var i:uint = 0; i < snake.length; i++){
				if (rndY == snake[i].y && rndX == snake[i].x){ 
					placeFood();
				}
			} 
		}
 
		private function move(e:TimerEvent):void{
			if (left){
				curI -= 1;
			}else if (right){
				curI += 1;
			}
			if (up){
				curJ -= 1;
			}else if (down){
				curJ += 1;
			}
 
			if (left || right || up || down){
				var s:Sprite = makeItem();
 
				if (curI > DIM - 1) curI = 0;
				if (curJ > DIM - 1) curJ = 0;
 
				if (curI < 0) curI = DIM - 1;
				if (curJ < 0) curJ = DIM - 1;
 
				s.x = grid[curI][curJ].x;
				s.y = grid[curI][curJ].y;
 
				addChild(s);
				snake.push(s);
 
 
				if (Math.floor(s.x) == Math.floor(food.x) && Math.floor(s.y) == Math.floor(food.y) ){
					placeFood();
				} else {
					removeChild(snake[0]);
					snake.shift();
				}
			}
		}
 
		private function changeDir(e:KeyboardEvent):void{
			if(e.keyCode == Keyboard.LEFT)	{if (!right){left = true;  up = false; down = false; right = false;}}
			if(e.keyCode == Keyboard.UP)	{if (!down)	{left = false; up = true;  down = false; right = false;}}
			if(e.keyCode == Keyboard.RIGHT)	{if (!left)	{left = false; up = false; down = false; right = true;}}
			if(e.keyCode == Keyboard.DOWN)	{if (!up)	{left = false; up = false; down = true;  right = false;}}
		}
	}
}

And here is the result. (Press any arrow key to start moving)

This movie requires Flash Player 9

  • Share/Bookmark

5 Comments to “How to make a snake game in flash with Actionscript 3”

  1. Snake Game 15 December 2009 at 10:16 pm #

    A great example, how simple code could be so efficient. I even tried playing it. Good idea in changing the color of object, just make it a bit slower…this is way too fast..
    Great article though

    Thanks

  2. elpideishion 11 March 2010 at 10:01 pm #

    hey, i am doing a snake game in as3 and i want every 100 scores when the snake eats its food to increase the speed of the snake by 20.Do you have any ideas how i will make it work?

  3. mehpac 12 March 2010 at 6:48 pm #

    bad, bad, bad..
    the snake doesn’t :s

  4. andikurnia 27 April 2010 at 6:45 am #

    thanks for the article. I’ll try it firstly…

  5. Chris4 10 June 2010 at 9:48 pm #

    Wish you had a .fla file!


Leave a Reply