JSFiddle - React, Tailwind, and code Playground

by craigm

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<div id="game"></div>

CSS

body {
  background: #2D9CE0;
}

#game {
  position: absolute;
  height: 450px;
  width: 600px;
  margin: -225px 0 0 -300px;
  top: 50%;
  left: 50%;
  background: #000;
}

canvas {
  background: #000;
}

JavaScript

$(function () {
  var FPS = 60,
      CANVAS_WIDTH = 600,
      CANVAS_HEIGHT = 450,
      BOUNDARY_MARGIN = 10,
      BOUNDARY_WIDTH = 15,
      PADDLE_WIDTH = 15,
      PADDLE_HEIGHT = 60,
      PADDLE_MOVE_INTERVAL = 6,
      BALL_SIZE = 15,
      MIN_BALL_VELOCITY = 2,
      MAX_BALL_VELOCITY = 8,
      VELOCITY_STEP = 1,
      KEY_CODES = {
        LEFT_UP: 87,
        LEFT_DOWN: 83,
        RIGHT_UP: 38,
        RIGHT_DOWN: 40,
        SPACE: 32
      },  
      FIELD = {
        TOP: BOUNDARY_MARGIN + BOUNDARY_WIDTH,
        BOTTOM: CANVAS_HEIGHT - BOUNDARY_MARGIN - BOUNDARY_WIDTH,
        RIGHT: CANVAS_WIDTH - BOUNDARY_MARGIN - BOUNDARY_WIDTH,
        LEFT: BOUNDARY_MARGIN + BOUNDARY_WIDTH
      },
      STATUS = {
        NEW_GAME: 'NEW_GAME',
        SERVING: 'SERVING',
        PLAYING: 'PLAYING',
        GAME_OVER: 'GAME_OVER'
      },
      DEFAULT_BALL_SETTINGS = {
        x: CANVAS_WIDTH / 2 - BALL_SIZE / 2,
        y: FIELD.TOP + 1,
        vector: {
          x: 1,
          y: -1,
          velocity: 3
        }
      },
      DEFAULT_STATE = {
        status: STATUS.NEW_GAME,
        left: {
          paddle: {
            x: FIELD.LEFT + BALL_SIZE,
            y: CANVAS_HEIGHT / 2 - PADDLE_HEIGHT / 2
          },
          input: { keyPressed: null },
          score: 0
        },
        right: {
          paddle: { 
            x: FIELD.RIGHT - BALL_SIZE - PADDLE_WIDTH,
            y: CANVAS_HEIGHT / 2 - PADDLE_HEIGHT / 2 
          },
          input: { keyPressed: null },
          score: 0
        },
        ball: clone(DEFAULT_BALL_SETTINGS)
      },
      $canvas = $('<canvas width="' + CANVAS_WIDTH + '" height="' + CANVAS_HEIGHT + '"></canvas>'),
      canvas = $canvas.get(0).getContext('2d'),
      gameLoopId = null,
      state = null;
      
  $canvas.appendTo('#game');
  
  // capture user input
  $(document).keydown(function (e) {
    switch (e.which) {
      case KEY_CODES.LEFT_UP:
        state.left.input.keyPressed =...