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

2012/7/5

What's wrong here?

darkmist255 darkmist255

2012/7/5

#
This is just a minor concern at the moment, but I seem to be unable to find what's wrong with this. The expected behaviour is that it will detect (if the mouse is within the actor's image) when a mouse button is down, save it in the list "keysPressed" so that it will only return true once per click, and return true or false depending on if this is the first act() cycle in which the mouse button was down. The behaviour I'm getting is that, say I call "if(mouseClicked(this, "left"))", it does returns true when I press the left button, but it also returns true whenever I release the left mouse button or move the mouse around on the actor's image while the button is still held down.
    public boolean mouseClicked(Actor actorTemp, String button)
    {
        MouseInfo mouse = Greenfoot.getMouseInfo();
        if(mouse != null)
        {
            int actorXradius = actorTemp.getImage().getWidth() / 2;
            int actorYradius = actorTemp.getImage().getHeight() / 2;
            if(mouse.getX() > actorTemp.getX() - actorXradius && mouse.getX() < actorTemp.getX() + actorXradius && mouse.getY() > actorTemp.getY() - actorYradius && mouse.getY() < actorTemp.getY() + actorYradius)
            {
                if(button == "left" && mouse.getButton() == 1 && !keysPressed.contains("mouseButton1"))
                {
                    keysPressed.add("mouseButton1");
                    return true;
                }
                if(button == "right" && mouse.getButton() == 3 && !keysPressed.contains("mouseButton3"))
                {
                    keysPressed.add("mouseButton3");
                    return true;
                }
                if(button == "middle" && mouse.getButton() == 2 && !keysPressed.contains("mouseButton2"))
                {
                    keysPressed.add("mouseButton2");
                    return true;
                }
                
                if(keysPressed.contains("mouseButton1") && mouse.getButton() != 1)
                {
                    keysPressed.remove("mouseButton1");
                }
                if(keysPressed.contains("mouseButton2") && mouse.getButton() != 2)
                {
                    keysPressed.remove("mouseButton2");
                }
                if(keysPressed.contains("mouseButton3") && mouse.getButton() != 3)
                {
                    keysPressed.remove("mouseButton3");
                }
            }
        }
        return false;
    }
Great thanks to anyone who takes a look at the code.
nccb nccb

2012/7/5

#
You're using several string comparisons using "==" rather than .equals(). That's one possible cause of odd behaviour. Similarly those strings in the list: I'd use three booleans for the mouse buttons rather than keeping track of strings in lists.
darkmist255 darkmist255

2012/7/6

#
I'll try using .equals() first, that sometimes does the job, and if not then I'll try using booleans instead. I'll post back on how things go once I try everything, thanks :D.
darkmist255 darkmist255

2012/7/6

#
Hmm... neither of them have any effect. I'll continue looking further into this, tell me if you happen to think of something. Thanks!
danpost danpost

2012/7/6

#
You should start with the check 'if (Greenfoot.mousePressed(actorTemp))' for adding buttons to the list; and 'if(Greenfoot.mouseClicked(actorTemp))' for removing them from the list. Within each block, get the MouseInfo object and check which button was used in the action. I had the following code stored away in my code folder for mouse clicks:
    final int btnNEITHER = 0, btnLEFT = 1, btnRIGHT = 3;
    int buttonsDown = 0;

    public void act()
    {
        if (Greenfoot.mousePressed(this))
        {
            MouseInfo mi = Greenfoot.getMouseInfo();
            buttonsDown += mi.getButton();
            if (buttonsDown == btnLEFT) System.out.println("Left button pressed");
            if (buttonsDown == btnRIGHT) System.out.println("Right button pressed");
            if (buttonsDown == btnLEFT + btnRIGHT) System.out.println("Both buttons pressed");
        }
        if (buttonsDown != btnNEITHER && Greenfoot.mouseClicked(this))
        {
            MouseInfo mi = Greenfoot.getMouseInfo();
            int wasDown = buttonsDown;
            buttonsDown -= mi.getButton();
            int buttonReleased = wasDown - buttonsDown;
            if (buttonReleased == btnLEFT) System.out.println("Left button released");
            if (buttonReleased == btnRIGHT) System.out.println("Right button released");
            if (buttonsDown == btnNEITHER) System.out.println("(all buttons released)");
        }
    }
You could add the middle button; though, you would probably have to change the values to 0, 1, 2, and 4 (2 for the middle button); and, add and subtract 'Math.pow(2, mi.getButton() - 1)'. Of course, there will be more combinations of possible buttons down at one time, but each would have a unique sum.
darkmist255 darkmist255

2012/7/6

#
I might give that a try, but the reason I didn't use the built-in methods in Greenfoot is because the actor I'm clicking on is in the background and thus it doesn't get picked up.
danpost danpost

2012/7/6

#
It might be best to just create a 'hit-box' actor (an invisible image the size of the 'background' actor, placed at the 'background' actor's location) and use it with Greenfoot's built-in methods. If you use 'setPaintOrder', give the 'hit-box' actor the lowest priority (list it last or not at all).
darkmist255 darkmist255

2012/7/6

#
Ah, clever idea, I never thought of that. I'll give that a try if I can't figure anything else out :D.
darkmist255 darkmist255

2012/7/6

#
Question though, if "hit-box" is last in the paint order, Greenfoot's methods won't pick it up anyway, so wouldn't I have to make it first in the paint order?
darkmist255 darkmist255

2012/7/6

#
Scratch that... Well... I just read this in the Greenfoot API: "If the parameter is null, then true will be returned for any mouse press, independent of the target pressed on. " Good fight life, good fight. That was three hours that could've been saved by re-reading the API :D. I don't even need a hit-box actor either, I can just call this anywhere.
darkmist255 darkmist255

2012/7/7

#
If you're curious, the working code I ended up using is:
    public void refreshMouseClick() //This is called every act() cycle
    {
        mouse = Greenfoot.getMouseInfo();
        if(mouse != null)
        {
            if(Greenfoot.mousePressed(null) && !keysPressed.contains("mouseButton"))
            {
                keysPressed.add("mouseButton");
            }
            else if(keysPressed.contains("mouseButton"))
            {
                keysPressed.remove("mouseButton");
            }
        }
    }
    
    public boolean mouseClicked(Actor actorTemp, String button)
    {
        if(keysPressed.contains("mouseButton"))
        {
            int actorXradius = actorTemp.getImage().getWidth() / 2;
            int actorYradius = actorTemp.getImage().getHeight() / 2;
            if(mouse.getX() > actorTemp.getX() - actorXradius && mouse.getX() < actorTemp.getX() + actorXradius && mouse.getY() > actorTemp.getY() - actorYradius && mouse.getY() < actorTemp.getY() + actorYradius)
            {
                if(button == "left" && mouse.getButton() == 1)
                {
                    return true;
                }
                if(button == "right" && mouse.getButton() == 3)
                {
                    return true;
                }
                if(button == "middle" && mouse.getButton() == 2)
                {
                    return true;
                }
            }
        }
        return false;
    }
mjrb4 mjrb4

2012/7/9

#
That code may work, but you're still using == to compare strings which is an almost universally bad idea. While it may work for you in some contexts, it definitely won't all the time, and it'll likely bite you when you least expect it. *Always* use .equals() instead - so
    if("left".equals(button) && mouse.getButton() == 1) 
...and so on. This way you can guarantee that it will always work as you expect.
darkmist255 darkmist255

2012/7/10

#
I suppose I'll run through and change them all. I've never had problems with them, but there's no harm in fail-proofing my code. I've been using .equals() since this.
You need to login to post a reply.