NullPointerException error during coding

Hello. I’m working on a project using Peter Lager’s AI for 2D games library, and tried to make a program to see if I understood how the library is used, since I am new to the concept. The program would make a world with obstacles with a wandering entity in it which would aimlessly wander around the screen, avoiding the obstacles. That worked.

Then I wanted to add a second entity, which would pursue the first one(Which would hide from it). All seemed well until I ran the new program and got a blank gray screen, which immediately crashed. I looked at the program but the only hint I could find was the error NullPointerException on lines 97 & 99. Can anybody explain this?

Here’s the code;

import game2dai.*;
import game2dai.entities.*;
import game2dai.entityshapes.*;
import game2dai.entityshapes.ps.*;
import game2dai.fsm.*;
import game2dai.graph.*;
import game2dai.maths.*;
import game2dai.steering.*;
import game2dai.utils.*;

int[] obs = new int[] {  //obstacles
  100, 100, 36, 
  200, 200, 32, 
  270, 70, 16, 
  380, 180, 37, 
  510, 110, 27, 
  520, 210, 23, 
  400, 80, 10, 
  90, 240, 15,
  20, 50, 20
};
World world;
Domain wd;
Vehicle tank;  //hiding tank
Vehicle tank2; //pursuing tank
BitmapPic view;  //hiding tank
BitmapPic view2; //pursuing tank

StopWatch sw = new StopWatch();

public void setup() {
  size(600, 300);
  world = new World(width, height);
  wd = new Domain(0, 0, width, height);

  ObstaclePic obView = new ObstaclePic(this, color(0, 96, 0), color(0), 3);
  for (int i = 0; i < obs.length; i += 3) {
    Obstacle obstacle = new Obstacle(
    new Vector2D(obs[i], obs[i+1]), // position
    obs[i+2] // collision radius
    );
    obstacle.renderer(obView);
    world.add(obstacle);
  }

  // Create the entity that's going to hide
  tank = new Vehicle(
    new Vector2D(width/2, height/2), // position
    16,                              // collision radius
    new Vector2D(0, 0),              // velocity
    60,                              // maximum speed
    new Vector2D(1, 1),              // heading
    7,                               // mass
    1.5f,                            // turning rate
    1000                             // max force
  ); 
 PersonPic view = new PersonPic(this);   //hiding entity icon
view.showHints(Hints.HINT_HEADING | Hints.HINT_VELOCITY | Hints.HINT_OBS_AVOID | Hints.HINT_WANDER);
  tank.renderer(view);
  tank.AP().obstacleAvoidOn().wanderOn().hideOn();
  tank.AP().wanderFactors(90, 20, 20);
  tank.AP().obstacleAvoidDetectBoxLength(35);
  tank.worldDomain(wd, SBF.REBOUND);
  world.add(tank);
  
  //Create the entity that's going to pursue the other one
  tank2 = new Vehicle(
    new Vector2D(100,40), // position
    16,                              // collision radius
    new Vector2D(0, 0),              // velocity
    60,                              // maximum speed
    new Vector2D(1, 1),              // heading
    7,                               // mass
    1.5f,                            // turning rate
    1000                             // max force
  ); 
  ArrowPic view2 = new ArrowPic(this);  //pursuing entity icon
  view2.showHints(Hints.HINT_HEADING | Hints.HINT_VELOCITY | Hints.HINT_OBS_AVOID | Hints.HINT_WANDER | Hints.HINT_VIEW);
tank2.renderer(view);
  tank2.AP().obstacleAvoidOn().wanderOn().pursuitOn(tank);
  tank2.AP().wanderFactors(90, 20, 20);
  tank2.AP().obstacleAvoidDetectBoxLength(35);
  tank2.worldDomain(wd, SBF.REBOUND);
  world.add(tank2);
}

public void draw() {
  double elapsedTime = sw.getElapsedTime();
  // Animate the tank image
  float speed = (float) tank.speed();
  float maxSpeed = (float) tank.maxSpeed();
  if (speed > 1) {
    float newInterval = map(speed, 0, maxSpeed, 0.6f, 0.04f);
    view.setAnimation(newInterval, 1);
  }
  else {
   view.pauseAnimation();   //line 97
  }
  world.update(elapsedTime);    //line 99
  background(220, 255, 220);   
  world.draw(elapsedTime);
}

If it helps, here is the original code with one wandering entity
(i renamed them tanks in the problematic code).

import game2dai.*;
import game2dai.entities.*;
import game2dai.entityshapes.*;
import game2dai.entityshapes.ps.*;
import game2dai.fsm.*;
import game2dai.graph.*;
import game2dai.maths.*;
import game2dai.steering.*;
import game2dai.utils.*;

// ObstacleAvoid_01.pde
int[] obs = new int[] {
  100, 100, 36, 
  200, 200, 32, 
  270, 70, 16, 
  380, 180, 37, 
  510, 110, 27, 
  520, 210, 23, 
  400, 80, 10, 
  90, 240, 15,
  20, 50, 20
};
World world;
Domain wd;
Vehicle entity1;  
BitmapPic view;

StopWatch sw = new StopWatch();

public void setup() {
  size(600, 300);
  world = new World(width, height);
  wd = new Domain(0, 0, width, height);

  ObstaclePic obView = new ObstaclePic(this, color(0, 96, 0), color(0), 3);
  for (int i = 0; i < obs.length; i += 3) {
    Obstacle obstacle = new Obstacle(
    new Vector2D(obs[i], obs[i+1]), // position
    obs[i+2] // collision radius
    );
    obstacle.renderer(obView);
    world.add(obstacle);
  }

  // Create the entity
  entity1 = new Vehicle(
    new Vector2D(width/2, height/2), // position
    16,                              // collision radius
    new Vector2D(0, 0),              // velocity
    60,                              // maximum speed
    new Vector2D(1, 1),              // heading
    7,                               // mass
    1.5f,                            // turning rate
    1000                             // max force
  ); 
  PersonPic view = new PersonPic(this);    //display entity
  view.showHints(Hints.HINT_HEADING | Hints.HINT_VELOCITY | Hints.HINT_OBS_AVOID | Hints.HINT_WANDER);
  entity1.renderer(view);
  entity1.AP().obstacleAvoidOn().wanderOn();
  entity1.AP().wanderFactors(70, 20, 20);
  entity1.AP().obstacleAvoidDetectBoxLength(37);
  entity1.worldDomain(wd, SBF.REBOUND);
  world.add(entity1);
}

public void draw() {
  double elapsedTime = sw.getElapsedTime();
  world.update(elapsedTime);
  background(220, 255, 220);
  world.draw(elapsedTime);
}

Well, i can‘t tell you much, but one thing i can say is that there are some null objects being worked on.

And i can say that the null object is not the world variable, because then there‘d be another error in line 101.

Also, you‘re Never setting view, that‘s why that one is giving a null Pointer error. You Are in fact creating a new variable view within setup, but that is not a global variable, so it will not be there anymore in draw().

I don‘t know how it‘s supposed to be defined exactly with that library, but you should add a line in setup that goes like this :

view = new BitmapPic(); 
//or some extension of the class BitmapPic. 
//Also, might need some parameters

And you should change the view variable of class PersonPic to viewPerson or something like that.

view.*something*()

is a function that is imported from the library and does not need to be called during the code. An example of this is

view.setAnimation(newInterval, 1);

which does work when the original program is run.
In the original program, I got the same line 97 error. The weird thing is, when I removed line 97, the original program worked. The new one doesn’t. Your suggestion of using the BitmapPic was good, but my library for some reason doesn’t seem to support it.

Uhm? I don‘t know what you mean… i doubt that the library you are using is using global variables that have to be written manually by the User, without just referencing them…

This is how a library would do it :

PVector needed;//using PVector just to represent any Class

class LibraryClass {

   LibraryClass (PVector n) {
      n = new PVector(100, 100);
   }
}

void setup() {
println(needed); //0,0
LibraryClass LC = new LibraryClass(needed);
println(needed); //100, 100
}

This is what you‘re (If i got you right) saying it does (which is pretty much terrible) :

PVector needed;//using PVector just to represent any Class

class LibraryClass {

   LibraryClass () {
      needed = new PVector(100, 100); //here‘s the difference!
   }
}

void setup() {
println(needed); //0,0
LibraryClass LC = new LibraryClass(needed);
println(needed); //100, 100
}

And although it does the same, the last Code would be disapproved by many even in personal Code, not to mention a library…

So again, i‘m 95% sure that you Have to set the Global Variable view from class BitmapPic somewhere, which you aren’t doing.

And since the error is a null Pointer error exactly in the line where you have a null object according to what your Code does (if it‘s not using this Bad way of calling global variables in a library, which i doubt), that should be pretty much the reason for it.

Edit: well, you said that view.setAnimation() does work, so… idk. I‘ll take a look at the libraries Code…

Edit2: So, i‘ve been taking a look at the Code, and again, i‘m sure you have to set BitmapPic view somewhere, because you can‘t invoke a method on a variable that has never been initialized…

If you have any Code that works, please post that version and also, please post an edited version of your Code if the problem is still not solved using the mentioned ways.