Понедельник, 01 Сентября 2025, 22:36

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
Результаты поиска
nilremДата: Четверг, 08 Октября 2009, 15:23 | Сообщение # 1041 | Тема: Мысли вслух: Своя ролевая система.
Просветленный разум
Сейчас нет на сайте
Ролевая система это свод правил по которых живет вымышленный мир, не последнее место в которых занимают различные формулы.
В мире много ролевых систем. Есть очень известные вроде D&D, а есть известные лишь паре/ тройке человек. Очень часто, делая свою игру, все необходимые формулы придумываются на лету. И часто от их продуманности зависит гейплей игры и ее интересность.
У меня много подобных мыслей, но поделюсь лишь некоторыми.

Мысля первая - В чем сила магов?

Задание сформулировано не совсем точно. Цель – разобраться почему один маг сильнее другого, в чем причина магического превосходства. Это необходимо для того, чтобы вывести приближенные к «реальным» формулы. Конечнo, все зависит от ролевой системы, но я попытаюсь учесть только общие параметры.
Итак, вероятно, что имея больший запас магической энергии, то есть маны, маг сильнее. Это пункт первый и самый важный. Но он правилен не всегда. Важное значение имеет то, как эта мана используется. В нашем случае это скорость с которой маг способен излучать ману и абсорбировать энергию стихий. Далее не менее важным являются способы использования маны, то есть количество и качество доступных заклинаний, а также навык в использовании этих заклинаний. То есть кроме обширных знаний магу требуется также и солидный опыт.
Значит, что мы имеем:
1. Мана, то есть ее объем. Этот показатель зависит во первых от врожденных способностей(Интелект), а во вторых от специальной практики. Соответственно в формуле расчета максимума маны должны присутствовать оба этих показателя. В нашем конкретном случае опыт персонажа имеет ступени выраженные уровнями. Сначит простейшая формула – Интеллект*уровень. Кроме того необходимо учесть что маг, возможно приобретет некоторые навыки, позволяющие ему немного увеличить запасы маны. Соответственно:

Мана = Интеллект * уровень * дополнительный коэффициент.

2. Каким бы ни был объем маны, если уступающий по этому показателю противник окажется способным быстрее создать и применить заклинание, он окажется победителем. От чего же зависит эта скорость. Опять же важными являются врожденные способности и практика, то есть в формуле должны быть задействованы Интеллект и уровень. (Важно – скорость излучения фиксирована, но скорость кастования заклинания переменна и зависит от опыта использования заклинания. Это относится к третьему пункту. )
3. Третий показатель это количество доступных заклинаний, их качество. В принципе к силе мага не имеет прямого отношения, а наоборот зависит от нее. .Чем больше маг знает заклинаний, тем шире его возможности в атаке и защите. Конечно, чем качественнее, то есть мощнее заклинание, то не поможет никакая хитроумная тактика. Вот здесь навыки использования имеют существенное влияние. Часто используя какое то одно заклинание, маг привыкает к его созданию, в результате чего оно начинает получатся быстрее(каждое заклинание имеет уровень освоения) и требует меньше маны, соответственно за то же время в него можно вложить больше силы – сделать намного мощнее. Но это опять же зависит от практики и раньше тем его показатели достигнут определенного уровня освоить мощное заклинание маг не сможет

Возьмем пример. Два мага выясняют кто из них сильнее. Это действие довольно примитивно. Используя чистую силу маги попросту давят друг на друга. Кто пересилит тот и сильнее. Здесь немаловажное значение имеет сила давления, то есть скорость излучения маны, если же она приблизительно одинаковая то решающим будет то, у кого первого она закончится. Если скорость отличается незначительно, то все зависит от того, успеет ли маг пересилить соперника раньше, чем закончится мана. Ну а если разница огромна, то противника просто сметет потоком маны. Делаем выводы.

Мысль вторая. Физический урон.

Цель. Понять как просчитать величину наносимого повреждения. От каких факторов это зависит.

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

На данном этапе получится формула

Урон = УО

Для простых систем хватит и такой, но не для нас, ведь она совершенно не учитывает характеристик персонажа.
Физическая сила - вот основной показатель, делающий урон индивидуальным. Чем сильнее персонаж, тем больше он сможет нанести повреждения одним и тем же оружием.
Пусть коэффициент высчитывается так Сила/10. Из чего ясно что если сила больше 10 и урон больше, если же сила меньше, то и урон, соответственно будет меньше.
Теперь наша формула примет такой, более интересный, вид

Урон = УО * Коэффициент силы

Но и этого мало. Ведь не трудно догадаться, что воин, впервые взявший в руки оружие, будет использовать его не так эффективно, как ветеран. Так что нужно еще учитывать и опыт в использовании этого оружия и воинский опыт вообще.

Урон = УО * Коэффициент силы * Коэффициент опыта

здесь Коэффициент опыта будет зависеть от того, как именно у вас определен опыт персонажа и навык владения оружием. Например у меня опыт персонажа, это его 1+(уровень/25 ), то есть на 25 уровне перс сможет наносить двойной урон и т.д. Навык владения - числовая величина от 1 до 20. Здесь каждая единица добавляет 5% к урону.
Формула будет такой
1+((навык владения * 5)/100)
Ну а весь

Коэффициент опыта = Опыт персонажа * Коэффициент навыка владения

