Drag sprite with finger example (and a question)

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Drag sprite with finger example (and a question)

Post by rbytes »

Here is the code that I posted earlier, with the added code for detecting hits from above and below.
Try it out. You can bump the blue block into the red block and hear the beep when it hits - from left, right, above and below.

Code: Select all

'dragsprite.txt
'Drag a sprite with finger example
'Code by Dav, JAN/2017

GET SCREEN SIZE sw,sh
OPTION BASE 1
OPTION SPRITE POS CENTRAL
GRAPHICS
REFRESH OFF

'draw blue box sprite
GRAPHICS CLEAR 0,0,1
DRAW RECT 2,2 TO 98,198
SPRITE "b" SCAN 0,0,100,200
SPRITE "b" SHOW
SPRITE "b" AT 0,0

'draw red box sprite
GRAPHICS CLEAR 1,0,0
DRAW RECT 2,2 TO 98,198
SPRITE "c" SCAN 0,0,100,200
SPRITE "c" SHOW
SPRITE "c" AT SCREEN_WIDTH()/2,SCREEN_HEIGHT()/2

GRAPHICS CLEAR 0,0,0
REFRESH ON

DRAW TEXT "Drag blue box with finger" AT 1,1
DRAW TEXT "Don't collide with red one" AT 1,30


DO

  GET TOUCH 0 AS tx,ty  'get first touch

  'if user presses on the blue sprite
  IF SPRITE_HIT("b", tx,ty) THEN
     'get sprite x,y location
     GET SPRITE "b" POS sx,sy

     DO

       GET TOUCH 0 AS tx2,ty2 'get finger drag
       IF tx2=-1 THEN BREAK 'break loop if up
       
       'save current x,y pos of sprite
       GET SPRITE "b" POS sx2,sy2
       
       SPRITE "b" AT tx2-tx+sx,ty2-ty+sy
     
       IF SPRITES_COLLIDE("b","c") THEN
         ' blue sprite is vertically coincident with red sprite
         ' blue sprite is left of red sprite
         IF sy2 >sh/2-200 AND sy2<sh/2+200 AND sx2<=sw/2-100 THEN
           SPRITE "b" AT sw/2-101,sy2
         ENDIF
         ' blue sprite is vertically coincident with red sprite
         ' blue sprite is right of red sprite
         IF sy2 >sh/2-200 AND sy2<sh/2+200 AND sx2>=sw/2+100 THEN
           SPRITE "b" AT sw/2+101,sy2
         ENDIF
         
         ' blue sprite is horizontally coincident with red sprite
         ' blue sprite is above red sprite
         IF sx2 >sw/2-100 AND sx2<sw/2+100 AND sy2<=sh/2-200 THEN
           SPRITE "b" AT sx2,sh/2-201
         ENDIF
         
         ' blue sprite is horizontally coincident with red sprite
         ' blue sprite is below red sprite
         IF sx2>sw/2-100 AND sx2<sw/2+100 AND sy2>=sh/2+200 THEN
           SPRITE "b" AT sx2,sh/2+201
         ENDIF
         
          BEEP
          BREAK
       END IF

     UNTIL 0
  END IF

  SLOWDOWN

UNTIL 0
The only thing that gets me down is gravity...

User avatar
Dav
Posts: 279
Joined: Tue Dec 30, 2014 5:12 pm
My devices: iPad Mini, iPod Touch.
Location: North Carolina, USA
Contact:

Re: Drag sprite with finger example (and a question)

Post by Dav »

That sure works better than my code. Thanks. But for some reason the sprites get stuck when two corners collide together quickly. Trying to figure this out is a real challenge for me, but I'm not ready to give up yet! :)

Thanks for your help and code.

- Dav

Operator
Posts: 138
Joined: Mon May 06, 2013 5:52 am

Re: Drag sprite with finger example (and a question)

Post by Operator »

Here is "another" approach, col. detection
and reaction function included... :D

Code: Select all

'dragsprite.txt
'Drag a sprite with finger example
'Code by Dav, JAN/2017
'mod by rbytes

'mod by Operator...;
'col. reaction port./mod out of: http://forums.elysianshadows.com/viewtopic.php?f=13&t=5767

GRAPHICS
REFRESH OFF
OPTION SPRITE POS CENTRAL
scr_w = SCREEN_WIDTH()
scr_h = SCREEN_HEIGHT()
scr_w2 = scr_w/2
scr_h2 = scr_h/2

