AS3 level editor

Almost a year ago I blogged about a basic level editor for a tile based game, and now Philipp Zins from Germany show us his AS3 level editor-

I made the level editor in ActionScript 3. You can scroll through the tiles with the mouse wheel – it isn’t necessary now, but very helpful if you use many, many tiles. You can change the map size and activate the “Generate”-Button by clicking or pressing Return.You can scroll the map, too. The finished array will be traced. The tile graphics are a little different – you will see that. I think I used some german words in the code, sorry.

Prepare yourself for a quite long source code…

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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/*1. variables
 
2.UI
2.1. map: height+width options, generate button
2.2. selectable tiles
 
3. functions
3.1. selectable tiles
3.1.1. current tile
3.1.2 scrolling
3.2. generate button
3.2.1. on Enter, too
3.2.2. generate map
3.2.2.1. get width, height
3.2.2.2. place containers
3.2.2.3. add tiles, map array	
3.2.2.4. add scrollbars
3.2.2.5. add masks
3.2.2.6. add btnArray
3.3. edit map
3.4. scroll map
3.4.1. scroll map: y-direction
3.4.2. scroll map: x-direction
3.5. trace array
*/
 
 
//1. variables
var tile_size = 20;
var totalTiles:int = currentTile_mc.totalFrames;
var currentTile:int = 0;
var map:Array = new Array();
//Sprites, Movieclips (+Positions)
var selection_container:Sprite;
var t:Tile; 
var map_height;
var map_width;
var level_container:Sprite;
var level_container_xPos = 65;
var level_container_yPos = 60;
var map_sprite_height:int = 0;
var map_sprite_width:int = 0;
var maskedView_map:Map_Maske;
var map_mask_height:int = 340;
var map_mask_width:int = 400;
var scroll_y_container:Sprite;
var scroll_y_container_yPos = 60;
var scrolltrack_y:Scrolltrack_y;
var scrollhead_y:Scrollhead_y;
var scroll_x_container:Sprite;
var scroll_x_container_xPos = 65;
var scrolltrack_x:Scrolltrack_x;
var scrollhead_x:Scrollhead_x;
var raster_x_container:Sprite;
var raster_x_container_xPos = 60;
var maskedView_raster_x:Raster_x_Maske;
var raster_y_container:Sprite;
var raster_y_container_yPos = 60;
var maskedView_raster_y:Raster_y_Maske;
var btnArray:ArrayButton;
var mapString:String = "";
//TextFormat
var format:TextFormat = new TextFormat();
format.size = 10;
format.align = TextFormatAlign.CENTER;
 
 
//2.UI
//2.1. map: height+width options, generate button
height_mc.height_txt.restrict = "0-9";
width_mc.width_txt.restrict = "0-9";
btnGenerate.addEventListener(MouseEvent.MOUSE_DOWN, generateMap);
 
//2.2. selectable tiles
selection_container = new Sprite();
selection_container.x = 10;
selection_container.y = 80;
for (var i:int; i<totalTiles; i++) {
	t = new Tile();
	t.gotoAndStop(i + 1);
	selection_container.addChild(t);
	t.y = (tile_size) * i;
	t.addEventListener(MouseEvent.MOUSE_DOWN, selectionClick);
}
var maskedView:Maske = new Maske();
selection_container.addChild(maskedView);
selection_container.mask=maskedView;
addChild(selection_container);
 
 
//3. functions
//3.1. selectable tiles
//3.1.1. current tile
function selectionClick (event:MouseEvent):void {
	currentTile = event.currentTarget.currentFrame;
	currentTile_mc.gotoAndStop(currentTile);
}
//3.1.2 scrolling
stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); 
var scroll_speed = 10;
var scroll_speed_multiplikator = 8;
function onMouseWheel (event:MouseEvent):void {
   if(event.delta < 0){
      //trace ("MouseWheel down");
	  selection_container.y += scroll_speed;
	  maskedView.y -= scroll_speed;
	} 
	else {
      //trace ("MouseWheel up");
	  selection_container.y -= scroll_speed;
	  maskedView.y += scroll_speed;
   }
}
up.addEventListener(MouseEvent.MOUSE_DOWN, scroll_up);
function scroll_up(event:MouseEvent):void {
	selection_container.y -= scroll_speed*scroll_speed_multiplikator;
	maskedView.y += scroll_speed*scroll_speed_multiplikator;
}
down.addEventListener(MouseEvent.MOUSE_DOWN, scroll_down);
function scroll_down(event:MouseEvent):void {
	selection_container.y += scroll_speed*scroll_speed_multiplikator;
	maskedView.y -= scroll_speed*scroll_speed_multiplikator;
}	
reset.addEventListener(MouseEvent.MOUSE_DOWN, scroll_start);
function scroll_start(event:MouseEvent):void {
	selection_container.y = 80;
	maskedView.y = 0;
}
 
