Page: [1]  2  3  4  5  6  7  8  9  
什么是程序智能化?

这里的智能并不是游戏中NPC的智能行为,而是程序运算处理的多种自动行为,是用户不可见的。

    例如:在AS3中向显示列表中增加显示对象,如果未指定在列表中的位置,将自动追加到最后,而且会事先从有此显示对象的显示列表中删除。这就是一种智能行为,在AS3之前是没有的,但在AS2中可以自己写出此功能。在AS2中实现显示列表功能就是一种程序智能化。

 

    要想程序智能需要三个基本的功能:类管理、储存列表、消息列队。类管理主要负责对各种命令进行处理,它从储存列表中获取数据放入消息列队。储存列表负责存放各种数据信息,方便管理查找。消息列队执行各种命令对应的处理方法。

    类管理在上次写的《FLASH程序开发基础》中介绍过,储存列表比较简单也就不多说了,这里介绍下消息列队的一种用途,在我们做外部载入的项目中经常会同时加载N个文件,文件大小不一样加载的时间也会不一样,怎样才知道所有文件都加载完了呢?最直接的方法是用int变量记录加载完的文件数量,这样就能判断出是否已经全部加载,但是要实现加载完一个后才加载下一个文件就比较麻烦了。我们来看消息列队是如何实现的,将所有的文件加载放入消息列队,程序自动依次执行,在当前消息没结束前不会执行下一条消息。

    消息列队的实现是用计时器Timer重复执行数组中的第一个元素,元素可以是任何类型的,只要能知道元素的结束,在结束后删除继续执行下一个。

 

使用以上三个基本功能实现AS3中的显示列表原理:

    步骤1:向类管理发出添加显示对象到显示列表的命令。

    步骤2:类管理查找储存列表中对应显示对象和所在的显示列表。

    步骤3:如果找到,添加(从显示列表中删除显示对象的命令)到消息列队。如果没找到则执行步骤4。

    步骤4:添加(增加显示对象到显示列表中的命令)到消息列队。

在AS2中可以使用此方法实现AS3中的可视化对象的深度管理。

 

    以上均为个人理论。

这里说的程序开发基础不是程序语言基础,语言基础的教程有很多,网上到处都能搜到,我也就不必说了。程序开发基础要说的究竟是什么?我们来了解下什么是程序开发,用程序语言编写软体的过程就是程序开发,可能有更好、更专业的描述,但大家能搞懂意思就是行了。用FLASH程序开发基础为标题,因为我是FLASH程序员,是用AS语言写程序,其他语言有什么高招就是他们的事了。

    废话就不多说了,下面就开始主题。一个程序项目在开发之前应该搞清楚有多少功能块,这些功能块有哪些是可以独立,哪些是需要与其他功能块互交的。独立功能块很简单,写好就能用,需要互交的功能块就复杂点了,在AS2.0里面可以把每个功能块装在一个MC(影片剪辑)里面,如果要访问另一个MC里面的属性,可以用路径直接找到,就象WINDOWS里面找文件一下方便,_root指向主场景,只要知道路径就万事OK,但是这样写程序很混乱,路径写错或忘记是常有的事,而且不方便修改,如果有个MC路径需要改变,指向这个MC的路径都要去改一下,MC太多就只有累死。在AS3.0里面取消了_root指向主场景,很多人就傻眼了,有经验的人就会用功能块类的属性来指向主场景,这样做和AS2.0的区别也不大,至于如何把主场景赋值给属性也是个新手问题,很多人都不知道,这里先不讨论。

 

    如何解决功能块互交的问题,创建功能块管理类,将功能块存放在此类中统一管理,存放方式可以用类属性和数组,使用数组存放应该规定每功能块所在数组单元格,例如:数组[功能块1.ID]=功能块1,这样可以不用考虑路径,对于合作开发也是很有好处的,而且可以演变出多种管理类,统称为管理类。

 

    现在开始程序开发一步,分出引擎和数据,引擎主要有逻辑和算法构成,也就是说引擎就是我们写出来的程序,数据就是项目的描述,例如:图片位置x=100、y=100,引擎根据描述做出相应的处理。很多人会说赋值了x和y的图片自己就会到坐标上,跟引擎有什么关系,AS代码其实是数据,是种描述,flash player是他的引擎,所以我们要写出自己引擎和数据,这里原理比较复杂,解释一下:自定义数据->AS代码->flash player->AS代码->flash player,原理性的东西就不祥解了,这样做的好处:大家都遇到过发布的时候等上很长的时间吧,客户频繁的让修改是不是很痛苦,把数据文件放到外部载入,修改一个数据而已,没什么大不了的。

 

    如何实现引擎和数据,例如:引擎实现表单提交,数据是lable=3,button=1,运行程序后出现3个文本框和1个按钮,引擎代码结构:

  var arr:Array;
  while (arr1.length > 0) {
    arr=arr1[0].split("=");
    for (var i:int=0; i < int(arr[1]); i++) {
      if (arr[0]="lable") {
        createlable();
      } else if (arr[0]="button") {
        createbutton();
      }
    }
  }
  function createlable() {
   //创建一个文本
  }
  function createbutton() {
   //创建一个按钮
  }

