Сохранен 59
https://2ch.hk/gd/res/234027.html
24 декабря 2023 г. Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!

Разработки игр под макабу тред

 Chekunov !VladgUJPdI 23/02/16 Втр 17:56:23 #1 №234027 
14562393838900.jpg
Привет, Анон. Меня зовут Влад. И я, если не единственный, то как минимум первый разработчик игр для макабы. За моей спиной уже целый один крупный проект (http://vk.com/zog_thread) игры для данной платформы. И вот, я решил поделиться с вами информацией о том, как же всё-таки можно создавать игры для макабы и какие имеются подводные камни.
Немного предыстории. Разрабатывать игры для макабы я начал около полугода назад, когда Абу открыл нам api. Идея была простой. На борде регулярно всплывали игровые треды с рулеточками, именуемые Захвати Странанейм-тред, в которых я также, как и многие из вас, принимал участие. Но играть всегда было не удобно, ведь уследить за большим количеством сообщений очень сложно. Поэтому было решено, во чтобы то ни стало упростить управление этой игрой. Так и началось моё первое знакомство с макабой. С тех пор игра эволюционировала, в ней появился отличный редактор уровней, трансляцию на ютубе, от которой наши модераторы очень бугуртили, заменила автоматическая отправка карты в тред, прокси и прочие костыли заменил простой плагин CORS Everywhere. В общем, много чего изменилось и за всё это время я получил огромный опыт в разработке игр для макабы.
Сегодня, на примере разработки очередной игры для макабы мы разберём основные этапы разработки и сложности, с которыми может столкнуться программист, разрабатывающий игру для владельцев девайсов, поддерживающих макабу.
Вопросы можете задавать по ходу. Буду постепенно описывать этапы разработки.
Chekunov !VladgUJPdI 23/02/16 Втр 18:01:55 #2 №234044 
Начнем мы конечно же с выбора языка программирования для нашего приложения для макабы. Самым оптимальным вариантом будет клиентский javascript. Оптимален он по нескольким причинам:
1) Двач прежде всего сайт и с сайтом проще всего взаимодействовать с помощью сайта. Именно по этой причине ведущие CMS предлагают удобную панель управления внутри сайта, а не вне его с помощью отдельной программы.
2) Не нужно открывать множество приложений. Достаточно открыть всего лишь браузер с двумя вкладками и в вашем распоряжении уже оказывается как клиент, так и сервер вашей игры.
3) Асинхронность. Учитывая, что мы работаем с интернетом, асинхронность безусловно будет плюсом при работе нашего приложения.
Это не все, но основные преимущества использования клиентского JS для написания игр под makaba engine.
Chekunov !VladgUJPdI 23/02/16 Втр 18:08:50 #3 №234055 
14562401308330.jpg
Как обычно устроены игры и приложения для makaba?
Есть ОП, который выполняет роль сервера и есть множество клиентов, которые этим сервером управляют. Управляют они им, как правило, по средством специальных команд. В ответ на команды, ОП отправляет результат и пользователи продолжают игру. Игры под makaba, как правило, многопользовательские. Поэтому отличным вариантом будет равноправность нескольких персонажей. Ведь таким образом пользователи будут конкурировать друг с другом, а значит игра будет интересней и соберет большее количество фанатов и наблюдателей. Также, чтобы игра была интересной, вместо простых ответов текстом лучше всего использовать динамичные иллюстрации, как например пикрелейтед.
В этот раз мы пойдем несколько дальше, чем это принято и совершим революцию в мире приложения для makaba. Вместо скучных статичных иллюстраций мы будем использовать интересные и красивые динамичные иллюстрации, проще говоря, грофен будет анимирован.
Chekunov !VladgUJPdI 23/02/16 Втр 18:15:56 #4 №234069 
14562405566010.gif
Какой геймплей подойдет для игры лучше всего?
Учитывая особенности макабы, игра должна быть:
1) Простой в управлении.
2) Медленной. Лучше всего пошаговой.
3) Автономной. То есть пользователи не должны зависить друг от друга.
Так, например, какой-нибудь 3d yoba шутер будет не лучшим решением для приложения по первому пункту.
Какой-нибудь Товер дефенс не подойдет по второму пункту, ибо пользователь не будет успевать реагировать на полчища противников.
Мафия не подойдет по третьему пункту, ведь один пользователь будет в теории знать больше другого, а этого не может быть по определению.
Что касается команд. В игру следует внести элемент случайности, дабы играть было интересней и игра не зависила от одних лишь команд и того как быстро анон может ввести их.
Chekunov !VladgUJPdI 23/02/16 Втр 18:23:44 #5 №234079 
14562410249490.png
Вернёмся к разработке. Мы уже определились с жанром игры JRPG и в целом с геймплеем. У нас есть идея, которая оптимально подходит под все описанные выше критерии и даже некоторый прототип интерфейса - пикрел. С чего же следует начать? А начать следует с установки необходимой среды в ваш браузер. Так как в 2ch API напрочь отсутствует поддержка CORS, нам понадобится искусственно внедрить её. К счастью, есть отличный плагин CORS Everywhere, который я уже упомянул ранее.
Зачем CORS? Дело в том, что браузерам запрещают скачивать информацию с некоторых URL, а затем передавать её, если на то нет разрешения, то есть определённого заголовка в CORS. По этой причине становится проблемотично взаимодействовать с макабой.
Также нам понадобится jQuery, дабы упростить написание нашего приложения.
Как будет устроен игровой процесс? Chekunov !VladgUJPdI 23/02/16 Втр 18:28:53 #6 №234082 
Пользователь создаёт новый тред или подключает уже имеющийся. Приложения начинает анализировать ответы в треде, интерпритируя их и строя на основе их результат, который будет через некоторое время/количество постов отправлен в тред.
В нашем случае приложение будет пытаться интерпритировать вводимые команды и создавать на их основе анимацию, которую через некоторое время оно отправит в тред.
Анимация Chekunov !VladgUJPdI 23/02/16 Втр 18:33:21 #7 №234086 
Так как в нашем приложении будет использоваться анимация, нам следует выбрать один из всевозможных вариантов её реализации, а именно:
1) Webm. Есть поддержка звука, но при этом большой размер выходного файла, а также долгое время генерации.
2) Gif. Для нашего приложения будет наиболее оптимальным использование GIF, ведь следует учитывать, что изображение будет передаваться через интернет, а не у всех наших пользователей столь мощное железо и интернет-соединение, чтобы генерировать WebM.
Как же сгенерировать GIF? А в этом нам поможет замечательный фреймворк от Yahoo. Gifshot, вот демонстрация его возможностей:
https://yahoo.github.io/gifshot/demo.html
Начало Chekunov !VladgUJPdI 23/02/16 Втр 18:53:40 #8 №234101 
Перейдём от слов к делу и наконец приступим к написанию нашего первого приложения для макабы. Для начала создадим общую файловую структуру, общепринятую в большинстве веб приложений. Создадим папки img, css и js, в которых соответственно будут находиться картинки нашей игры, стили интерфейса нашей игры и общая программная логика.
В корне также требуется создать файл index.html. Это и будет в итоге место, откуда мы будем запускать нашу игру.
Его мы заполним следущими тегами:
<!DOCTYPE html><html><head><title>Моё первое приложение для makaba</title></head><body></body></html>
Затем мы подключим jquery, добавив соответственный тег в head.
Также нам нужно установить плагин Cors Everywhere в наш браузер. Лично я использую FF и всячески призераю хромо-майкрософто-оперо-сафари-блядков. Возможно, под ваш браузер есть альтернативный плагин, способный включить постоянный CORS, но я советую использовать именно FireFox, дабы в дальнейшем избежать некоторых неточностей.

