UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on October 20, 2008, 08:36:33 AM

Title: Collision Zones Using Images
Post by: kevin on October 20, 2008, 08:36:33 AM
 Collision Zones Using Image

 This example creates two images.  one image represent the visible scene, the other is collision scene. The demo moves a ball objects across the screen (left to right),   The collision image is used to detect how fast the moving object should move.  


[pbcode]

   Constant Zone_ShortGrass   =ac(1)
   Constant Zone_MedGrass      =ac(1)
   Constant Zone_LongGrass      =ac(1)


   Dim Palette(100)
   Palette(Zone_ShortGrass)   = rgb(55,255,100)
   Palette(Zone_MedGrass)      = rgb(50,200,0)
   Palette(Zone_LongGrass)      = rgb(0,100,0)
   
   dim Friction#(100)
   Friction#(Zone_ShortGrass)   =1
   Friction#(Zone_MedGrass)   =1.5
   Friction#(Zone_LongGrass)   =2
   
   
   ; get the screen size   
   sw=GetScreenWidth()
   sh=GetScreenHeight()

   ; create the visible screen
   DisplayScreen      =NewIMage(sw,sh)

   ; create the zone screen.
   ; the zone screen is the same size as the 'visible'
   ; but is just used to tell what zone the ball is currently over
   ZoneScreen         =GetFreeimage()
   createfximageex ZoneScreen,sw,sh,32
   

   // Draw the Visible scene..
   rendertoimage Displayscreen
   c=Palette(Zone_ShortGrass)
   shadebox 0,0,sw,sh,c,rgbfade(c,80),c,rgbfade(c,80)

   inkmode 1+32   
   ellipsec sw*0.7,sh*0.5,200,100,true,Palette(Zone_MedGrass)       
   ellipsec sw*0.7,sh*0.5,100,50,true,Palette(Zone_LongGrass)       
   inkmode 1


   // draw the collision (zone) scene.  
   rendertoimage Zonescreen
   Cls Zone_ShortGrass
   ellipsec sw*0.7,sh*0.5,200,100,true,Zone_MedGrass       
   ellipsec sw*0.7,sh*0.5,100,50,true,Zone_LongGrass       
   


   rendertoscreen
   setfps 60

   ballx#=0
   bally#=sh/2
   Ballspeed#=2
   Do

      drawimage DisplayScreen,0,0,false

      rendertoimage ZoneScreen

      ; check what zone the ball is currently over.      
      ZoneType=Point(Ballx#,Bally#) and 255

      rendertoscreen

      ; get the amount of friction this zone has
      Friction#=Friction#(ZoneType)
   
      ; move the ball   
      ballx#=ballx#+(BallSpeed#*1/Friction#)
      if ballx#>sw then Ballx#=0
      
      ; draw the circle to represent the ball
      circle ballx#,bally#,10,true

      Sync
   loop

[/pbcode]

Title: Re: Collision Zones Using Images
Post by: ATLUS on October 20, 2008, 12:21:52 PM
its 2d crysis game=)
Title: Re: Collision Zones Using Images
Post by: kevin on October 21, 2008, 01:17:47 AM

erm, useful. 

It's actually related to this idea -> Mini Golf (http://www.underwaredesign.com/forums/index.php?topic=2697.msg18320#msg18320)
Title: Re: Collision Zones Using Images
Post by: kevin on October 21, 2008, 07:42:44 AM
 Rebounding Example / Mini Golf Collision Example

 This is quick 'cut & paste' hack showing some ball objects rebounding of vector environment combined with the friction method above.   Making basically a mini golf frame work.  


