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

2019/4/17

Making a shooting laser

NoobFected NoobFected

2019/4/17

#
So I'm trying to make a shooting laser, but I am having some trouble. Whenever I press the start button, I have this weird error that says: java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed. I don't know why this is happening. Can someone help me out? Here's my code for my world class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class MyWorld here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class MyWorld extends World
{   
    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    
    public boolean laserSpawned = false;
    
    public MyWorld()
    {    
        // Create a new world with 600x400 cells with a cell size of 1x1 pixels.
        super(400, 600, 1, false);; 
        addLaser();
        addPlayer(); 
    }

    public void addPlayer(){
        Player player = new Player();
        int pWidth = player.getImage().getWidth();
        int pHeight = player.getImage().getHeight();
        addObject(player, getWidth() / 2, getHeight() - pHeight / 2);
    }

    public void addLaser(){
        Laser laser = new Laser();
        addObject(laser, 0, 0);
        laserSpawned = true;
    }
}
Code for the player:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Player here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Player extends Actor
{
    /**
     * Act - do whatever the Player wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    
    public Player(){
        Centipede centipede = new Centipede();
        int width = centipede.getImage().getWidth();
        int height = centipede.getImage().getHeight();
        GreenfootImage image = getImage();
        image.scale(width, height);
        turn(90);
    }
    
    public void act() 
    {
        movingMech();
        shootingMech();
    }    
    
    private void movingMech(){
            
        World world = getWorld();
        int worldWidth = world.getWidth();
        int worldHeight = world.getHeight();
        
        int width = getImage().getWidth();
        int height = getImage().getHeight();
        
        int dx = 0;
        int dy = 0;
        
        if(Greenfoot.isKeyDown("left")){
            dy = 0;
            if(getX() < width / 2){
                dx = 0;
            }else{
                dx = -width / 2;
            }
        }else if(Greenfoot.isKeyDown("right")){
            dy = 0;
            if(getX() > worldWidth - width / 2){
                dx = 0;
            }else{
                dx = width / 2;
            }
        }else if(Greenfoot.isKeyDown("up")){
            dx = 0;
            if(getY() < worldHeight * 0.8 + height / 2){
                dy = 0;
            }else{
                dy = -height / 2;
            }
        }else if(Greenfoot.isKeyDown("down")){
            dx = 0;
            if(getY() > worldHeight - height){
                dy = 0;
            }else{
                dy = height / 2;
            }
        }
        setLocation(getX() + dx, getY() + dy);
    }
    
    private void shootingMech(){
        if(Greenfoot.isKeyDown("space")){
            MyWorld w = (MyWorld)getWorld();
            w.addLaser();
        }
    }
}
Code for the laser:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Laser here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Laser extends Actor
{
    /**
     * Act - do whatever the Laser wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    
    public void act() 
    {
        boolean laserSpawn = ((MyWorld) getWorld()).laserSpawned;
        if(laserSpawn == true){
            Player player = new Player();
            int PlayerX = player.getX();
            int PlayerY = player.getY();
            int width = player.getImage().getWidth();
            int height = player.getImage().getHeight();
            GreenfootImage image = getImage();
            image.scale(width, height);
            setLocation(PlayerX, PlayerY - height / 2);
        }
    }    
}
Super_Hippo Super_Hippo

2019/4/17

#
One problem I see is that in the Laser class, you create a NEW player (line 20) and try to get the location of it. And it obviously has none because it isn't in a world. Your Laser class doesn't need to perform all those checks. It will only execute the act method if it exists in the active world. Also, why are you trying to use the Player image as the image for the Laser?
NoobFected NoobFected

2019/4/17

#
Super_Hippo wrote...
One problem I see is that in the Laser class, you create a NEW player (line 20) and try to get the location of it. And it obviously has none because it isn't in a world. Your Laser class doesn't need to perform all those checks. It will only execute the act method if it exists in the active world. Also, why are you trying to use the Player image as the image for the Laser?
What I was trying to do for the laser class is that whenever you press the spacebar, the laser will relocate above the player. I need the laser to get the x coordinates and y coordinates of the player for this to work.
Super_Hippo Super_Hippo

2019/4/17

#
So is the laser a weapon attached to the player? Then it might be best to let the player move the laser.
danpost danpost

2019/4/17

#
Super_Hippo wrote...
So is the laser a weapon attached to the player? Then it might be best to let the player move the laser.
I am quite sure that a laser, in this case, is like a projectile or bullet; it is the ray of light that is emitted from the location of the player. It should be created and placed into the world by the player.
Super_Hippo Super_Hippo

2019/4/18

#
That was my first thought, but then I noticed it was added from the world and it tries to get the player's location so I was a bit confused.
NoobFected NoobFected

2019/4/18

#
danpost wrote...
Super_Hippo wrote...
So is the laser a weapon attached to the player? Then it might be best to let the player move the laser.
I am quite sure that a laser, in this case, is like a projectile or bullet; it is the ray of light that is emitted from the location of the player. It should be created and placed into the world by the player.
Wow... I should try adding the laser class from the player. Thanks for the help and support.
NoobFected NoobFected

2019/4/18

#
danpost wrote...
Super_Hippo wrote...
So is the laser a weapon attached to the player? Then it might be best to let the player move the laser.
I am quite sure that a laser, in this case, is like a projectile or bullet; it is the ray of light that is emitted from the location of the player. It should be created and placed into the world by the player.
wait how exactly do you do that
Super_Hippo Super_Hippo

2019/4/18

#
As a start, something along those lines:
if (Greenfoot.isKeyDown("space"))
{
    Actor laser = new Laser();
    getWorld.addObject(laser, getX(), getY());
    //laser.setRotation(getRotation()); as far as I can see, you won't need this line
}
And the Laser simply moves forward and can check for intersections.
public void act()
{
    move(2);
    if (isTouching(<someclass>)
    {
        //…
    }
}
danpost danpost

2019/4/18

#
NoobFected wrote...
wait how exactly do you do that
Simply:
if (Greenfoot.isKeyDown("space")){
    getWorld().addObject(new Laser(), getX(), getY());
}
NoobFected NoobFected

2019/4/18

#
Thank you!
You need to login to post a reply.