Flash/Flex/AIR:ActionScript2扩展图形接口

<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"> <meta name="GENERATOR" content="OpenOffice.org 2.3 (Linux)"> <style type="text/css"> <!-- @page { size: 21.59cm 27.94cm; margin: 2cm } P { text-indent: 0.75cm; margin-bottom: 0cm; page-break-before: auto } P.western { font-family: "Courier 10 Pitch"; font-size: 10pt } P.cjk { font-size: 10pt } P.ctl { font-size: 10pt } H1 { margin-bottom: 0.21cm; text-align: left; page-break-before: auto } H1.western { font-family: "Century Schoolbook L", serif; font-size: 18pt; font-style: italic } H1.cjk { font-family: "Nimbus Roman No9 L", serif; font-size: 18pt } H1.ctl { font-family: "Aharoni CLM"; font-size: 18pt } H2 { margin-bottom: 0.21cm; text-align: left; page-break-before: auto } H2.western { font-family: "Century Schoolbook L", serif; font-size: 14pt; font-style: italic } H2.cjk { font-family: "Nimbus Roman No9 L", serif; font-size: 14pt; font-style: italic } H2.ctl { font-family: "Aharoni CLM"; font-size: 14pt; font-style: italic } --></style> 本例将为ActionScript2的MovieClip添加坐标系统和网格系统,这将方便Flash游戏的开发。下面结合代码详细介绍:

1.接口

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;方法。

2.实用工具类

a.网格系统Grids:

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的说明同上。

b.坐标系统Coordinates:


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; //坐标系缩放比,值由scaleXscaleY决定

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的夹角的影响。

3.核心类

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

分享到:
评论
WarGrey
  • 浏览: 14900 次
  • 性别: Icon_minigender_1
  • 来自: 镇江
文章分类
社区版块
存档分类
最新评论

你可能感兴趣的:(游戏,linux,Flex,Flash,AIR)