MASIGNASUKA101
239990035665021724

Make Racing Car Game [Using JavaScript Code Only]

Make Racing Car Game [Using JavaScript Code Only]
Add Comments
Monday, November 9, 2020

Make a stylish racing car game using HTML, CSS, and JavaScript

A high-level programming code is used to make a racing car game. Create a beautiful and professional car game using only HTML, CSS, and JavaScript programming code. 

Java, Python, c, c +, etc. programming codes are used to make a game. But if you want to make it with JavaScript, it may not be so professional. This article shows you how to make a professional racing car game. Hope you like this game.


Some information about this racing car game

📌 This is a professional racing car game that I used JavaScript programming language to make. I have also used some amount of HTML and CSS code for style.

📌 When you open the game, a page will open in front of you. Below are all the details on how to drive a car and how to control this game.


📌 Below are all the instructions on how to drive the car. Basically, it's a computer game. You can use your computer keyboard to play this game. The arrow keys on the keyboard allow it to move forward, backward, right, and left.

📌 I have used different types of music in the background of this game. You can change the music if you want. 

📌 If you want to turn off the music during the game, press "M" on the keyboard. 


📌 The game is basically a racing game so there are a lot of cars here. You will be the first in this game where you can control your own car and lose these cars. Below you can see how fast the car is moving when you drive.

 All in all, this is a great game that you will love.




Below I have shared with you how to make this game in three steps. You follow these steps and try to make this game yourself.

To create the game, you must first create an HTML file. Then copy and paste the structure given below into the HTML file. Then copy and paste the following HTML codes in the place where the add HTML code is written. 

Copy and paste the following CSS codes in the place where the ad CSS code is written. Then paste the following JavaScript codes in the place where Add JavaScript is written.

 


Add HTML code to create the structure of the game

A very small amount of HTML code has been used for the game. You copy the HTML code below and paste it where the ad HTML code is written above.


<div id="game">

  <div id="road">

    <div id="cloud"></div>
    <div id="hero"></div>

  </div>
<!--/*url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/-->
  <div id="hud">

    <span id="time" class="topUI">0</span>
    <span id="score" class="topUI">0</span>
    <span id="lap" class="topUI">0'00"000</span>
    <span id="tacho">0</span>

  </div>

  <div id="home">

    <h1>OutRun</h1>
    <p id="text"></p>

    <div id="highscore">

    </div>

  </div>

</div>
<!--/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/-->
<div id="controls">
  <span><span>C</span>insert coin</span>
  <span><span>M</span>mute</span>
  <span><span>&lt;</span><span>&gt;</span>move</span>
  <span><span>&lt;</span><span>&gt;</span>accelerate</span>
</div>


Add CSS code to make racing game stylish

Basically, some CSS code has been added to this game. You copy the code below and paste it where the ad CSS code is written above.


 body {
  background#222;
  font-family'Press Start 2P'monospace;
  font-smooth: never;
  height98vh;
}

/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
.topUI {
  positionabsolute;
  z-index1000/* need this cause clip-path changes stack context */
  transformtranslate(-50%25px);
  text-shadow-2px 0 black0 2px black2px 0 black0 -2px black;
  letter-spacing2px;
  color#fff;
  font-size17px;
}
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
.topUI::before {
  displayinline-block;
  height17px;
  padding1px 2px;
  line-height19px;
  font-size17px;
  background#fff;
  text-shadownone;
  font-weight900;
  letter-spacing0;
  border-radius6px;
  margin-right30px;
  border2px solid #7dd8c9;
}
#time{
  left13%;
  color#f4f430;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}
#time::before {
  content'TIME';
  color#f57214;
}
#score{
  left45%;
}
#score::before {
  content'SCORE';
  color#a61a9d;
}
#lap{
  left88%;
  width45%;
}
#lap::before {
  content'LAP';
  color#0082df;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}