Ну и дабы сделать нашу формулу еще интереснее, добавим некую толику случайности. Ведь не все же удары будут одинаковыми, и нанесут одинаковый урон. Это может быть число от 0 до максимума УО или силы, а можно взять и что-то другое.
И на последок. Не все повреждение, что можно нанести будет нанесено. Ведь могут существовать факторы, которые будут этому препятствовать. Основной из них это броня цели. Как работает броня тоже зависит от фантазии. Например это может быть число от 0 до 100, где каждая единица это один процент заблокированного урона, или же эта единица и будет единицей заблокированного урона. А может для этого будет использоваться вообще какая-то умопомрачительная формула.
В результате наших измышлений получится нечто вроде этого

Урон = УО * Коэффициент силы * Коэффициент опыта + Случайная величина – Броня

Чтобы лучше разобраться, приведу пример:

Допустим есть воин 30 уровня, сила равна 15. Он вооружен коротким мечем с уроном в 10 единиц. Навык использования этого меча равен 18.
Противник имеет 48 брони.

Проведем подсчет.
Урон от оружия = 10
Коэффициент силы = 15/10 = 1,5
Коэффициент опыта = (1+(30/25))*(1+(18*5/100)) = 4,18
Случайная величина = (пусть это будет от 0 до УО) = допустим 7
Броня = (1 брони – минус 1 % урона) = 48 %

Теперь:

Предположительный урон = 10*1,5*4,18+7 = 69,7

Нанесенный урон = 69,7-(69,7*48%) = 36,2

Вот так.

Кроме использованных в формулы можно привязать еще множество факторов. Главное в них не потеряться.

Мысль третья. Опыт

Что же такое опыт?
Опыт это некая числовая величина, в которой учитываются все достижения персонажа. Под достижениями подразумевается выполнение миссий, победы над врагами и монстрами, исследование новых территорий, обнаружение сокровищ, решение загадок и многое другое.
Каждое такое действие повышает опыт. Значение, на которое будет повыше опыт, зависит от вас, от того насколько геймдизайнер оценил сложность выполненных действий.

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




Здесь количество опыта берется на основе предполагаемого потенциала. Только от желания геймдизайнера зависит, будет волк сильнее гоблина или гоблин сильнее волка.
НО, боевой потенциал игрока не постоянен. Со временем персонаж становится сильнее, естественно предположить, что чем дальше, тем проще ему будет справляться с одними и теми же противниками. Так же естественно, чтобы такие легкие победы приносили ему меньше опыта.
Необходимо как то учесть соотношение между мощью персонажа и его противника. Нужно использовать еще один показатель. Для этих целей опять может подойти уровень. Если уровень игрока и уровень убитого им существа одинаковый, то игрок получает полное количество опыта. Если уровни отличаются, то вычисление идет по такой формуле:

Количество полученного опыта = ЦС*( уровень существа/уровень персонажа)

Здесь:
ЦС – цена существа, то есть количество опыта согласно таблицы

Привожу пример, как эта формула работает
Допустим, персонаж 5 уровня сражается с волком 10 уровня.

Количество полученного опыта = 30 * (10/5) = 60

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

Теперь обратная ситуация. Персонаж 30 уровня сражается с волком 10 уровня.

Количество полученного опыта = 30 * (10/30) = 10

Соответственно, чем большее преимущество имеет персонаж, тем меньше опыта он получит.

С этим все ясно. Теперь переходим к ситуации посложнее. Допустим, что противников несколько. Понятно, что брать предыдущую формулу не имеет смысла. Ведь справится одновременно с двумя явно сложнее, причем с каждым новым противником сложность увеличивается на порядок.
Здесь можно пойти несколькими путями.
Первый, увеличивать количество опыта согласно количеству врагов. То если в приведенном выше примере напало два волка то подсчет ведем так:

КПО= (ЦС*( уровень существа/уровень персонажа))* количество врагов

Здесь КПО - Количество полученного опыта.

Количество полученного опыта = (30 * (10/30))*2 = 20

То есть за каждого волка будет получено 20 опыта.

Второй способ, и он мне нравится больше. Вообще не считать количество врагов, а учитывать интервал времени между их убийством.
Допустим, в качестве интервала мы выбрали 10 секунд. Если после первого убийства, до истечения 10 секунд происходит второе убийство, то за второе убитое существо дается двойное количество опыта. Далее если после второго убийства опять до истечения 10 секунд происходит третье, то количество опыта утраивается и так далее.

Весь КПО = Количество полученного опыта * номер врага

Здесь номер врага – порядковый номер врага, убитого до истечения интервала.

Пример:
Персонаж 20 уровня убивает 3 врагов. Все три убийства укладываются в заданный интервал
1. Орк 13 уровня.
2. Орк 17 уровня.
3. Шаман орков 10 уровня.

Считаем, сколько опыта отгребем:

1. Орк 13 уровня = (100 * (13/20))*1 = 65 опыта

Здесь *1 – это и есть порядковый номер врага.

2. Орк 17 уровня = (100 * (17/20))*2 = 170 опыта

3. Шаман орков 10 уровня = (250 * (10/20))*3 = 375 опыта

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

Формулу можно еще улучшить, учтя насколько быстро, в отведенный интервал, произошло следующее убийство.
Например, так:

Весь КПО = КПО * (номер врага + ((интервал времени ¬– прошедшее время)/ интервал времени))

Пример:
Предыдущая ситуация. Добавим, что второй орк был убит спустя 5 секунд после первого, а шаман - спустя 8 после второго орка.

1. Орк 13 уровня = (100 * (13/20)) = 65 опыта

2. Орк 17 уровня = (100 * (17/20))*(2+((10-5)/10)) = 212 опыта

3. Шаман орков 10 уровня = (250 * (10/20))*(3+((10-8)/10)) = 400 опыта

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

Ну, с этим тоже вроде разобрались. Теперь рассмотрим обратную ситуацию. Допустим, вы с напарником атакуете одного врага. В этом случае получить полное количество опыта будет нечестно.
Как поступить? Да все просто - поделить количество опыта пропорционально нанесенному урону:

Количество опыта = ЦС * (количество нанесенного урона/жизнь существа)

То есть пример:
ПротивникШаман орков – 10 уровень – 300 жизни
Персонаж - 10 уровня нанес 200 урона
Напарник - 15 уровня – 100 урона

Считаем для персонажа:

Количество опыта = 250 *(200/300) = 166 опыта

И используем полученное количество опыта в следующей формуле:

Количество полученного опыта = (166 * (10/10) = 166

Считаем для напарника:

Количество опыта = 250 *(100/300) = 83 опыта
Количество полученного опыта = (83 * (10/15) = 55

Кроме всего этого также не лишним будет учесть ваше численное превосходство:

Количество опыта = (ЦС * (количество нанесенного урона/жизнь существа))/1+количество напарников – количество врагов.

Эта формула подойдет для ситуации толпа на толпу. Но на основе изложенного здесь можно придумать еще много чего.

Надеюсь мои мысли будут кому-то полезны. Я не претендую на абсолютную непогрешимость и полную правоту. Это всего лишь мои мысли, и как и любые другие, они могут быть ошибочны. Моя цель, всего лишь подтолкнуть вас в верном направлении.
Выкладывайте свои соображения и идеи, а также замечания к уже выложенному. Делимся опытом, каким бы мизерным он не был.

Прикрепления: 7782460.png (5.2 Kb)


Windmill 2

WindMill 2D Game Engine
nilremДата: Среда, 07 Октября 2009, 20:31 | Сообщение # 1042 | Тема: Использование Xors3d
Просветленный разум
Сейчас нет на сайте
С2153 - номер ошибки. Означает что ты написал в коде черт знает что)
а предупреждение C4129 означает что ты где-то в строке символов напортачил с обратными косыми чертами (\).

Все это можно узнать из MSDN.

Возможно ругается на эту строчку - #include "inc\\xors3d.h".
попробуй так - #include "inc/xors3d.h".


Windmill 2

WindMill 2D Game Engine
nilremДата: Среда, 07 Октября 2009, 15:45 | Сообщение # 1043 | Тема: Использование Xors3d
Просветленный разум
Сейчас нет на сайте
А на какой строке С2153?

Windmill 2

WindMill 2D Game Engine
nilremДата: Среда, 07 Октября 2009, 14:44 | Сообщение # 1044 | Тема: One Day
Просветленный разум
Сейчас нет на сайте
Пробел между словами слишком большой.
Да и убого как-то. Нужен мрачный фон. Например могильная плита.


Windmill 2

WindMill 2D Game Engine
nilremДата: Среда, 07 Октября 2009, 14:40 | Сообщение # 1045 | Тема: Вопрос-Ответ - мини вопросы по созданию игр
Просветленный разум
Сейчас нет на сайте
Quote (doktor)
всем привет!админы прошу ответтьте плизз как мне до вас добраться-прошу прощения за несоответствия темы!

Для подобных вопросов есть ЛС, ICQ или соответствующий раздел форума "Администрация форума и сайта"


Windmill 2

WindMill 2D Game Engine
nilremДата: Вторник, 06 Октября 2009, 21:30 | Сообщение # 1046 | Тема: Использование Xors3d
Просветленный разум
Сейчас нет на сайте
Вот код простейшего приложения

Code


// Подключение заголовочного файла
#include "inc\\xors3d.h"   
// Подключение библиотечного файла
#pragma comment (lib,"lib\\Xors3d.lib ")

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   //инициализация
   xAppTitle("xors3d");
   xGraphics3D(1024, 768, 32, 0, 1);

   //основной цикл
   while(!xKeyDown(1))
   {
    //рендерим сцену
    xRenderWorld ();
    xFlip();
   }
   return 0;
}

Думаю, как подключать библиотечные и заголовочные файлы ты знаешь.
Чтобы не было проблем с dll, тупо копируешь их в system32, здесь ОС найдет их в любом случае. Главное в дальнейшем не забывать их обновлять, и поставлять рядом с исполняемым файлом. А зачем нужна LoadXors3D я так и не понял. Работает и без нее.
И все.
Уточняю про ООП. В самом С++ классы использовать можно, просто движок построен чисто на функциях.

зы: Бесплатный совет - учи английский.


Windmill 2

WindMill 2D Game Engine
nilremДата: Вторник, 06 Октября 2009, 16:35 | Сообщение # 1047 | Тема: Вредные привычки
Просветленный разум
Сейчас нет на сайте
А мне лень пить и курить. И работать лень. Да и отвеча....
Вобщем лень у меня вредная привычка.


