Parte 1. SVG y sistemas de coordenadas
Hasta hace poco, los tamaños de los mapas en mi juego
Dragons Abound eran fijos y algo no deterministas. Los consideré "regionales", no mapas de todo el mundo, sino sus partes importantes, como, por ejemplo, la costa occidental de los Estados Unidos o parte de Europa. Estaba bastante contento con esta escala, pero quería experimentar un poco con el juego para ver si podía generar mapas de todo el mundo (o al menos uno más grande). Pero antes de comenzar, hablemos un poco sobre los mapas del mundo de fantasía.
El mundo es un gran espacio. La mayoría de las cartas de "mundo" de fantasía ni siquiera se parecen mucho al tamaño real. Tomemos, por ejemplo, la Tierra Media, en la que tiene lugar la acción del Señor de los Anillos:
Aunque parece que un gran mundo está capturado en él, de hecho, la Tierra Media fue creada sobre la base de Europa.
Es decir, el mapa real del "mundo" para el mundo Tolkien será aproximadamente 50 veces más grande que el mapa de la Tierra Media (!). De hecho, la mayoría de los mapas del mundo de fantasía que he visto reflejan un territorio del tamaño de un continente:
Esta parece ser el área más grande que se visualiza bien en el estilo de tarjeta de fantasía.
Es decir, la tarea de generar "mapas mundiales" reales es probablemente demasiado ambiciosa. Es mejor apuntar a crear un mapa del continente (o parte del continente). (Sin embargo, aún es más conveniente considerar la tarjeta como el tamaño del "mundo"). Entonces, ¿qué tamaño debe tener la tarjeta? Si las
tarjetas actuales de
Dragons Abound tienen un tamaño "subcontinental", entonces podemos suponer que necesita generar tarjetas 8-10 veces más grandes.
Antes de pasar a la tarea de generar mapas grandes, necesito comprender mejor los diversos sistemas de coordenadas que se utilizan en mi juego. Tomé prestados muchos sistemas de coordenadas del código fuente de Martin O'Leary, y sus interacciones pueden ser confusas incluso cuando trabajas con ellos durante dos años. Por lo general, pude hacerlo sin experimentar con ellos, pero es obvio que tendré que hacer esto para generar mapas grandes.
Para empezar, el "mundo" del mapa regional se está generando actualmente dentro de una unidad cuadrada. Cada mapa regional tiene coordenadas desde (-0.5, -0.5) hasta (0.5, 0.5), y el origen (0,0) está en el medio de la región.
Una de las rarezas aquí es que el eje Y está invertido en comparación con lo que estudiamos en geometría escolar. -0.5 está en la parte superior del mapa y 0.5 está en la parte inferior. En gráficos de computadora, el eje Y a menudo se voltea. Escuché que esto se explica por la forma en que los primeros monitores (televisores) realizaron un escaneo de arriba a abajo, es decir, la primera línea de escaneo estaba en la parte superior, la siguiente inmediatamente debajo, y así sucesivamente, es decir, el índice Y de las líneas de escaneo cambió de cero en la parte superior a algún número positivo abajo abajo Sea como fuere, se utiliza el mismo sistema de coordenadas en el formato SVG (Gráficos Vectoriales Escalables), razón por la cual
Dragons Abound también.
Este sistema de coordenadas es independiente de cómo se muestra el mapa. Este es solo un sistema adimensional para crear el mundo: la ciudad está ubicada en (0.12875, -0.223), el límite pasa de (0.337, 0.010) a (0.333, 0.017), y así sucesivamente. Y aunque mis mapas regionales actuales están limitados a un rango de 0.5 a -0.5, este no es el límite del sistema de coordenadas. Puedo crear un mundo más allá de estos límites.
El siguiente sistema de coordenadas es lo que SVG llama viewbox. Establece las coordenadas verdaderas que se utilizarán para dibujar los gráficos. Por ejemplo,
Dragons Abound al principio establece el cuadro de vista en las coordenadas (-500, -500) y tiene un ancho de 1000 y una altura de 1000:
(Hay un error tipográfico en la imagen, la parte superior del eje Y debe ser -500, lo siento).
Puede notar que, en este caso, la transformación entre el primer y el segundo sistema de coordenadas consiste solo en multiplicar todo por 1000. Es decir. Para dibujar algo, el juego encuentra las coordenadas de este objeto, las multiplica por 1000 y dibuja SVG en estas coordenadas.
Es decir, puedo usar las coordenadas del cuadro de vista para permitirme dibujar una línea desde (0, 0) a (250, 250). Pero, de hecho, no quiero dibujar una línea de (0, 0) a (250, 250) en la pantalla de la computadora. Esto significaría que si quiero mostrar el mapa en otro punto de la pantalla, tendré que cambiar las coordenadas de todos los objetos del mapa y volver a dibujarlos. Eso sería un gran trabajo.
Para controlar las coordenadas de visualización de gráficos en la pantalla, SVG tiene un tercer sistema de coordenadas llamado ventana gráfica. Viewport es esa parte de la página en la que se deben dibujar los gráficos (en la página web, este es el elemento <svg>). Tiene un ancho, altura y ubicación. La ubicación son las coordenadas de la esquina superior izquierda de la ventana gráfica. Es decir, si tuviera que mostrar el mapa en la vista con coordenadas (30, 100), que tiene una altura y un ancho de 800, entonces el sistema de coordenadas de la vista se vería así:

En SVG, la ventana de visualización y el sistema de coordenadas están conectados entre sí, y SVG se ocupa de la transición entre ellos. Simplemente dibujamos en el sistema de coordenadas del cuadro de vista, y todo lo que se muestra se muestra en la ubicación de la ventana correspondiente. (Algunos problemas surgen al crear una ventana de visualización y una ventana gráfica con diferentes relaciones de aspecto. Luego, los objetos se recortan o se estiran, dependiendo del valor del atributo
preserveAspectRatio
. Recomiendo no hacerlo en absoluto).
Para resumir: una ciudad ubicada en coordenadas mundiales (0.10, 0.33) se dibuja en coordenadas (100, 330) y se muestra en la pantalla en (110, 764).
¡Ahora puedes entender por qué esto puede ser confuso!
¿Qué sucede si cambio cada uno de estos sistemas de coordenadas? Suponga que en el primer sistema de coordenadas generaré un mundo que va desde -0.25 a 0.25 en cada eje. Luego, el mundo resultante será cuatro veces más pequeño que el mundo habitual y ocupará solo la parte central de la ventana gráfica:
(También puede observar artefactos en los bordes que generalmente están ocultos). Del mismo modo, si doblo el tamaño del primer sistema de coordenadas (SK), no veremos la mayor parte del mapa, porque estará fuera de los bordes de la ventana gráfica.
¿Qué sucede si doblo el tamaño del viewbox? Bueno, si también doblo la relación entre el primer SC y el viewbox (de 1000 a 2000), entonces nada cambiará mucho. Si la proporción permanece igual a 1000, el mapa se reducirá a la mitad nuevamente.
Sin embargo, esta vez la tarjeta tiene un área inicial de 1x1. Nuevamente podemos observar artefactos en los bordes que generalmente están ocultos (por ejemplo, partes convexas de bosques). También puede ver que el patrón oceánico está mal: debo haber conectado algunas suposiciones sobre el tamaño de la ventana de visualización. Además, parece que la brújula no se encuentra en la esquina del mapa, sino en la esquina del cuadro de vista.
Y viceversa, si reduzco el tamaño de la vista a la mitad, esto creará un efecto de zoom del mapa:
Aquí solo vemos el cuarto medio del mapa. Esta no es una forma muy conveniente de hacer zoom, porque solo la mitad del mapa muestra algunos problemas, por ejemplo, el marcador de ciudad “South Owenson” fue más allá de la pantalla. Además, duplica el tamaño de las fuentes y otras cosas que no necesito.
Un aspecto más útil de la vista es cambiar el origen. Hasta ahora, el cuadro de vista se ha centrado en el mapa, pero esto no es necesario. Por ejemplo, puedo mover el mapa a la derecha al centrar el cuadro de vista en un punto en el lado izquierdo del mapa:
Nuevamente podemos notar los efectos en las fronteras y algunos otros problemas, pero en esencia el mapa se ha movido hacia la derecha. La utilidad de esto puede no ser obvia, pero imagine que generaré un mapa cuyo ancho es dos veces el ancho de un mapa normal. Por defecto, se ve así:
Se parece a cualquier otro mapa, pero en realidad es solo la parte central de un mapa más grande. Es decir, ahora puedo cambiar el cuadro de vista para transferir otras partes del mapa a la ventana de vista general:
Aquí moví el punto de vista hacia la izquierda, por lo que vemos una parte del mundo al este de la vista original. Algunos nombres en el mapa han cambiado porque
Dragons Abound realiza ciertas funciones (por ejemplo, da nombres a los objetos) en función de si son visibles. Tendré que cambiar esto para que al mover el cuadro de vista el mapa permanezca constante. Sin embargo, más tarde podré mover el cuadro de vista en un mapa grande y generar mapas regionales de cualquier área deseada. Es decir, puedo generar y mostrar mapas grandes del tamaño de un continente, pero también puedo generar mapas regionales de áreas dentro de un mapa grande.
Para resumir: el juego usa tres sistemas de coordenadas. El primero es un SC abstracto para los objetos del mundo. El segundo es el cuadro de vista, define el área visible del mundo. El tercero es la ventana gráfica, controla dónde se dibujará el mapa en la pantalla. Para dibujar un mundo más grande, necesito expandir el primer SC. Para mostrar más en la pantalla, debe expandir el cuadro de vista. También puedo mover la vista para mostrar diferentes partes del gran mundo.
Parte 2. Hacer tarjetas permanentes
En la parte anterior, exploré los sistemas de coordenadas y aprendí cómo mover el SVG de la ventana gráfica para mostrar solo partes individuales del gran mundo. Sin embargo, este enfoque tiene algunos problemas, porque anteriormente asumí que todo lo invisible para nosotros no importa. En esta parte, eliminaré estos supuestos para que sea posible generar y ver diferentes partes de mapas grandes inmutables.
El problema con la ubicación de los nombres, que describí en la parte anterior, obviamente se nota en estos dos tipos de una tarjeta:
Aquí está el mismo mundo, solo la vista se desplaza hacia la izquierda:
Puede notar que la geografía es la misma, pero muchos nombres han cambiado. Como en dos tipos se ven diferentes objetos, y el proceso de creación de nombres se controla mediante números aleatorios, se obtienen diferentes nombres.
Mirando el código, descubrí que casi todos los objetos reciben nombres según su visibilidad. Pero solo hay una excepción que hace que sea difícil dar nombres a todos los objetos posteriores. En nuestro caso, la excepción es que
Dragons Abound genera solo costas visibles. Las razones para esto son muy confusas. De hecho, hay una "línea costera" a lo largo de todo el borde del mundo, pero la creación de esta línea destruye parte de la lógica del programa, ya que abarca todo el mundo. Para evitar esto, solo generé solo la costa visible. Ahora que el mapa puede expandirse mucho más allá de la ventana gráfica, esta solución no se ve bien. En cambio, necesito dejar de generar costas cuando me acerco al borde real del mapa. (Que todavía dejo fuera de la pantalla para ocultar problemas en los bordes).
Después de eliminar este problema, los nombres en las dos tarjetas permanecen constantes:
y:
Otra nota para el futuro: si uso la
función de interactividad para cambiar los nombres de los objetos del mapa, este cambio no se recreará en su forma actual y probablemente ni siquiera sea reproducible. Vale la pena considerarlo.
Si observa detenidamente el mapa anterior, puede ver que el área del océano cerca de la parte central inferior del mapa tiene una etiqueta colgante "Isla Meb". Sucedió porque
Dragons Abound realmente cree que la región del océano es una isla. No entraré en detalles técnicos, pero es sorprendentemente difícil distinguir las islas de los lagos cuando van más allá del mapa. El algoritmo es confuso para el cambio que realicé en la generación de costas invisibles, y para evitar tales problemas, esto debe corregirse.
Ahora cuadrupliquemos el tamaño del mapa y muestremos solo una cuarta parte en la ventana del mapa:
En general, todo se ve bien (hay un sistema interesante de ríos en el mapa, un gran lago, pero puedes ver que las ciudades son muy raras. Sucedió porque
Dragons Abound genera 10-20 ciudades. Este intervalo es muy adecuado para un mundo de tamaño normal, pero malo, cuando el tamaño es cuatro veces mayor. Por lo tanto, el intervalo debe cambiarse de acuerdo con el tamaño relativo del mundo. Probablemente, debe hacerse en varios lugares.
Aquí está la misma tarjeta después de solucionar el problema:
Ahora en el mapa hay un número más lógico de ciudades y pueblos, pero esto nos muestra otro problema. Puede ver muchos nombres adicionales en los bordes del mapa, por ejemplo, Nanmrummombrook, Marwynnley y Noyewood en la esquina inferior izquierda. Esto sucede porque el método del código de ubicación intenta colocarlos donde están visibles. Anteriormente, este procedimiento nunca tuvo que preocuparse por las etiquetas fuera de la pantalla, porque en los mapas de tamaño regional, todo el mundo suele ser visible. Pero ahora puede haber ciudades y otros objetos ubicados fuera de la pantalla. Por lo tanto, necesito agregar lógica al procedimiento de colocación de etiquetas que no intente crear etiquetas para objetos de mapa invisibles.
Ahora la imagen es más lógica. A la derecha, Cumden apenas es visible en el mapa, pero la etiqueta todavía se encuentra donde está visible.
Hay un aspecto que no se nota de inmediato en mapas grandes: la cantidad de ubicaciones en el mundo no ha cambiado. Aunque el mapa (en cierto sentido) se ha vuelto 4 veces más grande, su área total todavía está limitada por el mismo número de ubicaciones. La etapa inicial de la generación de mapas fue cubrir el mundo con un diagrama de Voronoi con un número constante de ubicaciones. Es decir, cuando el mapa se hace más grande, las celdas de Voronoi también se hacen más grandes.
Sería lógico escalar el número de ubicaciones de acuerdo con el tamaño del mapa, pero desafortunadamente, la dependencia de la velocidad de ejecución de
Dragons Abound en el número de ubicaciones es mucho peor que lineal, es decir, generar un mapa con una gran cantidad de ubicaciones puede tomar mucho tiempo. Aquí hay un ejemplo de una tarjeta con resolución cuádruple (número de ubicaciones):
Las ubicaciones agregadas cambian el proceso de generación, por lo que el terreno es diferente de los mapas que se muestran arriba, pero en él puede ver los detalles agregados en las costas.
Afortunadamente, al perfilar el rendimiento de la generación de tarjetas grandes, noté que la mayor parte del tiempo del procesador está ocupado por problemas evidentes. Después de la depuración, eliminé los más inquietantes, lo que me permitió crear mapas aún más. Aquí está la tarjeta 4x completa:
Zoom del 25% realizado. Parece aproximadamente el tamaño máximo de mapa que Chrome puede mostrar. El procedimiento de generación mundial puede procesar mapas más grandes, pero al intentar mostrarlos, el navegador falla. En este sentido, Firefox parece ser más funcional; Puede mostrar tarjetas 9 veces más grandes que el tamaño original. Aquí hay parte de dicho mapa: lo dejé en tamaño completo, para que pueda abrirlo en una ventana separada para comprender mejor el tamaño y los detalles.
Firefox es capaz de generar mapas de este tamaño, pero solo puedo tomar capturas de pantalla en el tamaño máximo de la ventana del navegador. Tengo una función para guardar el mapa como un archivo PNG, pero solo puede guardar la parte mostrada del mapa. Creo que puede desplazarse por el mapa, capturar pantallas individuales y conectarlas, pero llevará mucho tiempo.
La mejor solución es guardar el SVG en sí mismo para que pueda abrirse en un programa como Inkscape.
Solía poder cortar y pegar mapas SVG en Inkscape, pero los SVG para mapas mundiales son tan grandes que cuando intento cortar el navegador se bloquea. Afortunadamente, encontré
FileSaver.js y puedes usarlo para guardar el SVG directamente en un archivo y luego abrirlo en Inkscape, creando así una imagen muy grande.
Al menos teóricamente. Cuando intento abrir estos mapas en Inkscape, me encuentro con un par de problemas.
El primer problema es que los supuestos de Inkscape son diferentes de los supuestos de Chrome y Firefox en cómo abrir SVG. En particular, si el color de relleno no se especifica en la ruta, los navegadores suponen que no hay relleno; Inkscape supone que el contorno está lleno de negro. Por lo tanto, cuando abro el SVG guardado en Inkscape, es casi completamente negro, porque la capa superior del mapa no contiene un color de relleno. Esto se puede solucionar especificando "fill: none" en los lugares necesarios para que los contornos aparezcan igualmente en el navegador y en Inkscape.
El segundo problema es que Inkscape tiene errores en el procesamiento de máscaras. Inkscape parece crear máscaras con un solo elemento, y maneja mal las máscaras con varios elementos.
Dragons Abound crea muchas máscaras con varios elementos. Puede solucionar este problema agrupando todos los elementos de cada máscara de juego en un elemento de grupo (opcional).
El tercer problema está relacionado con las imágenes y otros recursos descargables. En el SVG original, las referencias a ellos se indican en forma relativa, por ejemplo, "images / background0.png". Mis fuentes están organizadas de tal manera que el
servidor web separado que uso puede encontrar estos recursos en los lugares especificados. Cuando tomo el mismo SVG y lo abro en Inkscape, estas rutas relativas se tratan como el "archivo" URL e Inkscape busca recursos relativos a la carpeta donde se guardó el SVG. Este problema se puede evitar fácilmente guardando el SVG en una carpeta en la que ya hay recursos en los lugares correctos; puede ser la misma carpeta raíz utilizada por el servidor web u otro lugar en el que haya copias de recursos a lo largo de las mismas rutas (relativas).
El cuarto problema son las fuentes.
Dragons Abound utiliza fuentes web y fuentes almacenadas localmente; ambos en formato WOFF2. En el navegador, se aplican al texto usando el estilo de familia de fuentes CSS, y antes de generar el mapa, todas las fuentes posibles se cargan en la página web para estar listas para su uso. Cuando se abre el mismo archivo en el juego, busca fuentes en el directorio de fuentes del sistema, y parece que no se puede especificar ningún otro directorio de fuentes de ninguna manera. Una solución simple (al menos en la máquina donde estoy desarrollando) es instalar las fuentes utilizadas por el juego en el directorio de fuentes del sistema. Sin embargo, no es tan simple como parece, porque los nombres de las fuentes deben coincidir, y en Windows no hay formas fáciles de cambiar el nombre de la fuente. Pero, por supuesto, dicho esquema no funcionará en computadoras en las que no se instalan todas las fuentes necesarias. Una solución más portátil es
incrustar fuentes SVG en mapas . Esto estará en mi lista TODO.
Al final, llegué a esta interfaz de generación de mapas:
Los campos de entrada de extensión especifican el tamaño total del mundo, donde 1x1 es el tamaño de los mapas de origen. El tamaño de vbx (viewbox) determina el tamaño de un fragmento del mundo que se muestra en el mapa; en la captura de pantalla, también tiene un valor de 1x1, es decir, el mapa mostrará todo el mundo. Los campos del centro vbx especifican la ubicación del centro del mapa en el mundo; 0, 0 es el centro del mundo. Finalmente, los parámetros SVG especifican el número de píxeles de pantalla por 1 unidad de tamaño de cuadro de vista; con un valor de 775, se mostrará un mapa de 1x1 en la pantalla en la cantidad de 775x775 píxeles. Esto es conveniente cuando creo un mapa muy grande. Al establecer el parámetro en un valor bajo (por ejemplo, 150 píxeles), puedo ajustar un mapa grande en la pantalla como un todo.
Al cambiar estos seis parámetros, puedo controlar el tamaño del mundo y la fracción del mundo que se muestra en el mapa. El botón Generar funciona exactamente como podría adivinar; el botón Mostrar simplemente muestra una parte del mundo, es decir, puedo generar un mundo y luego mostrar sus partes individuales, cambiando los parámetros del cuadro de vista sin la necesidad de volver a generar el mundo. (Un programador implementaría esto mejor como escala y desplazamiento). El botón Guardar PNG guarda el mapa visible como un archivo PNG; El botón Guardar SVG guarda el archivo SVG de todo el mapa. El botón Probar se utiliza para ejecutar el código de prueba, que cambia durante el desarrollo de varias funciones.
Ahora que puedo generar y reflejar todas las partes del gran mundo, puedo pasar a adaptar la forma de la tierra a mapas más grandes.
Parte 3. Formas de sushi
Habiendo realizado varios cambios en la parte anterior, ahora puedo generar mundos que son mucho más grandes que los anteriores (hasta 8 veces más) y guardarlos como imágenes gráficas grandes:
(Abra la imagen en una ventana separada para ver el mapa en resolución completa 4800x2400 en Flickr).
Genero estos mapas usando la misma generación de procedimientos que creó los mapas regionales. El mapa que se muestra arriba tiene una forma continental bastante regular y algunas islas exteriores interesantes. Sin embargo, depende principalmente de la suerte. Aquí hay otro mapa:
Esta carta es solo el caos de las islas y el queso de sushi suizo.
Aquí hay otro ejemplo, algo entre las dos cartas anteriores. No es completamente realista, pero puede ser interesante para entornos de fantasía:
Esta es una gran masa continental de tierra, pero hay muchas formas extrañas de tierra y, en general, el mundo no se ve muy "real". (Aunque para alguien tal mundo parecerá bastante adecuado para la fantasía). Entonces, ¿qué formas debería tener el mapa del "mundo"?
La mayoría de los mapas del mundo de fantasía que he visto representan un gran continente insular (con pequeñas islas alrededor), por ejemplo, como este mapa de
Andelen :
O la península del continente, como en este mapa de
Angorun :
De vez en cuando, un mapa está compuesto completamente de tierra o varios continentes insulares, pero es más probable que sean excepciones a la regla.
Para comenzar, descubramos la generación de continentes "isleños". Como resultó en mi juego, ya había una función que genera una gran isla central en el mapa teniendo en cuenta el tamaño del mapa, por lo que debería ser adecuada para generar la forma principal del continente. El ruido y las islas adicionales se encargarán del resto.
No esperaba un gran mar central en este mapa, pero es una sorpresa agradable. Aquí hay otro ejemplo:
El problema con la función de la isla central es que comienza con un círculo que es adecuado para los mapas cuadrados mostrados por mí, pero no es muy bueno para los mapas rectangulares. (A continuación hay ejemplos con una pequeña cantidad de distorsión, de modo que las formas básicas son más claramente visibles).
Esto se corrige fácilmente enmascarando sushi en lugar de un círculo con una elipse (distorsionada), tomada de acuerdo con el tamaño del mapa:
Estas islas centrales están escaladas para llenar el mapa, pero en muchos casos para mapas continentales necesitamos dejar una "frontera" alrededor del continente. Dos parámetros controlan el tamaño del mapa que llena la isla a lo largo de los ejes X e Y.
Aquí está el mismo sistema de gestión de fronteras con más distorsiones lógicas:
Se puede ver que las partes este y oeste del mapa siguen siendo el océano. (Puede abrir el mapa en una ventana separada para estudiarlo más detenidamente). Esto significa que el mapa muestra todo el mundo (y sus bordes derecho e izquierdo se pueden conectar) o una parte del mundo que se puede conectar a otro mapa que también tiene un océano desde el borde correspondiente.
Un lector atento que ha estudiado el mapa anterior puede haber notado que los patrones del océano y la tierra se detienen en el medio del mapa. 1x1, . , . ( SVG , Chrome , .) , , . , !
, , «» — , .
. , .
— . , ( ) .
, , , :
, , . :
, ( ) , . , .
, , , , .
. , .
4.
,
Dragons Abound . , :
; , , . , .
, :
,
. .
Dragons Abound , . (
.) , , ,
. (
.) — . . , , , , . . , , .
,
Dragons Abound . ( , !) , , . , .
? , . .
.
— , . ,
(
). , ;
Red Blob Games , . , , - , .
, — . , . (
), , odd-r:
. (
. , .)
, . , (3, 3), ? 5 , (3, 3)? Y así sucesivamente. , , .
, , , . , , , . , , , , , :
, , , , .
, , :
, , .
— . Javascript
, (0, 0) . , . , , :
, , , . , . :
— , . — , .
, :
, — , . , , . «». ( .)
— , .
, , .
, , . () , . ( , ) : (1) , , (2) , .
. , . , , , , .. .
( , ) . — , :
, . ( , — .)
, ?
, , — , , , . , — .
. — :
, , — , :
, : , .
. , ?
(, ), .
, , , .
, . . -, X Y, :
, (0, 0), (X,Y) . . (X,Y) :
— :
, .
, , , , . , Javascript
Victor.js , .
, , :
.
— , . -, , .
:
0 , 60 — , . , , — 30 . - , , , , .
, 22 :
38/60 , 22/60 — . X Y, , (, 22/60), .
, , . :
, , .
— . , , , . . ,
:
- .
- , , , .
, , , . , , , , . , , , , :
. , . :
- , , .
, — . , , Breeches. , , . , . , , , . , :
, Breeches .
. — . , , , , , / .
, :
, , , . — , . (
! : .)
. ( , — ):
( , .) , . . , . , . , . .
( ), , , . , , .
, . ? . , 15-20 (!). , . , , , .
, .