То-ли движок ради рогалика... то-ли рогалик ради движка...

Закрытые или заброшенные проекты, не состоявшие в Клубе, но имевшие ветку на форуме.

Модератор: Jolly Roger

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 02 май 2010, 12:01

Jolly Roger писал(а):
Yozka писал(а):Книжка "совершенный код" - убивца рогликоф. нинадо ее читать!! :lol:
Страшная книга, сколько рогаликов она убила на RLG? :lol: Употреблять в терапевтических дозах.
а я залпом... :lol: до отладки(на 527 стр. остановился) на одном дыхании.
Сильная книжка :) и главное легко читается :) (не то что стоящая на полочке "Дискретная математика для программистов" той 2 страницы прочитаешь потом месяц мозги из трубочки разворачиваешь :D )
Так по ходу дела возникли вопросы такого плана (вот думаю создать отдельную тему или тут).

1. Обработка клавиатуры.
как правильнее обрабатывать нажатие нескольких клавиш?
ну с фукциональными клавишами вроде понятно ALT+A не равно ALT и A по отдельности.
разрешать ли возможность щелкать только фукнциональную клавишу типа правый CTRL что-бы она выполняла сама какие-то действий.
Разрешать ли сочетания буквенных клавиш типа A+B не равно по действию A и B по отдельности.
или A+B будет сразу вызывать 3 действия, то которое по нажатию A то которое по нажатию B и то которое по нажатию обоих клавишь.
или вообще запретить сочетания не с функциональными клавишами? т.е. оставить только возможность сочетаний типа "Right CTRL + Left CTRL + Shift + D"
исключить возможность "Left+Up" или "Y+H" (ну не полностью просто Left+Up будет одновременно равно 3 действиям Вверх влево и Вверх-Влево при чем так-как работает обработчик может получится что будет только Вверх влево (без вверх-влево))

Далее нужна ли маленькая задержка перед нажатием клавиши (100-200 мс) (в принципе это нужно только если оставить возможность A+B) человек не идеален и одновременно не может нажать 2 клавиши что-бы исключить это можно перед нажатием клавиш ввести задержку.

к чему эти вопросы :) мой обработчик клавиатуры имеет некоторые особенности которые надо лечить, а лечить их надо в зависимости от того что я решу важным.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 02 май 2010, 12:14

Теперь нужен совет тех кто Наследование хорошо понимает.

Думается создать класс "Игровой объект".
От него наследовать 2 класса:
"Монстры" и "Предметы"
От Класса "Монстры" всех монстров и главного героя.
От Класса "Предметы" Унаследовать еще 4 класса
1. Недвижимые (Стены\Ловушки\Двери\Лампочки\ и т.д.)
2. Надеваемые (Броня\Оружие\ и т.д.)
3. Используемые (Бутыльки\Свитки\ и т.д.)
4. Неразрушимые (Стены\Ловушки\ и т.д.)
Вот далее каждый предмет наследовать из нужных категорий.
(типа броня Надеваймая. Катапульта :D Надеваймая(условно) и Недвижимая там какой-нить мечь который кроме оружия может как-то иначе использоватся Надеваемый и используемый).
Вот теперь вопрос! :)
А есть способы как это реализовать с возможностью подгружать предметы из файла, а не хранить классами вшитыми в коде?

Аватара пользователя
Харука-тян
Мастер
Сообщения: 544
Зарегистрирован: 29 ноя 2006, 00:23
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Харука-тян » 02 май 2010, 12:59

Элементарно: сделай конструктор, который будет вытаскивать из файла данные по переданному идентификатору. А каждый тип объектов пусть свои данные и тащит.
"Женщина верит, что дважды два будет пять, если хорошенько поплакать и устроить скандал" (© Дж. Элиот).
ИзображениеИзображение

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 02 май 2010, 13:53

Харука-тян писал(а):Элементарно: сделай конструктор, который будет вытаскивать из файла данные по переданному идентификатору. А каждый тип объектов пусть свои данные и тащит.
Либо я не понял ответа. либо меня не поняли.

хочу:

я в файле храню что-то типа
[unmovable][usable]
[name:Flare]

и т.д.

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

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение kipar » 02 май 2010, 14:04

Jesus05 писал(а):объект наследованный от непередвижимого класса и от используемого класса.
Насколько я знаю, от классов наследуются классы. Объект может принадлежать к какому-то классу, а не наследовать, тем более у двух сразу.
Так что Харука-тян все правильно говорит:
хранишь в файле:
1. Или так:
[usable]
[name:Flare]
(Если факел - не отдельный класс, а объект)
2 Или так:
[Flare]
[Color=...]
(Если факел - класс, а объекты могут иметь разные свойства)

При считывании сначала считается имя класса (в первом случае usable, во втором - Flare), потом этот класс считает дополнительные данные (в первом случае имя, во втором - цвет).