数据是应该有一个对应的解析类,这里因为数据简单就直接写的,数据是可以更复杂的,格式也是自己定义的,其他人基本是看不懂,只要解析类够强,让数据象语言一样都可以,FLASH不就是这样的吗,呵呵。

 

    以上均为个人理论,天外有天,人外有人,可能会有其他更好的模式。来点小建议,在开发程序的时候尽可能封装功能类,以后开发此功能直接使用,如果此类在二次使用的时候需要修改的代码比较多,那这个类就可以扔垃圾箱了。

最近做卡牌游戏,看见魔兽世界卡牌游戏可以把牌列成一个扇形,感觉挺不错,也想在自己的卡牌游戏中用上这种排列,于是到网上搜算法,发现很多C#、C++的算法,代码还挺长,我最怕看见长篇的代码,那是很恐怖的东东,直接搜FLASH的吧,又搜出很多美工绘制的。哎~~,终于在快绝望的时候找到一个哥们写的画扇程序,这个算法挺好用的,借用了他计算点的算法完成了我的扇形排列。

 

import fl.controls.ComboBox;
import flash.events.MouseEvent;
btn.addEventListener(MouseEvent.CLICK,btnOnClick);
function btnOnClick(event:MouseEvent) {
while (aSpr.length>0) {
  removeChild(aSpr[0]);
  aSpr.shift();
}
aSpr=new Array(int(cbox.selectedItem.label));
init();
}
for (var i:int=1; i<=36; i++) {
cbox.addItem({label:i});
}
var aSpr:Array=new Array(14);
init();
function init() {
for (i=0; i<aSpr.length; i++) {
  aSpr=new sprite();
  addChild(aSpr);
  arrange(250,200,aSpr,trimsector(i,aSpr.length));
}
}
function trimsector(cnum:int,tnum:int) {
//根据数量计算弧度位置--扇形排列
var incept:int=-(Math.floor(tnum/2)*10);
incept=incept+Math.abs((tnum%2)-1)*5;
return incept + cnum * 10;
}
function arrange(dp:*,x0:int,y0:int,r:int) {
//排列显示对象--扇形排列
var obj:Object=getPoint(x0, y0, 100, -90, r);
dp.rotation=r;
dp.x=obj.x;
dp.y=obj.y;
}
function getPoint(x0:int, y0:int, r:int, a0:int, a:Number) {
//参数:x0=圆点坐标X,y=圆点坐标Y,r=半径,a0=原弧度,a=目标弧度
//计算位置坐标--扇形排列
a += a0;
a = a*Math.PI/180;
return {x:Math.cos(a) * r + x0,y:Math.sin(a) * r + y0};
}
演示地址

http://space.flash8.net/bbs/attachment.php?aid=349545

AS3中取消了onReleaseOutside事件,这对滑块的拖拉造成了点麻烦,不过我们可以用多个事件模拟出onReleaseOutside事件,以下是模仿了简单的ScrollBar类。

