UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on May 29, 2006, 01:38:10 PM

Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on May 29, 2006, 01:38:10 PM
  While PlayBASIC has included vector based engine since 2003/2004, but we've finally implemented a traditional pixel level collisions.   In case your unsure, Pixel Perfect Collision  lets you detect collision between sprites on a per pixel basis. So if any pixel overlaps a collision is registered. It doesn't matter if the sprites are scaled, rotated, inverted whatever. The collision engine in PlayBasic can handle it for you.

 To expand upon this, I'm also looking adding controls to detect collisions between vector shapes (rects/circles/lines/polygons) and sprites on a per pixel basis. So pixel perfect collisions can be combined with vector collisions.

 [plink] Simple Screen at TGC (http://forum.thegamecreators.com/?m=forum_view&t=80342&b=4&p=0)[/plink]
 
 Atm, the collision has handled through a temp test command which compares two sprites.  Pretty simple.  That will no doubt vanish and to be handled via the sprite collision engine..  

 

[pbcode]

   w=100
   h=100
   LoadImage "ship.bmp",1
   ScaleImage 1,w,h,1
   PrepareFXImage 1   
   

   Spr   =NewSprite(450,150,1)
   Spr2   =NewSprite(400,200,1)
   
   SpriteDrawMode spr,2
   RotateSprite spr,45
   CenterSpriteHandle spr

   SpriteDrawMode spr2,2
   ScaleSpriteXY spr2,2,3
   CenterSpriteHandle spr2
   RotateSprite spr2,10

   Do

 Cls RGB(100,100,100)
 SpriteDrawMode spr2,2

 PositionSprite spr,MouseX(),MouseY()  

 TurnSprite spr,(-1*LeftKey())+(1*RightKey())   
 TurnSprite spr2,0.25
 
 result=CompareSpritePixels(spr,spr2)
 If result
    SpriteDrawMode spr2,2+4096
    CenterText 400,50,"Sprites Hit"
 EndIf

 DrawAllSprites
   

 Sync
   Loop   
   End

[/pbcode]
Title: Pixel Perfect (rotated/scaled) Collision
Post by: Ian Price on May 29, 2006, 04:37:49 PM
Excellent news and something that I've been waiting for. :)

I don't mind a reduction in speed - the benefits of pixel-perfect collisions far outweigh a speed-loss (unless it's really significant).
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on May 29, 2006, 11:09:18 PM
erm, what benefits ?
Title: Pixel Perfect (rotated/scaled) Collision
Post by: Ian Price on May 30, 2006, 01:41:10 AM
Well for a start it saves having to fart around using vectors/shapes! :P

Your new animation tool may well help on that score, but I've never personally liked that idea - maybe it's because throughout my coding history, I've had access to pixel perfect collision and have been spoiled by it's ease of use and it's accuracy whn it's needed.

You perhaps prefer your method, and that's fair enough, but I prefer mine. I've never particularly liked bounding box collision either for games that need a bit more accuracy.

My JetPak remake could have done with pixel perfect collision, given that even true vector/shape collision info wasn't really available at the time of the comp.
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 01, 2006, 12:01:40 PM
Vector to Pixel Collision

  I've made few changes to the how this is implemented.  The most notable is that you can set an accuracy value. Which scales the span comparisons.  So you can reproduce the overhead when segment overlap but setting the accuracy value bellow 1,  For more accuracy set it higher that 1.      The more accuracy the slower and more cache memory is used.   Just so your aware setting it two 2 say, creates 4 times the pixel comparisons.    

 Anyway, i've also implemented the base segment to image comparisons routines.  So you can now check a vector shape for impacts against the pixels of a rotated, scaled sprite.  See BoxHitSpritePixels bellow.



[pbcode]

   LoadImage "ship.bmp",1
   PrepareFXImage 1   
   
   Spr   =NewSprite(450,150,1)
   SpriteDrawMode spr,2+4096
   SpriteAlphaAddColour spr,RGB(255,0,255)
   RotateSprite spr,45
   CenterSpriteHandle spr
   SpriteCollisionMode Spr,1


   max=10
   Dim Sprites(MAx)

   For lp=1 To max
 Spr2   =NewSprite(Rnd(800),Rnd(600),1)
 SpriteDrawMode spr2,2
 SpriteCollisionMode Spr2,1
