рдПрдХ рдЫрджреНрдо рддреНрд░рд┐-рдЖрдпрд╛рдореА рд░реЗрд╕рд┐рдВрдЧ рдЧреЗрдо рдмрдирд╛рдирд╛


рдПрдХ рдмрдЪреНрдЪреЗ рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдЖрд░реНрдХреЗрдб рдЖрд░реНрдХреЗрдб рд╣реЙрд▓ рдореЗрдВ рдЧрдпрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдирдХреА рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рдереА, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдШрд░ рдкрд░ C64 рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛ рдЧреЗрдо рдереЗ ... рд▓реЗрдХрд┐рди рддреАрди рдЖрд░реНрдХреЗрдб рдЧреЗрдо рд╣реИрдВ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рдкрд╛рд╕ рд╣рдореЗрд╢рд╛ рдкреИрд╕рд╛ рдерд╛ - рдЧрдзрд╛ рдХрд╛рдБрдЧ, рдбреНрд░реЗрдЧрди рд▓реИрдпрд░ рдФрд░ рдЖрдЙрдЯрд╕реВрди ...

... рдФрд░ рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ Outrun рд╕реЗ рдкреНрдпрд╛рд░ рдерд╛ - рдЧрддрд┐, рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ, рддрд╛рдбрд╝ рдХреЗ рдкреЗрдбрд╝ рдФрд░ рд╕рдВрдЧреАрдд, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ C64 рдХреЗ рдХрдордЬреЛрд░ рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рднреАред


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

рддреЛ, рдпрд╣рд╛рдБ рдореЗрд░реА "рд╕рдкреНрддрд╛рд╣рд╛рдВрдд рдкрд░рд┐рдпреЛрдЬрдирд╛" рд╣реИ, рдЬреЛ рдЕрдВрддрддрдГ рд╕рдкреНрддрд╛рд╣рд╛рдВрдд рдкрд░ рдкрд╛рдВрдЪ рдпрд╛ рдЫрд╣ рдорд╣реАрдиреЗ рд▓рдЧ рдЧрдП



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

рдпрд╣ рдкреЙрд▓рд┐рд╢ рдирд╣реАрдВ рд╣реИ, рдереЛрдбрд╝рд╛ рдмрджрд╕реВрд░рдд рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реА рддрд░рд╣ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╣реИред рдореИрдВ рдЖрдкрдХреЛ рдЪрд╛рд░ рд╕рд░рд▓ рдЪрд░рдгреЛрдВ рдореЗрдВ рдЕрдкрдиреЗ рджрдо рдкрд░ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред

рдЖрдк рднреА рдЦреЗрд▓ рд╕рдХрддреЗ рд╣реИрдВ


рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ


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

рдХреЛрдб рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ


рдРрд╕рд╛ рд╣реБрдЖ рдХрд┐ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ (рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреА рд╕рд╛рджрдЧреА рдХреЗ рдХрд╛рд░рдг) рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рддрдХрдиреАрдХ рдпрд╛ рдЕрдиреБрд╢рдВрд╕рд┐рдд рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдирд╛ рдирд╣реАрдВ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдордЭрдиреЗ рдореЗрдВ рдЖрд╕рд╛рдиреА рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд╕реАрдзреЗ HTML рдкреЗрдЬ (рд╣реЙрд░рд░!) рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ; рдЗрд╕рд╕реЗ рднреА рдмрджрддрд░, рдпрд╣ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

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

рднрд╛рдЧ 1. рд╕реАрдзреА рд╕рдбрд╝рдХреЗрдВред


рддреЛ, рд╣рдо рдПрдХ рдЫрджреНрдо рддреНрд░рд┐-рдЖрдпрд╛рдореА рд░реЗрд╕рд┐рдВрдЧ рдЧреЗрдо рдмрдирд╛рдиреЗ рдкрд░ рдХреИрд╕реЗ рдЖрд░рдВрдн рдХрд░реЗрдВ?

рдЦреИрд░, рд╣рдореЗрдВ рдЬрд░реВрд░рдд рд╣реИ

  • рддреНрд░рд┐рдХреЛрдгрдорд┐рддрд┐ рджреЛрд╣рд░рд╛рдПрдВ
  • 3 рдбреА рдкреНрд░рдХреНрд╖реЗрдкрдг рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рдпрд╛рдж рдХрд░реЗрдВ
  • рдЧреЗрдо рд▓реВрдк рдмрдирд╛рдПрдВ
  • рд╕реНрдкреНрд░рд╛рдЗрдЯ рдЪрд┐рддреНрд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ
  • рд╕рдбрд╝рдХ рдЬреНрдпрд╛рдорд┐рддрд┐ рдХрд╛ рдирд┐рд░реНрдорд╛рдг
  • рд░реЗрдВрдбрд░ рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб
  • рд░реЗрдВрдбрд░ рдХрд░реЗрдВ
  • рд░реЗрдВрдбрд░ рдХрд╛рд░
  • рдорд╢реАрди рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рд▓рд┐рдП рдХреАрдмреЛрд░реНрдб рд╕рдорд░реНрдерди рд▓рд╛рдЧреВ рдХрд░реЗрдВ

рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЪрд▓реЛ рд▓реВ рдХреЗ рдЫрджреНрдо 3 рдбреА рдкреЗрдЬ [ рдЕрдиреБрд╡рд╛рдж рд╣реИрдмреЗ] рдХреЛ рдкрдврд╝реЗрдВ - рд╕реВрдЪрдирд╛ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рд╕реНрд░реЛрдд (рдЬреЛ рдореБрдЭреЗ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ) рдХреИрд╕реЗ psevdotrohmernuyu рд░реЗрд╕рд┐рдВрдЧ рдЧреЗрдо рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдПред

рд▓реВ рдХрд╛ рд▓реЗрдЦ рдкрдврд╝рдирд╛ рд╕рдорд╛рдкреНрдд рдХрд┐рдпрд╛? рдареАрдХ! рд╣рдо 3 рдбреА-рдкреНрд░реЛрдЬреЗрдХреНрдЯреЗрдб рд╕реЗрдЧрдореЗрдВрдЯ рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдЙрдирдХреА рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреА рд╡рд┐рд╡рд┐рдзрддрд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗред рд╣рдо рдЗрд╕реЗ рдЕрдЧрд▓реЗ рдЪрд╛рд░ рднрд╛рдЧреЛрдВ рдореЗрдВ рдзреАрд░реЗ-рдзреАрд░реЗ рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рд╣рдо рдЕрднреА рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ, рд╕рдВрд╕реНрдХрд░рдг v1 рдХреЗ рд╕рд╛рде, рдФрд░ рдЗрд╕реЗ HTML5 рдХреИрдирд╡рд╛рд╕ рддрддреНрд╡ рдкрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд░рдХреЗ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рд╕реАрдзреА рд╕рдбрд╝рдХ рдЬреНрдпрд╛рдорд┐рддрд┐ рдмрдирд╛рдПрдБред

рдпрд╣рд╛рдВ рдбреЗрдореЛ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

рдереЛрдбрд╝рд╛ рддреНрд░рд┐рдХреЛрдгрдорд┐рддрд┐


рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЖрдПрдВ, рдЖрдЗрдП рддреНрд░рд┐рднреБрдЬрдорд┐рддрд┐ рдХреА рдореВрд▓ рдмрд╛рддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдпрд╣ рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ 3D рджреБрдирд┐рдпрд╛ рдХреЗ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдХреЛ 2D рд╕реНрдХреНрд░реАрди рдкрд░ рдХреИрд╕реЗ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЬрд╛рдПред

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

рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдиреЛрдЯреЗрд╢рди рдХрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

  • h = рдХреИрдорд░рд╛ рдКрдВрдЪрд╛рдИ
  • d = рдХреИрдорд░рд╛ рд╕реЗ рд╕реНрдХреНрд░реАрди рдХреА рджреВрд░реА
  • z = рдХреИрдорд░рд╛ рд╕реЗ рдХрд╛рд░ рдХреА рджреВрд░реА
  • y = рд╕реНрдХреНрд░реАрди y рд╕рдордиреНрд╡рдп

рдлрд┐рд░ рд╣рдо рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рддреНрд░рд┐рдХреЛрдг рдХреЗ рдХрд╛рдиреВрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

y = h * d / z

рдЪрд┐рддреНрд░ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


рдЖрдк рд╕рд╛рдЗрдб рд╡реНрдпреВ рдХреЗ рдмрдЬрд╛рдп рд╢реАрд░реНрд╖ рджреГрд╢реНрдп рдореЗрдВ рдПрдХ рд╕рдорд╛рди рдЖрд░реЗрдЦ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╕реНрдХреНрд░реАрди рдХреЗ X рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рди рд╕рдореАрдХрд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

x = w * d / z

рдЬрд╣рд╛рдБ w = рд╕рдбрд╝рдХ рдХреА рдЖрдзреА рдЪреМрдбрд╝рд╛рдИ (рдХреИрдорд░реЗ рд╕реЗ рд╕рдбрд╝рдХ рдХреЗ рдХрд┐рдирд╛рд░реЗ рддрдХ)ред

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, x рдФрд░ y рдХреЗ рд▓рд┐рдП рд╣рдо рдПрдХ рдХрд╛рд░рдХ рджреНрд╡рд╛рд░рд╛ рд╕реНрдХреЗрд▓ рдХрд░рддреЗ рд╣реИрдВ

d / z

рд╕рд┐рд╕реНрдЯрдо рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░реЗрдВ


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

рдпрджрд┐ рдЖрдк рдЕрдзрд┐рдХ рдФрдкрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

  1. рджреБрдирд┐рдпрд╛ рд╕реЗ рд░реВрдкрд╛рдВрддрд░рдг рд╕реНрдХреНрд░реАрди рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд▓рд┐рдП рд╕рдордиреНрд╡рдп рдХрд░рддрд╛ рд╣реИ
  2. рдкреНрд░реЛрдЬреЗрдХреНрдЯрд┐рдВрдЧ рдХреИрдорд░рд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдкреНрд░рдХреНрд╖реЗрдкрдг рд╡рд┐рдорд╛рди рдкрд░ рд╕рдордиреНрд╡рдп рдХрд░рддрд╛ рд╣реИ
  3. рднреМрддрд┐рдХ рд╕реНрдХреНрд░реАрди рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рдЕрдиреБрдорд╛рдирд┐рдд рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕реНрдХреЗрд▓ рдХрд░рдирд╛ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдХреИрдирд╡рд╛рд╕ рд╣реИ)


рдиреЛрдЯ: рд╡рд░реНрддрдорд╛рди 3 рдбреА-рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ , рд░реЛрдЯреЗрд╢рди рдЪрд░рдг 1 рдФрд░ 2 рдХреЗ рдмреАрдЪ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рд╣рдо рдШрдЯрддрд╛ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рд░реЛрдЯреЗрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдкреНрд░рдХреНрд╖реЗрдкрдг


рдФрдкрдЪрд╛рд░рд┐рдХ рдкреНрд░рдХреНрд╖реЗрдкрдг рд╕рдореАрдХрд░рдгреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


  • рд░реВрдкрд╛рдВрддрд░рдг рд╕рдореАрдХрд░рдг ( рдЕрдиреБрд╡рд╛рдж ) рдмрд┐рдВрджреБ рдХрдХреНрд╖ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ
  • рдкреНрд░рдХреНрд╖реЗрдкрдг рд╕рдореАрдХрд░рдг ( рдкрд░рд┐рдпреЛрдЬрдирд╛ ) рдКрдкрд░ рджрд┐рдЦрд╛рдП рдЧрдП "рд╕рдорд╛рди рддреНрд░рд┐рдХреЛрдг рдХреЗ рдХрд╛рдиреВрди" рдХреЗ рд░реВрдкрд╛рдВрддрд░ рд╣реИрдВред
  • рд╕реНрдХреЗрд▓рд┐рдВрдЧ рд╕рдореАрдХрд░рдгреЛрдВ ( рд╕реНрдХреЗрд▓ ) рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛:
    • рдЧрдгрд┐рдд , рдЬрд╣рд╛рдВ 0,0 рдХреЗрдВрджреНрд░ рдореЗрдВ рд╣реИ рдФрд░ y рдЕрдХреНрд╖ рдКрдкрд░ рд╣реИ, рдФрд░
    • , 0,0 , y :


: 3d- Vector Matrix 3d-, , WebGL ( )тАж . Outrun.



рдкрд╣реЗрд▓реА рдХрд╛ рдЕрдВрддрд┐рдо рдЯреБрдХрдбрд╝рд╛ рдбреА рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛрдЧрд╛ - рдХреИрдорд░реЗ рд╕реЗ рдкреНрд░рдХреНрд╖реЗрдкрдг рд╡рд┐рдорд╛рди рдХреА рджреВрд░реАред

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

рдпрджрд┐ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдПрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдкреНрд░рдХреНрд╖реЗрдкрдг рд╡рд┐рдорд╛рди рдкрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ -1 рд╕реЗ +1 рддрдХ рдХреЗ рд╣реИрдВ, рддреЛ d рдХреА рдЧрдгрдирд╛ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ:

d = 1 / tan (fov / 2)

рдлрд╝реЙрд╡ рдХреЛ рдПрдХ (рдХрдИ рдореЗрдВ рд╕реЗ) рдЪрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдХреЗ , рд╣рдо рд░реЗрдВрдбрд░ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдлрд╛рдЗрди-рдЯреНрдпреВрди рдХрд░рдиреЗ рдХреА рдЧреБрдВрдЬрд╛рдЗрд╢ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рд╕рдВрд░рдЪрдирд╛


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

  • Dom рдХреБрдЫ рдорд╛рдореВрд▓реА рдбреЛрдо рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рд╣реИред
  • Util - рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ, рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рд╕рд╣рд╛рдпрдХ рдЧрдгрд┐рддреАрдп рдХрд╛рд░реНрдпред
  • рдЧреЗрдо - рд╕рд╛рдорд╛рдиреНрдп рдЧреЗрдорд┐рдВрдЧ рд╕рдорд░реНрдерди рдлрд╝рдВрдХреНрд╢рди, рдЬреИрд╕реЗ рдЫрд╡рд┐ рдбрд╛рдЙрдирд▓реЛрдбрд░ рдФрд░ рдЧреЗрдо рд▓реВрдкред
  • рд░реЗрдВрдбрд░ - рдХреИрдирд╡рд╛рд╕ рдкрд░ рд╕рд╣рд╛рдпрдХ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд╛рд░реНрдпред

рдореИрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рддрд░реАрдХреЛрдВ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ common.jsрдХреЗрд╡рд▓ рддрднреА рдХрд░реВрдБрдЧрд╛ рдЬрдм рд╡реЗ рдЦреЗрд▓ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрдВ, рдФрд░ рдХреЗрд╡рд▓ рд╕рд╣рд╛рдпрдХ рдЧрдгрд┐рддреАрдп рдпрд╛ DOM рдлрд╝рдВрдХреНрд╢рди рди рд╣реЛрдВред рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдирд╛рдо рдФрд░ рд╕рдВрджрд░реНрдн рд╕реЗ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдЧрд╛ рдХрд┐ рддрд░реАрдХреЛрдВ рдХреЛ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рд╕реНрд░реЛрдд рдХреЛрдб рдЕрдВрддрд┐рдо рджрд╕реНрддрд╛рд╡реЗрдЬ рдореЗрдВ рд╣реИред

рд╕рд░рд▓ рдЦреЗрд▓ рд▓реВрдк


рдХреБрдЫ рджреЗрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЧреЗрдо рд▓реВрдк рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдк рдЦреЗрд▓ ( рдкреМрдВрдЧ , рдмреНрд░реЗрдХрдЖрдЙрдЯ , рдЯреЗрдЯреНрд░рд┐рд╕ , рд╕рд╛рдВрдк рдпрд╛ рдмреЛрд▓реНрдбрд░рдбреИрд╢ ) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореЗрд░реЗ рдХрд┐рд╕реА рднреА рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдХреЛ рдкрдврд╝рддреЗ рд╣реИрдВ , рддреЛ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдХреЗ рдХрджрдо рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рдкрд╕рдВрджреАрджрд╛ рдЦреЗрд▓ рдЪрдХреНрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦ рдЪреБрдХреЗ рд╣реИрдВ ред

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

рд╕рд┐рджреНрдзрд╛рдВрдд рдпрд╣ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдЪрд╛рд░ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ Game.run(...)рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдХреЙрд▓ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ

  • update - рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдХрджрдо рдХреЗ рд╕рд╛рде рдЦреЗрд▓ рдХреА рджреБрдирд┐рдпрд╛ рдХреЛ рдЕрджреНрдпрддрди рдХрд░рдирд╛ред
  • render - рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдкрд░ рдЦреЗрд▓ рдХреА рджреБрдирд┐рдпрд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ред

run: function(options) {

  Game.loadImages(options.images, function(images) {

    var update = options.update,    // method to update game logic is provided by caller
        render = options.render,    // method to render the game is provided by caller
        step   = options.step,      // fixed frame step (1/fps) is specified by caller
        now    = null,
        last   = Util.timestamp(),
        dt     = 0,
        gdt    = 0;

    function frame() {
      now = Util.timestamp();
      dt  = Math.min(1, (now - last) / 1000); // using requestAnimationFrame have to be able to handle large delta's caused when it 'hibernates' in a background or non-visible tab
      gdt = gdt + dt;
      while (gdt > step) {
        gdt = gdt - step;
        update(step);
      }
      render();
      last = now;
      requestAnimationFrame(frame);
    }
    frame(); // lets get this party started
  });
}

рдлрд┐рд░, рдпрд╣ рдореЗрд░реЗ рдкрд┐рдЫрд▓реЗ рдХреИрдирд╡рд╛рд╕ рдЧреЗрдо рдХреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХрд╛ рд░реАрдореЗрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдпрд╣ рдирд╣реАрдВ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдЧреЗрдо рд▓реВрдк рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯреЗрдВред

рдЪрд┐рддреНрд░ рдФрд░ рд╕реНрдкреНрд░рд┐рдЯ


рдЦреЗрд▓ рдЪрдХреНрд░ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрдкреНрд░рд╛рдЗрдЯрд╢реАрдЯ (рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ) рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ:

  • рдкреГрд╖реНрдарднреВрдорд┐ - рдЖрдХрд╛рд╢, рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдФрд░ рдкреЗрдбрд╝реЛрдВ рдХреЗ рд▓рд┐рдП рддреАрди рд▓рдВрдмрди рдкрд░рддреЗрдВ
  • рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ - рдорд╢реАрди рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ (рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреЗрдбрд╝ рдФрд░ рдмрд┐рд▓рдмреЛрд░реНрдб)


рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдХрд╛рд░реНрдп рд░реЗрдХ рдФрд░ рд░реВрдмреА рдЬреЗрдо рд╕реНрдкреНрд░рд╛рдЗрдЯ-рдлреИрдХреНрдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрддреНрдкрдиреНрди рдХреА рдЧрдИ рдереА ред

рдпрд╣ рдХрд╛рд░реНрдп рд╕рдВрдпреБрдХреНрдд рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯреНрд╕ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ x, y, w, h рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдХрд╛рдВрд╕реНрдЯреЗрдмрд▓ BACKGROUNDрдФрд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ SPRITESред

рдиреЛрдЯ: рдореИрдВрдиреЗ Inkscape рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреГрд╖реНрдарднреВрдорд┐ рдмрдирд╛рдИ рд╣реИ, рдФрд░ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдЙрддреНрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдкреБрд░рд╛рдиреЗ Outrun рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рд▓рд┐рдП рдЧрдП рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рд╣реИрдВ рдФрд░ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдЦреЗрд▓ рдЪрд░


рдкреГрд╖реНрдарднреВрдорд┐ рдФрд░ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдХрдИ рдЧреЗрдо рдЪрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЕрд░реНрдерд╛рддреН:

var fps           = 60;                      // how many 'update' frames per second
var step          = 1/fps;                   // how long is each frame (in seconds)
var width         = 1024;                    // logical canvas width
var height        = 768;                     // logical canvas height
var segments      = [];                      // array of road segments
var canvas        = Dom.get('canvas');       // our canvas...
var ctx           = canvas.getContext('2d'); // ...and its drawing context
var background    = null;                    // our background image (loaded below)
var sprites       = null;                    // our spritesheet (loaded below)
var resolution    = null;                    // scaling factor to provide resolution independence (computed)
var roadWidth     = 2000;                    // actually half the roads width, easier math if the road spans from -roadWidth to +roadWidth
var segmentLength = 200;                     // length of a single segment
var rumbleLength  = 3;                       // number of segments per red/white rumble strip
var trackLength   = null;                    // z length of entire track (computed)
var lanes         = 3;                       // number of lanes
var fieldOfView   = 100;                     // angle (degrees) for field of view
var cameraHeight  = 1000;                    // z height of camera
var cameraDepth   = null;                    // z distance camera is from screen (computed)
var drawDistance  = 300;                     // number of segments to draw
var playerX       = 0;                       // player x offset from center of road (-1 to 1 to stay independent of roadWidth)
var playerZ       = null;                    // player relative z distance from camera (computed)
var fogDensity    = 5;                       // exponential fog density
var position      = 0;                       // current camera Z position (add playerZ to get player's absolute Z position)
var speed         = 0;                       // current speed
var maxSpeed      = segmentLength/step;      // top speed (ensure we can't move more than 1 segment in a single frame to make collision detection easier)
var accel         =  maxSpeed/5;             // acceleration rate - tuned until it 'felt' right
var breaking      = -maxSpeed;               // deceleration rate when braking
var decel         = -maxSpeed/5;             // 'natural' deceleration rate when neither accelerating, nor braking
var offRoadDecel  = -maxSpeed/2;             // off road deceleration is somewhere in between
var offRoadLimit  =  maxSpeed/4;             // limit when off road deceleration no longer applies (e.g. you can always go at least this speed even when off road)

рдХрд╛рд░реНрдпрдХреНрд░рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдорд╣рддреНрд╡рдкреВрд░реНрдг рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдпреВрдЖрдИ рдирд┐рдпрдВрддреНрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХреЗрдВ рдХрд┐ рд╡реЗ рд╕рдбрд╝рдХ рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЛ рдХреИрд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЕрдиреНрдп рд╡рд┐рдзрд┐ рдореЗрдВ рдХрд╕реНрдЯрдо UI рдорд╛рдиреЛрдВ рд╕реЗ рдкреБрдирд░реНрдЧрдгрд┐рдд рд╣реИрдВ reset()ред

рд╣рдо рдлреЗрд░рд╛рд░реА рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддреЗ рд╣реИрдВ


рд╣рдо рдХреБрдВрдЬреА рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХрд░рддреЗ рд╣реИрдВ Game.run, рдЬреЛ рд╕рд░рд▓ рдХреАрдмреЛрд░реНрдб рдЗрдирдкреБрдЯ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рдореМрдЬреВрджрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЪрд░ рд╕реЗрдЯ рдпрд╛ рд░реАрд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ:

Game.run({
  ...
  keys: [
    { keys: [KEY.LEFT,  KEY.A], mode: 'down', action: function() { keyLeft   = true;  } },
    { keys: [KEY.RIGHT, KEY.D], mode: 'down', action: function() { keyRight  = true;  } },
    { keys: [KEY.UP,    KEY.W], mode: 'down', action: function() { keyFaster = true;  } },
    { keys: [KEY.DOWN,  KEY.S], mode: 'down', action: function() { keySlower = true;  } },
    { keys: [KEY.LEFT,  KEY.A], mode: 'up',   action: function() { keyLeft   = false; } },
    { keys: [KEY.RIGHT, KEY.D], mode: 'up',   action: function() { keyRight  = false; } },
    { keys: [KEY.UP,    KEY.W], mode: 'up',   action: function() { keyFaster = false; } },
    { keys: [KEY.DOWN,  KEY.S], mode: 'up',   action: function() { keySlower = false; } }
  ],
  ...
}

рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

  • рдЧрддрд┐ - рд╡рд░реНрддрдорд╛рди рдЧрддрд┐ред
  • рд╕реНрдерд┐рддрд┐ - рдЯреНрд░реИрдХ рдкрд░ рд╡рд░реНрддрдорд╛рди рдЬреЗрдб рд╕реНрдерд┐рддрд┐ред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдПрдХ рдХреИрдорд░рд╛ рд╕реНрдерд┐рддрд┐ рд╣реИ, рди рдХрд┐ рдлреЗрд░рд╛рд░реАред
  • playerX - рд╕рдбрд╝рдХ рдкрд░ рдПрдХреНрд╕ рдкрд░ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ред -1 рд╕реЗ +1 рддрдХ рдХреА рд╕реАрдорд╛ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд, рддрд╛рдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдореВрд▓реНрдп рдкрд░ рдирд┐рд░реНрднрд░ рди рд╣реЛ roadWidthред

рдпреЗ рдЪрд░ рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░ рд╕реЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВ update, рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рддреЗ рд╣реИрдВ:

  • positionрд╡рд░реНрддрдорд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрджреНрдпрддрди speedред
  • рдЕрджреНрдпрддрди playerXрдЬрдм рдЖрдк рдмрд╛рдИрдВ рдпрд╛ рджрд╛рдИрдВ рдХреБрдВрдЬреА рджрдмрд╛рддреЗ рд╣реИрдВред
  • speedрдКрдкрд░ рдХреА рдХреБрдВрдЬреА рджрдмрд╛рдП рдЬрд╛рдиреЗ рдкрд░ рдмрдврд╝ рдЬрд╛рддреА рд╣реИред
  • speedрдпрджрд┐ рдбрд╛рдЙрди рдХреБрдВрдЬреА рджрдмрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдШрдЯ рдЬрд╛рддреА рд╣реИред
  • рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ speedрдЕрдЧрд░ рдКрдкрд░ рдФрд░ рдиреАрдЪреЗ рдХреА рдЪрд╛рдмрд┐рдпрд╛рдБ рджрдмрд╛рдпрд╛ рдирд╣реАрдВ рд╣реИред
  • speedрдЕрдЧрд░ playerXрд╕рдбрд╝рдХ рдХреЗ рдХрд┐рдирд╛рд░реЗ рдФрд░ рдШрд╛рд╕ рдкрд░ рд╕реНрдерд┐рдд рд╣реЛ рддреЛ рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рд╕реАрдзреА рд╕рдбрд╝рдХреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡рд┐рдзрд┐ updateрдХрд╛рдлреА рд╕реНрдкрд╖реНрдЯ рдФрд░ рд╕рд░рд▓ рд╣реИ:

function update(dt) {

  position = Util.increase(position, dt * speed, trackLength);

  var dx = dt * 2 * (speed/maxSpeed); // at top speed, should be able to cross from left to right (-1 to 1) in 1 second

  if (keyLeft)
    playerX = playerX - dx;
  else if (keyRight)
    playerX = playerX + dx;

  if (keyFaster)
    speed = Util.accelerate(speed, accel, dt);
  else if (keySlower)
    speed = Util.accelerate(speed, breaking, dt);
  else
    speed = Util.accelerate(speed, decel, dt);

  if (((playerX < -1) || (playerX > 1)) && (speed > offRoadLimit))
    speed = Util.accelerate(speed, offRoadDecel, dt);

  playerX = Util.limit(playerX, -2, 2);     // dont ever let player go too far out of bounds
  speed   = Util.limit(speed, 0, maxSpeed); // or exceed maxSpeed

}

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

рд╕рдбрд╝рдХ рдХреА рдЬреНрдпрд╛рдорд┐рддрд┐


рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдЦреЗрд▓ рдХреА рджреБрдирд┐рдпрд╛ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХреЗрдВ, рд╣рдореЗрдВ segmentsрд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рд╕рд░рдгреА рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ resetRoad()ред

рд╕рдбрд╝рдХ рдХреЗ рдЗрди рдЦрдВрдбреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рдЕрдВрддрддрдГ рдЗрд╕рдХреА рджреБрдирд┐рдпрд╛ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕реЗ рдкреНрд░рдХреНрд╖реЗрдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рддрд╛рдХрд┐ рдпрд╣ рд╕реНрдХреНрд░реАрди рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдореЗрдВ 2d рдмрд╣реБрднреБрдЬ рдореЗрдВ рдмрджрд▓ рдЬрд╛рдПред рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдХреЗ рд▓рд┐рдП, рд╣рдо рджреЛ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ, рдкреА 1 рдХреИрдорд░реЗ рдХреЗ рд╕рдмрд╕реЗ рдХрд░реАрдм рдХрд╛ рдХреЗрдВрджреНрд░ рд╣реИ , рдФрд░ рдкреА 2 рдХреИрдорд░реЗ рд╕реЗ рд╕рдмрд╕реЗ рджреВрд░ рдХрд┐рдирд╛рд░реЗ рдХрд╛ рдХреЗрдВрджреНрд░ рд╣реИред


рдХрдбрд╝рд╛рдИ рд╕реЗ рдмреЛрд▓рдирд╛, рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдХрд╛ P2 рдкрд┐рдЫрд▓реЗ рдЦрдВрдб рдХреЗ p1 рдХреЗ рд╕рдорд╛рди рд╣реИ , рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд░реВрдкрд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред

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

function resetRoad() {
  segments = [];
  for(var n = 0 ; n < 500 ; n++) { // arbitrary road length
    segments.push({
       index: n,
       p1: { world: { z:  n   *segmentLength }, camera: {}, screen: {} },
       p2: { world: { z: (n+1)*segmentLength }, camera: {}, screen: {} },
       color: Math.floor(n/rumbleLength)%2 ? COLORS.DARK : COLORS.LIGHT
    });
  }

  trackLength = segments.length * segmentLength;
}

рд╣рдо рдХреЗрд╡рд▓ рджреБрдирд┐рдпрд╛ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ z рдХреЗ рд╕рд╛рде p1 рдФрд░ P2 рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╣реИрдВ , рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдХреЗрд╡рд▓ рд╕реАрдзреА рд╕рдбрд╝рдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред Y рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╣рдореЗрд╢рд╛ 0 рд╣реЛрдЧрд╛, рдФрд░ x рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╣рдореЗрд╢рд╛ рд╕реНрдХреЗрд▓ рдХрд┐рдП рдЧрдП рдорд╛рди рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░реЗрдЧрд╛ ред рдмрд╛рдж рдореЗрдВ, рдЬрдм рд╣рдо рдШрдЯрддрд╛ рдФрд░ рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╣рд┐рд╕реНрд╕рд╛ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред рд╣рдо рдХреИрдорд░реЗ рдореЗрдВ рдФрд░ рд╕реНрдХреНрд░реАрди рдкрд░ рдЗрди рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдЕрднреНрдпрд╛рд╡реЗрджрди рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦрд╛рд▓реА рдСрдмреНрдЬреЗрдХреНрдЯ рднреА рд╕реЗрдЯ рдХрд░реЗрдВрдЧреЗ рддрд╛рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ рдЕрд╕реНрдерд╛рдпреА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рди рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ ред рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЧреЗрдо рд▓реВрдк рдХреЗ рднреАрддрд░ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдирд╛ рдЪрд╛рд╣рд┐рдПред+/- roadWidth

render

рдЬрдм рдХрд╛рд░ рд╕рдбрд╝рдХ рдХреЗ рдЕрдВрдд рддрдХ рдкрд╣реБрдБрдЪрддреА рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдЪрдХреНрд░ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд▓реМрдЯрддреЗ рд╣реИрдВред рдЗрд╕реЗ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо Z рдХреЗ рдХрд┐рд╕реА рднреА рдорд╛рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЦрдВрдб рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВрдЧреЗ, рднрд▓реЗ рд╣реА рд╡рд╣ рд╕рдбрд╝рдХ рдХреА рд▓рдВрдмрд╛рдИ рд╕реЗ рдкрд░реЗ рд╣реЛ:

function findSegment(z) {
  return segments[Math.floor(z/segmentLength) % segments.length];
}

рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рд░реЗрдВрдбрд░рд┐рдВрдЧ


рд╡рд┐рдзрд┐ render()рдкреГрд╖реНрдарднреВрдорд┐ рдЫрд╡рд┐ рдкреНрд░рджрд╛рди рдХрд░рдХреЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рднрд╛рдЧреЛрдВ рдореЗрдВ, рдЬрд╣рд╛рдВ рд╣рдо рдШрдЯрддрд╛ рдФрд░ рдкрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝реЗрдВрдЧреЗ, рд╣рдореЗрдВ рдкреГрд╖реНрдарднреВрдорд┐ рдХреЛ рд▓рдВрдмрди рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЕрдм рдЗрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ, рдкреГрд╖реНрдарднреВрдорд┐ рдХреЛ рддреАрди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрд░рддреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВрдЧреЗ:

function render() {

  ctx.clearRect(0, 0, width, height);

  Render.background(ctx, background, width, height, BACKGROUND.SKY);
  Render.background(ctx, background, width, height, BACKGROUND.HILLS);
  Render.background(ctx, background, width, height, BACKGROUND.TREES);

  ...

рд╕рдбрд╝рдХ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди


рдлрд┐рд░, рд░реЗрдВрдбрд░ рдлрдВрдХреНрд╢рди рд╕рднреА рд╕реЗрдЧрдореЗрдВрдЯ рдФрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░рддрд╛ рд╣реИ рдФрд░ рджреБрдирд┐рдпрд╛ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рдкреА 1 рдФрд░ рдкреА 2 рд╕реНрдХреНрд░реАрди рдХреЛрдСрд░реНрдбрд┐рдиреЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рдЯреНрд░рд┐рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдиреНрдпрдерд╛ рд░реЗрдВрдбрд░ рдХрд░рддрд╛ рд╣реИ:

  var baseSegment = findSegment(position);
  var maxy        = height;
  var n, segment;
  for(n = 0 ; n < drawDistance ; n++) {

    segment = segments[(baseSegment.index + n) % segments.length];

    Util.project(segment.p1, (playerX * roadWidth), cameraHeight, position, cameraDepth, width, height, roadWidth);
    Util.project(segment.p2, (playerX * roadWidth), cameraHeight, position, cameraDepth, width, height, roadWidth);

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

    Render.segment(ctx, width, lanes,
                   segment.p1.screen.x,
                   segment.p1.screen.y,
                   segment.p1.screen.w,
                   segment.p2.screen.x,
                   segment.p2.screen.y,
                   segment.p2.screen.w,
                   segment.color);

    maxy = segment.p2.screen.y;
  }

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

project: function(p, cameraX, cameraY, cameraZ, cameraDepth, width, height, roadWidth) {
  p.camera.x     = (p.world.x || 0) - cameraX;
  p.camera.y     = (p.world.y || 0) - cameraY;
  p.camera.z     = (p.world.z || 0) - cameraZ;
  p.screen.scale = cameraDepth/p.camera.z;
  p.screen.x     = Math.round((width/2)  + (p.screen.scale * p.camera.x  * width/2));
  p.screen.y     = Math.round((height/2) - (p.screen.scale * p.camera.y  * height/2));
  p.screen.w     = Math.round(             (p.screen.scale * roadWidth   * width/2));
}

рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ p1 рдФрд░ P2 рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░реАрди x рдФрд░ y рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ , рд╣рдо рдЦрдВрдб рдХреЗ рдЕрдиреБрдорд╛рдирд┐рдд рдЪреМрдбрд╝рд╛рдИ ( w ) рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдкреНрд░рдХреНрд╖реЗрдкрдг рдЧрдгрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ ред рдЕрдВрдХ p1 рдФрд░ P2 рдХреЗ рд╕реНрдХреНрд░реАрди x рдФрд░ y рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ , рд╕рд╛рде рд╣реА рд╕рдбрд╝рдХ w рдХреА рдЕрдиреБрдорд╛рдирд┐рдд рдЪреМрдбрд╝рд╛рдИ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж , рд╣рдо рд╕рд╛рдорд╛рдиреНрдп рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдШрд╛рд╕, рд╕рдбрд╝рдХ, рдХреНрд╖реИрддрд┐рдЬ рдкрдЯреНрдЯрд┐рдпреЛрдВ рдФрд░ рд╡рд┐рднрд╛рдЬрд┐рдд рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдкреЙрд▓реАрдЧреЙрди рдХреЛ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рд╕рд╣рд╛рдпрддрд╛ рд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рджреЗрдЦреЗрдВ ред ) ред

Render.segmentRender.polygon common.js

рдХрд╛рд░ рд░реЗрдВрдбрд░рд┐рдВрдЧ


рдЕрдВрдд рдореЗрдВ, рдЖрдЦрд┐рд░реА рдЪреАрдЬ рд╡рд┐рдзрд┐ рдХреА рдЬрд░реВрд░рдд renderрд╣реИ рдПрдХ рдлреЗрд░рд╛рд░реА рдкреНрд░рддрд┐рдкрд╛рджрди:

  Render.player(ctx, width, height, resolution, roadWidth, sprites, speed/maxSpeed,
                cameraDepth/playerZ,
                width/2,
                height);

рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ player, рдФрд░ рдирд╣реАрдВ car, рдХреНрдпреЛрдВрдХрд┐ рдЦреЗрд▓ рдХреЗ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╕рдбрд╝рдХ рдкрд░ рдЕрдиреНрдп рдХрд╛рд░реЗрдВ рд╣реЛрдВрдЧреА, рдФрд░ рд╣рдо рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рдлреЗрд░рд╛рд░реА рдХреЛ рдЕрдиреНрдп рдХрд╛рд░реЛрдВ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рд╣реЗрд▓реНрдкрд░ рдлрд╝рдВрдХреНрд╢рди рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреЗ Render.playerрд▓рд┐рдП рдХреИрдирд╡рд╛рд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ drawImage, рдкрд╣рд▓реЗ рдЗрд╕реЗ рдЙрд╕реА рдкреНрд░рдХреНрд╖реЗрдкрдг рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдХреЗрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:

d / z

рдЬрд╣рд╛рдВ z рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдорд╢реАрди рд╕реЗ рдХреИрдорд░реЗ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рджреВрд░реА рд╣реИ, рдЪрд░ рдкреНрд▓реЗрдпрд░рдЬреЗрдб рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИ ред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдлрд╝рдВрдХреНрд╢рди рдЙрдЪреНрдЪ рдЧрддрд┐ рдкрд░ рдХрд╛рд░ рдХреЛ "рд╣рд┐рд▓рд╛рддрд╛ рд╣реИ", рдЧрддрд┐ / рдЕрдзрд┐рдХрддрдо рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрдХреЗрд▓рд┐рдВрдЧ рд╕рдореАрдХрд░рдг рдореЗрдВ рдереЛрдбрд╝рд╛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХрддрд╛ рдЬреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ ред

рдФрд░ рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдорд┐рд▓рд╛:


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


рд╣рдордиреЗ рд╕реАрдзреЗ рд╕рдбрд╝рдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдХрд╛рдо рдХрд┐рдпрд╛ред рд╣рдордиреЗ рдЬреЛрдбрд╝рд╛

  • рд╕рд╛рдорд╛рдиреНрдп рд╕рд╣рд╛рдпрдХ рдореЙрдбреНрдпреВрд▓ рдбреЛрдо
  • Util рд╕рд╛рдорд╛рдиреНрдп рдЧрдгрд┐рдд рдореЙрдбреНрдпреВрд▓
  • рд░реЗрдВрдбрд░ рд╕рд╛рдорд╛рдиреНрдп рдХреИрдирд╡рд╛рд╕ рд╕рд╣рд╛рдпрдХ рдореЙрдбреНрдпреВрд▓ ...
  • ... рд╕рд╣рд┐рдд Render.segment, Render.polygonрдФрд░Render.sprite
  • рдирд┐рд╢реНрдЪрд┐рдд рдкрд┐рдЪ рдЦреЗрд▓ рдЪрдХреНрд░
  • рдЫрд╡рд┐ рдбрд╛рдЙрдирд▓реЛрдбрд░
  • рдХреАрдмреЛрд░реНрдб рд╣реИрдВрдбрд▓рд░
  • рд▓рдВрдмрди рдкреГрд╖реНрдарднреВрдорд┐
  • рдХрд╛рд░реЛрдВ, рдкреЗрдбрд╝реЛрдВ рдФрд░ рд╣реЛрд░реНрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╢реАрдЯ
  • рд╕рдбрд╝рдХ рдХреА рдЕрд▓реНрдкрд╡рд┐рдХрд╕рд┐рдд рдЬреНрдпрд╛рдорд┐рддрд┐
  • update()рдорд╢реАрди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐
  • render()рдкреГрд╖реНрдарднреВрдорд┐, рд╕рдбрд╝рдХ рдФрд░ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рдХрд╛рд░ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐
  • <audio>рд░реЗрд╕рд┐рдВрдЧ рд╕рдВрдЧреАрдд рдХреЗ рд╕рд╛рде HTML5 рдЯреИрдЧ (рдЫрд┐рдкрд╛ рдмреЛрдирд╕!)

... рдЬрд┐рд╕рдиреЗ рд╣рдореЗрдВ рдЖрдЧреЗ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫреА рдиреАрдВрд╡ рджреАред

рднрд╛рдЧ 2. рд╡рдХреНрд░ред



рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛рдПрдВрдЧреЗ рдХрд┐ рд╡рдХреНрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред

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

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


рдпрджрд┐ рд╣рдо рдкреВрд░реА рддрд░рд╣ рдХрд╛рд░реНрдпрд╛рддреНрдордХ 3 рдбреА рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдереЗ, рддреЛ рд╣рдо рдКрдкрд░ рджрд┐рдЦрд╛рдП рдЧрдП рдмрд╣реБрднреБрдЬ рдХреА x рдФрд░ z рдзрд╛рд░рд┐рдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдХреЗ рдШрдЯрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬреНрдпрд╛рдорд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧрд╛, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рд╕рдореАрдХрд░рдгреЛрдВ рдореЗрдВ 3 рдбреА-рд░реЛрдЯреЗрд╢рди рдЪрд░рдг рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

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

рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рд╢рд╛рдпрдж рдпрд╣ рдЬрд╛рдирдХрд░ рдЖрд╢реНрдЪрд░реНрдп рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдо рд╕рдбрд╝рдХ рдЦрдВрдбреЛрдВ рдХреЗ x рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ ...

рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рд▓реВ рдХреА рд╕рд▓рд╛рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ :

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

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


рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХрд┐рддрдирд╛ рдмрджрд▓рд╛рд╡ рдХрд░рдирд╛ рд╣реИ, рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдЧрдореЗрдВрдЯ рдореЗрдВ рдПрдХ рд╡реИрд▓реНрдпреВ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ curveред рдпрд╣ рдорд╛рди рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреИрдорд░реЗ рдХреА рдХреЗрдВрджреНрд░ рд░реЗрдЦрд╛ рд╕реЗ рдЦрдВрдб рдХреЛ рдХрд┐рддрдирд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╡рд╣ рд╣реЛрдЧреА:

  • рдмрд╛рдПрдБ рдореБрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ рд╡рдХреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЛрдгрд╛рддреНрдордХ
  • рд╕рд╣реА рдореЛрдбрд╝ рдШрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рд╕рдХрд╛рд░рд╛рддреНрдордХ
  • рдЪрд┐рдХрдиреА рдШрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдХрдо
  • рддреЗрдЬ рдШрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдФрд░ рдЕрдзрд┐рдХ

рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реНрд╡рдпрдВ рдХрд╛рдлреА рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ; рдкрд░реАрдХреНрд╖рдг рдФрд░ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд╣рдо рдЕрдЪреНрдЫреЗ рдореВрд▓реНрдп рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕ рдкрд░ рд╡рдХреНрд░ "рд╕рд╣реА" рдкреНрд░рддреАрдд рд╣реЛрддреЗ рд╣реИрдВ:

var ROAD = {
  LENGTH: { NONE: 0, SHORT:  25, MEDIUM:  50, LONG:  100 }, // num segments
  CURVE:  { NONE: 0, EASY:    2, MEDIUM:   4, HARD:    6 }
};

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

easeIn:    function(a,b,percent) { return a + (b-a)*Math.pow(percent,2);                           },
easeOut:   function(a,b,percent) { return a + (b-a)*(1-Math.pow(1-percent,2));                     },
easeInOut: function(a,b,percent) { return a + (b-a)*((-Math.cos(percent*Math.PI)/2) + 0.5);        },

рдпрд╣реА рд╣реИ, рдЕрдм, рдПрдХ рдЦрдВрдб рдХреЛ рдЬреНрдпрд╛рдорд┐рддрд┐ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ ...

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

рд╣рдо рдШреБрдорд╛рд╡рджрд╛рд░ рд░рд╛рд╕реНрддреЗ рд╕реЗ рдЪрд┐рдХрдиреА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐, рдЦреЛрдЬ рдФрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:

function addRoad(enter, hold, leave, curve) {
  var n;
  for(n = 0 ; n < enter ; n++)
    addSegment(Util.easeIn(0, curve, n/enter));
  for(n = 0 ; n < hold  ; n++)
    addSegment(curve);
  for(n = 0 ; n < leave ; n++)
    addSegment(Util.easeInOut(curve, 0, n/leave));
}

... рдФрд░ рд╢реАрд░реНрд╖ рдкрд░ рдЖрдк рдЕрддрд┐рд░рд┐рдХреНрдд рдЬреНрдпрд╛рдорд┐рддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрд╕-рдЖрдХрд╛рд░ рдХреЗ рдШрдЯрддрд╛:

function addSCurves() {
  addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,  -ROAD.CURVE.EASY);
  addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,   ROAD.CURVE.MEDIUM);
  addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,   ROAD.CURVE.EASY);
  addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,  -ROAD.CURVE.EASY);
  addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,  -ROAD.CURVE.MEDIUM);
}

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


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

