UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on January 20, 2010, 11:15:15 AM

Title: Walking on Sprites
Post by: kevin on January 20, 2010, 11:15:15 AM
 Walking on Sprites


  This example sets up a simple sprite scene than uses the RayHitSprite function to position a 'character' on top them.




[pbcode]

   setfps 75

   // Make images
      
   Image_FloorBlock=NewFxImage(2,10)
   rendertoimage Image_FloorBlock
   Box 0,0,100,100,true
   rendertoscreen   


   // --------------------------------------------------------------------------------
   // make a sprite scene,  these will be a set of spirtes aligned along a sinus wave
   // --------------------------------------------------------------------------------
   AngleStep#=10   
   Xstep=20
   Radius=60
   Ypos=GetScreenHeight()/2

   X1=0
   Y1=Ypos+SinRadius(Angle#,Radius)

   for xlp=Xstep to 2000 step XStep

      Angle#=Angle#+AngleStep#
      X2=Xlp
      Y2=Ypos+SinRadius(Angle#,Radius)
      Y2=Y2+CosRadius(Angle#*3,Radius/2)

      ThisSprite=MakeAlignSpRiteToPOints(x1,y1,x2,y2,IMage_floorBlock)

      x1=x2
      y1=y2
         
   next




   // --------------------------------------------------------------------------------


      ; player variables   
      playerX#=300
      PLayerY#=100
      PLayerRadius#=25
   

   ; create camera to view the scene
      CreateCamera 1
   

   // --------------------------------------------------------------------------------
   //  Main Loop
   // --------------------------------------------------------------------------------

Do

   
   // init capture to scene mode
   CaptureToScene

   // clear the scene buffer of any old data
   ClsScene

   // capture the sprites to the scene
   drawallsprites


   // Run ray intersection against the entire sprite set
   // now __obviously___ you wouldn''t do this is real life..

   if leftkey() then playerx#=playerx#-2
   if rightkey() then playerx#=playerx#+2


   x1#=PLayerX#
   y1#=PLayerY#
   x2#=PLayerX#
   y2#=PLayerY#+(PLayerRadius#*2)

   capturedepth 2
   linec x1#,y1#,x2#,y2#,rgb(0,255,0)
   
   ThisSprite=GetFirstSprite()
   Collision=False
   While ThisSprite>0

      if RayHitSprite(x1#,y1#,x2#,y2#,ThisSprite)
         x2#=GetIntersectX#(2)                        
         Y2#=GetIntersectY#(2)-1                        
         circle x2#,y2#,5,false      
         Collision=true
      endif
   
      ThisSprite=GetNextSprite(ThisSprite)
   EndWhile   
         
   if Collision=False
      PlayerY#=PlayerY#+1
   else
      dist#=(y2#-y1#)
      if Dist#>PLayerRadius#
         PlayerY#=PlayerY#+1
      else
         PLayerY#=y2#-PlayerRadius#
      endif   
   endif   
   
   circlec playerx#,playery#,playerradius#,true,$ff0000      

   PositionCamera 1,PLayerX#-GetScreenWidth()/2,PlayerY#-GetScreenHeight()/2
   

   drawcamera 1

   Sync

loop
      


Function MakeAlignSpriteToPOints(x1,y1,x2,y2,CollisionIMage)

   ThisSprite=NewSprite(x1,y1,CollisionIMage)
   SpriteDrawMode ThisSprite,2
   positionSpriteZ ThisSprite,50

   tw#=GetImageWidth(CollisionImage)
   th#=GetImageHeight(CollisionImage)

   dist#=GetDistance2d(x1,y1,x2,y2)
   ScaleSpriteX ThisSprite,Dist#/tw#   
   angle#=getangle2d(x1,y1,x2,y2)
   rotateSprite ThisSPrite,Angle#


   SpriteCollisionMode 1,1  ;(collision mode is rotated rectangles)
      
EndFunction ThisSprite

[/pbcode]



Related Examples

  Walking on Sprite Collision Map (http://www.underwaredesign.com/forums/index.php?topic=3339.0)
  Platformer Pixel Collisions Via Ray Casting (http://www.underwaredesign.com/forums/index.php?topic=3163.0)
  Advanced Platform Collision (Vector WORLD) (http://www.underwaredesign.com/forums/index.php?topic=1364.0)



Title: Re: Walking on Sprites
Post by: ATLUS on January 20, 2010, 01:02:43 PM
nice exampale ;)
Title: Re: Walking on Sprites
Post by: micky4fun on January 22, 2010, 03:55:01 PM
Hi Kevin

well been trying to muck about with this type of collision as i like the look of it ,
can you tell me why the code below works when spritecollisonmode is set to 1 , but line falls short of ground , so no good for pixel pefect
but when changing spritecollisonmode is set to 6 , pixel perfect it does not work , returns RayX2 and RayY2 as 0
am i missing something , or is there another easy way to do this as pixel perfect

[pbcode]
     loadfximage "ground.png",10

    spr=getfreesprite()
    CreateSprite Spr
    PositionSprite Spr,0,600
    SpriteImage Spr,10
    SpriteCollisionMode Spr,1
 
; Init the Rays Starting Point
 RayX1=100
 RayY1=100
 
 Do
    Cls RGB(0,0,0)
 
    RayX2=MouseX()
    RayY2=MouseY()
   
       If RayHitSprite(RayX1,RayY1,rayX2,rayY2,Spr)=true
          RayX2=GetIntersectX#(0)
          RayY2=GetIntersectY#(0)
       EndIf
       
    Line RayX1,RayY1,RayX2,RayY2
    DrawAllSprites
    Sync
 Loop
[/pbcode]

thanks
mick :)

ground image im using attached
Title: Re: Walking on Sprites
Post by: kevin on January 22, 2010, 10:33:20 PM

Quoteam i missing something

Yes, Ray intersection is for vector collision, not pixels.. 
Title: Re: Walking on Sprites
Post by: micky4fun on January 23, 2010, 06:07:44 PM
Ok thanks Kevin

thats ashame , ile continue messing about with this for a little longer and see what happens

mick :)
Title: Re: Walking on Sprites
Post by: kevin on January 23, 2010, 08:40:30 PM
 
If the target object doesn't need rotation, then you can get a reasonable  approximation  as follows.


[pbcode]
   openscreen 1024,768,32,1

   loadfximage "E:\Downloads\ground.png",10

  spr=getfreesprite()
  CreateSprite Spr
  PositionSprite Spr,0,600
  SpriteImage Spr,10
  SpriteCollisionMode Spr,1
 
; Init the Rays Starting Point
 RayX1=300
 RayY1=300
 
 Do
    Cls RGB(0,0,0)
 
    RayX2=MouseX()
    RayY2=MouseY()

    DrawAllSprites

   
       If RayHitSprite(RayX1,RayY1,rayX2,rayY2,Spr)=true

            ThisImage=getSpriteImage(Spr)
            ImageXpos=GetSpritex(Spr)
            ImageYpos=GetSpritey(Spr)

            Collision,impactx#,impacty#=Plot_Ray_Over_image(Rayx1,Rayy1,Rayx2,Rayy2,ThisImage,ImageXpos,ImageYpos)

            if Collision
                  rayx2=impactx#            
                  rayy2=impacty#            
            

                  Circle Rayx2,Rayy2,5,false
            endif

;           RayX2=GetIntersectX#(0)
;          RayY2=GetIntersectY#(0)
       EndIf
       
    Line RayX1,RayY1,RayX2,RayY2
    Sync
 Loop




Function Plot_Ray_Over_image(Rayx1#,Rayy1#,Rayx2#,Rayy2#,ThisImage,ImageXpos,ImageYpos)

      width      =getimagewidth(Thisimage)
      height   =getimageheight(Thisimage)

      Collision=False
                     
      Result=LineIntersectRect(Rayx1#,Rayy1#,Rayx2#,Rayy2#,ImageXpos,ImageYpos,ImageXpos+Width,ImageYpos+height)
             
      if result>-1

         if Result=1
            Rayx1#=GetIntersectX#(0)
            Rayy1#=GetIntersectY#(0)
            Rayx2#=GetIntersectX#(1)
            Rayy2#=GetIntersectY#(1)
         endif
         
            ;linec Rayx1#,Rayy1#,Rayx2#,Rayy2#,255

            dist#=getdistance2d(Rayx1#,Rayy1#,Rayx2#,Rayy2#)
            dx#=Rayx2#-Rayx1#
            dy#=Rayy2#-Rayy1#

            if dist#<>0
               nx#=dx#/dist#      
               ny#=dy#/dist#      
            else
               nx#=0
               ny#=0
            endif            

            OldSurface=GetSurface()
            rendertoimage ThisImage
               lockbuffer

                  Transparentcolour=GetImageMaskCOlour(ThisImage)

                  for lp=0 To int(Dist#)
               
                     x#=rayx1#+(nx#*lp)
                     y#=rayy1#+(ny#*lp)

                     x#=x#-ImageXpos
                     y#=y#-ImageYpos
                     if point(X#,y#)<>Transparentcolour

                        Impactx#=x#+ImageXpos                        
                        Impacty#=y#+ImageYpos                        
                        Collision=true                     
                        exitfor
                     endif

      
                  next      
               unlockbuffer
            rendertoimage OldSurface
      endif


EndFunction  Collision,ImpactX#,ImpactY#




[/pbcode]


    Note:  - Today i'd recommend using the RayToMap pixel collision functions
Title: Re: Walking on Sprites
Post by: micky4fun on January 24, 2010, 07:36:02 AM
Hi Kevin

yes nice one , this looks good , will av a bit more time later today to get into this a bit deeper see what i can come up with

thanks
mick :)