同步声音

时间:2010-01-31 20:37:19

标签: flash actionscript-3 actionscript flash-cs4

看来我的声音不同步,我播放动画片段的时间越长,它就会越走越远。它没什么太复杂的,只是一些基本的射击声,每当我击中空格键时都会发出声音。我的代码如下:

package com.objects{

    import flash.display.MovieClip;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.net.URLRequest;
    import flash.events.Event;

    public class Avatar extends gameObject implements IKiller{

        public var targets:Array;
        public var delay:Number = 3000;
        public var weapon:Number = 1;
        private var fireSound:Sound;
        private var fireSound2:Sound;
        private var systems:Array;
        private var ext:Number = -1;
        private var channelTracer:SoundChannel;
        private var channelCount:Number = 0;


        public function Avatar():void
        {
            systems = new Array();
            channelTracer = new SoundChannel();
            var soundUrl = new URLRequest("com/images/mashingun_darkt.mp3");
            fireSound = new Sound();
            fireSound.load(soundUrl);

            var soundUrl = new URLRequest("com/images/mashingun_light.mp3");
            fireSound2 = new Sound();
            fireSound2.load(soundUrl);

            rotation = -90;
            lastTime = getTime();
            targets = new Array();
        }

        private function soundFinished(e:Event):void {
            channelCount--;
            trace(channelCount);
        }


        public function get Systems():Array
        {
            return systems;
        }

        override public function Attack(dir:Number = -40):void
        {
            switch(weapon){

                case 1:                 
                    var bullet1:Bullet = new Bullet();
                    bullet1.wielder = this;
                    bullet1.x = x + 35;
                    bullet1.y = y + 30;
                    bullet1.bulletDir = rotation;
                    eApi.addGameChild(bullet1);

                    var bullet2:Bullet = new Bullet();
                    bullet2.bulletDir = rotation;
                    bullet2.wielder = this;
                    bullet2.x = x - 35;
                    bullet2.y = y + 30;
                    eApi.addGameChild(bullet2);

                    var rand = Math.ceil(Math.random() * 100);
                    if (rand < 50) {
                        channelTracer = fireSound.play();
                        //RndSound = RndSound+50;
                    } else {
                        channelTracer = fireSound2.play();

                    }
                    channelTracer.addEventListener(Event.SOUND_COMPLETE, soundFinished);
                    channelCount++;
                    trace(channelCount);

                break;
                case 2:
                    if((getTime() - lastTime) > delay)
                    {
                        var missle = new Missile();
                        missle.shootOut *=  ext;
                        ext *= -1;
                        missle.x = x;
                        missle.y = y;
                        trace(ext);
                        missle.wielder = this;
                        eApi.addGameChildAt((eApi.numChildren - 2),missle);
                        lastTime = getTime();
                    }
                break;
                case 3:
                    var bullet1:Bullet = new Bullet();
                    bullet1.wielder = this;
                    bullet1.x = x + 35;
                    bullet1.y = y + 30;
                    bullet1.bulletDir = -80;
                    eApi.addGameChild(bullet1);

                    var laser = new StingerLaser();
                    laser.laserDir = -90;
                    laser.wielder.push(this);
                    laser.x = x + 20;
                    laser.y = y + -3;
                    eApi.addGameChild(laser);

                    var laser2 = new StingerLaser();
                    laser2.laserDir = -90;
                    laser2.wielder.push(this);
                    laser2.x = x + -20;
                    laser2.y = y + -3;
                    eApi.addGameChild(laser2);

                    var bullet2:Bullet = new Bullet();
                    bullet2.bulletDir = -100;
                    bullet2.wielder = this;
                    bullet2.x = x - 35;
                    bullet2.y = y + 30;
                    eApi.addGameChild(bullet2);
                break;              
                case 4:
                    if((getTime() - lastTime) > delay)
                    {
                        var missle1 = new Missile();
                        missle1.shootOut =  2;
                        missle1.x = x;
                        missle1.y = y;
                        missle1.wielder = this;
                        eApi.addGameChildAt((eApi.numChildren - 2),missle1);

                        var missle2 = new Missile();
                        missle2.shootOut =  -2;
                        missle2.x = x;
                        missle2.y = y;
                        missle2.wielder = this;
                        eApi.addGameChildAt((eApi.numChildren - 2),missle2);
                        lastTime = getTime();
                    }
                break;
                case 5:
                    if((getTime() - lastTime) > delay)
                    {
                        var side:Number = 1;
                        for(var i = 0; i < 20; i+=2)
                        {
                            var missle1 = new Missile();
                            missle1.shootOut =  (i+2) * side;
                            side *= -1;
                            missle1.straightShot = true;
                            missle1.x = x;
                            missle1.y = y;
                            missle1.wielder = this;
                            eApi.addGameChildAt((eApi.numChildren - 2),missle1);
                        }
                        lastTime = getTime();
                    }
                break;
                default:
            }
        }

        public function Hit(dmg:Number = .01):void {
            if(health > 0)
                health -= dmg;

            if(health < 0)
                health = 0,trace("dead");
        }

        override public function updateObject():void
        {

        }
    }
}

