This site requires JavaScript, please enable it in your browser!
Greenfoot back
miahg17
miahg17 wrote ...

2016/11/15

Need help with mp3 player code

miahg17 miahg17

2016/11/15

#
I'm currently building an mp3 with star/pause and volume up/down interaction. I have the basics completed, but the volume up and down are really buggy. For instance, one click on volume down nearly mutes the song, while a click on volume up as my first adjustment will lower initial volume but gradually increase with clicks. Any input for fixes or a better approach is welcome. Here is the code for my volume up
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class VolumeUp here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class VolumeUp extends Actor
{
    private GreenfootSound song;
    private int volume;
     
    public VolumeUp(int masterVolume, GreenfootSound song ){
       this.volume = masterVolume;
       this.song = song;
    }
     
    /**
     * Act - do whatever the VolumeUp wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
      changeOnClick();
      System.out.print(song.getVolume() + "\n");
    }  
     
    
     
    public void changeOnClick(){
        if (Greenfoot.mouseClicked(this)){
            if(volume < 97){
             volume  += 3;
             song.setVolume(volume);
            }
        }
         
    }
     
}
Here is volume down
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class VolumeDown here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class VolumeDown extends Actor
{
    GreenfootSound song;
    int volume;
     
     
    public VolumeDown(int masterVolume, GreenfootSound song ){
         
        this.song = song;
        this.volume = masterVolume;
    }
     
    /**
     * Act - do whatever the VolumeUp wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        changeOnClick();
    }  
     
    
     
    public void changeOnClick(){
        if (Greenfoot.mouseClicked(this)){
            if(volume > 3){
             volume  -= 3;
             song.setVolume(volume);
            }
        }
    }
}
Here is MyWorld
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
/**
 * Write a description of class MyWorld here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class MyWorld extends World
{
    private GreenfootSound song = new GreenfootSound ("Canon.mp3");
    private int masterVolume =25;
     
    /**
     * Constructor for objects of class MyWorld.
     *
     */
    public MyWorld()
    {   
        super(800, 600, 1);
        build();
         
         
    }
     
    public GreenfootSound getSong(){
        return song;
    }
     
    public int getMasterVolume(){
        return masterVolume;
    }
     
    public void setMasterVolume(int newVolume){
        this.masterVolume = newVolume;
    }
     
    public void build(){
        GreenfootImage background = getBackground();
        background.setColor(Color.BLACK);
        background.fill();
         
        StartButton play = new StartButton(song);
        addObject(play,400,250);
         
        VolumeUp volumeUp = new VolumeUp(masterVolume, song);
        addObject(volumeUp, 650, 300);
         
        VolumeDown volumeDown = new VolumeDown(masterVolume,song);
        addObject(volumeDown, 150, 300);
         
        VolumeBar volBar = new VolumeBar();
        addObject(volBar, 150, 450);
    }
Here is VolumeBar, which I havent scripted yet implemented yet but is placed as a holder in MyWorld.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class VolumeBar extends Actor
{
    private int index;
     
    public VolumeBar(){
    }
     
    /**
     * Act - do whatever the VolumeBar wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public  void act()
    {
        // Add your action code here.
    }   
     
     
     
    
}
Any help on the volume level is appreciated. Also, I'm wanting to build a volume bar by stacking a new segment when VolumeUp is clicked, and removing a segment when VolumeDown is clicked. Any suggestions on a sound way of doing so is also welcome. Thanks again.
miahg17 miahg17

2016/11/15

#
If you notice the setters and getters in MyWorld, I attempted to use them as a means to retrieve and manipulate the master volume from inside the volume buttons but kept getting an endless loop of "static" and "non-static" errors. So I just brought it in as a parameter and tried to assign it as a value to a variable. I'm still trying to fully understand OOP concepts and think that I may be adjusting completely different instances of volume from each button. Any help with that is welcome as well. Another question about image arrays. I'm thinking about using an array of pictures to cycle through to represent my Volume Bar. Can anyone tell me how to add my pics to the array? Here is what I have, but both attempts to place my first image into the index create errors
1
2
3
private GreenfootImage[] volBar = new GreenfootImage[10];
   volBar[0] = GreenfootImage("volBar1.jpg");
   volBar[0] = new GreenfootImage("volbar1.jpg");
Super_Hippo Super_Hippo

2016/11/15

#
I think the problem is that you have three variables for the volume, although the song only has one. At the beginning, the masterVolume is set to 25 and so are the volume fields of VolumeUp/Down. If you click on VolumeUp, the volume in the VolumeUp class is set to 28. The masterVolume (which doesn't seem to have any influence, is it started with this volume? I wonder which volume field the Start button is using...) is still at 25 and so is the volume in the VolumeDown class. If you keep clicking on VolumeUp, it will reach its maximum volume, but if you click on VolumeDown then, it will be 25-3=22. (I just see that you already guessed that in your second post.) I think the best thing would be to remove the VolumeUp/Down classes and try something like this in the MyWorld class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//...
import java.awt.Color;
 
//...
 
 
private Actor play = new Actor(),
    volumeUp = new Actor(),
    volumeDown = new Actor(),
    volBar = new Actor();
 
private GreenfootSound song = new GreenfootSound("Canon.mp3");
 
public MyWorld()
{
    //...
    song.setVolume(25);
}
 
 
public void act()
{
    if (Greenfoot.mousePressed(play))
    {
        song.play();
    }
    if (Greenfoot.mousePressed(volumeUp))
    {
        if (song.getVolume() < 98) song.setVolume(song.getVolume()+3);
        else song.setVolume(100);
        updateVolBar();
    }
    if (Greenfoot.mousePressed(volumeDown))
    {
        if (song.getVolume() > 2) song.setVolume(song.getVolume()-3);
        else song.setVolume(0);
        updateVolBar();
    }
}
 
 
private void build()
{
    play.setImage("....png");
    volumeUp.setImage("....png");
    volumeDown.setImage("....png");
    updateVolBar();
    addObject(play,400,250);
    addObject(volumeUp, 650, 300);
    addObject(volumeDown, 150, 300);
    addObject(volBar, 150, 450);
}
 
 
private void updateVolBar()
{
    GreenfootImage img = new GreenfootImage(104, 20);
    img.fill();
    img.setColor(Color.GREEN);
    img.fillRect(1, 1, volume, 18);
    volBar.setImage(img);
}
This is not tested, so if you find something which isn't working and you can't get it to work / don't understand what it should do, just ask.
miahg17 miahg17

2016/11/15

#
Your reply just made my day. I was trying to build the buttons as separate actor subclasses, but looking back at the assignment requirements, I now see that the requirement was to have actors, which of course, can also be implemented in your way. Thank you so much. The only adjustment I see at first glance is the use of getVolume(). I was told by my instructor to avoid this because the output is not consistent with the setVolume() input. I can use an int variable to hold my volume level though and just use setVolume() as needed.
miahg17 miahg17

2016/11/15

#
I tried adding these private data members:
1
private Actor playButton = new Actor(), volumeUp = new Actor(), volumeDown = new Actor(), volBar = new Actor();
and got an error that says " greenfoot.Actor is abstract, cannot be instantiated." Do you know what this means, and if there is a remedy?
danpost danpost

2016/11/15

#
I doubt Super_Hippo meant for you use those exact lines. 'Actor' refers to one or more subclasses of Actor. Objects created from subclasses of Actor are still actors and of type Actor (as well as of their unique types which the subclasses distinguish them by).
miahg17 miahg17

2016/11/15

#
So i still need to create subclasses with the same names and not have them as private members in MyWorld right? This is the hardest part for me to get when it comes to OOP within greenfoot. Should I create these actor subclasses with no methods inside them except maybe a setImage(), making them independent actors for the MyWorld class to reference? Of should I implement the volume adjustment methods within them as I previously tried and failed at? Sorry for the rant, just trying to get my head around it.
Super_Hippo Super_Hippo

2016/11/15

#
You have to add {} after the Actor(), then you can use it as it is.
1
private Actor play = new Actor(){}, //...
Abstract means that it is only a class, but you can't add objects of it to the world (which I just did). You could say that the class Animal could be abstract because in the (real) world there are subclasses of 'Animals' which inherit things from the Animal class but in fact they are not just Animals. (The Animal class which you can import is not abstract though, but I think you get my point.) That getVolume and setVolume is not the same, is really weird though. Found this discussion here relating to that issue. I have no idea if some developer looked into that already. By the way, I also used 'volume' at the end which should be song.getVolume() too, but yes, since getVolume doesn't return what setVolume does, this doesn't seem to be very helpful.
miahg17 miahg17

2016/11/15

#
Thanks for the clarification Super_Hippo. That fixed the error. The getVolume issue is the reason i'm having so many problems in the first place(besides my noob level skill). If I could song.getVolume from inside the other classes I wouldn't have tried to create an int masterVolume to try and manipulate from everywhere, which I messed up. The results in the discussion you posted match the same outputs I say when I printed getVolume() while running. Everything seemed to adjust by a product and not a sum. Regardless, It shouldn't be too hard to just reference and adjust an int within the same class, which I plan to do.
miahg17 miahg17

2016/11/15

#
I just added private int masterVolume to the code. I use it as comparitor in all volume related if statements and add adjustment before referencing in setVolume(). I use it as reference in the volBar method and the volume bar adjusts up and down as it changes. Works like a charm. Thanks again for the help guys.
You need to login to post a reply.