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

2014/12/9

Sharing a Variable Between Other Actors and the World

1
2
Kickero Kickero

2014/12/9

#
I need help again! I need to be able to share/update my variable kills between four different places Sewer1(the World), Characters(Actor), Porcubutt(Actor), BlackKnight(Actor),SirB(Actor) my actor tree looks like this World Sewer1 Actor Characters SirB Porcubutt BlackKnight preferably i would like to compile all the updates into characters so every time one of the classes updates kills the kills get updated in characters and all other classes then finally i need Sewer1 to be able to see (but not affect)the kills in characters so that Sewer1 can spawn a door... sorry if that was confusing... also I've been playing around with getter setter methods to get this to work but I've been unsuccessful so if that is an option to fix this if you could explain it in depth that would be awesome!
danpost danpost

2014/12/9

#
It does not work that way. Compiling all the updates into Characters is not feasible. Characters is a general blueprint of your sub-actors, which describes their individualities. Anything you put in Characters is not shared, but given individually to each actor created by it or any of its subclasses. Each actor can have a field to hold its own 'kills', but 'totalKills' will need to be in your Sewer1 class. Actually, you may not even need to do that. If you have exactly one SirB, one Porcubutt and one BlackKnight object in your world, just keep references to them in your Sewer1 class. You can give your Characters a 'kills' field and a getter method for it (which will give each of the three actors a 'kills' field and the getter method to return its own 'kills' value). Then you can check the total in your world act method:
if (getObjects(Door.class).isEmpty() && sirB.getKills()+porcubutt.getKills()+blackKnight.getKills() >= minimumTotalKillsForDoorToAppear)
The first condition in the 'if' statement is to ensure that door after door is not created, one on top of another, once the total kills reaches the set value.
vexqa vexqa

2014/12/9

#
You want to store it in the Sewer1 class.
Kickero Kickero

2014/12/9

#
thanks that will kinda work for a level but I cant get it to work because I'm getting an error that reads "non-static method getKills() cannot be referenced from a non-static context" also should the "kills" variable be public or private in each of the classes you also you mentioned a "field" which i haven't gotten the chance to mess with yet one last thing .... specified that I could only have one of each character on my level there is one level where i plan to have 3+ of both porcubutts and BlackKnights how do i get around that? I've deposited my code for the Porcubutt Sewer1 and SirB if that will help...
Kickero Kickero

2014/12/9

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * The Main character
 * 
 * Cody Dusthimer 
 * 1.01
 */
public class SirB extends Characters
{
    private int level;
    private GreenfootImage image1R;
    private GreenfootImage image1L;
    private GreenfootImage image2R;
    private GreenfootImage image2L;
    private GreenfootImage imageJR;
    private GreenfootImage imageAR;
    private GreenfootImage imageAL;
    private int X = 0;
    private int Y = 0;
    private int vSpeed = 0;
    private int accel = 2;
    private boolean jumping;
    private int jumpStrength = 20;
    private int speed = 10;
    private int direction = 0; // 1 = right and -1 = left
    private int height = 0;
    private static int kills = 0;
    private int SBHealth = 90;
    private boolean IsAttacking = false;
    private int stillAttacking = 100;

    public SirB()
    {
        image1R = new GreenfootImage ("SirButts_R.png");
        image1L = new GreenfootImage ("SirButts_L.png");
        image2R = new GreenfootImage ("SirButts_R2.png");
        image2L = new GreenfootImage ("SirButts_L2.png");
        imageJR = new GreenfootImage ("SirButts_R_J.png");
        imageAR = new GreenfootImage ("SirButts_R_A.png");
        imageAL = new GreenfootImage ("SirButts_L_A.png");
    }

    public void act() 
    {
        Controls();
        checkFall();
        Exit();

    }    

    public void Controls()
    {
        int x = getX();
        int y = getY();
        if(Greenfoot.isKeyDown("d"))
        {
            setLocation (x + 3, y);
            walk1();
            direction = 1;
        }
        if(Greenfoot.isKeyDown("a"))
        {
            setLocation (x - 3, y);
            walk2();
            direction = -1;
        }
        if(Greenfoot.isKeyDown("w") && jumping == false)
        {
            Jump();
        }
        if(Greenfoot.isKeyDown("space"))
        {
            Attack();
            checkAttack();
        }

    }

