PDA

Просмотр полной версии : [Starling] Работодатель отказал, хочу узнать почему?


Isfet
01.07.2015, 06:26
Здравствуйте, уважаемые гуру! Выполнил тестовое задание, после чего работодатель отказал. Раньше программировал только на чистом as3, со Starling никогда не работал, с Изометрией знакомиться не приходилось, пришлось учить и делать все с нуля, так как сами понимаете никаких наработок по этой части у меня нет.аимо Очень хочу узнать у вас, почему такая оценка ? На все про все ушло около 42 часов работы (обучение + программирование).

Вот текст тестового задания.

1. На базе старлинга создать игровую изометрическую сцену.

2. Создать изометрическую карту 500х500, зелёное поле.

3. При старте генерируется 1000 домиков на случайных позициях.
- Размер спрайта домика от 64х64 px
- 3 изометрических размера домиков: 1х1, 1х2, 3х3
- спрайты в png в отедльно папке загружать при старте
- конфиги в json загружать при старте
- 12 видов домиков

такой арт норм:
https://www.pinterest.com/pin/246994360790390965/
https://www.pinterest.com/pin/525584218988980048/

4. У каждого домика случайное кол-во жизней, от 1 до 5, при клике на домик теряет жизнь, при 0 жизней взрывается

5. В интерфейсе должен быть:
- счётчик фпс и счётчик дипов
- счётчик домиков
- кнопка '+' добавляется домик в случайное свободное место
- кнопка '-' убирает случайный домик

6. Карту драгаем мышкой

Необязательные условия:
- Добавить анимированные объекты
- Дороги
- Вода
- Бар с жизнями домиков
- Персонажи перебегающие по дорогам от домика к домику и прячущиеся внутри

Будем смотреть на:
- Фпс
- Отзывчивость карты
- Организацию кода
- Придираться к стилю и синтаксису в коде
- Наличие паттернов и ооп


///////////////////////////////////////////////////////////////////////////////////

а вот исходники (flashdevelop)
31692

caseyryan
01.07.2015, 07:33
Ну к стилю кода тут действительно можно придраться.
Где-то написано "e", где-то "event"
Часть констант написано капсами, часть кэмэлкейсом.
Методы кое где вызываются без скобок, например

e.stopImmediatePropagation;


События не красиво сделаны и не удобно
dispatchEvent(new Event(DECTRUCT_HOUSE_EVENT, true));
Лучше было это оформить в отдельный класс и отправлять уже со своим типом
new HouseEvent(HouseEvent.DESTRUCT);
FPS счетчик у старлинга есть свой

Размеры карты не по заданию
2. Создать изометрическую карту 500х500, зелёное поле.
3. При старте генерируется 1000 домиков на случайных позициях.
Даже близко не то

bifidokk
01.07.2015, 08:24
может вы скажете, что за работодатель? где-то я видел подобное ТЗ с домиками и взрывами

Isfet
01.07.2015, 08:25
Размеры карты не по заданию

Даже близко не то

извиняюсь , размеры карты забиваются в cfg - файле , перезалил исходник (им я отправил правильно, юзал маленькую карту для поиска ошибок).



FPS счетчик у старлинга есть свой


видел в некоторых приложения счетчик, но не мог найти его в старлинговских классах, только сейчас нашел StatsDisplay


Добавлено через 7 минут

caseyryan
01.07.2015, 10:59
видел в некоторых приложения счетчик, но не мог найти его в старлинговских классах, только сейчас нашел StatsDisplay
Все просто

_starling.showStats = true;

Isfet
01.07.2015, 12:27
хотелось бы еще какие-нибудь комментарии не только по коду , но и по структуре.

Tails
01.07.2015, 13:06
Не хилое такое заданице, тут можно на неделю засесть.
Зато, конечно, по выполнению такой работы, будет на 120% видно навыки кандидата и в добавок весь его богатый внутренний мир.

По поводу структуры:

Мвц - ттук. Это довольно плохо.
Класс House.as - Так делать, на самом деле, плохо. Должен быть или класс Building, или просто свойство isBuilding в классе MapObject. А все параметры, в том числе скинование и анимаций - где нить в конфиге.
Из предыдущего вытекает, что полностью отсудствует и модель данных (Не путать с моделью мвц, просто структура данных, как в mysql), её вообще нет. Все игровые объекты и их параметры жёстко прописываются в отдельных классах. 1 объект - 1 класс. Это очень плохо.

Моё скромное имхо.

Isfet
01.07.2015, 13:23
Не хилое такое заданице, тут можно на неделю засесть.


ну я на неделю и засел), хотя они писали, что специалист требуемого им уровня делает такое задание за 1-2 дня, хотя я не понимаю как такое задание можно сделать за такой короткий срок без каких-то наработок



