How to put an array of images inside a function?

As I said, before setup() you need to define

// constants for movementType 
final int typeRunLeft    = 0;   // must be UINQUE numbers 
final int typeRunRight  = 1;
final int typeLeftIdle     = 2;
final int typeLeftRight  = 3;

and whatever variable (constant in this case) you want to use.

1 Like

THANK YOU! It took many frustrated days, but I got it! It can now jump, land, stand idle, walk right and walk left. Thanks for all your help, it helped a lot a lot! I’m incredibly grateful.

1 Like

Great!

You can post the result here, so we can take a look.

Chrisir

Alright, I take it back. It turns out there are some bugs when I run the code that is “neater”.

So for comparison, the code that works better but is messier:

Note:

  1. Some of your suggestions I don’t implement (like the one about the movementType), because it’ll take a bit too much time. I’m really really sorry, I’m under a time limit to finish this in a month or so, and I just really need this to run.
  2. I added a new class flame, which is basically a sprite or pet that follows the boy (player) around.
class Flame {
  PImage [] flame = new PImage [8];
  int NumofImagesFlame = 8;
  int x, y;
}

class Boy {
  PImage idle;
  PImage idleleft;  
  PImage [] run = new PImage [4];
  PImage [] runleft = new PImage [4];
  int NumofImages = 8;
  PImage jump; 
  PImage jumpleft;
  int x, y;          //boy position
  int xspd, yspd;    //boy speed
}

Boy b;
Flame f;
int currentImageNumFlame;
int currentImageNum;  
int ground;
int gravity = 5;
int movementType;
int up;

void setup ()
{
  size (1280, 720);
  smooth ();
  noCursor ();
  frameRate (8);

  b = new Boy ();
  f = new Flame ();

  //standing
  b.idle = loadImage ("idle.png");
  b.idle.resize (100, 100);

  //standing left
  b.idleleft = loadImage ("idleleft.png");
  b.idleleft.resize (100, 100);

  //running
  for (int i = 0; i < b.run.length; i++) {
    b.run[i] = loadImage("run"+str(i)+".png");
    b.run[i].resize (100, 100);
  }
  currentImageNum = 0;

  //running left
  for (int i = 0; i < b.runleft.length; i++) {
    b.runleft[i] = loadImage("runleft"+str(i)+".png");
    b.runleft[i].resize (100, 100);
  }
  currentImageNum = 0;

  //jumping
  b.jump = loadImage ("jump.png");
  b.jump.resize (100, 100);

  //jumping left
  b.jumpleft = loadImage ("jumpleft.png");
  b.jumpleft.resize (100, 100);

  //flame
  for (int i = 0; i < f.flame.length; i++) {
    f.flame[i] = loadImage("flame"+str(i)+".png"); 
    f.flame[i].resize (100, 100);
  }
  currentImageNum = 0;

  ground = height/2;

  b.x = width/2 - 25;
  b.y = height/2;
  b.xspd = 0;
  b.yspd = 0;

  f.x = b.x + 50;
  f.y = b.y - 20;
}

void draw ()
{ 
  background (0);
  moveb ();
  moveflame ();
}

void moveb () {

  //idle
  if (movementType == 0) {                      //idle right
    image (b.idle, b.x, b.y);
  } else if (movementType == 1) {               //idle left
    image (b.idleleft, b.x, b.y);  

    //run
  } else if (movementType == 2) {               //run right
    image (b.run [currentImageNum], b.x, b.y);
    currentImageNum++;
    if (currentImageNum >= b.run.length) {
      currentImageNum = 0;
    }
  } else if (movementType == 3) {               //run left
    image (b.runleft [currentImageNum], b.x, b.y);
    currentImageNum++;
    if (currentImageNum >= b.runleft.length) {
      currentImageNum = 0;
    }

    //jump
  } else if (movementType == 4) {               //jump right
    image (b.jump, b.x, b.y);
    //jump left
  } else if (movementType == 5) {               //jump left
    image (b.jumpleft, b.x, b.y);
  }

  b.y = b.y + b.yspd;

  //if boy is above ground, apply gravity (reminder that - is up)
  if (b.y < ground) {
    b.yspd = b.yspd + gravity;
  } 

  //if boy is on the ground and up key is pressed, jump!
  if (b.y >= ground &&  up != 0) {
    b.yspd = -13;
  }
  if (b.y >= ground && b.yspd >= 0) {
    b.yspd = 0;
    b.y = ground;
  }

//flame position here instead of in flame class to make a lagging effect when following the prince
  f.x = b.x + 50;
  f.y = b.y - 20;
}

