рдПрдХ рдЫрджреНрдо 3 рдбреА рд░реЗрд╕рд┐рдВрдЧ рдЧреЗрдо рдмрдирд╛рдирд╛: рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдФрд░ рдЦреЗрд▓ рдХреЛ рдЦрддреНрдо рдХрд░рдирд╛

рднрд╛рдЧ 3. рдкрд╣рд╛рдбрд╝рд┐рдпрд╛рдБ



рдкрд┐рдЫрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЫрджреНрдо рддреНрд░рд┐-рдЖрдпрд╛рдореА рд░реЗрд╕рд┐рдВрдЧ рдЧреЗрдо рдмрдирд╛рдпрд╛ , рдЬрд┐рд╕рдореЗрдВ рд╕реАрдзреА рд╕рдбрд╝рдХреЛрдВ рдФрд░ рдШрдЯрддрд╛ рдХреЛ рд╕рд╛рдХрд╛рд░ рдХрд┐рдпрд╛ред

рдЗрд╕ рдмрд╛рд░ рд╣рдо рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреА рджреЗрдЦрднрд╛рд▓ рдХрд░реЗрдВрдЧреЗ; рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдШреБрдорд╛рд╡рджрд╛рд░ рд╕рдбрд╝рдХреЗрдВ рдмрдирд╛рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдпрд╣ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ред

рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рддреНрд░рд┐-рдЖрдпрд╛рдореА рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдп рдкреНрд░рдХреНрд╖реЗрдкрдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рддреНрд░рд┐рднреБрдЬреЛрдВ рдХреЗ рдирд┐рдпрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛:


... рдЬреЛ рд╣рдореЗрдВ 2 рдбреА рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рдордиреНрд╡рдп рдореЗрдВ 3 рдбреА рджреБрдирд┐рдпрд╛ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдореАрдХрд░рдгреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреЗрддреГрддреНрд╡ рдХрд░рддрд╛ рдерд╛ред


... рд▓реЗрдХрд┐рди рддрдм рд╕реЗ рд╣рдордиреЗ рдХреЗрд╡рд▓ рд╕реАрдзреА рд╕рдбрд╝рдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛, рджреБрдирд┐рдпрд╛ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рдХреЗрд╡рд▓ z рдШрдЯрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА , рдХреНрдпреЛрдВрдХрд┐ x рдФрд░ y рджреЛрдиреЛрдВ рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ рдереЗред

рдпрд╣ рд╣рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ рд╡реЗ рд╕рдбрд╝рдХ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рдЧреИрд░-рдСрдиреЗрд╕реНрдЯреЛ рд╕рдордиреНрд╡рдп y рджреЗрдВ , рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдореМрдЬреВрджрд╛ рдлрд╝рдВрдХреНрд╢рди render()рдЬрд╛рджреБрдИ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛ ред


рд╣рд╛рдБ, рдпрд╣ рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдмрд╕ рдкреНрд░рддреНрдпреЗрдХ рд╕рдбрд╝рдХ рдЦрдВрдб рдХреЗ рд╡рд┐рд╢реНрд╡ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд▓рд┐рдП y рдШрдЯрдХ рдЬреЛрдбрд╝реЗрдВ ред

рд╕рдбрд╝рдХ рдЬреНрдпрд╛рдорд┐рддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди


рд╣рдо рдореМрдЬреВрджрд╛ рдкрджреНрдзрддрд┐ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВрдЧреЗ, addSegmentрддрд╛рдХрд┐ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди P2.world.y , рдФрд░ p1.world.y рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╛рдЧ рдХреЗ P2.world.y рд╕реЗ рдореЗрд▓ рдЦрд╛ рд╕рдХреЗ :

function addSegment(curve, y) {
  var n = segments.length;
  segments.push({
     index: n,
        p1: { world: { y: lastY(), z:  n   *segmentLength }, camera: {}, screen: {} },
        p2: { world: { y: y,       z: (n+1)*segmentLength }, camera: {}, screen: {} },
     curve: curve,
     color: Math.floor(n/rumbleLength)%2 ? COLORS.DARK : COLORS.LIGHT
  });
}

function lastY() {
  return (segments.length == 0) ? 0 : segments[segments.length-1].p2.world.y;
}

рдХрдо ( LOW), рдордзреНрдпрдо ( MEDIUM) рдФрд░ рдЙрдЪреНрдЪ ( HIGH) рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЛ рдирд┐рд░реВрдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рд░рд╛рдВрдХ рдЬреЛрдбрд╝реЗрдВ :

var ROAD = {
  LENGTH: { NONE: 0, SHORT:  25, MEDIUM:  50, LONG:  100 },
  HILL:   { NONE: 0, LOW:    20, MEDIUM:  40, HIGH:   60 },
  CURVE:  { NONE: 0, EASY:    2, MEDIUM:   4, HARD:    6 }
};

рдореМрдЬреВрджрд╛ рдкрджреНрдзрддрд┐ рдХреЛ рдмрджрд▓реЗрдВ addRoad()рддрд╛рдХрд┐ рдпрд╣ рддрд░реНрдХ рд╡рд╛рдИ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗ , рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд╣рд╛рдбрд╝реА рд╕реЗ рдХреНрд░рдорд┐рдХ рдЪрдврд╝рд╛рдИ рдФрд░ рд╡рдВрд╢ рдХреЗ рд▓рд┐рдП рдЪрд┐рдХрдирд╛рдИ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:

function addRoad(enter, hold, leave, curve, y) {
  var startY   = lastY();
  var endY     = startY + (Util.toInt(y, 0) * segmentLength);
  var n, total = enter + hold + leave;
  for(n = 0 ; n < enter ; n++)
    addSegment(Util.easeIn(0, curve, n/enter), Util.easeInOut(startY, endY, n/total));
  for(n = 0 ; n < hold  ; n++)
    addSegment(curve, Util.easeInOut(startY, endY, (enter+n)/total));
  for(n = 0 ; n < leave ; n++)
    addSegment(Util.easeInOut(curve, 0, n/leave), Util.easeInOut(startY, endY, (enter+hold+n)/total));
}

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдордиреЗ рднрд╛рдЧ 2 рдПрд╕ рдореЗрдВ рдЬреЛ рдХреБрдЫ рдХрд┐рдпрд╛, рдЙрд╕рдХреЗ рд╕рдорд╛рди addSCurves(), рд╣рдо рдЬреНрдпрд╛рдорд┐рддрд┐ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХрд┐рд╕реА рднреА рддрд░реАрдХреЗ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

function addLowRollingHills(num, height) {
  num    = num    || ROAD.LENGTH.SHORT;
  height = height || ROAD.HILL.LOW;
  addRoad(num, num, num,  0,  height/2);
  addRoad(num, num, num,  0, -height);
  addRoad(num, num, num,  0,  height);
  addRoad(num, num, num,  0,  0);
  addRoad(num, num, num,  0,  height/2);
  addRoad(num, num, num,  0,  0);
}

рдЕрджреНрдпрддрди рд╡рд┐рдзрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди


рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдП рдЬрд╛ рд░рд╣реЗ рдЖрд░реНрдХреЗрдб рдЧреЗрдо рдореЗрдВ, рд╣рдо рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдЦрд┐рд▓рд╛рдбрд╝реА рдпрд╛ рдЦреЗрд▓ рдХреА рджреБрдирд┐рдпрд╛ рдХреЛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддреА рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡рд┐рдзрд┐ рдореЗрдВ update()рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдкрд╣рд╛рдбрд╝реА рдкреНрд░рддрд┐рдкрд╛рджрди


рд╡рд┐рдзрд┐ рдХреЛ render()рднреА рдХрд┐рд╕реА рднреА рдмрджрд▓рд╛рд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рдХреНрд╖реЗрдкрдг рд╕рдореАрдХрд░рдгреЛрдВ рдХреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ рддрд╛рдХрд┐ рдЧреИрд░-рд╢реВрдиреНрдп y рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд╕рд╛рде рд╕рдбрд╝рдХ рдЦрдВрдбреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ ред

рд▓рдВрдмрди рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдкреГрд╖реНрдарднреВрдорд┐


рд╕рднреА рд╕рдбрд╝рдХ рдЦрдВрдбреЛрдВ рдореЗрдВ y рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ , рдХреЗрд╡рд▓ рдкрд░рд┐рд╡рд░реНрддрди рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдкреГрд╖реНрдарднреВрдорд┐ рдХреА рдкрд░рддреЛрдВ рдХреЗ рдКрд░реНрдзреНрд╡рд╛рдзрд░ рд╡рд┐рд╕реНрдерд╛рдкрди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реЛрдЧрд╛ (рдЬреИрд╕реЗ рд╡реЗ рдШрдЯрддрд╛ рдХреЗ рд╕рд╛рде рдХреНрд╖реИрддрд┐рдЬ рд░реВрдк рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ)ред рд╣рдо рдЗрд╕реЗ рд╣реЗрд▓реНрдкрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдПрдХ рдЕрдиреНрдп рддрд░реНрдХ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ Render.backgroundред

рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрдВрддреНрд░ рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рд╛рдорд╛рдиреНрдп рдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛ рд╡рд┐рд╕реНрдерд╛рдкрди рд╣реЛрдЧрд╛ playerY(рдЬрд┐рд╕реЗ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рд╡рд┐рд╢реНрд╡ рд╕реНрдерд┐рддрд┐рдпреЛрдВ y рд╕реЗ рдкреНрд░рдХреНрд╖реЗрдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП )ред

рдпрд╣ рд╕рдмрд╕реЗ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рдВрднрд╡рддрдГ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд╕рдбрд╝рдХ рдХреЗ рд╡рд░реНрддрдорд╛рди рдЦрдВрдб рдХреЗ рдврд▓рд╛рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдкреНрд░рднрд╛рд╡ рд╕рд░рд▓ рд╣реИ рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдбреЗрдореЛ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣ рд╕рдм рд╣реИ, рдЕрдм рд╣рдо рдЕрд╕рд▓реА рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдирдХрд▓реА рдШрдЯреЛрдВ рдХреЛ рдкреВрд░рдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрдорд╛рдирд┐рдд 3 рдбреА рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рд╕рд╣рд┐рдд рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХрд╛рдо, рдореИрдВрдиреЗ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рдирд╣реАрдВ рдмрддрд╛рдпрд╛ рдерд╛ред

рд▓реЗрдЦ рдХреЗ рдЕрдВрддрд┐рдо рднрд╛рдЧ рдореЗрдВ рд╣рдо рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕, рд╕рд╛рде рд╣реА рд╕рдбрд╝рдХ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдкреЗрдбрд╝реЛрдВ рдФрд░ рд╣реЛрд░реНрдбрд┐рдВрдЧ рдХреЛ рдЬреЛрдбрд╝реЗрдВрдЧреЗред рд╣рдо рдЕрдиреНрдп рдХрд╛рд░реЛрдВ рдХреЛ рднреА рдЬреЛрдбрд╝реЗрдВрдЧреЗ рдЬрд┐рдирдХреЗ рдЦрд┐рд▓рд╛рдл рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзрд╛ рдХрд░рдирд╛, рдЯрдХрд░рд╛рд╡реЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдирд╛ рдФрд░ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ "рд╕рд░реНрдХрд▓ рд░рд┐рдХреЙрд░реНрдб" рдХреЛ рдареАрдХ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред

рднрд╛рдЧ 4. рддреИрдпрд╛рд░ рд╕рдВрд╕реНрдХрд░рдг



рдЗрд╕ рднрд╛рдЧ рдореЗрдВ рд╣рдо рдЬреЛрдбрд╝реЗрдВрдЧреЗ:

  • рдмрд┐рд▓рдмреЛрд░реНрдб рдФрд░ рдкреЗрдбрд╝
  • рдЕрдиреНрдп рдХрд╛рд░реЗрдВ
  • рдЯрдХрд░рд╛рд╡ рдХреА рдорд╛рдиреНрдпрддрд╛
  • рдХрд╛рд░реЛрдВ рдХреЗ рд░реБрдбрд┐рдореЗрдВрдЯрд░реА рдП.рдЖрдИ.
  • рд▓реИрдк рдЯрд╛рдЗрдорд░ рдФрд░ рд▓реИрдк рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рдлреЗрд╕