//3.2. generate button
//3.2.1. on Enter, too
stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
function key_down(event:KeyboardEvent) {
	if (event.keyCode == 13) {	//Enter?
		generateMap();	
	}
}
//3.2.2. generate map
//3.2.2.1. get width, height
function generateMap(evt:MouseEvent = null):void {
	map_height =  height_mc.height_txt.text;
	map_width =  width_mc.width_txt.text;
//3.2.2.2. place containers
	if (level_container) {
		removeChild(level_container);
		removeChild(raster_x_container);
		removeChild(raster_y_container);
		removeChild(scroll_y_container);
		removeChild(scroll_x_container);
		removeChild(btnArray);
		map = []; 
    } 
	scroll_x_container = new Sprite ();
	scroll_x_container.x = scroll_x_container_xPos;
	scroll_x_container.y = 415;
	addChild(scroll_x_container);
	scroll_y_container = new Sprite ();
	scroll_y_container.x = 480;
	scroll_y_container.y = scroll_y_container_yPos;
	addChild(scroll_y_container);
	raster_x_container = new Sprite ();
	raster_x_container.x = raster_x_container_xPos;
	raster_x_container.y = 40;
	addChild(raster_x_container);	
	raster_y_container = new Sprite ();
	raster_y_container.x = 50;
	raster_y_container.y = raster_y_container_yPos;
	addChild(raster_y_container);	
	level_container = new Sprite();	
	level_container.x = level_container_xPos;
	level_container.y = level_container_yPos;
	addChild(level_container);							
//3.2.2.3. add tiles, map array	
	for (var a=0; a<map_height; a++) {				//rows
		var raster_y:TextField = new TextField ();
		raster_y.defaultTextFormat = format;
		raster_y.text = ""+a;
		raster_y_container.addChild(raster_y);
		raster_y.x = 0-48;
		raster_y.y = a*tile_size+2;
		raster_y.selectable = false;
		map[a] = new Array();						
		for (var b=0; b<map_width; b++) {				//columns
			if (a==0) {
				var raster_x:TextField = new TextField ();
				raster_x.defaultTextFormat = format;
				raster_x.text = ""+b;
				raster_x_container.addChild(raster_x);
				raster_x.x = b*tile_size+10-46;
				raster_x.y = 0;
				raster_x.selectable = false;
			}
			t = new Tile();				
			t.x = b*tile_size;						
			t.y = a*tile_size;						
			t.gotoAndStop(0);					
			map[a][b] = t.currentFrame-1;						
			level_container.addChild(t);			
			t.addEventListener(MouseEvent.MOUSE_DOWN, editClick);
		}
	}
//3.2.2.4. add scrollbars
	//y-Scrollbar
	map_sprite_height = map_height*tile_size;
	scrolltrack_y = new Scrolltrack_y ();
	scroll_y_container.addChild(scrolltrack_y);
	scrollhead_y = new Scrollhead_y ();
	scroll_y_container.addChild(scrollhead_y);
	if (map_sprite_height <=  map_mask_height) {
		scrollhead_y.height = map_mask_height;
	}
	else {
		scrollhead_y.height = map_mask_height/map_sprite_height*map_mask_height; 
	}
	scrollhead_y.addEventListener(MouseEvent.MOUSE_DOWN, scroll_map_y_start);
	scrollhead_y.addEventListener(MouseEvent.MOUSE_UP, scroll_map_y_stop);
	//x-Scrollbar
	map_sprite_width = map_width*tile_size;
	scrolltrack_x = new Scrolltrack_x ();
	scroll_x_container.addChild(scrolltrack_x);
	scrollhead_x = new Scrollhead_x ();
	scroll_x_container.addChild(scrollhead_x);
	if (map_sprite_width <=  map_mask_width) {
		scrollhead_x.width = map_mask_width;
	}
	else {
		scrollhead_x.width = map_mask_width/map_sprite_width*map_mask_width; 
	}
	scrollhead_x.addEventListener(MouseEvent.MOUSE_DOWN, scroll_map_x_start);
	scrollhead_x.addEventListener(MouseEvent.MOUSE_UP, scroll_map_x_stop);
//3.2.2.5. add masks
	//mask for map
	maskedView_map = new Map_Maske();
	level_container.addChild(maskedView_map);
	level_container.mask=maskedView_map;
	//mask for x-scale
	maskedView_raster_x = new Raster_x_Maske ();
	raster_x_container.addChild(maskedView_raster_x);
	raster_x_container.mask=maskedView_raster_x;
	//mask for y-scale
	maskedView_raster_y = new Raster_y_Maske ();
	maskedView_raster_y.x = -5;
	raster_y_container.addChild(maskedView_raster_y);
	raster_y_container.mask=maskedView_raster_y;
//3.2.2.6. add btnArray
	btnArray = new ArrayButton ();
	btnArray.x = 390;
	btnArray.y = 7;
	addChild(btnArray);
	btnArray.addEventListener(MouseEvent.MOUSE_DOWN, traceArray);
}
 
