In the last part, we defined some variables that we will use for generating terrain. First we start off by selecting the canvas element from our html using the DOM document method called querySelector. Next we resize this via resizeCavas() function that we define later to fill the body of html. Now we need a drawing object for canvas. The getContext() is a built-in HTML object, with properties and methods for drawing. We have also created a points array to store the random points generated for the terrain.
//canvas variable selects the element canvasvar canvas = document.querySelector("canvas");//We resize the canvas to our needsresizeCanvas();//ctx gets the context for you to draw on itvar ctx = canvas.getContext("2d");//points array holds the points of the terrainvar points = [];function resizeCanvas(){var body = document.querySelector("body");canvas.width = body.offsetWidth;canvas.height = body.offsetHeight;}
Next, we will generate random (x,y) coordinates for our terrain and store them inside points array.
//HEIGHT_MAX is the height of the canvasvar HEIGHT_MAX = canvas.height;//function to generate terrain pointsfunction generate_terrain_pts(){//these below variables are for generating our terrain pointsvar STEP_MAX = 0.6;var STEP_CHANGE = 0.03;// starting conditionsvar height = (Math.random() * HEIGHT_MAX/3) + (2*HEIGHT_MAX/3);var slope = (Math.random() * STEP_MAX) * 2 - STEP_MAX;// creating the landscapefor (var i = 0; i < canvas.width; i++){// change height and slopeheight += slope;slope += (Math.random() * STEP_CHANGE) * 2 - STEP_CHANGE;// clip height and slope to maximumif (slope > STEP_MAX) { slope = STEP_MAX };if (slope < -STEP_MAX) { slope = -STEP_MAX };if (height > 0.75*HEIGHT_MAX) {height = 0.75*HEIGHT_MAX;slope *= -1;}if (height < 0.4*HEIGHT_MAX) {height = 0.4*HEIGHT_MAX;slope *= -1;}var temp = {x: i, y: height};points.push(temp);}}
We have generated and stored all the coordinates in the points array. Now we have to draw them on our canvas. We will loop through each index of the points array and draw our terrain.
//function to draw terrain using the points generated by generate_terrainfunction draw_terrain(){for(var i = 0; i < canvas.width; i++){ctx.beginPath();ctx.moveTo(points[i].x, HEIGHT_MAX);ctx.lineTo(points[i].x, points[i].y);ctx.lineWidth = 10;ctx.lineCap = 'round';ctx.strokeStyle = 'green';ctx.stroke();//we draw the line second time for the light green terrain effectctx.beginPath();ctx.moveTo(points[i].x, HEIGHT_MAX);ctx.lineTo(points[i].x, points[i].y + 190);ctx.strokeStyle = 'rgba(0,180,0,0.4)';ctx.stroke();}}
The properties of context used above are explained as follows :
- beginPath() - Begins a path, or resets the current path
- moveTo() - The moveTo() method moves the path to the specified point in the canvas, without creating a line. (Syntax moveTo(x,y) )
- lineTo() - The lineTo() method adds a new point and creates a line TO that point FROM the last specified point in the canvas (this method does not draw the line by itself).
- lineWidth - To specify the width of the line
- stroke() - The stroke() method actually draws the path you have defined with all those moveTo() and lineTo() methods. The default color is black.
Remember that the top left corner of the canvas is (0,0) and bottom right corner is (canvas.width, canvas.height)
We have completed creating functions for generating points for terrain and drawing them, now we will call these functions to view the output.
//canvas variable selects the element canvasvar canvas = document.querySelector("canvas");//Here we resize the canvas to our needsresizeCanvas();//ctx gets the context for you to draw on itvar ctx = canvas.getContext("2d");//points array holds the points of the terrainvar points = [];//HEIGHT_MAX is the height of the canvasvar HEIGHT_MAX = canvas.height;function resizeCanvas(){var body = document.querySelector("body");canvas.width = body.offsetWidth;canvas.height = body.offsetHeight;}//function to draw terrain using the points generated by generate_terrainfunction draw_terrain(){//before drawing a terrain we need to generate points everytimegenerate_terrain_pts();for(var i = 0; i < canvas.width; i++){ctx.beginPath();ctx.moveTo(points[i].x, HEIGHT_MAX);ctx.lineTo(points[i].x, points[i].y);ctx.lineWidth = 10;ctx.lineCap = 'round';ctx.strokeStyle = 'green';ctx.stroke();//we draw the line second time for the light green terrain effectctx.beginPath();ctx.moveTo(points[i].x, HEIGHT_MAX);ctx.lineTo(points[i].x, points[i].y + 190);ctx.strokeStyle = 'rgba(0,180,0,0.4)';ctx.stroke();}}//function to generate terrain pointsfunction generate_terrain_pts(){//these below variables are for generating our terrain pointsvar STEP_MAX = 0.6;var STEP_CHANGE = 0.03;// starting conditionsvar height = (Math.random() * HEIGHT_MAX/3) + (2*HEIGHT_MAX/3);var slope = (Math.random() * STEP_MAX) * 2 - STEP_MAX;// creating the landscapefor (var i = 0; i < canvas.width; i++){// change height and slopeheight += slope;slope += (Math.random() * STEP_CHANGE) * 2 - STEP_CHANGE;// clip height and slope to maximumif (slope > STEP_MAX) { slope = STEP_MAX };if (slope < -STEP_MAX) { slope = -STEP_MAX };if (height > 0.75*HEIGHT_MAX) {height = 0.75*HEIGHT_MAX;slope *= -1;}if (height < 0.4*HEIGHT_MAX) {height = 0.4*HEIGHT_MAX;slope *= -1;}var temp = {x: i, y: height};points.push(temp);}}
Putting it all together this should be your final code and it must be in file named terrain.js
We have made a separate file main.js where we can call the functions we create in other js files, like generate_terrain_pts() and draw_terrain()
So currently your main.js should look like this :
//We call the generate_terrain_pts function to generate points for terraingenerate_terrain_pts();//We call the draw_terrain function to draw the terraindraw_terrain();
Now your project should look like this :
Now that we have created the terrain, our next objective is to put two tanks at random positions on the terrain for both the players.