#tacho {
  positionabsolute;
  text-alignright;
  width23%;
  bottom5%;
  z-index2000;
  color#e62e13;
  text-shadow-2px 0 black0 2px black2px 0 black0 -2px black;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  letter-spacing2px;
  font-size23px;
}
#tacho::after {
  content'km/h';
  color#fab453;
  font-size18px;
  margin-left5px;
}

/*
  road
*/
#game {
  positionrelative;
  margin0 auto;
  overflow:hidden;
  background#222;
  user-select:none;
  transition: opacity 10s;
}
#road {
  transition: opacity 2s;
  transition-timing-functionsteps(8, end);/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}
#road * {
  positionabsolute;
  image-renderingpixelated;
}
#hero {
  background-repeatno-repeat;
  background-position-110px 0;
  z-index2000;
  transformscale(1.4)
}
#cloud {
  background-sizeauto 100%;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  width100%;
  height57%;
}

/*
  home
*/
#road {
  positionabsolute;
  width100%;
  height100%;
}

#home {
  positionabsolute;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  color#fff;
  width100%;
  height100%;

  z-index1000/* need this cause clip-path changes stack context */
}

#highscore {
  positionabsolute;
  width100%;
  height20%;
  bottom0;
  column-count3;
  column-fillauto;
}

#highscore * {
  color#9e95a8;
  margin0 0 6px 27px;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}

h1 {
  positionabsolute;
  left50%;
  top25%;
  transformtranslate(-50%-50%);
  font-size5em;

  background-webkit-linear-gradient(#25d8b1#e2bbf0);/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  -webkit-background-cliptext;
  -webkit-text-fill-colortransparent
}

#text {
  positionabsolute;
  left50%;
  top50%;
  transformtranslate(-50%-50%);
  font-size1.2em;
  color#d9bbf3;
  text-shadow0 0 black0 2px black2px 0 black0 0 black;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}

.blink{animation: blinker 2s steps(4, end) infinite}
@keyframes blinker {
  50% {opacity0}
}

/*
  Guide
*/
#controls {
  color#868686;
  font-size13px;
  line-height13px;
  margin10px;
  text-aligncenter;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}
#controls > span {
  margin-left20px;
}
#controls > span > span {
  border2px solid #868686;
  border-radius5px;
  padding7px;
  margin-right10px;
  displayinline-block;/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}
#controls > span:last-child  > span {
  transformrotate(90deg);
}


Add JavaScript code to complete the game

 These javascript are the main components of this game. JavaScript controls everything in this game. How I used these codes and for what purpose I gave them in the middle of the code.

Copy the JavaScript codes below and add the JavaScript code in the structure above.


 // ------------------------------------------------------------
// assets
// ------------------------------------------------------------

const ASSETS = {
  
  COLOR: {
    TAR: ['#959298''#9c9a9d'],
    RUMBLE: ['#959298''#f5f2f6'],
    GRASS: ['#eedccd''#e6d4c5']    
  },
  
  IMAGE: {
    TREE: {
      src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/tree.png',/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
      width: 132,
      height: 192
    },
    HERO: {
      src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/hero.png',
      width: 110,
      height: 56
    },
    CAR: {
      src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/car04.png',/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
      width: 50,
      height: 36
    },
    FINISH: {
      src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/finish.png',
      width: 339,
      height: 180,
      offset: -.5
    },
    SKY: {
      src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/cloud.jpg'
    }
  },
    
  AUDIO: {
    theme: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/theme.mp3',/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    engine: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/engine.wav',
    honk: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/honk.wav',
    beep: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/155629/beep.wav'
  }
  
}

// ------------------------------------------------------------
// helper functions
// ------------------------------------------------------------

Number.prototype.pad = function(numZeroschar = 0) {
    let n = Math.abs(this)
    let zeros = Math.max(0numZeros - Math.floor(n).toString().length )/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    let zeroString = Math.pow(10zeros).toString().substr(1).replace(0char)
    return zeroString + n
}

Number.prototype.clamp = function(minmax) {
  return Math.max(minMath.min(thismax))
}

