This was a really fun project in Harvard's CS50x course.
Tools Utilized: C, Graphical User Interface

This was the first GUI problem set in Harvard's CS50x course. It's written in C and uses Stanford's Portable Library API.

// standard libraries
  #define _XOPEN_SOURCE
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <time.h>
  
  // Stanford Portable Library
  #include <spl/gevents.h>
  #include <spl/gobjects.h>
  #include <spl/gwindow.h>
  
  // height and width of game's window in pixels
  #define HEIGHT 800
  #define WIDTH 600
  
  // number of rows of bricks
  #define ROWS 5
  
  // number of columns of bricks
  #define COLS 10
  
  // lives
  #define LIVES 3
  
  // bricks
  #define BRICKMARGIN 4
  #define BRICKHEIGHT 10
  #define BRICKLENGTH ((WIDTH / COLS) - BRICKMARGIN)
  
  // paddle
  #define PADDLE_Y HEIGHT - (BRICKHEIGHT * 2)
  #define PADDLE_X WIDTH / 2 - BRICKLENGTH
  
  // ball
  #define RADIUS 20
  #define BALL_Y HEIGHT - (BRICKHEIGHT * 2 + RADIUS)
  #define BALL_X (WIDTH / 2) - (RADIUS / 2)
  
  // prototypes
  void initBricks(GWindow window);
  GOval initBall(GWindow window);
  GRect initPaddle(GWindow window);
  GLabel initScoreboard(GWindow window);
  void updateScoreboard(GWindow window, GLabel label, int points, int lives);
  GObject detectCollision(GWindow window, GOval ball);
  
  int main(void)
  {
      // seed pseudorandom number generator
      srand48(time(NULL));
  
      // instantiate window
      GWindow window = newGWindow(WIDTH, HEIGHT);
  
      // instantiate bricks
      initBricks(window);
  
      // instantiate ball, centered in middle of window
      GOval ball = initBall(window);
  
      // instantiate paddle, centered at bottom of window
      GRect paddle = initPaddle(window);
  
      // instantiate scoreboard, centered in middle of window, just above ball
      GLabel label = initScoreboard(window);
  
      // number of bricks initially
      int bricks = COLS * ROWS;
  
      // number of lives initially
      int lives = LIVES;
  
      // number of points initially
      int points = 0;
      
      // speed of ball
      double velocityX = drand48() + 1;
      double velocityY = -3.0;
  
      // keep playing until game over
      while (lives > 0 && bricks > 0)
      {
          updateScoreboard(window, label, points, lives);
  
          // listen for mouse event
          GEvent event = getNextEvent(MOUSE_EVENT);
          // if we heard any event
          if (event != NULL)
          {
              // if the event was movement
              if (getEventType(event) == MOUSE_MOVED)
              {
                  // ensure paddle follows the cursor along the x-axis
                  double x = getX(event) - getWidth(paddle) / 2;
                  setLocation(paddle, x, PADDLE_Y);
              }
          }
          
          // move ball
          move(ball, velocityX, velocityY);
  
          // bounce off right edge of window
          if (getX(ball) + RADIUS >= WIDTH)
          {
              velocityX = -velocityX;
          }
          // bounce off left edge of window
          else if (getX(ball) <= 0)
          {
              velocityX = -velocityX;
          }     
          // bounce off the top
          if (getY(ball) <= 0)
          {
              velocityY = -velocityY;
          }
          // if the paddle misses the ball, remove a life and reset
          if (getY(ball) >= PADDLE_Y)
          {
              lives--;            
              updateScoreboard(window, label, points, lives);
              setLocation(paddle, PADDLE_X, PADDLE_Y);
              setLocation(ball, BALL_X, BALL_Y);
              if (lives > 0 && bricks > 0)
                  waitForClick();
          }
          pause(10);
          // detect collision
          GObject object = detectCollision(window, ball);
          
          if (object != NULL)
          {
              if (object == paddle)
              {
                  velocityY = -velocityY - .1;
                  velocityX = velocityX - .5;
              }
              else if (strcmp(getType(object), "GRect") == 0)
              {
                  removeGWindow(window, object);
                  velocityY = -velocityY;
                  points++;
                  bricks--;
                  updateScoreboard(window, label, points, lives);
              }
          }
          if (bricks > 0 && lives == 0)
          {
              char s[9];
              sprintf(s, "You lose!");
              setLabel(label, s);
              setLocation(label, (WIDTH - getWidth(label)) / 2, (HEIGHT - getHeight(label)) / 2);
          }
          else if (bricks <= 0 && lives > 0)
          {
              char s[8];
              sprintf(s, "You win!");
              setLabel(label, s);
              setLocation(label, (WIDTH - getWidth(label)) / 2, (HEIGHT - getHeight(label)) / 2);
          }
          
          
      }
  
      // wait for click before exiting
      waitForClick();
  
      // game over
      closeGWindow(window);
      return 0;
  }
  
  /**
   * Initializes window with a grid of bricks.
   */
  void initBricks(GWindow window)
  {
      int brickY = BRICKLENGTH + BRICKMARGIN;
  
      for (int i = 0; i < ROWS; i++)
      {
          int brickX = BRICKMARGIN - (BRICKMARGIN / 2);
          for (int j = 0; j < COLS; j++)
          {
              GRect brick = newGRect(brickX, brickY, BRICKLENGTH, BRICKHEIGHT);
              
              if (i == 0)
                  setColor(brick, "ffff9d");
              
              if (i == 1)
                  setColor(brick, "beeb9f");
              
              if (i == 2)
                  setColor(brick, "79bd8f");
              
              if (i == 3)
                  setColor(brick, "00a388");
              
              if (i == 4)
                  setColor(brick, "ff6138");
  
              setFilled(brick, true);
              add(window, brick);
              brickX+=(BRICKLENGTH + BRICKMARGIN);
          }
          brickY+=(BRICKHEIGHT + BRICKMARGIN);
      }
  }
  
  /**
   * Instantiates ball in center of window.  Returns ball.
   */
  GOval initBall(GWindow window)
  {
      GOval ball = newGOval(BALL_X, BALL_Y, RADIUS, RADIUS);
      setColor(ball, "83d1e8");
      setFilled(ball, true);
      add(window, ball);
      return ball;
  }
  
  /**
   * Instantiates paddle in bottom-middle of window.
   */
  GRect initPaddle(GWindow window)
  {
      GRect paddle = newGRect(PADDLE_X, PADDLE_Y, BRICKLENGTH * 2, BRICKHEIGHT);
      setColor(paddle, "646464");
      setFilled(paddle, true);
      add(window, paddle);
      return paddle;
  }
  
  /**
   * Instantiates, configures, and returns label for scoreboard.
   */
  GLabel initScoreboard(GWindow window)
  {
      GLabel label = newGLabel("Start");
      setFont(label, "SansSerif-28");
      setColor(label, "83d1e8");
      add(window, label);
      return label;
  }
  
  /**
   * Updates scoreboard's label, keeping it centered in window.
   */
  void updateScoreboard(GWindow window, GLabel label, int points, int lives)
  {
      // update label
      char s[28];
      sprintf(s, "Points: %i, Lives: %i", points, lives);
      setLabel(label, s);
  
      // center label in window
      setLocation(label, (WIDTH - getWidth(label)) / 2, (HEIGHT - getHeight(label)) / 2);
  }
  
  /**
   * Detects whether ball has collided with some object in window
   * by checking the four corners of its bounding box (which are
   * outside the ball's GOval, and so the ball can't collide with
   * itself).  Returns object if so, else NULL.
   */
  GObject detectCollision(GWindow window, GOval ball)
  {
      // ball's location
      double x = getX(ball);
      double y = getY(ball);
  
      // for checking for collisions
      GObject object;
  
      // check for collision at ball's top-left corner
      object = getGObjectAt(window, x, y);
      if (object != NULL)
      {
          return object;
      }
  
      // check for collision at ball's top-right corner
      object = getGObjectAt(window, x + RADIUS, y);
      if (object != NULL)
      {
          return object;
      }
  
      // check for collision at ball's bottom-left corner
      object = getGObjectAt(window, x, y + RADIUS);
      if (object != NULL)
      {
          return object;
      }
  
      // check for collision at ball's bottom-right corner
      object = getGObjectAt(window, x + RADIUS, y + RADIUS);
      if (object != NULL)
      {
          return object;
      }
  
      // no collision
      return NULL;
  }