рд╣рдо рдПрдХ рдордирдорд╛рдирд╛ рдХрд╛рд░рдХ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдорд╛рд░реА рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдУрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

var centrifugal = 0.3;   // centrifugal force multiplier when going around curves

рдФрд░ рдлрд┐рд░ рд╣рдо рдмрд╕ playerXрдЗрд╕рдХреА рд╡рд░реНрддрдорд╛рди рдЧрддрд┐, рд╡рдХреНрд░ рдорд╛рди рдФрд░ рдХреЗрдиреНрджреНрд░рд╛рдкрд╕рд╛рд░рдХ рдмрд▓ рдЧреБрдгрдХ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗ :

playerX = playerX - (dx * speedPercent * playerSegment.curve * centrifugal);

рд╡рдХреНрд░ рдкреНрд░рддрд┐рдкрд╛рджрди


рд╣рдордиреЗ рдКрдкрд░ рдХрд╣рд╛ рд╣реИ рдХрд┐ рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рд╕рдбрд╝рдХ рдЦрдВрдб cameraXрдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдкреНрд░рдХреНрд╖реЗрдкрдг рдЧрдгрдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдореВрд▓реНрдп рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдХреЗ рдирдХрд▓реА рд╡рдХреНрд░реЛрдВ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ render()ред


рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдбреНрд░рд╛рдЗрд╡ рд╡реИрд░рд┐рдПрдмрд▓ dx рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВрдЧреЗ , рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрд▓реНрдпреВ curveрдХреЗ рд╕рд╛рде-рд╕рд╛рде рд╡реЗрд░рд┐рдПрдмрд▓ x рдХреЛ рдмрдврд╝рд╛рдПрдВрдЧреЗ , рдЬрд┐рд╕рдХрд╛ cameraXрдЙрдкрдпреЛрдЧ рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдХреИрд▓рдХреБрд▓реЗрд╢рди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╡реИрд▓реНрдпреВ рдХреА рдСрдлрд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ ред

рдШрдЯрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

  • x рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддреНрдпреЗрдХ рдЦрдВрдб рдХреЗ рдкреНрд░рдХреНрд╖реЗрдкрдг p1 рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ
  • x + dx рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдкреА 2 рдХреЛ рд╢рд┐рдлреНрдЯ рдХрд░реЗрдВ
  • dx рджреНрд╡рд╛рд░рд╛ рдЕрдЧрд▓реЗ рдЦрдВрдб рдХреЗ рд▓рд┐рдП x рдмрдврд╝рд╛рдПрдБ

рдЕрдВрдд рдореЗрдВ, рдЦрдВрдб рдХреА рд╕реАрдорд╛рдУрдВ рдХреЛ рдкрд╛рд░ рдХрд░рддреЗ рд╕рдордп рдлрдЯреЗ рд╣реБрдП рдмрджрд▓рд╛рд╡реЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ dx рдХреЛ рд╡рд░реНрддрдорд╛рди рдЖрдзрд╛рд░ рдЦрдВрдбреЛрдВ рдХреЗ рдкреНрд░рдХреНрд╖реЗрдкрд┐рдд рд╡рдХреНрд░ рдорд╛рди рдХреЗ рд╕рд╛рде рдЖрд░рдВрднреАрдХреГрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ред