... рдФрд░ рдпрд╣ рдЕрдВрддрдд: рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ "рдЧреЗрдо" рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рдкрд░реНрдпрд╛рдкреНрдд рд╕реНрддрд░ рдХреА рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛ред

рдХреЛрдб рд╕рдВрд░рдЪрдирд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ


, /, Javascript.

. () , ...

тАж , , , , .



рднрд╛рдЧ 1 рдореЗрдВ, рдЦреЗрд▓ рдЪрдХреНрд░ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдордиреЗ рд╕рднреА рдХрд╛рд░реЛрдВ, рдкреЗрдбрд╝реЛрдВ рдФрд░ рд╣реЛрд░реНрдбрд┐рдВрдЧ рдореЗрдВ рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ рдЕрдкрд▓реЛрдб рдХреАред

рдЖрдк рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рднреА рдЫрд╡рд┐ рд╕рдВрдкрд╛рджрдХ рдореЗрдВ рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рднрдВрдбрд╛рд░рдг рдФрд░ рдПрдХ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЙрдкрдХрд░рдг рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХреЛ рд╕реМрдВрдкрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ рдХреЛ рд░реВрдмреА рдЬреЗрдо рд╕реНрдкреНрд░рд╛рдЗрдЯ-рдлреИрдХреНрдЯреНрд░реА рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рд░реЗрдХ рдХрд╛рд░реНрдп рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред

рдпрд╣ рдХрд╛рд░реНрдп рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЫрд╡рд┐ рдлрд╝рд╛рдЗрд▓реЛрдВ рд╕реЗ рд╕рдВрдпреБрдХреНрдд рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ x, y, w, h рдХреА рдЧрдгрдирд╛ рднреА рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╕реНрдерд┐рд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ SPRITES:

var SPRITES = {
  PALM_TREE:   { x:    5, y:    5, w:  215, h:  540 },
  BILLBOARD08: { x:  230, y:    5, w:  385, h:  265 },

  // ... etc

  CAR04:       { x: 1383, y:  894, w:   80, h:   57 },
  CAR01:       { x: 1205, y: 1018, w:   80, h:   56 },
};

рд╣реЛрд░реНрдбрд┐рдВрдЧ рдФрд░ рдкреЗрдбрд╝ рдЬреЛрдбрд╝рдирд╛


рд╕рдбрд╝рдХ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдореЗрдВ рдПрдХ рд╕рд░рдгреА рдЬреЛрдбрд╝реЗрдВ рдЬрд┐рд╕рдореЗрдВ рд╕рдбрд╝рдХ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╣реЛрдВрдЧреЗред

рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ sourceрдореЗрдВ рд╕рдВрдЧреНрд░рд╣ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ SPRITES, рд╕рд╛рде рдореЗрдВ рдПрдХ рдХреНрд╖реИрддрд┐рдЬ рдСрдлрд╕реЗрдЯ offset, рдЬрд┐рд╕реЗ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ -1 рд╕рдбрд╝рдХ рдХреЗ рдмрд╛рдПрдВ рдХрд┐рдирд╛рд░реЗ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ +1 рдХрд╛ рдЕрд░реНрде рд╣реИ рджрд╛рд╣рд┐рдиреЗ рдХрд┐рдирд╛рд░реЗ, рдЬреЛ рд╣рдореЗрдВ рдореВрд▓реНрдп рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ roadWidthред

рдХреБрдЫ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЛ рдЬрд╛рдирдмреВрдЭрдХрд░ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рджреВрд╕рд░реЛрдВ рдХреЛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

function addSegment() {
  segments.push({
    ...
    sprites: [],
    ...
  });
}

function addSprite(n, sprite, offset) {
  segments[n].sprites.push({ source: sprite, offset: offset });
}

function resetSprites() {

  addSprite(20,  SPRITES.BILLBOARD07, -1);
  addSprite(40,  SPRITES.BILLBOARD06, -1);
  addSprite(60,  SPRITES.BILLBOARD08, -1);
  addSprite(80,  SPRITES.BILLBOARD09, -1);
  addSprite(100, SPRITES.BILLBOARD01, -1);
  addSprite(120, SPRITES.BILLBOARD02, -1);
  addSprite(140, SPRITES.BILLBOARD03, -1);
  addSprite(160, SPRITES.BILLBOARD04, -1);
  addSprite(180, SPRITES.BILLBOARD05, -1);

  addSprite(240, SPRITES.BILLBOARD07, -1.2);
  addSprite(240, SPRITES.BILLBOARD06,  1.2);

  
  for(n = 250 ; n < 1000 ; n += 5) {
    addSprite(n, SPRITES.COLUMN, 1.1);
    addSprite(n + Util.randomInt(0,5), SPRITES.TREE1, -1 - (Math.random() * 2));
    addSprite(n + Util.randomInt(0,5), SPRITES.TREE2, -1 - (Math.random() * 2));
  }

  ...
}

рдиреЛрдЯ: рдпрджрд┐ рд╣рдо рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЧреЗрдо рдмрдирд╛ рд░рд╣реЗ рдереЗ, рддреЛ рд╣рдо рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдФрд░ рдШрдЯрддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдирдХреНрд╢рд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдбрд╝рдХ рд╕рдВрдкрд╛рджрдХ рдХреЛ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рд╕рдбрд╝рдХ рдХреЗ рд╕рд╛рде рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рддрдВрддреНрд░ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ ... рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ addSprite()ред

рдорд╢реАрдиреЗрдВ рдЬреЛрдбрд╝рдирд╛


рд╕рдбрд╝рдХ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдкрд░ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдЬреЛрдбрд╝реЗрдВрдЧреЗ рдЬреЛ рд░рд╛рдЬрдорд╛рд░реНрдЧ рдкрд░ рд╕рднреА рдХрд╛рд░реЛрдВ рдХреЗ рдПрдХ рдЕрд▓рдЧ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд▓реЗрдВрдЧреЗ ред

var cars      = [];  // array of cars on the road
var totalCars = 200; // total number of cars on the road

function addSegment() {
  segments.push({
    ...
    cars: [], // array of cars within this segment
    ...
  });
}