Собственно, вот ссылка на плагин, с его установкой, думаю, сами разберетесь:
https://addons.mozilla.org/en-us/firefox/addon/cors-everywhere/
Кодировка Chekunov !VladgUJPdI 23/02/16 Втр 18:57:17 #9 №234103 
Дабы избежать проблем с отображением кириллических символов, следует сохранить ваш index.html и другие файлы, которые мы будем создавать далее, в кодировке UTF-8.
Также внутри head мы допишем:
<meta charset="utf-8">
Тем самым мы дадим понять нашему браузеру, что приложение использует именно эту кодировку.
sageАноним 23/02/16 Втр 19:03:32 #10 №234108 
Ебанутый.
Аноним 23/02/16 Втр 19:04:34 #11 №234112 
>>234108
Я так не думаю.
Получение информации с борды Chekunov !VladgUJPdI 23/02/16 Втр 19:09:30 #12 №234122 
Итак, анончик, давай же попробуем получить, например, первый пост этого треда. Для этого заполним body нашего index.html следущим кодом:
$.ajax({
url : 'https://2ch.hk/gd/res/234027.json',
async : false,
dataType : 'json',
crossDomain: true,
success : function(data) {
console.log(data.threads[0].posts[0].comment)
}
});

Некоторые ключевые значения я выделил ЖЫДНЫМ:
1) Это буква нашей доски.
2) Это номер нашего треда.
3) Это номер сообщения в треде.
Итак, теперь, открыв наш файл в браузере, предварительно включив CORS Everywhere и открыв консоль, мы увидем, что в наше консоль вывелось первое сообщение этого треда.
Chekunov !VladgUJPdI 23/02/16 Втр 19:10:26 #13 №234128 
>>234122
\t - это табуляция, почему-то всё проебалось, ну да похуй. Представьте, что никаких \t нет.
Chekunov !VladgUJPdI 23/02/16 Втр 19:11:38 #14 №234132 
>>234108
Чего бугуртишь? Под эту вашу Unity ещё не завезли генерацию игр для makaba?
Аноним 23/02/16 Втр 19:12:15 #15 №234135 
Защекунов, ты хелловорлд неделю запускал, какие нахуй игры?
Аноним 23/02/16 Втр 19:12:30 #16 №234137 
>>234128
В CODE пихай.
Chekunov !VladgUJPdI 23/02/16 Втр 19:13:51 #17 №234138 
>>234135
Защекунов это ты так своего отца называть привык?
Что касается хеллоуворлда, очевидно, что пилился он так долго именно из-за нехватки времени, отчасти из-за проектирования описываемой игры.
Основной объект игры Chekunov !VladgUJPdI 23/02/16 Втр 19:24:31 #18 №234158 
Создадим основной объект игры, добавив в head следущий код:
<script>
var gm={
data:{},/Данные пользователей/
load:function(){/События при старте/},
timer:false,//Таймер
draw:function(){/Событие отрисовки нашего ответа/}
inter:function(){/Событие интерпретации полученной информации/}
}
</script>

Описанный ранее код можно закоментировать, так как в ближайшее время он нам не понадобится.
Данные игроков Chekunov !VladgUJPdI 23/02/16 Втр 19:33:22 #19 №234166 
Основываясь на прототипе мы можем уже заполнить некоторые данные игроков.
Создадим в нашем объекте данных data, объект players и заполним его:
players:[{name:"Влад",//Имя
pclass:0,//Класс
lvl:12,//Уровень
health:0.9,//Здоровье
coin:200,//Монеты
score:200,//Очки
helmet:0,//Идентификатор шлема
plat:0,//Идентификатор хз как назвать, в общем, верхней одежды
legs:0,//Идентификатор штанов
boots:0,//Идентификатор обуви
sprite:{//Спрайт персонажа
x:0, y:0, frame:0},
enemy:{//Данные противника
pclass:0,//Идентификатор вида противника
lvl:4,//Уровень противника
health:1,//Здоровье противника
sprite:{//Спрайт противника
x:0, y:0, frame:0
}}}]
Аноним 23/02/16 Втр 19:35:08 #20 №234170 
Не забывайте переодически проверять консоль на наличие ошибок. Так, например,
>>234158
я забыл поставить запятую после функции gm.draw.
Chekunov !VladgUJPdI 23/02/16 Втр 19:55:26 #21 №234230 
Теперь на основе наших данных, давайте отрисуем нашу игру.
Добавим canvas в body с width=500 и height=200, подключим его к нашему коду в load и добавим отрисовку интерфейса в функцию draw.
>gm.ctx=document.getElementById("canvas").getContext("2d")
Пока просто отрисуем фон и зададим некоторые размеры.
>gm.ctx.fillStyle="#211e33";gm.ctx.fillRect(0,0,500,200);
Нужно также не забыть связать load с загрузкой нашего приложения:
>window.onload=function(){gm.load();}
И, конечно же, добавить нашу переменную ctx в объект gm.
Дабы видеть результат в load добавим отрисовку:
>gm.draw();
Обновив страничку мы увидим прямоугольник 500х200, который будет в итоге клиентским интерфейсом нашей игры.
Chekunov !VladgUJPdI 24/02/16 Срд 19:31:10 #22 №236086 
14563314701810.png
Продолжим отрисовку интерфейса, нарисовав левую панель со списком пользователей, монетами, очками и полосой здоровья. Создадим спрайт sprite.png пикрелейдед и поместим его в наш img каталог.
Заполним функцию draw следующим кодом:
gm.ctx.fillStyle="#110f1a";
gm.ctx.fillRect(0,0,500,200);
gm.ctx.fillStyle="#ffffff";
gm.ctx.fillRect(95,0,500,200);
gm.ctx.font="10px Pixel Cyr";
gm.ctx.fillText("Игроки:",27,12);
gm.ctx.mozImageSmoothingEnabled = false;
gm.ctx.imageSmoothingEnabled=false
var img = new Image();
img.src = 'img/sprite.png';//Загружаем спрайт
img.onload = function(){
for(var i=0;i<gm.data.players.length;i++){
gm.ctx.fillStyle="#211e33";
gm.ctx.fillRect(1,20+i26,93,25);
gm.ctx.fillStyle="#ffffff";
gm.ctx.font="8px Pixel Cyr";
gm.ctx.fillText(gm.data.players[0].name, 35, 30+i
26);
gm.ctx.font="10px Pixel Cyr";
gm.ctx.fillText(gm.data.players[0].coin, 14, 31+i26);
gm.ctx.fillText(gm.data.players[0].score, 14, 41+i
26);
gm.ctx.drawImage(img,0,0,5,5,5,25+i26,5,5);
gm.ctx.drawImage(img,0,5,5,5,5,35+i
26,5,5);
gm.ctx.fillStyle="#a30d15";
gm.ctx.fillRect(35,35+i26,55,5);
gm.ctx.fillStyle="#0da913";
gm.ctx.fillRect(35,35+i
26,Math.ceil(55*gm.data.players.health),5);}}

