[Лог #1] Немного кода.

Добавлен , опубликован
Извиняюсь за не столь содержательный заголовок

ТЕМА: КОД

Генерация предметов

Весьма странно начинать лог разработки не рассказав об игре хотя бы двух слов, да ещё и издалека — предметы и инвентарь.
Будет затронута только программная часть т.е. без графики, а всю информацию будем выводить в консоль. В конце лог-статьи будет приведён код на языке С++.
А теперь приступим :)

Характеристики

Для начала определить структуру предмета необходимо… или же нет?
На самом деле, следует знать зачем эти всякие предметы нужны и на что они влияют, но тут ответ более-менее ясен — характеристики персонажа, но вот что это за характеристики? Это и следует обозначить.
// Характеристики
struct sAttributes
{
	short health;		// Здоровье
	short shield;		// Щит
	short defence;	// Оборона (глушитель урона)
	short damage;	// Урон
};
Если Вам знаком синтаксис языка Cи, то вопросов возникнуть не должно, а для тех кто «не в теме», следует пояснить кое-что, но не углубляться в подробности: (лучше найти информацию в интернете, а то я плохо объясняю)
struct название_структуры
{
	тип переменная;	// комментарий
};
Теперь у нас есть структура определяющая характеристики.
Можно завести структуру и для персонажа, затем для предмета, но лучше не спешить и немного подумать.

Описание предмета

Каждый предмет в игре лучше «зарегистрировать» т.е. записать их в особый список, который будет хранить всю «статичную» информацию о предметах ( характеристики, например ).
А оперировать в инвентаре будем с более простой структурой предмета, которая будет ссылаться на информацию предмета в списке.
// Качество
enum eQuality
{
	EQ_COMMON   =0,	// Обычный
	EQ_STANDARD =1,	// Стандартный (в чём отличие от обычного?)
	EQ_HANDMADE,	// Самопальный
	EQ_LEGENDARY,	// Легендарный
	EQ_EPIC,		// Эпичный

	Count_Quiality	// так узнаем кол-во
};

// Тип предмета, если установлен в OTHER, то может быть произвольный
enum eKind // TYPE
{
	Kind_WEAPON = 0,	// Оружие
	Kind_ARMOR,			// Броня
	//Kind_POTION,
	Kind_OTHER
};

// Бит-флаги предмета
enum eItemFlag
{
	IF_CLEAR			= 0x0000,	

	IF_EQUIP			= 0x0001,	// Можно экипировать
	IF_COLLECTABLE	= 0x0002,	// Занимает один слот, записывая кол-во
	IF_USABLE			= 0x0004,	// Можно использовать
	IF_QUEST			= 0x0008	// Предмет, необходимый по сюжету\квесту (нельзя выбросить, слот не учитывается)
};

// Описание предмета для глобального списка
struct sItemDescription
{
	// Уникальный ID
	unsigned long	ID;

	string		 name;	// название предмета для отображения
	string		 desc;	// описание
	sAttributes	 attrib;

	eQuality	qual;	// качество
	eKind		kind;	// тип
	long		 falgs;	// бит-флаги
	
	// Визуальная информация
	int			modelID;	// номер 3Д модели
	int			textureID;	// номер текстуры для 3Д модели
	int			pictureID;	// номер картинки\текстуры\иконки для отображения в инвентаре
	// Цена предмета, можно задать вручную или же воспользоваться специальной функцией
	int	cost; 
};
- Эй! Что такое unsigned long, string и eQuality ?
unsigned означает, что наша переменная имеет исключительно положительное значение (для целочисленных типов).
long - аналогично как и short, однако, занимает больше памяти и следовательно может иметь больше значений.
string - тип описывающий строку текста (из стандартной C++ библиотеки).
eQuality и eKind - перечисления.
Код, возможно, кого-то испугает, но на самом деле всё очень просто.
Мы имеем структуру описания предмета - это означает, что используя этот "бланк" можно будет обозначить любой предмет в игре.
Вот пример такого определения:
sItemDescription SuperSword;
SuperSword.ID = CurID++; // Для каждого предмета считается свой ID
SuperSword.name 	= 	"Супер меч";
SuperSword.desc 	= 	"Лишь избранный может нести его";

SuperSword.attrib.health		= 0;
SuperSword.attrib.shield		= 0;
SuperSword.attrib.defence	= 0;
SuperSword.attrib.damage	= 20;

SuperSword.kind		= Kind_WEAPON;	 // Тип "оружие"
SuperSword.qual		= EQ_LEGENDARY;	 // Качество предмета как "Легендарный"
SuperSword.falgs	= IF_EQUIP;			 // можно экипировать

SuperSword.cost = ItemCost( SuperSword ); // Вычислим стоимость предмета
И это очень простой предмет, а представьте если их, скажем, 20 .. это же жуть их так все описывать, поэтому напрашивается идея генерации этих самых предметов. Разумеется представленный мой способ не очень, но надо же начать с чего-то :)

Генератор

