-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathisometric-collision-map.js
More file actions
120 lines (100 loc) · 2.99 KB
/
isometric-collision-map.js
File metadata and controls
120 lines (100 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
ig.module(
'plugins.isometric-collision-map'
)
.requires(
'impact.map'
)
.defines(function(){
ig.IsometricCollisionMap = ig.Map.extend({
firstSolidTile: 1,
lastSolidTile: 255,
init: function( tilesize, data ) {
this.parent( tilesize, data );
},
trace: function( x, y, vx, vy, objectWidth, objectHeight ) {
// Set up the trace-result
var res = {
collision: {x: false, y: false},
pos: {x: x, y: y},
tile: {x: 0, y: 0}
};
// Break the trace down into smaller steps if necessary
var steps = Math.ceil(Math.max(Math.abs(vx), Math.abs(vy)) / this.tilesize);
if( steps > 1 ) {
var sx = vx / steps;
var sy = vy / steps;
for( var i = 0; i < steps && (sx || sy); i++ ) {
this._traceStep( res, x, y, sx, sy, objectWidth, objectHeight );
x = res.pos.x;
y = res.pos.y;
if( res.collision.x ) { sx = 0; }
if( res.collision.y ) { sy = 0; }
}
}
// Just one step
else {
this._traceStep( res, x, y, vx, vy, objectWidth, objectHeight );
}
return res;
},
_traceStep: function( res, x, y, vx, vy, width, height ) {
res.pos.x += vx;
res.pos.y += vy;
// 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((x + vx + pxOffsetX) / this.tilesize);
// Still inside this collision map?
if(
lastTileY >= 0 && firstTileY < this.height &&
tileX >= 0 && tileX < this.width
) {
for( var tileY = firstTileY; tileY < lastTileY; tileY++ ) {
var t = this.data[tileY] && this.data[tileY][tileX];
if( t >= this.firstSolidTile && t <= this.lastSolidTile ) {
res.collision.x = true;
res.tile.x = t;
res.pos.x = tileX * this.tilesize - pxOffsetX + tileOffsetX;
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((y + vy + pxOffsetY) / this.tilesize);
// Still inside this collision map?
if(
lastTileX >= 0 && firstTileX < this.width &&
tileY >= 0 && tileY < this.height
) {
for( var tileX = firstTileX; tileX < lastTileX; tileX++ ) {
var t = this.data[tileY] && this.data[tileY][tileX];
if( t >= this.firstSolidTile && t <= this.lastSolidTile ) {
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
}
});
// Static Dummy CollisionMap; never collides
ig.IsometricCollisionMap.staticNoCollision = { trace: function( x, y, vx, vy ) {
return {
collision: {x: false, y: false},
pos: {x: x+vx, y: y+vy},
tile: {x: 0, y: 0}
};
}};
});