Making a pacman and having a hard time with collisions

edited August 2017 in Questions about Code

Hello, I started a few months ago using processing and I'm also new to OOP. Now I'm doing a pacman, still have to code the ghosts and the pacman's food but I'm having problems with the walls. I've tried looking at other pacman codes so I know there are many ways to check collisions but I can't make it work on my code. I've also checked the jeffreythompson.org web but I still have problems. To make it short I would like to know, how do I check the collisions? where is a the "right" place to check the collisions, map or pac? And since I'm new to code, if my logic or format is not good and wanna point that out, I'll be happy to learn. Thanks!

The map1 class

class map1 {
  int SIDE = 30; //How big is the rectangle (30x30)
  PImage tile;
  char[][] map = {
  //Where X is a rectangle will be drawn. 
  //1,2,3 and 4 are for portals (which I didn't code yet). 
  //The A is an empty spot, seems like I can't leave the array empty so I filled it with A

    {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '2', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', 'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', ' ', ' ', ' ', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', 'X', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}, 
    {'X', ' ', ' ', ' ', 'X', 'X', ' ', 'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', ' ', 'X', 'X', ' ', ' ', ' ', 'P', 'x', 'x', 'x', 'x', 'x', 'p'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', ' ', ' ', 'X', 'X', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'x', 'x', 'x', 'x', 'x', 'X', 'X', ' ', ' ', ' ', ' ', ' ', 'X', 'X', ' ', ' ', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', 'X', ' ', ' ', 'X', 'X', 'X', 'x', 'X', 'X', 'X', ' ', ' ', 'X', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X', 'X', 'X', 'X', 'X', 'X', 'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', ' ', ' ', 'X', 'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', 'X', ' ', ' ', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', ' ', ' ', 'X', ' ', ' ', 'X', ' ', ' ', ' ', 'X', ' ', 'X', 'X', ' ', 'X', 'X', ' ', 'X', ' ', ' ', ' ', 'X', ' ', ' ', 'X', ' ', ' ', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', ' ', ' ', ' ', 'X', 'X', 'X', ' ', 'X', ' ', ' ', ' ', 'X', ' ', 'X', 'X', 'X', ' ', ' ', ' ', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', 'X', 'X', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ', 'X', 'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', ' ', 'X', ' ', 'X', 'X', 'X', 'X', ' ', 'X', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', 'X', ' ', 'X', 'X', 'X', 'X', ' ', 'X', ' ', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', '3', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'X', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '4', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'A', 'A', 'A', 'A', 'A', 'A'} };

  map1() {

    tile = loadImage("tile.jpg");
  }

  void display() {

    for (int i = 0; i<23; i++) {

      for (int j = 0; j<37; j++) { 

        if (map[i][j]=='X') { 

          image(tile, j*SIDE, i*SIDE); 
        }
      }
    }
  }
}

Pac class

class pac {

  int x, y, R, speed = 2;
  String TOUP, TODOWN, TOLEFT, TORIGHT, direction = "TORIGHT";

  pac() {
    x = 465;
    y = 405;
    R = 15; 
  }

  void display() {

    ellipse(x,y,R*2,R*2);
  }

  void move() {

    switch (direction) {

      case "TORIGHT":
          x+=speed;
      break;
      case "TOLEFT":
          x-=speed;
      break;
      case "TOUP":
          y-=speed;
      break;
      case "TODOWN":
          y+=speed;
      break;
      case "NOMOVE":
          //Stop moving if hits a wall
      break;      
    }

    if (keyCode == LEFT) {
      direction = "TOLEFT";
    }
    if (keyCode == RIGHT) {
      direction = "TORIGHT";
    }
    if (keyCode == DOWN) {
      direction = "TODOWN";
    }
    if (keyCode == UP) {
      direction = "TOUP";
    }

  }

  void collision() {


  }

}

How the game looks so far if helps, don't pay attention to the numbers, I was just trying to make collisions work.

Answers

  • edited August 2017

    the x and y varibles in the pac map to a column and a row on the map array, correct?

    if that's the case, the tiles adjacent the the pac would be, for example:

    map[ pacman.x + 1] [ pacman.y ]
    

    that's the tile to the right of the pac. and then you can check the tiles, you already know how to do that!

    does that help?

  • where is a the "right" place to check the collisions, map or pac?

    I would say map. It is the natural place to check. The character pac knows nothing about the universe. Map knows everything about the universe (where the walls are AND where pacman is allowed to be). Then, the natural way would be for the instance of pac to ask the instance to map if its next position is an allowed position.

    Kf

  • {'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'A', 'A', 'A', 'A', 'A', 'A'}, 
    

    you can use a String array and charAt() to save you typing all those 's

    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAA"
    

    but i guess it's a bit late now 8)

    i've also used a tiny png before, one pixel per grid position, different colours for each type of tile.

  • The nice things about a String array in the code is that you can see it much more easily. Doesn't really matter, but aesthetically pleasing.

    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAA
    X1            XXX            2XAAAAAA
    X X XXXXX XXX XXX XXX XXXXX X XAAAAAA
    X X            X            X XAAAAAA
    X X XXX X XX X   X XX X XXX X XAAAAAA
    X X     X XX XXXXX XX X     X XXXXXXX
    X   XX XX             XX XX   Pxxxxxp
    X X XX XX X XXX XXX X XX XX X XXXXXXX
    X X XX XX X XXX XXX X XX XX X XAAAAAA
    X X                         X XAAAAAA
    X X XX XXX XXXXXXXXX XXX XX X XAAAAAA
    X   XX     XXxxxxxXX     XX   XAAAAAA
    X X XX XXX  XXXxXXX  XXX XX X XAAAAAA
    X X      XX         XX      X XAAAAAA
    X X X XX XX XXXXXXX XX XX X X XAAAAAA
    X X   XX X           X XX   X XAAAAAA
    X   X  X   X XX XX X   X  X   XAAAAAA
    X X XX   XXX X   X XXX   XX X XAAAAAA
    X X XXXX     X X X     XXXX X XAAAAAA
    X X      XXX   X   XXX      X XAAAAAA
    X X XXXX XXXX XXX XXXX XXXX X XAAAAAA
    X3            XXX            4XAAAAAA
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAA
    
  • @kfrajer Ohh I see, thank you very much :) .

  • @koogs I didn't know about charAt() thank you, but yeah, there's too much to change now but I'll consider that next time.

    i've also used a tiny png before, one pixel per grid position, different colours for each type of tile.

    I saw something like that in some old pacman code (in processing) I found, I think that might be easier, but I wanna try checking the collisions like this if possible.

  • @Introscopia

    the x and y varibles in the pac map to a column and a row on the map array, correct?

    The Pac x and y values are the x and y of the sketch, if I make the pac move between positions like the char array, the pac would jump 30 pixles and that's not how the pacman actually moves. I will try to check collisions again and show you the code so that may give an idea of what I'm doing wrong/what I want.

  • well it's a simple matter of converting from pixels to map grid positions, then! If the the edge of the tile is 30px like you said, then the floor of the coordinate divided by 30 gives you the tile the pac is in, and then you can still use the basic logic that I showed you!

  • I think introscopia's approach is generally right - even if you're animating the pacman on a scale smaller than the block size you need to check the walls before starting the move.

  • An example of tile scroll, which 1st checks whether it's allowed to move: :D
    http://Studio.ProcessingTogether.com/sp/pad/export/ro.9Ql2E8JBC54LJ

Sign In or Register to comment.