interface wargrey.identification.IExtensible { /** * @description: public function extend(Object):Void; */ } |
IExtensive接口是一个标识接口,用于表示实现此接口的类是“可扩展的”。不过可能有一点比较奇怪,为什么其方法要注释掉?其实这也是因为AS2在面向对象方面的不足,因为AS2本身是一门动态语言,这类语言的特点之一便是类型弱化的,而这一特征比面向对象的方法重载更灵活,可以因为这个原因,AS一直不支持方法重载,而对于面向对象,又是强类型的,因此实现接口时必须严格实现匹配的接口方法。本来这没有矛盾,可以保留public function extend(Object):Void;方法,但很明显本例的扩展性是针对可视对象的,因此参数Object是比较宽的类型,为了避免不要必要的麻烦,因此设计成让开发者自我约束的方式:与其让开发者关注被扩展的对象类型,还不如原本就不知道有更多的方法可选,况且这样更利于定制系统所需要的接口。这是针对动态语言的解决方案,不适合带到其他静态面向对象语言。例外本例并非没有其他更规范的解决方案,只是这样的设计体现的一种思想,因为本人认为,软件设计在很多时候都需要反规范。本例实现此接口的类实现了public function extend(MovieClip):Void;方法。
class wargrey.util.Grids { private var _currentGrid:Object; //当前网格副本 public function get currentGrid():Object{ return this._currentGrid; } public function set currentGrid(pos:Object):Void{ var x=(pos.x==undefined)?pos._x:pos.x; var y=(pos.y==undefined)?pos._y:pos.y; if ((x!=undefined)&&(y!=undefined)){ var w=(pos.width==undefined)?pos._width:pos.width; var h=(pos.height==undefined)?pos._height:pos.height; if (w!=undefined)x=x+w; if (h!=undefined)y=y+h; this._currentGrid.x=Math.floor(x/this._width)*this._width+1; this._currentGrid.y=Math.floor(y/this._height)*this._height+1; } } private var _width:Number = 25; //网格宽 public function get width():Number{ return this._width; } private var _height:Number = 25; //网格高 public function get height():Number{ return this._height; }
public function Grids(w:Number,h:Number){ if((w!=undefined)&&(w>=1))this._width=Math.round(w); if((h!=undefined)&&(h>=1))this._height=Math.round(h); this._currentGrid=new Object(); this._currentGrid.x=1; this._currentGrid.y=1; this._currentGrid.width=this._width; this._currentGrid.height=this._height; } public function getCurrentGrid(pos:Object):Object{ if (pos!=undefined)currentGrid=pos; return this._currentGrid; } public function getNextRowGrid(pos:Object):Object{ if (pos!=undefined)currentGrid=pos; this._currentGrid.x+=this._width; return this._currentGrid; } public function getNextLineGrid(pos:Object):Object{ if (pos!=undefined)currentGrid=pos; this._currentGrid.y+=this._height; this._currentGrid.x=1; return this._currentGrid; } } |
网格系定义了网格的一系列属性,作用是为任一MovieClip划分行和列,以方便该MovieClip上其他MovieClip的位置布局,并且不受该MovieClip上可能存在的坐标系统的影响。
网格系统共三个属性,分别为:
width(Number):只读属性网格宽。初始大小在构造网格系时传递,默认为25,单位像素。
height(Number):只读属性网格高。初始大小在构造网格系时传递,默认为25,单位像素。
currentGrid(Object):当前网格位置。Object是一个包含位置属性的对像,无所谓其是否可视,实际上若该对象可视,会忽略其的这一特性。位置被定义为Object在MovieClip上所处的网格的左上顶点的MovieClip坐标。当currentGrid=Object发生时,object的大小或位置不会正好匹配网格大小或顶点,因此传入参数将被视为该Object右下顶点。
网格系还有三个方法getCurrentGrid(Object),getNextRowGrid(Object)和getNextLineGrid(Object),这三个方法的作用依次是获取相对Object的当前网格、下一列网格和下一行网格对象,并且在该方法发生后,currentGrid都会被设置成相对Object的相应网格。关于Object的说明同上。
class wargrey.util.Coordinates{ private var coordinateX:Number; //坐标系X轴原点所在的影片坐标系坐标 private var coordinateY:Number; //坐标系Y轴原点所在的影片坐标系坐标 private var scaleX:Number; //坐标系X轴缩放比,值为 影片尺寸:实际尺寸 private var scaleY:Number; //坐标系Y轴缩放比,值为 影片尺寸:实际尺寸 private var _scale:Number; //坐标系缩放比,值由scaleX和scaleY决定 public function get scale():Number{ return _scale; }
public function Coordinates(coordinateX:Number,coordinateY:Number,scaleX:Number,scaleY:Number){ this.coordinateX=(coordinateX==undefined)?0:coordinateX; this.coordinateY=(coordinateY==undefined)?0:coordinateY; this.scaleX=((scaleX!=undefined)&&(scaleX>=0))?scaleX:1; this.scaleY=((scaleY!=undefined)&&(scaleY>=0))?scaleY:1; var radian=Math.atan2(this.scaleY,this.scaleX); this._scale=scaleY/Math.sin(radian); } public function mapping(target:Object):Object{ if (target instanceof Number){ return target*_scale; }else{ var x:Number=(target.x==undefined)?target._x:target.x; var y:Number=(target.y==undefined)?target._y:target.y; var w:Number=(target.width==undefined)?target._width:target.width; var h:Number=(target.height==undefined)?target._height:target.height; var result:Object=new Object(); if(x!=undefined)result.x=coordinateX+x*scaleX; if(y!=undefined)result.y=coordinateY-y*scaleY; if(w!=undefined)result.width=w*scaleX; if(h!=undefined)result.height=h*scaleY; return result; } } public function converse(target:Object):Object{ if (target instanceof Number){ return target/_scale; }else{ var x:Number=(target.x==undefined)?target._x:target.x; var y:Number=(target.y==undefined)?target._y:target.y; var w:Number=(target.width==undefined)?target._width:target.width; var h:Number=(target.height==undefined)?target._height:target.height; var result:Object=new Object(); if(x!=undefined)result.x=(x-coordinateX)/scaleX; if(y!=undefined)result.y=-(y-coordinateY)/scaleY; if(w!=undefined)result.width=w/scaleX; if(h!=undefined)result.height=h/scaleY; return result; } } } |
坐标系统使得开发人员可以为MovieClip添加自定义坐标系的能力,这样一来对矢量的控制将更为方便。与网格系相比,坐标系更加强调与MovieClip的绑定。
坐标系只有一个只读属性scale(Number),表示坐标缩放比(影片尺寸:实际尺寸,以对角线为准)。其大小由构造时传入的scaleX和scaleY决定,默认为21/2。
坐标系有两个核心方法mapping(Object)和converse(Object)。Object是一个具有位置和大小属性的对象,同样也无所谓是否可视。这两个方法分别用于“将实际对象按其位置和大小映射为MovieClip对象”及“MovieClip对象按其位置和大小还原为实际对象”。
补充说明:
坐标系的(0,0)点对应于MovieClip坐标上的一个点,该点再构造时传入,默认为(0,0)。
一旦为MovieClip绑定了坐标系,则无论是否指定坐标参数,MovieClip都具有了一个正常的数学直角坐标系。
mapping和converse两个方法的参数也可以就是Number,这样就根据scale值只作长度变换。不过转化后的值受scaleX和scaleY的夹角的影响。
import mx.core.UIObject; import wargrey.util.*; import wargrey.identification.IExtensible; class wargrey.extension.GraphicalInterface extends UIObject implements IExtensible{ private var grids:Grids; //网格系统 private var coordinates:Coordinates; //坐标系统
private var currentX:Number; //光标坐标x private var currentY:Number; //光标坐标y private var currentZ:Number; //光标坐标z,即影片深度 private var textFields:Number; //用于构建display生成的文本域名称序号
public function GraphicalInterface(cs:Coordinates,gs:Grids){ setGraphicals(cs,gs); var loc=coordinates.converse({x:0,y:0}); currentX=loc.x; currentY=loc.y; currentZ=1; textFields=1; } public function setGraphicals(cs:Coordinates,gs:Grids):Void{ if (cs!=undefined)coordinates=cs; if (coordinates==undefined)coordinates=new Coordinates(); if (gs!=undefined)grids=gs; if (grids==undefined)grids=new Grids(); } public function createVisualObject(target:Object, id:Object, init:Object):MovieClip{ var von=(id==undefined)?"viusalobjectatdepth"+currentZ.toString():id.toString(); if (target instanceof Function){ var obj:UIObject=this.createClassObject(Function(target),von,getNextDepth(),init); }else{ var obj:MovieClip=this.attachMovie(target.toString(),von,getNextDepth(),init); } var rect:Object=new Object(); rect.x=(init.x==undefined)?init._x:init.x; rect.y=(init.y==undefined)?init._y:init.y; if (rect.x==undefined)rect.x=currentX; if (rect.y==undefined)rect.y=currentY; rect.width=(init.width==undefined)?init._width:init.width; rect.height=(init.height==undefined)?init._height:init.height; if (rect.width==undefined)rect.width=obj._width; if (rect.height==undefined)rect.height=obj._height; var w=rect.width; var h=rect.height; rect=coordinates.mapping(rect); obj._x=rect.x; obj._y=rect.y; if (!init.scale){ rect.width=w; rect.height=h; } obj.width=rect.width; obj.height=rect.height; newRow(obj); return obj; } public function display(msg:Object, size:Number, textColor:Number, backColor:Number, text:TextField, format:TextFormat):TextField{ if (!((size==undefined)&&(textColor==undefined)&&(format==undefined))){ var ft:TextFormat=(format==undefined)?new TextFormat():format; if (size!=undefined)ft.size=size; if (textColor!=undefined)ft.color=textColor; } var tfn:String="display"+(textFields++).toString(); var pos=coordinates.mapping({x:currentX,y:currentY}); createTextField(tfn,getNextDepth(),pos.x,pos.y,0,0); var temp:TextField=TextField(this[tfn]); if (text!=undefined)temp=text; if (backColor!=undefined){ temp.background=true; temp.backgroundColor=backColor; } temp.type="dynamic"; if (temp.antiAliasType!="normal")temp.antiAliasType="advanced"; temp.autoSize=true; temp.html=true; temp.htmlText=msg.toString(); if (ft!=undefined)temp.setTextFormat(ft); newRow(temp); return temp; } public function newLine(obj:Object):Void{ var cr=coordinates.converse(grids.getNextLineGrid(obj)); currentX=cr.x; currentY=cr.y; } public function newRow(obj:Object):Void{ var cr=coordinates.converse(grids.getNextRowGrid(obj)); currentX=cr.x; } public function locate(x:Number,y:Number):Void{ currentX=x; currentY=y; var p:Object=new Object(); p.x=x; p.y=y; p=coordinates.mapping(p); <font col 发表评论
最近访客 更多访客>>最新评论
|
评论