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

2013/7/9

pressing buttons and then adding an object to the world by clicking in it

1
2
darkmist002 darkmist002

2013/7/9

#
as stated in the title, I am trying to get it to where a person clicks a button for the tower they want, then click somewhere in the world to place it. I have tried:
        if(Greenfoot.mouseclicked(this) && m.getMinerals() >= ft.getPrice())
        {
            mineralsSub(ft.getPrice());
            MouseInfo mouse = Greenfoot.getMouseInfo();
//             addObject(ft, mouse.getX(), mouse.getY());            
            addObject(new fasttower(), mouse.getX(), mouse.getY());    
        } 
in the button, which makes the tower on top of the button, but it doesn't allow me to move it. i have also tried that code with another if statement,
if(Greenfoot.mouseClicked(this) && mins.getMinerals() >= T.getPrice())
        {
            if(Greenfoot.mouseMoved(null))
            {
                if(Greenfoot.mouseClicked(null))
                {
                    ((tdpath)getWorld()).mineralsSub(fastPrice);
                        
                     MouseInfo mouse = Greenfoot.getMouseInfo();
                     (getWorld()).addObject(new fasttower(), mouse.getX(), mouse.getY()); 
                     //setLocation(mouse.getX(), mouse.getY());
                }
            }
                
        }
which makes it not work at all. i've tried to put it in the world class, and changed this to an instance of the button, and i can get it to place the tower on the button like before, but i can't get it to move. i've tried separating that code into 2 methods like so:
public void buttonPressed()
    {
//         fasttower ft = new fasttower();
        if(Greenfoot.mousePressed(f) && m.getMinerals() >= ft.getPrice())
        {
            mineralsSub(ft.getPrice());
            MouseInfo mouse = Greenfoot.getMouseInfo();
//             addObject(ft, mouse.getX(), mouse.getY());            
            addObject(new fasttower(), mouse.getX(), mouse.getY());    
        }        
    }
    
    public void towerPlace()
    {
        if(Greenfoot.mousePressed(ft) && Greenfoot.mouseDragged(null))
            {
                if(Greenfoot.mouseDragEnded(null) )//&& !Greenfoot.mousePressed(null))//Greenfoot.mouseClicked(null))
                {
//                     ((tdpath)getWorld()).mineralsSub(fastPrice);
//                     mineralsSub(ft.getPrice());
                    MouseInfo mouse = Greenfoot.getMouseInfo();
                    ft.setLocation(mouse.getX(), mouse.getY());
//                     addObject(new fasttower(), mouse.getX(), mouse.getY()); 
                     //setLocation(mouse.getX(), mouse.getY());
                }
            }
    }
and that doesn't work either. (ft is an instance of the specific tower)
Gevater_Tod4711 Gevater_Tod4711

2013/7/9

#
Try to use some code from this scenario. That may help.
darkmist002 darkmist002

2013/7/9

#
ok, tried to do it like on there, but still didn't work. here's what i did coding wise: world
public class tdpath extends World
{
    /**have to add a ui for a menu to buy towers, to show towers/their prices and 
     * their abilities/stats. will have to add some music options so the player can 
     * choose from a few different musics to listen to. will try to add sound effects
     * to tower attacks, and also need to add tower attacks. need to add damage to the 
     * tower attacks that effects the spawn unit's health. will have to add health bars 
     * for units spawned as well. will also have to make a wave function so more than
     * one wave is in the game, so that spawns can be done in certain orders. also so
     * that boss waves can be made. make sure to scale unit health to waves, so make 
     * their health inc as the waves increase.
     * 
     * after game is made and playable, think of a way to make it where towers can't
     * be placed on the path, unless towers interfere with spawning paths, then figure
     * it out while making the game.
     */
    
