Diese Befehle überprüfen einzelne Bits.
Zahlen die mit 0x beginnen werden von Ruby als Hexadezimalzahlen interpretiert.
0x0F wäre demnach 16 was einem Bitmuster von 00001111 entspricht in einem Byte entspricht.
Der & Operator ist ein "bitweises und" was so viel bedeutet wie er geht jedes Bit von seinem ersten Operanden durch und vergleicht es mit dem Bit an der selben Stelle des zweiten Operanden, und liefert nur dann eine 1 an jener Stelle im Ergebnis wenn bei beiden Operanden dort eine 1 war.

Beispiele:
Code:
00001111 & 11110000 = 00000000
11111111 & 00000001 = 00000001
10101010 & 11110000 = 10100000
Der << Operator verschiebt in seinem 1. Operanden (sofern es sich um eine Zahl handelt) alle Bits um eine Anzahl an Bits nach links wie der 2. Operand angibt, und füllt von rechts mit 0en auf.

Beispiele:
Code:
00000001 << 3 = 00001000
00001111 << 4 = 11110000
Solche Operationen auf Bitebene werden normalerweise dann verwendet wenn man in einer einzigen Variable mehrere Wahr/Falsch Zustände Speichern möchte. Man kann sich das so vorstellen, dass jedes Bit in einem Byte quasi einen Switch darstellt der bei 0 auf OFF und bei 1 auf ON ist.
Um das jetzt auf die Begehrbarkeit von Tiles anzuwenden könnte es in etwa wie folgt aussehen:
Code:
 8 7 6 5 4 3 2 1 
+-+-+-+-+-+-+-+-+
|.|.|.|.|N|E|W|S|
+-+-+-+-+-+-+-+-+
N = Passierbar Norden?
E = Passierbar Osten?
W = Passierbar Westen?
S = Passierbar Süden?
Welches Bit jetzt tatsächlich mit welcher Richtung übereinstimmt weiß ich jetzt nicht auswendig, aber so in ungefähr könnte es aussehen. Gehen wir aber einmal davon aus, dass es so aussieht, so wäre ein Tile im Norden passierbar wenn im 4. Bit eine 1 steht, usw.

Die Abfrage
Code:
@passages[event.tile_id] & 0x0f == 0x0f
ist also die Abfrage ob ein Tile in alle Richtungen begehbar ist.
Wie vorher erwähnt ist 0x0f die hexadezimale schreibweise von 16 also Binär 00001111. Diese schreibweise hat den Vorteil, dass man immer 4 binäre Ziffern (also jeweils 4 Bits eines Bytes) mit einer Hexadezimalziffer darstellen kann.

Code:
0 = 0000
1 = 0001
2 = 0010
3 = 0011
4 = 0100
5 = 0101
6 = 0110
7 = 0111
8 = 1000
9 = 1001
A = 1010
B = 1011
C = 1100
D = 1101
E = 1110
F = 1111

Die andere Abfrage, nämlich
Code:
bit = (1 << (d / 2 - 1)) & 0x0f
überprüft ob ein Tile in eine bestimmte Richtung passierbar ist. Die Variable d gibt dabei die Richtung an (steht ja auch so in der Beschreibung der Methode). Je nach richtung steht 2, 4, 6 oder 8 in der Variable. Bei d / 2 - 1 kommt dir dementsprechend ein Wert zwischen 0 und 3 heraus.
Wenn du nun 1 (00000001 als Byte) um 0 bis 3 stellen verschiebst kommen dir dementsprechend 1 (00000001), 2 (00000010), 4 (00000100) oder 8 (00001000) heraus. Dadurch das du auch noch ein & mit 0x0f durchführst kannst du sicherstellen, dass du eine numerische Variable erhältst die entweder 0 ist wenn das Bit an dieser Stelle nicht gesetzt ist, oder größer als 0 wenn es gesetzt war.

Edit: Nach schnellem überfliegen der von dir angeschnittenen Methode (und vor allem der Kommentare), hab ich gerade herausgefunden, dass im Falle der Game_Map implementierung hier die einzelnen Bitflags nicht für Passierbarkeit sondern für Unpassierbarkeit stehen. Also steht in dem betreffenden Bit ein 1er so kann man das Tile an dieser Stelle nicht passieren