Create 2D game map with images

A Bomberman level can be considered a grid, of three types, each represented by a 16x16 pixel size image: the ground (ground.png), the destructible blocks (softBlock.png) and indestructible blocks (hardBlock.png).
The design of a level is shown in a csv file (level.csv), where
x represents indestructible blocks

  • represents the destructible blocks
    The lack of character represents the soil
    Any other character may be, at this stage, considered to be soil
    So you have to read the file and display correctly the level it represents

So I started by loading the csv file with loadStrings(), but now I dont know what to do? How can i put the Strings to have a grid, how can I make processing understand where to start ?

Thank you !

I would enumerate the different ground types, and then create a 16 by 16 array of ints that will store the current state of the game world in it.

Initially, you will want to parse the array of strings you have, to populate the game world array. The first string in your array of strings represents what’s in the top row of the game world.

You can thus use one loop to look at each character in your first string. If it is the character for ground, store a 0 at the right spot in your 16 x 16 array of ints. If it is the symbol for a soft wall, store a 1. If it is a hard wall symbol, store a 2.

Then add a second loop so you’re looking not just at the first row’s string, but all the strings!

Your code will look something like this:

int[][] level = new int[16][16];


void setup(){
  // size(); ??? etc
  String[] strings = loadStrings("whatever.csv");
  
  for( ???; ???; ??? ){
    for( ???; ???; ??? ){
      // Default case, soil?
      level[?][?] = 0;
      if( strings[?].charAt(?) == '?' ){ // Soft walls?
        level[?][?] = ?;
      }
      if( strings[?].charAt(?) == '?' ){  // Hard walls?
        level[?][?] = ?;
      }
    }
  }
}

Then you can use the numbers in that array when you draw your images in draw(). (And if you also store your images in an array, you can use the numbers in your level array as an index into your images array!)

Thank you for your answer,

int[][] level = new int[50][50];
PImage softBlock;
PImage hardBlock;
PImage floor;

void setup(){
  size(800,500);
  String[] lignes = loadStrings("level.csv");
   softBlock = loadImage( "softBlock.png");
  hardBlock = loadImage( "hardBlock.png");
  floor = loadImage("floor.png");
  
  for(int n=0; n<lignes.length; n++){
    for(int i=0; i<lignes[n].length(); i++){
      //floor
        level[n][i] = 0;
      if( lignes[n].charAt(i) == '-' ){ // Soft walls
        level[n][i] = 1;
      }
      if( lignes[n].charAt(i) == 'x' ){  // Hard walls
        level[n][i] = 2;
      }
       print(level[n][i]);
    }
   
  }
  

}

void draw(){
  
  for(int x=0;x<level.length;x++){
    for(int y=0;y<level[x].length;y++){
      if (level[x][y]==1){
          image(softBlock,y*16,x*16);
        }
        else if (level[x][y]==2){
          image(hardBlock,y*16,x*16);
        }else if (level[x][y]==0){
          image(floor,y*16,x*16);
        }
    
    
  }
  
}

}

This is what I did I have now a map but the problem is that it isnt in the right position and i cant find what i did wrong the blocks, I dont know if it is from the way i stored my data in the 2d array or from the way I position my images in draw().

i am getting this :
Capture

the order isnt right

I should get this instead

It’s good that you have images of different block types appearing! This is a total step in the right direction.

But you need to debug your code now. Perhaps it would be useful to display the values of X, Y and level[x][y] at each block’s location, instead of the blocks, for now.

Try this in draw():

background(100,0,0);
  for(int x=0;x<level.length;x++){
    for(int y=0;y<level[x].length;y++){
      text( "" + x + " " + y + " " + level[x][y], y*16,x*16 );
  }
}

Does what you see match up with what println() displayed when it printed out the level’s numbers?

1 Like

Thank you for your help :slight_smile:

And no it doesnt I think the problem is in the way I am reading my file csv, the values i am getting are different from the one in the csv file.

caaaaaaaaaaa

i found the problem its because of the ‘,’ the values arent in order how can i remove them or avoid them

Fantastic! That’s a great bug to have worked out.

Instead of parsing the string character by character, what you should do now is use split() on each string. This should give you an array of strings, some of which may be empty.

For example,

String[] csv_data = loadStrings("file.csv");
for(  ? ? ? ){ // For each line,
  String[] line = csv_data.split(','); // Split it based on commas.
  for( ? ? ? ){ // For each string in the line array,
    if( line[?].charAt[0] == 'x' ){
       level_data[?][?] = 1;
    } /// etc
  }
}

This will deal with the commas properly. You don’t want to just remove or ignore them, because two commas next to each other still has a meaning - that there is ground there!

Okay Thank you I will check it, but doesnt split return one line of string ? so in that case i will lose my lines

split() works on one string, and splits it into an array of strings that were separated by the given character. You can search for it in the Reference to see how it works.

map

it worked with split !! but now how can i fit the whole map in the window, so it has the exact size of the window ?

make the window smaller or the grid bigger

or the images bigger

Okay thank you,

Should i use scale to make the images bigger ?

Your blocks are 16 pixels square, right? How big is your level? You can just change size() to have the right size for your level.

Or you can stretch the blocks to fit. But that might not look right. You could just try to double their size. Put scale(2); in draw(). But that might cut some of the level off. You should probably do this and also make your window the right size.

Thank you ! it worked I used scale and changed the size() and it is all good now !

thank you so much for ur help, I learned alot from this :slight_smile:

1 Like

Great! Can you post your completed code so others can see how it works?

1 Like

sure when i finish the whole project i will post the complete code, I am now trying to make my character move in this maze, any ideas on how to prevent it to move through walls ?

When a character is going to move, first check if where it’s moving to is a valid place for it to be. If it’s not, don’t move there! It’s as simple as adding an if statement.

class Player {
  int x, y;
  /// ...
  void move(int dx, int dy){
    // Prevent movement into solid walls.
    if( is_solid( level_data[x+dx][y+dy] ) ) return;
    // Do movement.
    x += dx;
    y += dy;
  }
  boolean is_solid( int wall_type ){
    return( wall_type == 1 || wall_type == 2 );
  }
}

You might also need to add some logic to check that the position you are moving to is inside your grid too. For example, if your player is in the top left, (0,0), and trieds to move left, you don’t want to try to access level_data[-1][0]!

dx and dy is the position of the person when he moves?

Hi @oussama10 ,

Looks like dx and dy represent how much the Player is going to move. It’s common to use the letter d (for difference) to talk about a small change :wink:

Those values will be added to the player’s location respectively x and y for example :

player.move(1, 0); // Move the player by 1 column