Пятница, 26.04.2024, 23:46
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта
Категории каталога
BlitzMax [14]
Blitz3D [9]
BlitzPlus [0]
Xna [1]
DarkBasic [0]
Общее [3]
Наш опрос
Билл Гейтс уходит в отставку, Вы рады?
1. Да :)
2. Нет :(
Всего ответов: 9
Форма входа
Поиск
Друзья сайта
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Статьи
Главная » Статьи » BlitzMax

Коллизии в Blitz Max часть 1.
Коллизии в BlitzMax. Первая часть
Автор: (c) Assari 2006 Перевел: (c) JohnK 2007

Содержание.

  1. Вступление
  2. Пересечение_Прямоугольников
  3. Пересечение_Прямоугольника и Круга
  4. Функции коллизий в_BlitzMax
  5. ImagesCollide
  6. ImagesCollide с Анимацией
  7. ImagesCollide с Масштабированием
  8. ImagesCollide с Вращением
  9. Итоги

Вступление

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

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

Пересечение Прямоугольников

Самый простой способ проверки коллизии – это пересечение прямоугольников.

 Давайте рассмотрим пример:

   

Graphics 640,480
While Not (KeyHit
(key_escape) Or AppTerminate())
  Cls
  SetColor
0,255,0
  DrawRect
150,200,100,100
  SetColor
0,0,255
  DrawRect MouseX(),MouseY()
,100,100
  Flip
Wend
End

 

Как вы могли заметить из кода выше, при пересечении прямоугольников ничего не происходит. Это из-за того, что в коде нет проверки коллизии.

Давайте добавим ее, используя команду
RectsOverlap (Пересечение прямоугольников) И при столкновении сменим цвет синего прямоугольника.

   

Graphics 640,480
While Not (KeyHit
(key_escape) Or AppTerminate())
  Cls
  SetColor
0,255,0
  DrawRect
150,200,100,100
  If RectsOverlap
(150,200,100,100,MouseX(),MouseY(),100,100)
      SetColor
255,0,0
  Else
      SetColor
0,0,255
  EndIf
  DrawRect MouseX(),MouseY()
,100,100
  Flip 
Wend
End

Function
RectsOverlap:Int(x0, y0, w0, h0, x2, y2, w2, h2)
    If
x0 > (x2 + w2) Or (x0 + w0) < x2 Then Return False
    If
y0 > (y2 + h2) Or (y0 + h0) < y2 Then Return False
    Return True
End Function

 


Как вы могли заметить, синий прямоугольник становится красным каждый раз, когда происходит пересечение (коллизия).

Пересечение Прямоугольника и Круга

Давайте немного изменим код, дабы вместо прямоугольника появился овал:

   

Graphics 640,480
While Not (KeyHit(key_escape) Or AppTerminate())
  Cls
  SetColor 0,255,0
  DrawRect 150,200,100,100
  If RectsOverlap(150,200,100,100,MouseX(),MouseY(),100,100)
      SetColor 255,0,0
  Else
      SetColor 0,0,255
  EndIf
 
DrawOval MouseX()-50,MouseY()-50,100,100
  Flip 
Wend
End

Function RectsOverlap:Int(x0, y0, w0, h0, x2, y2, w2, h2)
    If x0 > (x2 + w2) Or (x0 + w0) < x2 Then Return False
    If y0 > (y2 + h2) Or (y0 + h0) < y2 Then Return False
    Return True
End Function

 


Как вы заметили, функция больше не работает должным образом. Нам нужна другая функция, которая поможет нам определить коллизию между овалом и прямоугольником. Вот она:

   

Graphics 640,480
While Not (KeyHit(key_escape) Or AppTerminate())
  Cls
  SetColor 0,255,0
  DrawRect 150,200,100,100
  If CircRectsOverlap(150,200,100,100,MouseX(),MouseY(),50)
      SetColor 255,0,0
  Else
      SetColor 0,0,255
  EndIf
  DrawOval MouseX()-50,MouseY()-50,100,100
  Flip 
Wend
End

Function CircRectsOverlap(x0, y0, w0, h0, cx, cy, r)
    testX=cX
    testY=cY
   
If TestX < x0 Then TestX=x0
   
If TestX > (x0+w0) Then TestX=(x0+w0)
   
If TestY < y0 Then Testy=y0
   
If TestY > (y0+h0) Then Testy=(y0+h0)

   
Return ((cX-TestX)*(cX-TestX)+(cY-TestY)*(cY-TestY))<r*r
End Function

 





Функции коллизий в BlitzMax

Если нам захочется использовать отдельную функцию для каждой пары различных объектов, у нас будут проблемы. Так же если это не функция RectsOverlap можно заметить, что математика в функциях на проверку столкновений становиться сложнее.

К счастью,
BlitzMax (а точнее Max2D) предоставляет пару функций, которые облегчат нам жизнь. А теперь давайте посмотрим, как можно использовать встроенные в Max2D функции.

ImagesCollide

Самая простая функция в BlitzMax это ImagesCollide. Она имеет следующий синтаксис:

 

Function ImagesCollide(image1:TImage,x1,y1,frame1,image2:TImage,x2,y2,frame2)

 


Функции требуется два изображения, которые надо проверить, а так же их положение на экране. Мы можем игнорировать параметр Frame, указав вместо значения - ноль.

   

  ImagesCollide(Alien,150,200,0,Player,MouseX(),MouseY(),0)

 


Итак, позиция НЛО =(150,200), а позиция игрока  равна позиции мыши.

Скомпилируйте код, что бы увидеть функцию в действии:

   

Graphics 640,480
Local
Player:TImage=LoadImage("blobship_1-1.png")
Local
Alien:TImage=LoadImage("cartoonufo_1-1.png")

While Not (KeyHit
(key_escape) Or AppTerminate())
  Cls
  DrawImage
Alien,150,200
  DrawImage
Player,MouseX(),MouseY()
  If ImagesCollide
(Alien,150,200,0,Player,MouseX(),MouseY(),0)
      SetClsColor
255,0,0
  Else
      SetClsColor
0,0,0
  EndIf
  Flip
Wend
End

 



Как вы могли заметить, использовать эту функцию очень просто.

ImagesCollide с Анимацией

Давайте разберемся с параметром Frame, который мы пропустили ранее. Что бы коллизия работала с анимационным изображением нужно немного изменить код:

   

Graphics 640,480
Local Player:TImage=LoadImage("blobship_1-1.png")

Local
Alien:TImage=LoadAnimImage("exp1.png",64,64,0,16)
Local
Frame:Int=0
Local AnimDelay:int=10

While Not (KeyHit(key_escape) Or AppTerminate())
  Cls
  DrawImage Alien,150,200
, Frame
  DrawImage Player,MouseX(),MouseY()
  If ImagesCollide(Alien,150,200,
Frame,Player,MouseX(),MouseY(),0)
      SetClsColor 255,0,0
  Else
      SetClsColor 0,0,0
  EndIf
  Flip
 
If AnimDelay<0 Then
     Frame :+ 1
     If
Frame>15 Then Frame=0
    
AnimDelay=10
 
EndIf
 
AnimDelay :- 1


Wend
End

 


Чтобы использовать ImagesCollide с анимационными изображениями, нам нужен параметр, характеризующий кадр анимации, что бы потом использовать в функции ImagesCollide. А увеличение параметров AnimDelay и Frame сделано для того, что бы анимация  проигрывалась должным образом.



ImagesCollide с Масштабированием

Blitzmax позволяет масштабировать изображения в реальном времени. Это можно сделать с помощью функции SetScale, ее синтаксис таков:

 

Function SetScale( scale_x#,scale_y# )

 


К сожалению, если используется функция SetScale, ImagesCollide не работает должным образом. Что бы убедится в этом, скомпилируйте этот код:

   

Graphics 640,480
Local Player:TImage=LoadImage("blobship_1-1.png")

Local Alien:TImage=LoadAnimImage("exp1.png",64,64,0,16)
Local Frame:Int=0
Local AnimDelay:int=10
Local PlayerSize:Int=1
Local AlienSize:Int=2

While Not (KeyHit(key_escape) Or AppTerminate())
  Cls
 
SetScale AlienSize,AlienSize
  DrawImage Alien,150,100,Frame
 
SetScale PlayerSize,PlayerSize
  DrawImage Player,MouseX(),MouseY()
  If ImagesCollide(Alien,150,100,Frame,Player,MouseX(),MouseY(),0)
      SetClsColor 255,0,0
  Else
      SetClsColor 0,0,0
  EndIf
  Flip
  If AnimDelay<0 Then
     Frame :+ 1
     If Frame>15 Then Frame=0
     AnimDelay=10
  EndIf
  AnimDelay :- 1

Wend
End

 

К счастью в BlitzMax есть еще одна функция, которая позволяет работать с масштабированными изображениями, чудо функция зовется ImagesCollide2,ее синтаксис таков:

 

Function ImagesCollide2(image1:TImage,x1,y1,frame1,rot1#,scalex1#,scaley1#,image2:TImage,x2,y2,frame2,rot2#,scalex2#,scaley2#)

 


Прим. Переводчика: Запомните! Функция не будет вращать или масштабировать изображение! Она лишь учитывает эти факторы, для определения коллизии!

 

Итак, все, что нам нужно чтобы использовать ImagesCollide2, это добавить:

   

  If ImagesCollide2(Alien,150,100,Frame,0,AlienSize,AlienSize,Player,MouseX(),MouseY(),0,0,PlayerSize,PlayerSize)

 


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

ImagesCollide с Вращением

Этот пункт я оставил вам, как упражнение, чтобы вы выяснили, что нужно ввести, чтобы  функция заработала :)

Итоги

Сначала в этом туториале мы разобрали два простых (и быстрых) способа проверки на коллизии. Жаль, что они работают только с кругами и прямоугольниками.

А так как многие игры полностью состоят из изображений, мы рассмотрели и разобрали функции
ImagesCollide и ImagesCollide2.

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


Категория: BlitzMax | Добавил: JohnK (25.03.2007) | Автор: JohnK
Просмотров: 2346
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright JohnK© 2024