09.01.2019, 15:15
|
|
Интересующийся
|
|
Регистрация: 09.01.2019
Сообщений: 14
|
|
Дурак Навсегда!
Доброго времени суток, ув. гуру, и новички, и просто интересующиеся JS. Посоветуйте, как быть. Хочу написать несколько приложений на JS. Но практически никогда не доводилось с этим сталкиваться. Поэтому даже не представляю толком, как это может выглядеть.
Хотелось бы написать приложения и разместить их на своем сайте + возможно что-то закинуть в ВК и на ФБ и т.д. Может даже Google.Play и тому подобное. То есть хотелось бы распространять код, совершенствовать и дорабатывать.
Я видел - такие вещи часто делают на классах и прототипах, но не понял, как это применить. Еще слышал что-то про MVC, но не осилил пока что.
В связи с этим набросал примерный план приложения, на примере наверное всем знакомой игры "Дурак", как я себе это представляю Ну, на самом деле не суть, что за приложение. Самое главное - что вы можете сказать об этом в целом?
Я просто использовал объекты, чтобы разделить на смысловые части методы и функции. Это вряд ли можно назвать ООП Но все-таки:
- Это нормальный рабочий подход?
- В принципе можно и так?
- Это бред и надо все делать по другому?
Если все плохо, то где можно увидеть нормальный пример, как надо? Может, посоветуете книгу или курс какой-то или еще что-то? Или может, есть у кого ссылка на не очень сложный готовый пример? Может, есть шаблоны какие-то для таких целей?
Короче, что можете сказать и посоветовать такому нубу как я?))
/* ======================================== */
/* ========== Глобальный объект =========== */
/* ======================================== */
var game = {};
/* ======================================== */
/* ================ Колоды карт =============== */
/* ======================================== */
game.deck = {};
game.deck.bot = [];
game.deck.user = [];
game.deck.desk = [];
game.deck.out = [];
game.deck.all = [
[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9],
[2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9],
[3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6], [3, 7], [3, 8], [3, 9],
[4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [4, 9]
];
/* ======================================== */
/* ============== Методы колоды =============== */
/* ======================================== */
game.cards = {};
// Создать новую колоду
game.cards.create = function(){};
// Перетасовать колоду
game.cards.shuffle = function(){};
// Выбрать случайный козырь
game.cards.trump = function(){};
// Добавить карту в колоду
game.cards.add = function(card, to){};
// Удалить карту из колоды
game.cards.del = function(card, from){};
// Переместить карту из одной колоды в другую
game.cards.move = function(card, from, to){};
// Найти наименьшую карту из колоды
game.cards.min = function(from){};
// Отсортировать карты по масти и достоинству
game.cards.sort = function(){};
// Положить карты в аут
game.cards.out = function(){};
/* ======================================== */
/* ================ Методы игрока ============== */
/* ======================================== */
game.user = {};
// Ход игрока
game.user.go = function(e){};
// Подкинуть карту
game.user.next = function(){};
// Ответить
game.user.ansver = function(){};
// Бито
game.user.out = function(){};
// Предложить боту ничью
game.user.draw = function(){};
// Сдаться
game.user.giveUp = function(){};
/* ======================================== */
/* ================ Методы бота =============== */
/* ======================================== */
game.bot = {};
// Ход бота
game.bot.go = function(){};
// Бот подбрасывает карту
game.bot.next = function(){};
// Бот отвечает
game.bot.answer = function(){};
// Бито
game.bot.out = function(){};
// Бот предлагает ничью
game.bot.draw = function(){};
/* ======================================= */
/* =============== Рендер =================== */
/* ======================================= */
game.render = {};
// Отобразить изменения
game.render.cards = function(){};
// Анимация передвижения карты
game.render.animation = function(){};
// Обновить игровой счет
game.render.score = function(){};
// Вывести актуальные сообщения
game.render.message = function(){};
// Отобразить актуальные кнопки ('Взять', 'Бито', 'Сдаться' и т.д.)
game.render.ui = function(){};
/* =================================== */
/* ============ Состояние игры ============ */
/* =================================== */
game.state = {
trump : undefined,
score : 0,
}
game.state.checkWin = function(){};
game.state.win = function(){};
game.state.loose = function(){};
/* ======================================= */
/* ========== DOM элементы (интерфейс) ========== */
/* ======================================= */
game.dom = {
'wrapper': undefined,
'trump': undefined,
'user': undefined,
'bot': undefined,
'out': undefined
}
// Получить DOM-элементы в переменные
game.dom.query = function(){};
/* ===================================== */
/* =============== Настройки ============== */
/* ===================================== */
game.setting = {
shirt: 'grey',
music: 'play',
musicVolume: 0.5,
animation: true
};
game.setting.load = function(){};
game.setting.display = function(){};
game.setting.apply = function(){};
game.setting.save = function(){};
/* ===================================== */
/* ============== Сохранение ============== */
/* ===================================== */
game.save = function(){};
game.list = function(){};
game.load = function(){};
/* ==================================== */
/* ============ Инициализация++ =========== */
/* ==================================== */
game.app = {};
game.app.start = function(){};
game.app.preloader = function(){};
game.app.init = function(){
game.app.preloader();
game.dom.query();
game.cards.trump();
game.cards.shuffle();
game.app.start();
}
game.app.replay = function(){};
game.app.pausePlay = function(){};
game.app.exit = function(){};
/* ====================================== */
/* ================ Старт ================= */
/* ====================================== */
window.onload = function() {
game.app.init();
}
/* =================================== */
/* ======== Вспомогательные функции ======== */
/* =================================== */
function genRnd(min, max) {
var rand = Math.floor(Math.random() * max - min + 1) + min;
return rand;
}
|
|
09.01.2019, 17:12
|
|
Интересующийся
|
|
Регистрация: 09.01.2019
Сообщений: 14
|
|
SuperZen,
Спасибо за ответ.
Как я понял, как ни крути, а в современном мире для этого нужно учить фреймворки. В принципе я чувствовал подставу... что что-то здесь не так . Что на голом JS и с таким подходом вряд ли что-то нормальное получится.
|
|
10.01.2019, 00:07
|
Аспирант
|
|
Регистрация: 06.02.2011
Сообщений: 54
|
|
VооDоо,
Если я правильно понял вас, могу посоветовать, постараться понять что именно не нравится вам в вашем коде и почему, так же при этом максимально абстрагироваться от самого языка как ЯвыСкрипта так и любого другого и уж темболее от фреймворков. Постараться выделить важное, фундаментальное в коде, то что менять будет сложнее всего, и то что второстепенное. На счет книг, опять же если я правильно понял ваше затруднение, могу посоветовать Фредерик Брукс "как создаются программные системы". И лекцию на ютубе Архитектура ПО там кстати что то подобное MVC упоминалось, хотя MVC не суть.
|
|
10.01.2019, 13:04
|
|
Интересующийся
|
|
Регистрация: 09.01.2019
Сообщений: 14
|
|
RX200,
Спасибо за дельные советы, буду смотреть.
Мне не нравится в моем коде то, что будет очень много функций. Смотрите, даже в таком небольшом проекте, как выше - будет наверно около 60-100 функций. Они, конечно, сгруппированы на смысловые блоки, что уже неплохо. Но все-таки, все эти функции будут вызывать друг друга, передавать разные параметры, что-то принимать и возвращать. Взять хотя бы этот фрагмент как пример:
game.app.init = function(){
game.app.preloader();
game.dom.query();
game.cards.trump();
game.cards.shuffle();
game.app.start();
}
При инициализации приложения уже вызывается масса функций из разных частей кода. И когда все 100 функций вот так начнут друг друга вызывать, передавать самые разные параметры, что-то возвращать, плюс появится куча разных флагов и состояний (которые хранятся везде)... код станет вообще неудобоваримым. А если приложение еще больше? В итоге получится код, в котором трудно будет найти какие-то концы. На самом деле это просто большой набор функций и все...
В связи с этим и возникает вопрос - что делать? Наверное существуют способы писать по нормальному. Что это за способы?
Фреймворки, которые SuperZen советует, думаю - реальный выход. Возможно, стоит еще разобраться все-таки с MVC. Возможно, что это также может помочь.
|
|
10.01.2019, 15:04
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,794
|
|
VооDоо, чего вы к MVC прицепились, как она вам тут поможет - я не представляю.
Попробуйте сначала описать модели вашей игры: User, Deck, Card, etc.
Карта (Card) хранит только описание карты.
Пользователь (User) хранит описание игрока и список карт, которые ему принадлежат.
Бот может наследоваться от Пользователя, если он вообще тут нужен.
Колода содержит список карт, которые могут быть присвоены игрокам.
После того, как опишите модели, добавьте им необходимые методы для управления вложенными сущностями. Например для колоды нужно реализовать метод shuffle, который перемешает принадлежащие ей карты, методы "push" (добавить) и "remove" (извлечь).
Как закончите с моделями, пишите классы, которые будут отвечать за логику игры.
Должно получится удобнее, чем когда все в одной куче.
|
|
10.01.2019, 19:23
|
|
Интересующийся
|
|
Регистрация: 09.01.2019
Сообщений: 14
|
|
Nexus,
Спасибо за советы. Видимо что-то подобное мне и нужно.
То есть как я понял, лучше сделать более ярко выраженные сущности, вместо набора функций.
Причем появилась мысль, что часть методов можно скрыть (инкапсулировать). Допустим, есть три метода для колоды:
1. push (добавить в колоду);
2. remove (удалить из колоды);
3. move (переместить из одной колоды в другую);
Они неравноценны, поскольку метод move использует два других. И эти два мне "снаружи" не нужны. Мне нужно только перемещать карту из одной колоды в другую. Получается как по учебнику, есть публичные и приватные методы (сам не понял, почему раньше до этого не додумался, хотя все известно давным давно).
Другая идея - после того как будут выписаны все эти сущности с данными и методами, их можно сохранить в отдельный файл. А логику писать уже в другом файле.
В итоге будет разделение на три слоя: скрытый, публичный и логика. Так должно быть легче по идее, чем когда все в одном.
В общем смутно уже начинает что-то проясняться....
|
|
11.01.2019, 07:13
|
Аспирант
|
|
Регистрация: 06.02.2011
Сообщений: 54
|
|
VооDоо,
Вы в правильном направлении, важно задаваться вопросом при написании сущностей, что она должна знать а чего знать не должна, в идеале каждая сущность знает только свои методы, а между ними менеджер который соединяет в одно целое все сушьности, например бот ни чего не знает о визуализации, он только сообщает некоторое действие, а визуализация в свою очередь ни чего не знает о том кто и зачем ей что то сообщил, так как бот ни чего не знает о визуализации он не может напрямую ей что то сообщить, и тут важно понять структуру программы кто что знает и с кем взаимодействует, одно из решений это и есть MVC.
|
|
12.01.2019, 14:37
|
|
Интересующийся
|
|
Регистрация: 09.01.2019
Сообщений: 14
|
|
RX200,
скорее всего в этом и заключается большая часть проблем. Но как реализовать менеджер-посредник?
Есть идея создать центральный объект, который будет выполнять функцию посредника и установить ему геттеры и сеттеры. Тогда, при изменении какого-либо поля, можно запускать произвольную функцию и дальше от этого отталкиваться. Небольшой пример:
var game = {
score: 0
};
game.state = {
get score() {
return game.score;
},
set score(val) {
console.log('setter');
game.score = val;
}
};
На строке 11 вызывается console.log() при изменении поля game.score. Вот это и можно попробовать использовать. Функции (или даже целые блоки-модули) будут взаимодействовать через один объект, что должно помочь.
Еще идея - для управления состояниями реализовать конечный автомат. Все же это будет лучше, чем хранить состояния где-то в виде флагов и потом if-ами проверять.
Посмотрим, что получится...
Последний раз редактировалось VооDоо, 12.01.2019 в 14:40.
|
|
12.01.2019, 23:40
|
Аспирант
|
|
Регистрация: 06.02.2011
Сообщений: 54
|
|
VооDоо,
То что менеджер соединяет все в целое и только он знает всех, это некий теоретический идеал на практике не совсем так, особенно для небольших проектов.
У вас в коде не совсем проявлены сущности, например переменная score это глобальная переменная игры, почему она глобальная, если я правильно понимаю она должна быть в Модели, дальше state это менеджер, которому известно об этой переменной? А нужно ли менеджеру напрямую знать об этой переменной? Какие задачи тогда у менеджера? Можем ли мы частично передать задачи менеджера модели, или визуализации? Или будем строго осуществлять взаимодействие Модели с Визуализацией через менеджера? Все это вопросы структуры программы, на которые лучше ответить до написания самого кода. Я бы к разработке игры дурака подошел так, есть три больших сущности Визуализация, Контроллер, и Модель, Визуализация должна уметь, 1. отображать начальное меню, где пользователь сможет задать некоторые настройки, например сколько игроков, какая колода 52 или 36, ну и любые другие. 2. Ситуацию игры за столом. 3. итоги игры. Далее Контроллер, должен сообщать(ответ) визуализации что отображать, и принимать(запрос) от пользователя через кнопки визуализации действия, события. То есть Визуализация ни чего не знает о Контроллере, лишь то что у неё на кнопках весят методы Контроллера, то есть пользователь по сути общается с Контроллером. При начальной загрузке, onload, контроллер как то должен понять что начало игры, и сказать Визуализации отобрази начальное меню, далее пользователь что то вводит, например 100 игроков, и нажимает начать игру. Контроллер принимает входные данные, тут надо решить кто будет проверять на соответствие входные данные, и сообщит что например что 100 игроков это много, может в самой визуализации уже будут стоять ограничения на вводимые данные, или контроллер, или модель, я бы все игровые моменты предоставил обрабатывать Модели, соответствие формату данных Контроллеру. Например если пользователь введет в поле количество игроков текст не число тут контроллер на такой запрос сообщает что бы визуализация отобразила ошибку, а количество игроков пусть обрабатывает Модель, вдруг у неё колода из миллиона карт. Дальше Контроллер не должен знать Модель вообще, какая там колода, какие игроки, какой бот, он должен знать только программный интерфейс Модели, который она предоставляет для взаимодействия с ней. Например получил Контроллер запрос от игрока СтартГаме(4 игрока), отправляет его Модели, Модель отвечает все норм, столько то карт роздано, козырь такой, у игрока который пользователь карты такие, ход его, Контроллер говорит Визуализации скрыть стартовое меню, отобразить игровой стол с такими то игроками, с такими то возможными действиями пользователя, Пользователь делает действие, посылая запрос контроллеру, контроллер проверяет соответствует ли действие формату, так как если на РНР пишем программу, какойнить хакер, вместо действия может отправить запрос совсем иного рода, вобщем Контроллер передал действие Модели, модель смотрит какой игрок должен ответить, смотрит дальше если игрок не пользователь, сообщает, ситуацию боту, причем бота достаточно одного на всех игроков, его задача принимать ситуацию и давать на неё ответ, ответ записывается в действие игрока, новая ситуация за столом передается от Модели Контроллеру, и он Передает её Визуализации, Пользователь смотрит принимает действие, и так по кругу.
Вот как то так я это вижу, суть в том что во первых я максимально абстрактно описал, структуру программы, не зависимо от языка, или фреймворков. Во вторых, одна сущность взаимодействует с другой, не на прямую меняя её переменные, переменные сущности это её личное дела, а через предоставляемый ею интерфейс. В общем глобальные переменные для структуры MVC как мне кажется не хорошо, ваша глобальная переменная игры score если её можно отнести к какой то сущности то лучше так и сделать.
Так же может вам будет интересно почитать MVC для веб
И видео Архитектура и проектирование ПО
|
|
|
|