рджреЛ рдСрдЯреЛрдореЛрдмрд╛рдЗрд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рднрдВрдбрд╛рд░рдг рд╣рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдЪрд▓рдиреЗ-рдлрд┐рд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рддрд░реАрдХреЗ рд╕реЗ рд╕рднреА рдХрд╛рд░реЛрдВ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рдПрдВ update(), рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕реЗрдЧрдореЗрдВрдЯ рд╕реЗ рджреВрд╕рд░реЗ рд╕реНрдерд╛рди рдкрд░ рд▓реЗ рдЬрд╛рдПрдВ; рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рдпрд╣ рд╣рдореЗрдВ render()рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдкрд░ рдХреЗрд╡рд▓ рдорд╢реАрдиреЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ ред

рдкреНрд░рддреНрдпреЗрдХ рдорд╢реАрди рдХреЛ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХреНрд╖реИрддрд┐рдЬ рдкрд╛рд░реА, z рд╕реНрдерд┐рддрд┐, рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╕реНрд░реЛрдд рдФрд░ рдЧрддрд┐ рджреА рдЬрд╛рддреА рд╣реИ:

function resetCars() {
  cars = [];
  var n, car, segment, offset, z, sprite, speed;
  for (var n = 0 ; n < totalCars ; n++) {
    offset = Math.random() * Util.randomChoice([-0.8, 0.8]);
    z      = Math.floor(Math.random() * segments.length) * segmentLength;
    sprite = Util.randomChoice(SPRITES.CARS);
    speed  = maxSpeed/4 + Math.random() * maxSpeed/(sprite == SPRITES.SEMI ? 4 : 2);
    car = { offset: offset, z: z, sprite: sprite, speed: speed };
    segment = findSegment(car.z);
    segment.cars.push(car);
    cars.push(car);
  }
}

рдкрд╣рд╛рдбрд╝реА рдкреНрд░рддрд┐рдкрд╛рджрди (рд╡рд╛рдкрд╕реА)


рдкрд┐рдЫрд▓реЗ рд╣рд┐рд╕реНрд╕реЛрдВ рдореЗрдВ, рдореИрдВрдиреЗ рд╕рдбрд╝рдХ рдХреЗ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреА рдмрд╛рдд рдХреА, рдЬрд┐рд╕рдореЗрдВ рдХрд░реНрд╡реНрд╕ рдФрд░ рд╣рд┐рд▓реНрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рдХреЛрдб рдХреА рдХреБрдЫ рд▓рд╛рдЗрдиреЗрдВ рдереАрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВрдиреЗ рдирд╣реАрдВ рдорд╛рдирд╛ред рдЙрдиреНрд╣реЗрдВ maxyрд╕реНрдХреНрд░реАрди рдХреЗ рдиреАрдЪреЗ рд╕реЗ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдПрдХ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреА рдЪрд┐рдВрддрд╛ рдереА , рд▓реЗрдХрд┐рди рд╕реНрдХреНрд░реАрди рдХреЗ рдХрд┐рд╕ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдерд╛, рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╕рдордп рдШрдЯрддреЗ рд╣реБрдП:

for(n = 0 ; n < drawDistance ; n++) {

  ...

  if ((segment.p1.camera.z <= cameraDepth) || // behind us
      (segment.p2.screen.y >= maxy))          // clip by (already rendered) segment
    continue;

  ...

  maxy = segment.p2.screen.y;
}

рдпрд╣ рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдлрд╕рд▓ рдЦрдВрдбреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдХрд▓рд╛рдХрд╛рд░ рдХреЗ

рдкрд╛рд░рдВрдкрд░рд┐рдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдореЗрдВ, рд░реЗрдВрдбрд░рд┐рдВрдЧ рдЖрдо рддреМрд░ рдкрд░ рд╕рд╛рдордиреЗ рдХреА рдУрд░ рд╣реЛрддреА рд╣реИ, рдЬрдмрдХрд┐ рдХрд░реАрдм рд╕реЗрдЧрдореЗрдВрдЯ рджреВрд░ рдХреЗ рд▓реЛрдЧреЛрдВ рдХреЛ рдУрд╡рд░рд▓реИрдк рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╣рдо рдмрд╣реБрднреБрдЬ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдореЗрдВ рд╕рдордп рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдВрддрддрдГ рдУрд╡рд░рд░рд╛рдЗрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдЖрдЧреЗ рд╕реЗ рдкреАрдЫреЗ рдФрд░ рдлрд╕рд▓ рдХреЗ рджреВрд░ рдХреЗ рдЦрдВрдбреЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЙрдирдХреЗ рдЕрдиреБрдорд╛рдирд┐рдд рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдЫреЛрдЯреЗ рд╣реЛрдиреЗ рдкрд░ рдЦрдВрдбреЛрдВ рдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рджрд╛рди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ maxyред

рдмрд┐рд▓рдмреЛрд░реНрдб, рдкреЗрдбрд╝реЛрдВ рдФрд░ рдХрд╛рд░реЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди


рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╕рдбрд╝рдХ рдХреЗ рдЦрдВрдбреЛрдВ рдХреЗ рдЖрдЧреЗ рд╕реЗ рдкреАрдЫреЗ рддрдХ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрдд рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЕрдХреНрд╕рд░ рдПрдХ рджреВрд╕рд░реЗ рдХреЛ рдУрд╡рд░рд▓реИрдк рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рд▓рд┐рдП рдХрд▓рд╛рдХрд╛рд░ рдХреЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдЧрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдпрд╣ рд╣рдорд╛рд░реЗ рддрд░реАрдХреЗ рдХреЛ рдЬрдЯрд┐рд▓ рдмрдирд╛рддрд╛ рд╣реИ render()рдФрд░ рд╣рдореЗрдВ рджреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рд╕рдбрд╝рдХ рдЦрдВрдбреЛрдВ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИ:

  1. рд╕рдбрд╝рдХ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдкреАрдЫреЗ
  2. рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ


рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдЕрддрд┐рд╡реНрдпрд╛рдкреА рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдкрд╣рд╛рдбрд╝реА рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдХреНрд╖рд┐рддрд┐рдЬ рдХреЗ рдХрд╛рд░рдг рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХрд╛рдлреА рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рдКрдкрд░реА рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рднрд▓реЗ рд╣реА рд╡рд╣ рдЬрд┐рд╕ рдЦрдВрдб рдкрд░ рд╕реНрдерд┐рдд рд╣реИ рд╡рд╣ рдкрд╣рд╛рдбрд╝реА рдХреЗ рдкреАрдЫреЗ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рд╣рдо рдЪрд░рдг 1 рдореЗрдВ maxyрдПрдХ рдкрдВрдХреНрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдХреЗ рдореВрд▓реНрдп рдХреЛ рдмрдЪрд╛рдХрд░ рдЕрдВрддрд┐рдо рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ clipред рдлрд┐рд░ рд╣рдо clipрдЪрд░рдг 2 рдореЗрдВ рд▓рд╛рдЗрди рдХреЗ рд╕рд╛рде рдЗрд╕ рдЦрдВрдб рдХреЗ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреА рдХрдЯрд╛рдИ рдХрд░ рд╕рдХрддреЗ

рд╣реИрдВред рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЗ рдмрд╛рдХреА рддрд░реНрдХ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╕рдбрд╝рдХ рдЦрдВрдбреЛрдВ рдХреЗ рдЧреБрдгрд╛рдВрдХ scaleрдФрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ screenрдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рд╕реНрдХреЗрд▓ рдФрд░ рд╕реНрдХреЗрд▓ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдП (рдЧрдгрдирд╛ рдХреА рдЧрдИ) рдЪрд░рдг 1), рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рд╡рд┐рдзрд┐ рдХреЗ рджреВрд╕рд░реЗ рдЪрд░рдг рдореЗрдВ render()рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ:

// back to front painters algorithm
for(n = (drawDistance-1) ; n > 0 ; n--) {
  segment = segments[(baseSegment.index + n) % segments.length];

  // render roadside sprites
  for(i = 0 ; i < segment.sprites.length ; i++) {
    sprite      = segment.sprites[i];
    spriteScale = segment.p1.screen.scale;
    spriteX     = segment.p1.screen.x + (spriteScale * sprite.offset * roadWidth * width/2);
    spriteY     = segment.p1.screen.y;
    Render.sprite(ctx, width, height, resolution, roadWidth, sprites, sprite.source, spriteScale, spriteX, spriteY, (sprite.offset < 0 ? -1 : 0), -1, segment.clip);
  }

  // render other cars
  for(i = 0 ; i < segment.cars.length ; i++) {
    car         = segment.cars[i];
    sprite      = car.sprite;
    spriteScale = Util.interpolate(segment.p1.screen.scale, segment.p2.screen.scale, car.percent);
    spriteX     = Util.interpolate(segment.p1.screen.x,     segment.p2.screen.x,     car.percent) + (spriteScale * car.offset * roadWidth * width/2);
    spriteY     = Util.interpolate(segment.p1.screen.y,     segment.p2.screen.y,     car.percent);
    Render.sprite(ctx, width, height, resolution, roadWidth, sprites, car.sprite, spriteScale, spriteX, spriteY, -0.5, -1, segment.clip);
  }

}

рдмрд┐рд▓рдмреЛрд░реНрдб рдФрд░ рдкреЗрдбрд╝реЛрдВ рдХреЗ рд╕рд╛рде рдЯрдХрд░рд╛рд╡


рдЕрдм рдЬрдм рд╣рдо рд╕рдбрд╝рдХ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рд╡рд╕реНрддреБ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЛ рдЬреЛрдбрд╝ рдФрд░ рд╕реМрдВрдк рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ update()рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзрд┐ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдЦрд┐рд▓рд╛рдбрд╝реА рдиреЗ рдЕрдкрдиреЗ рд╡рд░реНрддрдорд╛рди рдЦрдВрдб рдореЗрдВ рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рднреА рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ рд╣реИ:

рд╣рдо Util.overlap()рдЖрдпрддреЛрдВ рдХреЗ рдЪреМрд░рд╛рд╣реЗ рдХреА рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдорд╛рдиреНрдпрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ ред рдпрджрд┐ рдПрдХ рдЪреМрд░рд╛рд╣реЗ рдХрд╛ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ, рддреЛ рд╣рдо рдХрд╛рд░ рдХреЛ рд░реЛрдХрддреЗ рд╣реИрдВ:

if ((playerX < -1) || (playerX > 1)) {
  for(n = 0 ; n < playerSegment.sprites.length ; n++) {
    sprite  = playerSegment.sprites[n];
    spriteW = sprite.source.w * SPRITES.SCALE;
    if (Util.overlap(playerX, playerW, sprite.offset + spriteW/2 * (sprite.offset > 0 ? 1 : -1), spriteW)) {
      // stop the car
      break;
    }
  }
}

рдиреЛрдЯ: рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рдо рдХрд╛рд░ рдХреЛ рд░реЛрдХ рдирд╣реАрдВ рд░рд╣реЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рддрдм рдпрд╣ рдмрд╛рдзрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдЧрд╝рд▓ рдореЗрдВ рдЬрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛; рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╣реИрдХ рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдЙрдирдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдареАрдХ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХрд╛рд░ рдХреЛ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ "рд╕реНрд▓рд┐рдк" рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред

рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЯрдХрд░рд╛рд╡


рд╕рдбрд╝рдХ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдЯрдХрд░рд╛рд╡ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдЕрдиреНрдп рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЯрдХрд░рд╛рд╡ рдХреЛ рдкрд╣рдЪрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдПрдХ рдЪреМрд░рд╛рд╣реЗ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдЙрд╕ рдорд╢реАрди рдХреЗ рдкреАрдЫреЗ "рдзрдХреНрдХрд╛" рджреЗрдХрд░ рдзреАрдорд╛ рдХрд░ рджреЗрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╡рд╣ рдЯрдХрд░рд╛ рдЧрдпрд╛ рдерд╛:

for(n = 0 ; n < playerSegment.cars.length ; n++) {
  car  = playerSegment.cars[n];
  carW = car.sprite.w * SPRITES.SCALE;
  if (speed > car.speed) {
    if (Util.overlap(playerX, playerW, car.offset, carW, 0.8)) {
      // slow the car
      break;
    }
  }
}

рдорд╢реАрди рдЕрдкрдбреЗрдЯ


рддрд╛рдХрд┐ рдЕрдиреНрдп рдХрд╛рд░реЗрдВ рд╕рдбрд╝рдХ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝реЗрдВ, рд╣рдо рдЙрдиреНрд╣реЗрдВ рд╕рдмрд╕реЗ рд╕рд░рд▓ AI рджреЗрдВрдЧреЗ:

  • рд╕реНрдерд┐рд░ рдЧрддрд┐ рд╕реЗ рд╕рд╡рд╛рд░реА рдХрд░реЗрдВ
  • рдУрд╡рд░рдЯреЗрдХ рдХрд░рдиреЗ рдкрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдШреВрдордирд╛
  • рдУрд╡рд░рдЯреЗрдХ рдХрд░рдиреЗ рдкрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреНрдп рдХрд╛рд░реЛрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЬрд╛рдирд╛

рдиреЛрдЯ: рд╣рдореЗрдВ рд╕рдбрд╝рдХ рдкрд░ рд╡рдХреНрд░ рдХреЗ рд╕рд╛рде рдЕрдиреНрдп рдХрд╛рд░реЛрдВ рдХреЛ рдореЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡рдХреНрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдирд╣реАрдВ рд╣реИрдВред рдпрджрд┐ рд╣рдо рдХрд╛рд░реЛрдВ рдХреЛ рд╕рдбрд╝рдХ рдХреЗ рдЦрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╡реЗ рд╕реНрд╡рддрдГ рдШрдЯрддрд╛ рдХреЗ рд╕рд╛рде рдЧреБрдЬрд░реЗрдВрдЧреЗред

рдпрд╣ рд╕рдм рдЦреЗрд▓ рдЪрдХреНрд░ рдХреЗ update()рджреМрд░рд╛рди рд╣реЛрддрд╛ рд╣реИ рдПрдХ рдХреЙрд▓ рдХреЗ рджреМрд░рд╛рди updateCars()рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░ рдХреЛ рдПрдХ рдирд┐рд░рдВрддрд░ рдЧрддрд┐ рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рд╕реЗрдЧрдореЗрдВрдЯ рд╕реЗ рдЕрдЧрд▓реЗ рддрдХ рд╕реНрд╡рд┐рдЪ рдХрд░рддреЗ рд╣реИрдВ рдпрджрд┐ рд╡реЗ рдЗрд╕ рдлреНрд░реЗрдо рдХреЗ рджреМрд░рд╛рди рдкрд░реНрдпрд╛рдкреНрдд рджреВрд░реА рдкрд░ рдЪрд▓реЗ рдЧрдП рд╣реИрдВред

function updateCars(dt, playerSegment, playerW) {
  var n, car, oldSegment, newSegment;
  for(n = 0 ; n < cars.length ; n++) {
    car         = cars[n];
    oldSegment  = findSegment(car.z);
    car.offset  = car.offset + updateCarOffset(car, oldSegment, playerSegment, playerW);
    car.z       = Util.increase(car.z, dt * car.speed, trackLength);
    car.percent = Util.percentRemaining(car.z, segmentLength); // useful for interpolation during rendering phase
    newSegment  = findSegment(car.z);
    if (oldSegment != newSegment) {
      index = oldSegment.cars.indexOf(car);
      oldSegment.cars.splice(index, 1);
      newSegment.cars.push(car);
    }
  }
}

рд╡рд┐рдзрд┐ "рдХреГрддреНрд░рд┐рдо рдмреБрджреНрдзрд┐рдорддреНрддрд╛"updateCarOffset() рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ , рдЬрд┐рд╕рд╕реЗ рдорд╢реАрди рдЦрд┐рд▓рд╛рдбрд╝реА рдпрд╛ рдЕрдиреНрдп рдорд╢реАрдиреЛрдВ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛ рд╕рдХрддреА рд╣реИред рдпрд╣ рдХреЛрдб рдЖрдзрд╛рд░ рдореЗрдВ рд╕рдмрд╕реЗ рдЬрдЯрд┐рд▓ рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдФрд░ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЧреЗрдо рдореЗрдВ рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдорд╢реАрди рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдбреЗрдореЛ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рд▓рдЧреЗрдВред рд╣рдорд╛рд░реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдорд╢реАрди рдХреЛ рдордЬрдмреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рднреЛрд▓реЗ AI рдмреНрд░реВрдЯ рдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:



  • рдЖрдЧреЗ рджреЗрдЦрд┐рдП 20 рд╕реЗрдЧрдореЗрдВрдЯ
  • рдпрджрд┐ рд╡рд╣ рдЙрд╕рдХреЗ рд╕рд╛рдордиреЗ рдПрдХ рдзреАрдореА рдХрд╛рд░ рдкрд╛рддрд╛ рд╣реИ рдЬреЛ рдЙрд╕рдХреЗ рд░рд╛рд╕реНрддреЗ рдХреЛ рдкрд╛рд░ рдХрд░рддреА рд╣реИ, рддреЛ рдЙрд╕реЗ рдЧреЛрд▓ рдХрд░реЗрдВ
  • рд╕рдбрд╝рдХ рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдмрд╛рдзрд╛рдУрдВ рд╕реЗ рджрд╛рдПрдБ рдореБрдбрд╝реЗрдВ
  • рд╕рдбрд╝рдХ рдХреЗ рджрд╛рдИрдВ рдУрд░ рдмрд╛рдзрд╛рдУрдВ рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдореБрдбрд╝реЗрдВ
  • рд╢реЗрд╖ рджреВрд░реА рдХреЗ рднреАрддрд░ рдмрд╛рдзрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдореБрдбрд╝реЗрдВ

рд╣рдо рдЙрди рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рднреА рдзреЛрдЦрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд▓рд┐рдП рдЕрджреГрд╢реНрдп рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЙрдиреНрд╣реЗрдВ рдмрд╕ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рдЪрдХреНрдХрд░ рд▓рдЧрд╛рдиреЗ рдФрд░ рдЧреБрдЬрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рдорд┐рд▓рддреА рд╣реИред рдЙрдиреНрд╣реЗрдВ рдХреЗрд╡рд▓ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рджреГрд╢реНрдпрддрд╛ рдХреЗ рднреАрддрд░ "рд╕реНрдорд╛рд░реНрдЯ" рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

function updateCarOffset(car, carSegment, playerSegment, playerW) {

  var i, j, dir, segment, otherCar, otherCarW, lookahead = 20, carW = car.sprite.w * SPRITES.SCALE;

  // optimization, dont bother steering around other cars when 'out of sight' of the player
  if ((carSegment.index - playerSegment.index) > drawDistance)
    return 0;

  for(i = 1 ; i < lookahead ; i++) {
    segment = segments[(carSegment.index+i)%segments.length];

    if ((segment === playerSegment) && (car.speed > speed) && (Util.overlap(playerX, playerW, car.offset, carW, 1.2))) {
      if (playerX > 0.5)
        dir = -1;
      else if (playerX < -0.5)
        dir = 1;
      else
        dir = (car.offset > playerX) ? 1 : -1;
      return dir * 1/i * (car.speed-speed)/maxSpeed; // the closer the cars (smaller i) and the greater the speed ratio, the larger the offset
    }

    for(j = 0 ; j < segment.cars.length ; j++) {
      otherCar  = segment.cars[j];
      otherCarW = otherCar.sprite.w * SPRITES.SCALE;
      if ((car.speed > otherCar.speed) && Util.overlap(car.offset, carW, otherCar.offset, otherCarW, 1.2)) {
        if (otherCar.offset > 0.5)
          dir = -1;
        else if (otherCar.offset < -0.5)
          dir = 1;
        else
          dir = (car.offset > otherCar.offset) ? 1 : -1;
        return dir * 1/i * (car.speed-otherCar.speed)/maxSpeed;
      }
    }
  }
}

рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдпрд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛рдлреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдордиреЗ рдХрд╛рд░реЛрдВ рдХреА рдПрдХ рдмрдбрд╝реА рднреАрдбрд╝ рдХреЗ рд╕рд╛рде, рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХрд╛рд░реЗрдВ рдмрд╛рдПрдВ рд╕реЗ рджрд╛рдПрдВ рдФрд░ рдкреАрдЫреЗ рд╕реЗ рдЖрдЧреЗ рдмрдврд╝ рд░рд╣реА рд╣реИрдВ, рдЕрдиреНрдп рджреЛ рдорд╢реАрдиреЛрдВ рдХреЗ рдмреАрдЪ рдХреА рдЦрд╛рдИ рдХреЛ рдирд┐рдЪреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реА рд╣реИред рдПрдЖрдИ рдХреА рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдХрд╛рд░реЛрдВ рдХреЛ рдзреАрдорд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рд╡реЗ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдмрд╛рдзрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЬрдЧрд╣ рдирд╣реАрдВ рд╣реИред

рдЗрдВрдЯрд░рдлреЗрд╕


рдЕрдВрдд рдореЗрдВ, рд╣рдо рдПрдХ рдЕрд▓реНрдкрд╡рд┐рдХрд╕рд┐рдд HTML рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрдирд╛рдПрдВрдЧреЗ:

<div id = "hud">
  <span id = "speed" рд╡рд░реНрдЧ = "hud"> <span id = "speed_value" рд╡рд░реНрдЧ = "рдореВрд▓реНрдп"> 0 </ span> mph </ span>
  <span id = "current_lap_time" рд╡рд░реНрдЧ = "hud"> рд╕рдордп: <span id = "current_lap_time_value" рд╡рд░реНрдЧ = "рдореВрд▓реНрдп"> 0.0 </ span> </ span> 
  <span id = "last_lap_time" рд╡рд░реНрдЧ = "hud"> рдЕрдВрддрд┐рдо рдЧреЛрдж: <span id = "last_lap_time_value" рд╡рд░реНрдЧ = "рдореВрд▓реНрдп"> 0.0 </ span> </ span>
  <span id = "fast_lap_time" рд╡рд░реНрдЧ = "hud"> рд╕рдмрд╕реЗ рддреЗрдЬрд╝ рдЧреЛрдж: <span id = "fast_lap_time_value" рд╡рд░реНрдЧ = "рдореВрд▓реНрдп"> 0.0 </ span> </ span>
</ Div>

... рдФрд░ рдЗрд╕рдореЗрдВ CSS рд╕реНрдЯрд╛рдЗрд▓ рдЬреЛрдбрд╝реЗрдВ

#hud                   { position: absolute; z-index: 1; width: 640px; padding: 5px 0; font-family: Verdana, Geneva, sans-serif; font-size: 0.8em; background-color: rgba(255,0,0,0.4); color: black; border-bottom: 2px solid black; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
#hud .hud              { background-color: rgba(255,255,255,0.6); padding: 5px; border: 1px solid black; margin: 0 5px; transition-property: background-color; transition-duration: 2s; -webkit-transition-property: background-color; -webkit-transition-duration: 2s; }
#hud #speed            { float: right; }
#hud #current_lap_time { float: left;  }
#hud #last_lap_time    { float: left; display: none;  }
#hud #fast_lap_time    { display: block; width: 12em;  margin: 0 auto; text-align: center; transition-property: background-color; transition-duration: 2s; -webkit-transition-property: background-color; -webkit-transition-duration: 2s; }
#hud .value            { color: black; font-weight: bold; }
#hud .fastest          { background-color: rgba(255,215,0,0.5); }


... рдФрд░ рд╣рдо рдЦреЗрд▓ рдЪрдХреНрд░ рдХреЗ рджреМрд░рд╛рди рдЗрд╕рдХреЗ рдЕрджреНрдпрддрди () рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВрдЧреЗ:

if (position > playerZ) {
  if (currentLapTime && (startPosition < playerZ)) {
    lastLapTime    = currentLapTime;
    currentLapTime = 0;
    if (lastLapTime <= Util.toFloat(Dom.storage.fast_lap_time)) {
      Dom.storage.fast_lap_time = lastLapTime;
      updateHud('fast_lap_time', formatTime(lastLapTime));
      Dom.addClassName('fast_lap_time', 'fastest');
      Dom.addClassName('last_lap_time', 'fastest');
    }
    else {
      Dom.removeClassName('fast_lap_time', 'fastest');
      Dom.removeClassName('last_lap_time', 'fastest');
    }
    updateHud('last_lap_time', formatTime(lastLapTime));
    Dom.show('last_lap_time');
  }
  else {
    currentLapTime += dt;
  }
}