//3.3. edit map
function editClick (event:MouseEvent):void {
	event.currentTarget.gotoAndStop(currentTile);
	var mouse_x = Math.floor((mouseX-level_container.x)/tile_size);
	var mouse_y = Math.floor((mouseY-level_container.y)/tile_size);
	map[mouse_y][mouse_x] = event.currentTarget.currentFrame-1;
}
 
//3.4. scroll map
//3.4.1. scroll map: y-direction
function scroll_map_y_start(event:MouseEvent):void {
	scrollhead_y.removeEventListener(MouseEvent.MOUSE_DOWN, scroll_map_y_start);
	stage.addEventListener(MouseEvent.MOUSE_MOVE, scroll_y); 
	stage.addEventListener(MouseEvent.MOUSE_UP, scroll_map_y_stop);
}
function scroll_map_y_stop(event:MouseEvent):void {
	scrollhead_y.addEventListener(MouseEvent.MOUSE_DOWN, scroll_map_y_start);
	stage.removeEventListener(MouseEvent.MOUSE_MOVE, scroll_y); 
	stage.removeEventListener(MouseEvent.MOUSE_UP, scroll_map_y_stop);
}
function scroll_y(event:MouseEvent):void {
    if (mouseY-scroll_y_container_yPos-scrollhead_y.height/2>=0 && mouseY-scroll_y_container_yPos<=scrolltrack_y.height-scrollhead_y.height+scrollhead_y.height/2) {   
		scrollhead_y.y = mouseY-scroll_y_container_yPos-scrollhead_y.height/2;
	}
	else {
		if (mouseY-scroll_y_container_yPos-scrollhead_y.height/2<0) {
			scrollhead_y.y = 0;
		}
		else {
			scrollhead_y.y = scrolltrack_y.height-scrollhead_y.height;
		}
	}
	if (map_sprite_height <=  map_mask_height) {
		level_container.y = level_container_yPos;
 
		raster_y_container.y = raster_y_container_yPos;
 
	}
	else {
		level_container.y = level_container_yPos-(map_sprite_height-scrolltrack_y.height)*scrollhead_y.y/(scrolltrack_y.height-scrollhead_y.height);
		maskedView_map.y =(map_sprite_height-scrolltrack_y.height)*scrollhead_y.y/(scrolltrack_y.height-scrollhead_y.height);
 
		raster_y_container.y = raster_y_container_yPos-(map_sprite_height-scrolltrack_y.height)*scrollhead_y.y/(scrolltrack_y.height-scrollhead_y.height);
		maskedView_raster_y.y =(map_sprite_height-scrolltrack_y.height)*scrollhead_y.y/(scrolltrack_y.height-scrollhead_y.height);
	}
} 
//3.4.2. scroll map: x-direction
function scroll_map_x_start(event:MouseEvent):void {
	scrollhead_x.removeEventListener(MouseEvent.MOUSE_DOWN, scroll_map_x_start);
	stage.addEventListener(MouseEvent.MOUSE_MOVE, scroll_x); 
	stage.addEventListener(MouseEvent.MOUSE_UP, scroll_map_x_stop);
}
function scroll_map_x_stop(event:MouseEvent):void {
	scrollhead_x.addEventListener(MouseEvent.MOUSE_DOWN, scroll_map_x_start);
	stage.removeEventListener(MouseEvent.MOUSE_MOVE, scroll_x); 
	stage.removeEventListener(MouseEvent.MOUSE_UP, scroll_map_x_stop);
}
function scroll_x(event:MouseEvent):void {
	    if (mouseX-scroll_x_container_xPos-scrollhead_x.width/2>=0 && mouseX-scroll_x_container_xPos<=scrolltrack_x.width-scrollhead_x.width+scrollhead_x.width/2) {   
		scrollhead_x.x = mouseX-scroll_x_container_xPos-scrollhead_x.width/2;
	}
	else {
		if (mouseX-scroll_x_container_xPos-scrollhead_x.width/2<0) {
			scrollhead_x.x = 0;
		}
		else {
			scrollhead_x.x = scrolltrack_x.width-scrollhead_x.width;
		}
	}
	if (map_sprite_width <=  map_mask_width) {
		level_container.x = level_container_xPos;
 
		raster_x_container.x = raster_x_container_xPos;
 
	} 
	else {
		level_container.x = level_container_xPos-(map_sprite_width-scrolltrack_x.width)*scrollhead_x.x/(scrolltrack_x.width-scrollhead_x.width);
		maskedView_map.x =(map_sprite_width-scrolltrack_x.width)*scrollhead_x.x/(scrolltrack_x.width-scrollhead_x.width);
 
		raster_x_container.x = raster_x_container_xPos-(map_sprite_width-scrolltrack_x.width)*scrollhead_x.x/(scrolltrack_x.width-scrollhead_x.width);
		maskedView_raster_x.x =(map_sprite_width-scrolltrack_x.width)*scrollhead_x.x/(scrolltrack_x.width-scrollhead_x.width);
	}
}
 
