ActionScript 3.0 实例教程

前言:为什么是 AS3?

ActionScript 3.0 是 Adobe Flash Professional(现称 Adobe Animate)和 Adobe AIR 的核心编程语言,它相对于之前的 AS2.0 是一次革命性的升级,具有以下特点:

flash as3.0实例教程
(图片来源网络,侵删)
  • 性能卓越:采用 AVM2 (ActionScript Virtual Machine 2) 虚拟机,运行速度是 AS2.0 的 10 倍以上。
  • 面向对象:完全基于 ECMAScript 4 标准,是真正的面向对象编程语言,支持类、继承、封装等特性,代码更健壮、更易于维护和扩展。
  • 事件驱动模型:采用统一的事件处理机制(addEventListener),使得交互逻辑更清晰、更强大。
  • 强大的显示列表:提供了精确的舞台和显示对象管理,可以方便地控制图形、影片剪辑、文本等元素的显示、层级和交互。

注意:Adobe 已停止更新 Flash Player,但 AS3 依然是许多经典项目、游戏、教育软件和交互式应用的基础,学习 AS3 不仅能让你维护旧项目,更能让你深刻理解面向对象编程和事件驱动思想,这些思想在任何现代前端框架(如 JavaScript)中都是通用的。


准备工作

在开始之前,请确保你已安装以下软件之一:

  • Adobe Animate CC (推荐):这是目前 Adobe 官方用于制作 Flash 内容的工具,它完美支持 AS3。
  • Adobe Flash Professional CC (旧版):如果你有旧版,也可以使用。

打开 Animate,创建一个新的 ActionScript 3.0 文档。


你好,世界!—— 第一个 AS3 程序

这个实例将教你如何在舞台上动态创建文本并显示内容。

flash as3.0实例教程
(图片来源网络,侵删)

目标:在舞台中央显示 "Hello, AS3 World!"。

步骤

  1. 打开 Animate,新建一个 ActionScript 3.0 文档。

  2. 按快捷键 F9 打开 "动作" 面板,这是你编写所有 AS3 代码的地方。

    flash as3.0实例教程
    (图片来源网络,侵删)
  3. 在代码编辑区中,输入以下代码:

    // 1. 创建一个文本字段对象
    var myTextField:TextField = new TextField();
    // 2. 设置文本内容
    myTextField.text = "Hello, AS3 World!";
    // 3. (可选) 设置文本格式,让它更好看
    var myTextFormat:TextFormat = new TextFormat();
    myTextFormat.size = 24;
    myTextFormat.font = "Arial";
    myTextField.setTextFormat(myTextFormat);
    // 4. 将文本字段添加到舞台的显示列表中,使其可见
    addChild(myTextField);
  4. 按快捷键 Ctrl + Enter (Windows) 或 Cmd + Enter (Mac) 测试影片。

代码解析

  • var myTextField:TextField = new TextField();
    • var:声明一个变量。
    • myTextField:我们给这个变量起的名字。
    • 类型声明符,表示 myTextField 变量只能存储 TextField (文本字段) 类型的对象。
    • new TextField():创建一个 TextField 类的实例(也就是一个对象)。
  • myTextField.text = "Hello, AS3 World!";
    • 访问 myTextField 对象的 text 属性,并给它赋值。
  • addChild(myTextField);
    • 这是 AS3 中最核心的显示列表操作之一,它表示将 myTextField 这个对象添加到舞台的显示列表中,只有被添加到显示列表的对象,我们才能在画面上看到它。

事件监听与交互—— 让按钮动起来

这个实例将教你 AS3 的核心:事件驱动,我们将创建一个按钮,点击它时,舞台上的另一个图形会移动。

目标:点击一个圆形,让它移动到舞台右侧。

步骤

  1. 新建一个 ActionScript 3.0 文档。

  2. 使用 椭圆工具 在舞台上画一个圆形,并选中它。

  3. 按快捷键 F8 将其转换为 "影片剪辑",名称为 myButton,并勾选 "为 ActionScript 导出",点击“确定”。

  4. 选中舞台上的 myButton 实例,在 属性 面板中给它一个 实例名称,也叫 myButton

  5. F9 打开动作面板,在主时间轴的第1帧上输入以下代码:

    // 1. 定义移动函数
    function moveBall(event:MouseEvent):void {
        // 将 myButton 的 x 坐标增加 50 像素
        myButton.x += 50;
        // 如果球移出了舞台右侧,让它回到左侧
        if (myButton.x > stage.stageWidth) {
            myButton.x = 0;
        }
    }
    // 2. 为 myButton 添加事件监听器
    // 监听 "鼠标点击" 事件,当事件发生时,调用 moveBall 函数
    myButton.addEventListener(MouseEvent.CLICK, moveBall);
  6. Ctrl + Enter 测试影片,点击圆形,看看效果。

代码解析

  • function moveBall(event:MouseEvent):void { ... }
    • function:定义一个函数。
    • moveBall:函数名。
    • (event:MouseEvent)参数,这个函数必须接收一个 MouseEvent 类型的参数,这个参数对象包含了事件的所有信息(比如点击的坐标、按下的鼠标键等)。
    • void:返回值类型。void 表示这个函数执行后不返回任何值。
  • myButton.addEventListener(MouseEvent.CLICK, moveBall);
    • 这是事件监听的核心语法。
    • addEventListener:添加事件监听器的方法。
    • MouseEvent.CLICK:要监听的事件类型,这里是“鼠标点击”。
    • moveBall:事件发生时要调用的函数,这个函数被称为事件处理函数回调函数

面向对象编程—— 创建可复用的“子弹”类

这个实例将带你进入 AS3 的精髓:面向对象编程,我们将创建一个 Bullet 类,然后可以在舞台上动态创建多个子弹实例。

目标:按空格键,从屏幕底部发射一颗子弹向上移动。

步骤

  1. 新建一个 ActionScript 3.0 文档。

  2. Ctrl + F8 (或 Cmd + F8) 创建一个新的 "ActionScript 文件",保存为 Bullet.as

  3. Bullet.as 文件中输入以下代码:

    // Bullet.as
    // 必须声明包
    package {
        // 导入必要的类
        import flash.display.Sprite;
        import flash.events.Event;
        // Bullet 类继承自 Sprite,因为 Sprite 是一个可以绘制图形的显示对象容器
        public class Bullet extends Sprite {
            // 1. 定义属性
            private var speed:Number; // 子弹的移动速度
            // 2. 构造函数,当使用 new Bullet() 创建对象时,此函数自动执行
            public function Bullet(startX:Number, startY:Number) {
                // 设置子弹的初始位置
                this.x = startX;
                this.y = startY;
                // 设置子弹的移动速度
                this.speed = 10;
                // 绘制子弹的图形(一个黄色小方块)
                this.graphics.beginFill(0xFFFF00); // 黄色
                this.graphics.drawRect(-2.5, -10, 5, 20); // 从中心点绘制,宽5,高20
                this.graphics.endFill();
            }
            // 3. 更新子弹位置的方法
            public function update():void {
                this.y -= speed; // y 坐标减少,向上移动
                // 如果子弹移出屏幕顶部,则销毁它
                if (this.y < -20) {
                    destroy();
                }
            }
            // 4. 销毁子弹的方法
            public function destroy():void {
                // 从显示列表中移除
                if (this.parent) {
                    this.parent.removeChild(this);
                }
                // 停止并移除事件监听(如果有的话)
                this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            }
            // 5. 进入帧循环事件处理函数
            private function onEnterFrame(event:Event):void {
                update();
            }
        }
    }
  4. 回到你的 .fla 主文件,按 F9 打开动作面板,输入以下代码:

    // 在舞台上创建一个容器来存放所有子弹,方便管理
    var bulletContainer:Sprite = new Sprite();
    addChild(bulletContainer);
    // 监听键盘事件
    stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
    // 键盘按下事件处理函数
    function onKeyDown(event:KeyboardEvent):void {
        // 如果按下的键是空格键
        if (event.keyCode == Keyboard.SPACE) {
            // 在屏幕底部中央创建一颗新子弹
            var bullet:Bullet = new Bullet(stage.stageWidth / 2, stage.stageHeight - 20);
            // 将子弹添加到子弹容器中
            bulletContainer.addChild(bullet);
            // 为子弹添加一个 ENTER_FRAME 事件监听
            // 这个事件会在每一帧(每秒约60次)都触发一次,非常适合做动画
            bullet.addEventListener(Event.ENTER_FRAME, bullet.onEnterFrame);
        }
    }
  5. Ctrl + Enter 测试影片,按空格键发射子弹。

代码解析

  • package { ... },在 AS3 中,所有的类都必须放在一个包里,这有助于组织代码,主 .fla 文件的代码在默认包(无名称包)中。
  • public class Bullet extends Sprite { ... }类定义
    • public class Bullet:声明一个名为 Bullet 的公共类。
    • extends Sprite继承Bullet 类继承了 Sprite 类的所有属性和方法。Sprite 是一个轻量级的显示对象,非常适合用作游戏中的子弹、敌人等。
  • public function Bullet(...) { ... }构造函数,它的名字必须和类名完全一样,当用 new Bullet() 创建对象时,构造函数里的代码会自动执行,通常用于初始化对象的属性。
  • addEventListener(Event.ENTER_FRAME, ...)帧循环Event.ENTER_FRAME 是一个特殊的事件,它会在每一帧渲染前触发,这是制作游戏动画最常用、最高效的方式。

综合应用—— 简单的打飞机游戏

这个实例将综合运用前面所学的知识,制作一个极简版的打飞机游戏。

目标:玩家控制一架飞机,按空格键发射子弹,击中从上方下落的敌人。

步骤

  1. 准备工作

    • 创建三个影片剪辑:Player (玩家飞机)、Enemy (敌人)、Bullet (子弹),分别给它们导出类名,并保存对应的 .as 文件(Player.as, Enemy.as, Bullet.as)。
    • Player.as 中,添加 leftright 属性来控制移动。
    • Enemy.as 中,添加 update() 方法使其下落。
    • Bullet.as 代码如实例三所示。
  2. 主场景代码 (MainTimeline)

    // MainTimeline.as (写在 .fla 的第一帧)
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    public class MainTimeline extends Sprite {
        private var player:Player;
        private var bulletContainer:Sprite;
        private var enemyContainer:Sprite;
        private var enemySpawnTimer:int = 0;
        public function MainTimeline() {
            // 构造函数,初始化游戏
            init();
        }
        private function init():void {
            // 创建玩家
            player = new Player();
            player.x = stage.stageWidth / 2;
            player.y = stage.stageHeight - 50;
            addChild(player);
            // 创建子弹和敌机的容器
            bulletContainer = new Sprite();
            enemyContainer = new Sprite();
            addChild(bulletContainer);
            addChild(enemyContainer);
            // 添加事件监听
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
            addEventListener(Event.ENTER_FRAME, gameLoop);
        }
        private function gameLoop(event:Event):void {
            // 1. 更新玩家位置
            if (player.isLeft) {
                player.x -= 5;
            }
            if (player.isRight) {
                player.x += 5;
            }
            // 2. 更新所有子弹
            for (var i:int = bulletContainer.numChildren - 1; i >= 0; i--) {
                var bullet:Bullet = bulletContainer.getChildAt(i) as Bullet;
                bullet.update();
            }
            // 3. 更新所有敌人
            for (var j:int = enemyContainer.numChildren - 1; j >= 0; j--) {
                var enemy:Enemy = enemyContainer.getChildAt(j) as Enemy;
                enemy.update();
            }
            // 4. 生成敌人
            enemySpawnTimer++;
            if (enemySpawnTimer > 60) { // 每秒生成一个敌人
                spawnEnemy();
                enemySpawnTimer = 0;
            }
            // 5. 碰撞检测
            checkCollisions();
        }
        private function spawnEnemy():void {
            var enemy:Enemy = new Enemy();
            enemy.x = Math.random() * stage.stageWidth;
            enemy.y = -20;
            enemyContainer.addChild(enemy);
        }
        private function checkCollisions():void {
            // 遍历所有子弹和敌人
            for (var i:int = bulletContainer.numChildren - 1; i >= 0; i--) {
                var bullet:Bullet = bulletContainer.getChildAt(i) as Bullet;
                for (var j:int = enemyContainer.numChildren - 1; j >= 0; j--) {
                    var enemy:Enemy = enemyContainer.getChildAt(j) as Enemy;
                    // 简单的矩形碰撞检测
                    if (bullet.hitTestObject(enemy)) {
                        // 击中!
                        trace("Hit!");
                        bullet.destroy();
                        enemy.destroy();
                        // 这里可以加分、播放爆炸动画等
                    }
                }
            }
        }
        private function onKeyDown(event:KeyboardEvent):void {
            if (event.keyCode == Keyboard.LEFT) {
                player.isLeft = true;
            } else if (event.keyCode == Keyboard.RIGHT) {
                player.isRight = true;
            } else if (event.keyCode == Keyboard.SPACE) {
                // 发射子弹
                var bullet:Bullet = new Bullet(player.x, player.y - 20);
                bulletContainer.addChild(bullet);
                bullet.addEventListener(Event.ENTER_FRAME, bullet.onEnterFrame);
            }
        }
        private function onKeyUp(event:KeyboardEvent):void {
            if (event.keyCode == Keyboard.LEFT) {
                player.isLeft = false;
            } else if (event.keyCode == Keyboard.RIGHT) {
                player.isRight = false;
            }
        }
    }
  3. Player.as 类文件

    // Player.as
    package {
        import flash.display.Sprite;
        public class Player extends Sprite {
            public var isLeft:Boolean = false;
            public var isRight:Boolean = false;
            public function Player() {
                // 绘制玩家飞机
                this.graphics.beginFill(0x00FF00);
                this.graphics.moveTo(0, -15);
                this.graphics.lineTo(-10, 15);
                this.graphics.lineTo(10, 15);
                this.graphics.lineTo(0, -15);
                this.graphics.endFill();
            }
        }
    }
  4. Enemy.as 类文件

    // Enemy.as
    package {
        import flash.display.Sprite;
        import flash.events.Event;
        public class Enemy extends Sprite {
            private var speed:Number = 3;
            public function Enemy() {
                // 绘制敌人
                this.graphics.beginFill(0xFF0000);
                this.graphics.drawRect(-10, -10, 20, 20);
                this.graphics.endFill();
            }
            public function update():void {
                this.y += speed;
                if (this.y > stage.stageHeight + 20) {
                    destroy();
                }
            }
            public function destroy():void {
                if (this.parent) {
                    this.parent.removeChild(this);
                }
                this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
            }
            private function onEnterFrame(event:Event):void {
                update();
            }
        }
    }

