麻球开发者平台,麻球开发者大赛

只看楼主 楼主

艾睿会员有特权,登陆后广告自动屏障。
现在就花5秒钟免费注册!更有好礼相送!

《Flex模拟示波器》代码简要说明

接前不久kevin发的贴子《Flex模拟示波器》(http://bbs.airia.cn/Share/thread-2749-1-1.aspx),现在来对代码作个简要说明。
大概来说,这个程序是“为了画图而画图”,当时的目的在于做一个示波器的效果出来,就是为了骗骗眼睛,所有就没有太多的考虑结构,效率,扩展性,不过也许里面也有可以学习的东西。主要用到的是Graphics的drawXXX一系列方法。好,废话不说,开始大概解释一下。

1、类结构总共分为三个类。PQAWebUI是主mxml,联系其它两个类。OscilloscopeGenerator是“波形发生器”,生成一系列正弦波值。WaveScreen就是画出波形的东西。

2、详细分解

OscilloscopeGenerator

每调用getSinOs()这个方法一次就生成一个正弦值。比较简单,不说了。

PQAWebUI

privatefunctioninit():void{

AosGner =newOscilloscopeGenerator();

BosGner =newOscilloscopeGenerator();

BosGner.setAngle(120);//相差120度,这个叫相位吗?忘了,我把这些知识还给亲爱的老师了。有借有还,再借不难。。。

CosGner =newOscilloscopeGenerator();

CosGner.setAngle(240);//相差240度

timer =newTimer(200);//重绘间隔

timer.addEventListener(TimerEvent.TIMER, draw);

timer.start();

//控制缩放的Timer,以实现按下不动就连续缩放的效果:

HSupTmr.addEventListener(TimerEvent.TIMER,HSup);

HSdownTmr.addEventListener(TimerEvent.TIMER,HSdown);

VSupTmr.addEventListener(TimerEvent.TIMER,VSup);

VSdownTmr.addEventListener(TimerEvent.TIMER,VSdown);
//用callLater的原因是在这个对象creationComplete时它的stage属性为null,//而在callLater后就不为空了。但我不知道原因是什么,学艺不精,唉
this
.callLater(load);

}


private
functionHSup(evt:TimerEvent):void{

if(this.waveScreen.hscale <= 1)

this.waveScreen.hscale += 0.02;


}

……
//每隔一定时间(200ms)就会调用这个方法一次,为WaveScreen准备数据,并通知它重绘:


private
functiondraw(evt:TimerEvent):void{

waveScreen.computeCursorPersent();

if(waveScreen.isCursorMode()){

//如果有光标显示(),下面的几个TextInput就显示光标处的值:


this
.aVal.text ="A: "+ waveScreen.getA().toString().substr(0,6) +" V";
 ……
}else{

//否则就假打:

this.aVal.text ="A: 220 V";

this.bVal.text ="B: 220 V";

this.cVal.text ="C: 220 V";

this.nVal.text ="N: 0 V";
}
vari:int;
vary:Number;
varn:Number
if(! holdBtn.selected){
for(i=0; i<3600; i++){

   y = 311 * AosGner.getSinOs();

n = Math.random();
 
if(Math.random() >= 0.7){

    y += (n-0.5) * 30;

}
 
Avolts[i] = y;

//翻译成汉语,这段话的意思就是先得到一个“正弦值*311”的值(311是交流电的峰值,这个是真的哟220*√2=311V),它是波形的主要数据。后面还要进行一些处理,以模拟真实电网中的一些波动和干扰
     //然后有30%的概率在它的基础上随机增减0~15中的任意值      //就是说有30%的机率增加或减少随机0~15点攻击      //这些值是存放在一个长度为3600的数组里面,然后会把这些值赋给WaveScreen,  
//WaveScreen就会依次取出这3600个值一一画线
 
//其它略
    ……
}

//设置要画的波形的值

this.waveScreen.Acoords = Avolts;

this.waveScreen.Bcoords = Bvolts;

this.waveScreen.Ccoords = Cvolts;

this.waveScreen.Ncoords = Nvolts;

}

this.waveScreen.draw();
}


WaveScreen
privatefunctioninit():void{

//画线的Sprite:

curveSprite =newSprite();

curveSpritGraph = curveSprite.graphics;
//它需要一个mask,防止多余的部分显示出来了:
varmyMask:Sprite =newSprite();

myMask.graphics.beginFill(0x000000,1);

myMask.graphics.drawRect(0,0,this.width,this.height);

myMask.graphics.endFill();

curveSprite.mask = myMask;

//画格子:

gridSprite =newSprite();

gridSpriteGraph = gridSprite.graphics;

gridSpriteGraph.lineStyle(1,0x555555);

//10个列/行
……
//Canvas不直接添加Sprite,所以用了个虚无飘渺的UIComponent:
varuicomp:UIComponent =newUIComponent();
uicomp.addChild(gridSprite);

uicomp.addChild(curveSprite);

uicomp.addChild(myMask);

this.addChild(uicomp);
……
}

privatefunctionstartDragSprite(evt:MouseEvent):void{

if(evt.target==this|| evt.target==curveSprite || evt.target==gridSprite){

//限制只能水平拖动:

varlmtRng:Rectangle =newRectangle(0,0,65535,scrHeight);

lmtRng.x -= lmtRng.width/2;

lmtRng.y += lmtRng.height / 2;

lmtRng.height = 0;

……

}
}

public
functiondraw():void{

……


if(isMouseDown)

return;
//如果拖出边界了,直接把Sprite放到最边上的位置//很暴力,应该采用更温和的方式,比如拖到边界时就拖不动了if(curveSprite.width > scrWidth){
var
coordBoundLeft:Number = -(curveSprite.width/2 - scrWidth);

var
coordBoundRight:Number = curveSprite.width/2;

if(curveSprite.x < coordBoundLeft)

curveSprite.x = coordBoundLeft;

if(curveSprite.x > coordBoundRight)

   curveSprite.x = coordBoundRight;

}
else

{

curveSprite.x = scrWidth/2;
}}
private
functiondrawA():void{

//画线
//因为正好有3600个点的数据,就正好可以显示10个周波,所以才会有下面这些怪怪的计算              
curveSpritGraph.moveTo(- COUNT/2 * hscale, - Acoords[0] / MAX_VOLT * scrHeight/2 * vscale);

curveSpritGraph.lineStyle(1,0xffff00,1);

vari:int
var
x:Number, y:Number;


for
(i=0; i<COUNT; i++){

//要在200ms内画出3600个点的计算量实在是太大了,所以这样处理了一下,只画一半的点,没别的用处


if(i%2==0)continue;

x = (i - COUNT/2) * hscale;

y = - Acoords[i] / MAX_VOLT * scrHeight/2 * vscale;
 curveSpritGraph.lineTo(x,y);

}
}


