Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

HTML

              
                .container
  #app
              
            
!

CSS

              
                *, *:before, *:after {
  box-sizing: border-box;
}
.container {
  display: block;
  position: relative;
  margin: 0 auto;
  max-width: 600px;
  width: 100%;
  height: 100vh;
}
#app {
  width: 100%;
  height: 100vh;
  position: relative;
  background: #ddd;
  overflow: hidden;
}
.ground {
  display: block;
  position: absolute;
  width: 100%;
  background: #555;
}
.car {
  position: absolute;
  width: 75px;
  height: 25px;
  bottom: 50px;
  left: 20px;
  z-index: 100;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="56" height="28" viewBox="0 0 56 28" xmlns:xlink="http://www.w3.org/1999/xlink">
  <use fill="#D4B92C" xlink:href="#a"/>
  <use fill="#D4B92C" xlink:href="#b" transform="translate(36 7.5)"/>
  <use fill="#B89D10" xlink:href="#c" transform="translate(17 2)"/>
  <use fill="#B89D10" xlink:href="#d" transform="translate(7 2)"/>
  <use fill="#B89D10" xlink:href="#e" transform="rotate(-90 23 -13)"/>
  <use fill="#B89D10" xlink:href="#f" transform="rotate(-90 8.5 1.5)"/>
  <use fill="#B89D10" xlink:href="#c" transform="translate(34 2)"/>
  <g>
    <g fill="#D1E8F3" transform="translate(8 2)">
      <use xlink:href="#g"/>
      <use xlink:href="#h"/>
      <use xlink:href="#i"/>
    </g>
    <use fill="#C3DAE5" xlink:href="#j" transform="rotate(-47.395 20.278 -40.01)"/>
  </g>
  <g>
    <use fill="#838383" xlink:href="#k" transform="translate(3 12)"/>
    <use fill="#C4C4C4" xlink:href="#l" transform="translate(8 17)"/>
  </g>
  <g>
    <use fill="#838383" xlink:href="#k" transform="translate(37 12)"/>
    <use fill="#C4C4C4" xlink:href="#l" transform="translate(42 17)"/>
  </g>
  <defs>
    <path id="a" d="M4.7 9.982C2.514 5.34 5.9 0 11.033 0h22.11c3.19 0 5.977 2.157 6.777 5.245l1.813 7C42.88 16.677 39.535 21 34.956 21H14.33c-2.712 0-5.18-1.565-6.334-4.018l-3.296-7z"/>
    <path id="b" d="M0 0l20 3v9.5H4L0 0z"/>
    <path id="c" d="M0 0h2v7H0V0z"/>
    <path id="d" d="M0 0h1v7H0V0z"/>
    <path id="e" d="M0 0h1v10l-1 6.5V0z"/>
    <path id="f" d="M0 0h1v29H0V0z"/>
    <path id="g" d="M10.772 0h15.39v7H10.77V0z"/>
    <path id="h" d="M0 0h9.233v7H0V0z"/>
    <path id="i" d="M27.936 0h2.178L38 7H27.936V0z"/>
    <path id="j" d="M0 0l1.342 1.472.252 10.627-.18-.206L0 0z"/>
    <path id="k" d="M16 8c0 4.418-3.582 8-8 8s-8-3.582-8-8 3.582-8 8-8 8 3.582 8 8z"/>
    <path id="l" d="M6 3c0 1.657-1.343 3-3 3S0 4.657 0 3s1.343-3 3-3 3 1.343 3 3z"/>
  </defs>
</svg>');
  background-repeat: no-repeat;
  background-size: 100%;
  transform: scaleX(-1);
  filter: FlipH;
  &:nth-child(1):not(.crash) {
    transform: scaleX(1);
    filter: FlipH;
    &:before{
    content: '↑←try me→↓';
    position: absolute;
    bottom: 75px;
    left: -25px;
    width: 100px;
    background: #fef;
    z-index: 101;
    transform: rotateX(0deg);
    animation: 2s hovering ease infinite;
    }
  }
}