    /**
     * Constructor for objects of class tdpath.
     * 
     */
     
    
    public Wave w = new Wave();
    public minerals m = new minerals(w);
    public stopMusic s = new stopMusic();
    public int mins;
    private long count = 0;
    private long lastSecond = 0;
    private int seconds = 20;
    private boolean timesUp = false;
    private fasttowerbutton f;
    private slowingtowerbutton sL;
    private damagetowerbutton dt;
    private splashtowerbutton st;
    private tower T;
    private enemies E;
    private defenseSpot d;
    private LivesLeft life;
    private fasttower ft = new fasttower();
    private slowingtower slowT = new slowingtower();
    private damagetower damT = new damagetower();
    private splashtower splashT = new splashtower();
    public tdpath()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(800, 600, 1); 
        life = new LivesLeft();
        d = new defenseSpot(life);
        T = new tower(m);  
        //towerAttacks tA = new towerAttacks(T); 
// //         fasttower fT = new fasttower();
// //         fastAttack fa = new fastAttack(fa);
//         
        E = new enemies(m);
        f = new fasttowerbutton(ft, m);
        sL = new slowingtowerbutton(slowT, m);
        dt = new damagetowerbutton(damT, m);
        st = new splashtowerbutton(splashT, m);        
        addObject(new spawning(), 35, 100);
        addObject(d, 100, 580);
        addObject(life, 170, 550);        
        addObject(f, 300, 550);        
        addObject(sL, 300, 575);
        addObject(dt, 450, 550);
        addObject(st, 450, 575);
        addObject(m, 600, 550);
        addObject(w, 400, 10);
        addObject(new music1(), 643, 168);
        addObject(new music2(), 579, 108);
        addObject(new music3(), 518, 168);
        addObject(new stopMusic(), 579, 60);
    }
    
    public void mineralsAdd(int mins)
    {
        m.addMinerals(mins);
    }
    
    public void mineralsSub(int mins)
    {
        m.subMinerals(mins);
    }
    
    public void act()
    {
        buttonPressed();
    }
    
    public void buttonPressed()
    {
        if(Greenfoot.mousePressed(f) && m.getMinerals() >= ft.getPrice())
        {
            mineralsSub(ft.getPrice());           
            addObject(new fasttower(), f.getX(), f.getY());    
        }        
    }
}
tower (parent class of all the towers)
public class tower extends Actor
{
    /**
     * Act - do whatever the tower wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    
    /**be sure to use the radius method of the world/actor class to see around the tower a certain
     * distance. also add radius upon upgrading the towers. figure out a way to show the radius
    */
    public int damage;
    public double attspd; //in milliseconds
    public int range;
    public double attTimer;
    public int price;
    public int uprice;
    public int x = 0;
    public int y = 0;
    public int mins;
    public minerals m;
    //private int wave = 1; //have wave class come in as well
    public int lvl = 1;
    private boolean placed = false;
    
    public tower()
    {
        
    }
    public tower(minerals min)
    {
        m = min;
    }
    public void act() 
    {
        // Add your action code here.
        /**
         * create the levels of the towers in here. possibly make the attack spd and damage in here
         * as well, in which case also special effects. also put radius of each tower in here for sight
         * or in each specific tower.
         */
        placing();
        if(!isPlaced())
        {
            return;
        }
        mins = m.getMinerals();
        placing();
        attack();
        if(Greenfoot.mouseClicked(this) && canUpdate())
        {
            update();
        }
    }    
    
    public void attack()
    {
        //List<enemies> e = getObjectsInRange(range, enemies.class);
        //if(canAttack() && !e.isEmpty())
        if(canAttack() && !getObjectsInRange(range, enemies.class).isEmpty())
        {
            /** attack first enemy.
             * if(clock)
             * {
              *     e(0).health - attack;
              *}
              *
            **/
            //enemies temp = e.get(0);
            enemies temp = (enemies)getObjectsInRange(range, enemies.class).get(0);
            x = temp.getX();
            y = temp.getY();
            //shoot(x, y);
            shoot(temp);
            //temp.decHealth(damage);  
            attTimer = attspd;

        }
    }