Аватара пользователя
Aerton
Сообщения: 503
Зарегистрирован: 11 авг 2007, 02:58
Откуда: Новосибирск
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Aerton » 02 май 2010, 14:13

Если ты хочешь создать новый класс на лету, то в С++ это невозможно.

Если же просто загрузить данные объекта одного из существующих классов, но просто неизвестно какого, то Харука правильно говорит. Можно ещё почитать про паттерны "фабрика" и "абстрактная фабрика". И наследование тут не при чём.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 02 май 2010, 15:24

Aerton писал(а):Если ты хочешь создать новый класс на лету, то в С++ это невозможно.
Да. ясно. :) про фабрику читал... правда не сильно внимательно.
буду думать... :) но вообще сообщение про обработчик клавиатуры был важнее :)

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 02 май 2010, 15:42

Я правильно понимаю что тогда у меня 2 способа действовать.
1. Создать класс у которого будут указатели на все нужные мне классы
типа

Код: Выделить всё

class trashcan
{
  Unmovable *pUnmovable;
  Usable    *pUsable;
  Wearable  *pWearable;
  Destroy   *pDestroy;
}
и либо создаю "заглушки" на не используемые указатели а используемые подгружаю.
2. Создаю все варианты классов и при загрузки выбираю тот который подходит

Код: Выделить всё

class UnMove : public Unmovable;
class UnMoveUsable : public Unmovable , public Usable;
class UnMoveUsableDestroy : public Unmovable , public Usable, public Destroy;
class ....
либо в базовом классе (GameObject) реализую весь функционал и строчу заглушки в тех методах которые не будут использоватся у "не используемых" "не движимых" "не одеваемых".

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение kipar » 02 май 2010, 18:58

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

Насчет обработки клавиатуры - а зачем эти сложности с управлением типа А+Б. Насколько нужны они будут при игре?
Имхо достаточно оставить обработку только комбинаций с Alt, Shift, Ctrl (причем не различая левый и правый). Если более сложная обработка клавиш чем-то оправдана, то расскажи чем. Идеального варианта нет, все зависит от задачи.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 03 май 2010, 05:53

kipar писал(а):Насчет обработки клавиатуры - а зачем эти сложности с управлением типа А+Б. Насколько нужны они будут при игре?
Имхо достаточно оставить обработку только комбинаций с Alt, Shift, Ctrl (причем не различая левый и правый). Если более сложная обработка клавиш чем-то оправдана, то расскажи чем. Идеального варианта нет, все зависит от задачи.
Ничем не оправдана, такова была первоначальная идея. (да и вообще хотелось бы написать себе на будущее класс обработки клавы, что-бы потом его везде юзать, и расширять, сделать его мультиплатформенным.)
а насчет левого\правого обработчик от винды (на других платформах не знаю как будет) при нажатии правого шифта получает 2 кода. код шифта и код правого шифта т.ч. они как бы вместе идут и это не накладывает больших сложностей.

Спасибо за ответ :) мне нужно было хотя-бы 1 не мое мнение :) что-бы начать переделку обработчика :)

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Yozka » 03 май 2010, 06:04

не первый не второй вариант не подходит.
В первом варианте, нет масштабируемости, новый класс без переписки кода не добавить.
Второй вариант. наплодить кучу классов, что есть нехорошо.
Я бы сделал следующие.
Написалбы обстрактный базовый класс

Код: Выделить всё

class CObject
{
  public:
  void add(CObject * aObj);//добавить привязку к объекту

  /* базовые методы объекта
  */
  virtual void draw(...);
  virtual void move(..);
  ...

  private:
  CObject * aNext;//следующий привязанный класс

}

void CObject::add(CObject * aObj)
{
   if (aNext)
   {
       //если класс уже привязан, то передадим другому
       aObj->add(aObj);
       return;
   }
   aNext = aObj;
}

Код типа токой, тобишь есть метод add(CObject * aObj) он привязывает к одностороннему внутреннему списку некий объект.
далее, исопльзовать можно вот так

CObject * obj = new CObject;
obj->add(new CObjectArmor);//добавим в список объекта амуницию
obj->add(new CObjectMove);//объект может перемещатся
...

далее отрисовываем вот так:
obj->draw(...);

в базовом методе

Код: Выделить всё