@keyframes hovering{
  50%{
    transform: rotateX(30deg);
  }
  100%{
    transform: rotateX(90deg);
  }
}
.crash {
  background-image: url('data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" width="164" height="48" viewBox="0 0 164 48" xmlns:xlink="http://www.w3.org/1999/xlink">
  <desc>
    Created using Figma
  </desc>
  <g transform="translate(1194 666)">
    <mask id="c">
      <path fill="#fff" d="M-1155-661.8h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1154 -660.757)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1154 -660.757)" mask="url(#c)"/>
  </g>
  <use fill="#F60000" xlink:href="#d" transform="translate(53 18.243)"/>
  <use fill="#FF8F16" xlink:href="#e" transform="translate(54 19.243)"/>
  <g transform="translate(1194 666)">
    <mask id="f">
      <path fill="#fff" d="M-1194-661.8h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1193 -660.757)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1193 -660.757)" mask="url(#f)"/>
  </g>
  <use fill="#F60000" xlink:href="#g" transform="translate(17 21.243)"/>
  <use fill="#FF8F16" xlink:href="#h" transform="matrix(-1 0 0 1 23.6 22.958)"/>
  <g transform="translate(1194 666)">
    <mask id="i">
      <path fill="#fff" d="M-1116-661.8h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1115 -660.757)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1115 -660.757)" mask="url(#i)"/>
  </g>
  <use fill="#F60000" xlink:href="#j" transform="translate(87 13.243)"/>
  <use fill="#FF8F16" xlink:href="#k" transform="rotate(31.7 44.982 160.06)" opacity=".8"/>
  <use fill="#FC0" fill-opacity=".9" xlink:href="#k" transform="translate(79 8.243)"/>
  <g transform="translate(1194 666)">
    <mask id="l">
      <path fill="#fff" d="M-1077-661.8h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1076 -660.757)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1076 -660.757)" mask="url(#l)"/>
  </g>
  <use fill="#F60000" xlink:href="#m" transform="translate(129 17.243)"/>
  <use fill="#FF8F16" xlink:href="#k" transform="rotate(43.38 67.44 169.556)" opacity=".8"/>
  <use fill="#FC0" fill-opacity=".9" xlink:href="#n" transform="rotate(59.806 64.55 125.662)"/>
  <defs>
    <path id="a" d="M0 0h40v40H0V0z"/>
    <path id="b" d="M0 0v-1h-1v1h1zm40 0h1v-1h-1v1zm0 40v1h1v-1h-1zM0 40h-1v1h1v-1zM0 1h40v-2H0v2zm39-1v40h2V0h-2zm1 39H0v2h40v-2zM1 40V0h-2v40h2z"/>
    <path id="d" d="M15 7c0 4-3.4 7-7.5 7-4 0-7.5-3-7.5-7s3.4-7 7.5-7c4 0 7.5 3 7.5 7z"/>
    <path id="e" d="M12 6c0 3.3-2.7 6-6 6S0 9.3 0 6s2.7-6 6-6 6 2.7 6 6z"/>
    <path id="g" d="M9 4c0 2.2-2 4-4.5 4S0 6.2 0 4s2-4 4.5-4S9 1.8 9 4z"/>
    <path id="h" d="M4.8 2.3c0 1.2-1 2.3-2.4 2.3S0 3.6 0 2.3C0 1 1 0 2.4 0c1.3 0 2.4 1 2.4 2.3z"/>
    <path id="j" d="M25 11c0 6-5.6 11-12.5 11C5.5 22 0 17 0 11S5.6 0 12.5 0C19.5 0 25 5 25 11z"/>
    <path id="k" d="M20 0l4.5 11H39l-11.7 7 4.5 11L20 22 8.2 29l4.5-11L1 11h14.5L20 0z"/>
    <path id="m" d="M19 8c0 4.4-4.3 8-9.5 8S0 12.4 0 8s4.3-8 9.5-8S19 3.6 19 8z"/>
    <path id="n" d="M15 0l3.3 8.3H29l-8.7 5 3.4 8.3-8.8-5-9 5 3.3-8.3-8.8-5h11L14.8 0z"/>
  </defs>
</svg>');
  background-size: 400%;
  animation: explode 0.78s steps(4) forwards;
}
@keyframes explode {
  100% {
    background-position: -160px 0;
  }
}

.missile{
  display: block;
  position: absolute;
  background-image: url('data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" width="242" height="43" viewBox="0 0 242 43" xmlns:xlink="http://www.w3.org/1999/xlink">
  <desc>
    Created using Figma
  </desc>
  <g transform="translate(1683 754)">
    <mask id="c">
      <path fill="#fff" d="M-1683-754h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1682 -753)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1682 -753)" mask="url(#c)"/>
  </g>
  <use fill="#17DEE7" xlink:href="#d" transform="translate(18 19)"/>
  <g transform="translate(1683 754)">
    <mask id="e">
      <path fill="#fff" d="M-1643-754h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1642 -753)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1642 -753)" mask="url(#e)"/>
  </g>
  <use fill="#17DEE7" xlink:href="#f" transform="translate(56 17)"/>
  <g transform="translate(1683 754)">
    <mask id="g">
      <path fill="#fff" d="M-1603-754h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1602 -753)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1602 -753)" mask="url(#g)"/>
  </g>
  <use fill="#17DEE7" xlink:href="#h" transform="translate(93 15)"/>
  <g transform="translate(1683 754)">
    <mask id="i">
      <path fill="#fff" d="M-1563-753.8h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1562 -752.757)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1562 -752.757)" mask="url(#i)"/>
  </g>
  <use fill="#17DEE7" xlink:href="#j" transform="translate(132 13)"/>
  <g transform="translate(1683 754)">
    <mask id="k">
      <path fill="#fff" d="M-1523-753.8h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1522 -752.757)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1522 -752.757)" mask="url(#k)"/>
  </g>
  <use fill="#17DEE7" xlink:href="#l" transform="translate(171 13)"/>
  <g transform="translate(1683 754)">
    <mask id="m">
      <path fill="#fff" d="M-1483-754h42v42h-42z"/>
      <use xlink:href="#a" transform="translate(-1482 -753)"/>
    </mask>
    <use fill-opacity="0" xlink:href="#b" transform="translate(-1482 -753)" mask="url(#m)"/>
  </g>
  <use fill="#17DEE7" xlink:href="#n" transform="translate(208 8)"/>
  <defs>
    <path id="a" d="M0 0h40v40H0V0z"/>
    <path id="b" d="M0 0v-1h-1v1h1zm40 0h1v-1h-1v1zm0 40v1h1v-1h-1zM0 40h-1v1h1v-1zM0 1h40v-2H0v2zm39-1v40h2V0h-2zm1 39H0v2h40v-2zM1 40V0h-2v40h2z"/>
    <path id="d" d="M5 2c0 1-1 2-2.5 2S0 3 0 2s1-2 2.5-2S5 1 5 2z"/>
    <path id="f" d="M10 4c0 2.2-2.2 4-5 4S0 6.2 0 4s2.2-4 5-4 5 1.8 5 4z"/>
    <path id="h" d="M15 6c0 3.3-3.4 6-7.5 6C3.5 12 0 9.3 0 6s3.4-6 7.5-6c4 0 7.5 2.7 7.5 6z"/>
    <path id="j" d="M17 7c0 4-3.8 7-8.5 7S0 11 0 7s3.8-7 8.5-7S17 3 17 7z"/>
    <path id="l" d="M20 8c0 4.4-4.5 8-10 8S0 12.4 0 8s4.5-8 10-8 10 3.6 10 8z"/>
    <path id="n" d="M0 5l11.5 4.5-3-9.5L18 13.5 9.4 25l2-8.5-9.5 5L9 15l-9-1.5 8.5-1L0 5z"/>
  </defs>
</svg>');
    z-index: 103;
background-size: 240px;
    background-repeat: no-repeat;
  animation: shoot .7s steps(6);
}
@keyframes shoot {
  100% {
    background-position: -240px 0;
  }
}


.building {
  display: block;
  position: absolute;
  background-image: url('data:image/svg+xml;utf8, <svg xmlns="http://www.w3.org/2000/svg" width="84" height="263" viewBox="0 0 84 263" xmlns:xlink="http://www.w3.org/1999/xlink">
  <use fill="#54577C" xlink:href="#a" transform="translate(0 2)"/>
  <use fill="#B1B1B1" xlink:href="#b" transform="translate(6 246)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 229)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 214)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 199)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 184)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 169)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 154)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 139)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 124)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 109)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 94)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 79)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 64)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 49)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 34)"/>
  <use fill="#B1B1B1" xlink:href="#c" transform="translate(6 19)"/>
  <use fill="#B1B1B1" xlink:href="#d"/>
  <use fill="#B1B1B1" xlink:href="#e" transform="rotate(90 2 2)"/>
  <use fill="#B1B1B1" xlink:href="#e" transform="rotate(90 42 42)"/>
  <use fill="#999" xlink:href="#f" transform="translate(6 250)"/>
  <use fill="#B1B1B1" xlink:href="#g" transform="matrix(0 -1 1 0 6 259)"/>
  <use fill="#B1B1B1" xlink:href="#g" transform="rotate(-90 165.5 93.5)"/>
  <use fill="#E8DB49" xlink:href="#h" transform="translate(6 7)"/>
  <defs>
    <path id="a" d="M0 0h84v261H0V0z"/>
    <path id="b" d="M0 0h70v4H0V0z"/>
    <path id="c" d="M0 0h70v2H0V0z"/>
    <path id="d" d="M0 0h84v4H0V0z"/>
    <path id="e" d="M0 0h263v4H0V0z"/>
    <path id="f" d="M0 0h70v9H0V0z"/>
    <path id="g" d="M0 0h10v4H0V0z"/>
    <path id="h" fill-rule="evenodd" d="M0 0h10v10H0V0zm20 0h10v10H20V0zm30 0H40v10h10V0zm10 0h10v10H60V0zM0 15h10v10H0V15zm20 0h10v10H20V15zm30 0H40v10h10V15zm10 0h10v10H60V15zM10 30H0v10h10V30zm20 0H20v10h10V30zm10 0h10v10H40V30zm30 0H60v10h10V30zM0 45h10v10H0V45zm20 0h10v10H20V45zm30 0H40v10h10V45zm10 0h10v10H60V45zM10 60H0v10h10V60zm20 0H20v10h10V60zm10 0h10v10H40V60zm30 0H60v10h10V60zM0 75h10v10H0V75zm20 0h10v10H20V75zm30 0H40v10h10V75zm10 0h10v10H60V75zM10 90H0v10h10V90zm20 0H20v10h10V90zm10 0h10v10H40V90zm30 0H60v10h10V90zM0 105h10v10H0v-10zm20 0h10v10H20v-10zm30 0H40v10h10v-10zm10 0h10v10H60v-10zm-50 15H0v10h10v-10zm20 0H20v10h10v-10zm10 0h10v10H40v-10zm30 0H60v10h10v-10zM0 135h10v10H0v-10zm20 0h10v10H20v-10zm30 0H40v10h10v-10zm10 0h10v10H60v-10zm-50 15H0v10h10v-10zm20 0H20v10h10v-10zm10 0h10v10H40v-10zm30 0H60v10h10v-10zM0 165h10v10H0v-10zm20 0h10v10H20v-10zm30 0H40v10h10v-10zm10 0h10v10H60v-10zm-50 15H0v10h10v-10zm20 0H20v10h10v-10zm10 0h10v10H40v-10zm30 0H60v10h10v-10zM0 195h10v10H0v-10zm20 0h10v10H20v-10zm30 0H40v10h10v-10zm10 0h10v10H60v-10zm-50 15H0v10h10v-10zm20 0H20v10h10v-10zm10 0h10v10H40v-10zm30 0H60v10h10v-10zM0 225h10v10H0v-10zm20 0h10v10H20v-10zm30 0H40v10h10v-10zm10 0h10v10H60v-10z"/>
  </defs>
</svg>
');
  background-repeat: no-repeat;
  background-size: 100%;
  z-index: 99;
}

              
            
!

JS

              
                /** 
* Ref:
* https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
*/
const app = document.querySelector("#app");
document.addEventListener("keydown", function(e) {
  const player = items.find(item => item.player);
  switch (e.keyCode) {
    case 38: //up
      player.y += 10;
      break;
    case 40: //down
      player.y -= 10;
      break;
    case 39: //right
      player.x += 10;
      break;
    case 37: //left
      player.x -= 10;
      break;
    case 32: //space
      addToItems(createMissile);
      break;
    default:
      break;
  }
});

// document.addEventListener("click", function(e){
//         addToItems(createMissile); //click to shoot
// });
document.addEventListener("keyup", function(e) {
  const player = items.find(item => item.player);
  switch (e.keyCode) {
    case 38: // if user lets go of up, fall a little
      player.y -= 3;
      break;
    case 39: //right
      player.x -= 3;
      break;
    case 37: //left
      player.x -= 3;
      break;
    default:
      break;
  }
});
const items = [
  {
    name: "car",
    x: 5,
    y: 20,
    width: 50,
    height: 25,
    speed: 1,
    player: true,
    crash: false,
    dir: "right"
  },
  {
    name: "car",
    x: 500,
    y: 50,
    width: 50,
    height: 25,
    speed: 4
  },
  {
    name: "car",
    x: 540,
    y: 50,
    width: 50,
    height: 25,
    speed: 2
  },
  { name: "ground", x: 0, y: 0, height: 50, color: "#555" },
  { name: "building", x: 100, y: 50, height: 263, width: 84 },
  { name: "building", x: 300, y: 50, height: 400, width: 128 }
];
const timers = { counter: 0, intervals: [], timeouts: [], pointsAgainst: 0 };

/**
* Currently only tested with the first player (user) object from the items array as well as another item for which a setInterval has been called.
* @param {object} hero - The first object from the items array. The user.
* @param {object} opponent - Another item from the items array.
* @return {boolean} If a collision is detected, return true.
*/
function detectCollision(hero, opponent) {
  return (
    hero.x < opponent.x + opponent.width &&
    hero.x + hero.width > opponent.x &&
    hero.y < opponent.y + opponent.height &&
    hero.height + hero.y > opponent.y
  );
}
/**
* @param {object} obj - An item from the items array called by a setInterval
* @param {integer} timer - The index of the item from the items array for which the setInterval called.
* Calls update. Does lots of side-effect stuff. Needs to be refactored.
*/
function accelerate(obj, timer) {
  function move() {
    const direction = obj.dir === 'right' ? 1 : -1; 
    if (obj.name === "car" || obj.name === 'missile') {
      obj.x += obj.speed * direction;
      if (obj.y > 50) {
        obj.y -= 2;
      } //if car is above the ground, let it fall a little
    } else {
      obj.x -= obj.speed;
    }
  }
  if (timer !== 0 && detectCollision(items[0], items[timer]) || timers.pointsAgainst >= 3) {
    console.log(
      "collision detected! ....with " + items[timer].name + ", item: " + timer
    );
    items[0].crash = true;
    items[0].width = 40;
    items[0].height = 40;
    items[0].x += 15;
    timers.intervals.forEach(t => clearInterval(t));
    clearInterval(genCars);
  }
  if (obj.name === "missile") {
    items
      .forEach(item => {
        if (detectCollision(item, items[timer]) && item.name === "car") {
          item.crash = true;
          item.width = 40;
          item.height = 40;
          item.x += 15;
          clearInterval(timers.intervals[items.indexOf(item)]);
        }
      });
    move();
  }

  if (obj.x > app.offsetWidth && obj.name !== "missile") {
    obj.x = -obj.width;
    move();
  }
  if (obj.x <= 0 - obj.width) {
    obj.x = app.offsetWidth;
    move();
    if(obj.name === 'car' && !obj.player) timers.pointsAgainst++;
  }
  if (obj.x <= app.offsetWidth + obj.width && obj.x > 0 - obj.width) {
    move();
  }
  else {
    clearInterval(timers.intervals[timer]);
  }
  update();
}
/**
* Adds a setInterval to timers.intervals array at the same index as the element being animated
* @param {object} el - an object from the items array
*/
const drive = function(el) {
  timers.intervals[items.indexOf(el)] = setInterval(() => {
    accelerate(el, items.indexOf(el));
  }, 100);
};
const cars = items.filter(item => item.name === "car").map(c => drive(c));

const shoot = function(item) {
  drive(item);
};

/**
* pushes a new car into the items array and calls drive on it
*/
const createNewCar = function() {
  let vel = Math.floor(Math.random() * 10) + 1;
  const start = Math.floor(Math.random() * 200) + 50;
  return {
    name: "car",
    x: 600,
    y: start,
    width: 50,
    height: 25,
    speed: vel,
    crash: false,
    player: false
  };
};

const createMissile = function() {
  const start = [items[0].x + items[0].width + 10, items[0].y - 10];
  return {
    name: "missile",
    x: start[0],
    y: start[1],
    width: 40,
    height: 40,
    speed: 20,
    dir: "right"
  };
};

const addToItems = function(f) {
  items.push(f());
  animationHandler(items[items.length - 1]);
};

const animationHandler = function(item) {
  if (item.name === "car") {
    drive(item);
  } else if (item.name === "missile") {
    shoot(item);
  }
};

const genCars = setInterval(()=>{
  if(items.filter(item=> item.name === 'car' && !item.crash).length<8){
  addToItems(createNewCar);  
  }
}, 5000);

/**
* @param {array} components - Multiple arrays of HTMLElements to be rendered.
* @return {string} - Raw html for innerHTML of #app.
*/
function render(...components) {
  return components.map(c => c.outerHTML).join("");
}
/**
* Returns new element specified by selector and tag.
* @param {object} - An single item from the items array, destructured.
* @return {HTMLElement} - The HTML for each item.
*/
function createEl({ name, x, y, width, height, color, player, crash } = {}) {
  // return `<div class='${name}' style='width:${width}px; height:${height}px; left:${x}px; bottom:${y}px; background:${color}'></div>`;
  const el = document.createElement("div");
  const bg = color ? "background:" + color : "";
  el.setAttribute("class", name);
  if (crash) {
    el.classList.add("crash");
  }
  el.setAttribute(
    "style",
    `width:${width}px; height:${height}px; left:${x}px; bottom:${y}px;${bg}`
  );
  return el;
}

/**
* Calls the createEl function on each object in the items array.
* @return {array} An array of HTML strings for each item in the items array.
*/
function initItems(arr) {
  return arr.map(item => createEl(item));
}

/**
* Calls the render function and replaces the app innerHTML with a string of generated HTML.
*/
function update() {
  app.innerHTML = render(...initItems(items));
}

              
            
!
999px

Console