I am trying to make a snake-type game in Java.
To do so, I am using lists to keep hold every of the snake's body parts with
ArrayList<SnakeBodyPart> snakeBodyParts = new ArrayList<SnakeBodyPart>();.
I declare and initiate a variable, SnakeBodyPart SnakeBodyPart = null;.
I then add a body part to the snake with snakeBodyParts.add(SnakeBodyPart);.
(Not the most efficient way, I guess, but it'll have to do.)
But for some reason, whenever I run the script, I get
Exception in thread "main" java.lang.NullPointerException,
and that the error is
at game.Snake.<init>(Snake.java:60)
in the Java console.
I want to know what the problem is. Here is the code for the SnakeBodyPart.
class SnakeBodyPart{
int x,y,direction;
void move(){
if(direction == 0){
y -= 50;
}
if(direction == 1){
x += 50;
}
if(direction == 2){
y += 50;
}
if(direction == 3){
x -= 50;
}
}
}
Thanks in advance!
EDIT:
Line 60 is snakeBodyParts.get(0).direction = 0;.
You have done this:
SnakeBodyPart snakeBodyPart = null;
Create the object
SnakeBodyPart snakeBodyPart = new SnakeBodyPart();
Since snakeBodyPart is null, you are getting NullPointerException in Line 60. You are calling get() method on null as snakeBodyParts.get(0).direction = 0;
Related
Consider the following method:
void a ()
{
int x;
boolean b = false;
if (Math.random() < 0.5)
{
x = 0;
b = true;
}
if (b)
x++;
}
On x++ I get the "Local variable may not have been initialized" error. Clearly x will never be used uninitialized. Is there any way to suppress the warning except by initializing x? Thanks.
No, there is no way Java can examine all possible code paths for a program to determine if a variable has been initialized or not, so it takes the safe route and warns you.
So no, you will have to initialize your variable to get rid of this.
There is one :
void a () {
if (Math.random() < 0.5) {
int x = 1;
}
}
The compiler isn't responsible for devising and testing the algorithm. You are.
But maybe you should propose a more practical use case. Your example doesn't really show what's your goal.
Why don't you simply use
void a ()
{
int x;
boolean b = false;
if (Math.random() < 0.5)
{
x = 0;
b = true;
x++;
}
if (b) {
//do something else which does not use x
}
}
In the code why do you want to use x outside the first if block, all the logic involving x can be implemented in the first if block only, i don't see a case where you would need to use the other if block to use x.
EDIT: or You can also use:
void a ()
{
int x;
boolean b = (Math.random() < 0.5);
if (b) {
x=1
//do something
}
}
You can and should be defining the value of x unconditionally if it will be used later in your code.
There are a few ways to do this:
On initialization
int x = 0;
Because this is outside the conditional (if), Java won't complain.
Add else clause to conditional
if (Math.random() < 0.5)
{
x = 0;
b = true;
} else
{
x = 1;
}
Because there is an else to this if, and both code paths initialize x, Java will also be happy with this.
Move your usage of the variable into the conditional block
Clearly the question has a minimally-reproducible example, not a full one, but if you only ever want to use the variable conditionally, then it belongs in the conditional block.
if (Math.random() < 0.5)
{
x = 0;
x++;
}
If you don't aren't conditionally using the variable, then you need to provide an integer value to use in case Math.random() >= 0.5, using one of the solutions above.
if(handler.obj.isEmpty())
handler.addObject(new Box(x, y, ID.Box));
else{
for(int i = 0; i < handler.obj.size(); i++){
Object tempObj = handler.obj.get(i);
if (tempObj.getX() == x && tempObj.getY() == y && tempObj.getId() == ID.Box)
handler.removeObect(tempObj);
else
handler.addObject(new Box(x, y, ID.Box));
}
}
the handler.addObject() in the else statement seems unreachable or doesn't work
From comment:
public class Handler {
LinkedList<Object> obj = new LinkedList<Object>();
public void tick(){
for (int i = 0; i < obj.size();i++){
Object tempObj = obj.get(i);
tempObj.tick();
}
}
public void render(Graphics g){
for (int i = 0; i < obj.size(); i++){
Object tempObj = obj.get(i);
tempObj.render(g);
}
}
public void addObject(Object obj){
this.obj.add(obj);
}
public void removeObect(Object obj){
this.obj.remove(obj);
}
}
Let's see. Assume first time it runs, x,y is 1,1. So you add Box(1,1).
Next time is run, let's assume x,y is 2,3. So, enter for loop:
i = 0: Not same x,y, so enter else, and add Box(2,3).
i = 1: Same as x,y (yeah, we just added it), so enter if and remove Box(2,3).
Result: Box added and removed again.
Oh yeah, a debugger would have told you the same thing.
Your problem is that your for loop ends in the wrong place. This causes two undesirable symptoms.
Firstly, you're adding your new Box once for every element in your list that doesn't match the box, instead of adding it just once.
Secondly, you're removing some of those new Box objects that you just added, once you get to the end of the loop.
I would recommend rewriting the method like this. Notice how the for loop ends before the new object is added - this makes sure that the object is added at most once. Also notice the return statement after an object is removed - this can be done because once the object is removed, the method has no more work to do.
public void addOrRemoveBox(int x, int y) {
for(int i = 0; i < handler.obj.size(); i++){
Object tempObj = handler.obj.get(i);
if (tempObj.getX() == x && tempObj.getY() == y && tempObj.getId() == ID.Box) {
handler.removeObect(tempObj);
return;
}
}
handler.addObject(new Box(x, y, ID.Box));
}
Lastly, you appear to have written your own class called Object (otherwise this code wouldn't compile). This is probably a bad idea, because it will cause you to get confused between your Object class, and the Object class that's built into Java. I suggest you rename that class.
So well I'm just here wondering if there's a way to pass a variable through a statement. Something like this:
if (a < b) {
double g = 1
} else if (a > b) {
double g = 0
}
if (g = 1) {
System.out.print("true");
} else {
System.out.print("false");
}
Mainly saying, I want to set a variable if a statement is true or not, go to the next section of code and print out "true" or "false" and I pretty much am just wondering if this is possible without creating a new method (and of course if there is code for it).
Thank you.
You are almost there. You have to declare g outside the if statements, so you can access to it whithin the whole function. Read more about scopes, if you declare a variable inside a block {}, it will be accessible just inside it, so when you declared it into the if-else if blocks, you couldn't access to the variable outside.
Also to compare a primitive type (in this case double) you have to use == operator, because = is used for assignment.
double g;
if (a<b) {
g = 1;
}
else if (a>b) {
g = 0;
}
// What happen if 'a = b'?
if (g == 1) {
System.out.print("true");
}
else {
System.out.print("false");
}
Note: What value will take g if a == b? You may want to take care about that case too.
double g;
if (a<b) {
g=1
}
else if (a>b) {
g=0
}
if (g==1) {
System.out.print("true");
}
else {
System.out.print("false");
}
also make sure that you always use == instead of = in your if-statement
The if condition if (g=1) does not work with java. This would work with C though.
You should code if (g==1) to test if g is in fact equal to the int value 1.
You've got three problems.
a and b aren't defined. Define them before entering the if statement.
Define g outside of the if statement (a simple double g; will suffice), then set the values as part of your conditional logic. You do have to give it a default value if you intend to keep the else if there, since Java would complain about that not being defined.
g=1 isn't going to work the way you think it should; you probably mean g == 1.
With else if
int a, b; // assumed instantiated with values
double g = -1; // required since Java can't guarantee that the else-if will be hit
if (a<b) {
g = 1;
} else if (a>b) {
g = 0;
}
With else
int a, b; // assumed instantiated with values
double g; // instantiation not required since Java can guarantee the else case
if (a<b) {
g = 1;
} else {
g = 0;
}
double g; double a = 4.0; double b = 3.0;
if(a < b){
g = 1.0;
System.out.print("true");
}
else if (a > b){
g = 0.0;
System.out.print("false");
}
// Why not write your code like the above example. It seems like the
//same operations are executed but with less lines of code.
When compiled this static method comes up with the error that the int array variable, coord, cannot be found. I declared it within the method and it is of the type int[] and I can't figure out why it won't work. I have a feeling that it has to do with the method being static, but changing it to static was the only way I found to make that method work in the first place.
I feel like this is probably really simple for anybody but me especially when all I could find on this subject were much more complicated coding issues.
In case this helps.. this method is supposed to return the (x,y) coordinates for a move location. Sorry for probably not inputting the code correctly. First time doing this. Thanks in advance for any help
CODE:
public static int[] getMove(String player)
{
boolean done = false;
while(!done)
{
Scanner in = new Scanner(System.in);
System.out.println("Input row for " + player);
int x = in.nextInt() - 1;
System.out.println("Input column for " + player);
int y = in.nextInt() - 1;
int[] coord = {x,y};
if(getLoc(coord[0], coord[1]).equals("x") || getLoc(coord[0], coord[1]).equals("o") || coord[0] < 0 || coord[0] > ROWS || coord[1] < 0 || coord[1] > COLUMNS)
{
System.out.println("Invalid coordinates... please retry");
}
else
{
done = true;
}
}
return coord;
}
What you are missing is the scope of the variable. A variable declared in parent block is accessible in child blocks, but not the other way around.
public void someMethod()
{
int x=1;
while(x<10)
{
x++; //x is accessible here, as it is defined in parent block.
int j = 0; //This variable is local to while loop and will cause error if used inside method
j++;
}
System.out.println(j);// The outer block does not know about the variable j!!
}
Now in your case,
Notice where you have defined coors, and in what all places you are using it.
Try to figure where should you define coors variable.
That is because the array coord is local to the while loop. And therefore its not visible outside its scope. Move the declaration of coord outside the while and it should work.
int[] coord = new int[2];
while(!done){
...
...
coord[0] = x;
coord[1] = y;
...
}
In my current project I have an ArrayList of PVectors that store xyz coordinates for 3d points. I'm passing the ArrayList to another class that manipulates it, however, I'm getting a NullPointerException when doing so. I'm assuming that one of the PVectors is null, but I checked for this by assigning any null objects to (0,0,0) and I'm still getting the error. Also, is it more effecient to have an array of PVectors or an ArrayList of PVectors? Either way I'm still getting the error. Here is the line that produces it.
trip.pass(pointCoordinates);
And here is the main class
import org.openkinect.*;
import org.openkinect.processing.*;
Kinect kinect;
Trip trip;
boolean tripOn;
int w = 640;
int h = 480;
int distance = 5;
float[] depthLookUp = new float[2048];
ArrayList pointCoordinates = new ArrayList();
float factor = 400;
float a = 0;
float angle = 0;
float frequency = .05;
void setup() {
size(800,600,P3D);
kinect = new Kinect(this);
kinect.start();
kinect.enableDepth(true);
kinect.processDepthImage(false);
stroke(255);
for (int i = 0; i < depthLookUp.length; i++) {
depthLookUp[i] = rawDepthToMeters(i);
}
for(int i = 0; i < 31920; i++) {
pointCoordinates.add(new PVector(0, 0, 0));
}
}
void draw() {
background(0);
pushMatrix();
translate(width/2 + width/3,height/2, -200);
//add 1/3 width to account for rule of thirds
popMatrix();
int[] depth = kinect.getRawDepth();
calculate(depth);
if(!tripOn) {
for(int i = 0; i < pointCoordinates.size(); i++) {
PVector temp = (PVector) pointCoordinates.get(i);
point(temp.x, temp.y, temp.z);
}
}
if(frameCount % 10 == 0) {
if(tripOn) {
tripOn = false;
trip.clear();
}
else {
tripOn = true;
trip.pass(pointCoordinates);
}
}
if(tripOn) trip.run();
}
void stop() {
kinect.quit();
super.stop();
}
I can paste more classes if it helps to clarify the problem. Thanks!
You are not initializing your "trip" variable and therefore a call to trip.pass(..) would throw the NullPointerException.
You never seem to assign a value to the variable trip. That would certainly cause a NullPointerException at the line that you've shown.
From your code snippet its hard to get the source of your problem. But my first guess is a threading issue.
You are trying to use the trip.pass(pointCoordinates); in a worker thread. Although it appears that ArrayList pointCoordinates = new ArrayList(); is not part of that thread.
A possible solution could be:
check whether the pointCoordinates is initialized or not. If not then wait for it to get initialized.
Update
My bad. I have missed out the initialization of the trip object. :(
My +1 to Dan Breslau and jerluc