SpriteCollisionMode
SpriteCollisionMode SpriteNumber, Mode
 
Parameters:

    SpriteNumber = The Index of the sprite you wish to set the collision mode of
    Mode = The collison mode value
Returns: NONE
 

      The SpriteCollisionMode command sets the type of collision mode this sprite should use. Currently there are seven modes to choose from. Which range from simple rectangular intersections through to automatic sliding collision and pixel perfect.


Available Collision Modes

      Mode 0 - Static Rectangle
      Mode 1 - Rotated Rectangle
      Mode 2 - Circle
      Mode 3 - Shape
      Mode 4 - Sliding Collision (Worlds Only)
      Mode 5 - Sticky Collision (Worlds Only)
      Mode 6 - Pixel Perfect




Overview of Collision Modes



Mode #0 - Rectangle




      This is the simplest and default sprite collision mode available. When sprites are set to Rectangle mode, the sprite collision engine will use the rectangular area of it's image size (width, height) as the impact zone. So any sprite the overlays this area, will return a positive impact.

      Since the rectangular area is not rotated, This mode is obviously best suited for sprites that don't rotate.




Mode #1 - Rotated Rectangle



      When sprites are set to Rotated Rectangle mode, the sprite collision engine will use the rectangular area of it's image size, rotated and scaled to the sprites current rotation and size. This rotated rectangular shape will become the impact zone. So any sprite the overlays this area, will therefore return a positive impact.

      This mode is obviously best suited for sprites that need to rotate/scale.



Mode #2 - Circle




      When set circle mode, the sprite uses a circular region for the impact zone. Any sprite that overlaps the sprites circular zone will return a positive impact.

      It's important to note that the circle region is considered from the sprites position.

      Note: Sprite handles or scaling won't affect this.




Mode #3 - Shape



      This is one of the most powerful collision modes. Via the use of shapes that are attached to your images, you can perform ultra fast pixel perfect/rotated/scaled collisions between sprites, without the overhead of performing per pixel image masking (which is how such effects are normally done).

      When the sprite is set to shape mode, the sprite uses the Shape associated with the sprites currently assigned Image (the image that is set via SpriteImage) for it's collision zone. This requires that you've previously created a shape that represents the 'hard' region of this image.

      This mode is for use when you require highly accurate and zone/pixel perfect collisions between sprites, rotated or otherwise.





Mode #4 - Sliding Collision (Worlds Only)



      Sliding collision mode enables a sprite to perform sliding sliding against a world. In case your not familiar with Sliding collision, normally when an impact occurs between a sprite and your environment, the programmer has to reposition then sprite accordingly. Not only so the sprite doesn't get stuck on the environment, but so the sprite appears to smoothly navigate the environment as well. This can be fairly tricky to do. So we built it in!

      Sliding collision is circular. The collision and sliding occur between the sprites circle region and the sprites associated world. It's important to note that collision and sliding can only occur between the sprites circular region and lines (the walls) in the world. So by design, before you can use sliding collision, you must outline those regions your sprites should slide off.

      When sliding collision is enabled, you'll need to use the MoveSprite commands to move your sprite. As only the move sprite commands are capable to performance the sliding automatically for you.

      Since sliding collision is automatic, it can be very useful to see if a collision has occurred. You can check if you hit something using the GetSpriteWorldImpact and GetSpriteImpactObject commands


Note: About Sliding Collision:


      Sliding collision systems are based upon the assumption that the player (the sprite) is never positioned inside a solid region. As the sliding works via keeping the player on one side of the wall segments (the outside). If the player is on the inside of a region, the walls that define the solid region are ignored as their back facing the player.



Mode #5 - Sticky Collision (Worlds Only)



      Sticky collision mode enables a sprite to perform sticky (stop upon impact) collision against a world. Unlike sliding collision the Sticky mode stops the sprite at it's first point of contact with the world. This allows the user to manually del with sprite to world collisions.

      When sticky collision is enabled, you'll need to use the MoveSprite commands to shift your sprite. As only the move sprite commands are capable to performance the collision automatically for you.

      You can check if impact occurs after any movement using the GetSpriteWorldImpact function. This function will return a true if there was an impact. The impact point and normal at the point of impact can be obtained using the GetNormalX#/Y and GetIntersectX#/Y functions




Mode 6 - Pixel Perfect



      When sprites are set to Pixel Perfect mode, the sprite collision engine can detect collisions between sprites on a per pixel basis. Regardless of the sprites rotation/scaling. The collision engine is also powerful enough to detect collisions between vector shapes and sprite pixels. So a sprites set to rotated collision mode (1) can impact on a sprites set to pixel mode(6), or a sprites set to shape(3) mode can hit on pixel sprite(6) and vice versa.

      It's important to understand that Pixel level collisions always assume were comparing two transparent sprite images or a solid vector region from another sprite to a transparent sprite image. Obviously, if the sprite is solid, that would make every pixel hard. i.e. a solid rectangle. Making performing a pixel level comparison pointless.

      Since detecting sprite collisions on a Pixel Perfect level, this can be a very resource insensitive operation. As such, we've included a control to set the collision accuracy that you require. As general rule, the higher the accuracy, the slower such calculations can become.

      You can control collision accuracy using the SpriteCollisionAccuracy command. Which defaults to 1.0. A setting of 1.0 represents a 1 to 1 comparison (100% in other words). Generally speaking that's overkill though. %50 -> %75 is good trade off. Often you can go even lower and barely notice it.


      This mode is best if you absolutely need pixel level collisions. Otherwise use Shape mode.

      Note: When using pixel perfect collisions it's critical important that the sprites images be prepared as FX images (PrepareFXIMage, LoadFxIMage, NewFxImage.

      Note: Since sprites can be rotated and scaled, you'll possibly loose some pixel accuracy through linear interpolation. So if your game requires a lot of scaling down for example, then you might want to bump up the collision accuracy in those cases. It's always going to be trade off between speed and accuracy. So experiment and see what works best in your game.






FACTS:


      * Sprites Collision mode defaults to mode 0 (rect)






Mini Tutorial:


      This example is in 3 parts,

      Part 1 creates two coloured images.

      Part 2 then creates both out test sprite (sprite #1) and a group of randomly positioned/rotated sprites to check rotated collisions against.

      Part 3 The main loop, is where if checks for any collisions between sprite #1 and the other sprits have occured. If so, it prints the index of the sprite that was hit, and then continues checking until all sprites have been checked.


  
  MakeBitmapFont 1,$ffffff
  
; ====================================
; Part 1 - Create two coloured images
; ====================================
  
  Cls RGB(0,0,255)
  GetImage 1,0,0,32,32
  PrepareFXImage 1
  
  Cls RGB(0,155,100)
  GetImage 2,0,0,32,32
  PrepareFXImage 2
  
  
; =============================
; Part 2- Create some sprites
; =============================
  
; Create Sprite 1, and assign it image 1
  CreateSprite 1
  SpriteImage 1,1
  CenterSpriteHandle 1
  
; Set Sprites Drawing mode to rotated
  SpriteDrawMode 1,2
  
; Rotate this sprite 45 degree
  RotateSprite 1,45
  
; Enable Collision for Sprite #1
  SpriteCollision 1,on
  
; Set Sprite #1 to collision Class %0001
  SpriteCollisionClass 1,%0001
  
; Set Sprite #1 to collision mode to 1 (rotated)
  SpriteCollisionMode 1,1
  
  
  
; =====================================================
; Create a bunch of sprites to check collision against
; =====================================================
  
  For Sprites=2 To 50
     
     CreateSprite Sprites
     SpriteImage Sprites,2
     CenterSpriteHandle Sprites
     x=Rnd(GetScreenWidth()-32)
     y=Rnd(GetScreenHeight()-32)
     PositionSprite sprites,x,y
     
   ; Set the sprites draw mode/rotation and scale
     SpriteDrawMode Sprites,2
     RotateSprite Sprites,Rnd(360)
     ScaleSprite Sprites,0.5+(Rnd(100)/100.0)
     
   ; Enable Collision for this sprite
     SpriteCollision Sprites,on
   ; Set sprite to Collision Class %0010
     SpriteCollisionClass Sprites,%0010
   ; Set sprite to Collision mode 1 (rotated)
     SpriteCollisionMode Sprites,1
     
  Next
  
  
  
; =============================
; Part 3- The Main Loop
; =============================
  
; Start a DO/Loop
  Do
   ; Clear the screen
     Cls RGB(0,0,0)
     
   ; Display a message
     Print "Checking For Sprite Collisions"
     Print "Hit Space Bar to Toggle Sprite Debug mode"
     
     
   ; turn all the sprites
     For Sprites=1 To 50
        SpriteDrawMode Sprites,2
        If sprites>1 Then TurnSprite Sprites,0.15
        SpriteCollisionDebug Sprites,Debugflag
     Next
     
     
   ; Position the Sprite 1 at the mouses position
     PositionSprite 1,MouseX(),MouseY()
     
   ; Check if sprite #1 hit another sprite
   ; of this sprite class
     ThisSprite=SpriteHit(1,GetFirstSprite(),%0010)
     
   ; If there was impact, then we loop through and
   ; find any other sprites we might have also hit
     While ThisSprite>0
        Print "Hit Sprite:"+Str$(ThisSprite)
      ; set the sprites draw mode to rotated+Alpha colour fade
        SpriteDrawMode ThisSprite,2+4096
        
      ; Check if this sprite hit another sprite ?
     NextSprite=GetNextSprite(ThisSprite)
     ThisSprite=SpriteHit(1,NextSprite,%0010)
  EndWhile
  
  
  If SpaceKey() Then DebugFlag=1-debugFlag
  
  
; Draw All of the sprites
  DrawAllSprites
  
; Draw the screen
  Sync
  
; Loop back to the DO statement
  Loop
  
  




 
Related Info: CompareSpritePixels | EllipseHitSpritePixels | GetSpriteCollisionClass | GetSpriteCollisionDebug | GetSpriteCollisionMode | GetSpriteCollisionRadius | PointHitSprite | PointHitSpritePixels | QuadHitSprite | QuadHitSpritePixels | RayHitSprite | RectHitSprite | RectHitSpritePixels | SpriteCollision | SpriteCollisionAccuracy | SpriteCollisionClass | SpriteCollisionDebug | SpriteCollisionRadius | SpriteHit :
 


(c) Copyright 2002 - 2024 - Kevin Picone - PlayBASIC.com