The vector of booleans may work. And I think check the tile below the player character every frame is perfectly valid solution until you get to a point in your project where that does not work any more. For most games that may never happen.
A more evolved version is what I'm doing in my latest HTML5 canvas experiment to find the right collision method to use in a game I want to create.
My levels are also in tiles of same size and always aligned, only character and enemies may not be tile aligned.
I represent the level as a string constant, soon functionality to load from text file will be added. For example:
// First line
var level = " x x ";
// Then we check the width of the level by checking numbers of characters
var level_width = level.lenght;
// Then we add the next of the level. Note we are adding more characters not replacing.
var level += " aaaa aaaaaaaaa aaaa aaaaa" +
" aaaaaaaaaaaaaa aaaa aaaaa" +
" aaaaaaaaaaaaaa aaaa aaaaa" +
" " +
" bbbbbbbbbb bbbbbbb bbbbbbbb ";
// Now we calculate the height of the level
var level_height = level.length / level_width;
I have to calculate the level rectangle because I'm using a raw format to represent the level but you can use end of line characters (\n) to know where a line ends and avoid these calculations.
Meaning of characters:
x: enemies. Starts tile aligned, due to restriction of level format, but can move to any pixel latter during game.
a: tile type 1. Actually blue boxes.
b: tile type 2. Actually green boxes.
Both a and b don't allow the player sprite to pass.
Certain type of tiles are passable and certain ones are not. Your engine must know what ones are passable.
The idea begin this is not to code a level editor if formats to represent level already exists.