Как видите, теперь список наших пользователей отображается на странице. Однако, есть одна проблема. К тексту применился anti-aliasing. Из-за этого вместо одного белого цвета такста у нас также присутствуют и промежуточные цвета, что, конечно, скажется на размере файла, как это пофиксить, я расскажу позже, когда мы дойдем до этапа создания gifки.
Chekunov !VladgUJPdI 26/02/16 Птн 23:44:24 #23 №238698 
14565194650350.png
Добавляем некоторые элементы в спрайт. Создаём массив объектов mobs, добавляя первого противника:
>mobs:[{
>name:"Червь-пидор"
>}],
Также несколько дополняем событие draw и получается пикрелейтед.
Chekunov !VladgUJPdI 26/02/16 Птн 23:46:16 #24 №238704 
>>238698
Примечание
Для примера в массив объектов игроков players были добавлены ещё 3 дубликата нашего персонажа, дабы видеть как всё это будет прорисовываться.
Аноним 27/02/16 Суб 09:23:27 #25 №238924 
Хм, анон, ты меня заинтриговал. Может тоже набыдлокодить какую-нибудь игру для двача?

Стоит попобовать, лол.
Аноним 27/02/16 Суб 10:23:53 #26 №238938 
>>238924
Делай, именно для тебя и таких как ты я и сделал этот тред.
Аноним 27/02/16 Суб 15:48:08 #27 №239156 
Схороню, хоть и немного глупо все описано. Нет разбора синтаксиса почти, просто "скопируй и будет тебе хорошо"
Chekunov !VladgUJPdI 27/02/16 Суб 22:11:35 #28 №239564 
>>239156
Просто скопируй тут только насчет всего, что не касается взаимодействия с макабой и касается больше программирования на JS.
Chekunov !VladgUJPdI 27/02/16 Суб 22:17:03 #29 №239572 
Создадим объект с объектами массивов параметров вещей и добавим туда некоторые объекты, которые затем поместим на спрайт:
items:{
helmets:[{
name:"Бумажный пакет",
x:24,//Расположение на спрайте
y:0,
width:8,
height:8,
xo:4,//Offset на отрисовке
yo:0
},{
name:"Маска Гая Фокса",
x:24,
y:8,
width:8,
height:9,
xo:4,
yo:0
}],
plats:[],
legs:[],
boots:[]
},

Chekunov OP !VladgUJPdI 27/02/16 Суб 22:22:03 #30 №239577 
14566009235090.png
14566009235101.png
Также добавим на спрайт персонажа по умолчанию и несколько его поз, а также свяжем предметы, персонажа и их параметры в нашем draw. Так, что спрайт будет как первый пикрелейтед, а интерфейс как второй пикрелейтед. Я несколько поменял игроков для разнообразия.
Выбор команд для игры Chekunov OP !VladgUJPdI 27/02/16 Суб 22:47:09 #31 №239609 
Настало время придумать команды. Команды должны быть не сильно сложными, чтобы игрок не мучался их вводить. Исходя из задумки нашей игры, я выделил несколько основных команд:
>1)Создать персонажНейм
>2)ПерсонажНейм Похиляться
>3)ПерсонажНейм защититься
>4)ПерсонажНейм ударить
>5)Купить предметНейм
На основании этих наработок команд мы будем разрабатывать дальнейшую логику игры.
Создавать персонажа на даббл/траппл, остальные команды скорее всего на четность/нечетность, дабы играть было проще. Разве что, покупку на даббл/триппл оставить.
Аноним 27/02/16 Суб 22:50:04 #32 №239613 
>>239609
Почему бы не использовать какой нибудь конструктор игорей, и не сделать сетевую игру?
Chekunov OP !VladgUJPdI 27/02/16 Суб 22:53:31 #33 №239619 
>>239613
Потому что это будет уже не игра под макабу. Туториал не про это. Цель туториала не просто создать сетевую игру, а написать собственную ПЕРВУЮ ИГРУ ДЛЯ УСТРОЙСТВ С ПОДДЕРЖКОЙ MAKABA.
Аноним 27/02/16 Суб 23:42:33 #34 №239636 
>>239619
Не особо я так уверен, что кто то что то дельное сделает по этому гайду
Аноним 27/02/16 Суб 23:45:56 #35 №239638 
>>239636
-->
>>238924
Желающие уже есть.
Chekunov OP !VladgUJPdI 28/02/16 Вск 08:40:40 #36 №239709 
14566380403840.png
>>239609
Теперь сделаем аналогичный спрайту персонажа, спрайт червя-пидора - единственного, на данный момент, враждебного моба. Также отрисуем его в функции draw. Мы ещё вернёмся к отрисовке, но пока, этап предварительно отрисовки завершен и можно начать заниматься общей логикой игры.
Chekunov OP !VladgUJPdI 28/02/16 Вск 12:01:31 #37 №239734 
>>239609
>1)Создать персонажНейм
Теперь сделаем объект act для всех функций, связанных с игровым процессом и добавим в него функции createChar, которая будет добавлять игрока и checkUserName, которая будет проверять на повторение имя игрока. Ведь управлять игроком пользователь будет именно благодаря его имени.
!test Аноним 29/02/16 Пнд 01:06:47 #38 №239986 
Test
Chekunov OP !VladgUJPdI 02/03/16 Срд 17:43:17 #39 №240861 
Я тут немного подумал и решил, что при каждой проверке треда будет интерпритироваться действие, затем это действие в случае успеха ролла, будет добавляться в некоторый стек действия игрока. Когда хотя бы у одного игрока этот стек содержит более 5 действий, мы начинаем их реализовываться, создавая кадры для нашей gif и отправлять её в тред.
Chekunov OP !VladgUJPdI 02/03/16 Срд 18:21:18 #40 №240869 
>>239609
>>2)ПерсонажНейм Похиляться
Для этого сделаем функцию healChar с параметрами playerId (идентификатор персонажа), frame (номер кадра, ведь на одном кадре мы размещаем сразу несколько персонажей, а кадр у нас не единственный) и health (процент восстановления здоровья).
sageАноним 02/03/16 Срд 18:40:44 #41 №240873 
>>234137
[code] Итак, анончик, давай же попробуем получить, например, первый пост этого треда. Для этого заполним body нашего index.html следущим кодом:
$.ajax({
\turl : 'https://2ch.hk/gd/res/234027.json',
\tasync : false,
\tdataType : 'json',
\tcrossDomain: true,
\tsuccess : function(data) {
\t\tconsole.log(data.threads[0].posts[0].comment)
\t}
});
Некоторые ключевые значения я выделил ЖЫДНЫМ:
1) Это буква нашей доски.
2) Это номер нашего треда.
3) Это номер сообщения в треде.
Итак, теперь, открыв наш файл в браузере, предварительно включив CORS Everywhere и открыв консоль, мы увидем, что в наше консоль вывелось первое сообщение этого треда. [/code]
Аноним 02/03/16 Срд 18:42:23 #42 №240874 
>>240873
>Пытаться сагать в /gd/
Привет, ньюфаг.
Аноним 02/03/16 Срд 23:02:30 #43 №240962 
>>240874
это он так подписывается
неймфагохейтерочек такой злой ути пуси злая бака
Chekunov !VladgUJPdI 03/03/16 Чтв 13:33:22 #44 №241099 
>>240869
Что касается frame, это главный элемент функции, на его основе мы определяем, что именно делать, прибавлять здоровье или же рисовать анимацию, а если анимацию, то какой именно её этап. Поэтому проверку frame мы поместим сразу в тело функции.
Аноним 04/03/16 Птн 18:15:04 #45 №241497 
>>239609
>3)ПерсонажНейм защититься
Подумав, я решил, что самым оптимальным было бы реализовать это через бафы. То есть, персонаж побеждает и получает возможность защититься, происходит анимация защиты и у него появляется баф защиты на несколько ходов, слегка или даже сильно уменьшающий урон, наносимый ему противниками.
Аноним 05/03/16 Суб 16:49:33 #46 №241821 
14571857738440.png
Начнем с того, что ОП - хуй, делаешь какое-то скучное хелоувордговно и с форматированием полная хуйня.


Мое недавнее говнецо лежит тут:

http://83.217.26.110/tch/main.html

Из-за этого CORS без костылей не сделать локальную версию.
Аноним 05/03/16 Суб 17:42:15 #47 №241840 
>>241821
Рэритиблядь - не человек.
Chekunov !VladgUJPdI 05/03/16 Суб 18:11:23 #48 №241849 
>>241821
>хелоувордговно
Но ведь это для обучения.
>с форматированием полная хуйня
Поясни.

Chekunov !VladgUJPdI 05/03/16 Суб 18:12:12 #49 №241850 
14571907324520.png
>>241497
Сделал иконку бафа защиты.
Chekunov !VladgUJPdI 06/03/16 Вск 12:23:39 #50 №241982 
Бамп, пока ничего не сделал. Думаю, в ближайшее время следует добавить в функцию создания игрока массив бафов с количеством ходов, на которые эти бафы распространяются, а также отображать иконки этих самых бафов.
Аноним 10/03/16 Чтв 02:09:28 #51 №243407 
>>234027 (OP)
Отличная работа Влад. Так держать!
Chekunov !VladgUJPdI 11/03/16 Птн 13:54:15 #52 №243875 
>>243407
Рад стараться.
Аноним 15/03/16 Втр 07:44:41 #53 №245099 
Bmp
Chekunov !VladgUJPdI 15/03/16 Втр 21:06:32 #54 №245421 
14580651928880.png
>>241850
Сделаем цикл, который будет перебирать бафы пользователя и прорисуем их. Получим пикрелейтед.
Аноним 07/04/16 Чтв 07:25:59 #55 №251531 
ОП вернулся.
Chekunov !VladgUJPdI 10/04/16 Вск 17:06:56 #56 №252243 
>>251531
Вернулся и ничего не сделал.
Аноним 10/04/16 Вск 19:31:53 #57 №252267 
>>234079
>CORS
Поясни, зачем он тебе. Может я цепочки не очень понял:

Пользователи оставляют посты, ты их считываешь через API, обновляешь контент на своём сервере.
Chekunov !VladgUJPdI 10/04/16 Вск 20:36:12 #58 №252277 
>>252267
Обработка постов осуществляется через HTML5 приложение, которому обязательно нужен CORS, иначе костыли.
Аноним 14/04/16 Чтв 11:50:45 #59 №252841 
>>234027 (OP)
Интере(ный факт, в(е влады пидоры. Еще, (колько тут (ижу, не видел чужих имен кроме тебя. оправдывай(я.
comments powered by Disqus

Отзывы и предложения