Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Столкновение объектов. Как правильно реализовать? 
:(
    Опции темы
w1zard350
Дата 6.5.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 4.5.2009

Репутация: нет
Всего: нет



Здравствуйте!

Пишу игру в танчики. Borland C++ 3.1. 

Суть в том, что нужно реализовать столкновения объектов. Пока что объектами будем считать "стены" и "танки". 

У меня есть массив "стен". Элементом массива является структура, которая содержит координаты двух точек, образующих прямоугольник. 

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

Вот код для движения вверх:
Код

int front,leftSide,rightSide,upSide,downSide,flag=1,i;
    leftSide = tank->x - w/2;
    rightSide = tank->x + w/2;
    upSide = tank->y - h/2;
    downSide = tank->y + h/2;
 
switch(direction)
    {
        // up
        case 1:
            front = tank->y - h/2;
            for (i = 0; i < countObjects && flag; i++)
            {
                if((front - tank->v <= (walls[i].y2)) &&
                   (front - tank->v > (walls[i].y1)) &&
                   (leftSide < (walls[i].x2)) &&
                   (rightSide > (walls[i].x1))
                  )
                {
                    flag = 0;
                    if (front != (walls[i].y2 + distance))
                    {
                        printTank (tank->x, tank->y, 0);
                        printTank (tank->x, walls[i].y2 + h/2 + distance, 1);
                        tank->y = walls[i].y2 + h/2 + distance;
                    }
 
                    break;
                }
            }
            if (flag)
            {
                printTank (tank->x, tank->y, 0);
                printTank (tank->x, tank->y - tank->v, 1);
                tank->y -= tank->v;
            }
    }
            break;

как видите, я просматриваю объекты только "стены", и то, их количество определено константой, т.е. при добавлении нового объекта я увеличиваю константу. Это очень плохо.

Собственно, вопрос:
Как мне организовать подобную проверку, только для всех объектов - стен и танков (потом еще и снарядов). Т.е. мне как-то нужно занести в один список три разных вида массива: массив структур стен, массив структур танков и массив структур снарядов.

Я понятия не имею, каким образом объединить все эти массивы и потом еще организовать хорошую проверку на столкновение. 

Сейчас смотрю в сторону связных списков. Я эту тему еще не изучил, поэтому не уверен, в ту ли сторону я собрался. А связный список мне пригодится хотя бы потому, что я точно не могу знать количество объектов в игре.

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

Надеюсь на вас, профессионалы 
PM MAIL   Вверх
Static
Дата 6.5.2009, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: 1
Всего: 2



Мое видение:
Унаследовать все объекты от общего предка и поместить их в один вектор. Это позволит перебирать все объекты одним циклом.
Я бы наверно делал так
Псевдокод
Код

struct Base
{
int id; // например идентификатор. Или еще чего-нить общее можно сюда запихать.
}

struct tank : Base
{
int x,y;
//еще чего-нить
}

struct bullet : Base
{
int x,y;
char direction; //куда летим-то
//еще че-нить
}

struct MyTank : tank
{
int hp;
//еще че-нить
}

struct Wall : Base
{
coords;
}

vector<Base> objects; // все объекты
void PutAllObjectTogether(&objects); // существующие объекты запихиваем в вектор

vector<Base> movable;
void PutMovableObjectTogether(&objects); //это только те, кто умеет шевелиться

int Action = GetActionFromPlyer(); // смотрим, чего хочет юзер
switch (Action)
{
case ACTION_FIRE: //дефайн какой-нить
       Fire(My_tank->getCoords(), My_tank->getDirection()); // ну типа стреляем. В функции добавляем в спиок новый объект-снаряд
       break;
case ACTION_MOVE:
       if( VerifyObstacle(My_tank->getDirection()) ) //В этой функции с помощью for_each (например) обходим все objects и проверяем их координаты. Функция возвращает bool (например)
               Move(My_tank); //двигаемся
      break;
default:
       DoNothing();
}

//тут при помощи того же for_each обходим наших movable генерим им движение и повторяем процедуру проверки для них. 



ну это очень примерно и "на коленке". Для пущей кошерности можно вместо структур классы сделать. И конструкторы им качественные с деструкторами smile, которые позволят правильно  добавлять/удалять объекты из списков.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
math64
Дата 6.5.2009, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Танк и снаряд тоже можно считать прямоугольниками.
Для определения времени столкновения двух движущихся объектов перейти в систему координат связанную с одним из них.
Код

class Base {
protected:
double x, y; // координаты центра
double width, length; // ширина и длина прямоугольника
double angle; // угол поворота
double vx, vy; // скорость
Base* next; // Для включения в список
//Base* prev; // Если нужен двунаправленный список
public:
   virtual bool Intersects(Base& base2) = 0; // Столкнулись  ли два объекта?
   virtual double WillIntersectAfter(Base& base2) =0; // Вычислить время столкновения
   ...
};
class Wall : public Base {
   ...
};
class Tank : public Base {
   ...
};
class Bullet : public Base {
   ...
};
// В BC 3.1 нет vector<>, list<> создаём свой
class List {
protected:
   Base* first;
   Base* last;
public:
   ...
};

PM   Вверх
w1zard350
Дата 24.5.2009, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 4.5.2009

Репутация: нет
Всего: нет



Спасибо огромное, общий смысл ясен! Благодаря вашим примерам продвинулся уже дальше.

Сейчас перешел к столкновениям пуль. И возникла проблема.

Написал функцию fire(). Она закидывает в список новый элемент со всеми нужными параметрами (координаты, скорость,направление). Потом в главном цикле написал функцию moveBullets(), которая просматривает список пуль и двигает их на шаг в зависимости от скорости. 

Проблема возникает при столкновении пули с другим объектом. Мои мысли на эту тему: когда столкнулись пуля и объект, определить с каким типом объекта пуля столкнулась (танк, стена). Если со стеной, просто затереть пулю. Если с танком, то нужно достать из списка все его данные и обнулить их на некоторое время, потом танк вновь входит в игру. Проблема возникла детская: как мне получить указатель на объект, с которым столкнулась пуля? 

Внутри функции проверки столкновений, пытаюсь вернуть через параметр указатель на этот объект. Вот кусок кода:
Код

int verifyObstacle(object*pObject, int direction, int v, object*result)
{
    current = first;

    while (current->next != NULL)
    {
    switch(direction)
    {
        case DIRECTION_UP:
        if(/*если столкнулись*/)
          {
                        result = current;
                        return 0;
                  }

После работы функции указатель result уже никуда не указывает, как решить проблему пока не знаю, думаю. Надеюсь вы сможете указать на ошибку алгоритма.


PM MAIL   Вверх
andrew_121
Дата 24.5.2009, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Я вот заметил странную закономерность. На БС-3.1 пишут только студики. И это похоже он...


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Dmi3ev
Дата 24.5.2009, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 1
Всего: 41



 smile 
Цитата

Я вот заметил странную закономерность. На БС-3.1 пишут только студики. И это похоже он... 

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



--------------------

PM MAIL   Вверх
andrew_121
Дата 24.5.2009, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(Dmi3ev @  24.5.2009,  11:34 Найти цитируемый пост)
я даже на форуме спрашивал, есть ли что-то поновее, но при этом с таким же ср...ым интерфейсом, мне ваще нравится, не знаю почему )))

****ист!  smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
w1zard350
Дата 24.5.2009, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 4.5.2009

Репутация: нет
Всего: нет



С пулями проблема решилась, ответ в теме: 
http://forum.vingrad.ru/forum/topic-260485...ые-возврат.html

Продолжаем разработку smile

PS: 
Не по теме:
Цитата

Я вот заметил странную закономерность. На БС-3.1 пишут только студики. И это похоже он...

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

PM MAIL   Вверх
andrew_121
Дата 24.5.2009, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(w1zard350 @  24.5.2009,  12:40 Найти цитируемый пост)
Не охота мне ее заказывать у кого-то, т.к. сам программированием очень увлекаюсь

Похвально!


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
math64
Дата 25.5.2009, 08:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Насчёт столкновений: Для определения типа объекта, с которым произошло столкновение используется виртульная функция:
Код

class Base {
...
public:
virtual void Damaged(Base& other) = 0;// Вычисляем повреждения нанесённые объекту
...
}

...
Base* base1;
Base* base2;
...
// Определение стокновений
if (base1->Inresects(*base2) { // Если объекты столкнулись
   base1->Damaged(*base2); // Вычисляем повреждения нанесённые объекту base1
   base2->Damaged(*base1); // Вычисляем повреждения нанесённые объекту base2
}

PM   Вверх
w1zard350
Дата 8.6.2009, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 4.5.2009

Репутация: нет
Всего: нет



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

Я вообще не могу понять в какую сторону мне копать, что менять? Я проверял, что когда я выйду в винду (Alt-Enter) и в диспетчере смотрю быстродействие, то загрузка ЦП на 100%. Ну да, игра грузит, но... если такая слабая игра под дос грузит, как же делают современные игры?

В общем, я хотел просто у вас узнать, что может быть причиной глюков? 

PS: В аттач приложил exe-шник. Если есть желание, посмотрите пожалуйста и выскажите свои предположения.
Я тут убрал движение ботов, т.к. и без них игра глючит. управление wasd и тильда для стрельбы.
Выкладывать код пока не стал, т.к. не уверен, что у кого-то будет желание разбирать тысячи строк кода. Но если все таки нужен - я выложу.

Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  V0_5.rar 51,20 Kb
PM MAIL   Вверх
fry
Дата 8.6.2009, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 4.10.2006

Репутация: нет
Всего: 3



Я как-то ище в школе делал часы( правда на Pascal ). Так вот они грузили мало не покажется, а все из-за графического вывода, т.е. смысл в том, что стандартные средства визуализации из компиллятора были жудко тормозными. Думаю если проблеема в этом, то переписав графический вывод под, скажем, OpenGL ты разгрузишь проц т.к. всю визуализацию будет делать твоя видюха. Если этого будет недостаточно, то думаю надо копать в самих принципах реализации игрушки. Всетаки 100% это слишком много. Точнее сказать не могу, нужны коды (а еще желание).
PM MAIL   Вверх
w1zard350
Дата 8.6.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 4.5.2009

Репутация: нет
Всего: нет



Переписывать графический вывод явно не буду. Это ведь обычная курсовая. А Вы пробовали у себя запускать игрушку? У Вас она вылетает? Грузит проц?
PM MAIL   Вверх
zim22
Дата 8.6.2009, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(w1zard350 @  8.6.2009,  14:35 Найти цитируемый пост)
 А Вы пробовали у себя запускать игрушку? У Вас она вылетает? Грузит проц?

она вообще не запускается.
сначала ругалась на отстутствие файла EGAVGA.BGI
потом ввиду того, что у меня Vista, - отказалась запускаться в полноэкранном режиме. я знаю, что приплясывая с бубном можно добиться запуска - но оно мне не надо smile


--------------------
PM MAIL   Вверх
w1zard350
Дата 8.6.2009, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 4.5.2009

Репутация: нет
Всего: нет



Блин, а я думал,  что после того как откомпилировал прогу, то все пути к драйверу и т.п. уже не важны... вот блин. То есть, если я хочу кому-то дать игрушку, то у него обязательно должен быть установлен BC 3.1 и путь к драйверу точно такой же как и у меня? Наивный я был... А как делают тогда современные игры? Ты устанавливаешь вместе с игрой все драйвера нужные для работы, оно где-то у себя сохраняет... да получается что так. Эххх... В общем, пойду копать дальше сам, а если у кого-то есть желание повозиться, то все таки попробуйте запустить у себя. Если нужен исходный код - стучите в личку.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0599 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.