А можете немного пояснить?


По поводу структуры:

Мвц - ттук.


А какие бы вы методы CMap, куда перенесли?




Класс House.as - Так делать, на самом деле, плохо. Должен быть или класс Building, или просто свойство isBuilding в классе MapObject. А все параметры, в том числе скинование и анимаций - где нить в конфиге.



что вы подразумеваете под конфигом?



1 объект - 1 класс. Это очень плохо.
.

то есть класс VBuilding - будет вью, И в нем должна быть ссылка на модель здания ( MBuilding )?

Tails
01.07.2015, 13:46
Видимо, им нужен очень жёсткий хард кодер. Это довольно сложное задание, без хорошего опыта и за 2 дня его сделать, я думаю, не реально. По крайне мере так, чтоб приняли.

По поводу того, что куда перенести, лучше почитать про мвц в этой книжке (http://www.books.ru/books/actionscript-30-shablony-proektirovaniya-816636/), можно ещё на вики статейку глянуть, этого должно быть достаточно. Все создаваемые кнопки, обработчики, удаляющие домики из дисплей листа - всё это относится к вью и должно быть там. Контроллер должен быть пассивным, в его задачу должно входить "воздействие на модель конкретным способом". Например, в модели может быть всего один метод:
createBuilding(id, x, y, life)
А в контроллере мы можем прописать несколько методов:
createRandomBuildings(num)
createRandomDamagedBuildings(num, life)
createBuilding(id, x, y, life)
Каждый из этих методов будет использовать 1 метод модели, но со своими значениями. В этом суть контроллера - определять, на сколько и как менять модель, но модель при этом изменяется не на прямую (_mMap.addHouse), а через собственные методы - интерфейс.
Вся инициатива будет исходить от вью, пользователь кликнул какую-то кнопку, вью вызвала нужный метод контроллера. Такое построение гораздо выгоднее ттук. Подробнее о них в книжке и на вике.

Конфиг - это обычный json файл, который описывает структуру всех данных. (Как и требуется в тз)
В идеале, должно быть так, что бы мы меняя конфиг, могли добавлять новые объекты, менять их параметры но без изменения исходного кода и перекомпиляций приложения.
Проектирование конфига, это отдельная тема. Очень похожая на проектирование обычной mysql бд. Хороший конфиг не будет содержать вложенных сущностей друг в друга. (Это, кстати, ещё одна распространённая ошибка)
Пример хорошего конфига:
{
"buildings":[
{
"id":1,
"title":"Shop House",
"life":100,
"skin":"assets/house1.png",
"offsetX":5,
"offsetY":10,
"size":2
},
{
"id":2,
"title":"Vasya House",
"life":50,
"skin":"assets/house2.png",
"offsetX":2,
"offsetY":15,
"size":3
},
{
"id":3,
"title":"Simple House",
"life":80,
"skin":"assets/house3.png",
"offsetX":9,
"offsetY":21,
"size":1
}
],
"npc":[
{
"id":1,
"title":"Boy",
"life":10,
"skin":"assets/boy.png",
"offsetX":5,
"offsetY":10
},
{
"id":2,
"title":"Girl",
"life":5,
"skin":"assets/girl.png",
"offsetX":2,
"offsetY":15
},
{
"id":3,
"title":"Dog",
"life":2,
"skin":"assets/dog.png",
"offsetX":9,
"offsetY":21
}
],
"locations":[
{
"id":1,
"title":"Wonderful garden"
}
],
"mapNpc":[
{
"locationID":1,
"npcID":1,
"x":15,
"y":25,
"life":1
},
{
"locationID":1,
"npcID":1,
"x":25,
"y":2,
"life":1
},
{
"locationID":1,
"npcID":2,
"x":10,
"y":30,
"life":0.8
}
],
"mapBuilding":[
{
"locationID":1,
"buildingID":2,
"x":15,
"y":25,
"life":1
},
{
"locationID":1,
"buildingID":2,
"x":25,
"y":2,
"life":1
},
{
"locationID":1,
"buildingID":2,
"x":10,
"y":30,
"life":0.8
}
]
}
Онлайн сервис (http://json.parser.online.fr/) для удобного просмотра и редактирования json.
В конфиге я описал такие сущности как здания, npc, локаций, и объекты на локациях. Обрати внимание, что объекты на локациях находятся в отдельном объекте (таблице). Засовывать их в "locations" не нужно.
Далее приложение при старте грузит конфиг, парсит, и на основе этих данных уже строит локаций, объекты и т.д.

Вощем, так и не удалось до конца развёрнуто написать, хотя, больше часа потратил. Ну оно и не удивительно, тут не одна тема затрагивается.

Isfet
02.07.2015, 13:21
спасибо большое за разъяснение, почитаю на досуге.

но вот насчет того что им нужен был именно такой конфиг , не уверен,



Вот текст тестового задания.

3. При старте генерируется 1000 домиков на случайных позициях.


то есть, по сути, этот конфиг хранится в модели карты, его можно при желании выгрузить в файл при сохранении игры, и если бы им нужно было отрисовывать все объекты из данных прописанных в файле конфига,
то 3 пункт был бы как-нибудь по-другому сформулирован, хотя не спорю, можно бы было и побольше данных в конфиг вынести.

Tails
02.07.2015, 14:11
Что смущает в конфиге?
Для демонстраций случайной генераций, в нём можно создать пустую локацию, а в контроллере прописать функцию createRandomBuildings(num), просто дёргая её при старте игры.

В конфиг можно добавить данные о типах тайлов, а так-же карту тайлов для тестовой локаций.
(Вода, дороги) Ещё, для большего соответствия тз, жизни домиков в нём нужно указать 5. (фул хп)
В целом, это было бы то, что они хотели.

Конфиг грузится сразу после запуска приложения, 1 раз. Затем, вы просто храните его в памяти в любом удобном виде. Можете хранить его просто как динамический объект свойств. (Обычный Object, возвращаемый после JSON.parse). На протяжении всей работы приложения вам понадобится постоянно обращаться к этим данным самым разным способом. (По id, по title, по life и т.д.) Поэтому, я всегда дублирую все сущности конфига как as классы, создаю удобные обёртки для доступа к этим данным.
Простой пример класса данных локаций:
LocationData{
public var title:String;
public var id:uint;
}
Класс, содержащий данные по локациям:
LocationsData{
public var vec:Vector.<LocationData>;
}
Это самый краткий вариант записи. На практике, в эти классы добавляются такие метода как getLocationByID, getLocationByTitle и т.п. (Для удобного доступа)
После того как конфиг файл загружен, я разбираю его по этим классам и в дальнейшем храню и работаю с ними.

Указанная выше процедура является инициализацией приложения. Нужно обратить внимание, что это статические данные, они создаются только при запуске, далее вы будете только читать их.
После того как все данные были загружены и расфасованы по классам, в ход идёт мвц и запуск первой локаций.

Isfet
02.07.2015, 14:21
Спасибо, теперь понял, что конфиг должен хранить абсолютно все данные об игре (что-то вроде базы данных), чтобы правя его можно было менять локации, объекты, и все остальное, без правки приложения, просто я никогда с этим не работал, и из тз понял что там должны быть основные общие настройки игры , теперь буду делать правильно, еще раз спасибо.

miramax
05.07.2015, 00:54
Сорри, за прямоту - сам не люблю когда делают код ревью мне )
Не стал бы заострять внимание на e или event и прочей лабуде с табуляциями.

Сразу вижу что:
1. мало опыта в МВЦ, не очень логично распределены обязанности. Всё свалено в кучу.
- разделить на модель, вид , контроллер - дать описания каждому паблик методу в формате ас док на английском
2. Не понимает , что такое интерфейсы. Избыточно заявленые интерфейсы. Впечатление , что разработчик - смутно себе представляет зачем они нужны - типа "так правильно"
- Убрать интерфейсы вовсе, либо заморочиться и впилить инъекции (пусть интервьюер сам курит роботлегс например , покажите что-то интересное=)) и имплементировать в них обычные дисплей объекты вместе со старлингом, приправив парочкой геном2д объектов с шаред 3Дконтекстом.

3. Не гуглит - не заюзал всем известные решения типа isolib, и получилась пародия - которая точно будет багать с объектами на близких координатах и разных слоях.

4. А где ресайз ? А где фпс на 60 ? Где обработка ошибок ? Возможно разработчик никогда не сталкивался с этим. Варианта 2 - либо "лепил мини-игры-баннеры", либо флексил на простом уровне.
ФПС 24, а зачем 40 ?
new MovieClip(atlas.getTextures("boom_"), 40);

Тестовое задание - убойное, честно говоря. Но ту реализацию, что есть в исходнике, - реально за 1 день можно сделать.
Ничего из дополнительных тасков не реализовано.

Isfet
06.07.2015, 08:40
1. мало опыта в МВЦ


спасибо, про мвц уже понял, разбираюсь, про интерфейсы тоже буду читать.


3. Не гуглит - не заюзал всем известные решения типа isolib

естественно искал готовые решения, но работодатель сказал не юзать isolib.


4. а зачем 40 ?
new MovieClip(atlas.getTextures("boom_"), 40);


взрыв был слишком долгий, из атласа текстуры не стал выпиливать.