So you want all tiles outside of the collision map to be considered "non-passable" so that the entity can't escape the bounds of the collision map?
Make a new file called
collision-map.js
.
Put it in
/lib/game/
.
Give it the following code:
ig.module('game.collision-map')
.requires('impact.collision-map')
.defines(function(){ "use strict";
// This CollisionMap has been modified to allow
// negative value coordinates. Additionally,
// points with undefined values will be treated
// as if they are "this.defaultPermission".
ig.CollisionMap.inject({
data: {},
width: null,
height: null,
pxWidth: null,
pxHeight: null,
defaultPermission: 1, // blocked
init: function( tilesize, data, tiledef ) {
this.tilesize = tilesize;
this.data = data;
this.tiledef = tiledef || ig.CollisionMap.defaultTileDef;
for( var t in this.tiledef ) {
if( t|0 > this.lastSlope ) {
this.lastSlope = t|0;
}
}
},
_traceStep: function( res, x, y, vx, vy, width, height, rvx, rvy, step ) {
res.pos.x += vx;
res.pos.y += vy;
var t = 0;
// Horizontal collision (walls)
if( vx ) {
var pxOffsetX = (vx > 0 ? width : 0);
var tileOffsetX = (vx < 0 ? this.tilesize : 0);
var firstTileY = Math.floor(y / this.tilesize);
var lastTileY = Math.ceil((y + height) / this.tilesize);
var tileX = Math.floor( (res.pos.x + pxOffsetX) / this.tilesize );
// We need to test the new tile position as well as the current one, as we
// could still collide with the current tile if it's a line def.
// We can skip this test if this is not the first step or the new tile position
// is the same as the current one.
var prevTileX = Math.floor( (x + pxOffsetX) / this.tilesize );
if( step > 0 || tileX == prevTileX ) {
prevTileX = null;
}
for( var tileY = firstTileY; tileY < lastTileY; tileY++ ) {
if( prevTileX != null ) {
if( this.data[tileY] === undefined ||
this.data[tileY][prevTileX] === undefined ) {
t = this.defaultPermission;
} else {
t = this.data[tileY][prevTileX];
}
if(
t > 1 && t <= this.lastSlope &&
this._checkTileDef(res, t, x, y, rvx, rvy, width, height, prevTileX, tileY)
) {
break;
}
}
if( this.data[tileY] === undefined ||
this.data[tileY][tileX] === undefined ) {
t = this.defaultPermission;
} else {
t = this.data[tileY][tileX];
}
if(
t == 1 || t > this.lastSlope || // fully solid tile?
(t > 1 && this._checkTileDef(res, t, x, y, rvx, rvy, width, height, tileX, tileY)) // slope?
) {
if( t > 1 && t <= this.lastSlope && res.collision.slope ) {
break;
}
// full tile collision!
res.collision.x = true;
res.tile.x = t;
x = res.pos.x = tileX * this.tilesize - pxOffsetX + tileOffsetX;
rvx = 0;
break;
}
}
}
// Vertical collision (floor, ceiling)
if( vy ) {
var pxOffsetY = (vy > 0 ? height : 0);
var tileOffsetY = (vy < 0 ? this.tilesize : 0);
var firstTileX = Math.floor(res.pos.x / this.tilesize);
var lastTileX = Math.ceil((res.pos.x + width) / this.tilesize);
var tileY = Math.floor( (res.pos.y + pxOffsetY) / this.tilesize );
var prevTileY = Math.floor( (y + pxOffsetY) / this.tilesize );
if( step > 0 || tileY == prevTileY ) {
prevTileY = null;
}
for( var tileX = firstTileX; tileX < lastTileX; tileX++ ) {
if( prevTileY != null ) {
if( this.data[prevTileY] === undefined ||
this.data[prevTileY][tileX] === undefined ) {
t = this.defaultPermission;
} else {
t = this.data[prevTileY][tileX];
}
if(
t > 1 && t <= this.lastSlope &&
this._checkTileDef(res, t, x, y, rvx, rvy, width, height, tileX, prevTileY) ) {
break;
}
}
if( this.data[tileY] === undefined ||
this.data[tileY][tileX] === undefined ) {
t = this.defaultPermission;
} else {
t = this.data[tileY][tileX];
}
if(
t == 1 || t > this.lastSlope || // fully solid tile?
(t > 1 && this._checkTileDef(res, t, x, y, rvx, rvy, width, height, tileX, tileY)) // slope?
) {
if( t > 1 && t <= this.lastSlope && res.collision.slope ) {
break;
}
// full tile collision!
res.collision.y = true;
res.tile.y = t;
res.pos.y = tileY * this.tilesize - pxOffsetY + tileOffsetY;
break;
}
}
}
// res is changed in place, nothing to return
}
});
});
Did you notice the line
defaultPermission: 1
? Basically this says that any tile which does not have a defined persmission in the collision map will be treated like a "1", which is to say, not-passable.