Reputation: 1
I am rather new to programming in general, but I have managed to make a tile map system with collisions. I am looking for tips on optimization, or if the way I am doing this is completely stupid please let me know of a better way.
https://jsfiddle.net/19ed4sm0/
Basically I made a function that loops through the map array, and is called whenever a movement key is down. The system works with 8 directional movement, that is something I would like to keep.
//Collision with map tiles
function checkMove(px, py, pw, ph, pd) {
for(var y=0; y < map.length; y+=1) {
for(var x=0; x <map[y].length; x+=1) {
var tileX = x * 32;
var tileY = y * 32;
if (map[y][x] === 1) {
if (px < tileX+32 && px + pw > tileX && py < tileY+32 && py + ph > tileY) {
if (pd === 'right' && px+pw > tileX) {
_player.x = tileX - pw - _player.speed;
}
if (pd === 'left' && px < tileX+32) {
_player.x = tileX+32 + _player.speed;
}
if (pd === 'up' && py+ph > tileY) {
_player.y = tileY + ph + _player.speed;
}
if (pd === 'down' && py < tileY+32) {
_player.y = tileY-32 - _player.speed;
}
}
}
}
}
}
function playerInit() {
this.width = 32;
this.height = 32;
this.x = cWidth/2-16;
this.y = cHeight-96;
this.speed = 4;
this.gravity = 6;
this.color = '#ffb5e2'
this.update = function() {
//movement
if (keydown.up === true) {
checkMove(this.x, this.y - this.speed, tileSize, tileSize, 'up');
this.y -= this.speed;
}
if (keydown.left === true) {
checkMove(this.x-this.speed, this.y, tileSize, tileSize, 'left');
this.x -= this.speed;
}
if (keydown.right === true) {
checkMove(this.x+this.speed, this.y, tileSize, tileSize, 'right');
this.x += this.speed;
}
if (keydown.down === true) {
checkMove(this.x, this.y+this.speed, tileSize, tileSize, 'down');
this.y += this.speed;
}
//canvas border collision
if (this.x < 0) {
this.x = 0;
}
if (this.y < 0) {
this.y = 0;
}
if (this.x > cWidth - this.width) {
this.x = cWidth - this.width;
}
if (this.y > cHeight - this.height) {
this.y = cHeight - this.height;
}
}
this.render = function() {
c.fillStyle = this.color;
c.fillRect(this.x, this.y, this.width, this.height);
}
}
Upvotes: 0
Views: 239
Reputation: 116
Actually you just need to check the 8 tiles around your current position.
To calculate the next position you can store their offsets in an array:
var deltaX = [-1, -1, -1, 0, 0, 1, 1, 1];
var deltaX = [-1, 0, 1, -1, 1, -1, 0, 1];
for (var i = 0; i < deltaX.length; i++) {
var nextX = tileX + deltaX[i];
var nextY = tileY + deltaY[i];
// check collisions here
}
So instead of checking 20 * 20 = 400 tiles now you just need to check 8 tiles for collisions.
Upvotes: 1
Reputation: 4310
By measuring execution time:
//Collision with map tiles
function checkMove(px, py, pw, ph, pd) {
console.time("checkMove execution")
... // Rest of function
console.timeEnd("checkMove execution")
}
it can be seen that checkMove
only takes a fraction of a millisecond to execute.
So on the performance side, you are covered. This is not surprising even thought there are nested loops, since your map is small. Computers can calculate really fast. Probably faster than you think they can. I remember how grossly I underestimated the speed of computers when I started programming.
Upvotes: 0