void moveflame () {             
  image (f.flame [currentImageNumFlame], f.x, f.y);
  currentImageNumFlame++;
  if (currentImageNumFlame >= f.flame.length) {
    currentImageNumFlame = 0;
  }
}


//keyboard movements
void keyPressed() {
  if (key == CODED) {
    if (keyCode == LEFT) {
      movementType = 3;
    } else if (keyCode == RIGHT) {
      movementType = 2;
    } else if (keyCode == UP) {
      if (movementType == 0 || movementType == 2) {
        movementType = 4;
        up = 1;
      } else if (movementType == 1 || movementType == 3) {
        movementType = 5;
        up = 1;
      }
    }
  }
}

void keyReleased() {
  if (key == CODED) {
    if (keyCode == RIGHT) {
      movementType = 0;
    } else if (keyCode == LEFT) {
      movementType = 1;
    } else if (keyCode == UP) {
      if (movementType == 4) {
        movementType = 0;
        up = 0;
      } else if (movementType == 5) {
        movementType = 1;
        up = 0;
      }
    }
  }
}

The one I attempted to “tidy”:

Boy b;
Flame f;
int currentImageNumFlame;
int currentImageNum;  
int ground;
int gravity = 5;
int movementType;
int up;

void setup ()
{
  size (1280, 720);
  smooth ();
  noCursor ();
  frameRate (8);

  b = new Boy ();
  f = new Flame ();

  f.flamex = b.x + 50; 
  f.flamey = b.y - 20;
}

void draw ()
{ 
  background (0);
  b.moveboy ();
  f.moveflame ();
}


//keyboard movements
void keyPressed() {
  if (key == CODED) {
    if (keyCode == LEFT) {
      movementType = 3;
    } else if (keyCode == RIGHT) {
      movementType = 2;
    } else if (keyCode == UP) {
      if (movementType == 0 || movementType == 2) {
        movementType = 4;
        up = 1;
      } else if (movementType == 1 || movementType == 3) {
        movementType = 5;
        up = 1;
      }
    }
  }
}

void keyReleased() {
  if (key == CODED) {
    if (keyCode == RIGHT) {
      movementType = 0;
    } else if (keyCode == LEFT) {
      movementType = 1;
    } else if (keyCode == UP) {
      if (movementType == 4) {
        movementType = 0;
        up = 0;
      } else if (movementType == 5) {
        movementType = 1;
        up = 0;
      }
    }
  }
}

class Boy {
  PImage idle;
  PImage idleleft;  
  PImage [] run = new PImage [4];
  PImage [] runleft = new PImage [4];
  int NumofImages = 8;
  PImage jump; 
  PImage jumpleft;
  int x, y;          //boy position
  int xspd, yspd;    //boy speed

    Boy () {

    //standing
    idle = loadImage ("idle.png");
    idle.resize (100, 100);

    //standing left
    idleleft = loadImage ("idleleft.png");
    idleleft.resize (100, 100);

    //running
    for (int i = 0; i < run.length; i++) {
      run[i] = loadImage("run"+str(i)+".png");
      run[i].resize (100, 100);
    }
    currentImageNum = 0;

    //running left
    for (int i = 0; i < runleft.length; i++) {
      runleft[i] = loadImage("runleft"+str(i)+".png");
      runleft[i].resize (100, 100);
    }
    currentImageNum = 0;

    //jumping
    jump = loadImage ("jump.png");
    jump.resize (100, 100);

    //jumping left
    jumpleft = loadImage ("jumpleft.png");
    jumpleft.resize (100, 100);

    ground = height/2;

    x = width/2 - 25;
    y = height/2;
    xspd = 0;
    yspd = 0;

    moveboy ();
  }

  void moveboy () {

    //idle
    if (movementType == 0) {                      //idle right
      image (idle, x, y);
    } else if (movementType == 1) {               //idle left
      image (idleleft, x, y);  

      //run
    } else if (movementType == 2) {               //run right
      image (run [currentImageNum], x, y);
      currentImageNum++;
      if (currentImageNum >= run.length) {
        currentImageNum = 0;
      }
    } else if (movementType == 3) {               //run left
      image (runleft [currentImageNum], x, y);
      currentImageNum++;
      if (currentImageNum >= runleft.length) {
        currentImageNum = 0;
      }

      //jump
    } else if (movementType == 4) {               //jump right
      image (jump, x, y);
      //jump left
    } else if (movementType == 5) {               //jump left
      image (jumpleft, x, y);
    }

    y = y + yspd;

    //if boy is above ground, apply gravity (reminder that - is up)
    if (y < ground) {
      yspd = yspd + gravity;
    } 

    //if boy is on the ground and up key is pressed, jump!
    if (y >= ground &&  up != 0) {
      yspd = -13;
    }
    if (y >= ground && yspd >= 0) {
      yspd = 0;
      y = ground;
    }
  }
}

class Flame {
  PImage [] flame = new PImage [8];
  int NumofImagesFlame = 8;
  int flamex, flamey;

  Flame () {          

    //flame
    for (int i = 0; i < flame.length; i++) {
      flame[i] = loadImage("flame"+str(i)+".png"); 
      flame[i].resize (100, 100);
    }
    moveflame ();
  }

  void moveflame () {
    currentImageNum = 0;  
    image (flame [currentImageNumFlame], flamex, flamey);
    currentImageNumFlame++;
    if (currentImageNumFlame >= flame.length) {
      currentImageNumFlame = 0;

      flamex = b.x + 50; 
      flamey = b.y - 20;
    }
  }
}

It runs fine, but some bugs:

  1. The flame doesn’t follow the boy around, but ‘teleports’ a bit. While in the first code it follows the boy around with a little lag, which is exactly what I want.
  2. The boy can’t run - the run array stops at the first frame.

But either way, the first code works fine. Thank you so much for all this!

1 Like

In the 2nd code

Is in moveFlame

BUT since it’s a global variable (and not in the boy class as it should) we set it to 0 every time and therefore the boy can’t run

1 Like

Oh got it, thank you! Fixed!

Can you help me with the flame, too? I can’t figure out why in the first, messier one, the flame appears to jump up and down with a little lag when the boy jumps, which is absolutely perfect. But in the second one, it just “teleports” (it moves position once when the boy lands, and moves when the boy reaches the top, same).

Thank you again, as always!

1 Like

The process of finding and eliminating errors is called debugging.

It’s an art.

There is a debugger in processing.

But you can see debugging also as proofreading.

In your case the flame position is not behaving as it should. You could start by comparing the two versions. Where are the differences? Then you can check the sections in the code where you set the flame position (sections in connections with the boy position).

Somehow the boy position gets (not) copied into the flame position. Your proofreading should concentrate on these sections.

Chrisir

1 Like

Thanks! Dang, phrasing it like that helps a lot. It seems obvious looking back, but still.

Yeah, I figured that the problem is that the boy position is copied to the flame position after they’ve settled instead of immediately, so I need a way to put them in the same place. I’ve tried some things I thought of, and if I document it fully:

  1. Putting the flame position in the boy class (f.flamex = x + xspd and such)
    Result: Null Pointer Exception
  2. Putting the boy position in flame class (flamex = b.x + b.xspd and such)
    Result: same
  3. Putting both their positions in a separate class (void moveall ())
    Result: there’s an unexpected token
  4. What works: Putting them both in the regular void draw (f.flamex = b.x + b.y)

So yay, solved! Thanks so much!

1 Like