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

2018/3/18

Gamebreaking error and i don't know how to fix it

Recorsi Recorsi

2018/3/18

#
Hi recently added a boost key to my game which speeds up the actor for a short period of time. You have 2 boosts until the "boost bar" is empty. to access the boostbar class from the main actor i used this code:
World world = getWorld();
Spielfeld spielfeld = (Spielfeld)world;
BoostBar boostbar = spielfeld.boostbar;
(my world is called spielfeld) in the game you die when you hit a rock and the game resets automatically, but because of line 3 (thats what the error says) it crashes when you hit a rock. How can i bypass or fix this issue? Here is the LINK for the full scenario, i had to upload it to google drive because the project was too large. Thanks for the help :)
Super_Hippo Super_Hippo

2018/3/18

#
Is the error a nullpointer exception? If yes, you try to execute the code after the actor has been removed from the world.
Recorsi Recorsi

2018/3/18

#
Super_Hippo wrote...
Is the error a nullpointer exception? If yes, you try to execute the code after the actor has been removed from the world.
Yes it is :) How do i execute the code only when the actor is in the world?
Super_Hippo Super_Hippo

2018/3/18

#
That depends on where this code is and how your act method looks like. If you have the code in an extra method (or as the last important part of the act method), you can exit the method if it isn't in a world
//between lines 1 and 2
if (world == null) return;
danpost danpost

2018/3/18

#
Recorsi wrote...
How do i execute the code only when the actor is in the world?
Please provide the class codes of the actor for inspection.
Recorsi Recorsi

2018/3/19

#
Error message: java.lang.NullPointerException at Spaceship.Boost(Spaceship.java:131) at Spaceship.act(Spaceship.java:48) Spaceship class:
import greenfoot.*;  

/**
 * The main actor.
 * 
 * @author Julian
 * @version 18.03.18
 */
public class Spaceship extends Actor
{
  private static final int NUM_FRAGMENTS = 20;
  GifImage myGif = new GifImage("spaceship.gif");
  private int dx;
  private int dy;
  Laser laser = new Laser();
  GreenfootSound LaserSound = new GreenfootSound("Laser.wav");
  private int horizontalSpeed = 5;
  private int verticalSpeed = 5;
  explosion explosion = new explosion();
  GreenfootSound ExSound = new GreenfootSound("Explosion.wav");
  private double v = 0;
  private int mySpeed = 0;
  private static final int MAX_SPEED = 15;
  GreenfootSound EngineSound = new GreenfootSound("Engine.mp3");
  private int ProjectileTime;
  private static int ShootTime = 15;
  private int BoostCooldown;
  private static int BoostTime = 50;
  GreenfootSound BoostSound = new GreenfootSound("Boost.mp3");
  private final int SPEED_BOOST_TIMER = 30;
  private int speedBoostTimeLeft = SPEED_BOOST_TIMER;
  private boolean gotSpeedBoost = false;
  private int refillBoostTimer = 200;
  private boolean boostActive = false;
  private boolean boostEmpty = false;
  public Spaceship()
  {
      GreenfootImage image = getImage();  
      image.scale(75, 52);
      setImage(image);
  }     
  public void act() 
  {
      Movement();
      shootNew();
      GIF();
      TriggerEx();
      Boost();
      checkBorders();
      hitEnemy();
  }
  public void TriggerEx()
  {
      Rock rock = (Rock)getOneIntersectingObject(Rock.class);;
      if (rock != null && getNeighbours(getImage().getWidth()*8/10, false, Rock.class).contains(rock) && rock.hitsShip(this))
      {
         getWorld().addObject(explosion, getX()+1, getY()+1);
         explode2();
         ExSound.play();
      }
  }
  public void hitEnemy()
  {
      if (isTouching(Enemy.class))
      {
         explode2();
      }
  }
  private void GIF()
  {
      setImage(myGif.getCurrentImage());
      GreenfootImage image = getImage();
      image.scale(75, 52);
      setImage(image);
   }
  private void Movement()
  {
      if (Greenfoot.isKeyDown("a")||Greenfoot.isKeyDown("left"))
       {
            turn(-4);
       } 
      if (Greenfoot.isKeyDown("d")||Greenfoot.isKeyDown("right"))
       {
            turn(4);
       }
      if (!boostActive && Greenfoot.isKeyDown("w")||Greenfoot.isKeyDown("up"))
      { 
          mySpeed++;
          if (mySpeed > MAX_SPEED) mySpeed = MAX_SPEED;
      } else if (mySpeed > 0) mySpeed--; move(-mySpeed/3); 
      if (!boostActive && Greenfoot.isKeyDown("w")||Greenfoot.isKeyDown("up"))
      {
         EngineSound.playLoop();
         EngineSound.setVolume(100);
      } else 
      {
         EngineSound.pause();
      }
  }
  private void checkBorders()
  {
     if (getX() < 0) setLocation(0, getY());
     if (getX() > 900) setLocation(900, getY());
     if (getY() > 900) setLocation(getX(), 900);
     if (getY() < 0) setLocation(getX(), 0);
  }
  public void shootNew()
  {
       ProjectileTime++;
       if(ProjectileTime >= ShootTime)
           {
           if(Greenfoot.isKeyDown("space"))
           {
               Laser laser1=new Laser(), laser2=new Laser();
               getWorld().addObject(laser1, getX(), getY());
               getWorld().addObject(laser2, getX(), getY());
               laser1.setRotation(getRotation()-180);
               laser2.setRotation(getRotation()-180);
               laser1.turn(90); laser1.move(15); laser1.turn(-90);
               laser2.turn(-90); laser2.move(15); laser2.turn(90);
               LaserSound.play();
               ProjectileTime = 0;
           }
       }    
  }
   public void Boost()
   {
       BoostCooldown++;
       World world = getWorld();
       Spielfeld spielfeld = (Spielfeld)world;
       BoostBar boostbar = spielfeld.boostbar;
       refillBoostTimer--;
       if(BoostCooldown >= BoostTime)
       {
           if(!boostEmpty &&Greenfoot.isKeyDown("shift"))
           {
               boostActive = true;
               boostbar.usedBoost();
               BoostSound.play();
               speedBoostTimer();
               gotSpeedBoost = true;
               mySpeed = 50;
               BoostCooldown = 0;
           }else boostActive = false;
       }
       if (boostbar.boost > 0)
       {
           boostEmpty = false;
       }
       if(boostbar.boost <=0)
       {
           boostEmpty = true;
           gotSpeedBoost = false;
       }
       if(refillBoostTimer <= 0)
       {
           boostbar.refillBoost();
           refillBoostTimer = 200;
       }
  }
  public void speedBoostTimer()
   {
       speedBoostTimeLeft--;
       if (speedBoostTimeLeft <= 0)
       {
           gotSpeedBoost = false;
           mySpeed = 15;
           speedBoostTimeLeft = SPEED_BOOST_TIMER;
       }
  }
  public void explode2()
  { 
       placeDestroyed (getX(), getY(), NUM_FRAGMENTS);
       DeathScreen deathscreen = new DeathScreen();
       ResetInfo resetinfo = new ResetInfo();
       getWorld().addObject(deathscreen, 450, 350);
       getWorld().addObject(resetinfo, 450, 500);
       getWorld().removeObject(this);
       EngineSound.stop();
  }
  private void placeDestroyed(int x, int y, int numFragments)
   {
       for (int i=0; i < numFragments; i++) {
          getWorld().addObject(new Destroyed(), x ,y );
      }
  }
}
danpost danpost

2018/3/19

#
The TriggerEx method calls the explode2 method which removes the actor from the world. Once that is done, you cannot use location or collision type methods and the getWorld method will start returning a null value. Easiest solution is to move the call to TriggerEx to be last in the act method. EDIT: I now see that your hitEnemy method also calls the explode2 method. Since you can only call one of them last from the act method, you will have to either put the following at the beginning of the last line in act:
if (getWorld() != null)
or the following before the last line (between the last two lines in act):
if (getWorld() == null) return;
Recorsi Recorsi

2018/3/19

#
Thank you :)
You need to login to post a reply.