рд╡рд┐рдзрд┐ render()рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

var baseSegment = findSegment(position);
var basePercent = Util.percentRemaining(position, segmentLength);
var dx = - (baseSegment.curve * basePercent);
var x  = 0;
for(n = 0 ; n < drawDistance ; n++) {

  ...

  Util.project(segment.p1, (playerX * roadWidth) - x,      cameraHeight, position - (segment.looped ? trackLength : 0), cameraDepth, width, height, roadWidth);
  Util.project(segment.p2, (playerX * roadWidth) - x - dx, cameraHeight, position - (segment.looped ? trackLength : 0), cameraDepth, width, height, roadWidth);

  x  = x + dx;
  dx = dx + segment.curve;

  ...
}

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


рдЕрдВрдд рдореЗрдВ, рд╣рдореЗрдВ рд▓рдВрдмрди рдкреГрд╖реНрдарднреВрдорд┐ рдкрд░рддреЛрдВ рдХреЛ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдкрд░рдд рдХреЗ рд▓рд┐рдП рдСрдлрд╕реЗрдЯ рдХреЛ рд╕рдВрдЪрдпрд┐рдд рдХрд░рдирд╛ ...

var skySpeed    = 0.001; // background sky layer scroll speed when going around curve (or up hill)
var hillSpeed   = 0.002; // background hill layer scroll speed when going around curve (or up hill)
var treeSpeed   = 0.003; // background tree layer scroll speed when going around curve (or up hill)
var skyOffset   = 0;     // current sky scroll offset
var hillOffset  = 0;     // current hill scroll offset
var treeOffset  = 0;     // current tree scroll offset

... рдФрд░ update()рдореМрдЬреВрджрд╛ рдЦрд┐рд▓рд╛рдбрд╝реА рд╕реЗрдЧрдореЗрдВрдЯ рдХреЗ рд╡рдХреНрд░ рдореВрд▓реНрдп рдФрд░ рдЗрд╕рдХреА рдЧрддрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рдордп рдХреЗ рджреМрд░рд╛рди рдЗрд╕реЗ рдмрдврд╝рд╛рдирд╛ ...

skyOffset  = Util.increase(skyOffset,  skySpeed  * playerSegment.curve * speedPercent, 1);
hillOffset = Util.increase(hillOffset, hillSpeed * playerSegment.curve * speedPercent, 1);
treeOffset = Util.increase(treeOffset, treeSpeed * playerSegment.curve * speedPercent, 1);

... рдФрд░ рдлрд┐рд░ render()рдкреГрд╖реНрдарднреВрдорд┐ рдХреА рдкрд░рддреЗрдВ рдХрд░рддреЗ рд╕рдордп рдЗрд╕ рдСрдлрд╕реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ред

Render.background(ctx, background, width, height, BACKGROUND.SKY,   skyOffset);
Render.background(ctx, background, width, height, BACKGROUND.HILLS, hillOffset);
Render.background(ctx, background, width, height, BACKGROUND.TREES, treeOffset);

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


рддреЛ, рдпрд╣рд╛рдБ рд╣рдо рдирдХрд▓реА рдЫрджреНрдо рддреНрд░рд┐-рдЖрдпрд╛рдореА рдШрдЯрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:


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

рд╡рдХреНрд░ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЛрдб рдХреА рдХреБрдЫ рд╣реА рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдордЭрдирд╛ (рдФрд░ рд╡рд░реНрдгрди рдХрд░рдирд╛) рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред рдШрдЯрддрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ рдФрд░ рдЬрдм рд╡реЗ рдПрдХ рдореГрдд рдЕрдВрдд рдореЗрдВ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВ рддреЛ рднрдЯрдХрдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдХрд┐рд╕реА рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдп рдХреЛ рдЕрдВрдЬрд╛рдо рджреЗрдирд╛ рдФрд░ "рд╕рд╣реА рдврдВрдЧ рд╕реЗ" рд╕рдм рдХреБрдЫ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдирд╛ рдФрд░ рднреА рдЖрд╕рд╛рди рд╣реИ; рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдк рдпрд╣ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ, рдЖрдк рдореИрдЯреНрд░рд┐рд╕реЗрд╕, рдШреБрдорд╛рд╡ рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ 3 рдбреА-рдЬрд┐рдпреЛрдореЗрдЯреНрд░реА рдХреЗ рд╕рд╛рде рдПрдХ рдкреВрд░реА рддрд░рд╣ рдХрд╛рд░реНрдпрд╛рддреНрдордХ 3 рдбреА-рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗ ... рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рдпрд╣ рд╣рдорд╛рд░рд╛ рдХрд╛рдо рдирд╣реАрдВ рд╣реИред

рдЬрдм рдореИрдВрдиреЗ рдпрд╣ рд▓реЗрдЦ рд▓рд┐рдЦрд╛ рдерд╛, рддреЛ рдореБрдЭреЗ рдпрдХреАрди рдерд╛ рдХрд┐ рдШрдЯрддрд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рдорд╕реНрдпрд╛рдПрдВ рдереАрдВред рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реБрдП, рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрдпрд╛ рдХрд┐ рдореБрдЭреЗ рдПрдХ рдХреЗ рдмрдЬрд╛рдп dx рдФрд░ x рдбреНрд░рд╛рдЗрд╡ рдХреЗ рджреЛ рдореВрд▓реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ ... рдФрд░ рдЕрдЧрд░ рдореИрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХреБрдЫ рд╕рдордЭрд╛ рдирд╣реАрдВ рд╕рдХрддрд╛, рддреЛ рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рдЧрдпрд╛ рдХрд╣реАрдВ ...

... рд▓реЗрдХрд┐рди рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рд╕рдордп "рдкрд░" рд╕рдкреНрддрд╛рд╣рд╛рдВрдд " рд▓рдЧрднрдЧ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдФрд░, рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ, рдШрдЯрддрд╛ рдореБрдЭреЗ рдХрд╛рдлреА рд╕реБрдВрджрд░ рд▓рдЧрддрд╛ рд╣реИ, рдФрд░ рдЕрдВрдд рдореЗрдВ, рдпрд╣ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред

All Articles