这个综合实例展示了

  • 主类MainTimeline 作为游戏控制器,管理所有游戏对象和主循环。
  • 玩家控制:通过键盘事件控制玩家飞机左右移动。
  • 对象池思想:使用 Container (Sprite) 来批量管理子弹和敌人,方便遍历和销毁。
  • 游戏循环gameLoop 函数是游戏的核心,处理所有逻辑更新。
  • 碰撞检测:使用 hitTestObject 方法检测子弹和敌人是否发生碰撞。
  • 面向对象:玩家、子弹、敌人都是独立的类,职责分明,易于扩展。

总结与进阶

通过以上四个实例,你已经掌握了 AS3 的核心概念:

  1. 基础语法:变量、函数、数据类型。
  2. 显示列表addChild, removeChild
  3. 事件模型addEventListener, MouseEvent, KeyboardEvent, Event.ENTER_FRAME
  4. 面向对象package, class, extends, constructor

进阶学习方向

  • 动画与缓动:学习使用 TweenLite (GreenSock Tweening Platform) 等第三方库制作更流畅的动画。
  • 游戏物理:实现简单的重力、速度、加速度等物理效果。
  • 数据管理:学习使用 Array, Vector, Dictionary 等数据结构来高效地管理游戏对象。
  • 声音与视频:学习如何加载和播放外部资源(图片、声音、视频)。
  • 与服务器通信:学习使用 SocketXML/JSON 与后端进行数据交互,制作在线游戏。

希望这份教程能帮助你顺利入门 ActionScript 3.0!编程最好的老师就是实践,多写代码,多尝试,你很快就能掌握它。