潦潦草草把比较容易迷惑人的地方注解了一下。有兴趣的话根据这个demo可以做成很有用的波形,比如监测网络速度的曲线图,每天气温趋势图。以前看过一个网站还提供地震信息,那就还可以做一个可以预报地震的小东西出来,霍霍霍霍~
[本帖最后由 kevin.luo.sl 于 2008-11-17 23:52:15 编辑]

评分

举报 使用道具 TOP

只看该用户 沙发!

Re:《Flex模拟示波器》代码简要说明

值得收藏

评分

举报 使用道具 TOP

只看该用户 板凳

Re:《Flex模拟示波器》代码简要说明

Thank you Alert,  我帮你调整了一下页面布局
kevin.luo.sl的签名

评分

举报 使用道具 TOP

只看该用户 地板

Re:《Flex模拟示波器》代码简要说明

改了下字体,所有的东西都到一排了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。我断句的功夫还是挺能的
kevin.luo.sl的签名

评分

举报 使用道具 TOP

只看该用户 #4

Re:《Flex模拟示波器》代码简要说明

//用callLater的原因是在这个对象creationComplete时它的stage属性为null,//而在callLater后就不为空了。但我不知道原因是什么,学艺不精,唉

这是因为flex是单线层的,stage在这个还没有被创建好,callLater以后会最后执行这个方法,所以stage就不会为null了
kevin.luo.sl的签名

评分

举报 使用道具 TOP

只看该用户 #5

Re:《Flex模拟示波器》代码简要说明

续顶

评分

举报 使用道具 TOP

只看该用户 #6

Re:《Flex模拟示波器》代码简要说明

帮顶。
AdobeHitler的签名
Flex Builder 3中文教程:http://molebiology.blog.163.com/

评分

举报 使用道具 TOP

只看该用户 #7

re:地板 kevin.luo.sl

这个bbsMax的可视化编辑器有问题,本来我在word里面看起来很漂亮的,copy-paste到这里面就全乱了,颜色、代码高亮也没有了

评分

举报 使用道具 TOP

只看该用户 #8

感谢分心~~~~~

评分

举报 使用道具 TOP

只看该用户 #9

楼主好人呀!仔细研究中!

评分

举报 使用道具 TOP

只看该用户 #10

牛人 学习中

评分

举报 使用道具 TOP

只看该用户 #11

顶,希望我能在一个星期后,从菜鸟变神鸟.

评分

举报 使用道具 TOP

只看该用户 #12

谢谢LZ    新手学习中

评分

举报 使用道具 TOP

只看该用户 #13

新手顶过

评分

举报 使用道具 TOP

只看该用户 #14

好玩,收藏了

评分

举报 使用道具 TOP

只看该用户 #15

我路过,我顶贴。

不错,顶一下!

评分

举报 使用道具 TOP

只看该用户 #16

我看帖,我回帖,我美德!

我顶 借光。。。

评分

举报 使用道具 TOP

只看该用户 #17

感谢分享

评分

举报 使用道具 TOP

只看该用户 #18

楼主好人呀!仔细研究中!

评分

举报 使用道具 TOP
艾睿会员有特权,登陆后广告自动屏障。现在就花5秒钟免费注册!更有好礼相送!