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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 22.11.2011, 18:55   #1
mosxe
Пользователь
 
Регистрация: 22.11.2011
Сообщений: 18
По умолчанию Арканоид. Разрушение кирпичей шариком.

Не знаю, как разрешить данную проблему. Бывает, что шарик тупо проходит мимо кирпичей и не разрушает их. Возможно проблема в угле отражения или еще в чем-то, но как записать условие не как не соображу.
Вот часть кода программы:
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
var
    i: integer;
begin
   Ball.Top := Ball.Top + dy; {смещение шарика по вертикали}
   Ball.Left := Ball.Left + dx; {смещение шарика по горизонтали}
   if Ball.Left <= X1 then {если шарик столкнулся с левой стенкой}
      dx := -dx;
   if Ball.Left + Ball.Width >= X2 then {если шарик столкнулся с правой стенкой}
      dx := -dx;
   if Ball.Top <= Y1 then {если шарик столкнулся с верхней стенкой}
      dy := 2;
   if Ball.Top + Ball.Height > Board.Top then {если шарик опустился ниже платформы}
      begin
        lives := lives - 1;
        Timer1.Enabled := False;
        BallMoving := False;
        if lives = 0 then
        begin
          ShowMessage('Game Over');
          Ball.Destroy;
          Board.Destroy;
          SaveResults;
        end;
        Label4.Caption := IntToStr(lives);
        if lives > 0 then
        begin 
        Board.Left := 215;
        Board.Top := 620;
        Ball.Left := 235;
        Ball.Top := 600;
        end;
      end;
  if (Ball.Top + Ball.Height = Board.Top)
     and (Ball.Left >= Board.Left)
     and (Ball.Left + Ball.Width <= Board.Left + Board.Width + Ball.Width)
     or ((Ball.Top + Ball.Height = Board.Top)
          and (Ball.Left <= Board.Left) and (Ball.Left + Ball.Width >= Board.Left)) then {если шарик столкнулся с платформой}
    dy := -dy;
  for i := 0 to 49 do
    if (Bricks[i].Visible)
       and (Ball.Top - 1 = Bricks[i].Top + Bricks[i].Height)
       and (Ball.Left >= Bricks[i].Left)
       and (Ball.Left + Ball.Width <= Bricks[i].Left + Bricks[i].Width + Ball.Width) then {если шарик столкнулся с кирпичом}
      begin
        Bricks[i].Visible := False;
        dy := -dy;
        score := score + 10;
        Label2.Caption := IntToStr(score);
Для создание фигур использовался класс TShape.
Буду очень благодарен кто поможет в решение данной проблемы.



