collegemathgames.com

One Simple Game

Interested in game programming? Not sure? Let's make one simple game and find out.

Press the Next button on the bottom right of the screen to begin.

We are going to learn the absolute basics of making a video game.

When you are playing a game it repeatedly goes through a game loop, which involves handling updates to game values and drawing the current game screen.

First we need something to draw on. This is our game canvas.

Let's decide how big we want our game to be. Enter a width and height (in pixels). Let's make each at least 200 pixels so we can see.



Now do the same thing to draw a rectangle inside our canvas. Try entering a few numbers for the width and height here.



Okay, now that you've decided how wide and tall our rectangle is, let's toy with its position on the screen. A game object's x value is its position (in pixels) from the left side of the game canvas.

The y value is a little trickier. It describes the vertical position, but measures from the top of the game canvas rather than the bottom! Try some x and y values to see what I mean.







Great! You made a rectangle that we can draw and move.

But we want the game itself to do all that work of moving the rectangle around.

Let's store the the rectangle's position as variables, which can be different values. You can use the standard names of x and y (or left and top) or really, anything you want. Just avoid spaces or weird symbols (except an underscore _ if it makes it easier to read).

I'm going to make the rectangle a variable itself, called myRect.



Now we can change the position by changing these variables. (You can try changing them below if you want.)

myRect.

myRect.

Now, let's use the game's update() function to automatically move the rectangle. This function is used to handle any changes between game animation frames. Let's see how the "next frame" of the game changes things.

*Note: you can use a positive number to move one way, and a negative number to move the other way. Using zero means you won't move in either direction.


current frame

// The update() function might look something like this
function update()
{
    myRect.x = myRect.x +

    myRect.y = myRect.y +
}



next frame (preview)

Okay, let's back up a little. Once a game is started, the game loop basically looks like this:

update()
draw()

// Then repeat...

Well... that handles the animation. A real game will also need to deal with player input (from a controller, keyboard, etc.), which we will discuss later, and will look like this:

handle_input()
update()
draw()

// Then repeat...

Let's see our game loop in action. Enter how much you want the values to change on each update(). Then press Restart to see the resulting animation. (Hint: start with something small.)


// Be sure to also try NEGATIVE numbers!

function update()
{
    myRect.x = myRect.x +

    myRect.y = myRect.y +
}



Ok, but we don't always want to move the same way. Hm... let's use variables again! This will give us a new way to change the update() function.

Name a variable describing how much we'll move horizontally (along the "x" axis):

... and a variable describing how much we'll move vertically (along the "y" axis):

Now we can change these anywhere in our code, and our update() function will look like:

function update()
{
    myRect.x = myRect.x + myRect.x_speed

    myRect.y = myRect.y + myRect.y_speed
}

Let's see what that update function does now, when we set these variable values somewhere else in the code. Change the two new variables below to see how it affects movement in the game loop.

Press Restart to begin animating (or to reset your position).

// Now we can change these from anywhere, not just inside update()



Hooray! You have learned to use variables for animations. And since we can set movement now from anywhere, we can do it inside that handle_input() function I mentioned, letting the player control the movement.

I'll handle the code setup (below), you just decide what happens when the user presses up, down, left, or right.

// Positive and NEGATIVE numbers will determine movement
function handle_input( direction )
{
    // Btw, the == checks if two things are equal
    if( direction == "right" )
        
    
    if( direction == "left" )
        
    
    if( direction == "up" )
        
    
    if( direction == "down" )
        
}

Looking good... let's put it together and see if it works. See what pressing (or swiping) up, down, left, and right do. You can alway go back with the Previous button if this doesn't look right.

You can use the Restart button if you get lost offscreen.


Nice! Almost done. Now we need a goal for our player (to make it a game).

To keep it simple, let's just have the player try to grab something. We'll call it a "trophy" and we can just use a gold rectangle for it.

As you did with the player, decide how big your trophy is.






(preview)

We use "collision detection" to determine when two game objects overlap, like checking if the player has reached the trophy.

I'll spare you the extra code involved. Let's just say we have a colliding_with_trophy() function that will always give us true or false.

We'll add this into our udpate() function, so we can check for collision within each game loop.

But what happens if colliding_with_trophy() gives us true (so the rectangle and trophy are overlapping)? Well, then the game is won. Let's use a variable called gameOver to represent that.

function update()
{
    myRect.x = myRect.x + myRect.x_speed

    myRect.y = myRect.y + myRect.y_speed

    // The "if" here means: only look at the next line if colliding_with_trophy() gives us 'true'
    if( colliding_with_trophy() == true )
        gameOver = true

}

When the game is over, we want to let the player know they have won. One way to do this is change the draw() function.

Fill in the boxes below to decide what you'll say, and what x and y values the writing will start at.

function draw()
{
    // Btw, other drawing code would be up here...

    if( gameOver == true )
    {
        drawText(, , )
    }

}


(preview)

Congratulations!

You've learned the main concepts of creating one simple game.

Admittedly simple, but that was the point. Hopefully this helped you determine if you would find game programming interesting. (If so, go online and look for more in-depth tutorials!)

Now, press Next to play your simple masterpiece. NOTE: you can always go back through these pages to change the basics of your game. Have fun!


Review

Test yourself!

Q: What do you call an object in programming that can take different values?
A: A variable
Q: What is a game "canvas" used for?
A: Drawing the game on the screen
Q: Besides color, what are four properties that would let you draw a rectangle on a screen?
A: x, y, width, height (Note: this is one option. Some languages use right and bottom, some say left and top, etc.)
Q: A boolean variable, which might describe if a game is over, can only be one of two values. What are they?
A: true and false
Q: Writing or calling a function is often done by writing the function name followed by what?
A: Opening and closing parentheses, like (). Also, sometimes there will be a variable between them.
Q: Which of these makes sense as a negative value: a rectangle's width, an object's horizontal speed (more formally, "velocity"), or a game canvas height?
A: Horizontal speed (velocity) can be negative, meaning the object is moving left. Negative width and height make no sense.
Q: An animation loop can be defined as "update" (edit the latest variable values) and "draw" (draw to the screen). What needs to be added to make it a game?
A: Player interaction, or some way to "handle player input."
Q: What punctuation symbol is generally used to denote a variable property of a game object? (For example, the width property of myRect)
A: A period. For instance, myRect.width
Q: In a standard game layout, what direction will an object move if it's horizontal and vertical velocity are both positive: straight up and down, straight left and right, or diagonal?
A: Diagonal.

Wow, you made it all the way here!

If you want to keep learning, click the button below to download the code for the game you just made.

It will be a file called mygame.html. You can double-click/open it in your browser to play it.
Open it in a text editor (like Notepad, TextEdit, or Notepad++) to edit the code.
Have fun learning!