    private boolean canAttack()
    {
        if(attTimer > 0)
        {
            attTimer --;
        }
        return attTimer == 0;
    }
    
    public void shoot(enemies E)
    {
        
    }

    public int enemyPosX()
    {
        return x;
    }
    
    public int enemyPosY()
    {
        return y;
    }
    
    public int getPrice()
    {
        return price;
    }
    
    public int getDamage()
    {
        return damage;    
    }
    
    public void update()
    {
        damage = damage * 2;
        range = (int)(range *1.5);
        attspd = (int)(attspd*.8);
//         m.subMinerals(uprice);
    }
    
    public boolean canUpdate()
    {
        if(uprice <= mins)
        {
            return true;
        }
        return false;
    }
    
    public void placing()
    {
        if(!placed && Greenfoot.mouseClicked(null))
        {
            placed = true;
        }
        if(!placed && Greenfoot.mouseMoved(null))
        {
            MouseInfo mouse = Greenfoot.getMouseInfo();
            setLocation(mouse.getX(), mouse.getY());
        }
    }
    
    public boolean isPlaced()
    {
        return placed;
    }
}
the button code:
public class fasttowerbutton extends uiMenu
{
    /**
     * Act - do whatever the fasttowerbutton wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    private int fastPrice;
    private fasttower T;
    private minerals mins;
    public fasttowerbutton(fasttower Tower, minerals Mins)
    {
            T = Tower;
            mins = Mins;
    }
    
    public fasttowerbutton()
    {
        
    }
    
    public void act() 
    {
        // Add your action code here.
        shopButton1();
    }
    
    private void shopButton1()
    {
        fastPrice = T.getPrice();
        setImage(new GreenfootImage("Fast tower: $" + fastPrice, 20, Color.BLUE, Color.ORANGE));
    }

}
danpost danpost

2013/7/9

#
What do you have in your fasttower class?
darkmist002 darkmist002

2013/7/10

#
when i had the coding like that i put the placing method in the act of it, which would make it work if your adding one from the greenfoot window when it's paused and unpause it, but if try to do the button it just adds to the button, and doesn't activate with the mouse. i also tried putting that coding directly into the fasttower class instead of the parent class and it still doesn't work. fasttower class
public class fasttower extends tower
{
    /**
     * Act - do whatever the fasttower wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    //att lv 1/2/3          1/2/4/8
    //att spd lv 1/2/3      1/.75/.5/.35
    //price                 5
    //upgrade price         10
    private boolean placed;
    public fasttower()
    {
        damage = 1;
        attspd = 60;
        range = 55;
        attTimer = 0;
        price = 5;
        uprice = 10;
    }
    
    public void act() 
    {
        // Add your action code here.
        //use getObjectsInRange() method for actors to make a radius for towers
        placing();
        if(!placed)
        {
            return;
        }
        attack();
    }   
    
    //private void update()
    {
        /**if have minerals and click on tower, upgrade to next lv
         * will have to add a minerals class and have it seen in every class.
          *if(minerals == 10 && clickontower && (lv <= 4))
          *{
          *     lvl++;
          *     attack += (attack*lvl);
          *     attspd = attspd - 200;
          *     range += (range*lvl);
          *}
          **/     
    }

    public void shoot(enemies E)
    {
        int X = getX();
        int Y = getY(); 
        ((tdpath)getWorld()).addObject(new fastAttack(E, damage), X, Y);
    }
    
    public void placing()
    {
        if(!placed && Greenfoot.mouseClicked(null))
        {
            placed = true;
        }
        if(!placed && Greenfoot.mouseMoved(null))
        {
            MouseInfo mouse = Greenfoot.getMouseInfo();
            setLocation(mouse.getX(), mouse.getY());
        }
    }
    
    public boolean isPlaced()
    {
        return placed;
    }
}
danpost danpost

