Skip to content

Instantly share code, notes, and snippets.

@Joncom
Last active July 6, 2016 18:45
Show Gist options
  • Save Joncom/b55a4b0e9839548e87e354de47603f04 to your computer and use it in GitHub Desktop.
Save Joncom/b55a4b0e9839548e87e354de47603f04 to your computer and use it in GitHub Desktop.
ImpactJS Mixin That Adds Tile-Based Grid Movement to Entities
ig.module('plugins.mixin-grid-movement')
.requires()
.defines(function() {
MixinGridMovement = {
src_tile: null,
dst_tile: null,
grid_move: function(direction, seconds) {
var valid_directions = ['UP', 'DOWN', 'LEFT', 'RIGHT', 'NONE'];
if(valid_directions.indexOf(direction) === -1) {
throw 'An invalid direction was provided.';
}
if(typeof seconds !== 'number') {
throw 'The seconds argument must be a number.';
}
var tilesize = ig.game.collisionMap.tilesize;
if(!tilesize) {
throw 'The collision map must have a valid tilesize.';
}
var speed = this.speed || 64;
// Start moving towards a tile
if(this.src_tile === null && this.dst_tile === null) {
if(direction === 'NONE') {
return;
}
var new_src_tile = {
x: this.pos.x / tilesize,
y: this.pos.y / tilesize
};
var new_dst_tile = ig.copy(new_src_tile);
if(direction === 'LEFT') {
new_dst_tile.x -= 1;
} else if(direction === 'RIGHT') {
new_dst_tile.x += 1;
} else if(direction === 'UP') {
new_dst_tile.y -= 1;
} else if(direction === 'DOWN') {
new_dst_tile.y += 1;
}
// Prevent travel if destination tile is a wall
var data = ig.game.collisionMap.data;
if(data[new_dst_tile.y][new_dst_tile.x] !== 0) {
return;
}
this.src_tile = new_src_tile;
this.dst_tile = new_dst_tile;
}
// Move toward destination
var mx = 0;
var my = 0;
if(this.pos.x < this.dst_tile.x * tilesize) {
mx = seconds * speed;
} else if(this.pos.x > this.dst_tile.x * tilesize) {
mx = seconds * -speed;
} else if(this.pos.y < this.dst_tile.y * tilesize) {
my = seconds * speed;
} else if(this.pos.y > this.dst_tile.y * tilesize) {
my = seconds * -speed;
}
var res = ig.game.collisionMap.trace(
this.pos.x, this.pos.y, mx, my, this.size.x, this.size.y
);
this.handleMovementTrace( res );
if(typeof this.pos.x !== 'number' || typeof this.pos.y !== 'number') {
throw 'The entity position was set to a non-number.';
}
var reached_destination = (
(
// Right
this.src_tile.x < this.dst_tile.x &&
this.pos.x >= this.dst_tile.x * tilesize
) || (
// Left
this.src_tile.x > this.dst_tile.x &&
this.pos.x <= this.dst_tile.x * tilesize
) || (
// Down
this.src_tile.y < this.dst_tile.y &&
this.pos.y >= this.dst_tile.y * tilesize
) || (
// Up
this.src_tile.y > this.dst_tile.y &&
this.pos.y <= this.dst_tile.y * tilesize
)
);
if(reached_destination) {
// Calculate distance travelled beyond destination
var distance_over = 0;
if(this.src_tile.x !== this.dst_tile.x) {
distance_over = Math.abs(this.pos.x - (this.dst_tile.x * tilesize));
} else if(this.src_tile.y !== this.dst_tile.y) {
distance_over = Math.abs(this.pos.y - (this.dst_tile.y * tilesize));
}
// Snap to destination tile
this.pos.x = this.dst_tile.x * tilesize;
this.pos.y = this.dst_tile.y * tilesize;
if(typeof this.pos.x !== 'number' || typeof this.pos.y !== 'number') {
throw 'The entity position was set to a non-number.';
}
this.src_tile = null;
this.dst_tile = null;
var time_over = distance_over / speed;
if(time_over > 0) {
this.grid_move(direction, time_over);
}
}
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment