7. Collisions
Ya gotta have collisions! Whether you are trying to keep your character from walking through walls or other characters or maybe you want to launch a projectile at another object, collisions are required. Blitz makes collisions EASY so get ready for a quick lesson!

If you haven't already downloaded the tutorial files do so now, unzip to your desktop and OPEN up lesson7.bb, functions7.bb, and loadworld7.bb (below) and RUN / LANUCH the lesson7.bb program by pressing the ROCKET ICON

and you should see this...

NEW CODE is BOLD.

Here's the CODE!
lesson7.bb

Include "functions7.bb"

Global escape_key = 1
Global screen_width = 640, screen_height = 480

Graphics3D screen_width, screen_height, 16, 2
SetBuffer BackBuffer()


; Collision types
Global coll_player = 1, coll_characters = 2, coll_objects = 3

; Set collisions
Collisions coll_characters, coll_player, 1, 2
Collisions coll_player, coll_characters, 1, 2
Collisions coll_player, coll_objects, 1, 2
Collisions coll_characters, coll_characters, 1, 2
Collisions coll_characters, coll_objects, 1, 2

AmbientLight 200, 200, 200
light1 = CreateLight(2)

cam1 = CreateCamera()
CameraViewport cam1, 0, 0, screen_width, screen_height

Include "loadworld7.bb"

LoadMusic()
LoadSFX()

MoveMouse screen_width/2, screen_height/2

While Not KeyHit( escape_key )

    MoveCharacters( player )
    If run_vol# > 0 Then AnimSprite( player, anim_tex, 200, 4 )
    object_key_control( player )
    ChannelVolume runchannel, run_vol#
    PositionEntity sky, EntityX( player ), EntityY( player ), EntityZ( player )

    UpdateWorld
    RenderWorld

    ; 2D here


Flip
Wend

End


loadworld7.bb

. . .
For C=1 To 3
    Character.Sprite = New Sprite
    Character\ID = CreateSprite()
    Read temper, img$, X, Y, Z, X2, Y2, Z2
    Character\char_tex = LoadAnimTexture( img$, 7, 32, 48, 0, 4)
    EntityTexture Character\ID, Character\char_tex, 1
    HandleSprite Character\ID, 0, -1
    ScaleSprite Character\ID, 2, 2
    EntityAutoFade Character\ID, 100, 120
    PositionEntity Character\ID, X, Y, Z

    Character\temper = temper
    Character\pt1 = CreatePivot() : Character\pt2 = CreatePivot()
    PositionEntity Character\pt1, X, Y, Z
    PositionEntity Character\pt2, X2, Y2, Z2
    Character\targetpt = Character\pt2

    ; Set collision type
    EntityRadius Character\ID, 1
    EntityType Character\ID, coll_characters

Next
. . .
player = CreateSprite()
anim_tex=LoadAnimTexture( "char_back.bmp",7,32,48,0,4)
EntityTexture player, anim_tex, 1
HandleSprite player,0,-1
ScaleSprite player, 2, 2
PositionEntity player, 0, 0, 5
EntityParent cam1, player

; Set collision type
EntityRadius player, 1
EntityType player, coll_player

. . .
cone1 = CreateCone()
PositionEntity cone1, 0, 0, 50
ScaleEntity cone1, 30, 30, 30
texture2 = LoadTexture("rough.jpg")
ScaleTexture texture2, .2, .2
EntityTexture cone1, texture2

; Set collision type
EntityRadius cone1, 15
EntityType cone1, coll_objects



functions7.bb

. . .
Function LoadRandomSprites(sprite$, total, x1, x2, z1, z2)
   temp_sprite=LoadSprite( sprite$ , 7 )
   HandleSprite temp_sprite,0,-1
   SpriteViewMode temp_sprite,3
   EntityAutoFade temp_sprite,100,120

   ; Set collision type
   EntityType temp_sprite, coll_objects
   EntityRadius temp_sprite, 1

   For s=1 To total
      sx#=Rnd(x1,x2) : sz#=Rnd(z1,z2)
      copied_sprite=CopyEntity( temp_sprite )
      PositionEntity copied_sprite, sx, 0, sz
      ScaleSprite copied_sprite,Rand(2,3),Rand(4,6)
   Next
   FreeEntity temp_sprite

End Function
. . .


NEW COMMANDS
lesson7.bb

. . .
; Collision types
Global coll_player = 1, coll_characters = 2, coll_objects = 3

; Set collisions
Collisions coll_characters, coll_player, 1, 2 ; characters can't walk through you
Collisions coll_player, coll_characters, 1, 2 ; you can't walk through characters
Collisions coll_player, coll_objects, 1, 2 ; you can't walk through trees
Collisions coll_characters, coll_characters, 1, 2 ; characters can't walk through characters
Collisions coll_characters, coll_objects, 1, 2 ; characters can't walk through trees
. . .

In our main program we need to arbitrarily create different kinds of object collision categories
for the player, the characters and environment objects with
Global coll_player = 1, coll_characters = 2, coll_objects = 3


Once we decide on the object kinds we choose the style of collision detection and responses for all the combinations of object collisions we care about (listed above). Collisions coll_characters, coll_player, 1, 2 causes collisions between the characters and you the player.
Here is the format:
Collisions src_type, dest_type, method, response

src_type
- entity type to be checked for collisions.
dest_type - entity type to be collided with.

method - collision detection method.
1: ellipsoid-to-ellipsoid collisions
2: ellipsoid-to-polygon collisions
3: ellipsoid-to-box collisions

response - what the source entity does when a collision occurs.
1: stop
2: slide1 - full sliding collision
3: slide2 - prevent entities from sliding down slopes

loadworld7.bb

. . .
For C=1 To 3
    . . .
    ; Set collision type
    EntityRadius Character\ID, 1
    EntityType Character\ID, coll_characters

Next
. . .
player = CreateSprite()
. . .

; Set collision type
EntityRadius player, 1
EntityType player, coll_player

. . .
cone1 = CreateCone()
. . .

; Set collision type
EntityRadius cone1, 15
EntityType cone1, coll_objects


When doing collisions, especially with sprites that have no 3D collision volume, we must give some of our objects artificial volumes with EntityRadius. Next we assign the collision type with EntityType to the objects we care about, i.e. player, Character\ID, and cone1.
EXPERIMENT !
Change EntityRadius player, 1
to EntityRadius player, 10 and see what happens
Undo your changes

function7.bb

. . .
Function LoadRandomSprites(sprite$, total, x1, x2, z1, z2)
   . . .
   ; Set collision type
   EntityType temp_sprite, coll_objects
   EntityRadius temp_sprite, 1 ;sprites need fake volume for collisions
    . . .

End Function
. . .

Again, and lastly, we also modify our LoadRandomSprites(sprite$, total, x1, x2, z1, z2) for collisions, using EntityRadius and assign the collision type with EntityType temp_sprite, coll_objects.


NEXT : Lesson 8 - Projectiles