forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   FAQ и уроки (http://forum.boolean.name/forumdisplay.php?f=110)
-   -   Коллизии в BlitzMax Часть 2. (http://forum.boolean.name/showthread.php?t=3625)

johnk 14.06.2007 18:01

Коллизии в BlitzMax Часть 2.
 
Изучаем 2Д программирование: Max 2D Коллизии Часть 2
Автор: Assari 2006 Перевел: JohnK 2007

Содержание
  1. Вступление
  2. CollideImage
  3. Слой Коллизии
  4. Возвращение Массивов Объектов коллизиями
  5. Пример Слоя Коллизий
  6. Итоги
Вступление

В прошлой части мы увидели, как проверить объекты на коллизию, используя простые команды RectOverlaps и CircRectOverlaps. Так же рассмотрели пиксель-совершенные команды на проверку коллизий- ImagesCollide и ImagesCollide2.

В этой части мы рассмотрим другие команды, на проверку коллизий.

CollideImage

Давайте попробуем решить проблему неправильного определения коллизий, путем использования этой функции. Синтаксис этой функции вводит в заблуждение. Он представлен ниже, а теперь давайте заменим код таким образом, что бы он работал, мы не будем сейчас вникать в подробности, просто будем использовать CollideImage:
Код:

Function  CollideImage:Object[](image:TImage,x,y,frame,collidemask%,writemask%,id:Object=Null)

Заметьте, изменения выделены (серый текст это то, что осталось без изменения с прошлого раза)

Код:

  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
   
ResetCollisions()
    SetScale AlienSize,AlienSize
    DrawImage Alien,150,100,Frame
   
CollideImage(Alien,150,100,Frame,0,2)
 
    SetScale PlayerSize,PlayerSize
    DrawImage Player,MouseX(),MouseY()
    If
CollideImage(Player,MouseX(),MouseY(),0,2,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 основана на слоях, для того чтобы использовать ее, вы должны проделать следующие шаги:
  • Для начала, нужно удостовериться, что нужный слой – пуст.
  • Записать изображение, которое будет проверяться на коллизии, в нужный слой.
  • Проверять изображение на коллизии.
Вы можете использовать 32 слоя. В примере выше мы использовали первый слой.
Так же, в пример, мы прошли все 3 шага:

Функция
ResetCollisions() очищает все слои коллизий. Можно так же очистить только желаемый слой, например, для очищения второго слоя, мы должны написать так - ResetCollision(2)
Код:

  ResetCollisions()
Первое CollideImageвыражение приписывает изображение инопланетянина ко второму слою коллизий.
Код:

CollideImage(Alien,150,100,Frame,0,2)

А это
CollideImage выражение проверяет весь второй слой, а следовательно и изображение инопланетянина, с изображением Игрока.
Код:

If  CollideImage(Player,MouseX(),MouseY(),0,2,0)

А вот что Марки Сибли говорит о новой системе коллизий:

Цитата:

Главная идея параметров collidemaskи writemaskв том, что они являются ”битмасками” (т.е.: 1,2,4,8,16 и т.д.) это дает вам до 32 ‘слоев’ для проверки на коллизии. Например, вы можете создать следующие слои:

background=0, monsters=1, pickups=2, player=3.

Для этих слоев Битмаски 1,2,4,8 соответственно.

Использование битмасок, в отличие от просто номера слоя, дает преимущество в том, что вы можете обозначить несколько слоев, например: битмаска с номером 3 означает два слоя: нулевой и первый (2+1).

Функция
CollideImage одновременно записывает изображение в слой, в диапазоне от 0 до 32. (это зависит от параметра writemask) и проверяет на коллизии со слоями в диапазоне от 0 до 32. (это зависит от параметра collidemask).

'Запись Изображения’ несет в себе включение всего, что связано с изображением, а так же вращение и масштабирование. Или
же прощефизическаязаписьизображения.
Как вы помните, Марк говорил о параметрах collidemask% и writemask%:
Код:

Function CollideImage:Object[](image:TImage,x,y,frame,collidemask%,writemask%,id:Object=Null)

Чтобы приписать изображение к первому слою, мы должны записать так:

Код:

CollideImage(Alien,150,100,Frame,0,1)
Так же мы можем приписать наше изображением к двум слоям одновременно. Здесь мы записываем в первый и второй слои:
Код:

CollideImage(Alien,150,100,Frame,0,3)

Примерно также мы можем проверить слой на коллизии, манипулируя параметром
collidemask%:
Код:

If  CollideImage(Player,MouseX(),MouseY(),0,1,0)

Или же проверить два слоя сразу:

Код:

If  CollideImage(Player,MouseX(),MouseY(),0,3,0)

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


Возвращение Массивов Объектов коллизиями

Как вы помните, если происходят коллизии, то функция проверки на коллизию, возвращает значение true (истина)

Функция
CollideImage имеет больше возможностей в плане проверки на коллизии. Давайте рассмотрим до сих пор не знакомые нам параметры в синтаксисе этой функции, а именно Object[] и id:Object.

Function CollideImage:Object[](image:TImage,x,y,frame,collidemask%,writemask%,id:Object=Null)


Запомните, что существует два вида функции CollideImage,
  • Первая, для записи, с использованием параметра writemask
  • Вторая, для чтения, с использованием collidemask
Когда мы записываем изображение в слой, параметр id:Object позволяет опознавать изображение.

После записи, при чтении, функция вернет все объекты, вовлеченные в коллизию в виде массива объектов.

Вот
простой пример, иллюстрирующий это:
Код:

  Strict
  Graphics
640,480
  AutoMidHandle True
 
  Local
SpaceShip:TImage=LoadImage("blobship_1-1.png")
  Local
AlienShip1:TImage=LoadImage("cartoonufo_1-1.png")
  Local
AlienShip2:TImage=LoadImage("cartoonufo_1-1.png")
 
  Repeat
  Cls
  Local
R:Int=0
  Local
G:Int=0
  Local
B:Int=255
  ResetCollisions()
  SetColor
255,255,255
  DrawImage
AlienShip1, 250,100
  CollideImage
(AlienShip1,250,100,0,0,1,AlienShip1)
 
  DrawImage
AlienShip2, 400,100
  CollideImage
(AlienShip2,400,100,0,0,1,AlienShip2)
  Local
p:Object[]=CollideImage(Spaceship,MouseX(),MouseY(),0,1,0)
  For Local
i:TImage=EachIn  p
      Select
i
      Case
AlienShip1
          R=255
     
Case  AlienShip2
          G=255

      End Select
  Next
  SetColor
R,G,B    
  DrawImage
SpaceShip,MouseX(),MouseY()
  Flip
 
  Until KeyDown
(KEY_ESCAPE)  Or AppTerminate()


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






Если для объекта
AlienShip1 вы не напишете последний параметр в функции CollideImage, вы не сможете провести проверку коллизий. Попробуйте, и вы увидите:
Код:

            DrawImage  AlienShip1, 250,100
  CollideImage
(AlienShip1,250,100,0,0,1,Null)


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


Пример слоя коллизий

Ниже, пример определения коллизий между разными слоями:
Код:

  Strict
  Graphics 640,480
  AutoMidHandle True
 
  Local SpaceShip:TImage=LoadImage("blobship_1-1.png")
  Local AlienShip1:TImage=LoadImage("cartoonufo_1-1.png")
  Local AlienShip2:TImage=LoadImage("cartoonufo_1-1.png")
 
  Repeat
  Cls
  Local R:Int=0
  Local G:Int=0
  Local B:Int=255
  ResetCollisions(
3)
  SetColor 255,255,255
  DrawImage AlienShip1, 250,100
  CollideImage(AlienShip1,250,100,0,0,1,AlienShip1)
 
  DrawImage AlienShip2, 400,100
  CollideImage(AlienShip2,400,100,0,0,
2,AlienShip2)
 
Local Collision_Layer:int=2
  Local p:Object[]=CollideImage(Spaceship,MouseX(),MouseY(),0,
Collision_Layer,0)
  For Local i:TImage=EachIn p
      Select i
      Case AlienShip1
          R=255
      Case AlienShip2
          G=255
      End Select
  Next
  SetColor R,G,B   
  DrawImage SpaceShip,MouseX(),MouseY()
  Flip
 
  Until KeyDown(KEY_ESCAPE) Or AppTerminate()


Скомпилировав, вы увидите, что коллизия происходит только между одинаковыми слоями. Чтобы сделать проверку между двумя кораблями, вы должны присвоить переменной Collision_Layerзначение 3.
Итоги

В этой части мы рассмотрели способ проверки коллизий с помощью функции CollideImage.

Стоит запомнить, что BlitzMax предоставляет 32 слоя коллизий.
Следует повторить:
  • Сначала очищаем слои коллизий или один, нужный нам слой с помощью функции ResetCollisions(слой#).
  • Записать в слой(и) изображение, которое мы будем проверять
  • Считывать слой(и) для проверки на коллизии
** И не забудьте, что слои являются битмасковыми


johnk 14.06.2007 18:06

Re: Коллизии в BlitzMax Часть 2.
 
Вот нужные картинки:

johnk 14.06.2007 18:22

Re: Коллизии в BlitzMax Часть 2.
 
При копировании текста, почему то потерялись все пробелы, так что если вы заметите отсутсвие пробела или орфографическую ошибку, то просьба указать ее здесь.

ZanoZa 14.06.2007 20:58

Re: Коллизии в BlitzMax Часть 2.
 
это отлично что кто-то переводит!

johnk 15.06.2007 02:00

Re: Коллизии в BlitzMax Часть 2.
 
Присоединяйтесь! :)


Часовой пояс GMT +4, время: 00:24.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot