Пятница, 20.10.2017, 19:22
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта
Категории каталога
BlitzMax [14]
Blitz3D [9]
BlitzPlus [0]
Xna [1]
DarkBasic [0]
Общее [4]
Наш опрос
А вы пойдете на выборы?
1. Пошел бы, но я не совершеннолетний
2. Да
3. Нет
4. Да, я хочу сделать жизнь лучше
5. Нет, мой голос ни на что не повлияет
6. Нет, я не совершеннолетний
Всего ответов: 13
Форма входа
Поиск
Друзья сайта
Статистика

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

Коллизии в Blitz Max часть 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(слой#).
  • Записать в слой(и) изображение, которое мы будем проверять
  • Считывать слой(и) для проверки на коллизии

** И не забудьте, что слои являются битмасковыми

Категория: BlitzMax | Добавил: JohnK (14.06.2007) | Автор: Владимир
Просмотров: 1411 | Комментарии: 1
Всего комментариев: 1
1  
Нужные картинки:

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright JohnK© 2017