Simple rollover animations with image and sounds for mouseX and mouseY

edited March 2016 in Library Questions

Hello Forum,

I work with a beginning code class of teen-aged students. For the ones who struggle, I have a simple design project where they program a series of images (stop-motion type thinking) to move with mouseX and mouseY. I would like them also to be able to add a sound effect at different places with specific images. I am doing something like the code below but I would like the sound to just play once rather than looping when mouse hovers? And, I am assuming there are better ways to set up roll-over SFX - would love thoughts on how to make the sounds play once and other cool ways to simplify the loading of sound with roll-over images. Thanks!

//SOUND
import ddf.minim.*;
Minim minim;//audio context 
AudioPlayer song1;
AudioPlayer song2;
AudioPlayer song3;
AudioPlayer song4;

PImage img1, img2, img3, img4; 

//setup
void setup () {
  size (670,237);
  background (255);


  img1 = loadImage("bird1.png");
  img2 = loadImage("bird2.png");
  img3 = loadImage("bird3.png");
  img4 = loadImage("bird4.png");

}

//draw function that loops
void draw () {

  //draw lines to divide quadrants


  //upper left quadrant is red
  if ((mouseX < 150) && mouseY > 0) {
 image(img1, 0,0);
  minim=new Minim(this); 
  song1=minim.loadFile("one.mp3",1000);
  song1.play();


  //upper right quadrant cyan
  } else if ((mouseX < 250)&& (mouseY > 0)){
   image(img2, 0,0);
     minim=new Minim(this); 
  song2=minim.loadFile("two.mp3",1000);
  song2.play();


  //lower left quadrant gray
   }else if ((mouseX < 340) && (mouseY >0)) {
   image(img3, 0,0);
        minim=new Minim(this); 
  song3=minim.loadFile("three.mp3",1000);
  song3.play();


 // lower right quadrant black
  }else if ((mouseX < 440) && (mouseY > 0)){
 image(img4,0,0);
      minim=new Minim(this); 
  song4=minim.loadFile("four.mp3",1000);
  song4.play();
  }
}

Answers

  • Before we do anything else, please format your code properly.

    Edit your post. Select the code. Press Ctrl + o.

  • Thanks!!! Done!!!

  • Answer ✓

    Don't load files in draw, load them in setup.

    Minim setup can be done there too.

  • Thanks koogs! Seems like a simple enough solution!!!

  • edited March 2016 Answer ✓

    I've come up w/ this example. But since I don't have any of those files, it's completely untested: 8-|

    /**
     * Audio Buttons (v1.02)
     * GoToLoop (2016-Mar-07)
     *
     * forum.Processing.org/two/discussion/15352/
     * simple-rollover-animations-with-image-and-sounds-for-mousex-and-mousey
     */
    
    import ddf.minim.Minim;
    import ddf.minim.AudioPlayer;
    
    static final String IMG_NAME = "bird";
    static final String IMG_EXT = ".png", SND_EXT = ".mp3";
    static final String[] NUMS = { "one", "two", "three", "four" };
    
    static final int BUTTONS = 4, OFFSET = 100, GAP = 25;
    final AudioButton[] btns = new AudioButton[BUTTONS];
    
    void setup() {
      size(600, 250);
      smooth(4);
      noLoop();
      imageMode(CORNER);
    
      final Minim m = new Minim(this);
      for (int i = 0; i < BUTTONS; ++i) {
        final PImage img = loadImage(IMG_NAME + (i+1) + IMG_EXT);
        final AudioPlayer snd = m.loadFile(NUMS[i] + SND_EXT);
        final int x = i*(img.width + GAP) + OFFSET;
        btns[i] = new AudioButton(img, snd, x, GAP);
      }
    }
    
    void draw() {
      clear();
      for (final AudioButton btn : btns)  btn.display();
    }
    
    void mousePressed() {
      for (final AudioButton btn : btns)  if (btn.isMouseOver()) {
        btn.play();
        redraw = true;
        break;
      }
    }
    
    class AudioButton {
      final PImage img;
      final AudioPlayer snd;
      final short x, y;
    
      AudioButton(PImage im, AudioPlayer sn, int xx, int yy) {
        img = im;
        snd = sn;
        x = (short) xx;
        y = (short) yy;
      }
    
      void display() {
        image(img, x, y);
      }
    
      void play() {
        snd.play();
      }
    
      boolean isMouseOver() {
        return mouseX >= x & mouseX < x+img.width &
          mouseY >= y & mouseY < y+img.height;
      }
    }
    
  • edited March 2016

    Hi GoToLoop! I wasn't successful with this option - can I upload pictures/sounds or zipped code folders to the forum to show you what I tried?

  • Okay, so I have realized more specifically what I am trying to do! The solution of loading Minim and the audio files in set-up is a cleaner sound experience but I want the sounds to re-activate/reset if the mouse is moved from the region and then returned to the original hover spot. But, keeping them in draw causes them reload over and over in again sounding an an reverberant mess. What I would like to do is play the sound once when the mouse hovers over the region and reset for every time the mouse returns to the specified hover region. I am hoping for a very basic/simple solution for my own sake and my students? :)

    Any and all suggestions are much appreciated thank you!

  • edited March 2016
    1. Replaced mousePressed() w/ mouseMoved().
    2. New methods for class AudioButton: rewind() & isFinished().

    /**
     * Audio Buttons (v1.1)
     * GoToLoop (2016-Mar-08)
     *
     * forum.Processing.org/two/discussion/15352/
     * simple-rollover-animations-with-image-and-sounds-for-mousex-and-mousey
     */
    
    import ddf.minim.Minim;
    import ddf.minim.AudioPlayer;
    
    static final String IMG_NAME = "bird";
    static final String IMG_EXT = ".png", SND_EXT = ".mp3";
    static final String[] NUMS = { "one", "two", "three", "four" };
    
    static final int BUTTONS = 4, OFFSET = 100, GAP = 25, FPS = 10;
    final AudioButton[] btns = new AudioButton[BUTTONS];
    
    void setup() {
      size(600, 250);
      smooth(4);
      noLoop();
      frameRate(FPS);
      imageMode(CORNER);
    
      final Minim m = new Minim(this);
      for (int i = 0; i < BUTTONS; ++i) {
        final PImage img = loadImage(IMG_NAME + (i+1) + IMG_EXT);
        final AudioPlayer snd = m.loadFile(NUMS[i] + SND_EXT);
        final int x = i*(img.width + GAP) + OFFSET;
        btns[i] = new AudioButton(img, snd, x, GAP);
      }
    }
    
    void draw() {
      clear();
      for (final AudioButton btn : btns)  btn.display();
    }
    
    void mouseMoved() {
      for (final AudioButton btn : btns)  if (btn.isMouseOver()) {
        if (btn.isFinished())  btn.rewind();
        btn.play();
        redraw = true;
        break;
      }
    }
    
    class AudioButton {
      final PImage img;
      final AudioPlayer snd;
      final short x, y;
    
      AudioButton(PImage im, AudioPlayer sn, int xx, int yy) {
        img = im;
        snd = sn;
        x = (short) xx;
        y = (short) yy;
      }
    
      void display() {
        image(img, x, y);
      }
    
      void play() {
        snd.play();
      }
    
      void rewind() {
        snd.rewind();
      }
    
      boolean isFinished() {
        return snd.position() == snd.length();
      }
    
      boolean isMouseOver() {
        return mouseX >= x & mouseX < x+img.width &
          mouseY >= y & mouseY < y+img.height;
      }
    }
    
  • Hi GoToLoop,

    Only picture 1 and sound 1 loaded (once), do you think this is because I am Processing 2.0?

  • edited March 2016

    As I've mentioned before, I can't run it for I don't any any of those 8 files.
    I'm assuming they're called: one.mp3, two.mp3, three.mp3, four.mp3, bird1.png, bird2.png, bird3.png, bird4.png.

    I can't see anything in my example which would preclude it to be compiled under P2.
    As far as I can tell, much probably it works even for P1 too if we replace smooth(4); w/ plain smooth()!

    All of those 8 files are loaded within setup(). Then activated when needed after that.

  • Okay, so I have realized more specifically what I am trying to do! The solution of loading Minim and the audio files in set-up is a cleaner sound experience but I want the sounds to re-activate/reset if the mouse is moved from the region and then returned to the original hover spot. But, keeping them in draw causes them reload over and over in again sounding an an reverberant mess. What I would like to do is play the sound once when the mouse hovers over the region and reset for every time the mouse returns to the specified hover region. I am hoping for a very basic/simple solution for my own sake and my students?

    Any and all suggestions are much appreciated thank you!

    I posted the code with audio and image files here as a zip: https://drive.google.com/file/d/0B5xSBpJL4Eu6ZEdVOVBZWmdibzA/view?usp=sharing

  • Your "birdFlightSound.pde" is still pretty much your 1st posted code.
    Can't you try to implement some features of my own example?
    Like having a class to represent 1 AudioButton and load everything in setup()?

  • Oh, yes I was just trying to provide you the media files. I did try you code with my media files but I can see that you mean your code is just a reference - not a replacement. That is probably why it didn't work for me. Okay, I will play some more with your suggestions and see what i can solve. Thank you for you help GoToLoop!

  • Got another solution that works well.

    //SOUND import ddf.minim.*; Minim minim;//audio context AudioPlayer aplayer; // using a single audio player int crntSong = 0; // for tracking last played song int nextSong = 1;

    PImage img1, img2, img3, img4; 
    
    //setup
    void setup () {
      size (670,237);
      background (255);
    
    
      img1 = loadImage("bird1.png");
      img2 = loadImage("bird2.png");
      img3 = loadImage("bird3.png");
      img4 = loadImage("bird4.png");
    
      minim = new Minim(this); 
    
      // loading first song, just for initialiation
      aplayer = minim.loadFile("Dnote.mp3",1000);
    
    }
    
    //draw function that loops
    void draw () {
    
      //draw lines to divide quadrants
    
    
      //upper left quadrant is red
      if ((mouseX < 150) && mouseY > 0) {
     image(img1, 0,0);
    
    
     // check that last played song is not the same as the song to be played now,
     // so that song is not restarted 
     nextSong = 1;
     if(nextSong != crntSong)
     { 
      aplayer.close();
      aplayer = minim.loadFile("Dnote.mp3",1000);
      aplayer.play();
      crntSong = nextSong;  
     }
    
    
      //upper right quadrant cyan
      } else if ((mouseX < 250)&& (mouseY > 0)){
       image(img2, 0,0);
    
       nextSong = 2;
     if(nextSong != crntSong)
     {
      aplayer.close();
      aplayer = minim.loadFile("Enote.mp3",1000);
      aplayer.play();
      crntSong = nextSong;  
     }
    
      //lower left quadrant gray
       }else if ((mouseX < 340) && (mouseY >0)) {
       image(img3, 0,0);
    
    
      nextSong = 3;
     if(nextSong != crntSong)
     {
      aplayer.close();
      aplayer =  minim.loadFile("Fnote.mp3",1000);
      aplayer.play();
      crntSong = nextSong;  
     }
    
    
     // lower right quadrant black
      }else if ((mouseX < 440) && (mouseY > 0)){
     image(img4,0,0);
    
      nextSong = 4;
     if(nextSong != crntSong)
     {
      aplayer.close();
      aplayer = minim.loadFile("Gnote.mp3",1000);
      aplayer.play();
      crntSong = nextSong;  
     }
    
    
      }
    }
    
Sign In or Register to comment.