UnderwareDesign
September 10, 2010, 06:54:28 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: New Demo of Holly by Stevmjon (20th,June,2010) 
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Walking on Sprites  (Read 439 times)
kevin
Development Team
Administrator
Hero Member
*****
Offline Offline

Posts: 9418



WWW
« 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.




Code:

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






 Related Examples

   Walking on Sprite Collision Map
   Platformer Pixel Collisions Via Ray Casting
   Advanced Platform Collision (Vector WORLD)



 


* Walking_On_Sprites_Using_Ray_Hit_Sprite_V001.png (9.86 KB, 808x634 - viewed 55 times.)
« Last Edit: January 20, 2010, 09:43:42 PM by kevin » Logged

ATLUS
Sr. Member
****
Offline Offline

Posts: 321


WWW
« Reply #1 on: January 20, 2010, 01:02:43 PM »

nice exampale Wink
Logged

come back in summer 2011...
micky4fun
Sr. Member
****
Offline Offline

Posts: 423


« Reply #2 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

Code:
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

thanks
mick Smiley

ground image im using attached


* ground.png (2.55 KB, 1024x100 - viewed 45 times.)
« Last Edit: January 22, 2010, 03:58:10 PM by micky4fun » Logged
kevin
Development Team
Administrator
Hero Member
*****
Offline Offline

Posts: 9418



WWW
« Reply #3 on: January 22, 2010, 10:33:20 PM »


Quote
am i missing something

 Yes, Ray intersection is for vector collision, not pixels.. 
Logged

micky4fun
Sr. Member
****
Offline Offline

Posts: 423


« Reply #4 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 Smiley
Logged
kevin
Development Team
Administrator
Hero Member
*****
Offline Offline

Posts: 9418



WWW
« Reply #5 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.


 
Code:
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#




 
Logged

micky4fun
Sr. Member
****
Offline Offline

Posts: 423


« Reply #6 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 Smiley
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.10 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!