Windmill 2

WindMill 2D Game Engine
nilremДата: Вторник, 06 Октября 2009, 13:18 | Сообщение # 1048 | Тема: игра "террор"
Просветленный разум
Сейчас нет на сайте
Тема не соответствует ни правилам ни тематике поэтому уходит в другой раздел.

Windmill 2

WindMill 2D Game Engine
nilremДата: Вторник, 06 Октября 2009, 12:00 | Сообщение # 1049 | Тема: Использование Xors3d
Просветленный разум
Сейчас нет на сайте
Приблизительній перевод подключения

[C/C++ установка для Microsoft Visual Studio]

1) Скопировать папки inc и lib из Xors3dEngine/port/c в папку вашего проекта, предварительно создав в нем папку xors3d.
2) Для их подключения добавляете в код следующую строку
#include "../xors3d/inc/xors3d.h"

Quote (Vinchensoo)
+3

ниче подобного, ты уже раздаешь +4


Windmill 2

WindMill 2D Game Engine
nilremДата: Вторник, 06 Октября 2009, 11:31 | Сообщение # 1050 | Тема: Использование Xors3d
Просветленный разум
Сейчас нет на сайте
http://xors3d.com/depository/file/45-xors3d_1-14

Windmill 2

WindMill 2D Game Engine
nilremДата: Понедельник, 05 Октября 2009, 12:57 | Сообщение # 1051 | Тема: Использование Xors3d
Просветленный разум
Сейчас нет на сайте
Официально xors3d поддерживает следующие языки:
Blitz3d
BlitzMax
C (чистый С)
C++ (ООП) - в разработке

То есть, С++ как бы использовать можно, но без ООП.


Windmill 2

WindMill 2D Game Engine
nilremДата: Воскресенье, 04 Октября 2009, 19:42 | Сообщение # 1052 | Тема: Помогите выбрать правильный язык программирования
Просветленный разум
Сейчас нет на сайте
Тогда вот
http://www.rsdn.ru/article/devtools/perftest.xml
http://www.rsdn.ru/article/devtools/perftest2.xml
http://www.rsdn.ru/article/devtools/perftest3.xml

Добавлю: статьи идут в хронологическом порядке. В последней учтены все недочеты в предыдущих тестах.


Windmill 2

WindMill 2D Game Engine
nilremДата: Воскресенье, 04 Октября 2009, 19:28 | Сообщение # 1053 | Тема: Помогите выбрать правильный язык программирования
Просветленный разум
Сейчас нет на сайте
http://ru.wikipedia.org/wiki/Сравнение_языков_программирования

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


Windmill 2

WindMill 2D Game Engine
nilremДата: Воскресенье, 04 Октября 2009, 09:49 | Сообщение # 1054 | Тема: chm на txt сменил... как обратно сделать?
Просветленный разум
Сейчас нет на сайте
"А если я тебе монтировкой по голове дам, какой шнурок развяжется."

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


Windmill 2

WindMill 2D Game Engine
nilremДата: Воскресенье, 04 Октября 2009, 09:32 | Сообщение # 1055 | Тема: Курс : "Основы С++ для начинающих программистов игр."
Просветленный разум
Сейчас нет на сайте
Лекция 4. Сложные типы данных. Копаем глубже.
(или роем себе могилу)


Здравствуйте. В названии урока присутствует слово сложные, и это действительно так. По сравнению с предыдущими, этот урок будет намного сложнее. Поэтому игры сегодня мы делать не будем. По мере изложения нового материала я буду демонстрировать короткие примеры. Каждая мелочь будет продемонстрирована и опробована на практике. Не волнуйтесь, если что-то будет казаться непонятным. Со временем все станет на свои места.
И еще, мне тут в аське сказали, что какие же это к черту уроки, если их нужно полдня читать. Ну, я, в принципе, согласен. Так что с этого момента это не уроки, а лекции, я и раньше употреблял это термин. А лекции сами по себе теперь разбиты на разделы – уроки. Их так и нужно осваивать – прочитали урок, поняли, переходим дальше.

Урок 1. Как информация хранится в компьютере


Прежде чем изучать дальнейший материал, немного поговорим о том, как же все данные хранятся в памяти компьютера. Сравним память компьютера с книгой, в которой информация представлена в виде текста. В свою очередь этот текст состоит из слов, слова из букв. На этом разбиение на простые составляющие заканчивается. Но не для компьютера. Память компьютера состоит из электронных запчастей, которые могут находится всего в двух состояниях. Возьмем за аналогии обычный выключатель(или включатель). Он может быть или включен или выключен. Так и в компьютере один «кусочек» памяти может принимать значение условно считаемое 0 или 1.
Если вы думаете что этого мало, вспомните азбуку Морзе. Там с помощью тех же двух символов без труда передают весь алфавит и цифры. Вот о цифрах мы позже и поговорим.
Кто-то когда-то назвал эти 0 и 1 битом. Потом придумали объединить 8 битов вместе и назвать их байтом. С байтами мы и будем иметь дело. Также есть такие понятия как Килобайт – 1024, мегабайт – 1024 килобайта, гигабайт – 1024 мегабайта, терабайт и т.д. Почему именно 1024, потому что здесь учитывается степень двойки.
Сделаю небольшое отступление, тоже касающееся хранения информации, но не в памяти, а на жестком диске, по-другому винчестере. На этих устройствах хитрые производители часто указывают емкость не в мегабайтах, а в миллионах байт, а это существенная разница.
Вот пример. Есть у меня самсунговский диск емкостью 40 000 миллионов байт, то есть как бы сорок гигабайт. А вот фигушки.

