Foundation Game Design with ActionScript 3.0, Second Edition (90 page)

BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
6.98Mb size Format: txt, pdf, ePub
package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.ui.Keyboard;
  [SWF(width="550", height="400",
    backgroundColor="#FFFFFF", frameRate="60")]
  public class Jumping extends Sprite
  {
    private var _character:Character = new Character();;
    public function Jumping()
    {
      //Add the character to the stage
      stage.addChild(_character);
      _character.x = 250;
      _character.y = 175;
      //Add the event listeners
      stage.addEventListener
        (KeyboardEvent.KEY_DOWN, keyDownHandler);
      stage.addEventListener
        (KeyboardEvent.KEY_UP, keyUpHandler);
      stage.addEventListener
        (Event.ENTER_FRAME, enterFrameHandler);
    }
    public function keyDownHandler(event:KeyboardEvent):void
    {
      if (event.keyCode == Keyboard.LEFT)
      {
        _character.accelerationX = -0.2;
      }
      else if (event.keyCode == Keyboard.RIGHT)
      {
          _character.accelerationX = 0.2;
      }
      
else if (event.keyCode == Keyboard.UP
        
|| event.keyCode == Keyboard.SPACE)
      
{
        
if(_character.isOnGround)
        
{
          
_character.vy += _character.jumpForce;
          
_character.isOnGround = false;
        
}
      
}
    }
    public function keyUpHandler(event:KeyboardEvent):void
        {
      if (event.keyCode == Keyboard.LEFT
        || event.keyCode == Keyboard.RIGHT)
      {
        _character.accelerationX = 0;
      }
    }
    public function enterFrameHandler(event:Event):void
    {
      //Apply acceleration
      _character.vx += _character.accelerationX;
      
//Apply friction
      _character.vx *= _character.friction;
      
//Apply gravity
      _character.vy += _character.gravity;
      
//Limit the speed, except when the character
      //is moving upwards
      if (_character.vx > _character.speedLimit)
      {
        _character.vx = _character.speedLimit;
      }
      if (_character.vx < -_character.speedLimit)
      {
        _character.vx = -_character.speedLimit;
      }
      if (_character.vy > _character.speedLimit * 2)
      {
        _character.vy = _character.speedLimit * 2;
      }
      //Force the velocity to zero
      //after it falls below 0.1
      if (Math.abs(_character.vx) < 0.1)
      {
        _character.vx = 0;
      }
      if (Math.abs(_character.vy) < 0.1)
      {
        _character.vy = 0;
      }
      
//Move the character
      
_character.x += _character.vx;
      
_character.y += _character.vy;
      //Check stage boundaries
      if (_character.x < 0)
      {
        _character.vx = 0;
        _character.x = 0;
      }
      if (_character.y < 0)
      {
        _character.vy = 0;
        _character.y = 0;
      }
      if (_character.x + _character.width > stage.stageWidth)
      {
        _character.vx = 0;
        _character.x = stage.stageWidth - _character.width;
      }
      
if (_character.y + _character.height > stage.stageHeight)
      
{
        
_character.vy = 0;
        
_character.y = stage.stageHeight - _character.height;
        
_character.isOnGround = true;
      
}
    }
  }
}
Adding sounds to games

You now have a nice, bouncing, jumping game character. Wouldn't it be great to add a sound effect each time it jumps? Playing sounds in game is not difficult at all, and I'll show you how in this section.

Open the PlayingSounds project folder in the chapter's source file. Along with the usual folders, you'll find a new folder called sounds. It contains an MP3 file called bounce.mp3 (
Figure 9-8
). This MP3 file is going to be embedded into the application class in exactly the same way you've been embedding images.

Figure 9-8.
Keep your game sounds in a sounds folder with the rest of the project files.

Run the SWF file and press the space key. You'll hear a “bounce” sound, typical of the kind made by jumping game characters

Here's the entire
PlayingSounds
class. I've highlighted all the code that embeds the sound, creates the sound objects, and plays the sound.

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.ui.Keyboard;
  //Classes needed to play sounds
  import flash.media.Sound;
  import flash.media.SoundChannel;
  [SWF(width="550", height="400",
    backgroundColor="#FFFFFF", frameRate="60")]
  public class PlayingSounds extends Sprite
  {
    //Embed the sound
    [Embed(source="../sounds/bounce.mp3")]
    private var Bounce:Class;
    
//Create the Sound and Sound channel
    //objects for the sound
    private var _bounce:Sound = new Bounce();
    private var _bounceChannel:SoundChannel = new SoundChannel();
    public function PlayingSounds()
    {
      stage.addEventListener
        (KeyboardEvent.KEY_DOWN, keyDownHandler);
    }
    public function keyDownHandler(event:KeyboardEvent):void
    {
      if (event.keyCode == Keyboard.SPACE)
      {
        
//Tell the bounce sound channel
        
//to play the bounce sound
        
_bounceChannel = _bounce.play();
      }
    }
  }
}

To use sounds in a game, you need to import two classes:
Sound
and
SoundChannel
.

import flash.media.Sound;
import flash.media.SoundChannel;

You then embed the MP3 file in the class definition in exactly the same way that you embed an image.

[Embed(source="../sounds/bounce.mp3")]
private var Bounce:Class;

You then need to create two objects to help you play the sound.

  • The Sound object
    : This is the actual sound that you want to play.
    private var _bounce:Sound = new Bounce();
  • The SoundChannel object
    : This is an object that plays the sound for you.
    private var _bounceChannel:SoundChannel = new SoundChannel();

You need to use both objects together to play sounds. You can think of the
Sound
class as a CD and a
SoundChannel
as the CD player that actually loads and plays it.

The
SoundChannel
object can then play the
Sound
whenever it's called on to do so. In this case, it happens when you press the space key.

_bounceChannel = _bounce.play();

And that's really all there is to it. Keep this format in mind and you can't go wrong.

Integrating sound effects in a game

To see how to integrate sound effects into the context of a real game, open the JumpingWithSounds projects folder. Run the SWF, turn up the sound on your computer, and you'll now hear a bounce sound each time the character jumps. This is accomplished by playing the bounce sound each time the player presses the up or space key, which happens by running this directive:

_bounceChannel = _bounce.play();

There's a sounds folder in the project folder that contains the bounce.mp3 file. Here's the new code in the
JumpingWithSounds
application class that embeds and plays the sound. First, the
Sound
and
SoundChannel
classes are imported along with all the other classes needed in this example.

import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
//Classes needed to play sounds
import flash.media.Sound;
import flash.media.SoundChannel;

Next, the MP3 file is embedded and the sound objects are created in the class definition.

public class JumpingWithSound extends Sprite
{
  //Embed the sound
  [Embed(source="../sounds/bounce.mp3")]
  private var Bounce:Class;
  
//Create the Sound and Sound channel
  //objects for the sound
  private var _bounce:Sound = new Bounce();
  private var _bounceChannel:SoundChannel = new SoundChannel();
  private var _character:Character = new Character();

Finally, the sound is played by the
keyDownHandler
when the player presses the up or space keys.

else if (event.keyCode == Keyboard.UP
  || event.keyCode == Keyboard.SPACE)
{
  if(_character.isOnGround)
  {
    
_bounceChannel = _bounce.play();
    _character.vy += _character.jumpForce;
    _character.isOnGround = false;
  }
}

Adding sound effects to games like this is just a matter of choosing the right place to call the sound's
play
method. Most of your game sound effects will be short like this, but if you ever need to stop any of them, call the sound object's
stop
method, like this:

_bounceChannel = _bounce.
stop();

If you're using longer sounds that you need to loop, the next section will show you how to do this.

Looping music and setting volume and pan levels

You'll likely have music in your games that you'll need to loop over and over again during the course of the game. And you might also need to control the volume levels of sounds and balance sounds between the left and right speakers. The next sections cover some simple techniques to help you do this.

Looping sounds

Here's the format you need to use to loop a sound when you play it:

_soundChannel = _sound.play(startPosition, timesToPlay);

The
startPosition
is a number in milliseconds. Note that 0 is the very start of the sound and 1000 would be one second into the start of the sound.
timesToPlay
is the number of times you want a sound to play. So if you want to start a sound from the beginning and repeat it ten times, your code could look like this:

_soundChannel = _sound.play(0, 10);

If you want sound to repeat from the 5 second mark very time it repeats, use 5000 as the first argument:

_soundChannel = _sound.play(5000, 10);

To make a sound repeat infinitely (or almost infinitely) you need to use a little trick. Set the second argument, the times to loop, to the maximum possible number that AS3.0 knows. That's actually stored as a property of the integer class that you can access like this:

int.MAX_VALUE

int.MAX_VALUE
is the highest possible value that an integer can be: 2,147,483,647. It means the sound won't loop forever, but it will loop long enough for the player to finish the game—and possibly even continue to loop a few decades well beyond that. Here's how you can use it to make a sound loop “forever”:

_soundChannel = _sound.play(0, int.MAX_VALUE);

If you loop continuous sounds that don't have a discernible start or end, you might hear a moment of silence before the sound plays again. This is because some MP3 formats store the ID3 tag information (the name of the song, name of the artist, and so on) at the beginning or end of the file. That's the silence you hear. If this proves to be a problem, make sure that you export the MP3 file from your audio software without the ID3 information. Most sound editors have this as an option. If you don't have access to the original uncompressed sound file, use a dedicated audio editor, like Audacity, to trim the few milliseconds of silence from the beginning or end of the file. You can download Audacity from

http://audacity.sourceforge.net/download/

You'll also need to download and install the LAME MP3 encoder so that Audacity can export the finished MP3 file. You can find a link to the LAME download site at

http://audacity.sourceforge.net/help/faq?s=install&item=lame-mp3

You can also sometimes get around the few milliseconds delay between loops by starting the sound at a start position other than zero. You'll need to experiment a bit to find the right amount, but 30 is often a good place to start.

_soundChannel = _sound.play(30, int.MAX_VALUE);

This will skip the first 30 milliseconds, which is roughly where the sound gap ends.

On occasions where you need a bit more flexibility and control, you can create a loop using a
SOUND_COMPLETE
event. First, add a
SOUND_COMPLETE
event handler to the
SoundChannel
object when you play the sound.

Other books

Honeyed Words by J. A. Pitts
The Johnstown Flood by David McCullough
The Inquest by Stephen Dando-Collins
The Golden Age by Ajvaz, Michal
Trouble In Paradise by Norris, Stephanie
A Girl Like Me by Ni-Ni Simone
The Four Johns by Ellery Queen
A Greek God In Harlem by Kyeyune, Melissa
Caleb's Story by Patricia MacLachlan