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

2017/4/19

Creating and changing volume bar?

mjrx7 mjrx7

2017/4/19

#
Have created a mp3 player, created the volume bar, can't seem to get the volume bar to change when I click volume up or down. Any help is appreciated.
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("song1.mp3");
    private Play play = new Play();
    private VolumeUp volumeup = new VolumeUp();
    private VolumeDown volumedown = new VolumeDown();
    private int volumeLevel = 50;
    private GreenfootImage volume = new GreenfootImage (80, 20);
    private VolumeBar volumeBar = new VolumeBar();

    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    public MyWorld()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(400, 300, 1); 
        prepare();

    }
    
    public GreenfootImage getVolume(){
        return volume;
    }
    
    public void setVolume(GreenfootImage volume){
        this.volume=volume;
    }
    
    public VolumeBar getVolumeBar(){
        return volumeBar;
    }
    
    public int getVolumeLevel(){
        return volumeLevel;
    }
    
    public void setVolumeLevel(int volumeLevel){
        this.volumeLevel = volumeLevel;
    }
    
    public Play getPlay()
    {
        return play;
    }

    public VolumeUp getVolumeUp(){
        return volumeup;
    }

    public VolumeDown getVolumeDown(){
        return volumedown;
    }

    public GreenfootSound getSong()
    {
        return song;
    }

    public void setSong(String filename){
        song.stop();
        song.play();
    }
    
    /**
     * Prepare the world for the start of the program.
     * That is: create the initial objects and add them to the world.
     */
    private void prepare()
    {
        addObject(play,53,60);
        addObject(volumeup,305,73);
        addObject(volumedown,305,146);
        addObject(volumeBar,126,237);
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;

/**
 * Write a description of class VolumeBar here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class VolumeBar extends Volume
{
    private GreenfootImage bar = new GreenfootImage(100,10);
    private int audioLevel = 20;
    
    public VolumeBar(){
        bar.drawRect(0,0,99,9);
        bar.setColor( Color.YELLOW);
        bar.fillRect(1,1,audioLevel+2,9);
        setImage(bar);
    }
    
    public void setAudioLevel(int audioLevel){
        this.audioLevel = audioLevel;
    }
    
    public void changeVolume(int points){
        MyWorld world = new MyWorld();
        audioLevel = world.getVolumeLevel();
        GreenfootImage bar = getImage();
        bar.clear();
        bar.setColor(Color.BLACK);
        bar.drawRect(0,0,99,9);
        bar.setColor(Color.YELLOW);
        audioLevel += points;
        bar.fillRect(1,1,audioLevel+5,9);
    }
    
    /**
     * 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() 
    {
        if (Greenfoot.mouseClicked(VolumeUp.class)){
            changeVolume(audioLevel);
        }
    }
    
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
/**
 * Write a description of class VolumeUp here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class VolumeUp extends Volume
{
    private int volume = 0; 
    
    /**
     * 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() 
    {
        MyWorld myworld = new MyWorld();
        volume = myworld.getVolumeLevel();
        if (Greenfoot.mouseClicked(this)){
            MyWorld myWorld = (MyWorld)this.getWorld();
			GreenfootSound mySong = myWorld.getSong();
			myworld.setVolumeLevel(1000);
			mySong.setVolume(volume += 10);		
			VolumeBar volume = new VolumeBar();
			volume.changeVolume(500);
        }
    }    
}

I thought putting mouseClicked(VolumeUp.class) in VolumeBar would do the trick, but no. Where am I going wrong? Thanks, Matt
danpost danpost

2017/4/19

#
mjrx7 wrote...
I thought putting mouseClicked(VolumeUp.class) in VolumeBar would do the trick, but no. Where am I going wrong?
You cannot use a Class object for the parameter of 'mouseClicked' -- it takes an Actor object, a World object or no object ( 'null', for any click, anywhere ). You could use:
if (Greenfoot.mouseClicked(((MyWorld)getWorld()).getVolumeUp()))
You should remove the 'act' methods from the VolumeUp and VolumeDown classes and let the VolumeBar adjust the song volume when making the change in audioLevel. You should not be creating a new VolumeBar there, anyway as you would be changing the wrong bar.
mjrx7 mjrx7

2017/4/19

#
Yea, I was reading through a bunch of back and forth posts with other people regarding the mouseClicked and finally realized my mistake of needing an object and not a class. It'd be nice if Greenfoot told you that listing a class is not right as it doesn't flag it as an error, it just makes it not do anything. Enough people have seemed to have made the same mistake. In regards to removing the act method on volumeup and volumedown, what you're saying is to have volumebar look to see if volumeup or volumedown object is clicked and then adjust appropriately? Thanks for the reply and help. Matt
danpost danpost

2017/4/19

#
mjrx7 wrote...
Yea, I was reading through a bunch of back and forth posts with other people regarding the mouseClicked and finally realized my mistake of needing an object and not a class. It'd be nice if Greenfoot told you that listing a class is not right as it doesn't flag it as an error, it just makes it not do anything. Enough people have seemed to have made the same mistake.
The following:
Greenfoot class API documentation wrote...
public static boolean mouseClicked(java.lang.Object obj) True if the mouse has been clicked (pressed and released) on the given object. If the parameter is an Actor the method will only return true if the mouse has been clicked on the given actor. If there are several actors at the same place, only the top most actor will receive the click. If the parameter is a World then true will be returned if the mouse was clicked on the world background. If the parameter is null, then true will be returned for any click, independent of the target clicked on. Parameters: obj - Typically one of Actor, World or null Returns: True if the mouse has been clicked as explained above
almost spells it out -- just not giving any specific classes that you cannot use. To allow both World and Actor object, the parameter must be of type Object (which is the root class of ALL objects -- top of the hierarchy chain of extension). This means that any object can be used as a parameter -- even a Class object; but if the target of the click is not that object, then 'false' will be returned.
In regards to removing the act method on volumeup and volumedown, what you're saying is to have volumebar look to see if volumeup or volumedown object is clicked and then adjust appropriately?
Yes. It seems logical to perform that check there as that is where the audioLevel field is located and the bar can adjust its image at the same time as when the field value changes.
You need to login to post a reply.