从另一个处理所有键盘控件的类调用Attack()方法。当它被调用时,声音然后播放。 firesound和firesound2几乎相同。 firesound2听起来有点偏离,使声音听起来更逼真。起初声音听起来不错,不是很好。但随着时间的推移它会变得很糟糕。不确定这是否是一个已知问题。但如果有人有任何想法,请告诉我。谢谢!

我做了一个新的.fla项目。并且我自己将下面的课程附加到它上面。所以以下是整个.fla项目中唯一的代码,问题仍然存在。我按空格键,声音开始一天晚了。

package {
    import flash.display.MovieClip;
    import flash.events.*;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.net.URLRequest;

    public class test extends MovieClip
    {
        private var fireSound:Sound;
        private var fireSound2:Sound;
        private var aKeyPress:Array;

        public function test():void
        {
            aKeyPress = new Array();
            var soundUrl = new URLRequest("com/images/mashingun_darkt.mp3");
            fireSound = new Sound();
            fireSound.load(soundUrl);

            var soundUrl = new URLRequest("com/images/mashingun_light.mp3");
            fireSound2 = new Sound();
            fireSound2.load(soundUrl);
            addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownListener);
            stage.addEventListener(KeyboardEvent.KEY_UP,keyUpListener);
        }
        private function keyDownListener(e:KeyboardEvent) {
            //trace("down e.keyCode=" + e.keyCode);         
            aKeyPress[e.keyCode]=true;
        }

        private function keyUpListener(e:KeyboardEvent) {
            //trace("up e.keyCode=" + e.keyCode);
            aKeyPress[e.keyCode]=false;
        }
        public function loop(e:Event):void
        {
            if (aKeyPress[32]){//Right
                    var rand = Math.ceil(Math.random() * 100);
                    if (rand < 50) {
                        fireSound.play();
                        //RndSound = RndSound+50;
                    } else {
                        fireSound2.play();
                    }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

这可能与播放的并发声音数量有关吗?

每次调用Sound.play()都会返回一个新的SoundChannel对象(一次只能有32个这样的对象)。您可以像这样监视频道的使用方式:

private var channelTracer:SoundChannel;
private var channelCount:number = 0;
//...

private function soundFinished(e:Event):void {
channelCount--;
trace(channelCount);
}

//...

var rand = Math.random() * 100;
if (rand < 50) {
channelTracer = fireSound.play();
} else {
channelTracer = fireSound2.play();
}
channelTracer.addEventListener(Event.SOUND_COMPLETE, soundFinished);
channelCount++;
trace(channelCount);

这可能有助于您查明问题。

编辑:我更改了上面的代码以保持同时播放的声音的运行次数(我希望 - 抱歉,你必须为我测试它!)

答案 1 :(得分:1)

我使用此测试代码和我自己的声音文件测试了构建,并且无法遇到声音滞后问题。它可能是你的声音文件,虽然没有我知道的问题会导致调用Sound.play()开始滞后。

我以前测试的声音文件很短(马里奥火球和跳跃声音),并且无法使用超过4个并发的SoundChannel。没有延迟问题。

使用更长的声音文件,我能够将SoundChannel的数量推到32,此时通道跟踪器代码开始抛出空引用错误(正如预期的那样,因为Sound.play()无法返回更多的SoundChannels),它听起来很糟糕,但一旦声音完成,计数就会减少到零。经过两分钟的惩罚我的耳机和声卡,我仍然没有遇到延迟。

我建议在整个代码中插入对getTimer()的调用,以查看它是否是性能瓶颈(即Flash Player实际上没有快速响应事件)或声音延迟问题。此外,您可能需要尝试不同的声音文件,以查看问题是否仍然存在。