// Start here // Hello! We're going to keep this simple. You've already seen a lot of this. // Btw, you can write single-line comments after two forward slashes. Comments don't affect the code at all. // We will store our game canvas and its "drawing context" as variables var canvas var context // You can make a variable "object" whose properties are variables var myRect = { x: 0, y: 0, width: 1, height: 1, x_speed: 0, y_speed: 0 } // Now you can access myRect's properties with a . for instance by writing myRect.width = 10 // Our trophy is a little more simple var trophy = { x: 0, y: 0, width: 0, height: 0 } var gameOver = false // You can also use negative numbers! function update() { myRect.x = myRect.x + myRect.x_speed myRect.y = myRect.y + myRect.y_speed // The "if" here means: only look at the next line if colliding_with_trophy() gives us 'true' if( colliding_with_trophy() == true ) gameOver = true } function draw() { // We need to erase the last frame or weird stuff happens (comment this line out to see what I mean) context.clearRect(0, 0, canvas.width, canvas.height) // This is how we draw the player's rectangle context.fillStyle = "red" context.fillRect( myRect.x, myRect.y, myRect.width, myRect.height ) // This is how we draw the trophy rectangle context.fillStyle = "gold" context.fillRect( trophy.x, trophy.y, trophy.width, trophy.height ) if( gameOver == true ) { context.fillStyle = "blue" context.textBaseline = "top" // makes it write from the top left context.font = "20px Arial" // you can set the text size and font here // I know, I used "drawText" before for simplicity, but this is the real code context.fillText("Game Over", 0, 0) } } // Positive and negative numbers will determine movement function handle_input( direction ) { // Btw, the == checks if two things are equal if( direction == "right" ) myRect.x_speed = 1 if( direction == "left" ) myRect.x_speed = 1 if( direction == "up" ) myRect.y_speed = -1 if( direction == "down" ) myRect.y_speed = 1 } // ************************ // ************************ // // Try messing around with the code. Here are some ideas for you. // // Try changing the color of the player rectangle and the trophy. // // Try renaming any variable - just remember to change its name EVERYWHERE. // // Make a new variable that will count how many times you touch the trophy. // Now, change the code so that gameOver only becomes true after // you touch the trophy 100 times. // // Make the trophy move to a random location any time you reload the page. // You can use Math.random() to get a random number between 0 and 1, like: // var myRandomNumber = Math.random() // Multiply that by a bigger number to get a bigger random number. // (Use the asterisk * to multiply) // // Make something happen when the player's rectangle goes off the screen. // (You can use canvas.width to get the game canvas's width and // canvas.height to get the game canvas's height.) // // Use `if` statements to make it so that you stop when you press // the opposite direction. // // Example: // // if( myRect.x_speed > 0 ) // myRect.x_speed = 0 // // Be careful - the order in which you put the `if` statements might matter. // // ************************ // ************************ // ************************ // ************************ // // You can ignore all the stuff below (unless you are really curious and learning programming) // // ************************ // ************************ // This is one way to check for collision between the player's rectangle and the trophy. // Usually we have a more general function to check any two objects, like check_collision( object1, object2 ) function colliding_with_trophy() { if(myRect.x < trophy.x + trophy.width && myRect.x + myRect.width > trophy.x) { if(myRect.y < trophy.y + trophy.height && myRect.y + myRect.height > trophy.y) { return true; } } return false; } // This code waits for the webpage to load before setting some variables or adding events window.addEventListener("DOMContentLoaded", function() { canvas = document.getElementById("myCanvas"); context = canvas.getContext("2d"); // This connects the game to the user interactions (pressing a key or swiping a screen) window.addEventListener("keydown", handleInputs); window.addEventListener("touchstart", handleInputs); window.addEventListener("touchmove", handleInputs); setInterval(function() { // handle_input() is handled with other functions update(); draw(); }, 30); }); // Just a messy way to try and deal with all user interactions let latestTouchX = 0; let latestTouchY = 0; function handleInputs(e) { if(e.type === "touchstart") { latestTouchX = e.targetTouches[0].clientX; latestTouchY = e.targetTouches[0].clientY; return; } // convert a swipe/touchmove to look like a keyboard entry if(e.type === "touchmove") { if(e.preventDefault) e.preventDefault(); let newTouchX = e.changedTouches[0].clientX; let newTouchY = e.changedTouches[0].clientY; // handle horizontal if(newTouchX - latestTouchX > 5) { e.keyCode = 39; // right } else if(latestTouchX - newTouchX > 5) { e.keyCode = 37; // left } // handle vertical if(newTouchY - latestTouchY > 5) { e.keyCode = 40; // down } else if(latestTouchY - newTouchY > 5) { e.keyCode = 38; // up } latestTouchX = newTouchX; latestTouchY = newTouchY; } switch(e.keyCode) { case 38: // Up arrow case 87: // W handle_input("up"); break; case 40: // Down arrow case 83: // S handle_input("down"); break; case 37: // Left case 65: // A handle_input("left"); break; case 39: // Right case 68: // D handle_input("right"); break; default: { } } }
Download test code