热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

转第二章ActionScript3.0动画基础(2)(as3.0)

帧循环帧循环的理念,存在于Flash最早的版本中,那时ActionScript还不像今天那么强大。把代码写入关键帧,并在下一帧中写入像gotoAndPlay这样的语句,使播放头(

帧循环
     帧循环的理念,存在于 Flash 最早的版本中,那时 ActionScript 还不像今天那么强
大。把代码写入关键帧,并在下一帧中写入像 gotoAndPlay 这样的语句,使播放头(playhead)
回到前一帧。这样两帧之间就形成了一个无限循环,每当播放头到了代码帧上时,就会执行
那些代码。例如,在舞台上有一个实例名为 ball 的影片剪辑。
第一帧的代码就像这样:
ball.x ++;
第二帧的代码如下:
gotoAndPlay(1);
    实际上第二帧不需要做任何事,只是让时间轴自动回到第一帧而以。另一个版本是建立
三个帧,第一帧进行初始化,写入只执行一次的代码,不进行循环。第二帧才是主要的执行
代码,第三帧只写 gotoAndPlay(2); 这个方法在早期 Flash 版本中常被使用,虽然有点过
时,但是同样可以出色地完成任务。马上我们还要学到更灵活更强大的设置方法,但今后你
会发现其实原理上是一样的。
影片事件
     影片事件在 AS 3 中彻底的消失了,这真是件好事。但还要捎带提一下,回顾 Flash 5
的时代,只有帧循环和影片剪辑事件两种选择。影片事件指代码直接写在影片剪辑上,而不
是帧上。如何实现影片事件,首先选择舞台上的影片剪辑,然后打开动作面板并将代码写在
上面,这些代码只对该影片剪辑有效。所有代码必需写在事件块中,比如:
onClipEvent(eventName){
// code goes here
}
     对于 onClipEvent(eventName),作用于 eventName(某种事件)。对于"on"类型事件则
必需指定鼠标或键盘事件,如按下(press)和释放(release)。
     事件名称(eventName)是指许多 Flash 影片事件之一,所谓事件就是在影片中发生的
事。事件分为两种:系统事件和用户事件。系统事件指发生在如计算机,Flash,或影片上
的事件,比如调取数据,调取信息,或播放帧等。用户事件是指用户所做的一些事,基本上
就是鼠标和键盘两种。 影片事件使用得最多的就是 load 和 enterFrame 这两个。 Load 事
件会在影片第一次出现在舞台上时才执行, 且只执行一次。 所以说非常适合在这里面写入初
始化代码。只要把代码写在大括号间即可:
onClipEvent(load){
// initialization code
}
我们可以把带有如下代码的影片剪辑放入时间轴上(注意:此处为 AS 1 写法):
onClipEvent (load) {
  this._x = 100;
  this._y = 100;
}
onClipEvent (enterFrame) {
  this._x += 5;
}
     本书示例中的代码不使用这种写法(因为它已经不是一种语言了),但不论使用何种方
法, 初始化(initialization),重复动作(repeating actions)和屏幕刷新(screen refresh)
都是非常重要的。
事件及事件处理
    Flash MX 的 ActionScrpt 发生了重要的改变,这些转变与革新为 Flash 成为真正的
富客户端程序(RIA)奠定了基础。其中一个就是全新的事件结构,在编写非常复杂的行为时
比之前的版本好用很多。 Flash MX 之前的版本,只能把代码放在影片和按钮的
onClipEvent(eventName) 或 on(eventName) 这两种事件处理方法中。这就意味着,在设计
的时候就要把影片剪辑放到舞台上,并把代码写入影片剪辑中。MX 的事件结构并不完美,
但与之前版本来说已经有了长足的进步,并允许我们在任何时候访问任何事件,或是停止处
理任何事件,或是动态改变某个事件的行为,可以想象这有多么的强大和灵活。
    要想了解事件,就要明白下面几条概念:侦听器(lintener)与处理函数(handler),这
两个名字很贴切,侦听器就是侦听事件的对象,处理函数是一个用于处理所要发生的事件的
函数。侦听与处理在 ActionScript 的发展过程中进行过很多次演变,在 AS 2 中就有很多
不同的实现方法。为了避免混乱,我很推崇 AS 3,因为它简化了这个过程,使事件处理变
得更方便更一致。
事件侦听器与处理函数
    前面说过,侦听器是一个用于侦听事件的对象。我们可以设计一个类,通过调用
addEventListener 函数为某事件指定一个侦听器。输入要侦听的事件名称以及要执行处理
的函数名称。看一个例子:
addEventListener("enterFrame", onEnterFrame);
    在加入事件侦听器时,可使用可选参数,本书中不会用到;对于大多数的应用程序来说,
会使用以上这种写法就够用了。请注意事件名"enterFrame"为字符串型,戏称它为“魔力字
符串”(Magic String)。为什么这么叫?如果你误输入成了"entorFrame",尽管没有这个事
件名称,编译器也会编译执行它,会发现事件处理函数没有执行。但 AS 3 仍会对其进行处
理,除了使用“魔力字符串”以外,还可以使用事件类(Event Class)的属性。例如:
addEventListener(Event.ENTER_FRAME, onEnterFrame);
    实际上 Event.ENTER_FRAME 的值就是”enterFrame”这个字符串。那么这个属性也可
能输错就像 Event.ENTOR_FRAME ,但这种方法好在,如果输入错误了,程序会拒绝编译,
并提示你在事件类中不存在该属性。编译器会提示发生错误的行及确切的字符。所以,最好
使用这种方法,除非编译器会帮我们修正错误或编写代码。
除此之外,还有其它的事件类型如:MouseEvent.MOUSE_DOWN,KeyboardEvent.KEY_DOWN,
TimerEvent.TIMER 等。这些都由 "mouseDown" , "keyDown" , "timer" 这样的简单字符串
来表示,如果你记不住这些字符串,那么最好就去使用事件类的属性。
    另一个重点是,使用 addEventListener 函数直接调用类中的函数。有时,需要侦听另
一个对象产生的事件,例如,有一个名为 mySpriteButton 的 Sprite 影片(Sprite):影片
或按钮,能完成按钮的动作。当用户点击它的时候就会产生 mouseDown(鼠标按下)事件。侦
听该 Sprite 影片的 mouseDown 事件, 就要调用该对象的 addEventListener 方法,如下:
mySpriteButton.addEventListener(MouseEvent.MOUSE_DOWN, onSpritePress);
    最后一点,必需要有事件处理函数如 onEnterFrame,在 AS 3 中,可以任意地为事件
处理函数命名,这点与以前的 ActionScript 不同。在 enterFrame 示例中,使用
onEnterFrame 做事件处理函数, 是因为我们习惯使用这个名称。 AS 3 中,
                                                          在         onEnterFrame
已不再是关键字,当然也可以为这个处理函数命名为 move,run,或是 doSomethingCool。
然而,我们已经习惯使用”on”表示事件开始,后面跟一些描述词如 onStartButtonClick,
onConfigXMLLoad 或 onRoketCrash。有些朋友喜欢在事件名后面加上 "Handler" 作为后
缀,如: enterFrameHandler,这只是个人偏好问题。
      侦听器用于侦听事件,但对于一个侦听器来说,也许会同时侦听很多事件。在系统内部,
一个事件对象拥有一个包括了所有对象及自身的侦听器的列表。  如果一个对象能够产生多种
不同类型的事件,如 mouseDown,mouseUp,mouseMove 等,那么它就拥有一个侦听器列表,
其中包括它所涉及的所有类型的事件。无论触发何种事件,都会检索一遍列表,然后使列表
中的每个对象都知道所发生的事件。
另一种对事件的描述是,  将其看作一个加入到事件行列的侦听器成员。产生事件的对象将它
所产生的事件公布给所有成员,  当你不再需要这个对象进行侦听时,可以令其停止侦听或使
用 removeEventListener 方法解除该成员;就是告诉对象从侦听器列表中删除该侦听器,
这样一来,他就不会再接收信息了。
      让我们看看这段代码,下面是一段在舞台中创建 Sprite 影片,并进行绘图,然后再为
其添加侦听器的代码:
package {
  import flash.display.Sprite;
  import flash.events.MouseEvent;
  public class EventDemo extends Sprite {
   private var eventSprite:Sprite;
   public function EventDemo() {
     init();
   }
   private function init():void {
     eventSprite = new Sprite();
     addChild(eventSprite);
     eventSprite.graphics.beginFill(0xff0000);
     eventSprite.graphics.drawCircle(0, 0, 100);
     eventSprite.graphics.endFill();
     eventSprite.x = stage.stageWidth / 2;
     eventSprite.y = stage.stageHeight / 2;
     eventSprite.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
     eventSprite.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
   }
   private function onMouseDown(event:MouseEvent):void {
     trace("mouse down");
   }
   private function onMouseUp(event:MouseEvent):void {
     trace("mouse up");
   }
  }
}
      在初始化函数(init)中创建一个 Sprite 影片,并在里面画圆,置于舞台中心,最后两
句是为它添加两个侦听器,侦听鼠标按下(MOUSE_DOWN)和鼠标弹起(MOUSE_UP)这两个事件。
它们是 MouseEvent 类的两个属性,而这个类必需要导入。最后定义两个处理函数
onMouseDown 和 onMouseUp。
      由事件对象调用事件处理函数,通常还会包括一些事件信息。在处理鼠标事件时,就包
括触发该事件时鼠标位置的信息如:鼠标点击在按钮上。对于键盘事件,就要包括按下键时
的信息如 Ctrl,Alt,Shift 等。把上述示例保存为 EventDemo.as 文件,并选择一种前面
讲过的编译方式。当运行 SWF 时,就会看到每次点击或图形时,都会输出 pressed 或
released。
动画事件
      我们希望能够使用代码让物体动起来,并允许屏幕反复地刷新。前面看过一个使用
enterFrame 影片事件的示例。现在把这种方法运用到 AS 3 中,只需要增加一个
enterFrame 事件的侦听器即可:
addEventListener(Event.ENTER_FRAME, onEnterFrame);
      别忘了导入 Event 类,并创建一个名为 onEnterFrame 的方法。人们常常迷惑,只有
一帧怎么能执行 enterFrame(进入帧) 事件呢?事实上,播放头并非真正地在进入下一帧,
它只停留在第一帧上,  并不是把播放头移动到下一帧才形成了 enterFrame 事件,而是用另
一种方法:Flash 告诉播放头何时进行移动,可以把 enterFrame 看成一个定时器,只是有
些不精确。
下面我们看看第一个 AS 3 动画:
package {
  import flash.display.Sprite;
  import flash.events.Event;
  public class FirstAnimation extends Sprite {
   private var ball:Sprite;
   public function FirstAnimation() {
     init();
   }
   private function init():void {
     ball = new Sprite();
     addChild(ball);
     ball.graphics.beginFill(0xff0000);
     ball.graphics.drawCircle(0, 0, 40);
     ball.graphics.endFill();
     ball.x = 20;
     ball.y = stage.stageHeight / 2;
     ball.addEventListener(Event.ENTER_FRAME, onEnterFrame);
   }
   private function onEnterFrame(event:Event):void {
     ball.x++;
   }
  }
}
      init 函数创建了一个名为 ball 的 Sprite 影片,并为其建立事件侦听。
onEnterFrame 函数负责 ball 的运动及屏幕刷新工作。这是学习本书内容的基础,也是使
用 ActionScript 创建动画的基础,所以务必要掌握。
显示列表
      在 AS 3 之前,人们可以创建多个不同类型的可视化对象,包括影片剪辑,图形,按钮,
文本框,位图,组件和基本形状。这些对象没有真正的层次结构,它们的创建、删除、操作
方法也均不相同。比如,在 IDE 中,可以使用 attachMovie ,duplicateMovieClip 或
createEmptyMovieClip 的方法将影片剪辑放置于舞台上,文本框可以在开发环境中创建也
可以用代码创建。而在使用位图(bitmap),视频(video)及组件(component)时,它们就像是
来自于别的星球,最终被强硬地放在一起。
      对于 AS 3 来说,这些对象都有了统一的归属。在舞台上所有可见的对象都继承自
DisplayObject 类。换句话讲,这些对象都是一个大家庭的成员,并以相同的形式工作,使
用同样的方式进行创建,置入,删除,操作。无论创建 Sprite 影片,影片剪辑或文本框的
方法都非常相近,我们需要使用 new 关键字来完成,创建任意类型的对象。为了证明这一
点,请看下面三条示例:
var myTextfield:TextField = new TextField();
var myMovieClip:MovieClip = new MovieClip();
var mySprite:Sprite = new Sprite();
如果我们创建的是一个影片剪辑或 Sprite 影片的话,就可以直接里面进行绘制,如:
mySprite.graphics.beginFill(0xff0000);
mySprite.graphics.drawCircle(0, 0, 40);
mySprite.graphics.endFill();
    但只有这些代码,还不能看到效果,这就引发了接下来要讨论的显示列表。“显示列表”
是个新名词,可以理解为一颗由可视对象构成的树。舞台就是树根,默认为可见的,在舞台
上,我们可以有很多影片剪辑或可视对象(文本框,图形等),把它们加入舞台后,也就成为
可见的了。
    这些影片中也许还嵌套着很多层的可视对象,这就是我们所谓的显示列表。 AS 2 与 AS
3 显示列表最大的不同在于,AS 2 中,当使用 attach 或 createEmptyMovieClip 方法创
建影片剪辑时,必须指定它位于树的哪个位置。这样一来,影片剪辑要放置在列表的指定位
置。当删除该影片时,同样也无法改变它在列表中的位置或在列表中移除它。
    在 AS 3 中,创建了一些 Sprite 影片后,不会自动被加入显示列表。在上面的示例中
我们发现,创建一个 Sprite 后,并不涉及父级影片(parent)或深度(depth)的问题,这样
就可以在它没有加入视觉列表之前就对其进行操作了。说到舞台(Stage),可以把这些显示
对象看作是幕后的演员,虽然看不到,但确实存在,并时刻准备着亮相的一刻,我们使用
addChild 方法把对象加入显示列表。将文档类作为树根,向里面加入孩子时,会自己被设
置为可见的。
现在,在前面的例子中再加入创建 Sprite 对象以及 addChild 方法,如下:
var mySprite:Sprite = new Sprite();
mySprite.graphics.beginFill(0xff0000);
mySprite.graphics.drawCircle(0, 0, 40);
mySprite.graphics.endFill();
addChild(mySprite);
     如果大家有兴趣试一下这段代码的话,请把它们写入前面所给的类框架的 init 函数
中。请注意,绘制出的圆默认位置是 0,0 点,可以改变其 x 和 y 属性。还要注意,创建新
影片时不再需要像 AS 2 那样去设置深度(depth)。虽然深度管理为自动执行,但我们还有
指定深度或改变深度的方法,这部分等将来用到时再讲。
使用 removeChild 方法,从显示列表中删除一个对象,并以该对象的名字作为参数。第一,
删除一个对象,不是去毁灭它,对象依然保持原样,只是暂时被移除,当再次被加入到显示
列表中,对象仍保持原来的状态。换句话讲,如果显示对象里面绘制了图形,或是已加载了
一些外部信息,那么将它重新加入显示列表后,就不必再去重绘或重载这些信息。第二,把
该对象重新加入显示列表后, 还可以为它指定处在显示列表中的位置,这就是我们所熟知的
重定父级。
     从一个影片剪辑中删除一个对象,再把它加载到另一个影片中剪辑中,并保持刚刚被删
除时的状态,在以前是不可能完成的。事实上,有时并不需要去删除影片,因为,一个子对
象只能有一个父级,把它加入到另一个父级中,就会自动从原来的父级中删除。请看下面示
例:
package {
  import flash.display.Sprite;
  import flash.events.MouseEvent;
  public class Reparenting extends Sprite {
 private var parent1:Sprite;
 private var parent2:Sprite;
 private var ball:Sprite;
 public function Reparenting() {
   init();
 }
 private function init():void {
   parent1 = new Sprite();
   addChild(parent1);
   parent1.graphics.lineStyle(1, 0);
   parent1.graphics.drawRect(-50, -50, 100, 100);
   parent1.x = 60;
   parent1.y = 60;
   parent2 = new Sprite();
   addChild(parent2);
   parent2.graphics.lineStyle(1, 0);
   parent2.graphics.drawRect(-50, -50, 100, 100);
   parent2.x = 170;
   parent2.y = 60;
   ball = new Sprite();
   parent1.addChild(ball);
   ball.graphics.beginFill(0xff0000);
   ball.graphics.drawCircle(0, 0, 40);
   ball.graphics.endFill();
   ball.addEventListener(MouseEvent.CLICK, onBallClick);
 }
 public function onBallClick(event:MouseEvent):void {
   parent2.addChild(ball);
 }
}
}
    该类中有三个 Sprite 对象:parent1, parent2, ball。 parent1, parent2 影片直接
加入显示列表,并在影片中绘制了正方形。 Ball 影片被加入到 parent1,就相当于加入了
显示列表并可见。当小球被点击时,它将被加入 parent2 影片中。请注意,没有改变 Ball
的 x,y 坐标的代码,之所以产生移动是因为 Ball 被加载到了不同位置的 Sprite 影片中。
Sprite 影片被删除后再被加入显示列表,Ball 仍会出现。
子类化显示对象
    前面已经讲过生成 Sprite 或 MovieClip 类的子类,对某个类进行子类化是非常有用
的。首先,大家可能对 AS 3 取消 attachMovieClip 功能感到十分惊呀,如果这样的话,
我们怎么才能在 Flash CS3 IDE 库中取出影片剪辑元件放入舞台呢?答案是,使用一个继
承自 MovieClip 或 Sprite 的类。为了能够好地解释这个问题,简单地介绍一下 IDE:
1.创建一个新的 FLA 文件,并在舞台上绘制一些图形。
2.选中图形按下 F8 键转换为元件。
3.在转换为元件窗口中输入一个名称,并设置为影片剪辑类型。
4.选择为 ActionScript 导出。
      在以前的 Flash 版本中,可以自由地给出标识符或输入一个类名。而在 Flash CS3 中,
标识符一栏不可用了,类一栏会自动地填入默认值。这里还多出了基类一栏,默认为
flash.display.MovieClip,这里也可以填入继承自 MovieClip 或 Sprite 的自定义类。
      随意输入一个类名,不必担心没有这个类,然后点击确定。这个地方很有趣,Flash 找
不到这个类,它就会自动生成一个类,并对其进行编译。并不是说 Flash 会创建一个
ActionScript 类文件,但它会在 SWF 中,生成一串字节代码表示一个继承自 Sprite 或
MovieClip 的类。除了继承了基类,它什么都不会做,但它已经与库中的元件连接上了。比
如,你的类名为 Ball。在文档类或时间轴上,可以这么写:
var ball:Ball = new Ball();
addChild(ball);
      这样就在舞台上创建了一个库中的元件,就像 AS 2 的 attachMovie 方法一样。我们
要是能给出自定义的真正的类名及路径的话,那么就可以让元件附加很多功能。现在,我们
跳出 Flash IDE 回到类的世界,看下一个示例。下面再看一个重定父级的示例,这里有一
些重复的部分可以写入另一个类中。看一下示例,假设已经创建了一个名为 parent1 的
Sprite 实例,要里面绘制正方形:
parent1.graphics.lineStyle(1, 0);
parent1.graphics.drawRect(-50, -50, 100, 100);
      下面再创建一个名为 parent2 的 Sprite 实例,同样也是绘制一个正方形。当然这个
例子毫无意义,但它可以告诉我们 Sprite 的子类是多么的有用。首先,我们建立一个名为
ParentBox 的类,并继承自 Sprite,这样一来,就拥有了绘制正方形的代码:
package {
  import flash.display.Sprite;
  public class ParentBox extends Sprite {
   public function ParentBox() {
     init();
   }
   private function init():void {
     graphics.lineStyle(1, 0);
     graphics.drawRect(-50, -50, 100, 100);
   }
  }
}
然后,使用这个类创建两个 ParentBox,这样做比创建两个 Sprite 对象要好得多
package {
  import flash.display.Sprite;
  import flash.events.MouseEvent;
  public class Reparenting2 extends Sprite {
   private var parent1:ParentBox;
   private var parent2:ParentBox;
   private var ball:Sprite;
   public function Reparenting2() {
     init();
   }
   private function init():void {
     parent1 = new ParentBox();
     addChild(parent1);
     parent1.x = 60;
     parent1.y = 60;
     parent2 = new ParentBox();
     addChild(parent2);
     parent2.x = 170;
     parent2.y = 60;
     ball = new Sprite();
     parent1.addChild(ball);
     ball.graphics.beginFill(0xff0000);
     ball.graphics.drawCircle(0, 0, 40);
     ball.graphics.endFill();
     ball.addEventListener(MouseEvent.CLICK, onBallClick);
   }
   public function onBallClick(event:MouseEvent):void {
     parent2.addChild(ball);
   }
  }
}
      作为 ParentBox 的实例,它们仍是 Sprite ,因此还可以再增加子影片, init 方法
直接进行绘图。虽然这个示例价值不大,但可以让你学会这种思想,往后,会在书中看到更
多更复杂的示例。你也许想自己动手创建一个球(Ball)类,用于绘制小球,虽然这么做不会
减少代码里,但是当你的类变得十分复杂时,把功能代码分离到不同的类中,这绝对是个好
办法,它比将所有类写在一起要好得多,同时还促进了代码的重用性。那么现在就去创建这
个 Ball 类吧,在日后的学习中还要用到呢。
交互动画
    最后介绍一下交互动画,这也许是大家读这本书的主要原因。如果不使用交互运动,那
么只使用补间动画不就行了。在前面一章简单地提到过,用户交互动画基于用户事件,总的
来说可以归结为鼠标事件和键盘事件,下面就来学习不同的用户事件及其处理函数。
鼠标事件
    AS 3 中鼠标事件发生了显著的变化。在 AS 2 中,影片剪辑会自动添加鼠标侦听器。
现在,要手动地为对象添加侦听器。 AS 3 中鼠标指针经过显示对象时才能触发鼠标事件。
                               
在 AS 2 中,无论鼠标指针在哪里,只要执行 mouseDown 或 mouseMove 就会触发所有的影
片剪辑。而现在, mouseUp 和 mouseDown 事件与 AS 2 中的 onPress 和 onRelase 等同。
鼠标事件的名称是定义好的字符串,像我们之前所提到的,最好使用 MouseEvent 类的属性,
以避免输入错误,下面是 MouseEvent 类中所有可用的鼠标事件属性:
CLICK
DOUBLE_CLICK
MOUSE_DOWN
MOUSE_MOVE
MOUSE_OUT
MOUSE_OVER
MOUSE_UP
MOUSE_WHEEL
ROLL_OUT
ROLL_OVER
     创建下面这个类,来测试一下,这个类会输出发生在 Sprite 影片上的鼠标事件名称。
package {
 import flash.display.Sprite;
 import flash.events.MouseEvent;
 public class MouseEvents extends Sprite {
  public function MouseEvents() {
    init();
  }
  private function init():void {
    var sprite:Sprite = new Sprite();
    addChild(sprite);
    sprite.graphics.beginFill(0xff0000);
    sprite.graphics.drawCircle(0, 0, 50);
    sprite.graphics.endFill();
    sprite.x = stage.stageWidth / 2;
    sprite.y = stage.stageHeight / 2;
    sprite.addEventListener(MouseEvent.CLICK, onMouseEvent);
    sprite.addEventListener(MouseEvent.DOUBLE_CLICK,onMouseEvent);
    sprite.addEventListener(MouseEvent.MOUSE_DOWN,onMouseEvent);
    sprite.addEventListener(MouseEvent.MOUSE_MOVE,onMouseEvent);
    sprite.addEventListener(MouseEvent.MOUSE_OUT,onMouseEvent);
    sprite.addEventListener(MouseEvent.MOUSE_OVER,onMouseEvent);
    sprite.addEventListener(MouseEvent.MOUSE_UP,onMouseEvent);
    sprite.addEventListener(MouseEvent.MOUSE_WHEEL,onMouseEvent);
    sprite.addEventListener(MouseEvent.ROLL_OUT,onMouseEvent);
    sprite.addEventListener(MouseEvent.ROLL_OVER,onMouseEvent);
  }
  public function onMouseEvent(event:MouseEvent):void {
    trace(event.type);
  }
 }
}
请注意,每个事件类型都使用了同一个处理函数,输出所触发的事件类型的名称。
鼠标位置
    除了鼠标事件外,对于文档类还有两个非常重要属性用于表示鼠标当前的位置:mouseX
和 mouseY。请注意,影片剪辑的位置,返回的值是鼠标的位置与影片剪辑的注册点的相对
位置。例如,有一个名为 sprite 的 Sprite 影片,在舞台的 100,100 位置,而鼠标的位
置在 150,250,你会得到如下结果:
mouseX 为 150
mousey 为 250
sprite.mouseX 为 50
sprite.mouseY 为 150
请注意鼠标位置与影片位置的相对关系。
键盘事件
      键盘事件已被 AS 3 划分到另一个区域中。例如,在 AS 2 中,影片剪辑会自动侦听键
盘事件,但只在某种情况下才接收这些事件。所以,最好增加一个专门用来做侦听器的影片
剪辑,  有时,影片剪辑接收了多个事件但被看作是一个键盘事件,这样就不对了。 AS 2 的
                                                                         
组成框架中,很大部一部分都是为键盘交互服务的,比如 Flash Player 体系中的:
tab(table)管理,焦点(focus)管理及在文本框中对于 Enter 键与 Table 键的处理等。现
在好了,键盘事件的名称与鼠标事件的相似,都是定义好的字符串,也可为 KeyboardEvent
类的属性。只有两种:
KEY_DOWN
KEY_UP
      我们可以在一个特殊的对象上侦听键盘事件,就像上面那个鼠标侦听的例子一样。为了
实现这个功能,我们需要设置对象的焦点,以便能够捕获这些事件,可以这样写:
stage.focus = sprite;
在很多情况下,侦听键盘事件是否有焦点很有意义,实现它只需直接对舞台进行键盘侦听。
下面看一个示例:
package {
  import flash.display.Sprite;
  import flash.events.KeyboardEvent;
  public class KeyboardEvents extends Sprite {
   public function KeyboardEvents() {
     init();
   }
   private function init():void {
     stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyboardEvent);
     stage.addEventListener(KeyboardEvent.KEY_UP,onKeyboardEvent);
   }
   public function onKeyboardEvent(event:KeyboardEvent):void {
     trace(event.type);
   }
  }
}
键码
    通常人们并不关心一个键是否被按下,  而是关心按下的是什么键。 使用键盘事件处理有