package display{
 import flash.display.Sprite;
 import flash.display.SimpleButton;
 import flash.events.MouseEvent;
 import flash.geom.Rectangle;
 public class Scroll extends Sprite {
  public var container:*;//显示的容器  必须是MovieClip类或MovieClip子类
  public var viscera:*;//容器中的内容  必须是MovieClip类或MovieClip子类
  public var top:int=0;//滑块移动最小的Y坐标
  public var bottom:int=0;//滑块移动最大的Y坐标
  public function Scroll() {
   btn_scrollbar.addEventListener(MouseEvent.MOUSE_DOWN,btn_scrollbarOnDown);
   btn_up.addEventListener(MouseEvent.MOUSE_DOWN,btn_upOnDown);
   btn_down.addEventListener(MouseEvent.MOUSE_DOWN,btn_downOnDown);
   top=btn_up.y+btn_up.height;//根据btn_up(向上移动的按钮)计算top值
   bottom=btn_down.y-top-btn_scrollbar.height;//根据btn_down(向下移动的按钮)计算top值
   btn_scrollbar.y=top;
   btn_scrollbar.buttonMode=true
  }
  private function btn_scrollbarOnDown(event:MouseEvent):void {
   btn_scrollbar.startDrag(false,new Rectangle(btn_scrollbar.x,top,btn_scrollbar.x,bottom));
   stage.addEventListener(MouseEvent.MOUSE_UP,stageOnUp);
   stage.addEventListener(MouseEvent.MOUSE_MOVE,stageOnMove);
  }
  private function stageOnUp(event:MouseEvent):void {
   btn_scrollbar.stopDrag();
   stage.removeEventListener(MouseEvent.MOUSE_MOVE,stageOnMove);
   stage.removeEventListener(MouseEvent.MOUSE_UP,stageOnUp);
  }
  private function stageOnMove(event:MouseEvent):void {
   redressal();
  }
  private function btn_upOnDown(event:MouseEvent):void {
   btn_scrollbar.y-=2;
   if (btn_scrollbar.y<top) {
    btn_scrollbar.y=top;
   }
   redressal();
  }
  private function btn_downOnDown(event:MouseEvent):void {
   btn_scrollbar.y+=2;
   if (btn_scrollbar.y>bottom) {
    btn_scrollbar.y=bottom;
   }
   redressal();
  }
  private function redressal() {
   viscera.y=-numtopercent(btn_scrollbar.y-top, bottom, viscera.height-container.height);
  }
  public function containerRect(minx:int,miny:int,maxx:int,maxy:int){//容器的显示区域设定函数
   container.scrollRect=new Rectangle(minx,miny,maxx,maxy)
  }
  public function numtopercent(minnum:Number, maxnum:Number, barlen:Number) {
   var percent:Number = Math.floor(minnum/maxnum*100);
   percent = Math.floor(barlen*(percent/100));
   return percent;
  }
 }
}

此类为FLASH CS3 中使用,元件中需要btn_scrollbar(滑块元件),btn_up(上按钮),btn_down(下按钮),元件中图形的XY坐标为0。container,viscera需从上级传入。

不要在构造函数里创建MC  因为哪个时候创建_root不没有所以~~~会导致出问题

突然有用到一下子也不会找找帮助得左...果然最强高手还是帮助

var cls:Class = getDefinitionByName("MC名") as Class;
var spc=new cls();

getDefinitionByName () 函数   

public function getDefinitionByName(name:String):Object 

语言版本 :  ActionScript 3.0 
Player 版本 :  Flash Player 9 

返回 name 参数指定的类的类对象引用。 

参数  name:String — 类的名称。  

返回  Object — 返回 name 参数指定的类的类对象引用。  

坐标旋转,一般要得知到angle(角度),radius(距离).
  //的简单的坐标旋转
  var dx:Number = 主角.x - 参照物.x;
  var dy:Number = 主角.y - 参照物.y;
  var angle:Number = Math.atan2(dy, dx);
  var radius:Number = Math.sqrt(dx * dx + dy * dy);
  vx = Math.cos(angle) * radius;
  vy = Math.sin(angle) * radius;

  //先进的坐标旋转
  var dx:Number = 主角.x - 参照物.x;
  var dy:Number = 主角.y - 参照物.y;
  主角.x = cos(angle) * dx - sin(angle) * dy;
  主角.y = cos(angle) * dy + sin(angle) * dx;


有时候我们在调用事件侦听器的时候,需要给它传进相应的参数,这个时候用事件代理的方法非常简单:


function create(f:Function,... arg):Function {
    var F:Boolean=false;
   var _f:Function=function(e:*){
    var a:*=arg
      if(!F){
      F=true
      a.unshift(e)
    };
   f.apply(null,a);
    };
   return _f;
  }
stage.addEventListener(MouseEvent.MOUSE_DOWN,create(mouseDownHandler,"a","b"));
function mouseDownHandler(e:MouseEvent,...arg) {
  trace(arg);
}

// 从超链接处调用AS
这个AS2就已经能实现了不过现在只讲AS3的
var usr:String="<a href='event:http://www.skyterry.com'>skyterry</a>";
var my_txt:TextField=new TextField();
my_txt.htmlText=usr;

my_txt.addEventListener(TextEvent.LINK,link_func);
function link_func(e:TextEvent) {
 trace("你点到超链接了!!!");
 trace(e.text);//输出 http://www.hcxm.cn
 //添加这个侦听器后,不会在浏览器中打开页面了
}

addChild(my_txt);

如果想传参数的话就自已写个继承TextEvent类再传入参数就行了~~~还有不明可以留言


很简单~~~~不过充实一下这里教程还是加上来吧~~~~~~


原件也放上~:
按此在新窗口打开图片

把jpg改为rar就行了

Page: [1]  2  3  4  5  6  7  8  9