If you're seeing this message, it means we're having trouble loading external resources on our website.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

## Computer programming

### Course: Computer programming>Unit 4

Lesson 4: Making a side scroller: Hoppy Beaver

# Forest environment

This game is a classic 2D "side-scroller": that means that we are looking at it side-on, and the character is just moving forwards or backwards through it. We always want our character in the center of the screen however, so actually, we simulate apparent motion of the character by moving the background past the character. It's a trick, but it works!
To start off with, let's just draw the parts that won't show any motion, the blue sky and brown ground:
``````draw = function() {
background(227, 254, 255);
fill(130, 79, 43);
rect(0, height*0.90, width, height*0.10);
// ...
}``````
Now, to create the side-scrolling appearance, let's add grass, using the grass image from the image library. One way we could create this moving environment would be to pretend our canvas was 3000 pixels wide, and that's how wide our level was, and draw as many grass blocks to fit those 3000 pixels, moving them over each time. However, that's not very efficient, and in programming games, we tend to care a lot about efficiency. Instead, we are going to "tile" and "snake" the grass images. We'll just draw as many as we need to go across the 400 pixel screen, and then when one falls off the left side of the right screen, we'll immediately stick it back on the right side of the screen, and just continue doing that forever.
To do that, we'll start by initializing an array of our initial positions for the grass blocks:
``````var grassXs = [];
for (var i = 0; i < 25; i++) {
grassXs.push(i*20);
}``````
Then, inside our draw loop, we'll draw each of them:
``````for (var i = 0; i < grassXs.length; i++) {
image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
}``````
That looks good for a static scene, but we need this to move! So we can just subtract one from each grass position each time, moving them to the left 1 pixel.
``````for (var i = 0; i < grassXs.length; i++) {
image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
grassXs[i] -= 1;
}``````
Now the grass will be moving, but it'll eventually disappear, as the x values become more and more negative. Remember, we want to "snake" the tiles - we want to wrap them to the right side of the canvas once they drop off the left side. To do that, we'll check if we're sufficiently off screen (remember that our images are drawn from the upper left corner), and set the x value to the canvas width if so:
``````for (var i = 0; i < grassXs.length; i++) {
image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
grassXs[i] -= 1;
if (grassXs[i] <= -20) {
grassXs[i] = width;
}
}``````
Putting it all together, we now have a beaver that looks like it's moving while it's hopping. Magic!
Okay, we have a beaver hopping through a side-scrolling environment. But there's nothing for the beaver to do there! We need to add the sticks for the beaver to hop up and collect.
Let's think a bit about our sticks, as we need to decide how to program them:
• Each stick has an x and y position. We probably want the x positions distributed by some amount (possibly constant or random within a range), and we want the y positions randomized within a range, so that the user has to control the beaver's hop and fall.
• The sticks should have the same apparent movement as the grass, but they should not snake around. Once a stick is off screen, it's gone forever.
• There should be some set amount of sticks per level - at some point, there should stop being sticks.
There are many ways that we could program our sticks, but they seem sufficiently complex, so let's model them with an object, like we modeled our beaver character:
``````var Stick = function(x, y) {
this.x = x;
this.y = y;
};

Stick.prototype.draw = function() {
fill(89, 71, 0);
rect(this.x, this.y, 5, 40);
};``````
Then, before our game starts running - like after we initialize our beaver - let's create an array of 40 sticks, with constant offset and random y:
``````var sticks = [];
for (var i = 0; i < 40; i++) {
sticks.push(new Stick(i * 40 + 300, random(20, 260)));
}``````
Now we can draw the sticks - similar to how we drew the grass, just without the wrapping around:
``````for (var i = 0; i < sticks.length; i++) {
sticks[i].draw();
sticks[i].x -= 1;
}``````
Here it is, with the sticks drawn with that code. Try to hop for them! What happens? Nothing! We'll fix that soon...

## Want to join the conversation?