const timestamp = _ => new Date().getTime()
const accelerate = (vacceldt=> v + (accel * dt)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
const isCollide = (x1,w1,x2,w2=> (x1 - x2) ** 2 <= (w2 + w1) ** 2

function getRand(minmax) {
    return Math.random() * (max - min) + min | 0;
}

function randomProperty(obj) {
    let keys = Object.keys(obj)
    return obj[keyskeys.length * Math.random() << 0]]/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
}

function drawQuad(elementlayercolorx1y1w1x2y2w2) {
  element.style.zIndex = layer
  element.style.background = color
  element.style.top = y2 + `px`
  element.style.left = x1 - w1 / 2 - w1 + `px`
  element.style.width = w1 * 3 + `px`
  element.style.height = y1 - y2 + `px`

  let leftOffset = w1 + x2 - x1 + Math.abs(w2/2 - w1/2)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  element.style.clipPath = `polygon(${leftOffset}px 0, ${leftOffset + w2}px 0, 66.66% 100%, 33.33% 100%)`
}

const KEYS = {}
const keyUpdate = e => {
  KEYS[e.code] = e.type === `keydown`
  e.preventDefault()
}
addEventListener(`keydown`keyUpdate)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
addEventListener(`keyup`keyUpdate)

function sleep(ms) {
    return new Promise(function(resolvereject) {
        setTimeout(_ => resolve(), ms)
    })
}

// ------------------------------------------------------------
// objects
// ------------------------------------------------------------

class Line {

  constructor() {
    this.x = 0
    this.y = 0
    this.z = 0

    this.X = 0
    this.Y = 0
    this.W = 0

    this.curve = 0
    this.scale = 0

    this.elements = []
    this.special = null

  }
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  project(camXcamYcamZ) {
    this.scale = camD / (this.z - camZ)
    this.X = (1 + this.scale * (this.x - camX)) * halfWidth
    this.Y = Math.ceil( (1 - this.scale * (this.y - camY)) * height / 2 )/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    this.W = this.scale * roadW * halfWidth
  }

  clearSprites() {
    for(let e of this.elementse.style.background = 'transparent'
  }

  drawSprite(depthlayerspriteoffset) {

    let destX = this.X + this.scale * halfWidth * offset/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    let destY = this.Y + 4
    let destW = sprite.width * this.W / 265
    let destH = sprite.height * this.W / 265

    destX += destW * offset
    destY += destH * -1

    let obj = (layer instanceof Element) ? layer : this.elements[layer + 6]/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    obj.style.background = `url('${sprite.src}') no-repeat`
    obj.style.backgroundSize = `${destW}px ${destH}px`
    obj.style.left = destX + `px`
    obj.style.top = destY + `px`
    obj.style.width = destW + `px`
    obj.style.height = destH + `px`
    obj.style.zIndex = depth

  }

}
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
class Car {

  constructor(postypelane) {

    this.pos = pos
    this.type = type
    this.lane = lane

    var element = document.createElement('div')
    road.appendChild(element)
    this.element = element

  }

}

 class Audio {

  constructor() {

    this.audioCtx = new AudioContext()/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

    // volume
    this.destination = this.audioCtx.createGain()
    this.volume = 1
    this.destination.connectthis.audioCtx.destination )

    this.files = {}

    let _self = this
    this.load(ASSETS.AUDIO.theme'theme'function(key) {

      let source = _self.audioCtx.createBufferSource()/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
      source.buffer = _self.files[key]

      let gainNode = _self.audioCtx.createGain()
      gainNode.gain.value = .6
      source.connect(gainNode)
      gainNode.connect(_self.destination)

      source.loop = true
      source.start(0)

    })

  }
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  get volume() {
    return this.destination.gain.value
  }

  set volume(level) {
    this.destination.gain.value = level
  }


  play(keypitch) {
    if (this.files[key]) {
      let source = this.audioCtx.createBufferSource()/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
      source.buffer = this.files[key]
      source.connect(this.destination)
      if(pitchsource.detune.value = pitch
      source.start(0)
    } else this.load(key, () => this.play(key))/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  }
 
  load(srckeycallback) {
    let _self = this
    let request = new XMLHttpRequest()
    request.open('GET'srctrue)
    request.responseType = 'arraybuffer'
    request.onload = function() {
      _self.audioCtx.decodeAudioData(request.responsefunction(beatportBuffer) {
        _self.files[key] = beatportBuffer
        callback(key)
      }, function() {})
    }/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    request.send()
  }
}

// ------------------------------------------------------------
// global varriables
// ------------------------------------------------------------

const highscores = []

const width = 800
const halfWidth = width / 2
const height = 500
const roadW = 4000
const segL = 200
const camD = 0.2
const H = 1500
const N = 70
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
const maxSpeed = 200
const accel = 38
const breaking = -80
const decel = -40
const maxOffSpeed = 40
const offDecel = -70
const enemy_speed = 8
const hitSpeed = 20

const LANE = {
  A: -2.3,
  B: -.5,
  C: 1.2
}
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
const mapLength = 15000


// loop
let then = timestamp()
const targetFrameRate = 1000 / 25 // in ms

let audio

// game
let inGamestartplayerXspeedscoreValposcloudOffsetsectionProgmapIndexcountDown
let lines = []
let cars = []
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

// ------------------------------------------------------------
// map
// ------------------------------------------------------------

function getFun(val) {
  return i => val
}

function genMap() {

  let map = []

  for(var i = 0i < mapLengthi += getRand(050)) {

    let section = {
      from: i,
      to: (i = i + getRand(300600))
    }

    let randHeight = getRand(-55)
    let randCurve = getRand(530) * ((Math.random() >= .5) ? 1 : -1)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    let randInterval = getRand(2040)

    if(Math.random() > .9Object.assign(section, {curve: _ => randCurveheight: _ => randHeight})
    else if(Math.random() > .8Object.assign(section, {curve: _ => 0height: i => Math.sin(i/randInterval)*1000})
    else if(Math.random() > .8Object.assign(section, {curve: _ => 0height: _ => randHeight})
    else Object.assign(section, {curve: _ => randCurveheight: _ => 0})/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

    map.push(section)
  }

  map.push({from: ito: i + Ncurve: _ => 0height: _ => 0special: ASSETS.IMAGE.FINISH})
  map.push({from: Infinity})
  return map

}

let map = genMap()

// ------------------------------------------------------------
// additional controls
// ------------------------------------------------------------/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

addEventListener(`keyup`function(e){

  if(e.code === 'KeyM') {
    e.preventDefault()

    audio.volume = (audio.volume === 0) ? 1 : 0
    return
  }

  if(e.code === 'KeyC') {
    e.preventDefault()

    if(inGamereturn

    sleep(0).then(_ => {
      text.classList.remove('blink')/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
      text.innerText = 3
      audio.play('beep')
      return sleep(1000)
    }).then(_ => {
      text.innerText = 2
      audio.play('beep')
      return sleep(1000)
    }).then(_ => {

      reset()

      home.style.display = 'none'

      road.style.opacity = 1
      hero.style.display = 'block'
      hud.style.display = 'block'
                                                         /*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
      audio.play('beep'500)

      inGame = true

    })

    return
  }

  if(e.code === 'Escape') {
    e.preventDefault()

    reset()
  }


})

// ------------------------------------------------------------/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
// game loop
// ------------------------------------------------------------

function update(step) {

  // prepare this iteration
  pos += speed
  while (pos >= N * segLpos -= N * segL
  while (pos < 0pos += N * segL

  var startPos = (pos / segL)  | 0
  let endPos = (startPos + N - 1) % N

  scoreVal += speed*step
  countDown -= step

  // left / right position/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  playerX -= lines[startPos].curve / 5000 * step * speed

  if(KEYS.ArrowRighthero.style.backgroundPosition = '-220px 0'playerX+=.007*step*speed
  else if(KEYS.ArrowLefthero.style.backgroundPosition = '0 0'playerX-=.007*step*speed
  else hero.style.backgroundPosition = '-110px 0'

  playerX = playerX.clamp(-33)

  // speed

  if(inGame && KEYS.ArrowUpspeed = accelerate(speedaccelstep)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  else if(KEYS.ArrowDownspeed = accelerate(speedbreakingstep)
  else speed = accelerate(speeddecelstep)

  if(Math.abs(playerX) > 0.55 && speed >= maxOffSpeed) {
    speed = accelerate(speedoffDecelstep)
  }

  speed = speed.clamp(0maxSpeed)

  // update map
  let current = map[mapIndex]                                          /*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  let use = current.from < scoreVal && current.to > scoreVal
  if(usesectionProg += speed*step
  lines[endPos].curve = use ? current.curve(sectionProg) : 0
  lines[endPos].y = use ? current.height(sectionProg) : 0
  lines[endPos].special = null

  if(current.to <= scoreVal) {
    mapIndex++
    sectionProg = 0

    lines[endPos].special = map[mapIndex].special

  }                                                               /*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

  // win / lose + UI

  if(!inGame) {

    speed = accelerate(speedbreakingstep)
    speed = speed.clamp(0maxSpeed)

  } else if(countDown <= 0 || lines[startPos].special) {

    tacho.style.display = 'none'
                                                                   /*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    home.style.display = 'block'
    road.style.opacity = .4
    text.innerText = 'INSERT COIN'

    highscores.push(lap.innerText)                          /*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    highscores.sort()
    updateHighscore()

    inGame = false

  } else {

    time.innerText = (countDown|0).pad(3)
    score.innerText = (scoreVal|0).pad(8)
    tacho.innerText = speed | 0

    let cT = new Date(timestamp() - start)
    lap.innerText = `${cT.getMinutes()}'${cT.getSeconds().pad(2)}"${cT.getMilliseconds().pad(3)}`/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

  }


  // sound
  if(speed > 0audio.play('engine'speed * 4)

  // draw cloud
  cloud.style.backgroundPosition = `${ (cloudOffset -= lines[startPos].curve * step * speed * .13) | 0}px 0`

  // other cars
  for(let car of cars) {

    car.pos = (car.pos + enemy_speed * step) % N

    // respawn
    if( (car.pos|0) === endPos) {
      if(speed < 30car.pos = startPos
      else car.pos = endPos - 2
      car.lane = randomProperty(LANE)
    }
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    // collision
    const offsetRatio = 5
    if((car.pos|0) === startPos && isCollide(playerX * offsetRatio + LANE.B.5car.lane.5)) {
      speed = Math.min(hitSpeedspeed)
      if(inGameaudio.play('honk')
    }

  }

  // draw road
  let maxy = height
  let camH = H + lines[startPos].y
  let x = 0
  let dx = 0

  for (let n = startPosn < startPos + Nn++) {

    let l = lines[n % N]
    let level = N * 2 - n

    // update view
    l.project(playerX * roadW - xcamHstartPos * segL - (n >= N ? N * segL : 0))/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
    x += dx
    dx += l.curve

    // clear assets
    l.clearSprites()

    // first draw section assets
    if(n % 10 === 0l.drawSprite(level0ASSETS.IMAGE.TREE, -2)
    if((n + 5) % 10 === 0l.drawSprite(level0ASSETS.IMAGE.TREE1.3)

    if(l.speciall.drawSprite(level0l.speciall.special.offset||0)

    for(let car of carsif((car.pos|0) === n % Nl.drawSprite(levelcar.elementcar.typecar.lane)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

    // update road

    if (l.Y >= maxy ) continue
    maxy = l.Y

    let even = ((n / 2) | 0) % 2
    let grass = ASSETS.COLOR.GRASS[even * 1]
    let rumble = ASSETS.COLOR.RUMBLE[even * 1]
    let tar = ASSETS.COLOR.TAR[even * 1]

    let p = lines[(n - 1) % N]

    drawQuad(l.elements[0], levelgrasswidth / 4p.YhalfWidth + 2width / 4l.YhalfWidth)
    drawQuad(l.elements[1], levelgrasswidth / 4 * 3p.YhalfWidth + 2width / 4 * 3l.YhalfWidth)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

    drawQuad(l.elements[2], levelrumblep.Xp.Yp.W * 1.15l.Xl.Yl.W * 1.15)
    drawQuad(l.elements[3], leveltarp.X,p.Yp.Wl.Xl.Yl.W)

    if(!even) {
      drawQuad(l.elements[4], levelASSETS.COLOR.RUMBLE[1], p.Xp.Yp.W * .4l.Xl.Yl.W * .4)
      drawQuad(l.elements[5], leveltarp.Xp.Yp.W * .35l.Xl.Yl.W * .35)
    }

  }

}

// ------------------------------------------------------------/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
// init
// ------------------------------------------------------------

function reset() {

  inGame = false

  start = timestamp()
  countDown = map[map.length - 2].to / 130 + 10

  playerX = 0
  speed = 0
  scoreVal = 0

  pos = 0
  cloudOffset = 0
  sectionProg = 0
  mapIndex = 0

  for(let line of linesline.curve = line.y = 0

  text.innerText = 'INSERT COIN'
  text.classList.add('blink')

  road.style.opacity = .4
  hud.style.display = 'none'
  home.style.display = 'block'
  tacho.style.display = 'block'

}
/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
function updateHighscore() {
  let hN = Math.min(12highscores.length)
  for(let i = 0i < hNi++) {
    highscore.children[i].innerHTML = `${(i+1).pad(2'&nbsp;')}${highscores[i]}`
  }
}

function init() {

  game.style.width = width + 'px'
  game.style.height = height + 'px'
                                                                            /*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
  hero.style.top = height - 80 + 'px'
  hero.style.left = halfWidth - ASSETS.IMAGE.HERO.width / 2 + 'px'
  hero.style.background = `url(${ASSETS.IMAGE.HERO.src})`
  hero.style.width = `${ASSETS.IMAGE.HERO.width}px`
  hero.style.height = `${ASSETS.IMAGE.HERO.height}px`

  cloud.style.backgroundImage = `url(${ASSETS.IMAGE.SKY.src})`
  
  audio = new Audio
  Object.keys(ASSETS.AUDIO).forEach(key => audio.load(ASSETS.AUDIO[key], key_=>0))/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

  cars.push(new Car(0ASSETS.IMAGE.CARLANE.C))
  cars.push(new Car(10ASSETS.IMAGE.CARLANE.B))
  cars.push(new Car(20ASSETS.IMAGE.CARLANE.C))
  cars.push(new Car(35ASSETS.IMAGE.CARLANE.C))
  cars.push(new Car(50ASSETS.IMAGE.CARLANE.A))
  cars.push(new Car(60ASSETS.IMAGE.CARLANE.B))
  cars.push(new Car(70ASSETS.IMAGE.CARLANE.A))

  for (let i = 0i < Ni++) {
    var line = new Line
    line.z = i * segL + 270

    for (let j = 0j < 6 + 2j++) {
      var element = document.createElement('div')/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/
      road.appendChild(element)
      line.elements.push(element)
    }

    lines.push(line)

  }

  for(let i = 0i < 12i++) {
    var element = document.createElement('p')
    highscore.appendChild(element)
  }
  updateHighscore()

  reset()

  // START GAME LOOP
  ;(function loop(){
    requestAnimationFrame(loop)/*obj.style.background = `url('${sprite.src}') no-repeat`obj.style.backgroundSize = `${destW}px ${destH}px`obj.style.left = destX + `px`obj.style.top = destY + `px`obj.style.width = destW + `px`obj.style.height = destH + `px`obj.style.zIndex = depth*/

    let now = timestamp()
    let delta = now - then

    if (delta > targetFrameRate) {
      then = now - (delta % targetFrameRate)
      update(delta / 1000)
    }

  })()

}
                                                           
init()



Hopefully, you have followed the above three steps beautifully. By following these three steps you can easily create this racing car game using this simple HTML, CSS, and JavaScript programming code.


❤Sharing is caring❤