[pbcode]

   Constant Zone_ShortGrass   =ac(1)
   Constant Zone_MedGrass      =ac(1)
   Constant Zone_LongGrass      =ac(1)


   Dim Palette(100)
   Palette(Zone_ShortGrass)   = rgb(55,255,100)
   Palette(Zone_MedGrass)      = rgb(50,200,0)
   Palette(Zone_LongGrass)      = rgb(0,100,0)
   
   dim Friction#(100)
   Friction#(Zone_ShortGrass)   =1
   Friction#(Zone_MedGrass)   =1.5
   Friction#(Zone_LongGrass)   =2
   
   
   ; get the screen size   
   sw=GetScreenWidth()
   sh=GetScreenHeight()

   ; create the visible screen
   DisplayScreen      =NewIMage(sw,sh)

   ; create the zone screen.
   ; the zone screen is the same size as the 'visible'
   ; but is just used to tell what zone the ball is currently over
   ZoneScreen         =GetFreeimage()
   createfximageex ZoneScreen,sw,sh,32
   

   // Draw the Visible scene..
   rendertoimage Displayscreen
   c=Palette(Zone_ShortGrass)
   shadebox 0,0,sw,sh,c,rgbfade(c,80),c,rgbfade(c,80)

   inkmode 1+32   
   ellipsec sw*0.7,sh*0.5,200,100,true,Palette(Zone_MedGrass)       
   ellipsec sw*0.7,sh*0.5,100,50,true,Palette(Zone_LongGrass)       
   inkmode 1


   // draw the collision (zone) scene.  
   rendertoimage Zonescreen
   Cls Zone_ShortGrass
   ellipsec sw*0.7,sh*0.5,200,100,true,Zone_MedGrass       
   ellipsec sw*0.7,sh*0.5,100,50,true,Zone_LongGrass       
   


   // create collision world
   CollisionWorld=CreateVectorWorld()
   

   
   rendertoscreen


   camera=newcamera()
   cameracls camera,off

   setfps 60



   Type tBall
         x#,y#,angle#,speed#
   endType

   Dim Ball as tball List
   
   Do

      if Timer()>AddNewBallTime
            ball = new Tball
            ball.x#=rnd(sw)
            ball.y#=rnd(sh)
            Ball.Angle#=rnd(360)
            Ball.speed#=rndrange(2,10)
            AddNewBallTime=timer()+1000
      endif

      capturetoscene
      clsscene
      
      CaptureDepth 100

      CameraGrabWorld Camera,CollisionWorld

      DrawImage DisplayScreen,0,0,false

      CaptureDepth 10

      rendertoimage ZoneScreen

      for each Ball()

         ; check what zone the ball is currently over.         
         ZoneType=Point(Ball.x#,Ball.y#) and 255

         ; get the amount of friction this zone has
         Friction#=Friction#(ZoneType)
   
         ; move the ball   
         Speed#=Ball.Speed#*1/Friction#

         newx#=ball.x#+(cos(Ball.angle#)*speed#*1)
         newy#=ball.y#+(sin(Ball.angle#)*speed#*1)

         if RayIntersectWOrld(CollisionWorld,Ball.x#,Ball.y#,NewX#,NewY#)=true
               x2#   =getintersectx#(0)
               y2#   =getintersecty#(0)
               ; Calc reflection Direction
               WallAngle#=AtanFull(getnormaly#(0),getnormalx#(0))
               RayAngle#=GetAngle2d(x2#,y2#,ball.x#,ball.y#)
               Ball.Angle#=WrapAngle(WallAngle#,WallAngle#-RayAngle#)

               ball.x#=x2#
               ball.y#=y2#
            
         else
               ball.x#=newx#
               ball.y#=newy#
         endif

         ; draw the circle to represent the ball
         circle ball.x#,ball.y#,10,true
      next

      drawcamera camera
      Sync
   loop





Function CreateVectorWorld()
   WorldWidth=GetScreenWidth()
   WorldHeight=GetScreenHeight()


; Create world
   World=NewWorld()
   CaptureToWorld World

; draw a series of boarder line for this world
   line 0,0,worldwidth,0
   line worldwidth,0,worldwidth,worldheight
   line worldwidth,worldheight,0,worldheight
   line 0,worldheight,0,0

   for lp=0 to 7
      x=100+lp*80
      y=100+lp*80
      Make_Convex(4,x,y,50,90+lp*20)
   next

   Make_Convex(6,700,100,90,70)

   PartitionWorld World,32
   DrawGFXImmediate

EndFunction World



   ; This function creates a convex polygon shape

Function Make_Convex(edges,xpos#,ypos#,Size,angle)
      sa#=360.0/edges
      c=rndrgb()
      for lp=0 to edges-1
         a#=angle+(lp*sa#)
         x1#=xpos#+cosRadius(a#,size)
         y1#=ypos#+SinRadius(a#,size)
         if lp<(edges-1)
            a#=angle+((lp+1)*sa#)
         else
            a#=angle
         endif
         x2#=xpos#+cosRadius(a#,size)
         y2#=ypos#+SinRadius(a#,size)
         line x2#,y2#,x1#,y1#
      next lp
endfunction i


[/pbcode]


Title: Re: Collision Zones Using Images
Post by: ATLUS on October 21, 2008, 08:06:00 AM
Quote from: kevin on October 21, 2008, 07:42:44 AM

Rebounding Example / Mini Golf Collision Example

 This is quick 'cut & paste' hack showing some ball objects rebounding of vector environment combined with the friction method above.   Making basically a mini golf frame work.  


[pbcode]

   Constant Zone_ShortGrass   =ac(1)
   Constant Zone_MedGrass      =ac(1)
   Constant Zone_LongGrass      =ac(1)


   Dim Palette(100)
   Palette(Zone_ShortGrass)   = rgb(55,255,100)
   Palette(Zone_MedGrass)      = rgb(50,200,0)
   Palette(Zone_LongGrass)      = rgb(0,100,0)
   
   dim Friction#(100)
   Friction#(Zone_ShortGrass)   =1
   Friction#(Zone_MedGrass)   =1.5
   Friction#(Zone_LongGrass)   =2
   
   
   ; get the screen size   
   sw=GetScreenWidth()
   sh=GetScreenHeight()

   ; create the visible screen
   DisplayScreen      =NewIMage(sw,sh)

   ; create the zone screen.
   ; the zone screen is the same size as the 'visible'
   ; but is just used to tell what zone the ball is currently over
   ZoneScreen         =GetFreeimage()
   createfximageex ZoneScreen,sw,sh,32
   

   // Draw the Visible scene..
   rendertoimage Displayscreen
   c=Palette(Zone_ShortGrass)
   shadebox 0,0,sw,sh,c,rgbfade(c,80),c,rgbfade(c,80)

   inkmode 1+32   
   ellipsec sw*0.7,sh*0.5,200,100,true,Palette(Zone_MedGrass)       
   ellipsec sw*0.7,sh*0.5,100,50,true,Palette(Zone_LongGrass)       
   inkmode 1


   // draw the collision (zone) scene.  
   rendertoimage Zonescreen
   Cls Zone_ShortGrass
   ellipsec sw*0.7,sh*0.5,200,100,true,Zone_MedGrass       
   ellipsec sw*0.7,sh*0.5,100,50,true,Zone_LongGrass       
   


   // create collision world
   CollisionWorld=CreateVectorWorld()
   

   
   rendertoscreen


   camera=newcamera()
   cameracls camera,off

   setfps 60



   Type tBall
         x#,y#,angle#,speed#
   endType

   Dim Ball as tball List
   
   Do

      if Timer()>AddNewBallTime
            ball = new Tball
            ball.x#=rnd(sw)
            ball.y#=rnd(sh)
            Ball.Angle#=rnd(360)
            Ball.speed#=rndrange(2,10)
            AddNewBallTime=timer()+1000
      endif

      capturetoscene
      clsscene
      
      CaptureDepth 100

      CameraGrabWorld Camera,CollisionWorld

      DrawImage DisplayScreen,0,0,false

      CaptureDepth 10

      rendertoimage ZoneScreen

      for each Ball()

         ; check what zone the ball is currently over.         
         ZoneType=Point(Ball.x#,Ball.y#) and 255

         ; get the amount of friction this zone has
         Friction#=Friction#(ZoneType)
   
         ; move the ball   
         Speed#=Ball.Speed#*1/Friction#

         newx#=ball.x#+(cos(Ball.angle#)*speed#*1)
         newy#=ball.y#+(sin(Ball.angle#)*speed#*1)

         if RayIntersectWOrld(CollisionWorld,Ball.x#,Ball.y#,NewX#,NewY#)=true
               x2#   =getintersectx#(0)
               y2#   =getintersecty#(0)
               ; Calc reflection Direction
               WallAngle#=AtanFull(getnormaly#(0),getnormalx#(0))
               RayAngle#=GetAngle2d(x2#,y2#,ball.x#,ball.y#)
               Ball.Angle#=WrapAngle(WallAngle#,WallAngle#-RayAngle#)

               ball.x#=x2#
               ball.y#=y2#
            
         else
               ball.x#=newx#
               ball.y#=newy#
         endif

         ; draw the circle to represent the ball
         circle ball.x#,ball.y#,10,true
      next

      drawcamera camera
      Sync
   loop





Function CreateVectorWorld()
   WorldWidth=GetScreenWidth()
   WorldHeight=GetScreenHeight()


; Create world
   World=NewWorld()
   CaptureToWorld World

; draw a series of boarder line for this world
   line 0,0,worldwidth,0
   line worldwidth,0,worldwidth,worldheight
   line worldwidth,worldheight,0,worldheight
   line 0,worldheight,0,0

   for lp=0 to 7
      x=100+lp*80
      y=100+lp*80
      Make_Convex(4,x,y,50,90+lp*20)
   next

   Make_Convex(6,700,100,90,70)

   PartitionWorld World,32
   DrawGFXImmediate

EndFunction World



   ; This function creates a convex polygon shape

Function Make_Convex(edges,xpos#,ypos#,Size,angle)
      sa#=360.0/edges
      c=rndrgb()
      for lp=0 to edges-1
         a#=angle+(lp*sa#)
         x1#=xpos#+cosRadius(a#,size)
         y1#=ypos#+SinRadius(a#,size)
         if lp<(edges-1)
            a#=angle+((lp+1)*sa#)
         else
            a#=angle
         endif
         x2#=xpos#+cosRadius(a#,size)
         y2#=ypos#+SinRadius(a#,size)
         line x2#,y2#,x1#,y1#
      next lp
endfunction i


[/pbcode]

WoW its nice!!
Title: Re: Collision Zones Using Images
Post by: micky4fun on November 04, 2008, 05:54:22 PM
 ;D Thanks Kevin and ATLUS ,  ;D

WOW !!!  great stuff , love the program
got my brain ticking

thanks