40 000 000 000 / 1024 = 39062500 килобайт
39062500 / 1024 = 38146 мегабайт
38146 / 1024 = 37,25 гигабайт

Вот так нас обманывают.
Ладно, завязываем с отходом от темы. Сейчас я расскажу, как с помощью всего двух символов 0 и 1 в компьютере записывается все что угодно. Слышали ли вы когда-нибудь такой термин – система счисления. Система счисления это такая математическая система, в которой используется определенное количество цифр(количество цифр еще называют основанием). Не путаем понятие цифра и число. Цифра – это знак, символ, а число это математическое значение, состоящее из одной или скольких угодно цифр.
Так вот, в повседневной жизни мы пользуемся десятичной системой счисления, то есть используем десять цифр – от 0 до 9. Число 10 состоит уже из двух цифр и соответственно само цифрой не является.
Вообще, кроме десятичной, система счисления может быть любой, но наибольшей популярностью пользуются - двоичная, десятеричная и шестнадцатеричная.
Двоичная это наши 0 и 1, с десятеричной тоже понятно, но как быть с шестнадцатеричной, если цифр-то всего десять. Все просто, в качестве дополнительных, используются символы латинского алфавита от А до F (в нижнем регистре a и f), то есть 10 это A, а 15 это F.

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

ПРИМЕР одно число в трех системах счисления
Десятичная - 100
Шестнадцатеричная - 64
Двоичная – 1100100

Таким образом с помощью наших 0 и 1, то есть с помощью двоичной системы без труда записывается любая информация.
- Но ведь информация бывает не только числовая! – можете возразить вы. Да мы привыкли иметь дело с текстом, но в компьютере каждая буква, или любой другой символ, хранится в виде числа, которое в свою очередь в памяти представлено в двоичном виде. Мы об этом еще поговорим.

Урок 2. Перевод из одной системы счисления в другую


Самый простой способ перевода чисел из одной системы в другую это … стандартный калькулятор операционной системы Windows в его инженерной ипостаси.
Но нам как программистам необходимо, хотя бы теоретически, знать, как это делается вручную. Все системы счисления я затрагивать не буду, а остановлюсь только на привычной нам десятичной и родной для компьютера – двоичной.
Немного теории.
Чтобы перевести число из одной системы счисления в другую нужно представить его в таком виде:



Здесь:
an … a0 – цифры от первой до последней
n – количество цифр, нумерация идет по уменьшению
С – система счисления(например 2, 10, 16 и др.) в соответствующей позиции n–ной степени.

Из вышеприведенной формулы следует(хотя вряд ли, подозреваю что вы в нее не въехали, но ничего, дальше поймете), что для перевода из большей системы в меньшую необходимо провести целочисленное деление числа на основание(систему счисления). Остаток это и будет наша цифра a0. Затем предыдущий результат от деления вновь делим нацело и получаем a1. И так далее пока результат от деления не будет равен 0.

Теперь пример перевода из десятичной в двоичную:

Возьмем число 75.
75 / 2 = 37; остаток 1.
37 / 2 = 18; остаток 1.
18 / 2 = 9; остаток 0.
9 / 2 = 4; остаток 1.
4 / 2 = 2; остаток 0.
2 / 2 = 1; остаток 0.
1 / 2 = 0, остаток 1.

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

75 = 1001011

Теперь будем переводить обратно, из меньшей в большую, то есть из двоичной в десятичную. В этом случае нам и понадобится приведенная выше формула.
Проведем обратное преобразование 1001011. Вычисления должны идти по требуемой, в нашем случае десятичной системе счисления.

1 * 26 + 0 * 25 + 0 * 24 + 1 * 23 + 0 * 22 + 1 * 21 + 1 = 64 + 8 + 2 + 1 = 75

Также часто в информатике используется шестнадцатеричная система. С ней компьютер способен работать и так. То есть можно сразу давать ему такие числа, предварительно сообщив об этом. Чтобы программа знала о том, что предлагаемое число в 16ричной системе, используется специальная запись с префиксом .

0х10, 0х50, 0х5А, 0х1А9В – это все числа в шестнадцатеричной системе.

Аналогичная ситуация с восьмеричной системой. Здесь префикс – 0, а запись 0144, 0456 означает, что число восьмеричное, при этом запись 08 вызовет ошибку, так как в восьмеричной системе цифры 8 нет.
Кроме этого возможно переключение вывода информации в консоли, что называется на лету. Для этого достаточно сообщить об этом оператору cout, передав ему определенную инструкцию. Для десятичной системы - dec, для шестнадцатеричной – hex и oct для восьмеричной.

Code

     cout << hex;  // шестнадцатеричная
     cout << 100  << '\n';    // 64
     cout << 0x64 << '\n';    // 64
     cout << 0144 << '\n';    // 64

     cout << oct;  // восьмеричная
     cout << 100  << '\n';    // 144
     cout << 0x64 << '\n';    // 144
     cout << 0144 << '\n';    // 144

     cout << dec;  // возврат к десятичной
     cout << 100  <<'\n';    // 100
     cout << 0x64 <<'\n';    // 100
     cout << 0144 <<'\n';    // 100


