# Stage 1

## Overview

In the first stage of the Cityscape Challenge, we draw the shapes of buildings with different sizes. Because we will be drawing lots of buildings, we will automate the process using functions and variables.

## Draw a Building

A building is a filled in rectangle. We use the `context.fillStyle` property to set the color of the rectangle and the `context.fillRect()` method to draw the rectangle.

We start by setting the `context.fillStyle` property to the color `'#1E90FF'`:

``context.fillStyle = '#1E90FF';``

Then, we use the `context.fillRect()` method to draw the rectangle with the fill color:

``context.fillRect(100, 50, 160, 240);``

To draw a rectangle, we pass the `context.fillRect()` method four values. The first two values are the x- and y-coordinates of the top left corner of the rectangle. We are drawing this rectangle at the coordinates (100, 50).

The context's coordinate system is slightly different than the coordinate system we use in math. The origin (0, 0) is in the top left corner of the canvas, not the bottom left corner. The x-coordinate still measures distance to the right of the origin, but the y-coordinate measures distance down, not up. Therefore, the top left corner of our rectangle is 100 pixels to the right and 50 pixels down from the origin.

The second two values are the width and height of the rectangle. This rectangle is 160 pixels wide and 240 pixels tall.

Try changing the first two values passed into the `context.fillRect()` method to move the rectangle around the canvas. Change the second two values to resize the rectangle.

To learn more about the coordinate system, drawing rectangles, and defining fill colors, visit the and fillStyle lessons.

Quick Reference:

Message Log

## Challenge 1

Use the `context.fillRect()` method to draw a building (rectangle) that is 320 pixels wide and 160 pixels tall so the top left corner of the building is positioned at (40, 80).

Figure out the y-coordinate of the bottom of the building. Then, use the `drawGround()` function to draw a line representing the ground beneath the building. For example, if the y-coordinate of the bottom of the building is 120, use:

``drawGround(120);``

Make sure to draw the ground after drawing the building.

If you need help drawing the building or positioning the ground, visit the Coordinates and fillRect() lessons.

Quick Reference:

Message Log

## Use Variables to Size and Position a Building

We can use variables to automatically size and position a building.

In this example, we draw a green building (color `'#228B22'`) that is twice as tall as it is wide, and positioned at (60, 40).

To change the size of the building, all we do is assign a different value to the variable `w`. The program automatically calculates the height of the building and assigns it to the variable `h`.

``````var w = 80; // Change this value to resize the building
var h = 2 * w; // The height is automatically two times the width``````

We use the values stored in the variables to draw the building:

``````context.fillStyle = '#228B22';
context.fillRect(60, 40, w, h);``````

Change the value stored in the variable `w` to see what happens. To learn more about variables, visit the Variables lesson.

Quick Reference:

Message Log

## Challenge 2

Assign values to the variables `x`, `y`, `w`, and `h` in the program below to draw a gray (color `'#999999'`) building with its top left corner positioned at (100, 40) and a width of 150 and height of 240.

Then, figure out the y-coordinate of the bottom of the building. Use the `drawGround()` function to draw a line representing the ground. Draw the ground after drawing the building. Can you calculate the ground's y-coordinate using the variables in the program?

If you need help using variables, visit the Variables lesson.

Quick Reference:

Previous Challenge: View your code from Stage 1 Challenge 1 to use on this challenge.

Code Missing: You have not yet entered any code in to the previous challenge: Stage 1 Challenge 1
Stage 1 Challenge 1
Message Log

## Challenge 3

For our cityscape, we don't want think about buildings in terms of pixels. We want to size buildings based on the number of floors they have and the number of office units on each floor, and then write the program so it calculates the number of pixels for us.

Each office unit is 16 pixels wide and 16 pixels tall. The outer walls, roof, and floor of the building are each 4 pixels thick.

The number of office units on each floor is assigned to the variable `units` and the number of floors in the building is assigned to the variable `floors`. Use the values stored in those variables to calculate the width and height of the building.

Then, draw a gray (color `'#999999'`) building with 10 floors and 8 office units on each floor with its top left corner positioned at (120, 80).

Use the function `drawOffices()` to draw the offices in the building by passing it the values stored in the variables `x`, `y`, `w`, and `h`.

Finally, figure out the y-coordinate of the bottom of the building and then use the `drawGround()` function to draw a line representing the ground. Draw the ground after drawing the building.

If you need help using variables, visit the Variables lesson.

Quick Reference:

Previous Challenge: View your code from Stage 1 Challenge 2 to use on this challenge.

Code Missing: You have not yet entered any code in to the previous challenge: Stage 1 Challenge 2
Stage 1 Challenge 2
Message Log

## Use a Function to Draw a Building

Drawing a single building takes a few steps. First, we have to calculate the width and height of the building. Then, we have to set the building color and draw the rectangle. Once we start drawing in windows, the list of steps will get much longer.

To draw our cityscape, we have to draw dozens of buildings. Typing in all that code for each building is going to be a lot of work.

If there is a chunk of code that you are going to use over and over again, putting that code into a function can make your life much easier. Then, to run the code, all you have to do is call the function by typing one line.

In this example, we create a function that will draw a French flag. Because we might want to draw a French flag in lots of different places, we make the x- and y-coordinates of the flag parameters. When we call `drawFrenchFlag(30, 100)`, the 30 is automatically assigned to the parameter `x` and the 100 to the parameter `y` inside the function. Now we can easily draw as many French flags as we want!

Quick Reference:

Message Log

## Challenge 4

