Making of: Snake with classes

Yeah, it’s me another time!
I’m about in making a mimi-game based on the famous Snake, and it works using a lot of different things: I used a class called Snake to make a dynamic array of objects which represents the snake itself, and then another class called Fruit in which I save all the data about the fruits the snake is going to eat. (And, as you will see, it won’t be only the classical red apple, but some extra features I wanted to add, they’re not already applied in the code but I’ve got the idea in my head).
The game is compiled perfectly, not a single error in any of the files I have (one for each class and the game itself, with the rules and the functions for it to work); but when I’m about to run it, it gets in a NullPointerException failure, overlaying line 13 in the fruitClass file and it doesn’t work… anyone so kind to explain me why? Thanks!

Here are the files:

snakeClass

static class Snake {

  public int x, pX;
  public int y, pY;

  enum sDir {
    Up, Left, Down, Right, Stop
  }
}

void sSave() {

  for (int a=0; a<nPieces.size(); a++) {
    nPieces.get(a).pX=nPieces.get(a).x;
    nPieces.get(a).pY=nPieces.get(a).y;
  }
}

void sRestore() {

  for (int a=0; a<nPieces.size(); a++) {
    nPieces.get(a).x=nPieces.get(a).pX;
    nPieces.get(a).y=nPieces.get(a).pY;
  }
}

fruitClass

static class Fruit {

  public float x, y;
  public float chance;

  enum fruitType {
    redApple, goldApple, blueBerry
  }
}

void fSpawn() {

  f.x=(int)random(0, width/10)*10;
  f.y=(int)random(0, height/10)*10;
}

void fTypeGen() {

  f.chance=(int)random(0, 100);
  if (f.chance<=80) fType=Fruit.fruitType.redApple;
  else if (f.chance>80 && f.chance<=90) fType=Fruit.fruitType.goldApple;
  else if (f.chance>90 && f.chance<=100) fType=Fruit.fruitType.blueBerry;
}

gameLogic


static int dimStart=7;
int dim=dimStart;
ArrayList<Snake> nPieces;
Fruit f;
Snake.sDir dir=Snake.sDir.Stop;
Fruit.fruitType fType;

public void settings() {

  size(600, 600);
}

void sMove() {

  if (!keyPressed)
    switch(key) {
    case 'w':
      dir=Snake.sDir.Up;
      break;
    case 'a':
      dir=Snake.sDir.Left;
      break;
    case 's':
      dir=Snake.sDir.Down;
      break;
    case 'd':
      dir=Snake.sDir.Right;
      break;
    }

  switch(dir) {
  case Up:
    nPieces.get(0).y-=10;
    break;
  case Left:
    nPieces.get(0).x-=10;
    break;
  case Down:
    nPieces.get(0).y+=10;
    break;
  case Right:
    nPieces.get(0).x+=10;
    break;
  }
}

void logic() {

  sMove();
  sSave();
  for (int a=1; a<nPieces.size(); a++) {
    
    if (dir==Snake.sDir.Up) {
      if (nPieces.get(a-1).y!=nPieces.get(a).y && nPieces.get(a).x==nPieces.get(a-1).x)
        if (nPieces.get(a-1).y>nPieces.get(a).y) nPieces.get(a).pY+=10;
        else nPieces.get(a).pY-=10;
      else if (nPieces.get(a-1).x!=nPieces.get(a).x)
        if (nPieces.get(a-1).x>nPieces.get(a).x) nPieces.get(a).pX+=10;
        else nPieces.get(a).pX-=10;
        
    } else if (dir==Snake.sDir.Down) {
      if (nPieces.get(a-1).y!=nPieces.get(a).y && nPieces.get(a).x==nPieces.get(a-1).x)
        if (nPieces.get(a-1).y>nPieces.get(a).y) nPieces.get(a).pY+=10;
        else nPieces.get(a).pY-=10;
      else if (nPieces.get(a-1).x!=nPieces.get(a).x)
        if (nPieces.get(a-1).x>nPieces.get(a).x) nPieces.get(a).pX+=10;
        else nPieces.get(a).pX-=10;
        
    } else if (dir==Snake.sDir.Left) {
      if (nPieces.get(a-1).x!=nPieces.get(a).x && nPieces.get(a).y==nPieces.get(a-1).y)
        if (nPieces.get(a-1).x>nPieces.get(a).x) nPieces.get(a).pX+=10;
        else nPieces.get(a).pX-=10;
      else if (nPieces.get(a-1).y!=nPieces.get(a).y)
        if (nPieces.get(a-1).y>nPieces.get(a).y) nPieces.get(a).pY+=10;
        else nPieces.get(a).pY-=10;
        
    } else if (dir==Snake.sDir.Right) {
      if (nPieces.get(a-1).x!=nPieces.get(a).x && nPieces.get(a).y==nPieces.get(a-1).y)
        if (nPieces.get(a-1).x>nPieces.get(a).x) nPieces.get(a).pX+=10;
        else nPieces.get(a).pX-=10;
      else if (nPieces.get(a-1).y!=nPieces.get(a).y)
        if (nPieces.get(a-1).y>nPieces.get(a).y) nPieces.get(a).pY+=10;
        else nPieces.get(a).pY-=10;
    }

    if (nPieces.get(a).x==f.x && nPieces.get(a).y==f.y) {
      fSpawn();
      fTypeGen();
      dim++;
      nPieces.add(new Snake());
    }
  }
  sRestore();
  dir=Snake.sDir.Stop;
}

void setup() {

  frameRate(25);
  nPieces=new ArrayList<Snake>(dimStart);
  fSpawn();
  fTypeGen();

  for (int a=0; a<dimStart; a++) {
    nPieces.add(new Snake());
    nPieces.get(a).x=0;
    nPieces.get(a).y=0;
  }
  nPieces.get(0).x=width/2;
  nPieces.get(0).y=height/2;

  for (int a=1; a<nPieces.size(); a++) {
    nPieces.get(a).x=nPieces.get(a-1).x-10;
    nPieces.get(a).y=nPieces.get(a-1).y;
  }
}

void draw() {

  logic();
  background(0);
  fill(255);
  
  for (int a=0; a<width; a+=10)
    for (int b=0; b<height; b+=10)
      if (a==0 || a==width-10 || b==0 || b==height-10) rect(a, b, 10, 10);
      
  for (int a=0; a<nPieces.size(); a++) {
    if (a==0) fill(0, 130, 0);
    else fill(0, 255, 0);
    rect(nPieces.get(a).x, nPieces.get(a).y, 10, 10);
  }
  
  if (fType==Fruit.fruitType.redApple) fill(255, 0, 0);
  else if (fType==Fruit.fruitType.goldApple) fill(255, 255, 0);
  else if (fType==Fruit.fruitType.blueBerry) fill(0, 70, 255);
  rect(f.x, f.y, 10, 10);
}

PS I’m completely aware that there’s probably some easier way to do it, in a faster and smarter and more elegant and more whatever-you-want way, but I started programming with Processing at school about a month ago and I’m not very talented with Java and Processing (even if I’m the best student in my class with this stuff…), so please don’t use advanced constructs to fix the errors and explain in a clear way what you’re doing like you’re trying to explain it to a little baby… it would be really helpful for me! Thanks another time!

I actually forgot to declare the f variable with the line

f=new Fruit();

so I don’t need help anymore… sorry!

2 Likes