updateHud('speed',            5 * Math.round(speed/500));
updateHud('current_lap_time', formatTime(currentLapTime));

рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ updateHud()рд╣рдореЗрдВ DOM рддрддреНрд╡реЛрдВ рдХреЛ рддрднреА рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ рдЬрдм рдорд╛рди рдмрджрд▓рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдЕрдкрдбреЗрдЯ рдПрдХ рдзреАрдореА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ рдФрд░ рд╣рдореЗрдВ рдЗрд╕реЗ 60fps рдкрд░ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрджрд┐ рдорд╛рди рд╕реНрд╡рдпрдВ рдирд╣реАрдВ рдмрджрд▓рддреЗ рд╣реИрдВред

function updateHud(key, value) { // accessing DOM can be slow, so only do it if value has changed
  if (hud[key].value !== value) {
    hud[key].value = value;
    Dom.set(hud[key].dom, value);
  }
}

рдирд┐рд╖реНрдХрд░реНрд╖



Fuh! рдЕрдВрддрд┐рдо рднрд╛рдЧ рд▓рдВрдмрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╣рдо рдЕрднреА рднреА рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдП, рдФрд░ рд╕рдорд╛рдкреНрдд рд╕рдВрд╕реНрдХрд░рдг рдЙрд╕ рдЪрд░рдг рдореЗрдВ рдкрд╣реБрдВрдЪ рдЧрдпрд╛ рдЬрд╣рд╛рдВ рдЗрд╕реЗ рдПрдХ рдЦреЗрд▓ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╡рд╣ рдЕрднреА рднреА рд╕рдорд╛рдкреНрдд рдЦреЗрд▓ рд╕реЗ рджреВрд░ рд╣реИ , рд▓реЗрдХрд┐рди рдпрд╣ рдЕрднреА рднреА рдПрдХ рдЦреЗрд▓ рд╣реИред

рдпрд╣ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд╣реИ рдХрд┐ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЧреЗрдо рдмрдирд╛рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ, рднрд▓реЗ рд╣реА рдпрд╣ рдХрд┐рддрдирд╛ рд╕рд░рд▓ рд╣реЛред рдореИрдВ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдкреВрд░реНрдг рд░рд╛рдЬреНрдп рдореЗрдВ рд▓рд╛рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред рдЗрд╕реЗ рдХреЗрд╡рд▓ рдЫрджреНрдо рддреНрд░рд┐-рдЖрдпрд╛рдореА рд░реЗрд╕рд┐рдВрдЧ рдЦреЗрд▓реЛрдВ рдХреЗ рд╡рд┐рд╖рдп рдХреЗ рдкрд░рд┐рдЪрдп рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП ред

рдХреЛрдб рдХреЛ github рджреНрд╡рд╛рд░рд╛ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ , рдФрд░ рдЖрдк рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рд░реЗрд╕рд┐рдВрдЧ рдЧреЗрдо рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рднреА рдЖрдЬрдорд╛ рд╕рдХрддреЗ рд╣реИрдВ:

  • рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдзреНрд╡рдирд┐ рдкреНрд░рднрд╛рд╡ рдЬреЛрдбрд╝реЗрдВ
  • рд╕рдВрдЧреАрдд рд╕рд┐рдВрдХ рдореЗрдВ рд╕реБрдзрд╛рд░
  • рдлреБрд▓рд╕реНрдХреНрд░реАрди рд▓рд╛рдЧреВ рдХрд░реЗрдВ
  • ( , , , ..)
  • (, ..)
  • ,
  • , -
  • ,
  • ( , ..)
  • drawDistance
  • x,y
  • ( , )
  • рдХрд╛рдВрдЯрд╛ рдФрд░ рд╕рдбрд╝рдХ рдХрдиреЗрдХреНрд╢рди
  • рд░рд╛рдд рдФрд░ рджрд┐рди рдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди
  • рдореМрд╕рдо рдХреА рд╕реНрдерд┐рддрд┐
  • рд╕реБрд░рдВрдЧреЛрдВ, рдкреБрд▓реЛрдВ, рдмрд╛рджрд▓реЛрдВ, рджреАрд╡рд╛рд░реЛрдВ, рдЗрдорд╛рд░рддреЛрдВ
  • рд╢рд╣рд░, рд░реЗрдЧрд┐рд╕реНрддрд╛рди, рд╕рд╛рдЧрд░
  • рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдореЗрдВ рд╕рд┐рдПрдЯрд▓ рдФрд░ рд╕реНрдкреЗрд╕ рд╕реБрдИ рдЬреЛрдбрд╝реЗрдВ
  • "рдЦрд▓рдирд╛рдпрдХ" - рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдпреЛрдЧрд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝реЗрдВ
  • рдЦреЗрд▓ рдореЛрдб - рд╕рдмрд╕реЗ рддреЗрдЬ рдЧреЛрдж, рдПрдХ рджреМрдбрд╝ рдкрд░ рдПрдХ (рд╕рд┐рдХреНрдХреЗ рдЙрдард╛ ?, рдЦрд▓рдирд╛рдпрдХ рдкрд░ рд╢реВрдЯрд┐рдВрдЧ?)
  • рдЧреЗрдордкреНрд▓реЗ рдЕрдиреБрдХреВрд▓рди рд╡рд┐рдХрд▓реНрдк рдХреЗ рдЯрди
  • рдЖрджрд┐ред
  • ...

рддреЛ рд╣рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдПрдХ рдФрд░ "рд╕рдкреНрддрд╛рд╣рд╛рдВрдд рдкрд░рд┐рдпреЛрдЬрдирд╛" рдЬреЛ рдЙрдореНрдореАрдж рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдордп рд▓реЗрддреА рдереА, рд▓реЗрдХрд┐рди рдЕрдВрдд рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдерд╛ред

рд╕рдВрджрд░реНрдн



рдЦреЗрд▓рдиреЗ рдпреЛрдЧреНрдп рдбреЗрдореЛ рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ:


All Articles