Урок 27 - Создаем игру Ping-pong - часть(2/3)

  Продолжаем писать игру Пинг-Понг. В этом уроке мы займемся реализацией игрока.

   Вытащим еще один Shape и сделаем ему синий цвет. Вот собственно этим мы и будем отбивать шарик. Перемещать его мы будем мышкой.

шарик


   Для этого создадим событие Form1 OnMouseMove:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Shape2.Top:= Mouse.CursorPos.Y - Form1.ClientOrigin.Y;
end;
   Shape2 - это наш прямоугольник, Mouse.CursorPos - позиции курсора, Form1.ClientOrigin - экранные координаты формы. После компиляции прямоугольник двигается вместе с мышкой, но шарик не отбивается.

   В Delphi есть такая функция:
function InterSectRect(var Dst: TRect; const Src1: TRect; const Src2: TRect);
   Она определяет пересекаются ли Rect'ы, в нашем случае Shape1 и Shape2. Модифицируем код таймера добавив в конец процедуры вот это:

  if InterSectRect(Overlay, Shape2.BoundsRect, Shape1.BoundsRect) then  //если есть пересечение между прямоугольником
  begin                                                                 //и кружком то кружок отправляем обратно 
    VelX:= -VelX;
    VelY:= -VelY;
  end;

   И здесь нам понадобится локальная переменная Overlay: TRect. Вот что должно получится у вас:
procedure TForm1.Timer1Timer(Sender: TObject);
var
	Overlay: TRect;
begin
  PosX:= PosX + VelX;	// Изменяем 
  PosY:= PosY + VelY;	//  позицию

  if PosX > ClientWidth - Shape1.Width then  
    VelX:= -VelX;

  if PosY > ClientHeight - Shape1.Height then 
    VelY:= -VelY;

  if PosX < 0 then		
    VelX:= -VelX;

  if PosY < 0 then		
    VelY:= -VelY;


  Shape1.Left:= Round(PosX);  // Обновляем
  Shape1.Top:=  Round(PosY);  // положение шарика 
  
  if InterSectRect(Overlay, Shape2.BoundsRect, Shape1.BoundsRect) then  
  begin                                                                 
    VelX:= -VelX;	//если есть пересечение между прямоугольником
    VelY:= -VelY;	//и кружком то кружок отправляем обратно 
  end;

end;
   Теперь при столкновении шарик отскакивает! Но он движется по одному и тому же пути, избавимся от этого добавив немного случайности. В FormCreate допишем событие, добавим в конец слово Randomize, тем самым мы говорим Delphi, что будем использовать улучшенный алгоритм генерации случайных чисел и измени проверку пересечения 2 объектов:
  if InterSectRect(Overlay, Shape2.BoundsRect, Shape1.BoundsRect) then  
  begin                                                                 
    VelX:= -VelX - Random(5);
    VelY:= -VelY - Random(5);
  end;
   Теперь будет лучше.

   В следующем уроке мы будем делать искусственный интеллект.

Удачи!
Встретимся в следующем уроке!




Добавил(а): mikkylovejoe Дата: 2013-06-17
if InterSectRect(Overlay, Shape2.BoundsRect, Shape1.BoundsRect) Что за Overlay? Вы по нее не ранее не писали, и теперь delphi ругается.



Добавил(а): RinDproramer Дата: 2013-10-30
У меня нечего не ругается. Наверное, ты не объявил эту переменную.



Добавил(а): Timosha_45 Дата: 2014-05-09
вопрос, при наведении мыши на "ракетку", она за ней не следует а двигается вниз, что делать?



Добавил(а): eltgm Дата: 2014-07-31
что с функцией-то делать?Объявили,а дальше?У меня шарик просто проскакивает ракетку



Добавил(а): darkshark1231 Дата: 2014-10-16
ничего не понял что куда прописывать. Не понятно написано



Добавил(а): McDias Дата: 2015-02-03
выаыаф



Добавил(а): McDias Дата: 2015-02-03
Не обязательно писать имя переменной Overlay, можно присвоить и любую другую букву



Добавил(а): Bek1996 Дата: 2016-02-10
Кстати не забудтье написать в раздел var overlay:trect;



Добавил(а): pronin106 Дата: 2017-05-29
Все получилось! Спасибо за урок. У кого не получилось читайте внимательнее! Не делайте тупо копипаст


  1. Евгений
    Евгений 2 years ago
    Привет из 2022.
    Вот и до меня дошла необходимость паскаля и программирования в Винде ((((

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