На этот с системами счисления заканчиваем. Примеры кода с преобразованием будут позже.


Windmill 2

WindMill 2D Game Engine
nilremДата: Воскресенье, 04 Октября 2009, 09:31 | Сообщение # 1056 | Тема: Курс : "Основы С++ для начинающих программистов игр."
Просветленный разум
Сейчас нет на сайте
5. Послесловие.

Конечно, игра «Угадай число» получилась не в пример предыдущей, простая и не очень интересная. Но что мешает вам придумать свой сюжет, добавить функциональности, например, ограничив количество попыток для угадывания.

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

Удачи вам в ваших начинаниях.
Помните, ваше усердие будет вознаграждено приобретенными знаниями.
До встречи.

sea_src.rar - студийный проект с исходным кодом,
seashell_EXE.rar - запускаемый файл игры.

Прикрепления: sea_src.rar (9.5 Kb) · seashell_EXE.rar (158.1 Kb)


Windmill 2

WindMill 2D Game Engine
nilremДата: Воскресенье, 04 Октября 2009, 09:23 | Сообщение # 1057 | Тема: Курс : "Основы С++ для начинающих программистов игр."
Просветленный разум
Сейчас нет на сайте
3. Игра «Угадай число»

Возможно после предыдущего урока, после Лабиринта, эта игра покажется вам слишком простой, ведь она в десять раз меньше по объему кода. Но если бы мы на прошлом уроке знали то, что знаем сейчас, то и Лабиринт был бы раза в три меньше. После этой игры можете попробовать его переписать с использованием циклов.

Итак, как обычно начинаем с планирования:

Что же именно мы будем делать.
Сделаем мы простенькую игру. Программа генерирует случайное число, а игроку предстоит его отгадать. Сюжет я предлагаю вам придумать самостоятельно. Если у вас с этим туго, что ж, в данной игре можно обойтись и без сюжета.

Как это будет реализовано.
Реализовано это будет в виде диалога. Программа спрашивает, какое число она сгенерировала. Игрок пытается отгадать и вводит свое предположение. Игра проверяет введенные данные и выводит результат, сообщая больше введенное от сгенерированного, меньше или равно.

Что для этого понадобится.
Предполагается, что попыток отгадывания будет несколько, поэтому нам необходимо знать, как использовать циклы. С этим мы уже познакомились выше.
Единственное, что нам пока неизвестно – как сделать так, чтобы программа создавала некое случайное число. Об этом я сейчас и расскажу.

Генератор псевдослучайных чисел.

Для генерации случайных чисел в С++ предусмотрена специальная функция – rand(). Что такое функция, мы поговорим на следующем уроке. А сейчас вы просто следуйте предложенным примерам.
Для того, чтобы использовать ее в своих программах необходимо подключить к исходному коду заголовочный файл stdlib.h. Как это делается я надеюсь, вы помните:

Code


#include <stdlib.h>

Ну и небольшой пример :

Code

#include <iostream>
#include <stdlib.h>

using namespace std;

void main()
{
     for(int i=0;i<10;i++)  // цикл
     {
      int r = rand();   // генерация случайного числа     
      cout<<r<<"\n";       
     }

     cin.get();
}


Здесь в строке

Code

int r = rand();   // генерация случайного числа     

происходит генерация случайного числа с помощью функции rand() и его присвоение переменной r, а затем эта переменная выводится на экран. Поскольку все это происходит в цикле, то этот код выполняется несколько, в данном случае 10, раз.

Запустим эту программу, и она выдаст нам столбик из десяти чисел. Затем запустим эту программу повторно. Как это не прискорбно, но в обоих случаях эти столбики будут идентичны.
Все дело в том, что сгенерировать абсолютно случайное число компьютер не может. Функция всего лишь берет некое начальное значение(по умолчанию это единица), производит над ним определенные арифметические действия и выводит нам результат. Затем, при повторной генерации предыдущий результат используется как начальное значение.
Поскольку арифметические действия всегда одинаковые, то и последовательность чисел всегда идентична. Именно поэтому функцию называют генератором псевдослучайных чисел.
Думаю понятно, что для того, чтобы сделать эти числа более случайными, необходимо как то изменить начальное значение, используемое в генерации.
Для этих целей используется функция инициализации генератора

Code

srand(начальное значение)

которая это начальное значение и устанавливает.
Все что остается, это сделать это значение случайным.
Замкнутый круг, но выход есть. В качестве начального используют значение системного времени. При запуске программы время каждый раз будет разное, соответственно и результат работы генератора будет неповторим.
Теперь нам осталось узнать, как получить это системное время.
Для этого нам понадобится еще одна функция – time(0), которая выдает время в секундах, ведя отсчет от 1 января 1970 года по текущий момент. Естественно, что это число никогда не повторится. Для использования этой функции необходимо подключить еще один заголовочный файл time.h.

Вот код примера:

Code

#include <iostream>
#include <stdlib.h>
#include <time.h>  // подключение заголовочного файла

using namespace std;

void main()
{
     srand(time(0));   // инициализация генератора
     for(int i=0;i<10;i++)  // цикл
     {
      int r = rand();  // генерация случайного числа     
      cout<<r<<"\n";       
     }

     cin.get();
}