    public void checkAttack()
    {
        if(Greenfoot.isKeyDown("space") && stillAttacking >= 50 )
        {
            IsAttacking = true;
            stillAttacking = stillAttacking -1;
        }
        else
        {
            IsAttacking =false;
            if (IsAttacking = false && stillAttacking < 100 )
            {
                stillAttacking = stillAttacking +1;
            }
            if (IsAttacking = false && direction == -1)
            {
                walk2();
            }
            else
            {
                walk1();
            }
        }
    }

    public void Jump()
    {
        vSpeed = vSpeed - jumpStrength;
        jumping = true;
        Fall();
    }

    public void Fall()
    {
        setLocation(getX(), getY() + vSpeed);
        if(vSpeed <=9)
        {
            vSpeed = vSpeed + accel;
        }
        jumping = true;
    }

    public void checkFall()
    {
        if(onGround())
        {
            vSpeed = 0;
        }
        else
        {
            Fall();
        }
    }

    public boolean onGround()
    {
        int spriteHeight = getImage().getHeight();
        int yDistance = (int)(spriteHeight/2) + 8;
        Actor ground = getOneObjectAtOffset(0, getImage().getHeight()/2, Platforms.class);
        if(ground == null)
        {
            jumping = true;
            return false;
        }
        else
        {
            moveToGround(ground);
            return true;
        }
    }

    public boolean checkFloor()
    {
        Actor under = getOneObjectAtOffset (0,55,Platforms.class);
        return (under) != null;
    }

    public void walk1()
    {
        if ( getImage() == image1R )
        {
            setImage(image2R);
        }
        else
        {
            setImage(image1R);
        }    
    }

    public void walk2()
    {
        if ( getImage() == image1L )
        {
            setImage(image2L);
        }
        else
        {
            setImage(image1L);
        }    
    }

    public void Attack()
    {

        if (stillAttacking >= 15)
        {
            IsAttacking = true;
            DofAttack();
        }
        else
        {
            IsAttacking = false;
        }
    }

    public void moveToGround(Actor ground)
    {
        int groundHeight = ground.getImage().getHeight();
        int newY = ground.getY() - (groundHeight + getImage().getHeight())/2;
        setLocation(getX(), newY);
        jumping = false;
    }

    public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;        
    }

    public void Exit() 
    {
        if (canSee(SewerExit.class)) 
        {
            Greenfoot.setWorld (new Sewer2());
        }
        if (canSee(Ladder.class)) 
        {
            Greenfoot.setWorld (new Forest());
        }
        if (canSee (Exits.class))
        {

        }
    }

    public boolean DofAttack()
    {
        if(Greenfoot.isKeyDown("space") && direction == 1)
        {
            setImage(imageAR);
        }
        if(Greenfoot.isKeyDown("space") && direction == -1)
        {
            setImage(imageAL);
        }
        return false;
    }

    public int getKills()
    {
        return this.kills;
    }

}
Kickero Kickero

2014/12/9

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Porcubutt here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Porcubutt extends Characters
{
    private GreenfootImage imageR;
    private GreenfootImage imageL;
    public static int Health = 1;
    private boolean IsAttacking = false;
    private int stillAttacking = 100;
    private int spriteHeight = getImage().getHeight();
    private int spriteWidth = getImage().getWidth();
    private int lookForEdge = (int)spriteHeight/2;
    private int lookForGroundDistance = (int)spriteWidth/2;
    private int speed = 2;
    private int direction = 1; //-1=left 1=right
    private int kills = 0;
    private int SBHealth = 90;

    public Porcubutt()
    {
        imageR = new GreenfootImage ("PorcuButt_R.png");
        imageL = new GreenfootImage ("PorcuButt_L.png");
    }

    /**
     * Act - do whatever the Enemy wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        SirBAlert();
        checkAttack();
        move();
    }    

    public void checkAttack()
    {
        if(Greenfoot.isKeyDown("space") && stillAttacking >= 50 )
        {
            IsAttacking = true;
            stillAttacking = stillAttacking -1;
        }
        else
        {
            IsAttacking =false;
            if (IsAttacking = false && stillAttacking < 100 )
            {
                stillAttacking = stillAttacking +1;
            }
        }
    }

    public void move()
    {

        if (getWorld() != null)
        {
            Actor ground = getOneObjectAtOffset(lookForEdge, lookForGroundDistance, Platforms.class);
            if(ground == null && getWorld() != null)
            {
                speed *= -1; // Reverses direction
                lookForEdge *= -1; // Looks for a negative number
            }
            else
            {
                setLocation (getX() + speed, getY());
            }
            if (speed == 2)
            {
                direction = 1;
                setImage(imageR);
            }
            else 
            {
                direction = -1;
                setImage(imageL);
            }

        }
        else
        {
            return;
        }

    }

    public void SirBAlert()
    {
        if (canSee(SirB.class))
        {
            checkSirB();
        }
    }

    public void checkSirB()
    {

        if (IsAttacking == true )
        {
            Greenfoot.playSound("Squeak.wav");
            Health --;
        }
        else
        {
            SBHealth =SBHealth-15;
            Greenfoot.playSound("Hurt.wav");

        } 
        if (Health <= 0)
        {
            kills++;
            getWorld().removeObject(this);

        }

        if (SBHealth <= 0)
        {
            Greenfoot.stop();
        }
    }

    public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;     
    }

    public int getKills()
    {
        return this.kills;
    }

}
davmac davmac

2014/12/9

#
I'm getting an error that reads "non-static method getKills() cannot be referenced from a non-static context"
Are you sure it doesn't actually read "non-static method getKills() cannot be referenced from a static context"? ... in which case what it's saying is that you can't call a method that isn't static from a method that is static (unless you qualify it with an object reference). Probably, you have a method which should not be static. I can't see the error with a quick inspection, it would help if you pointed out which line you get the error on.
Kickero Kickero

2014/12/9

#
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class Sewer1 here. * * @author (your name) * @version (a version number or a date) */ public class Sewer1 extends World { /** * Constructor for objects of class Sewer1. * */ public Sewer1() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super(488, 244, 1); addObject ( new SewerFloor1(), 244, 213); addObject ( new SirB(), 59, 137); addObject ( new Porcubutt(), 398, 165); } public void act() { if (getObjects(Exits.class).isEmpty() && SirB.getKills() + Porcubutt.getKills() + BlackKnight.getKills() >= 1) { addObject ( new SewerExit(), 398, 165); } } }
Kickero Kickero

2014/12/9

#
yea there was a point when i got it to work but then by making it static but ive been going back and forth playing with it trying to figure it out on my own
Kickero Kickero

2014/12/9

#
but that was awhile ago and i tried to make it easier on my self by compiling all the class kills together and when that didnt work i wasnt able to remember how i had originally done it
Kickero Kickero

2014/12/9

#
also even after i changed the static variable back it still gave me the same error
davmac davmac

2014/12/9

#
You are trying to call the getKills() method on the classes themselves (this is the 'static context'), when you should be calling them on instances of those classes. In these lines:
 addObject ( new SewerFloor1(), 244, 213);
 addObject ( new SirB(), 59, 137);
 addObject ( new Porcubutt(), 398, 165); 
You need to save the objects you create in variables of the appropriate type eg:
 // instance variables:
 SewerFloor1 sewerFloor1;
 
 // in the constructor:
 sewerFloor1 = new SewerFloor1();
 addObject ( sewerFloor1, 244, 213);
And then instead of 'SewerFloor1.getKills()' you should call 'sewerFloor1.getKills()'.
danpost danpost

2014/12/9

#
Kickero wrote...
Please use the 'code' link below the reply box for inserting code into your posts. To see what it looks like after you do this, click on Quote for this post and view the text in the content box. If you noticed, I did not start the references with uppercase letters. They are not class names, but they were to be fields the referenced objects from those classes. I did say 'just keep references to them in your Sewer1 class':
import greenfoot.*;

public class Sewer1 extends World
{
    // these three fields will reference your actors
    private SirB sirB = new SirB();
    private Porcubutt porcubutt = new Porcubutt();
    private BlackKnight blackKnight = new BlackKnight();

    public Sewer1()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(488, 244, 1); 
        addObject ( new SewerFloor1(), 244, 213);
        // adding referenced actors into world
        addObject (sirB, 59, 137);
        addObject (porcubutt, 398, 165);
        // where is blackKnight added into the world???
    }

    public void act()
    {
        if (getObjects(Exits.class).isEmpty() && sirB.getKills() + porcubutt.getKills() + blackKnight.getKills() >= 1)
        {
            addObject ( new SewerExit(), 398, 165);
        }
    }
}
Kickero Kickero

2014/12/9

#
Thanks! Finally got it! will that work with as many characters as i want?
danpost danpost

2014/12/9

#
I was not able to edit out the 'quote' tags before another post was created. There is nothing quoted in my last post.
There are more replies on the next page.
1
2