Create a `drawBuilding()` function to draw buildings like the one from Challenge 3. The function is passed four values that it will assign to the following four parameters. The first two parameters,`x`and `y`, are the coordinates of the top left corner of the building; the third parameter, `units`, is the number of office units per floor; and the fourth parameter, `floors`, is the number of floors in the building.

Inside the `drawBuilding()` function, use the parameters to calculate the width and height of the building, set the `context.fillStyle` property to the color `'#999999'`, and use the `context.fillRect()` method to draw the building.

Once the `drawBuilding()` function has been defined, use it to draw two buildings. The first building has 8 office units per floor and 10 floors, and it is positioned at (60, 20). The second building has 6 office units per floor and 16 floors, and it is positioned at (210, 20).

If you need help using functions, visit the Functions lesson.

Quick Reference:

Previous Challenge: View your code from Stage 1 Challenge 3 to use on this challenge.

Code Missing: You have not yet entered any code in to the previous challenge: Stage 1 Challenge 3
Stage 1 Challenge 3
Message Log

## Anchor the Building to the Ground

You may have noticed that the two buildings in Challenge 3 are lined up along their top edges, not their bottom edges. In general, buildings are lined up along their bottom edges where they sit on the ground.

In this example, we create the `fillCenteredRectangle()` function, which automatically positions a rectangle by its top center point. This function has four parameters: `centerX`, `topY`, `w`, and `h`.

``````function fillCenteredRectangle(centerX, topY, w, h) {

// code block

}``````

Inside the function, we use the parameters to calculate the coordinates of the rectangle's top left corner and draw the rectangle:

``````function fillCenteredRectangle(centerX, topY, w, h) {
var x = centerX - w / 2;
var y = topY;

context.fillRect(x, y, w, h);
}``````

Since `centerX` is the x-coordinate of the center of the rectangle, we need to subtract half the rectangle's width to get the x-coordinate of the rectangle's top left corner. Since `topY` is the y-coordinate of the top of the rectangle, which is what we want, we assign it to the variable `y`.

Now we can easily draw a group of rectangles and line them up by their top center points. To learn more about positioning rectangles using variables, visit the and fillRect() lessons.

Quick Reference:

Message Log

## Challenge 5

Update the `drawBuilding()` function from Challenge 4 so its parameters are now: `leftX`, `groundY`, `w`, and `h`.

Inside the function, calculate the coordinates of the top left corner of the building's rectangle. Then, set the `context.fillStyle` to the color `'#999999'` and use the `context.fillRect()` method to draw the rectangle.

Once the `drawBuilding()` function has been updated, use it to draw two buildings. The first building has 12 office units per floor and 8 floors, and it is sitting on the ground at (20, 280). The second building has 9 office units per floor and 15 floors, and it sitting on the ground at (230, 280).

The `drawGround()` function is used to draw the ground at y = 280. Draw the buildings before the ground is drawn.

If you need help positioning rectangles using variables, visit the and fillRect() lessons.

Quick Reference:

Previous Challenge: View your code from Stage 1 Challenge 4 to use on this challenge.

Code Missing: You have not yet entered any code in to the previous challenge: Stage 1 Challenge 4
Stage 1 Challenge 4
Message Log

## Use translate() to Position the Building

Now we are going to clean up the `drawBuilding()` function a little bit.

A well-written function is like a polite robot who comes over to your house to do a job, and then leaves everything exactly as it found it. But if you look at the function used to draw a French flag in the previous example, it wasn't so tidy. It changed the `context.fillStyle` property to the color `'#EF4135'` and never changed it back.

To make our function more tidy, we call `context.save()` at the start of the function and `context.restore()` at the end. Calling `context.save()` saves the drawing state of the context (including the current `context.fillStyle` property) and `context.restore()` restores the drawing state to the last time we saved it.

The other change is to use the `context.translate()` method. Notice how we had to do calculations with x and y to figure out the positions of the white and red rectangles in the French flag? Imagine we had to do the same for dozens of windows in a building. We can eliminate a lot of that math by using the `context.translate()` method.

The `context.translate()` method moves the origin of the coordinate system. If we move the origin to the top left corner of the flag, then we can draw the rectangles in the flag as though the flag is positioned at (0, 0). The math is much easier. However, when using the `context.translate()` method, it is even more important to save and then restore the drawing state. If changing the `context.fillStyle` property is rude, moving the origin of the coordinate system and not moving it back is much ruder!

Try to predict what would happen if we left out the `context.save()` and `context.restore()` method calls in the function. To learn more about saving and restoring the drawing state and translating the origin of the coordinate system, visit the save() / restore() and translate() lessons.

Quick Reference:

Message Log

## Challenge 6

Tidy up the drawBuilding() function from Challenge 5 in the same way by calling the `context.save()` and `context.restore()` methods at the start and end of the function, respectively. Then, use the `context.translate()` method to move the origin to (x, y) and draw the rectangle at (0, 0).

Once the `drawBuilding()` function is tidy, draw one building with 10 office units per floor and 16 floors sitting on the ground at (20, 290) and another building with 12 office units per floor and 10 floors sitting on the ground at (200, 290).

The `drawGround()` function is used to draw the ground at y = 290. Draw the buildings before the ground is drawn.

If you need help saving and restoring the drawing state and translating the origin of the coordinate system, visit the save() / restore() and translate() lessons.

Quick Reference:

Previous Challenge: View your code from Stage 1 Challenge 5 to use on this challenge.

Code Missing: You have not yet entered any code in to the previous challenge: Stage 1 Challenge 5
Stage 1 Challenge 5
Message Log

## Ready for the next lesson?

Next up, the "Stage: 2" lesson >