Здесь мы видим подключение нового файла, и инициализацию генератора псевдослучайных чисел перед циклом. Казалось бы, правильнее поместить эту инициализацию внутри цикла, тогда каждое число будет еще более случайным. Но это не так. Дело в том, что компьютеры в наше время обладают чудовищной производительностью. Весь цикл займет всего лишь мгновение, соответственно и функция тайм все десять раз передаст в качестве начального значения одно и то же время. В результате все сгенерированные числа будут одинаковыми. Вы можете проверить это, поместив инициализацию внутри цикла.
Теперь нам нужно узнать какие же именно числа способен выдавать rand, то есть узнать диапазон возможных значений. Я и так знаю ответ, но думаю, что интереснее получить эти данные практически, получив в процессе крупицу опыта.

Следующая программа это и делает, а как – видно из комментариев:

Code

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

void main()
{
     srand(time(0));  // инициализация генератора
     int max, min, r;  // переменные для максимального, минимального и случайного
     max=min=rand();  // присвоение случайного значение переменным

     for(int i=0;i<1000000;i++)    // цикл
     {
      r=rand();  // присвоение переменной r случайного значения

      if(r>max)  // если r больше имеющегося максимума
       max=r;    // то оно становится максимумом

      if(r<min)  // если r меньше минимума
       min=r;    // то оно становится минимумом
     }
     // вывод результата
     cout<<"min= "<<min;
     cout<<"\nmax= "<<max;

     cin.get();

}


Запустив эту программу мы узнаем, что минимальное значение равно 0, а максимальное 32767.
Это очень большой разброс значений, тогда как часто необходимо получить число в заранее определенном, и возможно весьма узком диапазоне.
В языке программирования С++ есть один интересный арифметический оператор - %. Этот знакомый значок процента называется деление по модулю или по другому взятие остатка. Из второго названия ясно, что он делает. Допустим, есть такое выражение

Code

20%6

результат равен 2. Это остаток от целочисленного деления. То есть 20 = (3*6)+2. Здесь тройка ближайший делитель, а оставшаяся двойка и есть результат.

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

Code

     int x=20,y=6,i,res;
     i = 20/6;
     res = 20-( i * 6 );

Здесь сначала происходит обычное деление 20 на 6. Результат равен 3,3 (3 целых 3 десятых). Поскольку i у нас целочисленная переменная, запомните, что числа вроде 3,3 в ней хранится не смогут, и в результате преобразования типов дробная часть пропадает. Остается только целая часть 3.
Теперь мы множим эту тройку на шесть и то, что получилось, отнимаем от двадцати.
Результат это и будет то, что называют остатком от деления, и это как раз то, что получается при делении по модулю.
Теперь мы знаем, как этот оператор работает, что же нам это дает. А то, что при делении по модулю результат всегда будет меньше делителя как минимум на единицу.
Поэтому поделив таким способом любое случайное число, например, на десять, мы в результате получим число от 0 до 9.
То есть:

Code

х = rand() % 10;

не зависимо от того что здесь выдаст rand(), х будет присвоено значение от 0 до 9.

Так, думаю, немного разобрались. Но что делать, если нам необходимо число не от 0 и до, а например от 50 и до 80.

Вот как это вычислить:

Code

     int min = 50;     // начало диапазона
     int max = 80;     // конец диапазона
     int res = min + (rand()%(max-min));

Сначала вычисляется разность между максимумом и минимумом, что равно 30.
Затем в части выражения rand()%(max-min) получаем случайное число в диапазоне от 0 до 30, и прибавляем его к 50 (минимуму в данном случае), получив таким образом число в необходимом диапазоне.
Надеюсь вам все понятно, ибо на этом с генерацией случайных чисел мы закончили и переходим непосредственно к написанию кода игры.

«Угадай число»

Теперь зная все что необходимо, написание программы не составит никакого труда.
Вот ее исходный код:

Code

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

void main()
{
     setlocale(LC_ALL,"Rus");
     int r,    // случайное число
      i=-1,   // вводимое значение
      c=0;   // счетчик колличества попыток

     srand(time(0));  // инициализация генератора
     r=rand()%100;   // генерация случайного числа от 0 до 100

     cout<<"Программа задумала число от 0 до 100.\nПопробуй угадать!!!\n";
         
     while(r!=i)   // цикл
     {
      // ввод числа
      cout<<"Введите число\n";
      cin>>i;

      // проверка и вывод подсказки
      if(i>r)
       cout<<"Многовато будить\n";
      if(i<r)
       cout<<"Однако, маловато\n";

      c++;    // наращивание счетчика попыток
     }

     // отображение результата
     if(c < 10)
      cout << "Молодец, угадал с "<< c <<" попытки";
     if(c > 10)
      cout << "Ну с "<< c <<" попытки любой угадает";

     cin.get();
     cin.get();
}

Думаю, вдаваться в детали не нужно, лишь расскажу вкратце, как он работает.
Вначале объявлены три переменные для хранения случайного числа, введенного значения и счетчика, которым тут же и присвоено начальное значения. Для счетчика это начало отсчета – 0, а вот для вводимого это отрицательное значение, чтобы выражение в условии цикла r!=i было истинным. Ведь сгенерированное число всегда положительное.
Далее происходит инициализация генератора и генерация случайного числа. Это случайное число сравнивается в цикле с вводимым значением, и до тех пор, пока они не равны, программа выдает подсказку больше или меньше сгенерированное число от введенного. Каждый цикл происходит наращивание счетчика попыток.
Как только пользователь вводит верное значение, цикл завершается и выводится результат, с указанием количества попыток. Все.

4. Visual Studio. Структура проекта.

Мы уже на протяжении трех уроков учимся писать программы. Но до сих пор программы, в прямом смысле этого слова мы так и не увидели. Ведь то, что мы пишем это исходный код. Да он работает так, как задумано. Но программа с точки зрения обычного человека (не программиста) это некий файл, имеющий окончание .ехе, и его можно запускать в не зависимости от студии, и можно поделится им с друзьями, похваставшись своими достижениями.
Я вас обрадую. Такой файл существует, просто вы пока не знаете, а кто-то может уже и знает, где он находится. Сейчас я укажу вам на его месторасположение, заодно рассказав, из каких файлов и папок состоит проект и для чего они предназначены. Я имею в виду не то, как мы видим проект в студии в обозревателе решений, а то как он хранится на диске.
Итак, все свои проекты, если вы конечно ничего не меняли в настройках, студия хранит в папке Мои документы. Надеюсь, что вы знаете где находится эта папка. Если нет, то самое время поискать самому, ибо объяснять, как пользоваться операционной системой я не намерен.
В Моих документах студия создает папку Visual Studio 2008, это если студия 2008 года. Здесь есть несколько папок, в одной из которых – Projects, и хранятся все создаваемые пользователем проекты.
Каждая папка в Projects, это отдельное решение, которое может включать в себя несколько проектов. Поскольку все С++ проекты имеют одинаковую структуру, то объяснять я буду на примере своего проекта seashell, добавленного к этой статье.
Открываем решение sea. Внутри мы видим папки Debug, Release, seashell и файлы sea. sln , sea.suo и sea.ncb.
О Debug и Release. В этих папках, в зависимости от конфигурации решения, и находится необходимый нам ехе файл вместе с промежуточными файлами компоновки - seashell.pdb, seashell.ilk. Думаю стоит немного упомянуть о конфигурации решения. Есть два варианта конфигурации, или по-простому два набора настроек - Debug и Release. Debug используется в процессе разработки и отладки программы, а Release - для более-менее нормально работающей программы, которую предполагается поставлять конечному пользователю. В зависимости от выбранного, ехе файл попадает в соответствующую папку. О конфигурациях мы поговорим, когда будем изучать отладку программы, а сейчас возвращаемся к структуре проекта.
Файл sea. sln содержит информацию о проектах, входящих в решение. Запуск этого файла приводит к старту студии и загрузки всех объединенных в это решение проектов.
В файле sea.suo хранятся настройки решения. seal.ncb содержит данные, необходимые для работы компонента студии Intellisence. Intellisence – это инструмент, облегчающий работу в студии, подсказывая нам существующие названия переменных, функций и операторов, выполняя автозавершение кода и многое другое
В папке seashell хранится все, что относится к конкретному проекту. В ней находятся папки Debug, Release и три файла:
seashell.cpp – файл исходного кода.
seashell.vcproj.user и seashell.vcproj – файлы с настойками проекта.
А в папках Debug, Release, как и в прошлый раз в зависимости от выбранной конфигурации, хранится скомпилированный исходный код с дополнительными файлами.
На этом разбор структуры закончен. Возможно, из-за повторяющихся названий все выглядит немного запутанным, но не волнуйтесь, со временем вы освоитесь, тем более что самое важное что нужно запомнить – где находится этот самый екзешник, а о назначении остальных файлов знать пока не обязательно.


Windmill 2

WindMill 2D Game Engine
nilremДата: Суббота, 03 Октября 2009, 11:15 | Сообщение # 1058 | Тема: Профессиональный сценарист (услуги платные)
Просветленный разум
Сейчас нет на сайте
Quote (FERAMON)
Придумай мне сценарии для моего тетриса!

С хорошей фантазией сценарий и сюжет можно придумать для любого жанра.Ты то должен об этом знать.

Автор не отреагировал на мое предупреждение, поэтому тема переносится во флейм.


Windmill 2

WindMill 2D Game Engine
nilremДата: Пятница, 02 Октября 2009, 21:28 | Сообщение # 1059 | Тема: [3D] Stargate: Operation Tok'Ra [Action\RPG]
Просветленный разум
Сейчас нет на сайте
Дам бесплатный совет. Делай то, что у тебя получается лучше всего, правда я пока так и не понял что. Ведь кроме идеи у тебя ничего нет.
И как тебе сказал TrueIfrit, ищи людей, ибо судя по всему сам ты не потянешь.


Windmill 2

WindMill 2D Game Engine
nilremДата: Пятница, 02 Октября 2009, 20:24 | Сообщение # 1060 | Тема: Нашел конструктор MMORPG - Hero Engine
Просветленный разум
Сейчас нет на сайте
Quote (GC-Vic)
Можно только сочувствовать тому, кто не играл в Star Wars: The Old Republic

Так он же еще не вышел, запланирован на 2010 год. Ты что, из будущего?

Может ты имел в виду SW KOTOR - Star Wars : Knights Of The Old Republic


Windmill 2

WindMill 2D Game Engine
Поиск:

Все права сохранены. GcUp.ru © 2008-2025 Рейтинг