AS3.0中的区块设计

这篇文章主要是讲解如何基于AS3来制作一个区块游戏,但仍然保持OOP的结构。
这篇文章的代码能够被诸如FlexBuilder,FlashDevilop这里的编译器解释,当然Flash IDE也可以,但是要在主场景上指明main类。
该应用程序需要一个XML文件存储地图数据,它将会被转换为实际地图显示在屏幕上。这里面是没有什么交互的,不过是区块的放置位置和管理。
程序需要X类,每个来都负责不同的功能。
1、main类:管理所有的类和所创建的实例。
2、XmlLoader:载入一个xml文件并保存他的数据。
3、Parser:解析xml到一个二维的数组当中。
4、Screen:接收parser所创建的数字来构造一个区块的矩阵。
5、Tile:单个区块,保存类型x位置和y位置。
在最后我将会给出main文件:
第一个类:XmlLoader

package tools
{
  import flash.events.EventDispatcher;
  import flash.net.URLRequest;
  import flash.net.URLLoader;
  import flash.events.Event;
  
  public class XmlLoader extends EventDispatcher{
    
    private var _loader:URLLoader;
    
    private var _xml:XML;
    
    public function XmlLoader(path:String){
      _loader = new URLLoader();
      try{
        _loader.load(new URLRequest(path));
      }catch(e:Error){
        trace("error in loading the XML file")
      }
      _loader.addEventListener(Event.COMPLETE,onLoadXml);
    }
    
    private function onLoadXml(event:Event):void{
      //trace("xml loaded")
      _xml = XML(URLLoader(event.target).data)
      dispatchEvent(new Event(Event.COMPLETE));
    }  
    
    public function get xml():XML{
      return _xml;
    }
  }
}


这个类接收XML文件的路径,尝试载入它。xml被载入以后,类将会dispatch一个事件,以便创建XmlLoader实例的类能够知道载入已经完成了,我们可以继续了。(这是一个非即时的操作,所有我们需要一个事件机制)。
请注意:有一个事件监听来监听载入的操作,还有一个事件的派遣-main 来接收该事件。第一个市内置的,第二个是同其他的类来连接。载入了xml数据以后,XmlLoader 的实例会保存该数据然后通过其他的类中的一个指定的getter函数来获得它。另一个应该注意到的是try & catch
来处理一些特定的错误事件,这样可以防止一个错误信息在运行中发送给用户。

第二个类:parser
解析的工作是非常的简单的,-获得一个xml对象,然后分割成行,每一行对应一个数字。在完成了划分以后,这个类的一个实例会保存数组中的行以便其他的类能够读取它。这也是由一个getter函数来完成的。_rows数组是一个二维数组。根据xml文件,其中的每一个单元都被描述成一行,每行都有若干的数字。
接收xml文件的类的结构如下所示:

package tools
{
  public class Parser{
    
    private var _xml:XML;
    private var _rows:Array;
    
    
    public function Parser(xml:XML){
      _xml = xml;
      _rows = new Array();
      getRows();
    }
    
    private function getRows():void{
      // get all rows
      var rows:XMLList = _xml.screen.children();
      var singleRow:Array;
      var rowString:String = rows[i];
      for(var i:uint=0;i<rows.length();i++){
        rowString= rows[i];
        // split numbers in string to cells in singleRow array
        singleRow = rowString.split("");
        //save singleRow in _rows array;        
        _rows.push(singleRow);
      }  
    }
    
    //return an arra of all rows (every row is an array of numbers
    public function get rows():Array{
      return _rows;
    }
    
  }
}



为了能让该工作完成,xml文件的结构应该是这样的:

<?xml version='1.0' encoding='UTF8'?>
<data>
  <screen id="" title="">
    <row>111111111111111111111111111111</row>
    <row>100000000000000000000000000001</row>
    <row>101000000000000000003300000001</row>
    <row>101000000000000000000000000001</row>
    <row>101111110000001111000000000001</row>
    <row>100000000000004400000000000001</row>
    <row>100000000000000000000111510001</row>
    <row>100000000000000000000000000001</row>
    <row>111111111111111111111111111111</row>
  </screen>
</data>


如果你是其他的结构需要改变一下parser。
Parser和XmlLoader都在一个名为tools的包中。
第三个类:一个视觉上的Screen

Screen类的实例接收到数组中的数据(Parser类中所解析成的样子)然后根据数组构建一个区块的矩阵。它需要一个两层的for循环。第一层循环遍历所有的行。内部的循环来遍历行里面的所有的数字。内部的for循环每执行一次都创建一个区块,然后将他放到一个数组中(这样做可以让我们以后访问到所有的区块)。
这个类和Tile类都在一个名为"visual"的包中:

package visual
{
  import visual.Tile;
  import flash.display.Sprite;
  
  public class Screen extends Sprite{
    
    private var _screenArray:Array;
    private var _tiles:Array;
    
    public function Screen(screenArray:Array){
      _screenArray = screenArray;
      _tiles = new Array();
      var tile:Tile;
      var row:Array;
      
      // create matrix
      for(var i:uint=0;i<_screenArray.length;i++){
        row = _screenArray[i] as Array;
        for(var j:uint=0;j<row.length;j++){
          // create a new tile and push it to _tiles
          tile = new Tile(Number(row[j]),j,i)
          addChild(tile)
          _tiles.push(tile);
        }  
      }    
    }
    
    //let other classes get the tiles array.
    public function get allTiles():Array{
      return _tiles;
    }
  }
}


第四个类:Tile

最后的visual类是Tile类,它提供单个的区块,具有3个属性:
Type:(代码在XML来描述这一区块)
locationX-描述他在矩阵中的水平位置-数字的位置而不是像素的。
locationY-描述他在矩阵中的垂直的位置。
三个属性都是getter函数。外部的对象可以"ask"每一个区块的属性。我决定使用颜色来区分区块类型的不同。
以下是Tile类的代码:

package visual{
  import flash.display.Sprite;
  
  public class Tile extends Sprite{
    
    private var _type:uint;
    private var _locationX:uint;
    private var _locationY:uint;
    
    // colors of tiles
    static private var TILE_TYPES:Array = [0xDDDDDD,
0xFF00AA,
0xCC00CC,
0xCCCC00,
0x3300FF];
    private const TILE_SIZE:uint = 10;
      
    public function Tile(type:uint,locationX:uint,locationY:uint){
      // get parameters
      _type = type;
      _locationX = locationX;
      _locationY = locationY;
      //draw a square
      graphics.lineStyle(1,0x000000,0.2);
      // different color by type parameter
      graphics.beginFill(  TILE_TYPES[_type],1);
      graphics.drawRect(0,0,TILE_SIZE,TILE_SIZE);
      graphics.endFill();
      x=TILE_SIZE*_locationX;
      y=TILE_SIZE*_locationY;
    }
    
    public function get type():uint{
      return _type;
    }
    public function get locationX():uint{
      return _locationX;
    }
    public function get locationY():uint{
      return _locationY;
    }
  }
}


main 类
最后,我们让所有的东西都运行起来:

package {
  import flash.display.Sprite;
  import tools.XmlLoader;
  import flash.events.Event;
  import tools.Parser;
  import visual.Screen

  public class TileGame extends Sprite{
    
    private var _xmlLoader:XmlLoader;
    private var _xmlData:XML;
    private var _screenParser:Parser;
    private var _screenArray:Array;
    private var _screen:Screen;
    
    
    public function TileGame(){
  var url:String = "http://www.avgil.com/as3/tilegame/screen1.xml";
      try{
      _xmlLoader = new XmlLoader(url);
      } catch(e:Error){
        trace("couldn't load XML file")
      }
      // wait till the XmlLoader will finish loading the data
      _xmlLoader.addEventListener(Event.COMPLETE,onXmlReady);      
    }
    
    private function onXmlReady(event:Event):void{
      //recieve the XML data from the event
      _xmlData = XmlLoader(event.target).xml as XML;
      //parse and build a screen from parsed data
      _screenParser = new Parser(_xmlData);
      _screenArray = _screenParser.rows;
      _screen = new Screen(_screenArray);
      _screen.x = 50;
      _screen.y = 50;
      addChild(_screen);
    }
  }
}


需要注意的是在创建了XmlLoader以后,需要等到XmlLoader说"OK-done"才能做起他的事情。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页