Sounds On Keypress

Hey everyone,
I’m new to this website and also kinda new to Java but am using BlueJ to code a game as a side project. I am making a 2d Fighting Game. I don’t know how to make it so when it punches it makes the sound, so like A and D to walk left and right across the screen and E for punch and R to kick, I’m trying to make it so when you press the corresponding buttons the sounds will play for either punching or kicking. Can anyone help me with this? Thanks In Advance :slight_smile:

Well this is really a question of two things:

a) How do I respond to key presses
and
b) How do I play sounds

If you know both you should be able to do what you want.

If you’re using Swing, key presses are pretty easy


public class MyWindow extends JFrame implements KeyListener
{
    // a bunch of your class's stuff

    public void keyPressed(KeyEvent e)
    {
        int i = e.getKeyChar();
        if (i == KeyEvent.VK_UP)
        {
            // Move up!
        }
        //etc.
    }

    public void keyReleased(KeyEvent e)
    {
        int i = e.getKeyChar();
        if (i == KeyEvent.VK_A)
        {
            System.out.println("Punch!");
        }
        else if (i == KeyEvent.VK_B)
        {
            System.out.println("Kick!");
        }
    }

    public void keyTyped(KeyEvent e) {//do nothing}
}

As for sounds, this is a much more complicated beast. Have a look around the forums and you should find many, many, different ways of implementing it.


Sound doesn’t have to be complicated, either. The easiest option is probably my SoundSystem Library (perhaps overkill for your project, but very easy to use). You would need the SoundSystem core, LibraryJavaSound plug-in, and a codec plug-in (CodecWav, for example). Assuming you have sound files named “punch.wav” and “kick.wav”, you would compile them into your JAR in a package/directory named “Sounds”. Here is Demonpants’ example with sound effects added in:

// Add these imports at top of the program:
import paulscode.sound.SoundSystem;
import paulscode.sound.SoundSystemConfig;
import paulscode.sound.SoundSystemException;
import paulscode.sound.libraries.LibraryJavaSound;
import paulscode.sound.codecs.CodecWav;
//...etc

// And you'll need a SoundSystem handle:
SoundSystem mySoundSystem;

public class MyWindow extends JFrame implements KeyListener
{
    // Call initSound() from the constructor or from an initialization method:
    public void initSound()
    {
        try
        {
            SoundSystemConfig.addLibrary( LibraryJavaSound.class );
            SoundSystemConfig.setCodec( "wav", CodecWav.class );
            mySoundSystem = new SoundSystem();
        }
        catch( SoundSystemException sse )
        {
            sse.printStackTrace();
        }
    }

    // A method for quickly playing a sound file:
    public void quickPlay( String filename )
    {
        mySoundSystem.quickPlay( false, filename, false,
            0, 0, 0,
            SoundSystemConfig.ATTENUATION_ROLLOFF,
            SoundSystemConfig.getDefaultRolloff() );
    }
 
    public void keyPressed(KeyEvent e)
    {
        int i = e.getKeyChar();
        if (i == KeyEvent.VK_UP)
        {
            // Move up!
        }
        //etc.
    }

    public void keyReleased(KeyEvent e)
    {
        int i = e.getKeyChar();
        if (i == KeyEvent.VK_A)
        {
            System.out.println("Punch!");
            quickPlay( "punch.wav" );
        }
        else if (i == KeyEvent.VK_B)
        {
            System.out.println("Kick!");
            quickPlay( "kick.wav" );
        }
    }

    public void keyTyped(KeyEvent e) {//do nothing}
}

I appreciate the help you guys, I found something that seems to be working for it so far, but is this okay or do I need to do something more complicated?

import java.awt.*;
import java.applet.*;

public class Project30 extends Applet
{
   Image Buffer;
   Graphics gBuffer;
   boolean pressedLeft, pressedRight, pressedUp, pressedDown;
   AudioClip mySound1;
   AudioClip mySound2;
   AudioClip mySound3;
   AudioClip mySound4;
   AudioClip mySound5;


   public void init()
   {
      Buffer=createImage(size().width,size().height);
      gBuffer=Buffer.getGraphics();

      try
      {
           mySound1=getAudioClip(getCodeBase(),"punch.wav");
           mySound2=getAudioClip(getCodeBase(),"kick.wav");
           mySound3=getAudioClip(getCodeBase(),"punch2.wav");
           mySound4=getAudioClip(getCodeBase(),"punch3.wav");
           mySound5=getAudioClip(getCodeBase(),"sword.wav");
      }

      catch (Exception e){}
   }

   public boolean keyDown(Event e, int key)
   {
      if(key==Event.LEFT)
      pressedLeft=true;

      if(key==Event.RIGHT)
      pressedRight=true;

      if(key==Event.UP)
      pressedUp=true;
      if(key==Event.DOWN)
      pressedDown=true;

      if(key=='s'||key=='S')
           mySound1.play();

      if(key=='e'||key=='E')
           mySound2.play();      
           
      if(key=='r'||key=='R')
           mySound3.play(); 
           
      if(key=='q'||key=='Q')
           mySound4.play();
 
      if(key=='d'||key=='D')
           mySound5.play(); 
           
      if(key=='9'||key=='9')
           mySound5.play(); 
           
      repaint();

      return true;
   }

Also I would like a song playing in the background as all this is going on, how would I go about that?

That should work fine for playing short clips. Background music depends on the length of the song and the format.

There is a maximum size that an audio clip can be (generally around 5 seconds or so, depending on the quality). If your song is longer than that, you will need to “stream” it. That’s where you feed the data to a line in chunks over time (as one chunk finishes, you feed in another). Most developers will run that process on a separate Thread.

If your song is a MIDI file, you don’t stream it. MIDI is a complicated format, not like other audio formats. In that case, you would read the data from the MIDI file (called the Sequence), pass that information to an available Sequencer, and link that to an available Synthesizer which outputs the music.

If you need to do either of these two options (i.e. if your music is too long or if it is MIDI), then I recommend using the SoundSystem library I mentioned earlier, because it makes both of these processes much easier (1 line of code vs. 30 lines).
After initializing the SoundSystem as mentioned in my earlier post, you can simply use the backgroundMusic method (works for both MIDI and for long audio files):

mySoundSystem.backgroundMusic( "Background Music", "beethoven.mid", true );

If you want to use AudioClip to play music (AudioClip, in my opinion, is the easiest way to get sound to work at a very minimal level), you can just link a sounds like you did otherwise except call mySound.loop() instead of mySound.play(). The big problem with this, aside from AudioClip sucking many ways in general, is that you can’t use compressed audio in any fashion whatsoever. So your game will be 99% sounds (in terms of disk space) if you don’t use compressed audio.

paulscode’s library is great, but it might be too difficult for you at this point to use external libraries - if you’re not worried about file size and potential issues just stick with AudioClip.

I just noticed you were using java.applet.AudioClip (for some reason I interpreted this as javax.sound.sampled.clip). Disregard my comment about the length limitation. AudioClip can play longer files I believe, and it supports the wav, .au, and .aif formats. The limitation with this method is that it only provides play(), loop(), and stop() functions, and the supported file formats can get rather large in size as Demonpants pointed out (especially if you are considering music). Otherwise, it is a simple solution.

So to use AudioClip I need to add a new thread? is that what you were saying?

Also if I wanted a sound to play right at the beginning to say like Fight! or something like that how would I just add that to play once at the very beginning and then not play anymore till the next time it is played, or make it so at the end of the game it says You Win! Thanks for all the help

Lol wow I feel stupid lol. Sorry I was not paying attention to what I was saying, I already have the audioclip but how do I make background music into it?

I’ve never used AudioClip myself, to be honest. Is there a limitation with this class preventing you from creating and playing a couple of AudioClip’s for your “Fight!” sound and the background music, somewhere at the beginning of your program (say in the init() method)?

try
{
    getAudioClip( getCodeBase(), "FIGHT!!!.wav" ).play();
    getAudioClip( getCodeBase(), "myCoolMusic.wav" ).play();
}
catch( Exception e ){}

I’m assuming AudioClip’s play in the background (according to JavaDoc they play on their own thread). Is that not the case, or are you only able to play one at a time or something?

vection, you should probably study up a bit more on Java in general if you can. Your questions are not really sound related. Here is a simple pseudo code game that has background music and plays sounds when you press buttons.


public class SimpleGame
{
    AudioClip music;
    AudioClip punchSound;
    AudioClip fightSound;

    public void preloadGame()
    {
        try
        {
            music = getAudioClip( getCodeBase(), "music.aif");
            punchSound = getAudioClip( getCodeBase(), "punch.aif");
            fightSound = getAudioClip( getCodeBase(), "fight.aif");

            player.initializePlayer();
            world.preloadWorld();
            //etc.
        }
        catch (Exception e)
        {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void startGame()
    {
        music.loop();
        fightSound.play();

        while (inGameLoop)
        {
            player.update();
            world.update();
            //etc.
        }
    }

    public void keyPressed(KeyEvent e)
    {
        if (e.getKeyCode() == KeyEvent.VK_A)
        {
            player.punch();
            punchSound.play();
        }
    }
}

That should hopefully illuminate things for you, even though the code’s design is totally retarded (for example, you wouldn’t play sounds from the main class, you would have player.punch() play the punch sound, and world.startGame() play the fight sound and the music) and the game loop is totally BS.

This actually worked perfectly for me, I just need to find out how to loop the song after the song ends. :slight_smile:

Ok so now how would I make it so the ouch sound would play when the characters get hit by a punch or kick?

As Demonpants suggested, why not just use loop() instead of play()?

The same way you are playing a sound when a key is pressed, you would simply create your AudioClip instance at the beginning of your program, and then call play() on it when an impact occurred.

I wouldn’t recommend doing it exactly as paulscode suggested, as you’re instantiating a new sound every single time you play it, which is crazy wasteful and really really slow. I think he put that example there just to give you a clearer idea of what’s going on. Instead, do as I suggested, and store the sound somewhere, only to play it later.

And honestly I’m sort of frustrated with you at this point as you don’t seem to be actually reading what we’re saying to you. You have now been told three times how to loop a sound.

Similarly, you asking now how to make an ouch sound shows that in general you just don’t understand what you’re doing yet. Go back to basics and learn how code / Java work, because your comprehension right now is severely limited. To play a sound, anywhere, at any time, you use sound.play() at the bit of code where you would want the sound to play. It’s the same concept. Exactly the same.

Just to clarify, my suggestion was for the two sounds that are played only once, in which case you would not be instantiating a new sound every single time you play it, because you are only playing it once.

Ah, that makes more sense, then. I didn’t realize that. :slight_smile:

Sorry, is it possible to explain this with more depth? The other way didn’t end up working in the end :frowning:
Thanks.