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

2016/5/13

How do I get a button to change to another button sprite when I hover over it?

bjornjulian00 bjornjulian00

2016/5/13

#
I'm trying to get the code to change the button's sprite from Play Button.png to an inverted version (Play Button 2.png) when I hover over it. As a bonus, could you tell me how to switch to world InvestScreen after I click said button? Here is my code at the moment: import greenfoot.*; public class PlayButton extends Actor { public void act() { GreenfootImage PlayButton = getImage(); PlayButton.scale(2800,2000); } public void OnMouseOver() { if (getX()>0) { if (getX()<250) { if(getY()>150) { if(getY()<400) { setImage("Play Button 2.png"); } } } } else { setImage("Play Button.png"); } } }
SPower SPower

2016/5/13

#
The problem is that getX and getY return the position of the actor, not the position of the mouse. You're going to have to use the class MouseInfo that Greenfoot provides in order to 'listen' to what the mouse does. Using this is a little tricky though. First you'll have to get an instance of MouseInfo, like this:
MouseInfo info = Greenfoot.getMouseInfo();
to which you can ask for the x and y coordinates of the mouse pointer. However, this object can also be null, so you'll have to check for that:
if (info != null) {
    // doo stuff
}
Then, you can do what you wanted to do:
if (info.getX() > 0 && info.getX() < 250 && info.getY() > 150 && info.getY() < 400) {
    // do stuff
}
And next time you post something, please use the tags (without the spaces) to mark code, or use the button under the text field marked 'code'.
valdes valdes

2016/5/13

#
    public void act() 
    {
        if (Greenfoot.mouseMoved(this)) {
            setImage("image_hover.png");
        } else if (Greenfoot.mouseMoved(null)) {
           setImage("image.png");
        }
        if (Greenfoot.mousePressed(this)) {
            getImage().scale((int)Math.round(getImage().getWidth() * 0.9), (int)Math.round(getImage().getHeight() * 0.9));
        }
        if (Greenfoot.mouseClicked(null) || Greenfoot.mouseDragEnded(null)) {
            setImage("image.png"); 
        }
        if (Greenfoot.mouseClicked(this)) {
            setImage("image.png");
            Greenfoot.delay(5); 
            Greenfoot.setWorld(new WhateverWorld());
        }
    }  
danpost danpost

2016/5/13

#
valdes wrote...
if (Greenfoot.mouseMoved(this)) {
    setImage("image_hover.png");
} else if (Greenfoot.mouseMoved(null)) {
   setImage("image.png");
}
With this, if the mouse stops (or if a mouse movement is not detected) while hovering over the button, the image will change back. This will cause the image to franticly switch back and forth while the mouse moves over the button. Changing line 3 here should solve the issue:
} else if (Greeenfoot.mouseMoved(null) && ! Greenfoot.mouseMoved(this)) {
danpost danpost

2016/5/13

#
I cannot see why a button image would have to be so large (2800, 2000) -- or a world for that matter. To comfortably fit on most screens, I try not to exceed a world size of (1000, 600) and usually use (800, 600). You can have a large world, but if the "hitbox" of the button is to be only an area the size of (250, 250), then that should be the size of your button images. Also, there is no need to scale the image continuously to the same size. Maybe the following would be better for the code given:
import greenfoot.*;

public class PlayButton extends Actor
{
    private Greenfootimage mainImage, hoverImage;
    private boolean mouseHover;

    public PlayButton()
    {
        GreenfootImage image = new GreenfootImage(getImage());
        image.scale(2800, 2000);
        mainImage = new GreenfootImage(250, 250);
        mainImage.drawImage(image, 0, 150);
        setImage(mainImage);
        image = new GreenfootImage("Play Button 2.png");
        image.scale(2800, 2000);
        hoverImage = new GreenfootImage(250, 250);
        hoverImage.drawImage(image, 0, 150);
    }

    public void act() 
    {
        if (Greenfoot.mouseMoved(null))
        {
            if (mouseHover != Greenfoot.mouseMoved(this)
            {
                mouseHover = ! mouseHover;
                setImage(mouseHover ? hoverImage : mainImage);
            }
        }
        if (Greenfoot.mouseClicked(this)) Greenfoot.setWorld(new InvestScreen());
    }
}
valdes valdes

2016/5/13

#
Thanks @danpost, I think I understand your change (line 5), I try it out and still works, honestly the change is not perceptible to the eye. @bjornjulian00 here is the code with the modification and add some comments.
public void act() 
{
    if (Greenfoot.mouseMoved(this)) {
// when mouse is over the button, change the image
        setImage("image_hover.png");
    } else if (Greenfoot.mouseMoved(null) && ! Greenfoot.mouseMoved(this)) {
// when mouse is somewhere else, return to original image
       setImage("image.png");
    }
    if (Greenfoot.mousePressed(this)) {
//when mouse is pressed, simulate a pressed button, making it a bit smaller
        getImage().scale((int)Math.round(getImage().getWidth() * 0.9), (int)Math.round(getImage().getHeight() * 0.9));
    }
    if (Greenfoot.mouseClicked(null) || Greenfoot.mouseDragEnded(null)) {
// if mouse is dragged inside button, looks pressed, when you release, change to original
        setImage("image.png"); 
    }
    if (Greenfoot.mouseClicked(this)) {
// when mouse is clicked, return to original image, last line is the bonus you ask for
        setImage("image.png");
        Greenfoot.delay(5); 
        Greenfoot.setWorld(new WhateverWorld());
    }
}
danpost danpost

2016/5/13

#
I forgot to change the sign in the 'drawImage' parameters. All values should be negative in both 'drawImage' lines.
bjornjulian00 bjornjulian00

2016/5/18

#
Thank you so very much! You all are lifesavers! I got an A on my assignment :D
danpost danpost

2016/5/19

#
@valdes, I am so sorry. I stated that the change in line five was to prevent flicker -- and that is not what I meant to say (that is why the changes was not perceptible to your eye). That change was introduced so that the image of the actor was not continuously being set when it was not changing.
You need to login to post a reply.