Blitz3D+ Command Reference

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

Parameters

image1 - first image

x1 - x position image1 is drawn at

y1 - y position image1 is drawn at

frame1 - frame of image1 to test

image2 - second image

x2 - x position image2 is drawn at

y2 - y position image2 is drawn at

frame2 - frame of image2 to test

Description

Returns True if two images touch, testing pixel by pixel and ignoring masked pixels.

This is the accurate collision test. It first checks whether the two images overlap at all, and if they do it walks the overlapping area looking for a place where both images have a pixel that is not their mask colour. Transparent pixels never cause a hit, so an awkwardly shaped ship only collides when its actual metal touches something.

Pass the same x,y you would pass to DrawImage - the test accounts for each image's handle, so centred sprites work without any adjustment. The frames matter: a wide-armed animation frame collides where a crouching one does not.

It is the right tool for bullets against irregular enemies, a player sprite against spikes, or a mouse pointer against an odd-shaped button. The cost is speed - the pixel walk is far more work than a rectangle test - so do not run it against every object in a big level. The usual pattern is to filter first with ImagesOverlap or RectsOverlap, and only call this on the handful of pairs that survive.

Both frame numbers are required, unlike in ImagesOverlap, which always tests frame 0. If you change an image's mask with MaskImage, the collision shape changes with it.

See also: ImagesOverlap, ImageRectCollide, ImageRectOverlap, RectsOverlap, MaskImage.

Example

; ImagesCollide Example
; ---------------------

Graphics 640,480,0,2
SetBuffer BackBuffer()

player=LoadImage("media/player.bmp")

; Create an asteroid image - a round boulder with empty corners
rock=CreateImage(96,96)
SetBuffer ImageBuffer(rock)
Color 130,120,110
Oval 8,8,80,80,True
SetBuffer BackBuffer()

px=100
py=100

While Not KeyDown(1)

    Cls

    ; Arrow keys steer the ship
    If KeyDown(203) Then px=px-3
    If KeyDown(205) Then px=px+3
    If KeyDown(200) Then py=py-3
    If KeyDown(208) Then py=py+3

    ; ImagesCollide is pixel-perfect: transparent pixels never count,
    ; so brushing past the boulder's empty corners is safe.
    ; It is slower than ImagesOverlap - use it when accuracy matters.
    ; The 0s are the animation frames to test (frame 0 of each image).
    hit=ImagesCollide(player,px,py,0,rock,272,192,0)

    DrawImage rock,272,192
    DrawImage player,px,py

    ; Flash a warning border while colliding
    If hit Then
        Color 255,0,0
        Rect 0,0,640,480,False
        Rect 1,1,638,478,False
    End If

    Text 0,0,"Arrow keys: fly the ship into the asteroid   Esc: exit"
    If hit Then
        Text 0,20,"ImagesCollide=1 - solid pixels really touch"
    Else
        Text 0,20,"ImagesCollide=0 - corners do not count, only solid pixels"
    End If

    Flip

Wend

End

Index