Well sort of; for example if we had a normal level made in the editor of say 200 x 100 tiles and we had a screen display area (camera view) of 100 x 100 tiles we can move the camera view at whatever speed we want to the right up to another 100 tiles. If we forget about the player for a bit as this is simply a reference point for the camera we could simply scroll the tile map in our main update:
this.scrollMap.scroll.x += (ig.system.tick * 100);
Of course you could simply move the view screen as it does in the camera class instead of using scroll:
ig.game.screen.x += myspeed;
Now the tile map you want does not exist because you are generating it so we need to create a 2d array to store the level data. Note this is stored in Y, X order. Generally this needs to be big enough to fill the camera view area so for this example 100 x 100. If we simply create this map with some graphic tile and update it using either of the methods above the map will get pushed out of the camera view to the left.
So we need some kind of off screen (out of camera view) buffer that we can generate before we need to draw it on the screen. Keeping the numbers easy we will use a tile size of 10 x 10 this means we need ten tiles to fill the camera view from left to right (we don’t care about vertical tiles as you are not moving them, if you are the idea is the same). If we use a single tile buffer as in the above example we need to generate the background map to be 1 tile wider that the visible area.
this.viewSize.x = Math.floor(ig.system.width / this.tileSize) + 1;
this.viewSize.y = Math.floor(ig.system.height / this.tileSize);
// Generate blank array for the display map & collision Map
var data = new Array(this.viewSize.y);
var cdata = new Array(this.viewSize.y);
for (var iY = 0; iY < this.viewSize.y; iY++) {
data[iY] = new Array(this.viewSize.x);
cdata[iY] = new Array(this.viewSize.x);
for (var iX = 0; iX < this.viewSize.x; iX++) {
data[iY][iX] = 0;
cdata[iY][iX] = 0;
}
}
Each time the update routine executes it scrolls the visible area to the left by whatever speed has been specified in the scroll.x until the screen has moved approx. one whole tile to the left (10 pixels in this case) at this point we have no more tiles on the right of the map so the scroll.x position is moved back to 0 (the example needs some cleaning up as this is a fractional move at the moment and will cause some kind of judder, I would take a look in the engine code as Dominic must have resolved this somehow already).Currently this example uses shift() and push(x) to remove the first tile from the map row and add a new tile to the end. This gives us the new display data required as we start the next scroll.
I have no idea of your player movement requirements but if the player is static in the middle of the screen on the x axis (we will leave y alone and let the normal gravity / velocity do its job) instead of moving the player which uses a camera to position the camera view we can move the screen based on the same calculations you would get from your player entity. If you take a look in the entity code you will see getNewVelocity which we can use to pass onto the scroll.x .
Add a few properties to the above example:
scrollvelx:0,
scrollaccel:0,
scrollmaxvelx:10,
Replace the update code:
update:function () {
if (ig.input.state('right'))
{
this.scrollvelx = this.scrollvelx < 0 ? 0 : this.scrollvelx;
this.scrollaccel= 2;
}
if (ig.input.state('left'))
{
this.scrollvelx = 0; // stop dead
}
this.scrollMap.scroll.x += this.scrollvelx;//(ig.system.tick * this.scrollvelx);
if (this.scrollMap.scroll.x >= this.tileSize) {
// some fractional error that may cause judder..
this.scrollMap.scroll.x = (this.scrollMap.scroll.x % this.tileSize);
// Remove first element in array
this.scrollMap.data[10].shift();
ig.game.collisionMap.data[10].shift();
// Push the new tile to the end of the array .. some random generation!
if (Math.floor(Math.random() * 2) != 0) {
this.scrollMap.data[10].push(1);
ig.game.collisionMap.data[10].push(1);
}
this.scrollMap.data[10].push(0);
ig.game.collisionMap.data[10].push(0);
}
this.scrollvelx = this.getNewVelocity(this.scrollvelx,this.scrollaccel,0,this.scrollmaxvelx);
this.parent();
this.scrollaccel=0;
},
This is a bit hacky but you should get the idea, we move the screen to the right in the same way we would move a player entity. Just bind and check the jump key as normal.
The above assumes that the player does not move on the x axis but of course you could create a trap area in the same way the camera class does and take the values into account or modify the camera class to do the same work as above.
I would look a generating as much of the map upfront as possible before entering the game loop, if the map backgrounds are not going to change much once generated then it would be faster and of course you can pre render the chunks.
But if you are generating the map based on what happens in the game then you will have to take a similar approach to the above example. If you can increase the scroll buffer and the tile size you will probably get smoother results.
I’m still newish to JavaScript and the HTML5 Canvas and of course Impact so some of the more experienced member’s may have other ideas but this is similar to how I have done the same thing on other engines.