synchronizing sound
It appears my sound is off sync and the longer I play the movieclip, the farther off sync it goes. Its nothing too complicated, just some basic shooting sounds that fire every time I hit the space bar. My code is below:
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开发者_Go百科.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
{
}
}
}
The Attack() method gets called from another class that handles all keyboard controls. when it gets called the sound then plays. firesound and firesound2 are almost the same. firesound2 sounds a little off pitch to make it sound more realistic. At first the sound sounds pretty good, not great. but then it gets terrible as time passes. Not sure if this is a known issue. But if anyone has any ideas, let me know. thanks!
I made a new .fla project. and I attached the following class to it by it self. so the following is the only code in the entire .fla project and the issue still occurs. I press the spacebar and the sound starts a day late.
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();
}
}
}
}
}
Any chance this could be something to do with the number of concurrent sounds playing?
Each call to Sound.play() returns a new SoundChannel object (you can only have 32 of these at a time). You could monitor how the channels are being used like this:
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);
This might help you pinpoint the problem.
EDIT: I changed the code above to keep a running count of how many sounds are playing concurrently (I hope - sorry you'll have to test it for me!)
I tested a build using this test code and my own sound files, and am unable to encounter the sound lagging issue. It could be your sound files, though there are no issues that I am aware of that would cause calls to Sound.play() to begin lagging.
The sound files I used to test were short (Mario fireball and jump sounds), and was unable to get more than 4 concurrent SoundChannels in use. No latency issues.
Using longer length sound files, I was able to push the number of SoundChannels to 32, at which point the channel tracer code began throwing null reference errors (as would be expected since Sound.play() cannot return more SoundChannels), and it sounded pretty awful, but once the sounds completed the count decremented to zero. After two straight minutes of punishing my headphones and soundcard, I still encountered no latency.
I'd suggest inserting calls to getTimer() throughout your code to see if it's a performance bottleneck (i.e. Flash Player not actually responding to events quickly) or a sound latency issue. Also, you may want try different sound files to see if the issue still occurs.
精彩评论