Sunday, May 27, 2012

SnoozeBlitz!!!

yo yo yo! i'm super excited co'z i just officially finished my latest game! :D

SnoozeBlitz! check it out!

SnoozeBlitz!

yes i know i have said that before but this time it's different, when i first finished it it didn't have any sounds in it and to be honest i didn't put much thought on that subject, luckily enough, world famous musician Omri Lahav saw my game and generously enough offered to compose music for my game, yey! not only did this give me motivation to add sound effects in the actual game but also to try a bit of sound programming, if you will pay close attention in the game you will notice how to music tempo is increased according to the wakeOmeter in the top left, below 20% it sound normal but it gets crazy towards the 100% :D

Omri Lahav

sooooo, i would like to give a big thanks to Omri Lahav, who made all the music in the game, to be honest i never thought music and sound could make such a big different in games (especially in casual games) but lo and behold, i was proven wrong, if you want to see the true difference for yourself just mute the sound before you start play, it's bad!





and now for all you code lovers, when i first wanted to make the sound speed up, what i did of course was googling "as3 speed up sound", eventually i came across this page, in which i'v learned that Flash Player 10.1 had a new Sound API, which enables developers easy way to sound programming, you can basically write the bytes yourself,

here's the class that i wrote for my game, for a Sound Class you can also speed up on the fly:
i can't take any credit for it though :P it's almost identical to the original.

package 
{
import flash.events.Event;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.utils.ByteArray;
public class SpeedUpSound
{
private var sound:Sound;
private var rawSound:Sound;
private var bytes:ByteArray;
private var position:Number = 0;
private var _speed:Number = 1;
private var totalLength:int;
public function SpeedUpSound(s:Sound):void {
sound = s;
rawSound = new Sound();
bytes = new ByteArray();
sound.extract(bytes, int(s.length * 44.1));
totalLength = bytes.length / 8;
}
public function set speed(s):void {
_speed = s;
}
public function play():void {
if(! rawSound.hasEventListener(SampleDataEvent.SAMPLE_DATA)){
rawSound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleRawSoundData);
}
rawSound.play();
}
public function restart():void {
_speed = 1;
position = 0;
}
public function stop():void {
_speed = 1;
position = 0;
if(rawSound.hasEventListener(SampleDataEvent.SAMPLE_DATA)){
rawSound.removeEventListener(SampleDataEvent.SAMPLE_DATA, sampleRawSoundData);
}
}
public function pause():void {
if(rawSound.hasEventListener(SampleDataEvent.SAMPLE_DATA)){
rawSound.removeEventListener(SampleDataEvent.SAMPLE_DATA, sampleRawSoundData);
}
}
private function sampleRawSoundData(e:SampleDataEvent):void {

var l:Number;
var r:Number;
 
var outputLength:int = 0;
while (outputLength < 2048) { 
// until we have filled up enough output buffer
// move to the correct location in our loaded samples ByteArray
bytes.position = int(position) * 8; // 4 bytes per float and two channels so the actual position in the ByteArray is a factor of 8 bigger than the phase
// read out the left and right channels at this position
l = bytes.readFloat();
r = bytes.readFloat();
// write the samples to our output buffer
e.data.writeFloat(l);
e.data.writeFloat(r);
outputLength++;
// advance the phase by the speed...
position += _speed;
// and deal with looping (including looping back past the beginning when playing in reverse)
if (position < 0) {
  position += totalLength;
} else if (position >= totalLength) {
  position -= totalLength;
}
}
}
}
}


this class is short enough to read through but i'l break it down for you,
basically what happens is this:
when creating a new Sound Class in as3, if no sound is loaded in it, it will try to dynamically read sound bytes using the SAMPLE_DATA event.
when this event is called you can use it to write memory into the sound object, in any way you want, in this class we extract sound data from the the Sound class using Sound.extract() function into a ByteArray object, and then we read from this object and write to the SAMPLE_DATA event, in any rate we want, thus changing the music's tempo.

to be honest i would never have any idea how the sound bytes array structure is built if i hadn't read the article if found, stuff like the rate in which the sound is coded (44.1) and that the Sound byte array have a Float for each channel in the array :P i guess is more obvious to you if you do sound programming.

so! try the game, publish your score, tell your friends, don't do drugs, stay in school, and if you find any bugs let me know! cheers! :D