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:
They can be easily customized to meet the unique requirements of your project.
















(12 votes, average: 3.58 out of 5)









This post has 10 comments
HiddenSpartan
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.
Vadersapien
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)
Nathan
Hmmm…
A click and drag function would be useful, so I don’t kill my wrist making one level.
sascha/hdrs
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!! ;)
Guest
i click on Show array and i get nothing…
this level editor shows a preview? (it should)
maw
too much lines of code – is this really neccesary for this post ?
Pipo (=Phil)
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 :-)
dim
i think for BASIC editor is good … indeed it’s a buggy and slow but … that’s why it’s called BASIC
Sprite l?sst sich nicht l?schen - Flashforum
[...] [...]
Flash Professional 2009
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?