Tutorial 05 - Collision Detection and Material Collisions
This tutorial shows how control collisions with materials and how to use ppIsaac's collision detection system. At first the source code:
SuperStrict
Import pyroplay.ppisaac
Graphics 800,600
' this is only because of the ppIsaac logo that uses black color and I don't want it to be transparent
SetMaskColor(255 , 255 , 0)
' initialise ppIsaac
ppIsaac.Start()
ppIsaac.gravity.y = 20000
ppIsaac.SetWorldSize(0,0,800,600)
ppIsaac.SetGlobalCollisionDetection(True)
' create some objects
Local ground:ppBox = ppBox.Create(394 , 415 , 541 , 46 , 0)
ground.LoadTexture("media/brick.png")
ground.SetAngle(15)
Local box01:ppBox = ppBox.Create(200,200, 128,128, 5)
box01.LoadTexture("media/box_texture.png")
Local box02:ppBox = ppBox.Create(300,0, 128,128, 5)
box02.LoadTexture("media/box_texture.png")
box02.SetCollisionDetection(False)
' create Materials
Global matWood:ppMaterial = ppMaterial.Create()
Global matStone:ppMaterial = ppMaterial.Create()
Global matGround:ppMaterial = ppMaterial.Create()
' set the material to the objects
ground.SetMaterial(matGround)
box01.SetMaterial(matWood)
box02.SetMaterial(matStone)
' set collision between different materials
ppMaterial.SetCollision(matGround, matWood, True)
ppMaterial.SetCollision(matGround, matStone, False)
ppMaterial.SetCollision(matWood, matStone, False)
' Load a soundfile to play on collision
Local sound:TSound = LoadSound("media/click01.ogg")
' Load an background image
Local img_background:TImage = LoadImage("media/background01.png")
While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
Cls
SetColor 255,255,255
DrawImage img_background, 0,0
ppIsaac.Draw()
ppIsaac.Update()
If MouseHit(1) Or MouseHit(2) Then
ppIsaac.AddExplosion(MouseX(),MouseY(), 1000000000)
EndIf
If box01.CollisionBegin = ground Then PlaySound(sound)
'If box01.CollisionProcess = ground Then PlaySound(sound)
'If box01.CollisionEnd = ground Then PlaySound(sound)
If box02.CollisionBegin = ground Then PlaySound(sound)
DrawText "fps:" + ppIsaac.GetFPS(), 10,10
DrawText MouseX() + "," + MouseY(), 10,20
Flip
Wend
ppIsaac.Stop()
End
In ppIsaac you will find the terms 'collision' and 'collision detection'. Collision means the physical collision, the reaction of the two bodies when they collide. On the other hand collision detection means the detection if two objects that are overlapping.
Now this initialises ppIsaac:
' initialise ppIsaac
ppIsaac.Start()
ppIsaac.gravity.y = 20000
ppIsaac.SetWorldSize(0,0,800,600)
ppIsaac.SetGlobalCollisionDetection(True)
The following line tells ppIsaac to do collision detection.
ppIsaac.SetGlobalCollisionDetection(True)
In the prevous examples I had set ppIsaac.SetGlobalCollisionDetection(False) since we don't need collision detection there and it saves some calculation cycles.
Ok, we have ppIsaac properly initialised and told it to look for any overlapping geometries. Now we need some objects to collide with:
' create some objects
Local ground:ppBox = ppBox.Create(394 , 415 , 541 , 46 , 0)
ground.LoadTexture("media/brick.png")
ground.SetAngle(15)
Local box01:ppBox = ppBox.Create(200,200, 128,128, 5)
box01.LoadTexture("media/box_texture.png")
Local box02:ppBox = ppBox.Create(300,0, 128,128, 5)
box02.LoadTexture("media/box_texture.png")
box02.SetCollisionDetection(False)
Have a look at the following line:
box02.SetCollisionDetection(False)
ppIsaac.SetGlobalDetection() sets the collision detection on or off for all objects. But every object can set the collision detection on and off individually. The line above deactivates the collision detection for the box2 object (we do this here just to show you this functionalitiy). If GlobalCollisionDetection is off you cannot detect any collisions, even if you have set the individual collision detection on.
The next part creates some materials:
' create Materials
Global matWood:ppMaterial = ppMaterial.Create()
Global matStone:ppMaterial = ppMaterial.Create()
Global matGround:ppMaterial = ppMaterial.Create()
The following assigns the materials to the objects:
' set the material to the objects
ground.SetMaterial(matGround)
box01.SetMaterial(matWood)
box02.SetMaterial(matStone)
Now this the interesting part:
' set collision between different materials
ppMaterial.SetCollision(matGround, matWood, True)
ppMaterial.SetCollision(matGround, matStone, False)
ppMaterial.SetCollision(matWood, matStone, False)
The above code set the collision between these materials on (true) and of (false). This concerns the physical collisions. As you can see matGround and matWood does not collide with matStone which means that box02 will fall through box01 and the ground object. If you try to set the collision between matGround and matStone to True, you will see that box2 will fall through box01 but collides with the ground object. By using materials to control the collision you can set a whole bunch of objects to do not collide with a certain different material group. Now this is handy, isn't it?
Ok, last part to examine is this:
If box01.CollisionBegin = ground Then PlaySound(sound)
'If box01.CollisionProcess = ground Then PlaySound(sound)
'If box01.CollisionEnd = ground Then PlaySound(sound)
If box02.CollisionBegin = ground Then PlaySound(sound)
In fact this is the collision detection. An object in ppIsaac does have three collision detection states: Begin, Process and End. Therefore every object does have the CollisionBegin, CollisionProcess and CollisionEnd variables. Each of these three variables contain the object that is involved in the collision or Null if no collision occurs.
CollisionBegin: this variable is set when the object has not touched before.
CollisionProcess: this is set when the same object does already touched the object in the program cycle before.
CollisionEnd: this is set when the object has touched the object in the last program cycle but now it is not touching anymore.
In the above example I have already written all three collision states to be checked but did comment them out. Please try the other collision detection states of box01 to get an example, what the three collison detection states mean and when they are called.
You can see that box02 should also play a sound when it collides with the ground object. But it does not. This because of
box02.SetCollisionDetection(False)
which we set up above. Set it to true and box02 should play a sound when it hits the ground, too.
Thats it for today.
Links:
ppIsaac Product Page
Tutorial 01 - Hello Isaac!
Tutorial 02 - Static and Dynamic Objects
Tutorial 03 - Texture and Materials
Tutorial 04 - Joints