Back to Forum
Mechanic im having trouble on...maybe a good video topic?
Mini posted 5 years ago

Hello Chris, I didn't want to bother you by email so I decided to ask here.

I have been following your canvas tutorials for about a week, really learning a lot from them.

I started a top-down game project that has a similar concept to your Mario scroll game. I have been trying to understand top down game development for a while now, but still can't quite get it. Ive also been searching youtube but only found limited info.

Ive been trying to solve this issue by creating barries around my center-player, and moving the barriers based on whichever keys im pressing. This doesn't seem like the best approach because I would have to move every other map / entites by the same amount.

Would you be able to help?

heres a picture of what i have in the game

unknown.png (761×452) (discordapp.net)


//im looping through the map and drawing it where it should be, im doing this for each boardering grid
const MAP = [
	[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
	[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];

class Map {
	constructor(x, y, color, size, type) {
		this.x = x;
		this.y = y;
		this.color = color;
		this.size = size;
		this.type = type;
		this.velocity = { x: 1, y: 1 };
		this.speed = 3;
	}
	render() {
		var keysHeld = 0;
		keysHeld += Keys.W ? 1 : 0;
		keysHeld += Keys.S ? 1 : 0;
		keysHeld += Keys.A ? 1 : 0;
		keysHeld += Keys.D ? 1 : 0;
		var _speed = this.speed;
		if (keysHeld > 1) {
			_speed /= Math.sqrt(2);
		}

		// move buildings then moving mouse
		if (Keys.D) this.x += -this.velocity.x * _speed;
		if (Keys.A) this.x += this.velocity.x * _speed;
		if (Keys.W) this.y += this.velocity.y * _speed;
		if (Keys.S) this.y += -this.velocity.y * _speed;

		if (this.type === 1) {
			c.save();
			c.beginPath();
			c.lineWidth = 3;
			c.stroke();
			c.fillStyle = this.color;
			c.rect(this.x, this.y, this.size, this.size);
			c.fill();
			c.restore();
		}
	}
}
chris's profile photo
chris posted 5 years ago

Hey Mini - would you be able to post a link with your image here? Unfortunately don't have images set up on chriscourses.com since it requires a bit of extra moderation when it comes to spammers.

A CodePen to what you have so far would be great also!

M
Mini posted 5 years ago

Thanks for getting back

I worked on it a bit more, I was able to create the mechanic I wanted but not sure if I went with the best approach. I eventually want to make this multiplayer.

(btw I restarted and not using the previous code I posted)

https://codepen.io/steve323/pen/XWeGjGx

chris's profile photo
chris posted 5 years ago

So after checking things out, I think I have a better idea of where you're going with it. I haven't personally done a top-down game, but I found a CodePen that might push you in the right direction: https://codepen.io/martyzz/pen/KXVOOb?editors=1010

In there, check out the MapProcessor function as well as the Camera function, both should give you some tips in regards to how to set the game up correctly.

Basically, the MapProcessor will create rectangles and walls based on your map array, and then the Camera is responsible for moving the walls and everything in-between.

This sounds like something I'll cover in a future course, maybe after the Pacman one I'm doing next.

M
Mini posted 5 years ago

Thanks, I checked that out, and after a lot more trial and error, I was able to find what I think is the most simple solution.

Just in case anyone was following along with the same problem, I found what seems to be the best solution. My solution was to translate the canvas by (-myPosition.x + canvas.width/2, -myplayer.y + canvas.height/2)

This makes it so the player will always be seen in the center of the screen, regardless of its x and y coords.

Inside the after the translation between the save and restore, you can draw stuff that would appear on the games map, (example: game-borders, other players, ect...)

Outside that translation is where you can draw stuff that doesnt move according to the player. (exmaple: leaderboard, inventory, status bar etc...)

function loop() {
	if (GameState.runloop) GameState.loop = requestAnimationFrame(loop);


	c.fillStyle = GameState.backgroundColor;
	c.fillRect(0, 0, canvas.width, canvas.height);

	c.save(); // needs save before this translation
	c.translate(-myplayer.x + canvas.width / 2, -myplayer.y + canvas.height / 2);

	/* --- Entity Updates --- */
    myplayer.update();

    /* draw everything that should be moving with the games map in between this save/restore
 example: other players. 
coords example:
u can draw this at x:4000,y:4000, and as long as ur player is close to it, it will be visable on the screen
   */
	c.restore(); // if drawing inside this save/restore, it will draw on game borad (entities), if outside: will draw on screen (ui)

	// draws on real canvas width/height
	GameState.UI.draw();
}

Want to participate?

Create a free Chris Courses account to begin

Providing the lift to launch your development career

© 2026 Chris Courses. All rights reserved.