CObject::draw()
{
   //делаем
   //отрисовываем базовые картинки
   //далее по списку вызываем другие драв методы
   if (aNext)
   {
       aNext -> draw();
   }
}
ну это только идея.
Нужно решить еще ряд вопросов, это при деструкторе объекта, чтобы удалялись следующие по списку объекты.
Нужен сделать внутренний индификатор объекта, чтобы фабрика классов (которая создает объекты) могла точно знать что ей какой класс создовать.
Ну и нужно грамотно описать базовый абстрактный клаасс. чтобы туда больше нелезть.
--
что делать когда есть некий класс потомок, у которого ессть совершенно космичесткие методы которые есть только у этого потомка а у другого нет?
МОжно сделать так. пробежатся по всему списку, найти по индификатору объект "CObjectCosmos" привезти его к типу CObjectCosmos, и выполнить у него метод CObjectCosmos::superGood();
Будет лучше, если этот функционал по поиску нужных функций в нужных объъектов завернуть в некий класс под именим execFunction;
тобишь, в итоге можно получить следующие

CObject * obj = new CObject;
obj->add(new CObjectArmor);//добавим в список объекта амуницию
obj->add(new CObjectMove);//объект может перемещатся
obj->add(new CObjectCosmos);//космическая поебень

....
new execFunction_superGood(obj); //выполняем функцию космической поебени
//тоесть execFunction бежит по всему списку объекта, ищет там нужный класс и дергает для него функцию супергуд.
..
типа так.

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение kipar » 03 май 2010, 06:27

Jesus05 писал(а):а насчет левого\правого обработчик от винды (на других платформах не знаю как будет) при нажатии правого шифта получает 2 кода. код шифта и код правого шифта т.ч. они как бы вместе идут и это не накладывает больших сложностей.
Главное чтоб пользователю было удобно. А ctrl-в и alt-в для того два и сделано, чтоб можно было нажимать тот, который ближе. Так что привязывать какую-то функцию к только правому или только левому альту есть смысл только если это управление настраиваемое и в раскладке по умолчанию такой фичи все равно не использовать.
Yozka писал(а):Я бы сделал следующие.
Красивый вариант. Правда выглядит как костыль для замены множественного наследования, но если главная задача в том, чтобы получить возможность наследования от любых комбинаций классов, то так, наверное, будет лучше, чем много пустых классов заглушек во втором варианте. Второй вариант лучше если эти комбинации заранее известны - т.е. если мы объявляем классы Оружие, факел, дверь -> поворотная дверь, то от кого они будут наследовать нам ясно сразу и потому эти списки не нужны.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 03 май 2010, 06:31

kipar писал(а):В базовом классе функционала потомков быть не должно, это факт. Если кроме этих четырех фич других ТОЧНО не будет, то можно юзать вариант 1, иначе я бы посоветовал второй.
Другие фичи могут быть.
kipar писал(а): Его плюс в расширяемости - всегда можно добавить новый класс, не трогая старых. Тем более все комбинации UnMoveUsableDestroy не понадобятся - можно добавить только те, которые реально используются.
да не, придется все :) иначе как потом добавлять в файл предметы если для них не готов класс.

Аватара пользователя
Yozka
Сообщения: 127
Зарегистрирован: 29 июл 2008, 06:42
Откуда: Тюмень
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Yozka » 03 май 2010, 06:53

Множественное наследование это ЗЛО.
Вообще наследование это зло, нужно использовать только там где оно действительно неообходимо. 3 - 4 потомка это норма, но когда их штук 10... да ище с виртуальными функциями. Компилятор такие "пирамиды в коде строит", распухает таблица виртуальных функций, вся производительность идет втран тарары.
Мне вот интересно, как поведет себя компилятор, когда есть базовый объект, с виртуальными функциями например draw() далее от этого объекта идут множество других...
а потом это множество других сливается в один класс... компилятор не даст это сделать. ибо он не сможет слинковать виртуальныую функцию draw().

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: То-ли движок ради рогалика... то-ли рогалик ради движка...

Сообщение Jesus05 » 03 май 2010, 06:56

Yozka писал(а):не первый не второй вариант не подходит.
В первом варианте, нет масштабируемости, новый класс без переписки кода не добавить.
Второй вариант. наплодить кучу классов, что есть нехорошо.
Я бы сделал следующие.
Написалбы обстрактный базовый класс
......
а этот вариант лично мне кажется слишком сложным :( (не момещается в мозг)
да и типов думаю не будет более 10.
(хотя и 10 типов при всех вариантах комбинаций наплодят............. в подсчетах дошел до цифры 370 :( и решил на этом остановится)

так второй вариант мне уже меньше нравится :oops:
а чем плох первый вариант.
Фактически мы имеем 1 класс который содержит указатели на все возможные подклассы. реализовать в нем методы

Код: Выделить всё

bool IsMovable() {return pMovable!=NULL;}
и перед вызовом функции для перемещений\использования\одевания, вызвать этот метод если он вернет "правда" то использовать метод

Код: Выделить всё

if (trashcan->IsUsable())
{
  trashcan->pUsable->Use()
}
else
{
  //вывести сообщение игроку что этот предмет нельзя использовать
}
тем кто будет вызывать должно быть паралелно добавление новых указателей в этот класс которыми они пользоватся не будут.

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость