艾睿会员有特权,登陆后广告自动屏障。现在就花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);
}
privatefunctionHSup(evt:TimerEvent):void{
if(this.waveScreen.hscale <= 1)
this.waveScreen.hscale += 0.02;
}
……
//每隔一定时间(200ms)就会调用这个方法一次,为WaveScreen准备数据,并通知它重绘:
privatefunctiondraw(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;
……
}
}
publicfunctiondraw():void{
……
if(isMouseDown)
return;//如果拖出边界了,直接把Sprite放到最边上的位置//很暴力,应该采用更温和的方式,比如拖到边界时就拖不动了if(curveSprite.width > scrWidth){
varcoordBoundLeft:Number = -(curveSprite.width/2 - scrWidth);
varcoordBoundRight:Number = curveSprite.width/2;
if(curveSprite.x < coordBoundLeft)
curveSprite.x = coordBoundLeft;
if(curveSprite.x > coordBoundRight)
curveSprite.x = coordBoundRight;
}
else
{
curveSprite.x = scrWidth/2;}}
privatefunctiondrawA():void{
//画线//因为正好有3600个点的数据,就正好可以显示10个周波,所以才会有下面这些怪怪的计算
curveSpritGraph.moveTo(- COUNT/2 * hscale, - Acoords[0] / MAX_VOLT * scrHeight/2 * vscale);
curveSpritGraph.lineStyle(1,0xffff00,1);
vari:int
varx: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可以做成很有用的波形,比如监测网络速度的曲线图,每天气温趋势图。以前看过一个网站还提供地震信息,那就还可以做一个可以预报地震的小东西出来,霍霍霍霍~