Building a map editor

As we are building a tile-based isometric map, the whole map is composed grid-by-grid. Every grid is set to a number which represents the graphic of that grid.

When the map dimension is getting larger and when the amount of maps is getting bigger, inputting the texture information into the external map data file can be time-consuming. We usually build a map editor for fast development on the huge amount of map data. Like Warcraft has its own map editor, we will have our own editor for the Flash virtual world.

Building a map editor here can also be a good summarized example for the whole chapter. We will make use of different techniques that we learned in this chapter including tile texturing and coordination conversion.

Building a map editor
  1. Create a new Flash document.
  2. Copy the previously created IsoTile movie clip into the library.
  3. Drag the 10 instances of IsoTile movie clip on stage from the library.
  4. Name the 10 IsoTile instances as brush1 to brush10.
  5. Create a button on stage and name it btnOutput.

The 10 IsoTiles placed on the stage act as the brush texture selector. It is like selecting the color of the brushes in paint application. The button is for us to ask the map editor to output the map drawing into our own map data format.

Let's take a look at the document class of the map editor.

Compared to the previous examples, we added four instance variables to the map editor. _mapWidth and _mapHeight is the dimension of the map. Here we set a 10x10 tiles map. _currentBrush stores the current brush type for painting in the map. The brush type is actually the current frame of the IsoTile because every frame in the IsoTile represents different graphic texture of the tile. The _drawing Boolean variable determines when to paint the map.

private var _mapWidth:Number = 10;
private var _mapHeight:Number = 10;
private var _currentBrush:Number = 1;
private var _drawing:Boolean = false;

The initialize function is similar to the previous example while newly added code is highlighted.

private function init(e:Event):void
{
// For each IsoTile brush, we display one texture by gotoAndStop function. We also add a mouse click event listener to change the brush.
for(var i:int=1;i<=10;i++){
this['brush'+i].gotoAndStop(i+1);
this['brush'+i].addEventListener(MouseEvent. CLICK,onBrushClick);
}
addChild(_mapHolder);
_map = new Array();
for(i=0;i<_mapHeight;i++){
_map[i] = new Array();
for(var j:int=0;j<_mapWidth;j++){
_map[i][j] = new IsoTile();
_mapHolder.addChild(_map[i][j]);
_map[i][j].x = (j-i) * _gridWidth / 2;
_map[i][j].y = (i+j) * _gridHeight / 2;
}
}
_mapHolder.x = (stage.stageWidth - _gridWidth)/2;
_mapHolder.y = (stage.stageHeight - _mapHolder.height) /2;
/* We need to keep track of the mouse movement and the mouse pressed and released. When the mouse is pressed, we will prepare the drawing and painting. When the mouse is moving, we paint the map. When the mouse is released, we stop the painting action. */
stage.addEventListener(MouseEvent.MOUSE_DOWN,startDraw);
stage.addEventListener(MouseEvent.MOUSE_MOVE,drawing);
stage.addEventListener(MouseEvent.MOUSE_UP,stopDraw);
/* We somewhere need to tell the map editor to output the map data and this button will call the map data output logic */
btnOutput.addEventListener(MouseEvent.CLICK,onOutputClick);
}

When the map editor is in painting mode, we will keep painting on the tile by calling following function.

private function drawTile(sx:Number,sy:Number):void {
/* In the drawTile function, we will make use of the screen-to-isometric coordinate conversion function. When painting, we need to select the IsoTile, which is in isometric coordinate, from mouse screen position. */
var isoCoord:Point = s2i(sx,sy);
/* The coordinate conversion function calculates the result from formula so we need to ensure we have a valid tile there. */
if (isoCoord.x >=0 && isoCoord.x < _mapWidth
&& isoCoord.y >=0 && isoCoord.y < _mapHeight
){
/* We will then paint the tile if it is valid. Painting the tile means set the tile to display the frame number as same as the selected brush. */
var isoTile:IsoTile = _map[isoCoord.y][isoCoord.x];
isoTile.gotoAndStop(_currentBrush);
}
}

When one of the ten brushes IsoTile is clicked, we set the brush texture to the frame number of the latest selected IsoTile.

private function onBrushClick(e:MouseEvent):void {
_currentBrush = e.currentTarget.currentFrame;
}

When the mouse is pressed, we start drawing by setting the _drawing flag to true and try to draw the tile under the current mouse position.

private function startDraw(e:MouseEvent):void {
_drawing = true;
drawTile(stage.mouseX,stage.mouseY);
}

When the mouse is moving, we need to check if the _drawing flag is true. The _drawing flag as true means the mouse is moving while being pressed. Then we draw all tiles that the mouse moves over.

private function drawing(e:MouseEvent):void {
if (_drawing){
drawTile(stage.mouseX,stage.mouseY);
}
}

The _drawing flag is set to false when the mouse is up so that a normal mouse move will not trigger the tile painting.

private function stopDraw(e:MouseEvent):void {
_drawing = false;
}

The map editor outputs the map data when the output button is clicked. As Flash cannot write files directly, we use trace, the simplest way, to output the map data. We will output the map data according to our XML structure and map format that was defined previously.

private function onOutputClick(e:MouseEvent):void
{
trace("<map>");
trace("	<name>Map Name</name>");
trace("	<width>"+_mapWidth+"</width>");
trace("	<height>"+_mapHeight+"</height>");
trace("	<terrain>");
trace("		<![CDATA[");
/* output the map terrain data. The tile textures are separated by commas and line breaks. */
for(var i=0;i<_mapHeight;i++){
var rowData = "";
for(var j=0;j<_mapWidth;j++){
rowData += _map[i][j].currentFrame+",";
}
trace("		"+rowData);
}
trace("		]]>");
trace("	</terrain>");
trace("</map>");
}

The following screenshot shows a very basic feature of our map editor:

Building a map editor

The map data is traced into the output window in Flash IDE and the flashlog.txt. We need to copy the text from the output window to the map data file to use it. Using trace output method of map data is convenient for a small or medium amount of maps. If there are huge amounts of map data that need to be edited and stored, it is better to save the files from the map editor instead of tracing the output.

There are several ways to save the map data into files from the map editor. We only list the methods here instead of implementing them because that is beyond the scope of this book.

One method is sending the data to server-side HTTP server and saving the data into files with server-side logic such as PHP and JSP.

Another method is building the map editor into AIR runtime and using the FileStream class to save the data into files.

One more solution is to use third-party SWF plugins that can convert the SWF into EXE with the extra permission of writing files.

The main purpose of building a map editor is to speed up the map data editing process during development. The map editor is mostly used by the developing team of the virtual world, so it is recommended to modify and add features to the map editor to make it as handy as possible for the developing team.

The map editor that we built has only very basic core features. In order to make it more handy and powerful, the following features can be considered:

  • Save/load any map data file
  • Change the map dimension
  • Change the name of the map
  • Multi/mass map editing
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.202.30