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

2012/3/25

mouse click question

Tomc84 Tomc84

2012/3/25

#
Anyone know how to change the pic of one object through the mouse click of another object?
matt.milan matt.milan

2012/3/25

#
psuedo code: private ObjectA objectA; public ObjectB(ObjectA newObjectA) { objectA = newObjectA; } public void act() { if (clicked) objectA.setImage(newImage) }
danpost danpost

2012/3/25

#
if (Greenfoot.mouseClicked(this))
{
    // get object reference if no readily available
    // assume name as 'morpheus'
    morpheus.updateImage("imageFilename.gif");
}
with a public void method updateImage(String) in morpheus' class. You could use an 'int' value instead of 'imageFilename' and have an updateImage(int) method determine which picture to use, depending on the value of the 'int'. On how to get the reference to the object whose pic needs changed: that would depend on several things: (1) is the object the only object of its class? if so, it would be fairly easy to get reference to it. (2) is the object always in the same location? again, would not be difficult to get a reference. (3) is there already a reference to the object in the world class? so much, the easier. (4) is there variable being held by the object that seperates it from the other of its class? not so easy, but do-able. (5) if none of the above, then in the world class, get a reference to the object whose image is to change when it is created (before adding it to the world), then send that to the object to be clicked on when it is created (you will have to add a parameter to the constructor of the object to be clicked on. Example: in the world constructor or a method it calls
Morpheus morpheus = new Morpheus();
addObject(morpheus, x_coord, y_coord);
//  assume object to be clicked on as 'Icon.class'
addObject(new Icon(morpheus), x2_coord, y2_coord);
Then in the 'Icon' class:
private Morpheus morpheus;

public Icon(Morpheus morph)
{
    morpheus = morph;
    // rest of constructor
}

public void act()
{
    // some of act method (maybe)
    if (Greenfoot.mouseClicked(this)) morpheus.updateImage("imageFilename.gif");
    // rest of act method (maybe)
}
Tomc84 Tomc84

2012/3/25

#
I think I have that stuff, It takes me some time for me to understand and follow. here is my code...
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class LightWorld here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class LightWorld extends World
{
    private Light l1,l2;
    /**
     * Constructor for objects of class LightWorld.
     * 
     */
    public LightWorld()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(600, 400, 1);
        
        l1 = new Light();
        addObject(l1, 71, 65);
        
        l2 = new Light();
        addObject(l2, 304, 60);
    }
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Button here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Button extends Actor
{
    private GreenfootImage sB0;
    private GreenfootImage sB1;
    private GreenfootImage sBDown;
    private boolean wasBtnPushed;
    
    public Button()
    {
        sB0 = new GreenfootImage ("Button0.png");
        sB1 = new GreenfootImage ("Button1.png");
        sBDown = new GreenfootImage ("ButtonDown.png");
        setImage (sB0);
        wasBtnPushed = false;
        
    }

    /**
     * Act - do whatever the Button wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        if (Greenfoot.mousePressed(this) && !wasBtnPushed)
        {
            setImage (sBDown);
            wasBtnPushed = true;
        }

        if (!Greenfoot.mousePressed(this) && wasBtnPushed)
        {
            setImage (sB1);
            wasBtnPushed = false;
        }
    } 
}
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Light here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Light extends Actor
{
    private GreenfootImage red;
    private GreenfootImage blue;
    private GreenfootImage off;
    private int count;
    
    
    public Light()
    {
        red = new GreenfootImage("red.png");
        blue = new GreenfootImage("blue.png");
        off = new GreenfootImage("Off.png");
        setImage(off);
        count = 0;
        
        
    }

    /**
     * Act - do whatever the Light wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        if (Greenfoot.mousePressed(this))
        {
            setImage(red);
            count = count +1;
            
        }
        if (Greenfoot.mousePressed(this) && count == 2)
        {
            setImage(blue);
            count = count +1;
            
        }
        if (Greenfoot.mousePressed(this) && count > 3)
        {
            setImage(off);
            count = 0;
            
        }
    }    
}
Im trying to get the button to be clicked and then the lights cycle trough.
danpost danpost

2012/3/25

#
Since there are only three options (off, red, and blue) or (0, 1, and 2), your act method should be:
public void act()
{
    if (count == 0 && Greenfoot.mousePressed(this))
    {
        setImage(red);
        count = count + 1;
    }
    if (count == 1 && Greenfoot.mousePressed(this))
    {
        setImage(blue);
        count = count + 1;
    }
    if (count == 2 && Greenfoot.mousePressed(this))
    {
        setImage(off);
        count = 0;
    }
}
I moved the count to be checked first so the mouseClick was not checked on multiple times. Another way of doing this is (showing the whole class):
import greenfoot.*;

public class Light extends Actor
{
    private GreenfootImage[] image= {
             new GreenfootImage("Off.png"),
             new GreenfootImage("red.png"),
             new GreenfootImage("blue.png") };
    private state = 0; // same as your 'count'

    public Light()
    {
        setImage(image[state]);
    }

    public void act()
    {
        if (Greenfoot.mouseClicked(this))
        {
            state = (state + 1) % 3;
            setImage(image[state]);
        }
    }
}
Here I used mouseClicked instead of mousePressed (so the image changes once per click). Also line 20 will cycle the value of 'state' as follows: 0, 1, 2, 0, 1, 2, 0, ...(just what you need).
Tomc84 Tomc84

2012/3/28

#
The top way did not work for me I must have been putting it in wrong. The bottom way worked flawless!! it is an array? and how does it work?
danpost danpost

2012/3/28

#
Lines 5 through 8 sets up a GreenfootImage array of three elements, for which the values are immediately set. Line 9 sets the state to zero (off). Line 13 in the Light constructor sets the image to its initial state (off). The act() method (lines 16 through 24) checks to see if this object was clicked on, and if so, goes to the next state and sets the image for the new state. As far as the array is concerned, the first element of the array is 'image', the second one is 'image', etc. If you are not familiar with the '%' operator, think of it as dividing by what follows it, except that it returns the remainder part (dropping the number of whole times it goes into the first number). It comes in handy for wrapping.
Tomc84 Tomc84

2012/3/29

#
OK, I kinda get it. I think I need to learn about the % operator. Thank you so much for the insight!!
danpost danpost

2012/3/29

#
The Java tutorials has a section on arithmetic operators in the Language Basics trail. Just click here.
mik mik

2012/3/30

#
A similar thing (changing the image by rotating through a set of different images) is explained in the Joy Of Code, Episode 17 (towards the end). However, there it uses an if-statement instead of the modulo operator (%). The modulo operator is a little more elegant, using an if statement is (initially) easier to understand. The bit about changing images starts around 16:40.
You need to login to post a reply.