//3.5. trace array
function traceArray(evt:MouseEvent):void {
	mapString = "";
	for (var i:int; i<map_height; i++) {	//rows
		mapString += "map["+i+"]=[";
		for (var j:int; j<map_width; j++) {		//columns
			mapString += map[i][j];
			if (j<map_width-1) {
				mapString += ", ";
			}
		}
		mapString += "]; \n"; 
		j = 0;
	}
	trace (mapString);
}

And this is the result:

Download the source code

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

  1. HiddenSpartan

    on September 18, 2009 at 4:16 am

    I made one of these a while ago. Can be found here. I’ve still got the source for the builder and the engine, (neither are 100% complete or stable, but they still work) and I’ll release them if anybody wants them.

  2. Vadersapien

    on September 18, 2009 at 9:10 am

    Extremely Slow…I the following message from Flash Player: “Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
    at FeronatoLevelEditor_fla::MainTimeline/generateMap()”

    And the computer I use is NOT SLOW (Intel Core 2 Quad, 4gb RAM, 1gb graphics RAM)

  3. Nathan

    on September 18, 2009 at 11:39 pm

    Hmmm…

    A click and drag function would be useful, so I don’t kill my wrist making one level.

  4. sascha/hdrs

    on September 19, 2009 at 5:46 am

    Hmm doesn’t work for me. I cannot place any tiles. Is that above timeline code?? Oh wait .. it almost looks like AS2 .. uuh ahhhh… my eyes!! ;)

  5. Guest

    on September 19, 2009 at 10:22 am

    i click on Show array and i get nothing…
    this level editor shows a preview? (it should)

  6. maw

    on September 19, 2009 at 11:28 am

    too much lines of code – is this really neccesary for this post ?

  7. Pipo (=Phil)

    on September 20, 2009 at 2:57 pm

    Hi everybody!
    Sorry, if that one is a little bit slow. I just began with Flash one month ago and this is my first Flash app I build myself without any Tutorials.
    I know it’s not perfect, but I worked hard on this one.
    Anyway, I hope that the code will be helpful for somebody :-)

  8. dim

    on September 20, 2009 at 8:30 pm

    i think for BASIC editor is good … indeed it’s a buggy and slow but … that’s why it’s called BASIC

  9. Sprite l?sst sich nicht l?schen - Flashforum

    on September 22, 2009 at 11:02 am

    [...] [...]

  10. Flash Professional 2009

    on October 30, 2009 at 11:00 pm

    Ok… This is what I have when I use this script you made Pipo…

    http://img11.imageshack.us/img11/7879/savebg.jpg

    I don’t know if bb code is allowed but ill try it anyway…
    [img]http://img11.imageshack.us/img11/7879/savebg.jpg[/img]

    But those are all the errors I get…

    DO I have to make all of things my self?