{"id":484240,"date":"2026-06-19T09:20:59","date_gmt":"2026-06-19T09:20:59","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=484240"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=484240","title":{"rendered":"\u0428\u0435\u0441\u0442\u0438\u0434\u0435\u0441\u044f\u0442\u0438\u043b\u0435\u0442\u043d\u0438\u0439 \u0437\u0430\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0439 \u0438 \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u043a\u0440\u044b\u0441\u0430. F# \u043d\u0430 Godot. \u0427\u0430\u0441\u0442\u044c 15. \u041a\u0443\u043b\u044c\u043c\u0438\u043d\u0430\u0446\u0438\u044f \u0438 \u043f\u043e\u043b\u0451\u0442"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/1a\/8c\/dd\/1a8cdd8891a32e1190dab5802fc43831.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/1a\/8c\/dd\/1a8cdd8891a32e1190dab5802fc43831.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/1a\/8c\/dd\/1a8cdd8891a32e1190dab5802fc43831.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p> \u0412 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/1026100\/\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0433\u043b\u0430\u0432\u0435<\/a> \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e\u0440\u0442 <a href=\"https:\/\/habr.com\/ru\/articles\/554960\/\">\u0442\u0430\u0439\u043b\u043e\u0432\u044b\u0445 \u043c\u0438\u0440\u043e\u0432<\/a> \u043d\u0430 F#, \u0433\u0434\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0438\u0441\u044c \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u0430\u043b\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 Godot. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043d\u0430\u0448 \u043f\u0440\u0438\u0446\u0435\u043b \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u0441\u044f \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 <code>RenderingServer<\/code> \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u0431\u044b\u0442\u043e\u0432\u0443\u0445\u0443 (\u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 + \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435). <\/p>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u043b \u043f\u0435\u0440\u0432\u043e\u043f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440\u0430 \u0442\u0435\u0445 \u0442\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u0446\u0438\u043a\u043b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0441 \u0436\u0434\u0451\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0441 \u043f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u044f\u043c\u0438 \u0432\u0438\u0434\u0430 \u00ab\u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f <code>&lt;\u0448\u0442\u0443\u043a\u043e\u0432\u0438\u043d\u0435, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0438 \u0432 \u0446\u0438\u043a\u043b\u0435&gt;<\/code>\u00bb. \u041a\u043e\u043d\u0435\u0447\u043d\u043e-\u0436\u0435, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043a\u0437\u043e\u0442\u0438\u043a\u0438, \u043d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0441 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e (\u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043c\u0438\u043d\u0438-\u043a\u0430\u0440\u0442\u044b, \u043e\u043d\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 GUI \u043f\u043e\u043f\u0430\u043b\u0430 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0433\u043b\u0430\u0432\u0443) \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0432 \u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u0438\u0433\u0440\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<h3>\u041f\u0440\u0438\u043a\u0432\u0435\u043b<\/h3>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/806145\/\">An incursion under C#. \u041f\u0440\u043e\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c F# \u0432 Godot<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/904306\/\">\u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>\u0428\u0435\u0441\u0442\u0438\u0434\u0435\u0441\u044f\u0442\u0438\u043b\u0435\u0442\u043d\u0438\u0439 \u0437\u0430\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0439 \u0438 \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u043a\u0440\u044b\u0441\u0430. F# \u043d\u0430 Godot<\/h3>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/846224\/\">\u0427\u0430\u0441\u0442\u044c 1. \u0412\u0441\u0442\u0440\u0435\u0447\u0430 \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/850980\/\">\u0427\u0430\u0441\u0442\u044c 2. \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/856406\/\">\u0427\u0430\u0441\u0442\u044c 3. \u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b c \u043f\u0435\u0440\u0435\u0441\u0430\u0434\u043a\u0430\u043c\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/904772\/\">\u0427\u0430\u0441\u0442\u044c 4. \u0414\u0435\u0444\u043e\u043b\u0442\u044b, option \u0438 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/909536\/\">\u0427\u0430\u0441\u0442\u044c 5. \u041e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/917404\/\">\u0427\u0430\u0441\u0442\u044c 6. \u041a\u0430\u043a \u0434\u043e\u0431\u044b\u0442\u044c \u043d\u0435\u0447\u0442\u043e<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/919448\/\">\u0427\u0430\u0441\u0442\u044c 7. \u041a\u0430\u043a \u0443\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0435\u0447\u0442\u043e<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/926138\/\">\u0427\u0430\u0441\u0442\u044c 8. \u0417\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0449\u0438\u0439 \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/939202\/\">\u0427\u0430\u0441\u0442\u044c 9. \u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, _Ready<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/941480\/\">\u0427\u0430\u0441\u0442\u044c 10. C# \u043d\u0435 \u043d\u0443\u0436\u0435\u043d<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/962564\/\">\u0427\u0430\u0441\u0442\u044c 11. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0434\u0435\u0440\u0435\u0432\u044c\u044f<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/970686\/\">\u0427\u0430\u0441\u0442\u044c 12. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/1001216\/\">\u0427\u0430\u0441\u0442\u044c 13. \u041e\u0431\u0449\u0438\u0439 \u0441\u0431\u043e\u0440<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/1026100\/\">\u0427\u0430\u0441\u0442\u044c 14. RenderingServer \u043d\u0430 \u043f\u043e\u043b\u043d\u0443\u044e<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/1049342\/\">\u0427\u0430\u0441\u0442\u044c 15. \u041a\u0443\u043b\u044c\u043c\u0438\u043d\u0430\u0446\u0438\u044f \u0438 \u043f\u043e\u043b\u0451\u0442<\/a> \/\/ \u043c\u044b \u0437\u0434\u0435\u0441\u044c<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<h3>\u0417\u0432\u0435\u0437\u0434\u043e\u043b\u0451\u0442<\/h3>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u044f \u043e\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043b \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u0446\u0435\u043d\u044b \u043a\u0430\u043a \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u044f \u0438\u0437 3 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442:<\/p>\n<ul>\n<li>\n<p>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u043d\u0432\u0435\u043d\u0442\u0430\u0440\u044f (<code>props<\/code>);<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0440\u044b\u0447\u0430\u0433\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u0441\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u043c\u0435\u0442\u043e\u0434\u044b);<\/p>\n<\/li>\n<li>\n<p>\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0445\u043e\u043b\u0441\u0442\u0430 (<code>: CanvasItemId<\/code>).<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0438\u043f <code>Spaceship<\/code> \u0432 \u044d\u0442\u0443 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"fsharp\">type Spaceship (disposables, cellOps : IsometricGrid.CellOps) =    static let spaceshipTexture : Texture2D = GD.load \"\"\"uid:\/\/oyqyauhtdyno\"\"\"    static let iconSize = 48f * Vector2.One    let surfaces = {|        Highlight = CanvasItemId.Create(Disposables = disposables)        Spaceship = CanvasItemId.Create(Disposables = disposables)    |}    let mutable direction = Vector2I.Zero    let mutable position = Vector2I.Zero    let mutable progress = 0f    let mutable isHighlightDirty = true    let mutable isSpaceshipDirty = true    let redraw () =        if isHighlightDirty then            surfaces.Highlight.Clear()            cellOps.Draw false 2f SceneColors.spaceship surfaces.Highlight position            isHighlightDirty &lt;- false        if isSpaceshipDirty then            surfaces.Spaceship.Clear()            surfaces.Spaceship.AddPolygon(                Corners.clockwise false                     (cellOps.ToPixelCenter position                         - 0.5f * iconSize                        - 0.125f * (2f + cos progress) * iconSize._Y                    )                    iconSize.X_                    iconSize._Y                , [||]                , (                    Vector2.clockwiseCorners false                    |&gt; Array.map ^ fun p -&gt;                        (Vector2.One + p + direction.AsVector2) \/ 3f                )                , textureId = spaceshipTexture.TextureId            )            isSpaceshipDirty &lt;- false    do redraw ()    let positionChanged = Event&lt;_&gt;()    member _.Direction        with get () = direction        and set value =            if direction &lt;&gt; value then                direction &lt;- value                isSpaceshipDirty &lt;- true    member this.LookToward target =        this.Direction &lt;-             (target - position).AsVector2            |&gt; SimplifyDirection.toward     member _.Position        with get () = position        and set value =            if position &lt;&gt; value then                let previous = position                position &lt;- value                isHighlightDirty &lt;- true                isSpaceshipDirty &lt;- true                positionChanged.Trigger {|                    Previous = previous                    Current = position                |}    member _.PositionChanged = positionChanged.Publish    member _.Process delta =        if delta &lt;&gt; 0f then            progress &lt;- progress + delta            isSpaceshipDirty &lt;- true    member _.DeferRedraw () =        IDisposable.create redraw    member _.Surfaces = surfaces<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>1 Model -&gt; 2 View<\/h4>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u0431\u0440\u043e\u0441\u0430\u0435\u0442\u0441\u044f \u0432 \u0433\u043b\u0430\u0437\u0430, \u2014 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0443\u0445 \u0445\u043e\u043b\u0441\u0442\u043e\u0432 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u041d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c \u043a\u043e\u0440\u0430\u0431\u043b\u044c, \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u2014 \u0437\u0435\u043b\u0451\u043d\u0443\u044e \u0440\u0430\u043c\u043a\u0443 \u043f\u043e\u0434 \u043a\u043e\u0440\u0430\u0431\u043b\u0451\u043c. \u0412 \u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0434\u0438\u043d \u0443\u0437\u0435\u043b \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0434\u0432\u0430 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c\u0435\u0440\u0442\u0432\u043e \u043f\u0440\u0438\u0431\u0438\u0442\u044b \u0434\u0440\u0443\u0433 \u043a \u0434\u0440\u0443\u0433\u0443.<\/p>\n<p>\u041f\u043e \u043c\u043e\u0438\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f\u043c, \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0441\u0432\u043e\u044e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c (\u0438 \u0434\u0430\u0436\u0435 \u0442\u043e\u043f\u043e\u0440\u043d\u043e\u0441\u0442\u044c) \u2014 \u043d\u0435\u0442\u0438\u043f\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043a\u043e\u0434\u043e\u0432\u044b\u0445 \u0431\u0430\u0437 \u043d\u0430 Godot. \u0418 \u0434\u0435\u043b\u043e \u043d\u0435 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0445\u043e\u043b\u0441\u0442\u043e\u0432, \u0432\u0435\u0434\u044c \u043d\u0430 \u0438\u0445 \u043c\u0435\u0441\u0442\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u043d\u043e\u0434\u044b:<\/p>\n<pre><code class=\"fsharp\">type Hero (...) =    ...    member val Views = {|        Battlefield = ... \/\/ : Node2D        Minimap = ... \/\/ : Node2D        Skills = ... \/\/ : Control        Summary = ... \/\/ : Control        ...    |}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043d\u0435\u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c Godot \u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 Godot-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432. \u0412 \u043d\u0451\u043c \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043d\u043e\u0434\u0430\u043c\u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u0432\u044f\u0437\u043a\u0430\u043c\u0438, \u043a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u041d\u043e \u043a\u0430\u043a \u043d\u0435\u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0433\u043b\u0430\u0432\u0430\u0445, \u043d\u043e\u0434\u044b, \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442, \u0430 \u044d\u0442\u043e \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u0442 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 F#. \u041d\u0430\u0448\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043a\u0442\u043e-\u0442\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u0422\u043e \u0435\u0441\u0442\u044c, \u043d\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u2014 \u043d\u0435\u0442 \u0432\u044c\u044e\u0445\u0438.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0434\u044b \u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u0441 \u043d\u0430 \u0432\u043a\u043e\u0440\u044f\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u044d\u0442\u043e\u0439 \u0441\u0430\u043c\u043e\u0439 \u043d\u043e\u0434\u044b, \u0447\u0442\u043e \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u043b\u0438\u0448\u044c \u0440\u0430\u0437\u043c\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>hero.Views.Battlefield<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e <code>Node2D<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043a\u0438\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0438\u0433\u0440\u043e\u043a \u0437\u0430\u0431\u0440\u043e\u0441\u0438\u0442 \u0432 <code>battlefield.AddChild<\/code> \u0438 \u0435\u0433\u043e <code>Position<\/code> \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u0438\u0431\u043e <code>Hero<\/code>, \u043b\u0438\u0431\u043e \u0442\u0435\u043c \u0436\u0435 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0438\u0433\u0440\u043e\u043a\u043e\u043c (\u043a\u0430\u043a \u043d\u0430\u043f\u0438\u0448\u0435\u043c). \u0412 \u0442\u0430\u043a\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 <code>Views.Battlefield<\/code> \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0448\u0430\u0440\u0438\u043a\u043e\u043c \u0431\u0435\u0437 \u0440\u0443\u0447\u0435\u043a, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u0451\u0440\u0433\u0430\u0442\u044c, \u0438 \u0431\u0435\u0437 \u043d\u043e\u0436\u0435\u043a, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u043d \u043c\u043e\u0433 \u0431\u044b \u043a\u0443\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u0443\u0431\u0435\u0436\u0430\u0442\u044c. \u0416\u0451\u0441\u0442\u043a\u043e, \u043d\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u043e. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441 \u0440\u043e\u0441\u0442\u043e\u043c \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0435\u0439, \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u044c\u044e\u0445\u0443 \u0442\u0430\u043a\u0438 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043e\u0442\u043e\u0440\u0432\u0430\u0442\u044c \u043e\u0442 \u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u043e \u0434\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u043d\u0430\u0434\u043e \u0435\u0449\u0451 \u0434\u043e\u0436\u0438\u0442\u044c.<\/p>\n<h4>\u0418 \u0441\u043d\u043e\u0432\u0430 rec<\/h4>\n<p>\u0425\u043e\u043b\u0441\u0442\u044b <code>spaceship.Surfaces<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0446\u0430 \u0441\u0446\u0435\u043d\u044b \u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"fsharp\">do  let rootLayer = CanvasItemId.Create(        Parent = main.CanvasItemId        , Disposables = disposables        , Transform = gridTransform    )    [        motionLayers.UnderGrid        pathView.Surfaces.UnderGrid        gridView.Surface        \/\/ \u0422\u0443\u0442 \u0437\u0435\u043b\u0451\u043d\u0430\u044f \u0440\u0430\u043c\u043a\u0430.        spaceship.Surfaces.Highlight        motionLayers.OverGrid        pathView.Surfaces.OverGrid        underMouse.Surface            \/\/ \u0412\u043d\u0443\u0442\u0440\u0438 \u043b\u0435\u0436\u0430\u0442 `spaceship.Surfaces.Spaceship` \u0438 \u0445\u043e\u043b\u0441\u0442\u044b \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439.        figureLayers.Surface    ]    |&gt; Seq.iter rootLayer.AddCanvasItem<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a <code>surfaces.Highlight<\/code> \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d, \u043e \u043d\u0451\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u044b\u0442\u044c. \u0421 <code>surfaces.Spaceship<\/code> \u0432\u0441\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0417\u0432\u0435\u0437\u0434\u043e\u043b\u0451\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439, \u0442\u043e \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0445\u043e\u043b\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u0442\u044c \u0432 \u0441\u043b\u043e\u0435 \u0441 \u0431\u043b\u043e\u043a\u0430\u043c\u0438, \u0447\u0435\u0439 <code>ZIndex<\/code> \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c <code>ZIndex<\/code> \u043a\u043e\u0440\u0430\u0431\u043b\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c <code>surfaces.Spaceship<\/code> \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u044f\u043c\u0438 <code>figureLayers<\/code> \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c <code>spaceship.PositionChanged<\/code>:<\/p>\n<pre><code class=\"fsharp\">do disposables.Add ^ spaceship.PositionChanged.subscribe ^ fun p -&gt;    figureLayers.GetLayerByPosition p.Current    |&gt; spaceship.Surfaces.Spaceship.SetParent    camera.Position &lt;- grid.Cell.ToPixelCenter p.Current * gridTransform    \/\/ ...<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u043f\u0440\u043e \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u044f \u043a\u043e\u0440\u0430\u0431\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0435\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0442\u043e \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435 \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u043a\u043e\u0440\u0430\u0431\u043b\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u043d\u043e. \u0421\u0432\u044f\u0437\u043a\u0430 <code>\u0412\u044b\u0437\u043e\u0432 + (\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 =&gt; \u0412\u044b\u0437\u043e\u0432)<\/code> \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u043e, \u0438 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432 \u043e\u043d\u0430 \u0432\u0435\u0434\u0451\u0442 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\/\u0438\u043b\u0438 \u043a \u043b\u043e\u0436\u043d\u044b\u043c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0412 F# \u0441 \u043d\u0435\u0439 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f, \u043f\u043e \u0441\u0443\u0442\u0438, \u0442\u0430\u043a\u0436\u0435, \u043d\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0443\u0442\u044c \u0438\u043d\u0430\u0447\u0435:<\/p>\n<pre><code class=\"fsharp\">\/\/ \u041d\u0435 \u0437\u0430\u0441\u043e\u0440\u044f\u0435\u043c \u0441\u043a\u043e\u0443\u043f.do  let rec go () =        invalidate spaceship.Position        disposables.Add ^ spaceship.PositionChanged.subscribe ^ fun p -&gt; invalidate p.Current    and invalidate position =        figureLayers.GetLayerByPosition position        |&gt; spaceship.Surfaces.Spaceship.SetParent        camera.Position &lt;- grid.Cell.ToPixelCenter position * gridTransform        \/\/ ...    \/\/ \u0422\u0443\u0442 \u043d\u0430\u0434\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u043f\u0440\u043e \u0432\u044b\u0437\u043e\u0432.    \/\/ \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0441\u0451 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0431\u043b\u043e\u043a\u0435 do, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430\u043c \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u043e\u043c\u043d\u0438\u0442.    go ()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 (\u0432 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435) \u043d\u0435 \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u044d\u0442\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u0437\u043b\u043e\u0443\u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 <code>let rec ... and<\/code>, \u0447\u0435\u043c \u0432 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/856406\/\">\u0433\u043b\u0430\u0432\u0435 3<\/a>. \u041e\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u0437\u0434\u0435\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0433\u0434\u0435 \u0438 \u043a\u043e\u0433\u0434\u0430 \u0434\u0451\u0440\u0433\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0438 \u043b\u0438\u0448\u044c \u043f\u043e\u0442\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u0442\u0435\u043b\u043e. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0442\u0438\u043f\u044b \u0431\u0443\u0434\u0443\u0442 \u0443 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0430\u0436\u043d\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445.<\/p>\n<h4>\u0414\u044b\u0445\u0430\u043d\u0438\u0435 \u0436\u0438\u0437\u043d\u0438<\/h4>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>Spaceship<\/code> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f 3 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><code>position<\/code> \u2014 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0437\u0432\u0435\u0437\u0434\u043e\u043b\u0451\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><code>direction<\/code> \u2014 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d \u0441\u043c\u043e\u0442\u0440\u0438\u0442 (\u0438\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e 8 \u0448\u0442\u0443\u043a).<\/p>\n<\/li>\n<li>\n<p><code>progress<\/code> \u2014 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0441\u0446\u0435\u043d\u044b, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0432\u044b\u0441\u043e\u0442\u0430 \u043a\u043e\u0440\u0430\u0431\u043b\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0437\u0438\u0446\u0438\u044f \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u0430 \u0432\u043e\u0442 \u043f\u0440\u043e \u0432\u044b\u0441\u043e\u0442\u0443 \u0442\u0430\u043c \u0440\u0435\u0447\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e. \u0415\u0451 \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u044f \u0442\u0440\u0443\u0434\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0430\u0445, \u043d\u043e \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0440\u0430\u0431\u043b\u044c \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0432\u0435\u0440\u0445-\u0432\u043d\u0438\u0437 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043e\u043d \u043f\u043e \u043f\u043e\u043b\u044e \u0438\u043b\u0438 \u043d\u0435\u0442:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/6a\/80\/5e\/6a805ebd0ce8dc4b5ce45813f90706d0.gif\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/webt\/6a\/80\/5e\/6a805ebd0ce8dc4b5ce45813f90706d0.gif 780w,&#10;       https:\/\/habrastorage.org\/webt\/6a\/80\/5e\/6a805ebd0ce8dc4b5ce45813f90706d0.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u042f \u043d\u0430\u0437\u044b\u0432\u0430\u044e \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u00ab\u0434\u044b\u0445\u0430\u043d\u0438\u0435\u043c\u00bb. \u041c\u043d\u0435 \u043e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e \u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u044d\u0442\u0430 \u0448\u0442\u0443\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0435 (\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u0434\u0440 \u043f\u0430\u0434\u0435\u043d\u0438\u0435) \u043c\u0435\u0442\u043e\u0434\u0430 <code>_Process<\/code> \u0432 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 IDE \u0438\u043b\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430.<\/p>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430: \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0435 \u0430\u043a\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u0438\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0430\u043a\u0442\u043e\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u043c-\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u0442\u0443\u043f\u043d\u044f\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u043b. \u041a\u043e\u043c\u0443 \u0434\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0432 IoT, \u043c\u043e\u0433\u043b\u0438 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0436\u0435\u043b\u0435\u0437\u044f\u0447\u043d\u0438\u043a\u0438. \u041e\u043d\u0438 \u043c\u0438\u0433\u0430\u044e\u0442 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430\u043c\u0438 \u043f\u043b\u0430\u0442\u044b \u0432 <strong>\u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435<\/strong> \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0415\u0441\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u0437\u0430\u0432\u0438\u0441\u0430\u0435\u0442, \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0451\u0442 \u043c\u0438\u0433\u0430\u0442\u044c (\u0442\u0443\u043f\u043e \u0433\u043e\u0440\u0438\u0442 \u0438\u043b\u0438 \u0442\u0430\u043a\u0436\u0435 \u0442\u0443\u043f\u043e \u043d\u0435 \u0433\u043e\u0440\u0438\u0442), \u0438\u0437 \u0447\u0435\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434, \u0447\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430.<\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u0439 \u0441\u0446\u0435\u043d\u0435 \u0430\u043a\u0442\u043e\u0440 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043c\u043e\u0433 \u0448\u0438\u043a\u0430\u043d\u0443\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043c\u0438\u0433\u0430\u044e\u0449\u0435\u0433\u043e \u043e\u0433\u043e\u043d\u044c\u043a\u0430. \u041d\u043e \u0432 \u043a\u0440\u0443\u043f\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u0430\u043b\u0438\u0432\u0430\u0442\u044c \u0437\u0430 \u0442\u044b\u0441\u044f\u0447\u0438. \u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u043a\u043d\u0430 \u0441 \u043f\u043e\u043b\u044f\u043c\u0438 \u043c\u0438\u0433\u0430\u044e\u0449\u0438\u0445 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u2014 \u0441\u0430\u043c\u044b\u0439 \u0434\u0435\u0448\u0451\u0432\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0443\u043c\u0435\u0440\u0448\u0438\u0445 \u0438\u043b\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0430\u043a\u0442\u043e\u0440\u043e\u0432. \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0430\u043a (\u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0434\u043d\u0438, \u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 \u0434\u0432\u0435):<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/3c\/45\/5e\/3c455e1f0bbf2baecc852e41356a6443.gif\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/webt\/3c\/45\/5e\/3c455e1f0bbf2baecc852e41356a6443.gif 780w,&#10;       https:\/\/habrastorage.org\/webt\/3c\/45\/5e\/3c455e1f0bbf2baecc852e41356a6443.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 \u043f\u043b\u0430\u043d\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u0437\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0430\u043a\u0442\u043e\u0440\u043e\u043c \u044d\u0442\u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u0435\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u0435\u043d, \u0447\u0435\u043c \u043b\u043e\u0433\u0438 \u0438\u043b\u0438 \u0434\u0435\u0431\u0430\u0433, \u043e\u0434\u043d\u0430\u043a\u043e \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043e\u0431\u0449\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0442\u043d\u044e \u0430\u043a\u0442\u043e\u0440\u043e\u0432. \u041e\u043d\u0438 \u0431\u044b\u0432\u0430\u044e\u0442 \u0434\u0432\u0443\u0445 \u0442\u0438\u043f\u043e\u0432 (\u043d\u0435\u043a\u0438\u0435 \u0437\u0435\u043b\u0451\u043d\u044b\u0435 \u0438 \u043d\u0435\u043a\u0438\u0435 \u0441\u0438\u043d\u0438\u0435), \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443 (\u0431\u0435\u043b\u044b\u0439), \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438 (\u043a\u0440\u0430\u0441\u043d\u044b\u0439), \u0430 \u0438\u043d\u043e\u0433\u0434\u0430 \u0438 \u0442\u0438\u0445\u043e \u0443\u043c\u0438\u0440\u0430\u0442\u044c (\u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u044f\u0447\u0435\u0439\u043a\u0438 \u0431\u0435\u0437 \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u0432 \u043f\u0430\u0443\u0437\u044b).<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043d\u0430\u043c\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u0438\u0445\u0438\u0435 \u0441\u043c\u0435\u0440\u0442\u0438 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0445 \u0447\u0443\u0442\u044c \u043f\u043e\u0433\u0440\u043e\u043c\u0447\u0435. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u044b \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0432\u044b\u0432\u043e\u0434\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0422\u0430\u043a \u043d\u0430 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432\u044b\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 225 \u043a\u0430\u0434\u0440\u043e\u0432, \u0438 \u0441\u0440\u0435\u0434\u0438 \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u044b \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e. \u041a\u043e\u043c\u0443 \u0434\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c\u0438 \u0436\u0435\u043b\u0435\u0437\u043a\u0430\u043c\u0438, \u043f\u043e\u0439\u043c\u0443\u0442, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0443.<\/p>\n<p>\u041d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0443\u0442\u043e\u0447\u043d\u044e, \u0447\u0442\u043e \u0432\u0441\u044f \u044d\u0442\u0430 \u0438\u043d\u0444\u0430 \u043d\u0443\u0436\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u0443, \u0438 \u043b\u0438\u0448\u044c \u0432 \u043e\u0447\u0435\u043d\u044c \u0440\u0435\u0434\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0435\u0451 \u043c\u043e\u0436\u0435\u0442 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0434\u043e\u043a\u0430\u0437\u0430\u0432\u0448\u0438\u0439 \u0441\u0432\u043e\u044e \u0440\u0430\u0437\u0443\u043c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u0438\u043a. \u0415\u0451 \u043d\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u044f\u0434\u043e\u0432\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e (\u0438\u0433\u0440\u043e\u043a\u0443), \u0438 \u0443\u0436 \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043d\u043e\u0441\u0430\u0442\u043e\u043c\u0443 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0443.<\/p>\n<h4>\u0413\u0440\u044f\u0437\u043d\u044b\u0439, \u043d\u0435\u0433\u0440\u044f\u0437\u043d\u044b\u0439, \u0433\u0440\u044f\u0437\u043d\u044b\u0439, \u2026<\/h4>\n<p>\u0425\u043e\u043b\u0441\u0442 \u0441 \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u043e\u0439 \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 <code>position<\/code>, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0445\u043e\u043b\u0441\u0442 \u043a\u043e\u0440\u0430\u0431\u043b\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u0441\u0440\u0430\u0437\u0443 \u043e\u0442 \u0432\u0441\u0435\u0445 \u0442\u0440\u0451\u0445 \u043f\u043e\u043b\u0435\u0439. \u041f\u0440\u0438\u0447\u0451\u043c \u044d\u0442\u0438 \u043f\u043e\u043b\u044f \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c. \u0414\u0435\u043b\u044c\u0442\u0443 \u0434\u043b\u044f <code>progress<\/code> \u043c\u044b \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0435\u043c \u0432 \u0440\u0443\u0447\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435, \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430, \u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043b\u0438\u0431\u043e \u043e\u0442 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u0443\u0440\u0441\u043e\u0440\u0430, \u043b\u0438\u0431\u043e \u043e\u0442 \u0442\u043e\u0439 \u0436\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438.<\/p>\n<p>\u041c\u0430\u043b\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0446\u0435\u043d\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430 \u043c\u043d\u043e\u0433\u043e\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0433\u043b\u0430\u0437\u0430, \u043d\u043e \u043f\u043e-\u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443 \u043f\u0440\u0438 \u0442\u0430\u043a\u0438\u0445 \u0432\u0432\u043e\u0434\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u0445\u043e\u043b\u0441\u0442\u043e\u0432 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0441 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432. \u041d\u0430\u0434\u043e \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435\u0445 \u043f\u0440\u0430\u0432\u043e\u043a \u0432 \u043a\u0430\u0434\u0440\u0435 \u0438 \u043b\u0438\u0448\u044c \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044e. \u0412 Godot \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u044b\u043b \u0440\u0435\u0448\u0451\u043d \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u0430 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0430\u0437\u0443 <code>_Draw<\/code>, \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0441 <code>_Process<\/code>. \u041f\u043e \u0437\u0430\u043c\u044b\u0441\u043b\u0443 \u0430\u0432\u0442\u043e\u0440\u043e\u0432, \u043c\u044b \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u043c \u0432 <code>_Process<\/code> (\u0438\/\u0438\u043b\u0438 \u0435\u0449\u0451 \u0433\u0434\u0435) \u0438 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>QueueRedraw<\/code>. \u041f\u0440\u0438\u0447\u0451\u043c \u043d\u0430\u043c \u043d\u0435 \u043d\u0430\u0434\u043e \u0431\u0435\u0441\u043f\u043e\u043a\u043e\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u0447\u0442\u043e-\u0442\u043e \u0441\u043b\u043e\u043c\u0430\u0435\u043c \u043f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 <code>QueueRedraw<\/code>. \u0427\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435 \u0434\u0432\u0438\u0436\u043e\u043a \u0441\u043a\u0430\u0442\u0430\u0435\u0442 \u0432\u0441\u0451 \u0432 \u043e\u0434\u0438\u043d \u0444\u043b\u0430\u0433 (\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 <code>isDirty<\/code>) \u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u0442 <code>_Draw<\/code> \u0440\u043e\u0432\u043d\u043e \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u00ab\u0433\u0440\u044f\u0437\u043d\u043e\u0439\u00bb \u043d\u043e\u0434\u044b.<\/p>\n<p>\u0425\u043e\u043b\u0441\u0442\u044b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 <code>RenderingServer<\/code>, \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0443 <code>QueueRedraw<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0433\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0430\u0448\u0430\u043c\u0430\u043d\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0423 \u043c\u0435\u043d\u044f \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043f\u043e\u0434\u0430\u044e\u0449\u0438\u0439 \u043d\u0430\u0434\u0435\u0436\u0434\u044b \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0438\u043d\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0432 \u00ab\u043f\u0440\u043e\u0434\u0435\u00bb, \u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c, \u0447\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u0435\u0437 \u043d\u0435\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0433\u043b\u044f\u0434\u0435\u0432\u0448\u0438\u0441\u044c \u043a \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0441\u0446\u0435\u043d. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>GD.Implements._process<\/code> \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u044b, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043b\u0438 <code>redraw<\/code> \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0430\u0437\u0435 <strong>\u043f\u043e\u0441\u043b\u0435<\/strong> \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 \u0438\u043b\u0438 \u0432 \u0435\u0433\u043e <strong>\u043a\u043e\u043d\u0446\u0435<\/strong>. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043d\u0430\u0431\u0440\u043e\u0441\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 <code>use<\/code>:<\/p>\n<pre><code class=\"fsharp\">    member _.DeferRedraw () =        IDisposable.create redraw<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"fsharp\">do main.AddChild ^ GD.Implements._process ^ fun _ delta -&gt;    let delta = float32 delta    use _ = spaceship.DeferRedraw()    underMouse.Process ()    ...    \/\/ \u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435,    \/\/ \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0451, \u0447\u0442\u043e \u043c\u043e\u0433\u043b\u043e \u0443\u043f\u0430\u0441\u0442\u044c, \u0443\u0441\u043f\u0435\u043b\u043e \u0443\u043f\u0430\u0441\u0442\u044c.    spaceship.Process delta    \/\/ \u0421\u044e\u0434\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0437\u0430\u0441\u0443\u043d\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 `redraw`.<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u0448\u0435 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0447\u0443\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0434\u0432\u0438\u0436\u043e\u0447\u043d\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0437\u0430\u043c\u0435\u0442\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e\u043c \u0432\u0437\u0433\u043b\u044f\u0434\u0435. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>Spaceship<\/code> \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u044e\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0444\u043b\u0430\u0433\u0438 <code>isDirty&lt;canvasName&gt;<\/code> (= <code>.QueueRedraw()<\/code>). \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u044d\u0442\u0438 \u0444\u043b\u0430\u0433\u0438 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0438 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0445\u043e\u043b\u0441\u0442\u044b. \u0412\u043e\u0442 \u0437\u0430 \u044d\u0442\u0443 \u043d\u0435\u0432\u0438\u0434\u0438\u043c\u0443\u044e \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 Godot \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043e\u0442\u0432\u0435\u0447\u0430\u044e <code>DeferRedraw<\/code>.<\/p>\n<h3>\u041f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043f\u0443\u0442\u0438<\/h3>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c <code>PathPredictor<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u0441\u0446\u0435\u043d\u044b \u0438 \u0437\u0430 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u044d\u0442\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u0434 \u0438\u0433\u0440\u043e\u043a\u043e\u043c.<\/p>\n<h4>Data<\/h4>\n<p>\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u043c\u044b \u043f\u044b\u0442\u0430\u043b\u0438 4 \u0433\u043b\u0430\u0432\u044b (\u0438\u043b\u0438 \u0434\u0430\u0436\u0435 7, \u0441\u043c\u043e\u0442\u0440\u044f \u043a\u0430\u043a \u0441\u0447\u0438\u0442\u0430\u0442\u044c). \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u043f\u0440\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043a \u0441\u0446\u0435\u043d\u0435 \u0435\u0433\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0434\u043e\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0432 GUI \u043f\u0430\u043d\u0435\u043b\u044c\u043a\u0443, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b\u0432\u0435\u043b \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u0443\u0442\u0438 \u0434\u043e \u043a\u043b\u0435\u0442\u043a\u0438 \u043f\u043e\u0434 \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u043c. \u0422\u0443\u0434\u0430 \u0436\u0435 \u044f \u0432\u044b\u0432\u0435\u043b \u043e\u0448\u0438\u0431\u043a\u0438, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0435 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438. \u0411\u044b\u0441\u0442\u0440\u043e \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043f\u0443\u0442\u044c \u0434\u043e \u0442\u043e\u0447\u043a\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u0440\u0430\u0431\u043b\u044c \u0443\u0436\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f, \u043d\u0430\u0434\u043e \u043c\u0430\u0440\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u0415\u0433\u043e \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c \u043f\u043e\u043b\u0451\u0442\u043d\u044b\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/49\/4d\/c0\/494dc064b60207df4ff40128d5d87bc4.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/49\/4d\/c0\/494dc064b60207df4ff40128d5d87bc4.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/49\/4d\/c0\/494dc064b60207df4ff40128d5d87bc4.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c\u044b\u0435 \u043a\u043b\u0435\u0442\u043a\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043d\u0435\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u043d\u043e. \u0412\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u0440\u043e\u0434\u0435\u043b\u044b\u0432\u0430\u043b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u0441\u043a\u0440\u044b\u0442\u0430 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0445\u043e\u0442\u044f \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u043f\u043e\u0438\u0441\u043a\u0430 \u043c\u044b \u0437\u0430\u043b\u0435\u0437\u043b\u0438 \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043c\u0435\u043d\u044c. \u041f\u0440\u043e\u0441\u0442\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/86\/26\/8c\/86268cca7d63f587384e8612caa9bfa4.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/86\/26\/8c\/86268cca7d63f587384e8612caa9bfa4.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/86\/26\/8c\/86268cca7d63f587384e8612caa9bfa4.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041e\u0431\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u043e\u0433\u0443\u0442 \u0440\u0435\u0448\u0438\u0442\u044c\u0441\u044f \u0437\u0430\u043c\u0435\u043d\u043e\u0439 <code>PathFinder.Error<\/code>:<\/p>\n<pre><code class=\"fsharp\">type Error =    | Obstacle    | OutOfBounds    | Unreachable <\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u0447\u0442\u043e-\u0442\u043e \u0442\u0430\u043a\u043e\u0435:<\/p>\n<pre><code class=\"fsharp\">type Error =    | AlreadyInGoal    | Obstacle    | OutOfBounds    | Unreachable of {| Ready : ...; Paths : ... |}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u044f \u043d\u0435 \u0441\u0442\u0430\u043b, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u043e\u0432\u043b\u0435\u043a\u043b\u043e \u0431\u044b \u043a\u0430\u0441\u043a\u0430\u0434\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 (\u043e\u043d \u0431\u044b\u043b \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0443\u0435\u043c\u043e\u0433\u043e). \u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0438 \u0431\u044b \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443 \u043c\u0435\u043d\u044f \u043d\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u044f \u0437\u0430\u0432\u0451\u043b \u0435\u0449\u0451 \u043e\u0434\u043d\u043e DU \u0438 \u043f\u0435\u0440\u0435\u0443\u043f\u0430\u043a\u043e\u0432\u0430\u043b \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0432 \u043d\u043e\u0432\u043e\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0441\u0446\u0435\u043d\u0435:<\/p>\n<pre><code class=\"fsharp\">module PathPredictor =    type UnreachableData (core) =        member this.Core = core    type PathFound (core) as this =        static let rec tryCreate (pathFinder : PathFinder.Main4) goal =            pathFinder.TryFind goal            |&gt; Result.map ^ fun p -&gt;                PathFound {| p with Ready = pathFinder.Ready |}            |&gt; Result.mapError ^ Error.OfPathFinderError pathFinder            let core = {| core with Shell = this |}            static member TryCreate (pathFinder, goal) =            tryCreate pathFinder goal            member _.Core = core            member _.Costs =            core.Paths            |&gt; Seq.map ^ fun p -&gt; p.Key, p.Value.Last.Cost            member _.Path =            core.Path            |&gt; Seq.map ^ fun p -&gt; p.Position    and Error =        | AlreadyInGoal        | Obstacle        | OutOfBounds        | Unreachable of UnreachableData            with        member this.Stringify () =            match this with            | Obstacle -&gt; \"\u0412 \u043f\u0443\u043d\u043a\u0442\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435.\"            | OutOfBounds -&gt; \"\u041f\u0443\u043d\u043a\u0442 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043f\u043e\u043b\u044f.\"            | Unreachable _ -&gt; \"\u041f\u0443\u043d\u043a\u0442 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c.\"            | AlreadyInGoal -&gt; \"\u041a\u043e\u0440\u0430\u0431\u043b\u044c \u0443\u0436\u0435 \u0432 \u043f\u0443\u043d\u043a\u0442\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.\"            static member OfPathFinderError finder err =            match err with            | PathFinder.Obstacle -&gt; Obstacle            | PathFinder.OutOfBounds -&gt; OutOfBounds            | PathFinder.Unreachable -&gt; Unreachable ^ UnreachableData {| Ready = finder.Ready; Paths = finder.Paths |}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u043f\u043e \u043c\u0435\u0440\u043a\u0430\u043c F# \u043c\u0435\u0448\u0430\u043d\u0438\u043d\u0443 \u0442\u0438\u043f\u043e\u0432. \u041f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u043d\u0430 \u043e\u0442 \u043c\u043e\u0435\u0439 \u043b\u044e\u0431\u0432\u0438 \u043f\u043b\u043e\u0434\u0438\u0442\u044c \u0442\u0438\u043f\u044b \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441 \u044d\u0442\u0438\u043c \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u044f\u0432\u043d\u043e\u0439 \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438. \u041e\u0431\u0430 \u0436\u0435\u043b\u0430\u043d\u0438\u044f \u0431\u044b\u043b\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u044b. \u042f \u0443\u043a\u0430\u0437\u0430\u043b \u043b\u0438\u0448\u044c \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e <code>pathFinder<\/code> \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>PathFinder.Main4<\/code>, \u043e \u0447\u0451\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f \u0431\u0435\u0437 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043e\u043a, \u0430 \u0432\u0441\u0451 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u0430 \u043c\u0435\u043d\u044f \u0432\u044b\u0432\u0435\u043b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440. \u041f\u0440\u0438\u0447\u0451\u043c \u044d\u0442\u043e \u043e\u0442\u0440\u0430\u0437\u0438\u043b\u043e\u0441\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043d\u043e \u0438 \u0432 \u0442\u0438\u043f\u0430\u0445 (\u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0438 \u0432 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/917404\/\">6 \u0433\u043b\u0430\u0432\u0435<\/a> \u0438 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/919448\/\">7 \u0433\u043b\u0430\u0432\u0435<\/a>), \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u044f\u0445.<\/p>\n<p>\u041d\u0430\u0434\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0430 DU \u2014 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430 \u0432\u0435\u0449\u044c, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0434\u043e \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432 \u0442\u0435\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 DU \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0439\u0442\u0438 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c, \u0430 \u043c\u044b \u043d\u0435 \u0443\u0434\u043e\u0441\u0443\u0436\u0438\u043b\u0438\u0441\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0433\u0434\u0435-\u0442\u043e \u0440\u044f\u0434\u043e\u043c. \u041e\u0434\u043d\u0430\u043a\u043e \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u0430\u043f\u0440\u0438\u043e\u0440\u043d\u044b\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430\u043c \u0442\u043e\u0436\u0435 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442. \u042f \u0432\u0438\u0434\u0435\u043b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043a\u043e\u0434\u0430, \u0433\u0434\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0434\u0432\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0445\u0441\u044f DU \u0432 \u043e\u0434\u043d\u043e\u043c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u043c \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u0442\u044c \u043d\u0430\u0447\u0435\u043a\u0443. \u041f\u043e \u00ab\u043d\u0435\u043e\u0431\u044a\u044f\u0441\u043d\u0438\u043c\u043e\u043c\u0443\u00bb \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044e \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u0442\u043e\u0442 \u0442\u0438\u043f \u0437\u0430\u043d\u0443\u0434\u043d\u044b\u0445 \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043e\u0442\u0432\u0440\u0430\u0442\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0440\u0438\u0439, \u0447\u0442\u043e \u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0451\u043b \u0431\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u043b\u044b\u0448\u0430\u0442\u044c, \u0438 \u0443\u0436 \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u0436\u0438\u0442\u044c.<\/p>\n<h4>Model<\/h4>\n<p><code>PathPredictor.Model<\/code> \u2014 \u044d\u0442\u043e \u0441\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439 <code>PathFinder<\/code>, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0435\u0433\u043e \u0438\u0437\u044b\u0441\u043a\u0430\u043d\u0438\u0439 \u0438 \u043e\u0431\u0432\u044f\u0437\u043a\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0438\u0445:<\/p>\n<pre><code class=\"fsharp\">module PathPredictor =    ...    type Model (finder) =        static let create gridSize isObstacle spaceshipPosition =            PathFinder.Main4(gridSize, isObstacle, spaceshipPosition)            |&gt; Model                    let mutable finder = finder        let buildPath goal = {|            Start = finder.Start            Goal = goal            Result =                if goal = finder.Start                then Result.Error Error.AlreadyInGoal                else PathFound.TryCreate(finder, goal)        |}        let mutable path = buildPath finder.Start        let changed = Event&lt;_&gt;()        let invalidatePath goal =            path &lt;- buildPath goal            changed.Trigger path        member _.Path = path        member _.Changed = changed.Publish        member _.InvalidatePath goal =            invalidatePath goal        member this.InvalidatePathFinder gridSize isObstacle spaceshipPosition =            finder &lt;- PathFinder.Main4(gridSize, isObstacle, spaceshipPosition)            this.InvalidatePath path.Goal        static member Create gridSize isObstacle spaceshipPosition =            create gridSize isObstacle spaceshipPosition<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u0434\u0443 \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435. \u0415\u0433\u043e \u0442\u0430\u043a\u0436\u0435 \u0441\u043b\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0451, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c, \u0431\u044b\u043b\u043e \u0438\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u043b\u0435\u043d\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0442\u0438\u043f\u0430\u0445.<\/p>\n<h4>View<\/h4>\n<p>\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u2014 \u044d\u0442\u043e \u0434\u0432\u0430 \u0445\u043e\u043b\u0441\u0442\u0430. \u041d\u0430 <code>UnderGrid<\/code> \u043c\u044b \u0437\u0430\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u043a\u043b\u0435\u0442\u043a\u0438. \u041d\u0430 <code>OverGrid<\/code> \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c. \u041b\u0435\u0436\u0430\u0442\u044c \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"fsharp\">[    motionLayers.UnderGrid    \/\/ \u0421\u0442\u0430\u0442\u0443\u0441 \u043a\u043b\u0435\u0442\u043e\u043a.    pathView.Surfaces.UnderGrid    gridView.Surface    spaceship.Surfaces.Highlight    motionLayers.OverGrid    \/\/ \u0421\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c\/\u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u044c \u043a\u043b\u0435\u0442\u043e\u043a.    pathView.Surfaces.OverGrid        underMouse.Surface    figureLayers.Surface]|&gt; Seq.iter rootLayer.AddCanvasItem<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043a:<\/p>\n<pre><code class=\"fsharp\">module PathPredictor =    ...    type View (disposables, model : Model, font, cellOps : IsometricGrid.CellOps) =        let surfaces = {|            UnderGrid = CanvasItemId.Create(Disposables = disposables)            OverGrid = CanvasItemId.Create(Disposables = disposables)        |}        do  let rec go () =                invalidate model.Path                disposables.Add ^ model.Changed.subscribe invalidate            and invalidate path =                 surfaces.UnderGrid.Clear()                surfaces.OverGrid.Clear()                seq {                    match path.Result with                    | Ok path -&gt;                        for position, _ in path.Costs do                            SceneColors.seen, position                        for position in path.Core.Ready.Keys do                            SceneColors.explored, position                        for step in path.Core.Path do                            SceneColors.path, step.Position                        SceneColors.goal, path.Core.Goal                    | Result.Error (Error.Unreachable p) -&gt;                        for position in p.Core.Paths.Keys do                             SceneColors.seen, position                        for position in p.Core.Ready.Keys do                            SceneColors.explored, position                        SceneColors.unreachableGoal, path.Goal                    | _ -&gt;                         SceneColors.unreachableGoal, path.Goal                }                |&gt; Seq.iter ^ fun (color, cell) -&gt;                    cellOps.Fill surfaces.UnderGrid color cell                seq {                    match path.Result with                    | Ok path -&gt;                        yield! path.Costs                    | Result.Error (Unreachable p) -&gt;                        for p in p.Core.Paths do                            p.Key, p.Value.Last.Cost                    | _ -&gt;                        ()                }                |&gt; Seq.iter ^ fun (key, value) -&gt;                    let text = string value                    let fontSize = 12                    let textSize = (font : Font).GetStringSize(text, fontSize = fontSize)                                    font.DrawString(                        surfaces.OverGrid.AsRid                        , cellOps.ToPixelCenter key                             + 0.5f * Vector2.Left * textSize                            + Vector2.Down * font.GetDescent fontSize                        , text                        , fontSize = fontSize                    )            go ()        member _.Surfaces = surfaces        member _.Hide () =            let f visible =                [                    surfaces.UnderGrid                    surfaces.OverGrid                ]                |&gt; List.iter ^ fun p -&gt; p.SetVisible visible            f false            IDisposable.create ^ fun () -&gt; f true<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0430\u043a\u0442\u043e\u043c \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u043d\u044b, \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u044b \u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0432 \u0433\u043e\u0442\u043e\u0432\u043e\u043c \u043a \u0443\u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044e \u0432\u0438\u0434\u0435.<\/p>\n<p><code>View<\/code> \u2014 \u043d\u0430\u043c\u0435\u0440\u0442\u0432\u043e \u043f\u0440\u0438\u0431\u0438\u0442 \u043a <code>Model<\/code>, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043b\u0438\u0448\u0451\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u043e\u0434\u0435\u043b\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u0430\u043b\u0435\u043a\u043e \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u044f. \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0446\u0438\u043a\u043b\u0430\u0445 \u0434\u043b\u044f \u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 <code>Model.Path<\/code> \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043f\u043e \u0441\u043c\u044b\u0441\u043b\u0443 \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u043d\u0430 <code>'a Hopac.Stream.Var<\/code> (\u0438\u043b\u0438 <code>'a SubjectBehavior<\/code> \u0438\u0437 <code>RX<\/code>). \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u0440\u0430\u043a\u0443\u0440\u0441\u0435 <code>View<\/code> \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0451\u0442 \u0447\u0435\u0440\u0442\u044b \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438, \u043d\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u043d\u0451\u043c \u0432 \u0442\u0430\u043a\u043e\u043c \u043a\u043b\u044e\u0447\u0435 \u0441\u0442\u043e\u0438\u0442 \u0443\u0436\u0435 \u0441\u0435\u0439\u0447\u0430\u0441.<\/p>\n<h3>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0430\u0431\u043b\u044f<\/h3>\n<p>\u041a\u043e\u0440\u0430\u0431\u043b\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0442\u043e\u0447\u043a\u0438 \u0410 \u0432 \u0442\u043e\u0447\u043a\u0443 \u0411 \u043d\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e, \u0430 \u043f\u043e \u0448\u0430\u0433\u0430\u043c, \u0447\u0442\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u042d\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043e \u043a\u0430\u043a \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 (\u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 <code>option<\/code>), \u0442\u0430\u043a \u0438 \u0432\u043e\u0432\u043d\u0435. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 F# \u044f \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0441\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435 \u0432\u0435\u0434\u0430\u0435\u0442 \u043e \u0441\u0432\u043e\u0451\u043c \u043d\u0435\u0431\u044b\u0442\u0438\u0438, \u0438 \u043b\u0438\u0448\u044c \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0431\u043b\u0435\u043a\u0430\u0435\u043c \u0432 \u0442\u0438\u043f\u044b \u0446\u0438\u043a\u043b \u00ab\u0431\u044b\u0442\u0438\u0435 &lt;-&gt; \u043d\u0435\u0431\u044b\u0442\u0438\u0435\u00bb. \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 \u0431\u044b\u043b \u0441\u043e\u0431\u0440\u0430\u043d \u043c\u043e\u0434\u0443\u043b\u044c <code>Motion<\/code>. \u041e\u043d \u043d\u0435 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0435\u0442 \u043e\u0431 \u044d\u043a\u0437\u0438\u0441\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0433\u0440\u043e\u0437\u0430\u0445, \u0430 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u0432\u043e\u0432\u043d\u0435.<\/p>\n<h4>Model<\/h4>\n<p>\u042f\u0434\u0440\u043e \u043c\u043e\u0434\u0435\u043b\u0438 \u2014 <code>member _.Process delta<\/code>. \u041c\u044b \u043a\u043e\u0441\u0432\u0435\u043d\u043d\u043e <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/926138\/\">\u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u043b\u0438<\/a> \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u043b\u0430\u0432 \u043d\u0430\u0437\u0430\u0434, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u0438 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438 \u0441\u043f\u0438\u0441\u043e\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0443\u0442\u0435\u0439. \u0418\u0437-\u0437\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0434\u0435\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u044f \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e \u044d\u0442\u043e\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043a\u0430\u043a \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e \u0434\u0432\u0438\u0436\u043a\u0443, \u0447\u0442\u043e \u043d\u0435 \u043b\u0443\u0447\u0448\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u0435\u0451 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"fsharp\">module Motion =    type 'a Changed =        | Completed        | Moved of 'a    type Model (path : PathPredictor.PathFound) =        static let stepTime = 0.123f        let mutable next =            path.Core.Path            |&gt; List.ofSeq             |&gt; List.tail         let mutable progress = 0f        let mutable isCompleted = false        let changed = Event&lt;_&gt;()        member _.Process delta =            if isCompleted then () else            progress &lt;- progress + delta            if progress &gt; stepTime then                progress &lt;- progress - stepTime                match next with                | [] -&gt;                    isCompleted &lt;- true                    changed.Trigger Completed                | current :: newNext -&gt;                    next &lt;- newNext                    changed.Trigger ^ Moved {|                        Current = current                        Remain = next                    |}        member _.Changed = changed.Publish        member _.Remain = next                    member _.Path = path<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>Model<\/code> \u043d\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439 \u043a\u043e\u0440\u0430\u0431\u043b\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043a \u043d\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u043f\u043e\u043a\u0430\u0434\u0440\u043e\u0432\u043e \u043f\u0440\u043e\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u0443\u0442\u044c \u0438 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445 \u043d\u0430\u0440\u0443\u0436\u0443 \u0447\u0435\u0440\u0435\u0437 <code>changed.Trigger ^ Moved<\/code>. \u0422\u0430\u043c \u044d\u0442\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u043d\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442 <code>Spaceship<\/code>.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u043a\u0435\u0439\u0441 <code>Changed.Moved<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u043a\u0430\u043a \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a, \u0445\u043e\u0442\u044f \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0432\u0438\u0434\u0438\u0442\u0441\u044f \u0432\u043f\u043e\u043b\u043d\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c. \u041e\u0431\u044b\u0447\u043d\u043e \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0432 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u043d\u0435 \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c (\u043c\u043d\u0435 \u043b\u0435\u043d\u044c) \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 <code>Moved<\/code> \u043d\u0438 \u0432 \u044f\u0432\u043d\u043e\u043c \u0432\u0438\u0434\u0435, \u043d\u0438 \u043a\u043e\u0441\u0432\u0435\u043d\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0443 (\u043a\u0430\u043a \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 <code>PathPredictor.UnreachableData<\/code>).<\/p>\n<p>\u042d\u0442\u043e\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0440\u0430\u0441\u0442\u0432\u043e\u0440\u0438\u043c\u044b\u0439 \u0445\u0430\u043a \u043c\u043e\u0433 \u0431\u044b \u0441\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u0435\u0441\u043b\u0438 \u0431\u044b \u043d\u0430\u0448 <code>Changed.Moved<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0443\u0437\u043b\u0430\u0445 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u041d\u043e <code>Changed<\/code> \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u043b\u0435\u0436\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 <code>Motion<\/code>. \u041e\u043d \u043f\u0440\u0438\u0431\u0438\u0442 \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u0432\u0441\u044f\u043a\u0438\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0432\u0448\u0438\u0439\u0441\u044f \u043d\u0430 <code>Model.Changed<\/code> \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0441 \u0447\u0435\u043c \u0438\u043c\u0435\u0435\u0442 \u0434\u0435\u043b\u043e. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0433\u0434\u0435-\u0442\u043e \u0438 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0438\u0432\u0435\u043d\u0442 \u0441\u043e \u0441\u0445\u043e\u0436\u0435\u0439 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u043e\u0439, \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0440\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u0442\u044c, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0430\u0445\u043d\u0435\u043c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d <code>Changed<\/code> \u0432 <code>module NewModule<\/code>, \u0438 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0432\u043e\u0438\u0445.<\/p>\n<h4>View<\/h4>\n<p>\u0417\u0434\u0435\u0448\u043d\u0438\u0439 <code>View<\/code> \u043d\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0440\u0430\u0441\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0435 \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043a\u043e\u0440\u0430\u0431\u043b\u044f. \u0412 \u0442\u0435\u043e\u0440\u0438\u0438 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0445\u043e\u043b\u0441\u0442\u044b \u043e\u0442 <code>PathPredictor.View<\/code>, \u043d\u043e \u044f \u0441\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0440\u0430\u0441\u043a\u0440\u0430\u0441\u043a\u0443 \u043a\u043b\u0435\u0442\u043e\u043a \u043f\u0443\u0442\u0438, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043e\u0449\u0443\u0449\u0430\u043b\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0438\u043d\u0430\u0447\u0435:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/7a\/e5\/28\/7ae528bccd33bd6714d0e58445ddf05d.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/7a\/e5\/28\/7ae528bccd33bd6714d0e58445ddf05d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/7a\/e5\/28\/7ae528bccd33bd6714d0e58445ddf05d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<pre><code class=\"fsharp\">module Motion =    ...    type View (disposables, model : Model, font, cellOps : IsometricGrid.CellOps) =        let surfaces = {|            UnderGrid = CanvasItemId.Create(Disposables = disposables)            OverGrid = CanvasItemId.Create(Disposables = disposables)        |}        do  model.Path.Costs            |&gt; Seq.iter ^ fun (key, value) -&gt;                cellOps.Fill surfaces.UnderGrid SceneColors.seen key                let text = string value                let fontSize = 12                let textSize = (font : Font).GetStringSize(text, fontSize = fontSize)                            font.DrawString(                    surfaces.OverGrid.AsRid                    , cellOps.ToPixelCenter key                         + 0.5f * Vector2.Left * textSize                        + font.GetDescent fontSize * Vector2.Down                    , text                    , fontSize = fontSize                )            for position in model.Path.Core.Ready.Keys do                cellOps.Fill surfaces.UnderGrid SceneColors.explored position            for step in model.Path.Path do                cellOps.Fill surfaces.UnderGrid SceneColors.motion step                    member _.Surfaces = surfaces<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u0430, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043e\u043a \u0438\u043b\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u0442\u0438\u043f \u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u043e. \u0417\u0430\u0442\u043e \u043e\u043d\u0438 \u043f\u043e\u043f\u0430\u043b\u0438 \u0432\u043e \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u043e\u0431\u0432\u044f\u0437\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0446\u0435\u043b\u0435\u0441\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0441\u0446\u0435\u043d\u044b.<\/p>\n<h3>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432<\/h3>\n<p>\u0417\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0433\u043b\u0430\u0432\u0435, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0431\u0435\u0440\u0451\u043c \u0432\u0441\u0435 \u0442\u0438\u043f\u044b \u0432 \u043a\u0443\u0447\u0443, \u0447\u0442\u043e\u0431\u044b \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0447\u0442\u043e-\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435 \u00ab\u043d\u0430 \u043f\u043e\u0442\u044b\u043a\u0430\u0442\u044c\u00bb. \u042d\u043a\u0441\u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043e\u0431\u044a\u0451\u043c\u043d\u0430\u044f:<\/p>\n<pre><code class=\"fsharp\">type Ready1 (main : Node) =    inherit Node()    static let gridTransform =        Transform2D            .Identity            .Scaled(2f * Vector2.One)    static let inversedGridTransform =        gridTransform.AffineInverse()    static let gridSize =        Vector2I(24, 24)            \/\/ \u041d\u0443\u0436\u0435\u043d CanvasItem.    let main = FG.Node2D(Parent = main)    let disposables = IDisposable.composite()                do  main.GetWindow().Name &lt;- \"Chapter 15\"        RenderingServer.SetDefaultClearColor SceneColors.background    let camera = FG.Camera2D(        Parent = main        , PositionSmoothingEnabled = true        , PositionSmoothingSpeed = 4f    )    let font = main.GetWindow().GetThemeDefaultFont()    let grid = IsometricGrid.Main(60f, 1.43f)    let gridView = GridView(disposables.CreateChild(), grid.Grid, gridSize)    let underMouse = UnderMouse(        disposables.CreateChild()        , grid.Cell        , fun () -&gt; inversedGridTransform * main.GetLocalMousePosition()    )    let figureLayers = FigureLayers(disposables.CreateChild())    let blocks = Blocks.Main(disposables.CreateChild(), 0.5f, figureLayers.GetLayerByZIndex, grid.Cell)    let spaceship = Spaceship(disposables, grid.Cell)    let pathPredictor = PathPredictor.Model.Create gridSize blocks.Obstacles.Contains spaceship.Position    let pathView = PathPredictor.View(disposables.CreateChild(), path, font, grid.Cell)    let motionLayers = {|        UnderGrid = CanvasItemId.Create(Disposables = disposables)        OverGrid = CanvasItemId.Create(Disposables = disposables)    |}    let mutable motion = None<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u044f\u0441\u043d\u043e, \u043a\u0440\u043e\u043c\u0435 \u043a\u0435\u0439\u0441\u0430 <code>motion<\/code> \u0438 \u0435\u0433\u043e \u0445\u043e\u043b\u0441\u0442\u043e\u0432. \u042f \u043d\u0435 \u0441\u0442\u0430\u043b \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c \u0440\u0443\u043a\u0430\u043c\u0438. \u0421\u0442\u043e\u043b\u044c \u043a\u0430\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043d\u0435 \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f, \u043d\u043e \u0446\u0438\u043a\u043b \u0443\u0436\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0430 \u043c\u043d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043d\u0451\u043c \u043d\u0435\u0447\u0442\u043e \u0440\u0430\u0437\u0434\u0440\u0430\u0436\u0430\u044e\u0449\u0435\u0435, \u043a \u0447\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043f\u043e\u0437\u0434\u043d\u0435\u0435 (\u0441 \u0443\u043b\u044c\u0442\u0438\u043c\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u043b\u0435\u043a\u0430\u0440\u0441\u0442\u0432\u043e\u043c), \u0438 \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0438\u043b\u0430\u043c\u0438 \u043d\u0430 \u0441\u0432\u043e\u0451 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435.<\/p>\n<p><code>motionLayers<\/code> \u2014 \u044d\u0442\u043e \u043f\u0443\u0441\u0442\u044b\u0435 \u0445\u043e\u043b\u0441\u0442\u044b-\u0441\u043b\u043e\u0442\u044b \u043f\u043e \u0442\u0438\u043f\u0443 \u0442\u0435\u0445, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0432 <code>FigureLayers<\/code> (\u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0434\u0435\u0441\u044c \u0438\u043c\u0435\u0435\u0442 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 1 \u043a 1, \u0430 \u043d\u0435 1 \u043a\u043e \u043c\u043d\u043e\u0433\u0438\u043c). \u041e\u043d\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 <code>motion<\/code> \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u0447\u0451\u0442\u043a\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0441\u043b\u043e\u0451\u0432. \u0412\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0445\u043e\u043b\u0441\u0442\u044b <code>Motion.View.Surfaces<\/code> \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u0441\u043b\u043e\u0442\u043e\u0432 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u0441\u043f\u0430\u0432\u043d\u0430, \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0440\u043e\u0432\u043d\u043e \u0442\u0430\u043c, \u0433\u0434\u0435 \u043d\u0430\u0434\u043e. \u0412 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445 GUI-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445 \u044d\u0442\u043e\u0442 \u043c\u0430\u043d\u0451\u0432\u0440 \u0441\u043e\u043f\u0440\u044f\u0436\u0451\u043d \u0441 \u0440\u0438\u0441\u043a\u043e\u043c \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0443\u0434\u0430 \u0441\u0434\u0432\u0438\u043d\u0443\u0442\u044c, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u0443\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u043b\u0438\u0448\u043d\u0438\u0439 \u043e\u0442\u0441\u0442\u0443\u043f \u0438 \u0442.\u0434., \u043d\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0445\u043e\u043b\u0441\u0442\u0430\u043c\u0438 \u0438 \u043f\u0440\u043e\u0447\u0438\u043c\u0438 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u043c\u0438 <code>Node2D<\/code> \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u0443\u0440\u0430:<\/p>\n<pre><code class=\"fsharp\">do  let rootLayer = CanvasItemId.Create(        Parent = main.CanvasItemId        , Disposables = disposables        , Transform = gridTransform    )    [        motionLayers.UnderGrid        pathView.Surfaces.UnderGrid        gridView.Surface        spaceship.Surfaces.Highlight        motionLayers.OverGrid        pathView.Surfaces.OverGrid        underMouse.Surface        figureLayers.Surface    ]    |&gt; Seq.iter rootLayer.AddCanvasItem<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 <code>Spaceship.PositionChanged<\/code> (\u043c\u0435\u043b\u044c\u043a\u0430\u043b\u0430 \u0432\u044b\u0448\u0435) \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c \u0441 <code>PathPredictor<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0438\u043d\u0430\u0442\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u043a\u043e\u0440\u0430\u0431\u043b\u044f:<\/p>\n<pre><code class=\"fsharp\">do  let rec go () =        invalidate spaceship.Position        disposables.Add ^ spaceship.PositionChanged.subscribe ^ fun p -&gt; invalidate p.Current    and invalidate position =        figureLayers.GetLayerByPosition position        |&gt; spaceship.Surfaces.Spaceship.SetParent        camera.Position &lt;- grid.Cell.ToPixelCenter position * gridTransform        pathPredictor.InvalidatePathFinder gridSize blocks.Obstacles.Contains position    go ()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 <code>UnderMouse.CellChanged<\/code> \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u0441\u0435\u0431\u044f \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0433\u043b\u0430\u0432\u044b \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0438\u043d\u0430\u0435\u0442 <code>PathPredictor<\/code> \u0438 <code>Spaceship<\/code>:<\/p>\n<pre><code class=\"fsharp\">do  let rec go () =        invalidate underMouse.Cell        disposables.Add ^ underMouse.CellChanged.subscribe ^ fun ev -&gt;            blocks.TryGetBlock ev.Previous            |&gt; Option.iter ^ fun p -&gt; p.IsUnderMouse &lt;- false            invalidate ev.Current    and invalidate current =        blocks.TryGetBlock current        |&gt; Option.iter ^ fun p -&gt; p.IsUnderMouse &lt;- true        pathPredictor.InvalidatePath underMouse.Cell        if motion.IsNone then            spaceship.LookToward current    go ()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0432\u043e\u0440\u043e\u0442 \u043a\u043e\u0440\u0430\u0431\u043b\u044f \u0432 \u0444\u0430\u0437\u0435 \u043f\u043e\u043a\u043e\u044f \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u043a\u0443\u0440\u0441\u043e\u0440\u043e\u043c \u043c\u044b\u0448\u0438, \u0430 \u0432 \u0444\u0430\u0437\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0448\u0430\u0433\u0430. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0443\u0440\u044b\u0432\u043a\u0430\u043c\u0438, \u0442\u043e \u0442\u0430\u043c, \u0442\u043e \u0442\u0443\u0442, \u043d\u043e \u043f\u043e-\u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443 \u0442\u0430\u043a\u0438\u0435 \u0448\u0442\u0443\u043a\u0438 \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u044b\u043f\u044f\u0447\u0438\u0432\u0430\u0442\u044c \u0438 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"fsharp\">let beginMotion currentPath =    let newMotion = Motion.Model currentPath    let disposables = disposables.CreateChild()    let view = Motion.View(disposables, newMotion, font, grid.Cell)    view.Surfaces.UnderGrid.SetParent motionLayers.UnderGrid    view.Surfaces.OverGrid.SetParent motionLayers.OverGrid    disposables.Add ^ IDisposable.create ^ fun () -&gt;        motion &lt;- None    disposables.Add ^ pathView.Hide()    disposables.Add ^ newMotion.Changed.subscribe ^ fun ev -&gt;        match ev with        | Motion.Changed.Completed -&gt;            disposables.Dispose()        | Motion.Changed.Moved ev -&gt;            spaceship.LookToward ev.Current.Position            spaceship.Position &lt;- ev.Current.Position    motion &lt;- Some {| Process = newMotion.Process |}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438 \u0441\u0432\u043e\u0435\u0439 \u044d\u0442\u043e \u0441\u0430\u043c\u0430\u044f F#-\u043e\u0432\u0430\u044f \u0448\u0442\u0443\u043a\u0430 \u0438\u0437 \u0432\u0441\u0435\u0445, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u044d\u0442\u043e\u0439 \u0441\u0446\u0435\u043d\u0435. \u041c\u044b \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u044f\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u043b\u0438\u0441\u044c, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c, \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u0437\u0430\u0447\u0438\u0441\u0442\u043a\u0438 \u0438 \u0441\u043a\u0440\u044b\u043b\u0438\u0441\u044c, \u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043f\u043e\u0441\u043b\u0435 \u0441\u0435\u0431\u044f \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0439 \u0441\u043b\u0435\u0434. \u0422\u0443\u0442 \u0435\u0441\u0442\u044c, \u0447\u0442\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c (\u0442\u043e\u0442 \u0436\u0435 <code>motion<\/code>), \u043d\u043e \u043e\u0431\u0449\u0430\u044f \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0430 \u0438 \u043d\u0430\u0448\u0438 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 \u0443\u0441\u0442\u0440\u0435\u043c\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u044b \u0443\u0436\u0435 \u0441\u0435\u0439\u0447\u0430\u0441.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, <code>_Process<\/code>:<\/p>\n<pre><code class=\"fsharp\">do main.AddChild ^ GD.Implements._process ^ fun _ delta -&gt;    let delta = float32 delta    use _ = spaceship.DeferRedraw()    underMouse.Process ()            gridView.IsClosed &lt;- not ^ Input.IsKeyPressed Key.Ctrl                    match motion with    | Some motion -&gt;        motion.Process delta    | None -&gt;        if  Input.IsActionJustPressed \"mouse_left\"            &amp;&amp; PathFinder.inMap gridSize underMouse.Cell            &amp;&amp; spaceship.Position &lt;&gt; underMouse.Cell        then            blocks.Change { Position = underMouse.Cell }            |&gt; Option.iter ^ fun p -&gt; p.IsUnderMouse &lt;- true            pathPredictor.InvalidatePathFinder gridSize blocks.Obstacles.Contains spaceship.Position                        match pathPredictor.Path.Result with        | Ok path when Input.IsActionJustPressed \"mouse_right\" -&gt;            beginMotion path        | _ -&gt; ()                if Input.IsKeyPressed Key.Escape then        main.GetTree().Free()    spaceship.Process delta<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u043e\u043f\u044f\u0442\u044c \u0432\u043e\u0437\u0438\u043c\u0441\u044f \u0441 <code>motion<\/code>, \u043d\u043e \u0432 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u0434 \u043f\u0440\u043e\u0441\u0442 \u043a\u0430\u043a \u043f\u0440\u043e\u0431\u043a\u0430.<\/p>\n<h3>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043d\u0430 \u043a\u043e\u043d\u0435\u0446 \u0434\u0430\u043d\u043d\u043e\u0439 \u0433\u043b\u0430\u0432\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/StrigoEnTurbano\/Article11\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u0426\u0438\u043a\u043b \u0436\u0434\u0451\u0442 \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0433\u043b\u0430\u0432\u0430, \u043d\u043e \u0443\u0436\u0435 \u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a \u043e\u0442\u0432\u043b\u0435\u0447\u0451\u043d\u043d\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u0438\u0437 \u043d\u0430\u0447\u0430\u043b\u0430 \u0446\u0438\u043a\u043b\u0430 \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u044e\u0442 \u0441\u0435\u0431\u044f \u0432 \u043a\u043e\u0434\u0435 \u043a\u0430\u043a \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c, \u0442\u0430\u043a \u0438 \u043d\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u0430 \u043f\u043e\u0440\u0430 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e\u0442 \u0446\u0438\u043a\u043b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u00ab\u0428\u0435\u0441\u0442\u0438\u0434\u0435\u0441\u044f\u0442\u0438\u043b\u0435\u0442\u043d\u0438\u0439 \u0437\u0430\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0439 \u0438 \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u043a\u0440\u044b\u0441\u0430\u00bb \u2014 \u044d\u0442\u043e \u0446\u0438\u0442\u0430\u0442\u0430 \u0438\u0437 \u0444\u0438\u043b\u044c\u043c\u0430 \u00ab\u0421\u043a\u0430\u043b\u0430\u00bb (\u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0435 \u00abThe Rock\u00bb), \u0434\u0440\u0435\u0432\u043d\u0435\u0433\u043e \u0431\u043e\u0435\u0432\u0438\u0447\u043a\u0430 \u0430\u0436 1996 \u0433\u043e\u0434\u0430 \u0432\u044b\u043f\u0443\u0441\u043a\u0430. \u042d\u0442\u0443 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0434\u0438\u043d \u0438\u0437 \u0430\u0433\u0435\u043d\u0442\u043e\u0432 \u0424\u0411\u0420 \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0433\u0435\u0440\u043e\u0435\u0432 \u0444\u0438\u043b\u044c\u043c\u0430, \u043a\u043e\u0433\u0434\u0430 \u0442\u0435 \u0432\u0434\u0432\u043e\u0451\u043c \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u0438 \u043d\u0430 \u043e\u0441\u0442\u0440\u043e\u0432\u0435 \u043f\u0440\u043e\u0442\u0438\u0432 \u0434\u044e\u0436\u0438\u043d\u044b \u0432\u043e\u043e\u0440\u0443\u0436\u0451\u043d\u043d\u044b\u0445 \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u043b\u0434\u0430\u0442. \u0412\u043e\u043f\u0440\u0435\u043a\u0438 \u0442\u0430\u043a\u043e\u0439 \u043d\u0438\u0437\u043a\u043e\u0439 (\u0438 \u0432\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u0432\u0435\u0440\u043d\u043e\u0439) \u043e\u0446\u0435\u043d\u043a\u0435, \u044d\u0442\u0438 \u0434\u0432\u043e\u0435 \u043f\u043e\u0431\u0435\u0436\u0434\u0430\u044e\u0442, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0437\u0435\u043a-\u043f\u0435\u043d\u0441\u0438\u043e\u043d\u0435\u0440 \u0431\u043b\u0430\u0433\u043e\u043f\u043e\u043b\u0443\u0447\u043d\u043e \u0441\u043c\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0430 \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u043a\u0440\u044b\u0441\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0431\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0436\u0435\u043d\u043e\u0439 \u0438 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0430\u0442\u043e\u043c \u043d\u0430 \u0432\u0441\u0451 \u0424\u0411\u0420 \u0443\u0435\u0437\u0436\u0430\u0435\u0442 \u0432 \u0437\u0430\u043a\u0430\u0442 (\u0432\u0441\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u0432\u0438\u0434, \u0447\u0442\u043e \u00ab\u043d\u044b\u043d\u0447\u0435 \u0424\u0411\u0420 \u0443\u0436\u0435 \u043d\u0435 \u0442\u043e\u00bb \u0438 \u0437\u0430 \u043d\u0438\u043c\u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0434\u0451\u0442).<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u2014\u00a0\u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u044f \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u0443 F# \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0431\u044b\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u044f\u0437\u044b\u043a\u043e\u043c, \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441 \u044d\u0442\u0438\u043c \u043e\u043d \u0438\u043c\u0435\u0435\u0442 \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0438 \u0441 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043a\u043e\u0434 \u043d\u0430 F# \u2014 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043f\u043b\u0430\u0432 \u0437\u0430\u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439 \u0441 \u0432\u043e\u043f\u0438\u044e\u0449\u0435 \u043f\u0440\u0438\u0437\u0435\u043c\u043b\u0451\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u043a\u043e\u0439. \u041c\u044b \u0441\u043e\u0447\u0435\u0442\u0430\u0435\u043c \u0442\u043e, \u0447\u0442\u043e (\u043f\u043e \u043c\u043d\u0435\u043d\u0438\u044e \u00ab\u0440\u0435\u0430\u043b\u0438\u0441\u0442\u043e\u0432\u00bb) \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e (\u043f\u043e \u043c\u043d\u0435\u043d\u0438\u044e \u00ab\u043f\u0443\u0440\u0438\u0441\u0442\u043e\u0432\u00bb) \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u0430 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u0423 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0435\u0441\u0442\u044c 3 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.<\/p>\n<ul>\n<li>\n<p><strong>\u0417\u0430\u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438.<\/strong> \u0428\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043f\u0430\u0440\u0430\u0434\u043e\u043a\u0441 \u0411\u043b\u0430\u0431\u0430, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043d\u0435\u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 (\u043d-\u0440., \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0411\u043b\u0430\u0431) \u0441\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435 \u043e\u0442\u043d\u044e\u0434\u044c \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043e\u0442\u043a\u0430\u0437\u0443 \u043e\u0442 \u043d\u0435\u0433\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0433\u043e \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u0443\u043c\u0430\u0435\u0442 \u0432 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u0445 \u044d\u0442\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043f\u0438\u043d\u043e\u043a \u0438\u0437\u0432\u043d\u0435, \u0447\u0442\u043e\u0431\u044b \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u0443\u0437\u043d\u0430\u043b \u043e\u0431 \u0438\u043d\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0438 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u044f\u043b \u0438\u0437\u044a\u044f\u043d \u0441\u0432\u043e\u0435\u0433\u043e \u043a\u0430\u043a \u0432\u044b\u0437\u043e\u0432 \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443. \u0417\u0430\u043c\u0435\u0442\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u044e\u0434\u0435\u0439 \u0434\u0430\u0432\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043f\u0438\u043d\u0430\u0442\u044c \u0441\u0435\u0431\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e (\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432 \u0443\u0442\u0438\u043b\u044c), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441 \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439 \u0443 \u043d\u0430\u0441 \u043d\u0435\u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0438\u043c\u044b\u0445 \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u0442\u0441\u044f. \u042f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e \u043d\u0435\u043e\u0444\u0438\u0442\u043e\u0432 \u0441 \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0448\u0435 \u043c\u043e\u0435\u0433\u043e.<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u043e\u043f\u0438\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u043a\u0430<\/strong>. \u0421 \u043d\u0435\u0439 \u043c\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0437\u0430\u0432\u044f\u0437\u043b\u0438. \u041c\u043e\u0439 \u043f\u0440\u043e\u043f\u0430\u0433\u0430\u043d\u0434\u0438\u0441\u0442\u0441\u043a\u0438\u0439 \u043e\u043f\u044b\u0442 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430\u043f\u0430\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0430 \u00ab\u043c\u043e\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0438\u043d\u0430\u0447\u0435\u00bb \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u00ab\u0442\u0432\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0432\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u00bb. \u041e\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439 \u044f \u043c\u043e\u0433\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u044d\u0442\u0438 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043c\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432. \u0421 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043c\u043d\u0435 \u043b\u044c\u0441\u0442\u0438\u0442 \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u044f \u043d\u0430\u043b\u043e\u0432\u0447\u0438\u043b\u0441\u044f \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u043d\u0435\u0447\u0442\u043e \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0434\u0430\u0447\u043d\u043e \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u043e\u0435, \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u043e\u0435 \u0438 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u043d\u043e\u0435, \u0447\u0442\u043e \u043d\u0435\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044c \u0442\u0435\u0440\u044f\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u043a \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0443 \u043e\u043f\u044b\u0442\u0430 \u043d\u0430 \u0441\u0432\u043e\u044e \u0437\u0430\u0434\u0430\u0447\u0443. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u044f \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u044e, \u043a\u0430\u043a \u0431\u043e\u0440\u043e\u0442\u044c\u0441\u044f \u0441 \u0442\u0430\u043a\u043e\u0439 \u0440\u0438\u0442\u043e\u0440\u0438\u043a\u043e\u0439 \u0431\u0435\u0437 \u043f\u0440\u0435\u043f\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u043e\u043f\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u0438\u043d\u0442\u0435\u0437<\/strong> \u00ab\u0437\u0430\u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439 \u0441 \u0432\u043e\u043f\u0438\u044e\u0449\u0435 \u043f\u0440\u0438\u0437\u0435\u043c\u043b\u0451\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u043a\u043e\u0439\u00bb. \u0412 \u0433\u043b\u0430\u0437\u0430\u0445 \u043f\u0443\u0431\u043b\u0438\u043a\u0438 \u0442\u0430\u043a\u043e\u0439 \u0441\u043e\u044e\u0437 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u0432\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u043d\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043d\u0435 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0440\u0435\u0446\u0435\u043f\u0442 \u0443\u0441\u043f\u0435\u0445\u0430, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043d\u0430 \u043d\u0435\u0433\u043e \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c. \u042f \u043d\u0435 \u0437\u043d\u0430\u044e, \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u043e\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e, \u0438 \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043f\u043e\u0431\u0435\u0436\u0434\u0430\u0435\u0442 \u043f\u043e\u0434\u0445\u043e\u0434, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u043d\u0430\u0434 \u043d\u0430\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438. \u0417\u0430 \u0441\u0447\u0451\u0442 \u044d\u0442\u043e\u0433\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043c\u043d\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u00ab\u043a\u0430\u043a \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0443 \u0432\u0430\u0441?\u00bb \u043d\u0430 \u00ab\u0430 \u0447\u0442\u043e \u043d\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u0435\u0448\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a?\u00bb. \u0417\u0430\u0431\u0430\u0432\u043d\u043e, \u0447\u0442\u043e \u0447\u0435\u043c \u0431\u043e\u0433\u0430\u0447\u0435 \u043e\u043f\u044b\u0442, \u0442\u0435\u043c \u043f\u0440\u043e\u0449\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u0442\u0438\u043f \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 (\u0438 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441 \u043f\u044f\u0442\u043e\u043a \u00ab\u0442\u0430\u043a \u043d\u0435\u043b\u044c\u0437\u044f\u00bb \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a \u0443\u0434\u0430\u0447\u043d\u043e\u043c\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u044e, \u0447\u0435\u043c \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u043e\u0440\u043d\u043e\u043c\u0443 \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u043a\u0430\u043d\u043e\u043d\u0443.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437 \u044d\u0442\u0438\u0445 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0438\u0441\u0442\u0435\u043a\u0430\u044e\u0442 \u043c\u043e\u0438 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 \u043f\u043b\u0430\u043d\u044b \u043d\u0430 \u0425\u0430\u0431\u0440\u0435. \u041c\u043e\u043d\u043e\u043b\u043e\u0433 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0441\u044f \u0432 \u044d\u0442\u043e\u043c \u0436\u0435 \u043a\u043b\u044e\u0447\u0435, \u043f\u0443\u0441\u0442\u044c \u0438 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u0434\u043e \u044d\u0442\u0438\u0445 \u0441\u0442\u0440\u043e\u043a, \u0432\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u043c\u043e\u0438 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0438 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u043e\u0432 \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438, \u0432\u0441\u0442\u0443\u043f\u0438\u0432 \u0441\u043e \u043c\u043d\u043e\u0439 \u0432 \u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u0434\u0438\u0430\u043b\u043e\u0433\u0430.<\/p>\n<hr\/>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0433\u043b\u0430\u0432\u0435 \u043d\u0430\u0441 \u0436\u0434\u0451\u0442 \u043c\u0438\u043d\u0438-\u043a\u0430\u0440\u0442\u0430, UI \u0438 \u043f\u0430\u0440\u043e\u0447\u043a\u0430 \u0432\u043d\u0443\u0442\u0440\u0438\u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<hr\/>\n<p>\u041d\u041b\u041e \u043f\u0440\u0438\u043b\u0435\u0442\u0435\u043b\u043e \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u043c\u043e\u043a\u043e\u0434 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u0433\u0430: <a href=\"https:\/\/firstvds.ru\/?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=product&amp;utm_content=vds15exeptprogrev\">-15% \u043d\u0430 \u0437\u0430\u043a\u0430\u0437 \u043d\u043e\u0432\u043e\u0433\u043e VDS<\/a> \u2014 <strong>HABRFIRSTVDS<\/strong>.<\/p>\n<p><a href=\"https:\/\/firstvds.ru\/habr15\">\u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0431 \u0430\u043a\u0446\u0438\u0438<\/a><\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1049342\/\">https:\/\/habr.com\/ru\/articles\/1049342\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p> \u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e\u0440\u0442 \u0442\u0430\u0439\u043b\u043e\u0432\u044b\u0445 \u043c\u0438\u0440\u043e\u0432 \u043d\u0430 F#, \u0433\u0434\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0438\u0441\u044c \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u0430\u043b\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 Godot. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043d\u0430\u0448 \u043f\u0440\u0438\u0446\u0435\u043b \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u0441\u044f \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 RenderingServer \u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u0431\u044b\u0442\u043e\u0432\u0443\u0445\u0443 (\u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 + \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435). \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u043b \u043f\u0435\u0440\u0432\u043e\u043f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440\u0430 \u0442\u0435\u0445 \u0442\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u0446\u0438\u043a\u043b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0441 \u0436\u0434\u0451\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0441 \u043f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u044f\u043c\u0438 \u0432\u0438\u0434\u0430 \u00ab\u044d\u0442\u043e \u0441\u0442\u0430\u043b\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f &lt;\u0448\u0442\u0443\u043a\u043e\u0432\u0438\u043d\u0435, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0438 \u0432 \u0446\u0438\u043a\u043b\u0435&gt;\u00bb. \u041a\u043e\u043d\u0435\u0447\u043d\u043e-\u0436\u0435, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043a\u0437\u043e\u0442\u0438\u043a\u0438, \u043d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0441 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e (\u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043c\u0438\u043d\u0438-\u043a\u0430\u0440\u0442\u044b, \u043e\u043d\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 GUI \u043f\u043e\u043f\u0430\u043b\u0430 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0433\u043b\u0430\u0432\u0443) \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0432 \u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u0438\u0433\u0440\u044b.\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u041f\u0440\u0438\u043a\u0432\u0435\u043bAn incursion under C#. \u041f\u0440\u043e\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c F# \u0432 Godot \u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0428\u0435\u0441\u0442\u0438\u0434\u0435\u0441\u044f\u0442\u0438\u043b\u0435\u0442\u043d\u0438\u0439 \u0437\u0430\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0439 \u0438 \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u043a\u0440\u044b\u0441\u0430. F# \u043d\u0430 Godot\u0427\u0430\u0441\u0442\u044c 1. \u0412\u0441\u0442\u0440\u0435\u0447\u0430 \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c\u0427\u0430\u0441\u0442\u044c 2. \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0427\u0430\u0441\u0442\u044c 3. \u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b c \u043f\u0435\u0440\u0435\u0441\u0430\u0434\u043a\u0430\u043c\u0438\u0427\u0430\u0441\u0442\u044c 4. \u0414\u0435\u0444\u043e\u043b\u0442\u044b, option \u0438 \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438\u0427\u0430\u0441\u0442\u044c 5. \u041e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\u0427\u0430\u0441\u0442\u044c 6. \u041a\u0430\u043a \u0434\u043e\u0431\u044b\u0442\u044c \u043d\u0435\u0447\u0442\u043e\u0427\u0430\u0441\u0442\u044c 7. \u041a\u0430\u043a \u0443\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0435\u0447\u0442\u043e\u0427\u0430\u0441\u0442\u044c 8. \u0417\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0449\u0438\u0439 \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438\u0427\u0430\u0441\u0442\u044c 9. \u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, _Ready\u0427\u0430\u0441\u0442\u044c 10. C# \u043d\u0435 \u043d\u0443\u0436\u0435\u043d\u0427\u0430\u0441\u0442\u044c 11. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u0427\u0430\u0441\u0442\u044c 12. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u0427\u0430\u0441\u0442\u044c 13. \u041e\u0431\u0449\u0438\u0439 \u0441\u0431\u043e\u0440\u0427\u0430\u0441\u0442\u044c 14. RenderingServer \u043d\u0430 \u043f\u043e\u043b\u043d\u0443\u044e\u0427\u0430\u0441\u0442\u044c 15. \u041a\u0443\u043b\u044c\u043c\u0438\u043d\u0430\u0446\u0438\u044f \u0438 \u043f\u043e\u043b\u0451\u0442 \/\/ \u043c\u044b \u0437\u0434\u0435\u0441\u044c\u0417\u0432\u0435\u0437\u0434\u043e\u043b\u0451\u0442\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u044f \u043e\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0437\u043e\u0432\u0430\u043b \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u0446\u0435\u043d\u044b \u043a\u0430\u043a \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u044f \u0438\u0437 3 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442:\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u043d\u0432\u0435\u043d\u0442\u0430\u0440\u044f (props);\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0440\u044b\u0447\u0430\u0433\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u0441\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u043c\u0435\u0442\u043e\u0434\u044b);\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0445\u043e\u043b\u0441\u0442\u0430 (: CanvasItemId).\u0422\u0438\u043f Spaceship \u0432 \u044d\u0442\u0443 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f:type Spaceship (disposables, cellOps : IsometricGrid.CellOps) =    static let spaceshipTexture : Texture2D = GD.load &#171;&#187;&#187;uid:\/\/oyqyauhtdyno&#187;&#187;&#187;    static let iconSize = 48f * Vector2.One    let surfaces = {|        Highlight = CanvasItemId.Create(Disposables = disposables)        Spaceship = CanvasItemId.Create(Disposables = disposables)    |}    let mutable direction = Vector2I.Zero    let mutable position = Vector2I.Zero    let mutable progress = 0f    let mutable isHighlightDirty = true    let mutable isSpaceshipDirty = true    let redraw () =        if isHighlightDirty then            surfaces.Highlight.Clear()            cellOps.Draw false 2f SceneColors.spaceship surfaces.Highlight position            isHighlightDirty &lt;- false        if isSpaceshipDirty then            surfaces.Spaceship.Clear()            surfaces.Spaceship.AddPolygon(                Corners.clockwise false                     (cellOps.ToPixelCenter position                         &#8212; 0.5f * iconSize                        &#8212; 0.125f * (2f + cos progress) * iconSize._Y                    )                    iconSize.X_                    iconSize._Y                , [||]                , (                    Vector2.clockwiseCorners false                    |&gt; Array.map ^ fun p -&gt;                        (Vector2.One + p + direction.AsVector2) \/ 3f                )                , textureId = spaceshipTexture.TextureId            )            isSpaceshipDirty &lt;- false    do redraw ()    let positionChanged = Event&lt;_&gt;()    member _.Direction        with get () = direction        and set value =            if direction &lt;&gt; value then                direction &lt;- value                isSpaceshipDirty &lt;- true    member this.LookToward target =        this.Direction &lt;-             (target &#8212; position).AsVector2            |&gt; SimplifyDirection.toward     member _.Position        with get () = position        and set value =            if position &lt;&gt; value then                let previous = position                position &lt;- value                isHighlightDirty &lt;- true                isSpaceshipDirty &lt;- true                positionChanged.Trigger {|                    Previous = previous                    Current = position                |}    member _.PositionChanged = positionChanged.Publish    member _.Process delta =        if delta &lt;&gt; 0f then            progress &lt;- progress + delta            isSpaceshipDirty &lt;- true    member _.DeferRedraw () =        IDisposable.create redraw    member _.Surfaces = surfaces1 Model -&gt; 2 View\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u0431\u0440\u043e\u0441\u0430\u0435\u0442\u0441\u044f \u0432 \u0433\u043b\u0430\u0437\u0430, \u2014 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0443\u0445 \u0445\u043e\u043b\u0441\u0442\u043e\u0432 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u041d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c \u043a\u043e\u0440\u0430\u0431\u043b\u044c, \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u2014 \u0437\u0435\u043b\u0451\u043d\u0443\u044e \u0440\u0430\u043c\u043a\u0443 \u043f\u043e\u0434 \u043a\u043e\u0440\u0430\u0431\u043b\u0451\u043c. \u0412 \u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0434\u0438\u043d \u0443\u0437\u0435\u043b \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0434\u0432\u0430 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c\u0435\u0440\u0442\u0432\u043e \u043f\u0440\u0438\u0431\u0438\u0442\u044b \u0434\u0440\u0443\u0433 \u043a \u0434\u0440\u0443\u0433\u0443.\u041f\u043e \u043c\u043e\u0438\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f\u043c, \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0441\u0432\u043e\u044e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c (\u0438 \u0434\u0430\u0436\u0435 \u0442\u043e\u043f\u043e\u0440\u043d\u043e\u0441\u0442\u044c) \u2014 \u043d\u0435\u0442\u0438\u043f\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043a\u043e\u0434\u043e\u0432\u044b\u0445 \u0431\u0430\u0437 \u043d\u0430 Godot. \u0418 \u0434\u0435\u043b\u043e \u043d\u0435 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0445\u043e\u043b\u0441\u0442\u043e\u0432, \u0432\u0435\u0434\u044c \u043d\u0430 \u0438\u0445 \u043c\u0435\u0441\u0442\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u043d\u043e\u0434\u044b:type Hero (&#8230;) =    &#8230;    member val Views = {|        Battlefield = &#8230; \/\/ : Node2D        Minimap = &#8230; \/\/ : Node2D        Skills = &#8230; \/\/ : Control        Summary = &#8230; \/\/ : Control        &#8230;    |}\u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043d\u0435\u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0440\u043e\u0436\u0434\u0435\u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c Godot \u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 Godot-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432. \u0412 \u043d\u0451\u043c \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043d\u043e\u0434\u0430\u043c\u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u0432\u044f\u0437\u043a\u0430\u043c\u0438, \u043a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u041d\u043e \u043a\u0430\u043a \u043d\u0435\u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0433\u043b\u0430\u0432\u0430\u0445, \u043d\u043e\u0434\u044b, \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440, \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442, \u0430 \u044d\u0442\u043e \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u0442 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u0435 F#. \u041d\u0430\u0448\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043a\u0442\u043e-\u0442\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435. \u0422\u043e \u0435\u0441\u0442\u044c, \u043d\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u0438 \u2014 \u043d\u0435\u0442 \u0432\u044c\u044e\u0445\u0438.\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0434\u044b \u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u0441 \u043d\u0430 \u0432\u043a\u043e\u0440\u044f\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u044d\u0442\u043e\u0439 \u0441\u0430\u043c\u043e\u0439 \u043d\u043e\u0434\u044b, \u0447\u0442\u043e \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u043b\u0438\u0448\u044c \u0440\u0430\u0437\u043c\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, hero.Views.Battlefield \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e Node2D, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043a\u0438\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0438\u0433\u0440\u043e\u043a \u0437\u0430\u0431\u0440\u043e\u0441\u0438\u0442 \u0432 battlefield.AddChild \u0438 \u0435\u0433\u043e Position \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u0438\u0431\u043e Hero, \u043b\u0438\u0431\u043e \u0442\u0435\u043c \u0436\u0435 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0438\u0433\u0440\u043e\u043a\u043e\u043c (\u043a\u0430\u043a \u043d\u0430\u043f\u0438\u0448\u0435\u043c). \u0412 \u0442\u0430\u043a\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 Views.Battlefield \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0448\u0430\u0440\u0438\u043a\u043e\u043c \u0431\u0435\u0437 \u0440\u0443\u0447\u0435\u043a, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u0451\u0440\u0433\u0430\u0442\u044c, \u0438 \u0431\u0435\u0437 \u043d\u043e\u0436\u0435\u043a, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u043d \u043c\u043e\u0433 \u0431\u044b \u043a\u0443\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u0443\u0431\u0435\u0436\u0430\u0442\u044c. \u0416\u0451\u0441\u0442\u043a\u043e, \u043d\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u043e. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441 \u0440\u043e\u0441\u0442\u043e\u043c \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0435\u0439, \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u044c\u044e\u0445\u0443 \u0442\u0430\u043a\u0438 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043e\u0442\u043e\u0440\u0432\u0430\u0442\u044c \u043e\u0442 \u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u043e \u0434\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u043d\u0430\u0434\u043e \u0435\u0449\u0451 \u0434\u043e\u0436\u0438\u0442\u044c.\u0418 \u0441\u043d\u043e\u0432\u0430 rec\u0425\u043e\u043b\u0441\u0442\u044b spaceship.Surfaces \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0446\u0430 \u0441\u0446\u0435\u043d\u044b \u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:do  let rootLayer = CanvasItemId.Create(        Parent = main.CanvasItemId        , Disposables = disposables        , Transform = gridTransform    )    [        motionLayers.UnderGrid        pathView.Surfaces.UnderGrid        gridView.Surface        \/\/ \u0422\u0443\u0442 \u0437\u0435\u043b\u0451\u043d\u0430\u044f \u0440\u0430\u043c\u043a\u0430.        spaceship.Surfaces.Highlight        motionLayers.OverGrid        pathView.Surfaces.OverGrid        underMouse.Surface            \/\/ \u0412\u043d\u0443\u0442\u0440\u0438 \u043b\u0435\u0436\u0430\u0442 `spaceship.Surfaces.Spaceship` \u0438 \u0445\u043e\u043b\u0441\u0442\u044b \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439.        figureLayers.Surface    ]    |&gt; Seq.iter rootLayer.AddCanvasItem\u0422\u0430\u043a \u043a\u0430\u043a surfaces.Highlight \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d, \u043e \u043d\u0451\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u044b\u0442\u044c. \u0421 surfaces.Spaceship \u0432\u0441\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0417\u0432\u0435\u0437\u0434\u043e\u043b\u0451\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0440\u0435\u0434\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439, \u0442\u043e \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0445\u043e\u043b\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u0442\u044c \u0432 \u0441\u043b\u043e\u0435 \u0441 \u0431\u043b\u043e\u043a\u0430\u043c\u0438, \u0447\u0435\u0439 ZIndex \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c ZIndex \u043a\u043e\u0440\u0430\u0431\u043b\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c surfaces.Spaceship \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u044f\u043c\u0438 figureLayers \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c spaceship.PositionChanged:do disposables.Add ^ spaceship.PositionChanged.subscribe ^ fun p -&gt;    figureLayers.GetLayerByPosition p.Current    |&gt; spaceship.Surfaces.Spaceship.SetParent    camera.Position &lt;- grid.Cell.ToPixelCenter p.Current * gridTransform    \/\/ &#8230;\u0422\u0443\u0442 \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u043f\u0440\u043e \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u044f \u043a\u043e\u0440\u0430\u0431\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0435\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0442\u043e \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435 \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430 \u043a\u043e\u0440\u0430\u0431\u043b\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u043d\u043e. \u0421\u0432\u044f\u0437\u043a\u0430 \u0412\u044b\u0437\u043e\u0432 + (\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 =&gt; \u0412\u044b\u0437\u043e\u0432) \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u043e, \u0438 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432 \u043e\u043d\u0430 \u0432\u0435\u0434\u0451\u0442 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\/\u0438\u043b\u0438 \u043a \u043b\u043e\u0436\u043d\u044b\u043c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0412 F# \u0441 \u043d\u0435\u0439 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f, \u043f\u043e \u0441\u0443\u0442\u0438, \u0442\u0430\u043a\u0436\u0435, \u043d\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u0447\u0443\u0442\u044c \u0438\u043d\u0430\u0447\u0435:\/\/ \u041d\u0435 \u0437\u0430\u0441\u043e\u0440\u044f\u0435\u043c \u0441\u043a\u043e\u0443\u043f.do  let rec go () =        invalidate spaceship.Position        disposables.Add ^ spaceship.PositionChanged.subscribe ^ fun p -&gt; invalidate p.Current    and invalidate position =        figureLayers.GetLayerByPosition position        |&gt; spaceship.Surfaces.Spaceship.SetParent        camera.Position &lt;- grid.Cell.ToPixelCenter position * gridTransform        \/\/ &#8230;    \/\/ \u0422\u0443\u0442 \u043d\u0430\u0434\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u043f\u0440\u043e \u0432\u044b\u0437\u043e\u0432.    \/\/ \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0441\u0451 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0431\u043b\u043e\u043a\u0435 do, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430\u043c \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u043e\u043c\u043d\u0438\u0442.    go ()\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 (\u0432 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435) \u043d\u0435 \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u044d\u0442\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u0437\u043b\u043e\u0443\u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 let rec &#8230; and, \u0447\u0435\u043c \u0432 \u0433\u043b\u0430\u0432\u0435 3. \u041e\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u0437\u0434\u0435\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0433\u0434\u0435 \u0438 \u043a\u043e\u0433\u0434\u0430 \u0434\u0451\u0440\u0433\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0438 \u043b\u0438\u0448\u044c \u043f\u043e\u0442\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u0442\u0435\u043b\u043e. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0442\u0438\u043f\u044b \u0431\u0443\u0434\u0443\u0442 \u0443 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0430\u0436\u043d\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445.\u0414\u044b\u0445\u0430\u043d\u0438\u0435 \u0436\u0438\u0437\u043d\u0438\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 Spaceship \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f 3 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438:position \u2014 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0437\u0432\u0435\u0437\u0434\u043e\u043b\u0451\u0442\u0430.direction \u2014 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d \u0441\u043c\u043e\u0442\u0440\u0438\u0442 (\u0438\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e 8 \u0448\u0442\u0443\u043a).progress \u2014 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0441\u0446\u0435\u043d\u044b, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0432\u044b\u0441\u043e\u0442\u0430 \u043a\u043e\u0440\u0430\u0431\u043b\u044f.\u041f\u043e\u0437\u0438\u0446\u0438\u044f \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u0430 \u0432\u043e\u0442 \u043f\u0440\u043e \u0432\u044b\u0441\u043e\u0442\u0443 \u0442\u0430\u043c \u0440\u0435\u0447\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e. \u0415\u0451 \u043a\u043e\u043b\u0435\u0431\u0430\u043d\u0438\u044f \u0442\u0440\u0443\u0434\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0430\u0445, \u043d\u043e \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0440\u0430\u0431\u043b\u044c \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0432\u0435\u0440\u0445-\u0432\u043d\u0438\u0437 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043e\u043d \u043f\u043e \u043f\u043e\u043b\u044e \u0438\u043b\u0438 \u043d\u0435\u0442:\u042f \u043d\u0430\u0437\u044b\u0432\u0430\u044e \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u00ab\u0434\u044b\u0445\u0430\u043d\u0438\u0435\u043c\u00bb. \u041c\u043d\u0435 \u043e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e \u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u044d\u0442\u0430 \u0448\u0442\u0443\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0435 (\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u0434\u0440 \u043f\u0430\u0434\u0435\u043d\u0438\u0435) \u043c\u0435\u0442\u043e\u0434\u0430 _Process \u0432 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 IDE \u0438\u043b\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430.\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430: \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0435 \u0430\u043a\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u0438\u043c \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0430\u043a\u0442\u043e\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u043c-\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u0442\u0443\u043f\u043d\u044f\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u043b. \u041a\u043e\u043c\u0443 \u0434\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0432 IoT, \u043c\u043e\u0433\u043b\u0438 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0436\u0435\u043b\u0435\u0437\u044f\u0447\u043d\u0438\u043a\u0438. \u041e\u043d\u0438 \u043c\u0438\u0433\u0430\u044e\u0442 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430\u043c\u0438 \u043f\u043b\u0430\u0442\u044b \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0415\u0441\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-484240","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/484240","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=484240"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/484240\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=484240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=484240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=484240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}