'draw blue box sprite
GRAPHICS CLEAR 0,0,1
spr1_cx = 50
spr1_cy = 100
spr1_w  = 100
spr1_h  = 100
spr1_w2 = spr1_w/2
spr1_h2 = spr1_h/2
SPRITE "b" SCAN spr1_cx-spr1_w2,spr1_cy-spr1_h2,spr1_w,spr1_h
SPRITE "b" SHOW
SPRITE "b" AT spr1_cx,spr1_cy

'draw red box sprite
GRAPHICS CLEAR 1,0,0
spr2_cx = scr_w2
spr2_cy = scr_h2
spr2_w  = 100
spr2_h  = 200
spr2_w2 = spr2_w/2
spr2_h2 = spr2_h/2
SPRITE "r" SCAN spr2_cx-spr2_w2,spr2_cy-spr2_h2,spr2_w,spr2_h
SPRITE "r" SHOW
SPRITE "r" AT spr2_cx,spr2_cy


GRAPHICS CLEAR 0,0,0
DRAW TEXT "Drag blue box with finger" AT 1,1
DRAW TEXT "Don't collide with red one" AT 1,30

FIELD "info" TEXT "" AT 0,400 SIZE 320,30 RO
REFRESH ON

LOOP:
GET TOUCH 0 AS tx,ty
spr_hit = SPRITE_HIT("b",tx,ty)

IF spr_hit AND tx >-1 THEN
  GET SPRITE "b" POS spr1_cx,spr1_cy
  tx2 = tx ! ty2 = ty
  WHILE tx2 >-1 AND SPRITE_HIT("b",tx2,ty2)
    GET TOUCH 0 AS tx2,ty2
    IF tx2 > -1 THEN
      spr1_cx_new = spr1_cx+(tx2-tx)
      spr1_cy_new = spr1_cy+(ty2-ty)
      
      CALL colAABB(spr1_cx_new,spr1_cy_new,spr1_w,spr1_h,spr2_cx,spr2_cy,spr2_w,spr2_h)
      spr1_cx_new += colAABB.move_x
      spr1_cy_new += colAABB.move_y
      SPRITE "b" AT spr1_cx_new,spr1_cy_new
    END IF
  END WHILE
END IF
GOTO LOOP



'collision detection and reaction
'by axis allinged bounding box,
'rectangles/boxes a,b
'calculates the overlaping distances
'and directions
'--> move_x, move_y to repositon
'sprite in case of a collision
'a_cx, b_cx center_x of box a,b
'a_cy, b_cy center_y of box a,b
'a_w , b_w  width of box a,b
'a_h , b_h  height of box a
'by Operator
DEF colAABB(a_cx,a_cy,a_w,a_h,b_cx,b_cy,b_w,b_h)
move_x = 0           'init./reset
move_y = 0           'init./reset

dcx = a_cx - b_cx    'centre dist. x
dcy = a_cy - b_cy    'centre dist. y
dw  = (a_w + b_w)/2  'min. width
dh  = (a_h + b_h)/2  'min. height

FIELD "info" TEXT "dirX: "&SIGN(dcx)&" dirY: "&SIGN(dcy)

'if no overlap/collision then return
IF ABS(dcx) > dw THEN RETURN
IF ABS(dcy) > dh THEN RETURN

'so far here? ..we have a collision..
'calculate where the col. hapened:
'4 quadrants around red sprite centre
'-1,-1 =above,left : 1,1 =below,right
'--> dir_x, dir_y
'calculate spr. overlap in x and y
'update sprite centre by the lowest
'overlap direction only!

dir_x = SIGN(dcx)
dir_y = SIGN(dcy)
overlap_x = ABS(ABS(dcx) - dw)
overlap_y = ABS(ABS(dcy) - dh)

IF overlap_x < overlap_y THEN
  move_x = overlap_x*dir_x
END IF

IF overlap_y < overlap_x THEN
  move_y = overlap_y*dir_y
END IF 

FIELD "info" TEXT "dirX: "&dir_x&" dirY: "&dir_y&" ovrlapX: "&overlap_x&" ovrlapY: "&overlap_y

END DEF

Attachments
image.jpg
image.jpg (66.75 KiB) Viewed 2772 times

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Drag sprite with finger example (and a question)

Post by rbytes »

This has an excellent response and never gets stuck. Great coding!
The only thing that gets me down is gravity...

User avatar
Dav
Posts: 279
Joined: Tue Dec 30, 2014 5:12 pm
My devices: iPad Mini, iPod Touch.
Location: North Carolina, USA
Contact:

Re: Drag sprite with finger example (and a question)

Post by Dav »

Thank you, Operator! That is a very good approach, and works very well! I'll be playing around with that code!

- Dav

Post Reply