Skip to content

Drifting car

I was experimenting with the technique of rendering fading trails to an off-screen canvas... before realizing I've made a car. Good excuse to try to make a reasonable mobile control scheme—left third of the screen maps to the left arrow, and likewise for the other three edge.

A box-y car with unrealistic handling, leaving thick back trails whereever it goes

Drfiting car? More like a car in snow!

function setup() {
  createCanvas(windowWidth, windowHeight);
  scene = window;
  track = createGraphics(windowWidth, windowHeight)
  track.background(220)
  track.noStroke()
  track.fill(0)
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight)
  track.resizeCanvas(windowWidth, windowHeight)
  track.background(220)
}

let scene
let track
let player = {x: 0, y: 0, a: - Math.PI / 2, vx: 0, vy: 0, va: 0, breaking: false}
let touchAreasFrame = 0

function draw() {
  track.background(220, 1)
  
  let controls = {
    up: keyIsDown(UP_ARROW),
    down: keyIsDown(DOWN_ARROW),
    left: keyIsDown(LEFT_ARROW),
    right: keyIsDown(RIGHT_ARROW),
  }
  for (let touch of touches) {
    if (touch.x < width / 3 && touch.x > 0) {
      controls.left = true
    }
    if (touch.x > width / 3 * 2 && touch.x < width) {
      controls.right = true
    }
    if (touch.y < height / 3 && touch.y > 0) {
      controls.up = true
    }
    if (touch.y > height / 3 * 2 && touch.y < height) {
      controls.down = true
    }
  }
  
  fill(255)
  stroke(0)
  
  for (let subframe = 0; subframe < 2; subframe ++) {
    resetMatrix()
    image(track, 0, 0)
    track.resetMatrix()
    
    for (let what of [scene, track]) {
      what.translate(player.x + width/2, player.y + height/2)
      what.rotate(player.a)
      what.rectMode(CENTER)
    }

    //scene.rect(-10, 0, 30, 20)

    let ax = cos(player.a)
    let ay = sin(player.a)

    let lx = player.vx * ax + player.vy * ay
    let ly = - player.vx * ay + player.vy * ax
    let movement = (controls.up - controls.down * 0.7)
    if (movement != 0) {
      if (player.breaking && movement * lx < 0.0) {
        lx *= 0.95
      } else {
        // lx += movement * (0.005 + min(movement * lx, 3) * 0.015)
        lx += movement * 0.04
      }
    } else {
      player.breaking = abs(lx) > 0.03
    }
    lx *= 0.99
    push()
    resetMatrix()
    textAlign(RIGHT, TOP)
    text(round(lx * 100), width, 0)
    pop()
    
    let turning = (controls.right - controls.left)
    player.va += turning * map(abs(lx) ** 0.5, 3, 0, 0.01, 0.02)
    player.va *= 0.95
    
    player.a += lx * player.va * 0.05
    ly *= 0.96
    player.vx = lx * ax - ly * ay
    player.vy = lx * ay + ly * ax
    player.x += player.vx
    player.y += player.vy

    for (let what of [scene, track]) {
      for (let side of [10, -10]) {
        what.push()
        what.translate(0, side * 0.8)
        what.rotate(player.va * 1)
        what.rect(0, side * 0.2, 10, 3)
        what.pop()
        what.rect(-20, side, 10, 3)
      }
    }

    rect(-10, 0, 30, 20)
  }
  
  if (touches.length > 0 && touchAreasFrame == 0) {
    touchAreasFrame = 1
  }
  if (touchAreasFrame > 0 && touchAreasFrame < 80) {
    touchAreasFrame++
    noStroke()
    fill(0, (1 - cos(touchAreasFrame/40*PI*2)) * 15)
    resetMatrix()
    rectMode(CORNER)
    rect(0, 0, width / 3, height)
    rect(width / 3 * 2, 0, width / 3, height)
    rect(0, 0, width, height / 3)
    rect(0, height / 3 * 2, width, height / 3)
  }
}

(Originally seen at https://editor.p5js.org/bojidar-bg/sketches/2Fpfg_KmB)

Experiments tagged p5 (12/85)

Experiments tagged interactive (5/26)

|← Experiments tagged touchscreen (1/1) →|

Experiments on this site (12/85)