几种方法可以读取输入的信息。前面说到,一个事件处理程序可以由一个事件对象来触发,
该对象包括触发这个事件的数据。在键盘事件中有两个相关的属性,事件所涉及的键:字符
码(charCode)和键码(keyCode)。
字符码指按下的键所表示的真正字符。例如,用户按下”a”键,字符码就是”a”,如果用
户同时又按着 shift 键,这样字符码就是”A”。
键码指按键所代表的数值。如果用户按下”a”键,它所对应的键码为 65,无论是否按着其
它键。如果先按下 Shift 键后按下“a”键,那么会获得两个键盘事件,先是 Shift(键码 16)
后是 a(键码 65)。 Flash.ui.Keyboard 类同样也有一些属性是针对非字母键的,   我们不需
要把它们背下来。例如: Keyboard.SHIFT 等于 16,当 Shift 键按下后,可以测试其是否
等于 Keyboard.SHIFT。请本章的最后一段代码:
package {
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class KeyCodes extends Sprite {
 private var ball:Sprite;
 public function KeyCodes() {
   init();
 }
 private function init():void {
   ball = new Sprite();
   addChild(ball);
   ball.graphics.beginFill(0xff0000);
   ball.graphics.drawCircle(0, 0, 40);
   ball.graphics.endFill();
   ball.x = stage.stageWidth / 2;
   ball.y = stage.stageHeight / 2;
   stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyboardEvent);
 }
 public function onKeyboardEvent(event:KeyboardEvent):void {
   switch (event.keyCode) {
    case Keyboard.UP :
     ball.y -= 10;
     break;
    case Keyboard.DOWN :
     ball.y += 10;
     break;
    case Keyboard.LEFT :
     ball.x -= 10;
     break;
    case Keyboard.RIGHT :
     ball.x += 10;
     break;
      default :
        break;
     }
   }
  }
}
      当我们在 Flash 编辑环境下测试影片时,IDE 会拦截用于控制 IDE 自身的键。Tab 键
和所有功能键以及作为快捷菜单项的键,在测试影片时不会接收到。不过,我们可以在菜单
中选择“控制” -> “禁用快捷键”,来解除限制。这样一来,测试的影片就像在浏览器中
工作一样了。

 

 

 

这章把常用机制的介绍的差不多了 既然常用说明很重要 大家如果不懂 尽量回头看下


推荐阅读
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • android语法高亮编辑器,HighlightTextEditor
    软件简介语法高亮HighlightTextEditor是一个安卓代码语法高亮控件,目前已经支持200多种语言,近90多种主题配色方案,同时 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
author-avatar
豆腐心_suile
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有