2013/7/10

#
Try removing the act method altogether from the fasttower class. By having an act method there, the act method of the superclass will not run unless you specifically call it with 'super.act();'. This is probably why it was not working as you wanted. BTW, it is called 'overriding' when you have a method in a subclass with the same name as one in the superclass. One unnecessary statement in your tower class is on line 47 'placing();'. It will never execute any changes as at no time will processing reach that statement when the value of 'placed' is 'false' due to lines 42 through 45. Another thing is the 'isPlaced' method in both the tower and the fasttower class. Unless you are calling it from another class (one that is not tower or fasttower), the method is unnecessary and all instances of 'isPlaced()' can be replaced with 'placed'.
darkmist002 darkmist002

2013/7/10

#
i have to use the act method of the fasttower because it doesn't attack unless i use it. (when i have everything in the act method of the parent class the subclasses don't do anything so i have to override it with the act methods of the children classes to get them to do anything, which is why i've been using em.
danpost danpost

2013/7/10

#
The act method in the 'tower' class will run for any fasttower object provided you have no act method in the fasttower class. If it does not attack after removing the act method from the fasttower class, then it is something else that is causing it not to.
darkmist002 darkmist002

2013/7/10

#
tried no act method, just gives an error for not having the act method in the fasttower class. also tried having an act method with nothing in it except super.act(), but that causes it to do nothing. least it did give an error the first time i tried it, but after trying it again with just the stuff in the parent's act class and no act class in the fasttower it runs like it did before, but still does nothing, no attacking or anything. it's not just the coding to make it go where you click the mouse that isn't work, it's also the update coding as well. it will update it if i have it paused, and right click and select the update method, but if i try to click a placed tower, it doesn't update it. is there a way to select the tower object, and then have coding that says if selected/highlighted, and clicked/double clicked, update that way if they have enough money?
darkmist002 darkmist002

2013/7/10

#
figured out why it wouldn't work with the parent class act method. for the update, i have to check whether they have enough money to do the update, so i had something in there that would check the value of the money, but for some reason it wouldn't call the method in the minerals class to get the amount, even though i had an instance of it in the world class and passed to the tower class through the constructor. i tried placing a method in the world class that just returns the getMinerals method, and then called that instead in the tower class, and it got rid of the error and allows the tower to attack without an act method now. do the same thing got the update system to work as well for when i double click the tower. still doesn't solve why it won't use the place method when the world adds a tower at the button like your spider game did.
darkmist002 darkmist002

2013/7/10

#
ok.... it seems to be working for 3 of the 4 towers, but the fasttower just doesn't want to do it for some reason.
darkmist002 darkmist002

2013/7/10

#
ok, got it. needed to take out the part that was in the world class, and just have the stuff i had in the button class to add it to the world where the mouse clicked it, and then the part you had in the spider game i had to add to my tower class to get it to stick to the mouse till you click a spot in the world. now i have to make it where you can't place them on top of each other and i'll be set for sticking them down. i think there is a method that checks if it's intersecting another object, so i probably should make an if condition stating that it can't intersect with another tower class object.
danpost danpost

2013/7/10

#
I found with your originally posted code that by changing 'mouseMoved' to 'mouseDragged' in the 'placing' method, it works.
darkmist002 darkmist002

2013/7/10

#
oops, was trying with the wrong coding, let me try again
danpost danpost

2013/7/10

#
You latest code post is for updating (not placing) a tower. When updating, the tower is already placed. You need to change the placing method to something like the following:
public void placing()
{
    if(!placed && Greenfoot.mouseClicked(null) && getIntersectingObjects(null).isEmpty()) placed = true;
    if(!placed && Greenfoot.mouseDragged(null))
    {
        MouseInfo mouse = Greenfoot.getMouseInfo();
        setLocation(mouse.getX(), mouse.getY());
    }
}
There are more replies on the next page.
1
2