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

2015/5/11

Double actor trouble

1
2
Corrupted Corrupted

2015/5/11

#
I am making a new version of a previous game I made, long story short, I am using two actors instead of one to work as one actor. One actor being the body, responsible for taking damage and movement. The other actor is the arm, responsible for shooting and aiming towards the mouse. The problem I am having is that I cannot find a way to make the arm follow the body, I've tried numerous ways but the arm will either move towards the mouse or just move towards the body. Help?
public class Body extends Actor
{
    private int speed = 10;
    private int health = 100;
    private boolean hurt = true;
    
    private static final GreenfootImage norm = new GreenfootImage("Hum.png");
    private static final GreenfootImage high = new GreenfootImage("Hum.png");
    private static final GreenfootImage med = new GreenfootImage("Hum.png");
    private static final GreenfootImage low = new GreenfootImage("Hum.png");
    
    public Body()
    {
        setImage(norm);
    }

    public void addedToWorld(greenfoot.World wrld)
    {
        move();
    }

    public void act() 
    {
        move();
        
        Actor a = getOneIntersectingObject(Zombie.class);
        Actor b = getOneIntersectingObject(Tanker.class);
        Actor c = getOneIntersectingObject(Crawler.class);
        
        if (a != null)
        {
            hurt(2);
            a.move(-30);
            hurt = true;
        }

        if (b != null)
        {
            hurt(4);
            b.move(-20);
            hurt = true;
        }
        
        if (c != null)
        {
            hurt(1);
            c.move(-40);
            hurt = true;
        }
        
        if (health <= 95)
        {
            setImage(high);
        }
        if (health <= 65)
        {
            setImage(med);
        }
        if (health <= 20)
        {
            setImage(low);
        }
        if (health <= 0)
            ((zworld)getWorld()).gameOver();
    }  

    public void move()
    {
        if(Greenfoot.isKeyDown("d"))
            move(3);
            turn(90);
        if(Greenfoot.isKeyDown("s"))
            move(3);
            turn(90);
        if(Greenfoot.isKeyDown("a"))
            move(3);
            turn(90);
        if(Greenfoot.isKeyDown("w"))
            move(3);
            turn(90);
    }
    
    public void move(int dist)
    {
        int x = getX();
        int y = getY();
        super.move(dist);
        if (getX() > getWorld().getWidth() || getX() < 0)
            setLocation(x, getY());
        if (getY() > getWorld().getHeight() || getY() < 200)
            setLocation(getX(), y);
    }
    
    public void hurt(int amount)
    {
        health -= amount;
        int size = Greenfoot.getRandomNumber(5)+1;
        for (int i = 0; i < size; i++)
        {
            int rot = Greenfoot.getRandomNumber(360);
            int spd = 2;
        }
    }
}



public class Arm extends Actor
{
    private int counter = 5;
    
    public Arm()
    {
        setImage("Arm.png");
    }

    public void act() 
    {
        shoot();
        
        if (Greenfoot.getMouseInfo() == null)
            return;
        int x = Greenfoot.getMouseInfo().getX();
        int y = Greenfoot.getMouseInfo().getY();
        turnTowards(x, y);
    } 

    private void shoot()
    {
        if (counter < 40)
            counter++;
        if (counter < 10)
            return;
        if (Greenfoot.isKeyDown("space"))
        {
            shootAssault();
            Greenfoot.playSound("bullet.wav");
        }
        if (counter < 40)
            return;
    }

    public void shootAssault()
    {
        counter = 0;
        Bullet b = new Bullet(false,20);
        getWorld().addObject(b,getX(),getY());
        b.setRotation(getRotation());
        b.move(10);
        b.turn(90);
        b.move(2);
        b.turn(-90);
        b.turn(Greenfoot.getRandomNumber(3)-1);
    }
}
danpost danpost

2015/5/11

#
You may want to have a reference field in the Body class for the Arm. Then, at the end of the Body act method, you can just place the arm at its location.
Corrupted Corrupted

2015/5/11

#
So I would want a reference in my Body class to call the Arm from and then would I use the Body's coordinates or could I find an easier way to do that? Do you think that maybe I can get an example of a reference, I always try to avoid references and go for an easier way (since they confuse me) and go for an easier solution. Sorry if this is a hassle I already tried doing some research and only managed to confuse myself more...
danpost danpost

2015/5/11

#
If you insert the following at line 6 of the Body class of the code above:
private Arm arm;
and have it assigned the Arm object that is given the body (this can be done in several way -- either via method or constructor parameter or by creating the arm directly within this class). Then, at the end of the Body act method:
arm.setLocation(getX(), getY());
would keep the arm with the body.
Corrupted Corrupted

2015/5/12

#
I tried it and this message popped up java.lang.NullPointerException at Body.act(Body.java:61) at greenfoot.core.Simulation.actActor(Simulation.java:594) at greenfoot.core.Simulation.runOneLoop(Simulation.java:552) at greenfoot.core.Simulation.runContent(Simulation.java:215) at greenfoot.core.Simulation.run(Simulation.java:205) I tried creating the arm within the Body class but the images always seem to fail at turning
danpost danpost

2015/5/12

#
You need to show what you tried. Post the entire revised Body class.
Corrupted Corrupted

2015/5/12

#
public class Body extends Actor
{
    private int speed = 10;
    
    private int health = 100;
    
    private boolean hurt = true;
    
    private Arm arm;
    
    private static final GreenfootImage norm = new GreenfootImage("Hum.png");
    private static final GreenfootImage high = new GreenfootImage("Hum.png");
    private static final GreenfootImage med = new GreenfootImage("Hum.png");
    private static final GreenfootImage low = new GreenfootImage("Hum.png");
    
    public Body()
    {
        setImage(norm);
    }

    public void addedToWorld(greenfoot.World wrld)
    {
        move();
    }

    public void act() 
    {
        move();
        
        Actor a = getOneIntersectingObject(Zombie.class);
        Actor b = getOneIntersectingObject(Tanker.class);
        Actor c = getOneIntersectingObject(Crawler.class);
        
        if (a != null)
        {
            hurt(2);
            a.move(-30);
            hurt = true;
        }

        if (b != null)
        {
            hurt(4);
            b.move(-20);
            hurt = true;
        }
        
        if (c != null)
        {
            hurt(1);
            c.move(-40);
            hurt = true;
        }
        
        if (health <= 95)
        {
            setImage(high);
        }
        if (health <= 65)
        {
            setImage(med);
        }
        if (health <= 20)
        {
            setImage(low);
        }
        if (health <= 0)
        {
            ((zworld)getWorld()).gameOver();
        }
        
        arm.setLocation(getX(), getY());
    }  

    public void move()
    {
        if(Greenfoot.isKeyDown("d"))
            move(3);
            turn(90);
        if(Greenfoot.isKeyDown("s"))
            move(3);
            turn(90);
        if(Greenfoot.isKeyDown("a"))
            move(3);
            turn(90);
        if(Greenfoot.isKeyDown("w"))
            move(3);
            turn(90);
    }
    
    public void move(int dist)
    {
        int x = getX();
        int y = getY();
        super.move(dist);
        if (getX() > getWorld().getWidth() || getX() < 0)
            setLocation(x, getY());
        if (getY() > getWorld().getHeight() || getY() < 200)
            setLocation(getX(), y);
    }
    
    public void hurt(int amount)
    {
        health -= amount;
        int size = Greenfoot.getRandomNumber(5)+1;
        for (int i = 0; i < size; i++)
        {
            int rot = Greenfoot.getRandomNumber(360);
            int spd = 2;
        }
    }
}
Super_Hippo Super_Hippo

2015/5/12

#
It says line 61:
setImage(med);
I don't know how this causes the error unless you set 'med' to null at some moment. I think this line will cause the error:
arm.setLocation(getX(), getY());
'arm' is null because you don't set it to anything anywhere. It doesn't have to do anything with your issue, but you should put { and } around the 'move(3); turn(90);' or it will turn 360 degrees every time. Every key press also does the same. Is this wanted? The for loop at the end doesn't do anything either.
danpost danpost

2015/5/12

#
danpost wrote...
have it assigned the Arm object that is given the body
Where are you doing this? You have not yet added any code to assign an Arm object to the 'arm' field declared at line 9. First thing you need is a 'setter' method that will assign a given object to the field. Then you need to have the world pass the created arm to the body via the method.
Corrupted Corrupted

2015/5/12

#
Super_Hippo; I don't know about the image being a problem, the arm.setLocation is what I am having trouble with, and the move method work just find with out the brackets. danpost; That just is the problem, I have just about no clue on how to make a 'setter' or any steps from there.
danpost danpost

2015/5/12

#
Super_Hippo wrote...
It says line 61
The code does not appear to be the entire class code as import statements are missing.
you should put { and } around the 'move(3); turn(90);' or it will turn 360 degrees every time. Every key press also does the same. Is this wanted?
I believe it is wanted. The movement direction for each key is set by the 'turn' statements and the character will return to an upright position after all for directions are checked.
danpost danpost

2015/5/12

#
A 'setter' method receives a value and assigns it to a field.
public void setTheField(TheFieldType theFieldValue)
{
    theFieldName = theFieldValue;
}
where the field is declared in the class:
private TheFieldType theFieldName;
Corrupted Corrupted

2015/5/13

#
So I'll want to put that in the Arm class, so that I could call it from the Body class?
Super_Hippo Super_Hippo

2015/5/13

#
danpost wrote...
I believe it is wanted. The movement direction for each key is set by the 'turn' statements and the character will return to an upright position after all for directions are checked.
Ah, I see. I was confused because it was both inserted (well, I don't know the right word, I mean it has the four spaces at the beginning). I think you should put it in the Body class, so the arm can say: "I am your arm, save me in the 'arm' field."
danpost danpost

2015/5/13

#
Super_Hippo wrote...
Ah, I see. I was confused because it was both inserted (well, I don't know the right word, I mean it has the four spaces at the beginning).
Yeah -- the 'turn' lines were over-indented.
There are more replies on the next page.
1
2