___________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE] (это кнопочка с решёточкой #)
Не забывайте об этом!
Модератор.

Последний раз редактировалось Beermonza; 23.11.2011 в 15:24.
mosxe вне форума Ответить с цитированием
Старый 22.11.2011, 21:40   #2
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,881
По умолчанию

Без проекта (прикрепить сюда вложением) разобраться в этой каше очень проблематично.
На будущее - оформляем код кнопочкой # ну или тегом CODE (что равнозначно)
phomm вне форума Ответить с цитированием
Старый 22.11.2011, 22:41   #3
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

Чего-то у тебя вообще простая проверка. Я когда писал нечто подобное, проверял все четыре угла квадрата (он у мну исполнял роль шарика).

Код проверки проверяющий 4-ре угла на возможные столкновения у мну такой.
Код:
void test_blocks_collision( PMAP pm, PBALL pb )
{
  
  int mx0 = pb->x / 32;
  int my0 = pb->y / 32;
  
  int mx1 = (pb->x+32) / 32;
  int my1 = pb->y / 32;
  
  int mx2 = (pb->x+32) / 32;
  int my2 = (pb->y+32) / 32;

  int mx3 = pb->x / 32;
  int my3 = (pb->y+32) / 32;

  if ((mx0 <= (MAP_SIZE_X-1)) && (mx0 >= 0))
    if ((my0 <= (MAP_SIZE_Y-1)) && (my0 >= 0))
      if (g_map.blocks[mx0][my0].type != BT_NONE) 
      {
        
        
        if (pb->dx > pb->dy)
          pb->dx = - pb->dx;
        else
          pb->dy = - pb->dy;

        //if (g_map.blocks[mx0][my0].hit)
        switch(g_map.blocks[mx0][my0].type)
        {
        case BT_ONE:
          g_map.blocks[mx0][my0].type = BT_NONE;
        	break;
        case BT_DOUBLE:
          g_map.blocks[mx0][my0].type = BT_ONE;
          break;
        case BT_TRIPLE:
          g_map.blocks[mx0][my0].type = BT_DOUBLE;
          break;
        }
        
        return;
      }
      
 if ((mx1 <= (MAP_SIZE_X - 1)) && (mx1 >= 0))
    if ((my1 <= (MAP_SIZE_Y - 1)) && (my1 >= 0))
      if (g_map.blocks[mx1][my1].type != BT_NONE) 
      {
        if (pb->dx > pb->dy)
          pb->dx = - pb->dx;
        else
          pb->dy = - pb->dy;

        switch(g_map.blocks[mx1][my1].type)
        {
        case BT_ONE:
          g_map.blocks[mx1][my1].type = BT_NONE;
          break;
        case BT_DOUBLE:
          g_map.blocks[mx1][my1].type = BT_ONE;
          break;
        case BT_TRIPLE:
          g_map.blocks[mx1][my1].type = BT_DOUBLE;
          break;
        }
        return;
      }
  
if ((mx2 <= (MAP_SIZE_X - 1)) && (mx2 >= 0))
    if ((my2 <= (MAP_SIZE_Y - 1)) && (my2 >= 0))
      if (g_map.blocks[mx2][my2].type != BT_NONE) 
      {
        if (pb->dx > pb->dy)
          pb->dx = - pb->dx;
        else
          pb->dy = - pb->dy;

        switch(g_map.blocks[mx2][my2].type)
        {
        case BT_ONE:
          g_map.blocks[mx2][my2].type = BT_NONE;
          break;
        case BT_DOUBLE:
          g_map.blocks[mx2][my2].type = BT_ONE;
          break;
        case BT_TRIPLE:
          g_map.blocks[mx2][my2].type = BT_DOUBLE;
          break;
        }
        return;
      }
  
if ((mx3 <= (MAP_SIZE_X - 1)) && (mx3 >= 0))
    if ((my3 <= (MAP_SIZE_Y - 1)) && (my3 >= 0))
      if (g_map.blocks[mx3][my3].type != BT_NONE) 
      {
        if (pb->dx > pb->dy)
          pb->dx = - pb->dx;
        else
          pb->dy = - pb->dy;

        switch(g_map.blocks[mx3][my3].type)
        {
        case BT_ONE:
          g_map.blocks[mx3][my3].type = BT_NONE;
          break;
        case BT_DOUBLE:
          g_map.blocks[mx3][my3].type = BT_ONE;
          break;
        case BT_TRIPLE:
          g_map.blocks[mx3][my3].type = BT_DOUBLE;
          break;
        }
        return;
      }  
}
Сначала я выделяю ячейку (размером 32*32) на карте (n*32 X 32*m) в которой находиться тот или иной угол летящего квадрат. Проверяю каждую (из 4-х) не является ли она пустой (BT_NONE), если нет то идет обработка - меняется скорость на противоположную, и уменьшается "хрупкоть" стенки с которой столкнулись, у меня их несколько градаций - тройная, двойная, одинарная и пустота. Важно - столкновение может произойти с несколькими квадратами одновременно (по крайней мере у квадрата) на рисунке я изобразил как это может случится.
Изображения
Тип файла: gif 45.gif (3.6 Кб, 160 просмотров)
Вложения
Тип файла: rar mygame.rar (3.7 Кб, 33 просмотров)
Warn вне форума Ответить с цитированием
Старый 23.11.2011, 18:06   #4
mosxe
Пользователь
 
Регистрация: 22.11.2011
Сообщений: 18
По умолчанию

Проект добавил. На данный момент интересует как убрать проскакивание шарика через кирпичи, ост. не значительные погрешности уберу. Т.е. как я понял, надо добавить условия проверки ударения шарика об кирпичи?
Вложения
Тип файла: rar Программа.rar (240.0 Кб, 44 просмотров)
mosxe вне форума Ответить с цитированием
Старый 26.11.2011, 15:34   #5
mosxe
Пользователь
 
Регистрация: 22.11.2011
Сообщений: 18
По умолчанию

У кого-нито появились какие-нито мысли?
mosxe вне форума Ответить с цитированием
Старый 26.11.2011, 16:11   #6
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

Цитата:
У кого-нито появились какие-нито мысли?
мои все... скончались выше)

ты в своем коде делаешь проверку только в синих метках (см. рис), а надо бы еще добавить проверку в желтых метках (см. рис).
Изображения
Тип файла: jpg 56.jpg (9.5 Кб, 139 просмотров)

Последний раз редактировалось Warn; 26.11.2011 в 16:38.
Warn вне форума Ответить с цитированием
Старый 27.11.2011, 18:29   #7
mosxe
Пользователь
 
Регистрация: 22.11.2011
Сообщений: 18
По умолчанию

Т.е. нужно добавить еще 4 условия на проверку этих 4-х углов?
mosxe вне форума Ответить с цитированием
Старый 27.11.2011, 18:53   #8
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

Хотя бы так
Код:
  for i := 0 to 49 do
    if	(Bricks[i].Visible) and
    		((Ball.Top <= Bricks[i].Top + Bricks[i].Height) and (Ball.Top+Ball.Height >= Bricks[i].Top)) and
		((Ball.Left >= Bricks[i].Left) and (Ball.Left + Ball.Width <= Bricks[i].Left + Bricks[i].Width + Ball.Width)) then
      begin
        Bricks[i].Visible := False;
Warn вне форума Ответить с цитированием
Старый 27.11.2011, 22:36   #9
mosxe
Пользователь
 
Регистрация: 22.11.2011
Сообщений: 18
По умолчанию

to Warn: большое спасибо. Шарик стал разрушать кирпичи намного корректней. Но теперь только он бывает сразу разрушает два кирпича, хотя до 2-го кирпича он даже не коснулся. Т.е. надо добавить в это условие ( которые вы написали ) еще как бы условие о ударение шарика об кирпича? Чтобы бы он сразу несколько кирпичей за 1 касание не разрушал...
mosxe вне форума Ответить с цитированием
Старый 28.11.2011, 07:09   #10
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

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


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Арканоид Kostia Gamedev - cоздание игр: Unity, OpenGL, DirectX 11 03.04.2021 21:50
Арканоид jasonfuck Помощь студентам 6 29.05.2011 18:49
Разрушение формы Delphi Яська Помощь студентам 3 12.12.2010 22:53
арканоид GaLiof Помощь студентам 1 18.01.2010 11:25
разрушение индексов при изменении таблицы bosston БД в Delphi 1 23.06.2009 08:22