Это функция, принимающая в качестве аргумента требования к процедурному предмету (смотри ниже).
sItemDescription GenerateItem( const sItemGenerationDesc &gendesc )
{
	sItemDescription desc;

	desc.ID = CurID++;

	desc.kind = gendesc.kind;
	desc.qual = gendesc.quality;

	desc.attrib.health = 0;
	desc.attrib.defence = 0;
	desc.attrib.damage = 0;
	desc.attrib.shield = 0;

	if( desc.kind == Kind_WEAPON )
	{
		desc.name = QualityToString(desc.qual) + " " + weapons_names[ RandomRange(0,weapons_names_count) ];
		// Лихо рассчитываем параметр используя качество, начальное значение и великий рандом 
		desc.attrib.damage = gendesc.attribs_ranges.damage + ((int)desc.qual) * RandomRange( 0, 4 );
	
		desc.falgs = IF_EQUIP;

	}else
	if( desc.kind == Kind_ARMOR )
	{
		desc.name = QualityToString(desc.qual) + " " + armor_names[ RandomRange(0,armor_names_count) ];
		desc.attrib.shield = gendesc.attribs_ranges.shield + ((int)desc.qual) * RandomRange( 0, 2 );
		desc.attrib.defence = gendesc.attribs_ranges.defence + RandomRange( 0, 2 );
		desc.falgs = IF_EQUIP;
	}

	desc.cost = ItemCost( desc ); // Вычисляем цену
	desc.desc = "Этот предмет сгенерирован программой"; // описание описания, извините за тавтологию 
	
	return desc;
}
А что-то за структура sItemGenerationDesc ?
struct sItemGenerationDesc
{
	eQuality		quality;			// Качество, которое мы хотим дать предмету
	eKind		kind;			// Тип предмета - оружие, броня или может ещё что
	sAttributes	attribs_ranges; 	// Разброс по атрибутам или их начальное значение
};
Таким образом, можно манипулируя тремя параметрами получить различные предметы.
Должен заметить, что с названием предметов есть неприятный момент, например, такой - "ЭПИЧНЫЙ труба" ... такое можно исправить, но это уже на будущее :)
Вот скриншот с консоли программы, демонстрирующие генератор предметов:
Можно скачать код или посмотреть.
Безусловно этот код изменится, ведь данная программа больше написана для тестирования.
Это первая статья из цикла, поэтому принимаю различные предложения по улучшению подачи контента )
Хотелось бы разрабатывать игру не просто для себя, а совместно с сообществом.

Что дальше?

На радаре концепт арты врагов! Если не терпится посмотреть на них, то можете разыскать их на сайте стопгейм.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
28
9 лет назад
0
мне кажется или автор не верит в инкапсуляцию
0
21
9 лет назад
Отредактирован Editor
0
Praytic:
А чего плохого в написании игры на плюсах? Мне правда интересно, ибо я пока только этот язык и изучаю.
Да ничего там плохого, на них написаны дум3 и хл2 )
Просто костыли везде разные.
2
28
9 лет назад
2
Praytic, мне не нравится адресная арифметика и то что код читается по порядку
проще говоря этот код работать не будет :
void A0(){}

void A1(){
A0();
A2();
}

void A2(){}
да и у функций такие имена что хочется удалить c++
2
20
9 лет назад
2
ну а как на счет прототипизации в головном файле?
2
14
9 лет назад
2
Doc: Писать игры на с++ канеш смело (и глупо имхо), движок для графона уже подобрал?
Слабоумие и отвага - двигатель прогресса! Я тоже на C++/DirectX/Lua пишу - с каждым годом разработки всё отчётливей понимаю, что сделал правильный выбор. :D
0
34
9 лет назад
0
"легендарный труба"
ЭЙ! какОй у тебя легендАрный трубА!
0
15
9 лет назад
0
PhysCraft:
Генератор будет меняться, спасибо за некоторые идеи )
Да, вся игра будет на Си++.
Doc:
Писать игры на с++ канеш смело (и глупо имхо), движок для графона уже подобрал?
Ну это кому как) Графон? Не не гонюсь за супер графикой, всё что будет необходимо проекту можно написать самому - это же весело! Эксперименты и всякое такое )
lentinant:
Интересно, надо будет это запомнить)
nvc123:
Я старался показать более простой код. Решил попробовать метод "сделай проще", зачем мне вся мощь ООП, если я её использовать не буду?
Порядок функций, как заметил Praytic , решается прототипами функций в заголовочном файле.
Слабоумие и отвага - двигатель прогресса!
А то! :)
0
29
9 лет назад
Отредактирован Doc
0
Не, я наверное неправильно выразился частично, в голове одно, а пишу слегка другое. Писать МАЛЕНЬКИЕ/инди игры на С++ - глупо, как я считаю. Это просто не нужно, больше борьбы с инструментом, чем собственно делания игры. И я уверен, те кто пишут на С++ игры, даже не представляют, что это совсем не то, что делают большие компании. Посмотрите видео, где человек из Ubisoft объясняет, как они используют С++ в продакшне. Никаких эксцепшнов, шаблонов, буста и прочего. Вот эти ребята гонятся за производительностью. А зачем другие люди пишут на С++ мне не понятно :3 Очень забавно, что меня минусанул Denj, который тут вроде с 2012 года или вроде и все это время разрабатывал свой крутой модный очередной движок на С++ и в итоге где-то к 2015 подобрался все-таки к написанию игры на нем. Об этом я и говорил, no offense. Другое дело Kozinaka, у него по-крайней мере есть игра, первый раз такое вижу, хотя вроде тоже много времени прошло.
0
14
9 лет назад
0
Doc, для разработчика с нулевым опытом, безусловно, С++ не лучший выбор. Но бэкграунд сильно меняет дело - мне юнити осваивать дольше, чем накидать прототип игрухи пользуясь своими старыми велосипедами. Каждый делает свой выбор исходя из своих условий.
0
29
9 лет назад
Отредактирован Doc
0
Kozinaka, с этим никак не поспорить, квалифицированный разработчик, прекрасно знающий свой инструмент, использует его как угодно и где угодно лучше, чем что-то незнакомое, пусть и более подходящее для конкретной задачи.
4
14
9 лет назад
4
Мне кажется С++ уже так разросся, то используют его только те, кто начал его изучать, когда он был ещё маленький, остальных он отпугивает. Впрочем, буду рад ошибаться.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.