• I've noticed that you guys started using "height" and "width" to define parameters inside shapes. Are those referring the to height and width of the canvass? •   Every Processing.js environment (like KA) can count on two predefined variables, `width` and `height` that describe the dimensions of the canvas, aka the sketch.
• i'm probly a very simple Javascript user but i can't and don't get anything of what she is saying. •  If none of this is making sense to you, then double back and do the Intro to Javascript course. Do ALL the challenges and projects, Skip nothing. You can burn through the whole thing in a couple of evenings, and then you will be ready for this Advanced JS course.

This course assumes you've got everything in the Intro course down; if you skimmed that, or skipped it entirely, you're going to be lost in this course. There is simply no substitute for practice with the basics before you start to get tricky.
• Hi, could someone help understand this part of the code?

``var sticks = [];for (var i = 0; i < 40; i++) {      sticks.push(new Stick (i * 40 + 300, random(20, 260)   )     );}``

I don't understand how was a new 'Stick' created with this line... Shouldn't we use something like this `var sticks = new Stick (" ");`?
How does this `sticks.push( new Stick (x,y) );` do the same job?

I get the push statement but how can it push a new Stick inside that array? Sorry if it is a bit confused... • Remember, an array is storing multiple variables, so by adding an object to it, it's like using `var` to create a new variable, except inside the array.
So using `sticks.push(new Stick());` is still creating a new stick object. It just isn't making it a separate variable with a name as you're used to.
• i feel like this is just giving me code, and not teacthing me how to do it. How would i learn to do this? • It doesn't show anything on my canvas even though I pass the chalenge. Here is my code:
var player1Y = height/2;
var player2Y = height/2;
var player1Score = 0;
var player2Score = 0;
var ball;
var gameStarted = false;
var t = 0;

//Constants
var PAUSE_TIME = 60;
var PLAYER_MOVE_SPEED = 2;
var BALL_SPEED = 2.5;

angleMode = "degrees";

var Ball = function(position, speed) {
this.position = position;
this.speed = speed || BALL_SPEED;

this.resetVelocity = function() {
this.theta = random(0, 360);
this.velocity = new PVector(
this.speed*cos(this.theta), -this.speed*sin(this.theta));
player2Y = height/2;
};
this.resetVelocity();

this.draw = function() {
fill(255, 255, 255);
noStroke();
ellipse(this.position.x, this.position.y,
};

if (dist(0, this.position.y, 0, y) <
if (this.position.x > x) {
this.position.x = x +
}
else if (this.position.x < x) {
this.position.x = x -
}
this.velocity.mult(new PVector(-1, 1));
}
}
};

this.update = function() {
//Handle wall collisions
if (this.position.x < 0) {
player2Score++;
this.position = new PVector(width/2, height/2);
gameStarted = false;
this.resetVelocity();
}
else if (this.position.x > width) {
player1Score++;
this.position = new PVector(width/2, height/2);
gameStarted = false;
this.resetVelocity();
}
if (this.position.y < 0) {
this.position.y = 0;
this.velocity.mult(new PVector(1, -1));
}
else if (this.position.y > height) {
this.position.y = height;
this.velocity.mult(new PVector(1, -1));
}

};
};

ball = new Ball(new PVector(width/2, height/2));

var drawScores = function() {
var s;

fill(255, 255, 255);
textSize(20);

s = "Player 1: " + player1Score;
text(s, width*0.25-textWidth(s)/2, 25);
s = "Player 2: " + player2Score;
text(s, width*0.75-textWidth(s)/2, 25);
};

var updatePlayer2 = function() {
if (abs(player2Y-ball.position.y) < PLAYER_MOVE_SPEED){
player2Y = ball.position.y;
}
else if (player2Y-ball.position.y >= PLAYER_MOVE_SPEED) {
player2Y -= PLAYER_MOVE_SPEED;
}
else if (player2Y-ball.position.y <= PLAYER_MOVE_SPEED) {
player2Y += PLAYER_MOVE_SPEED;
}

};

//Move the player up
var movePlayerUp = function() {
player1Y -= PLAYER_MOVE_SPEED;
};

//Move the player down
var movePlayerDown = function() {
player1Y += PLAYER_MOVE_SPEED;
};

var drawPlayers = function() {
//Constrain the player movement
player1Y = constrain(player1Y, 0, height);

rectMode(CENTER);
fill(255, 255, 255);
};

draw = function() {
//Control Player 1

//Draw the environment
background(0, 0, 0);
updatePlayer2();
drawPlayers();
drawScores();
stroke(255, 255, 255);
line(width/2, 0, width/2, height);

//Draw the ball
ball.draw();

if (!gameStarted) {
t++;
if (t >= PAUSE_TIME) {
t = 0;
gameStarted = true;
}
return;
}

ball.update();
};
draw = function() {
if(!gameStarted){
t++;
if(t >= PAUSE_TIME) {
t = 0;
gameStarted = true;
}
return;
}
if (keyIsPressed) {
if (keyCode === UP) {
movePlayerUp();
} else if (keyCode === DOWN) {
movePlayerDown();
}
}
ball.update();
}; • Org! I felt like it was a mega jump from "Intro to JS" to "Advanced JS: Games & Visualizations" and incorporates difficult concepts suddenly. Is there something that I am missing? • "At ,I am not sure what to do in step 1 of pong". • I did "Intro to JS" and I understood everything. I felt confident and moved on to "Advanced JS: Games and Visualizations" and now I'm totally lost. I get confused by every article I read, and none of the code makes sense. I've only gotten this far because of the hints offered in the challenges. I try reading answers to people's questions, but they just confuse me even more. HELP! • I also recently finished the Intro course and I can see what you mean that this one jumps forward a lot at once. What I have found helped a lot is to go back to the Intro course and when a new skill is introduced or a small challenge it had you do, think of a way you could make it cooler to challenge yourself. Then, you can ask questions or google to figure out how to make it inot what you imagined. This will really solidify the skills. For example, on the number analizer challenge that told you if a number was positive, negative, or zero, I took mine and added identifiers for even and odd also. I also made it so that it generated a new random whole number every time you click the screen. It forced me to learn a couple new things and also practice with other skills from the intro course without the prompts to use as a crutch. It's not a race to get through the courses, so taking your time and creating your own opportunities to practice is key. Also browse other people's projects for inspiration and practicing reading other people's code to see how things work together. You can change random numbers to see what changes on the screen to really figure each value out. I hope this is helpful! Good luck!
• ive been kind of struggling with objects so im not super sure what exactly this is doing or why its there can someone explain?
`var Stick = function(x, y) { this.x = x; this.y = y;};Stick.prototype.draw = function() { fill(89, 71, 0); rect(this.x, this.y, 5, 40);};` • `Stick` is a constructor function. That means that if you call it using `new`, like `new Stick()`, it will construct a stick object for you.
`Stick` takes in two parameters: `x` and `y`. The two lines inside the function set the stick's x and y properties to the values passed in. For example, if you write `new Stick(100, 200)`, the constructor will set `this.x = 100` and `this.y = 200`. Now your stick object has x = 100 and y = 200, and you can access those properties like so:
``var stick = new Stick(100, 200); // create a Stickprintln(stick.x); // print out our stick's x: 100println(stick.y); // print out our stick's y: 200// we can modify the stick's properties:stick.x += 100; // move the stick 100 to the right``

The next line adds a draw function to the Stick constructor's prototype, which is also called a method of `Stick`. This draw function draws the stick as a rectangle: `rect(this.x, this.y, 5, 40)`. The rectangle's coordinates are `this` particular stick's `x` and `y`. We can call this method on our stick using `stick.draw()`, which draws the stick at its coordinates: (100, 200).
• i can't understand if (grassXs[i] <= -20)
for (var i = 0; i < grassXs.length; i++) {
image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
grassXs[i] -= 1;
if (grassXs[i] <= -20) {
grassXs[i] = width;
}
} In the case of this code, there is an array of grass blocks that are each 20 pixels wide and 20 pixels apart. This loop draws each one and subtracts `1` from them so that they all move to the left. If any of them are all the way to the left, then set its position all the way to the right and start the cycle all over again. The reason that the conditional statement uses `-20` instead of `0` is that you would see the block change positions and it would ruin the illusion of movement.