Intro to JS: Day 1

Course Goals

Psuedo code

The <Canvas> Element: Intro to MS Paint

Draw functions

var canvas = document.getElementById("canvas");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
var context = canvas.getContext("2d");

function rect(shape) {
  context.fillStyle = shape.color;
  context.beginPath();
  context.rect(shape.x, shape.y, shape.w, shape.h);
  context.fill();
  context.closePath();
}

function circle(c) {
  context.fillStyle = c.color;
  context.beginPath();
  context.arc(c.x, c.y, c.r, 0, Math.PI*2, true);
  context.fill();
  context.closePath();
}
function clear() { context.clearRect(0,0,WIDTH,HEIGHT); }

Draw functions: Let's start coding!

function rect(shape) {
  context.fillStyle = shape.color;
  context.beginPath();
  context.rect(shape.x, shape.y, shape.w, shape.h);
  context.fill();
  context.closePath();
}

function circle(c) {
  context.fillStyle = c.color;
  context.beginPath();
  context.arc(c.x, c.y, c.r, 0, Math.PI*2, true);
  context.fill();
  context.closePath();
}
function clear() {
  context.clearRect(0,0,WIDTH,HEIGHT);
}

var paddle = {
  w: 60,
  h: 15,
  y: HEIGHT - 30,
  color: "white"
}

paddle.x = WIDTH/2 - paddle.w/2;

var ball = {
  r: 10,
  y: HEIGHT - 45,
  color: "white"
}
ball.x = WIDTH/2; // arc is already centered!

clear();
circle(ball);
rect(paddle);

All the html we'll need


<canvas id="canvas" height="500" width="680" style="background: black;display: block;margin: 0 auto;"></canvas>
<script src="game.js"></script>
<center>
  <button onclick="start();return false;">Start Game</button>
  <button onclick="stop();return false;">Stop Game</button>
</center>

Make it Bounce!

var ball = {
  r: 10,
  y: HEIGHT - 45,
  dx: 150, // speed is in pixels per second
  dy: -150, // up is negative!
  color: "white"
}
ball.x = WIDTH/2;// arc is already centered!

var fps = 100;
function move() {
  // move the ball around
  if (ball.x < 0 || ball.x > WIDTH) { ball.dx = -ball.dx }
  if (ball.y < 0 || ball.y > HEIGHT) { ball.dy = -ball.dy }

  //(pixels per second)/(frames per second) = pixels per frame
  ball.x += ball.dx/fps; 
  ball.y += ball.dy/fps;
}

function draw() {
  clear();

  // draw ball
  circle(ball);
  rect(paddle);
}

function tick() {
  move()
  draw();
}

function start() {
  window.interval = setInterval(tick,1000/fps);
}

function stop() {
  clearInterval(interval);
}

Is it bouncing right?

Keyboard input

var rightDown = false;
var leftDown = false;

//set rightDown or leftDown if the right or left keys are down
function onKeyDown(event) {
  if (event.keyCode == 39) rightDown = true;
  else if (event.keyCode == 37) leftDown = true;
}

//and unset them when the right or left key is released
function onKeyUp(event) {
  if (event.keyCode == 39) rightDown = false;
  else if (event.keyCode == 37) leftDown = false;
}

document.addEventListener("keydown",onKeyDown);
document.addEventListener("keyup",onKeyUp);

//where paddle is defined, give the paddle a dx
paddle.dx = 200;

//put this in move
  if (leftDown) {
    paddle.x -= paddle.dx/fps;
  }
  if (rightDown) {
    paddle.x += paddle.dx/fps;
  }

//put this in draw
  rect(paddle);

Keyboard input: Demo

Creating the bricks

function createBricks(o) {
  var out = [], x, y, col_max, color;
  var colors = ["red","green","blue","yellow"];
  for (var row=0; row<o.rows; row++) {
    col_max = Math.floor(WIDTH / (o.w + o.separation));
    if (row%2 == 0) { col_max -=1; }
    y = (row+3)*(o.h + o.separation) + o.separation;
    for (var col=0; col<col_max; col++) {
      x = col*(o.separation + o.w) + o.separation;
      if (row%2 == 0) { x += o.w/2; }
      color = colors[Math.floor((row+col)%colors.length)];
      out.push({x: x, y: y, w: o.w, h: o.h, color: color, broken: false});
    }
  }
  return out;
}

var brick_options = {w: 40, h: 15, separation: 5, canvas: canvas, rows: 4};
var bricks = createBricks(brick_options);

// put this in the draw function
  for (var i=0;i<bricks.length;i++) {
    b = bricks[i];
    if (!b.broken) {
      rect(b);
    }
  }

Creating the bricks

Collision Detection

function collide(ball,brick) {
  var out = { x: false, y: false };
  var d_left = ball.x - brick.x;
  var d_right = brick.x + brick.w - ball.x;
  var d_top = ball.y - brick.y;
  var d_bot = brick.y + brick.h - ball.y;
  if (d_left > 0 && d_right > 0 && d_top > 0 && d_bot > 0) {
    if (Math.min(d_left,d_right) > Math.min(d_top,d_bot)) {
      out.y = true;
    }
    else {
      out.x = true;
    }
  }
  return out;
}

// inside tick()
  for (var i=0;i<bricks.length;i++) {
    var _b = bricks[i];
    if (!_b.broken) {
      var _c = collide(ball,_b);
      if (_c.x || _c.y) {
        _b.broken = true;
        if (_c.x) { ball.dx = -ball.dx }
        if (_c.y) { ball.dy = -ball.dy }
        continue;
      }
    }
  }
  
  _c = collide(ball,paddle);
  if (_c.x || _c.y) {
    ball.dy = - ball.dy;
  }

Collision Detection: Demo

Cleanup

Extra Credit

/