;  SpriteCollisionDebug Spr2,True
 CenterSpriteHandle spr2
 ScaleSprite Spr2,RndRange(3,3)
 RotateSprite spr2,10
 Sprites(lp)=spr2
   Next

   PositionSprite sprites(1),400,300

 Do
   
    Cls RGB(100,100,100)

    PositionSprite spr,MouseX(),MouseY()  
    TurnSprite spr,(-1*LeftKey())+(1*RightKey())   

   For lp=1 To max
      Spr2=Sprites(lp)
      SpriteDrawMode spr2,2
      SpriteAlphaAddColour spr2,$00ff00
      TurnSprite spr2,0.55
      If CompareSpritePixels(spr,spr2,0.50)
     SpriteDrawMode spr2,2+4096
      EndIf
   Next

   rX1=MouseX()
   rY1=MouseY()
   rX2=rX1+200    
   rY2=rY1+200

   LockBuffer
   For lp=1 To max
      Spr2=Sprites(lp)
      If BoxHitSpritePixels(rx1,ry1,rx2,ry2,spr2,1)
     SpriteDrawMode spr2,2+4096
     SpriteAlphaAddColour spr2,$0000ff
      EndIf
   Next
   UnLockBuffer

   BoxC rx1,ry1,rx2,ry2,False,$255

   DrawAllSprites

    Sync
 Loop   
 End


[/pbcode]

Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 01, 2006, 02:36:54 PM
Ellipse to Sprite Pixels Collision  

    This piccy shows that you can check if a ellipse intersects a sprites pixels.  Rect are already implemented but i still have Dot / Quad & shape to do and probably a line/ray to sprite intersection also.  But we'll see.
Title: Pixel Perfect (rotated/scaled) Collision
Post by: thaaks on June 01, 2006, 02:42:16 PM
We are nearly there, Houston...  :P

Looks and sounds great! Pixel perfect and shape collision as a mixture is certainly an outstanding feature.

What about the new VM? Any plans when you'll start on that beast?

Cheers,
Tommy
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 01, 2006, 03:02:28 PM
QuoteAny plans when you'll start on that beast

     With any luck, before the end of time.  While there's always more than a few tidbits on the 'wouldn't it be cool list',  this is pretty much it for PB VM in it's current state.  I'm not even sure i'll spend any time implementing these test commands into the existing collision frame work.  Which means, it might take 2 lines of code resolve a sprite collision. Heaven forbid..
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 01, 2006, 04:39:15 PM
   Triangle to Sprite Pixels Collision

 Added Triangle to sprite method, which will cover quads also.



[pbcode]


   LoadImage "ship.bmp",1
   PrepareFXImage 1   
   
   Spr   =NewSprite(450,150,1)
   SpriteDrawMode spr,2+4096
   SpriteAlphaAddColour spr,RGB(255,0,255)
   RotateSprite spr,45
   CenterSpriteHandle spr
   SpriteCollisionMode Spr,1

   w=getimagewidth(1)
   h=getimageheight(1)

   max=100
   Dim Sprites(MAx)

   For lp=1 To max
 Spr2   =NewSprite(Rnd(800),Rnd(600),1)
 SpriteDrawMode spr2,2
 SpriteImageUV spr2,0,6,6
 SpriteImageUV spr2,1,w-6,6
 SpriteImageUV spr2,2,w-6,h-6
 SpriteImageUV spr2,3,6,h-6

 SpriteCollisionMode Spr2,1
;  SpriteCollisionDebug Spr2,True
   
 CenterSpriteHandle spr2
 RotateSprite spr2,10
 Sprites(lp)=spr2
   Next

   PositionSprite sprites(1),400,300

 Do
    Cls RGB(100,100,100)

    PositionSprite spr,MouseX(),MouseY()  
    TurnSprite spr,(-1*LeftKey())+(1*RightKey())   

   For lp=1 To max
      Spr2=Sprites(lp)
      SpriteDrawMode spr2,2
      SpriteAlphaAddColour spr2,$00ff00
      TurnSprite spr2,0.55
      If CompareSpritePixels(spr,spr2,0.50)
     SpriteDrawMode spr2,2+4096
      EndIf
   Next

   mX=MouseX()
   mY=MouseY()



   x1=mx
   y1=my

   x2=x1+250
   y2=y1+30
   x3=x1+90
   y3=y1+240
   
   

   TriC x1,y1,x2,y2,x3,y3,$1abb55

   LockBuffer
   For lp=1 To max
      Spr2=Sprites(lp)
      If TriangleHitSpritePixels(x1,y1,x2,y2,x3,y3,spr2,0.5)
     SpriteDrawMode spr2,2+4096
     SpriteAlphaAddColour spr2,$ffff00
      EndIf
   Next
   UnLockBuffer





   DrawAllSprites

    Sync
 Loop   
 End



[/pbcode]

Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 02, 2006, 11:02:45 AM
Quads to Sprite Pixel Collisions

Added compare Quad (poylgon) to sprite pixels collision method..
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 02, 2006, 12:18:10 PM
and now you test if point hits a sprites pixels using PointHitSpritePixels(x,y,sprite,accuracy#)
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 02, 2006, 04:12:06 PM
  Line To Sprite Pixel

   Here's another screenie.  This one is testing the latest  LineHitSpritePixels() command.  While it can detect if an Intersection occurs, it can't return the first  point/normal of intersection.  That's not so easy..

  Also added PointHitSpritePixels().  So you can detect if a pixel overlaps a rotated/scale sprites pixels



[pbcode]


   LoadImage "ship.bmp",1
   PrepareFXImage 1   
   
   Spr   =NewSprite(450,150,1)
   SpriteDrawMode spr,2+4096
   SpriteAlphaAddColour spr,RGB(255,0,255)
   RotateSprite spr,45
   CenterSpriteHandle spr
   SpriteCollisionMode Spr,1

   w=GetImageWidth(1)
   h=GetImageHeight(1)

   max=100
   Dim Sprites(MAx)

  p=6

   For lp=1 To max
 Spr2   =NewSprite(Rnd(800),Rnd(600),1)
 SpriteDrawMode spr2,2
 SpriteImageUV spr2,0,p,p
 SpriteImageUV spr2,1,w-p,p
 SpriteImageUV spr2,2,w-p,h-p
 SpriteImageUV spr2,3,p,h-p

 SpriteCollisionMode Spr2,1
 CenterSpriteHandle spr2
;  ScaleSprite Spr2,RndRange(1,3)
 RotateSprite spr2,10
 Sprites(lp)=spr2
   Next

   PositionSprite sprites(1),400,300

 Do
    Cls RGB(100,100,100)

;  PositionSprite spr,MouseX(),MouseY()  
    TurnSprite spr,(-1*LeftKey())+(1*RightKey())   

   For lp=1 To max
      Spr2=Sprites(lp)
      SpriteDrawMode spr2,2
      SpriteAlphaAddColour spr2,$00ff00
      TurnSprite spr2,0.55
      If CompareSpritePixels(spr,spr2,0.50)
     SpriteDrawMode spr2,2+4096
      EndIf
   Next

   mX=MouseX()
   mY=MouseY()


   Dot mx,my

   LockBuffer
      For lp=1 To max
     Spr2=Sprites(lp)
     If PointHitSpritePixels(mx,my,spr2,0.5)
        SpriteDrawMode spr2,2+4096
        SpriteAlphaAddColour spr2,$ffff00
     EndIf
      Next
   UnLockBuffer



   Line lastx,lasty,mx,my

   LockBuffer
      For lp=1 To max
     Spr2=Sprites(lp)
     If LineHitSpritePixels(lastx,lasty,mx,my,spr2,1)
        SpriteDrawMode spr2,2+4096
        SpriteAlphaAddColour spr2,$00ffff
     EndIf
      Next
   UnLockBuffer

   If MouseButton()=2
      lastx=mx
      lasty=my    
   EndIf

   DrawAllSprites

    Sync
 Loop   
 End



[/pbcode]

Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 03, 2006, 07:51:12 PM
Line To Sprite Pixel Cont.

 Had a few unexpected issues with LineHitSpritePixels() command. BUt it's fixed now.
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 11, 2006, 01:26:56 PM
Convex / Concave & Complex Polygon Shape  to Sprite Pixel Collisions

  This pic shows the most recent (and most difficult)  intersection, that being comparing polygon shapes to sprite pixels. Speed wise it's ok, already. Even though implementation is still in it infancy, so there's certainly some room for some fine tuning.   But, it's certainly doable... :)
Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 11, 2006, 01:50:17 PM
The above example.

[pbcode]

   LoadImage "ship.bmp",1
   PrepareFXImage 1   
   
   Spr   =NewSprite(450,150,1)
   SpriteDrawMode spr,2+4096
   SpriteAlphaAddColour spr,RGB(255,0,255)
   RotateSprite spr,45
   CenterSpriteHandle spr
   SpriteCollisionMode Spr,1

   w=GetImageWidth(1)
   h=GetImageHeight(1)

   max=25
   Dim Sprites(MAx)

  p=6
   
 For lp=1 To max
    Spr2   =NewSprite(Rnd(800),Rnd(600),1)
    SpriteDrawMode spr2,2
    SpriteImageUV spr2,0,p,p
    SpriteImageUV spr2,1,w-p,p
    SpriteImageUV spr2,2,w-p,h-p
    SpriteImageUV spr2,3,p,h-p
;  spritetransparent spr2,off
   
    SpriteCollisionMode Spr2,1
    CenterSpriteHandle spr2
    ScaleSprite Spr2,RndRange#(1,2)
    RotateSprite spr2,10
    Sprites(lp)=spr2
 Next

   PositionSprite sprites(1),400,300


   TestSHape=NewConvexShape(150,4)
   TestSHape2=NewConvexShape(100,5)
   MergeShape TestShape2,TestShape   
   
   gfxmmx on

   Do
    Cls RGB(100,100,100)

;  PositionSprite spr,MouseX(),MouseY()  
    TurnSprite spr,(-1*LeftKey())+(1*RightKey())   

   For lp=1 To max
      Spr2=Sprites(lp)
      SpriteDrawMode spr2,2
      SpriteAlphaAddColour spr2,$00ff00
      TurnSprite spr2,(LP/10.0)*0.55
      If CompareSpritePixels(spr,spr2,0.5)
     SpriteDrawMode spr2,2+4096
      EndIf
   Next

   mX=MouseX()
   mY=MouseY()


;    mx=300
   my=300



   LockBuffer
      For lp=1 To max
     Spr2=Sprites(lp)
     If ShapeHitSpritePixels(TestShape,mx,my,0,1,1,spr2)
        SpriteDrawMode spr2,2+8192
        SpriteAlphaAddColour spr2,$0000ff
     EndIf
      Next
   UnLockBuffer


   drawshape testshape,mx,my,2



   If MouseButton()=2
      lastx=mx
      lasty=my    
   EndIf

   DrawAllSprites



    Sync

 Loop   
 End




[/pbcode]

Title: Pixel Perfect (rotated/scaled) Collision
Post by: kevin on June 13, 2006, 12:48:17 PM
Optimized Polygon Shape to Sprite Pixels Intersections

   Here's another WIP (probably final) shot of the Shape to sprite pixel command.  The command has been debugged and optimized some what. The optimization has given about *2  performance increase.  Of course this only applies to certain types of  overlapping segments, but hey, given that his is a unique feature to PlayBasic, you can't complain :)..
Title: Pixel Perfect (rotated/scaled) Collision
Post by: thaaks on June 13, 2006, 01:47:11 PM
How many forums do you visit today?  :P

I assume we have to register to see the pics, hmm?

What about fixing this forum to enable download/image viewing again?
Or switching to some new forum software?

I mean, currently I follow some of your steps at CodersTurf, in the 2D section of the game creators and here - and honestly that's enough for me...

Could you please decide what forum will be the main one for piccies (if not this one, which is a pity :( ) and tell us addicts?

Thanks,
Tommy
Title: Pixel Perfect (rotated/scaled) Collision
Post by: stef on June 20, 2006, 01:15:07 PM
Hi!

The example above (with shape) doesn't work.

If ShapeHitSpritePixels(TestShape,mx,my,0,1,1,spr2)  ????
(too many parameters or crashes )

Thanks and Greetings
stef
Title: Pixel Perfect (rotated/scaled) Collision
Post by: thaaks on June 20, 2006, 02:12:53 PM
Hi Stef, change the line to

    If ShapeHitSpritePixels(TestShape,mx,my,spr2, 1.0)

and it'll work. I found the proper syntax in the update thread where all changes regarding the last versions are listed.

I'm pretty sure Kevin will update the documentation asap  :D

Good to see you back! Any PB projects going on?

Cheers,
Tommy
Title: Pixel Perfect (rotated/scaled) Collision
Post by: stef on June 21, 2006, 01:07:21 PM
Hi thaaks

Thanks for reply.
It's working now. Great example!

Tested it also with 1000 ships ( max= 1000). Fascinating!!!

I am just dealing with my "great game-idea"and working on a game-proposal including the game-design. This I will offer a game-publisher.

As everybody knows a game-idea is worth about $0.0083333 ( 1 dime for a dozen ideas  :)  ) , but think this game would be really interesting for a publisher.

It is a completely unique idea. A game with enormous potential and possibilities.

Greetings
stef
Title: Pixel Perfect (rotated/scaled) Collision
Post by: thaaks on June 21, 2006, 02:21:32 PM
QuoteI am just dealing with my "great game-idea"and working on a game-proposal including the game-design. This I will offer a game-publisher.
Do you already have a publisher in mind? I think you might need to create a working prototype to convince any publisher...paper doesn't blush (german: Papier ist geduldig)!

Anyway, I wish you luck!

Cheers,
Tommy
Title: Pixel Perfect (rotated/scaled) Collision
Post by: stef on June 21, 2006, 03:38:27 PM
Hi

Hm, ..."paper doesn't blush"
That's right. ;)

My intention is to make some graphics for "simulating" screenshots and some (small) working demos to demonstrate the principles.

For this task Playbasic is absolutely suitable.


Maybe it works B)

stef