Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.05.2010, 19:35   #471
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

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

Код:
  // цикл по числу юнитов
  For i := 1 to nUnits do
    Begin
      // если юнит в игре
      If Units[i].InGame then
        Begin
          // работаем с записями юнита
          With Units[i] do
            Begin
              Case UAction of
              //0 - флаг нормального состояния 
              0: Begin
                    UAnimType := 0;  // тип анимации
                  end;
              //1 - флаг действия 1
              1: Begin
                    UAnimType := 1;  // тип анимации
                    // на последнем кадре сцены действия
                    If UFrame = {номер последнего кадра} then
                     Begin
                       UAction := 0; // переход на нормальное состояние
                     end;
                  end;
              //2 - флаг действия 2 
              2: Begin
                    // ----
                  end;

              // сколько еще нужно типов действия

              end; // case


              // Смена кадра анимации
              UFrame := Inc(UFrame);
              // проверка на переполнение
              If UFrame > {количество кадров анимации от типа} then UFrame := 0;

            end;
        end;
    end;
В этой структуре могут быть записаны и процедуры. Когда идет последний кадр некоторого типа анимации, в условии идет не только смена состояния, но и выполняется некая процедура, например, удар достиг конца, на последнем кадре запускается процедура расчета урона, ...или есть промежуточное условие на некоторый кадр, оно запускает процедуру расчета урона, а анимация продолжается до последнего.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 02.06.2010, 03:16   #472
M0rf
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 21
По умолчанию

Ура! Теперь у меня один таймер. Все неплохо работает, анимации корректно воспризводятся, но сложно регулировать скорость воспроизведения. при некоторых ударах получается, что анимация получения удара выполняется быстрее, чем нанесение. Пытался вручную менять интервалы у таймера, но это влияет на все скорости воспроизведения анимаций, что не решает проблемму. Возможно нужно использовать sleep() ?

З. Ы. Не подскажите ли мне аналог команды With на С++. Как я понял в данном примере, эта команда позволяет не писать каждый раз Units[i] при обращении к элементам. В helpe по С++ ее нет.

Последний раз редактировалось M0rf; 02.06.2010 в 03:20.
M0rf вне форума Ответить с цитированием
Старый 02.06.2010, 08:57   #473
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Цитата:
при некоторых ударах получается, что анимация получения удара выполняется быстрее, чем нанесение
Похоже, дело тут у вас в количестве кадров каждой анимации и другого адекватного совета, кроме как унифицировать количество кадров (или хотя бы подогнать для этой ситуации) тут быть не может.
Цитата:
Не подскажите ли мне аналог команды With на С++.
Эк вы вовремя! Просто как раз в данный момент в разделе по C++ висит на этот счет тема.
Говоря кратко - нет такого аналога в C++, только в функциях-членах вы не пишете, к какому объекту обращаетесь.

И еще добавлю, что при написании игры (и вообще любой нетривиальной программы) на C++ часто стоит активно использовать ООП. Если Pascal и Delphi несмотря на поддержку этой парадигмы часто оказываются склонны к функциональному программированию, что выражается хотя бы в разнице между записями и классами (отсутствие функций-членов и наследования в записях), то C++ является в противовес Си ориентированным именно на ООП и принципиальной разницы между структурами и классами там нет вообще никакой. Поэтому я советую использовать те средства, которые ближе выбранному вами языку (C++ в данном случае) - в частности, активно использовать функции-члены, например, таким образом:
Код:
for (int i = 0; i < nUnits; i++)
//Или вы можете использовать не массив, а один из стандартных контейнеров с его итераторами
 {
 if (Units[i].inGame())
  Units[i].Draw();
 }

class Unit
 {
 public:
 //...
 void Draw();
 //...
 private:
 int UAction; //Или это enum
 //...
 };
void Unit::Draw()
 {
 switch(UAction)
  {
  case 0: {/*анимация первого типа*/}; break;
  case 1: {/*анимация второго типа*/}; break;
  }
 }
Это, конечно, очень грубая схема и скорее только иллюстрация на тему того, в каком направлении вам стоит думать, работая конкретно с C++.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 02.06.2010, 12:52   #474
Вадим Буренков
Участник клуба
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
По умолчанию

Цитата:
анимации корректно воспризводятся, но сложно регулировать скорость воспроизведения. при некоторых ударах получается, что анимация получения удара выполняется быстрее, чем нанесение. Пытался вручную менять интервалы у таймера, но это влияет на все скорости воспроизведения анимаций, что не решает проблемму. Возможно нужно использовать sleep() ?
sleep, как и изменение скорости основного таймера не поможет, так как повлияет на скорость всей игры. В своих анимациях я делал задержки через переменную-счетчик. Вот тут можешь почитать про теорию т.к. вопрос уже обсуждался:
http://www.programmersforum.ru/showthread.php?t=70140
Почитай там мои посты, посмотри мою демку (правда она на Delphi, но как я понял ты его понимаешь). Смысл в том, что есть переменная, она каждый цикл таймера возрастает на 1. Как она становится равной, например 10 происходит ее сброс на 1 и выполняется код анимации. В итоге анимация работает в 10 раз медленнее таймера. Ту же систему можно использовать при других задержках чтобы не захламлять игру лишними таймерами.
Вадим Буренков вне форума Ответить с цитированием
Старый 02.06.2010, 16:30   #475
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от Вадим Буренков Посмотреть сообщение
... Смысл в том, что есть переменная, она каждый цикл таймера возрастает на 1. Как она становится равной, например 10 происходит ее сброс на 1 и выполняется код анимации. В итоге анимация работает в 10 раз медленнее таймера. Ту же систему можно использовать при других задержках чтобы не захламлять игру лишними таймерами.
Да, использую такой же алгоритм задержки (в играх типа РПГ очень чато приходится рулить анимацией, то же заклинание "медлительности", персонаж медленно перебирает ногами и перемещается тоже медленно), вот пример:
Код:
If FrameWait = 0 then Inc(Frame); // смена кадра
Inc(FrameWait); // счетчик задержки
If FrameWait = AnimWait then FrameWait := 0; // задержка равна установленной
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 03.06.2010, 01:46   #476
M0rf
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 21
По умолчанию

Цитата:
И еще добавлю, что при написании игры (и вообще любой нетривиальной программы) на C++ часто стоит активно использовать ООП.
Согласен на сто процентов. Но поскольку я новичек в создании игр, то совершил все возможные ошибки. Так в проге у меня 4 Image (1 фон, 2 бойца, полоса жизней). Знаю, что лучше переделать хотя бы под Canvas (в идеале OpenGL). Игру начинаю переделывать под ООП только сечас, поэтому и спроил об аналоге команды (писать полное обращение - захломляется код). В идеале планирую перенести в класс не только переменные бойцов, но и выполняемые функции. Но это уже позже.
Цитата:
Смысл в том, что есть переменная, она каждый цикл таймера возрастает на 1. Как она становится равной, например 10 происходит ее сброс на 1 и выполняется код анимации. В итоге анимация работает в 10 раз медленнее таймера. Ту же систему можно использовать при других задержках чтобы не захламлять игру лишними таймерами.
отличный способ. Сам думал над введением новой переменной, отвечающей за скорость, но не знал как реализовать. Попробую отпишусь.
M0rf вне форума Ответить с цитированием
Старый 13.06.2010, 01:42   #477
M0rf
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 21
По умолчанию

Сессия закончилась, можно иделом заняться.
Решил переделать вывод графики через Canvas в один Image. нашел пару примеров (в С++ синтаксис не такой как в Delphi), но возникли трудности:
TPicture *fon=new TPicture; - задаю указатель на фон игры
fon->Bitmap->Width=1280;
fon->Bitmap->Height=800; - указываю ширину и высоту
fon->Bitmap->LoadFromFile("Арена1.bmp"); - загружаю
Image1->Canvas->Draw(0,0,fon->Bitmap); - рисую.
Выскакивает ошибка при запуске программы: "Stream read error". Все сделано в соответсвии с примером. Есть ли ошибка в коде, и как правильно сделать вывод?

И еще, про классы. В начале планировалось использовать один класс - Fighter, который будет хранить все переменные, функции ударов, движения, получение урона. В общем все функции. Но один товарищ посоветовал мне писать несколько классов: описание бойца, описание анимаций и др. Никак не могу понять преимуществ такого способа. Как, на ваш взгляд, лучше писать классы?
M0rf вне форума Ответить с цитированием
Старый 13.06.2010, 07:58   #478
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Не надо рисовать все в один Image. Рисуйте сразу на форму. В реализации разницы никакой - т.к. вывод происходит через канву, которая у Form и Image одна и та же, а результат уже ближе к идеалу.
Также вместо TPicture советую TBitmap (уже хотя бы потому, что TBitmap является членом TPicture и это именно через него вы работаете).
Ошибка, возможно, из-за использования русских букв (вообще у Билдера с русскими символами и взаимодействием их с внешним миром все очень плохо).
Цитата:
И еще, про классы. В начале планировалось использовать один класс - Fighter, который будет хранить все переменные, функции ударов, движения, получение урона. В общем все функции. Но один товарищ посоветовал мне писать несколько классов: описание бойца, описание анимаций и др. Никак не могу понять преимуществ такого способа. Как, на ваш взгляд, лучше писать классы?
Один-единственный класс (особенно если с единственным экземпляром) - это еще не ООП. Это всего лишь чуть лучше, чем оставить все функции и данные вообще без обертки (в лучшем случае - в пространстве имен). Без множества классов в ООП не обойтись просто по той причине, что Объектно-Ориентированное Программирование предполагает множество классов, а не один (классы, их взаимодействие, наследование, и т.п.) Если у вас есть какая-то сущность - скорее всего, ее стоит сделать классом. Хотя меру тоже надо знать и подходить к процессу с точки зрения логики.
Вообще - почитайте Страуструпа, он много про ООП писал.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 18.06.2010, 10:59   #479
M0rf
Пользователь
 
Регистрация: 12.03.2010
Сообщений: 21
По умолчанию

Блин, столько времени и все зря. Уже по-всякому перепробывал. Или я что-то недопонял или чего-то не хватает Builder'у. Смотрим сами:
Graphics::TBitmap *tmpBitmap = new Graphics::TBitmap(); //создаем битмап
tmpBitmap->LoadFromFile("1.bmp");// загружаем изоьражение (специально переименовал, чтобы русских букв не было)
Form1->Canvas->Draw(0,0,tmpBitmap);//отображаем рисунок на форме, начиная с координаты (0,0)

По идее, все должно отображаться. Но при запуске вылетает ошибка Stram read error. При загрузке этой же картинки в Image (Image1->Picture->LoadFromFile("1.bmp")) все грузится нормально. Может быть кто-нибудь выложит пример (самый простой), чтобы я мог проверить - будет ли он у меня работать или нет?
M0rf вне форума Ответить с цитированием
Старый 18.06.2010, 20:56   #480
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

С проблемами в коде в свою созданную тему, здесь только фундаментальное, на словах или в коде.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Хорошие уроки Render Общие вопросы Delphi 9 15.09.2012 07:13
Акцесс вопросы новичков Yaga Помощь студентам 4 02.06.2008 00:16
Учебники для новичков в програмировании Рар Общие вопросы Delphi 6 08.01.2007 08:07