{"id":298799,"date":"2020-02-17T15:00:07","date_gmt":"2020-02-17T15:00:07","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=298799"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2020-02-17T15:00:07","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=298799","title":{"rendered":"Golang + Phaser3 = MMORPG \u2014 \u0414\u0435\u043b\u0430\u0435\u043c \u0431\u0430\u0437\u0443 \u0434\u043b\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u0438\u0440\u0430"},"content":{"rendered":"\n<div class=\"post__text post__text-html\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/488752\/\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/op\/4h\/rr\/op4hrrqfwq-r_zzrzymmna7sjau.png\" alt=\"image\"\/><\/p>\n<p>  \u041d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0442\u0440\u0443\u0434\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044d\u0442\u043e\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0430\u043c \u043f\u043e\u043d\u044f\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0441\u043d\u043e\u0432\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u0433\u0440 \u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e. \u042f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0435\u0440\u0438\u044e \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e 2.5D MMORPG, \u0442\u043e \u0431\u0438\u0448\u044c \u0432 \u0438\u0437\u043e\u043c\u0435\u0442\u0440\u0438\u0438, \u043d\u0430\u0448 \u043c\u0438\u0440 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d \u043d\u0430 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u043e-\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0447\u0430\u043d\u043a\u0438, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u0438\u0437 \u0442\u0430\u0439\u0442\u043b\u043e\u0432. \u0421\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Golang, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 JavaScript \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u2014 Phaser.js <\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043c\u0438\u0440\u0430<\/h3>\n<p>  \u0418 \u0442\u0430\u043a \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0447\u0430\u043d\u043a\u043e\u0432 \u0434\u043b\u044f \u041c\u041c\u041e \u043d\u0430 \u0413\u043e\u043b\u0430\u043d\u0433, \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043a\u0430 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c Phaser. \u0414\u043b\u044f \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0448\u0443\u043c\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/post\/265775\/\">\u0428\u0443\u043c \u041f\u0435\u0440\u043b\u0438\u043d\u0430<\/a>, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 \u0413\u043e \u0438\u043b\u0438 \u0432\u0437\u044f\u0442\u044c \u043c\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442.<br \/>  <a name=\"habracut\"><\/a>   <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Perlin.go<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">package PerlinNoise  import ( \t&quot;math&quot; \t&quot;math\/rand&quot; )  func Noise(x, y float32) float32 { \t\/\/Coordinate left and top vertex square \tleft := float32(math.Floor(float64(x))) \ttop := float32(math.Floor(float64(y)))  \t\/\/Local coordinate \tlocalPoinX := x - left \tlocalPoiny := y - top  \ttopLeft := getRandomVector(left, top) \ttopRight := getRandomVector(left+1, top) \tbottomLeft := getRandomVector(left, top+1) \tbottomRight := getRandomVector(left+1, top+1) \t\/\/ \u0412\u0435\u043a\u0442\u043e\u0440\u0430 \u043e\u0442 \u0432\u0435\u0440\u0448\u0438\u043d \u0434\u043e \u0442\u043e\u0447\u043a\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \tDtopLeft := []float32{localPoinX, localPoiny} \tDtopRight := []float32{localPoinX - 1, localPoiny} \tDbottomLeft := []float32{localPoinX, localPoiny - 1} \tDbottomRight := []float32{localPoinX - 1, localPoiny - 1}  \t\/\/\u0421\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \ttx1 := dot(DtopLeft, topLeft) \ttx2 := dot(DtopRight, topRight) \tbx1 := dot(DbottomLeft, bottomLeft) \tbx2 := dot(DbottomRight, bottomRight)  \t\/\/\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u043d\u0435\u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0441\u0442\u0438 \tpointX := curve(localPoinX) \tpointY := curve(localPoiny)  \t\/\/\u0418\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f  \ttx := lerp(tx1, tx2, pointX) \tbx := lerp(bx1, bx2, pointX) \ttb := lerp(tx, bx, pointY) \treturn tb  } func getRandomVector(x, y float32) []float32 { \trand.Seed(int64(x * y)) \tv := rand.Intn(3)  \tswitch v {  \tcase 0: \t\treturn []float32{-1, 0} \tcase 1: \t\treturn []float32{1, 0} \tcase 2: \t\treturn []float32{0, 1} \tdefault: \t\treturn []float32{0, -1}  \t} } func dot(a []float32, b []float32) float32 {  \treturn (a[0]*b[0] + b[1]*a[1]) } func lerp(a, b, c float32) float32 {  \treturn a*(1-c) + b*c  } func curve(t float32) float32 {  \treturn (t * t * t * (t*(t*6-15) + 10))  }<\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u0433\u0434\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432\u043e\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/i.ibb.co\/VSg54Wv\/image.png\" alt=\"image\"\/><\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u0444\u0430\u0439\u043b main.go \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435: <\/p>\n<pre><code class=\"go\">func main() { \tvar a, b float32= 1330, 2500 \tv:= PerlinNoise.Noise(a\/2500, b\/2500) \tfmt.Println(v) }<\/code><\/pre>\n<p>  \u0411\u0443\u0434\u044c\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 \u0447\u0438\u0441\u0435\u043b, \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0439\u0442\u0435 \u0442\u0438\u043f\u044b \u044f\u0432\u043d\u043e, \u044d\u0442\u043e \u0438\u0437\u0431\u0430\u0432\u0438\u0442 \u0432\u0430\u0441 \u043e\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u0432\u044b\u0432\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: <\/p>\n<pre><code class=\"go\">-0.23416707<\/code><\/pre>\n<p>  \u0418 \u0442\u0430\u043a \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0448\u0443\u043c\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0438\u0445 \u043c\u0438\u0440\u043e\u0432. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0447\u0430\u043d\u043a\u043e\u0432. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e Chunk \u0438 \u0444\u0430\u0439\u043b Chunk.go \u0432 \u043d\u0435\u0439 \u0438 \u0441\u0440\u0430\u0437\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b:<\/p>\n<pre><code class=\"go\">var TILE_SIZE = 16 var CHANK_SIZE = TILE_SIZE * TILE_SIZE var PERLIN_SEED float32 = 150<\/code><\/pre>\n<p>  TILE_SIZE \u2014 \u044d\u0442\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0438\u0445 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u043d\u043a\u043e\u0432 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445<br \/>  CHANK_SIZE \u2014 \u0440\u0430\u0437\u043c\u0435\u0440 \u0447\u0430\u043d\u043a\u0430, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 16*16<br \/>  PERLIN_SEED \u2014 \u0437\u0434\u0435\u0441\u044c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u0447\u0435\u043c \u0432\u044b\u0448\u0435 \u043e\u043d\u043e, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0440\u043e\u0434\u0435\u043d \u0448\u0443\u043c, \u0442.\u0435. \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043e\u0441\u0442\u0440\u043e\u0432\u0430, \u0442\u043e \u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0447\u0438\u0441\u043b\u043e \u043c\u0435\u043d\u044c\u0448\u0435, \u0435\u0441\u043b\u0438 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u043a\u0438 \u0442\u043e \u0432\u044b\u0448\u0435.<\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442:<\/p>\n<pre><code class=\"go\">type Coordinate struct { \tX int  \tY int  }<\/code><\/pre>\n<p>  \u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043d\u0430\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0432\u0430\u0436\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0430 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0445 ID:<\/p>\n<pre><code class=\"go\">func GetChunkID(x, y int) Coordinate { \ttileX := float64(float64(x) \/ float64(TILE_SIZE)) \ttileY := float64(float64(y) \/ float64(TILE_SIZE))  \tvar ChunkID Coordinate \tif tileX &lt; 0 { \t\tChunkID.X = int(math.Floor(tileX \/ float64(TILE_SIZE))) \t} else { \t\tChunkID.X = int(math.Ceil(tileX \/ float64(TILE_SIZE))) \t} \tif tileY &lt; 0 { \t\tChunkID.Y = int(math.Floor(tileY \/ float64(TILE_SIZE))) \t} else { \t\tChunkID.Y = int(math.Ceil(tileY \/ float64(TILE_SIZE))) \t} \tif tileX == 0 { \t\tChunkID.X = 1 \t} \tif tileY == 0 { \t\tChunkID.Y = 1 \t} \treturn ChunkID  }<\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f ID \u0447\u0430\u043d\u043a\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0438\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u0430 \u043a\u0430\u0440\u0442\u0435 \u043d\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0430\u0439\u043b\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u0435\u043b\u0438\u043c \u0435\u0449\u0435 \u0440\u0430\u0437 \u043d\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0430\u0439\u043b\u0430 \u0441 \u043e\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u0435\u043c \u0432 \u043c\u0435\u043d\u044c\u0448\u0443\u044e \u0438\u043b\u0438 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 ID \u0447\u0430\u043d\u043a\u0430 \u0442.\u043a. \u043d\u0430\u0448 \u043c\u0438\u0440 \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0432 \u043b\u044e\u0431\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438.<\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448 \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0447\u0430\u043d\u043a\u0430, \u044d\u0442\u043e \u0442\u0430\u0439\u043b \u0438 \u0441\u0430\u043c \u0447\u0430\u043d\u043a:<\/p>\n<pre><code class=\"go\">type Chunk struct { \tChunkID [2]int \tMap     map[Coordinate]Tile } type Tile struct { \tKey string \tX   int \tY   int }<\/code><\/pre>\n<p>  \u0427\u0430\u043d\u043a \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u0430\u0440\u0442\u0443 \u0442\u0430\u0439\u043b\u043e\u0432. \u0422\u0430\u0439\u043b\u044b \u0445\u0440\u0430\u043d\u044f\u0442 \u0441\u0432\u043e\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u043a\u043b\u044e\u0447(\u043a\u043b\u044e\u0447 \u044d\u0442\u043e \u0442\u0438\u043f \u0432\u0430\u0448\u0435\u0433\u043e \u0442\u0430\u0439\u0442\u043b\u0430: \u0437\u0435\u043c\u043b\u044f, \u0432\u043e\u0434\u0430, \u0433\u043e\u0440\u044b \u0438 \u0442.\u0434.) <\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0433\u043b\u0430\u0432\u043d\u043e\u043c\u0443, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0430, \u044f \u0432\u0437\u044f\u043b \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043b \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">func NewChunk()<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">func NewChunk(idChunk Coordinate) Chunk { \t\/\/ \u041f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0447\u0430\u043d\u043a \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0418\u0414 \tchunk := Chunk{ChunkID: [2]int{idChunk.X, idChunk.Y}} \t\/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0447\u0430\u043d\u043a\u0430 \tvar chunkXMax, chunkYMax int \t\/\/ \u0418\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u0442\u0443 \u0434\u043b\u044f \u0442\u0430\u0439\u043b\u043e\u0432 \tvar chunkMap map[Coordinate]Tile \tchunkMap = make(map[Coordinate]Tile) \t\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u0447\u0430\u043d\u043a\u0430 \tchunkXMax = idChunk.X * CHUNK_SIZE \tchunkYMax = idChunk.Y * CHUNK_SIZE \tswitch { \t\/\/ \u043b\u043e\u0433\u0438\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0447\u0430\u043d\u043a\u0430 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \tcase chunkXMax &lt; 0 && chunkYMax &lt; 0: \t\t{ \t\t\tfor x := chunkXMax + CHUNK_SIZE; x &gt; chunkXMax; x -= TILE_SIZE { \t\t\t\tfor y := chunkYMax + CHUNK_SIZE; y &gt; chunkYMax; y -= TILE_SIZE { \t\t\t\t\t\/\/\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043b\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \t\t\t\t\tposX := float32(x - (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y + (TILE_SIZE \/ 2)) \t\t\t\t\ttile := Tile{}  \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY)  \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.01: \t\t\t\t\t\ttile.Key = &quot;~&quot; \/\/\u0412\u043e\u0434\u0430 \t\t\t\t\tcase perlinValue &gt;= -0.01 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot; \/\/\u0417\u0435\u043c\u043b\u044f  \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \/\/ \u0413\u043e\u0440\u044b \t\t\t\t\t} \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t} \t\t\/\/\u0414\u043b\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 X \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \tcase chunkXMax &lt; 0: \t\t{ \t\t\tfor x := chunkXMax + CHUNK_SIZE; x &gt; chunkXMax; x -= TILE_SIZE { \t\t\t\tfor y := chunkYMax - CHUNK_SIZE; y &lt; chunkYMax; y += TILE_SIZE { \t\t\t\t\tposX := float32(x - (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y + (TILE_SIZE \/ 2))  \t\t\t\t\ttile := Tile{}  \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY)  \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.12: \t\t\t\t\t\ttile.Key = &quot;~&quot; \t\t\t\t\tcase perlinValue &gt;= -0.12 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot;  \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \t\t\t\t\t}  \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t} \t\t\/\/ \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 Y \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \tcase chunkYMax &lt; 0: \t\t{ \t\t\tfor x := chunkXMax - CHUNK_SIZE; x &lt; chunkXMax; x += TILE_SIZE { \t\t\t\tfor y := chunkYMax + CHUNK_SIZE; y &gt; chunkYMax; y -= TILE_SIZE { \t\t\t\t\tposX := float32(x + (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y - (TILE_SIZE \/ 2)) \t\t\t\t\ttile := Tile{} \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY) \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.12: \t\t\t\t\t\ttile.Key = &quot;~&quot; \t\t\t\t\tcase perlinValue &gt;= -0.12 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot; \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \t\t\t\t\t} \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t} \t\t\/\/ \u0414\u043b\u044f \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \tdefault: \t\t{ \t\t\tfor x := chunkXMax - CHUNK_SIZE; x &lt; chunkXMax; x += TILE_SIZE { \t\t\t\tfor y := chunkYMax - CHUNK_SIZE; y &lt; chunkYMax; y += TILE_SIZE { \t\t\t\t\tposX := float32(x + (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y + (TILE_SIZE \/ 2)) \t\t\t\t\ttile := Tile{} \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY) \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.12: \t\t\t\t\t\ttile.Key = &quot;~&quot; \t\t\t\t\tcase perlinValue &gt;= -0.12 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot; \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \t\t\t\t\t} \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t}  \t}  \tchunk.Map = chunkMap \treturn chunk }<\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0418 \u0442\u0430\u043a, \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043b\u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0430 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0447\u0430\u043d\u043a\u0430, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f, \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u044f \u0442\u0430\u0439\u043b\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439. ChunkMax \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u043c ID \u0447\u0430\u043d\u043a\u0430 \u043d\u0430 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440(CHUNK_SIZE), \u0442.\u0435 \u043f\u0440\u0438 ID{1;1} \u043d\u0430\u0448\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b chunkXMax \u0438 chunkYMax \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0432\u043d\u044b 256.<\/p>\n<p>  \u0412 posX\/posY \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u043d\u0430\u0448\u0435\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0438:<\/p>\n<pre><code class=\"go\">\t\t\t\t\tposX := float32(x + (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y + (TILE_SIZE \/ 2))<\/code><\/pre>\n<p>   \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c switch \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ID \u043d\u0430\u0448\u0435\u0433\u043e \u0447\u0430\u043d\u043a\u0430(\u041c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f). \u041a\u043b\u044e\u0447 \u0442\u0430\u0439\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0448\u0443\u043c \u043f\u0435\u0440\u043b\u0438\u043d\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0448\u0443\u043c \u043f\u0435\u0440\u043b\u0438\u043d\u0430 \u043d\u0438\u0436\u0435 0 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0434\u0430, \u0432\u044b\u0448\u0435 \u2014 \u0441\u0443\u0448\u0430. \u041c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"go\">\t\t\t\t\tcase perlinValue &lt; -0.12: \t\t\t\t\t\ttile.Key = &quot;~&quot; \/\/ \u0412\u043e\u0434\u0430 \t\t\t\t\tcase perlinValue &gt;= -0.12 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot; \/\/ \u0417\u0435\u043c\u043b\u044f \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \/\/ \u0413\u043e\u0440\u044b<\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0448\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043a\u043e\u0434 \u0432 main \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<pre><code class=\"go\">func main() { \tcoord := Chunk.Coordinate{Y: 1, X: 1} \tchunk := Chunk.NewChunk(coord) \tm := chunk.Map \tout := os.Stdout \tfor y := 8; y &lt; 16*16; y += 16 { \t\tfor x := 8; x &lt; 16*16; x += 16 { \t\t\tc := Chunk.Coordinate{X: x, Y: y} \t\t\tout.Write([]byte(m[c].Key))  \t\t} \t\tout.Write([]byte(&quot;\\n&quot;)) \t}  } <\/code><\/pre>\n<p>  \u0412\u044b\u0432\u043e\u0434:<\/p>\n<pre><code class=\"go\">11~~~11111111111 11~~~11111111111 11~~~~1111111111 11~~~~1111111111 11~~~~~111111111 11~~~~~~1111111~ 11~~~~~~~~~11~~~ 11~~~~~~~~~~~~~~ 11~~~~~~~~~~~~~~ 11~~~~~~~~~~~~~~ 11~~~~~~~~~~~~~~ 11~~~~~~~~~~~~~~ 11~~~~~~~~~~~~~~ 11~~~~~~~~~~~~~~ 11~~~~~~~~~~1111 11~~~~~~~~~11111 <\/code><\/pre>\n<p>  \u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0441\u044f \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u044b\u0432\u043e\u0434\u0430 \u0438 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438:<\/p>\n<pre><code class=\"go\">11111~~~~~~~~111111111111111111111111111111~~~~~~~11111111111111 11111~~~~~~~~111111111111111111111111111111~~~~~~~11111111111111 11111~~~~~~~~111111111111111111111111111111~~~~~~~11111111111111 11111~~~~~~~~111111111111111111111111111111~~~~~~~~1111111111111 11111~~~~~~~~11111111111111111111111111111~~~~~~~~~1111111111111 11111~~~~~~~~11111111111111111111111111111~~~~~~~~~1111111111111 11111~~~~~~~~~111111111111111111111111111~~~~~~~~~~~111111111111 11111~~~~~~~~~111111111111111111111111111~~~~~~~~~~~~11111111111 11111~~~~~~~~~~1111111111111111111111111~~~~~~~~~~~~~11111111111 11111~~~~~~~~~~~11111111111111111111111~~~~~~~~~~~~~~~1111111111 11111~~~~~~~~~~~1111111111111111111111~~~~~~~~~~~~~~~~~111111111 11111~~~~~~~~~~~~~11111111111111111111~~~~~~~~~~~~~~~~~111111111 11111~~~~~~~~~~~~~~111111111111111111~~~~~~~~~~~~~~~~~~~11111111 11111~~~~~~~~~~~~~~~~11111111111111~~~~~~~~~~~~~~~~~~~~~~1111111 11111~~~~~~~~~~~~~~~~~~11111111111~~~~~~~~~~~~~~~~~~~~~~~~111111 11111~~~~~~~~~~~~~~~~~~~~~111111~~~~~~~~~~~~~~~~~~~~~~~~~~~11111 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1111 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~111 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~11 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~~~1111111111~~~~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~~~111111111111111~~~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~~1111111111111111111~~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~~111111111111111111111~~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~~11111111111111111111111~~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~~1111111111111111111111111~~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~~111111111111111111111111111~~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~11111111111111111111111111111~~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~~111111111111111111111111111111~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~~1111111111111111111111111111111~~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~111111111111111111111111111111111~~~~~~~~~~ 11111~~~~~~~~~~~~~~~~1111111111111111111111111111111111~~~~~~~~~ 11111~~~~~~~~~~~~~~~~11111111111111111111111111111111111~~~~~~~~ 11111~~~~~~~~~~~~~~~~11111111111111111111111111111111111~~~~~~~~ 11111~~~~~~~~~~~~~~~~111111111111111111111111111111111111~~~~~~~ 11111~~~~~~~~~~~~~~~~1111111111111111111111111111111111111~~~~~~ 11111~~~~~~~~~~~~~~~~1111111111111111111111111111111111111~~~~~~ 11111~~~~~~~~~~~~~~~~11111111111111111111111111111111111111~~~~~ 11111~~~~~~~~~~~~~~~~11111111111111111111111111111111111111~~~~~ 11111~~~~~~~~~~~~~~~~~11111111111111111111111111111111111111~~~~ 11111~~~~~~~~~~~~~~~~~11111111111111111111111111111111111111~~~~ 11111~~~~~~~~~~~~~~~~~~11111111111111111111111111111111111111~~~ 1111~~~~~~~~~~~~~~~~~~~11111111111111111111111111111111111111~~~ 1111~~~~~~~~~~~~~~~~~~~~1111111111111111111111111111111111111~~~ 1111~~~~~~~~~~~~~~~~~~~~~111111111111111111111111111111111111~~~ 1111~~~~~~~~~~~~~~~~~~~~~1111111111111111111111111111111111111~~ 1111~~~~~~~~~~~~~~~~~~~~~~111111111111111111111111111111111111~~ 1111~~~~~~~~~~~~~~~~~~~~~~~11111111111111111111111111111111111~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~1111111111111111111111111111111111~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~1111111111111111111111111111111111~~ 1111~~~~~~~~~~~~~~~~~~~~~~~~~111111111111111111111111111111111~~ <\/code><\/pre>\n<p>  \u041a\u043e\u0434:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Chunk.go<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">package Chunk  import ( \t&quot;PerlinNoise&quot; \t&quot;math&quot; )  var TILE_SIZE = 16 var CHUNK_SIZE = 32 * 32 var PERLIN_SEED float32 = 600  type Coordinate struct { \tX int `json:&quot;x&quot;` \tY int `json:&quot;y&quot;` } type Chunk struct { \tChunkID [2]int \tMap     map[Coordinate]Tile } type Tile struct { \tKey string \tX   int \tY   int }  func GetChunkID(x, y int) Coordinate { \ttileX := float64(x) \ttileY := float64(y)  \tvar ChunkID Coordinate \tif tileX &lt; 0 { \t\tChunkID.X = int(math.Floor(tileX \/ float64(TILE_SIZE))) \t} else { \t\tChunkID.X = int(math.Ceil(tileX \/ float64(TILE_SIZE))) \t} \tif tileY &lt; 0 { \t\tChunkID.Y = int(math.Floor(tileY \/ float64(TILE_SIZE))) \t} else { \t\tChunkID.Y = int(math.Ceil(tileY \/ float64(TILE_SIZE))) \t} \tif tileX == 0 { \t\tChunkID.X = 1 \t} \tif tileY == 0 { \t\tChunkID.Y = 1 \t} \treturn ChunkID  } func NewChunk(idChunk Coordinate) Chunk { \t\/\/ \u041f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u0447\u0430\u043d\u043a \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0418\u0414 \tchunk := Chunk{ChunkID: [2]int{idChunk.X, idChunk.Y}} \t\/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0447\u0430\u043d\u043a\u0430 \tvar chunkXMax, chunkYMax int \t\/\/ \u0418\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u0440\u0442\u0443 \u0434\u043b\u044f \u0442\u0430\u0439\u043b\u043e\u0432 \tvar chunkMap map[Coordinate]Tile \tchunkMap = make(map[Coordinate]Tile) \t\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u0447\u0430\u043d\u043a\u0430 \tchunkXMax = idChunk.X * CHUNK_SIZE \tchunkYMax = idChunk.Y * CHUNK_SIZE \tswitch { \t\/\/ \u043b\u043e\u0433\u0438\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0447\u0430\u043d\u043a\u0430 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \tcase chunkXMax &lt; 0 && chunkYMax &lt; 0: \t\t{ \t\t\tfor x := chunkXMax + CHUNK_SIZE; x &gt; chunkXMax; x -= TILE_SIZE { \t\t\t\tfor y := chunkYMax + CHUNK_SIZE; y &gt; chunkYMax; y -= TILE_SIZE { \t\t\t\t\t\/\/\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043b\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \t\t\t\t\tposX := float32(x - (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y + (TILE_SIZE \/ 2)) \t\t\t\t\ttile := Tile{}  \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY)  \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.01: \t\t\t\t\t\ttile.Key = &quot;~&quot; \/\/\u0412\u043e\u0434\u0430 \t\t\t\t\tcase perlinValue &gt;= -0.01 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot; \/\/\u0417\u0435\u043c\u043b\u044f  \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \/\/ \u0413\u043e\u0440\u044b \t\t\t\t\t} \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t} \t\t\/\/\u0414\u043b\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 X \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \tcase chunkXMax &lt; 0: \t\t{ \t\t\tfor x := chunkXMax + CHUNK_SIZE; x &gt; chunkXMax; x -= TILE_SIZE { \t\t\t\tfor y := chunkYMax - CHUNK_SIZE; y &lt; chunkYMax; y += TILE_SIZE { \t\t\t\t\tposX := float32(x - (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y + (TILE_SIZE \/ 2))  \t\t\t\t\ttile := Tile{}  \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY)  \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.12: \t\t\t\t\t\ttile.Key = &quot;~&quot; \t\t\t\t\tcase perlinValue &gt;= -0.12 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot;  \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \t\t\t\t\t}  \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t} \t\t\/\/ \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 Y \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \tcase chunkYMax &lt; 0: \t\t{ \t\t\tfor x := chunkXMax - CHUNK_SIZE; x &lt; chunkXMax; x += TILE_SIZE { \t\t\t\tfor y := chunkYMax + CHUNK_SIZE; y &gt; chunkYMax; y -= TILE_SIZE { \t\t\t\t\tposX := float32(x + (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y - (TILE_SIZE \/ 2)) \t\t\t\t\ttile := Tile{} \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY) \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.12: \t\t\t\t\t\ttile.Key = &quot;~&quot; \t\t\t\t\tcase perlinValue &gt;= -0.12 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot; \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \t\t\t\t\t} \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t} \t\t\/\/ \u0414\u043b\u044f \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \tdefault: \t\t{ \t\t\tfor x := chunkXMax - CHUNK_SIZE; x &lt; chunkXMax; x += TILE_SIZE { \t\t\t\tfor y := chunkYMax - CHUNK_SIZE; y &lt; chunkYMax; y += TILE_SIZE { \t\t\t\t\tposX := float32(x + (TILE_SIZE \/ 2)) \t\t\t\t\tposY := float32(y + (TILE_SIZE \/ 2)) \t\t\t\t\ttile := Tile{} \t\t\t\t\ttile.X = int(posX) \t\t\t\t\ttile.Y = int(posY) \t\t\t\t\tperlinValue := PerlinNoise.Noise(posX\/PERLIN_SEED, posY\/PERLIN_SEED) \t\t\t\t\tswitch { \t\t\t\t\tcase perlinValue &lt; -0.12: \t\t\t\t\t\ttile.Key = &quot;~&quot; \t\t\t\t\tcase perlinValue &gt;= -0.12 && perlinValue &lt;= 0.5: \t\t\t\t\t\ttile.Key = &quot;1&quot; \t\t\t\t\tcase perlinValue &gt; 0.5: \t\t\t\t\t\ttile.Key = &quot;^&quot; \t\t\t\t\t} \t\t\t\t\tchunkMap[Coordinate{X: tile.X, Y: tile.Y}] = tile  \t\t\t\t} \t\t\t} \t\t}  \t}  \tchunk.Map = chunkMap \treturn chunk } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Perlin.go<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">package PerlinNoise  import ( \t&quot;math&quot; \t&quot;math\/rand&quot; )  func Noise(x, y float32) float32 { \t\/\/Coordinate left and top vertex square \tleft := float32(math.Floor(float64(x))) \ttop := float32(math.Floor(float64(y)))  \t\/\/Local coordinate \tlocalPoinX := x - left \tlocalPoiny := y - top  \ttopLeft := getRandomVector(left, top) \ttopRight := getRandomVector(left+1, top) \tbottomLeft := getRandomVector(left, top+1) \tbottomRight := getRandomVector(left+1, top+1) \t\/\/ \u0412\u0435\u043a\u0442\u043e\u0440\u0430 \u043e\u0442 \u0432\u0435\u0440\u0448\u0438\u043d \u0434\u043e \u0442\u043e\u0447\u043a\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \tDtopLeft := []float32{localPoinX, localPoiny} \tDtopRight := []float32{localPoinX - 1, localPoiny} \tDbottomLeft := []float32{localPoinX, localPoiny - 1} \tDbottomRight := []float32{localPoinX - 1, localPoiny - 1}  \t\/\/\u0421\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \ttx1 := dot(DtopLeft, topLeft) \ttx2 := dot(DtopRight, topRight) \tbx1 := dot(DbottomLeft, bottomLeft) \tbx2 := dot(DbottomRight, bottomRight)  \t\/\/\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u043d\u0435\u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0441\u0442\u0438 \tpointX := curve(localPoinX) \tpointY := curve(localPoiny)  \t\/\/\u0418\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u044f  \ttx := lerp(tx1, tx2, pointX) \tbx := lerp(bx1, bx2, pointX) \ttb := lerp(tx, bx, pointY) \treturn tb  } func getRandomVector(x, y float32) []float32 { \trand.Seed(int64(x * y)) \tv := rand.Intn(3)  \tswitch v {  \tcase 0: \t\treturn []float32{-1, 0} \tcase 1: \t\treturn []float32{1, 0} \tcase 2: \t\treturn []float32{0, 1} \tdefault: \t\treturn []float32{0, -1}  \t} } func dot(a []float32, b []float32) float32 {  \treturn (a[0]*b[0] + b[1]*a[1]) } func lerp(a, b, c float32) float32 {  \treturn a*(1-c) + b*c  } func curve(t float32) float32 {  \treturn (t * t * t * (t*(t*6-15) + 10))  } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">main.go<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">package main  import ( \t&quot;fmt&quot; \t&quot;habr\/Chunk&quot; \t&quot;os&quot; )  func main() { \tcoord:= Chunk.GetChunkID(0,0) \tfmt.Println(coord) \tchunk := Chunk.NewChunk(coord) \tm := chunk.Map \tout := os.Stdout \tfor y := 8; y &lt; 32*32; y += 16 { \t\tfor x := 8; x &lt; 32*32; x += 16 { \t\t\tc := Chunk.Coordinate{X: x, Y: y} \t\t\tout.Write([]byte(m[c].Key))  \t\t} \t\tout.Write([]byte(&quot;\\n&quot;)) \t}  } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 HTTP \u0430 \u0435\u0441\u043b\u0438 \u0437\u0430\u0442\u0440\u043e\u043d\u0435\u043c \u0442\u043e \u0438 WS \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0422\u0438\u043f \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u043c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 json \u0444\u043e\u0440\u043c\u0430\u0442 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u043d\u0430\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c.<\/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\/post\/488752\/\"> https:\/\/habr.com\/ru\/post\/488752\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/488752\/\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/op\/4h\/rr\/op4hrrqfwq-r_zzrzymmna7sjau.png\" alt=\"image\"\/><\/p>\n<p>  \u041d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0442\u0440\u0443\u0434\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044d\u0442\u043e\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0430\u043c \u043f\u043e\u043d\u044f\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0441\u043d\u043e\u0432\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0438\u0433\u0440 \u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e. \u042f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0435\u0440\u0438\u044e \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e 2.5D MMORPG, \u0442\u043e \u0431\u0438\u0448\u044c \u0432 \u0438\u0437\u043e\u043c\u0435\u0442\u0440\u0438\u0438, \u043d\u0430\u0448 \u043c\u0438\u0440 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d \u043d\u0430 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u043e-\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0447\u0430\u043d\u043a\u0438, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u0438\u0437 \u0442\u0430\u0439\u0442\u043b\u043e\u0432. \u0421\u0435\u0440\u0432\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Golang, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u043d\u0430 JavaScript \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u2014 Phaser.js <\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043c\u0438\u0440\u0430<\/h3>\n<p>  \u0418 \u0442\u0430\u043a \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0447\u0430\u043d\u043a\u043e\u0432 \u0434\u043b\u044f \u041c\u041c\u041e \u043d\u0430 \u0413\u043e\u043b\u0430\u043d\u0433, \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043a\u0430 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c Phaser. \u0414\u043b\u044f \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0448\u0443\u043c\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/post\/265775\/\">\u0428\u0443\u043c \u041f\u0435\u0440\u043b\u0438\u043d\u0430<\/a>, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 \u0413\u043e \u0438\u043b\u0438 \u0432\u0437\u044f\u0442\u044c \u043c\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-298799","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/298799","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=298799"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/298799\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=298799"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=298799"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=298799"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}