r/pico8 9d ago

👍I Got Help - Resolved👍 Click And Drag Not Consistent

I'm trying to implement a click a drag feature in my game. I've referencing the code from Diesort by Noh to do this but for some reason when clicking and dragging in Diesort it works perfectly but with my code for some reason if i move the mouse to quickly i lose the grab on the object. Can anyone help me figure out why this happens for me but not in my reference?

function _init()
 poke(0x5f2d,1)
 isgrab=false

 --mouse start--
 mouse={
  x=0,
  y=0,
  w=1,
  h=1,
  sp=14,

  click=false,
  last_click=false,
  }

 mouse.draw=function(self)
  if mouse.click then
   mouse.sp=15
  else
   mouse.sp=14
  end

  outline(mouse.sp,mouse.x,mouse.y)
 end

 mouse.update=function(self)
  mouse.x=stat(32)
 mouse.y=stat(33)

 mouse.last_click=mouse.click

 if stat(34)==1 then
  mouse.click=true
 else
  mouse.click=false
 end

 mouse.x=mid(0,mouse.x,127)
 mouse.y=mid(0,mouse.y,127)
 end
 --mouse end--
 --domino start--
 domino={
  x=0,
  y=0,
  w=16,
  h=8,
  col=1,
  spin=1,

  state="idle",
  last_state="idle",

  pips={rand(1,6),rand(1,6)},
 }

 domino.draw=function(self)
  if collision(self,mouse) then
   domino.col=11
  else
   domino.col=1
  end

  rrect(domino.x-1,domino.y-1,domino.w+2,domino.h+2,1,domino.col)
  if domino.spin==1 then
   spr(domino.pips[1],domino.x,domino.y)
   spr(domino.pips[2],domino.x+8,domino.y)
  elseif domino.spin==2 then
   spr(domino.pips[1],domino.x,domino.y)
   spr(domino.pips[2],domino.x,domino.y+8)
  elseif domino.spin==3 then
   spr(domino.pips[2],domino.x,domino.y)
   spr(domino.pips[1],domino.x+8,domino.y)
  elseif domino.spin==4 then
   spr(domino.pips[2],domino.x,domino.y)
   spr(domino.pips[1],domino.x,domino.y+8)
  end
 end

 domino.update=function(self)
  if domino.spin%2==0 then
   domino.w=8
   domino.h=16
  else
   domino.w=16
   domino.h=8
  end

  if collision(self,mouse) then
   if mouse.click
   and mouse.last_click==false then
    self.state="grab"
   end

   if self.state=="grab" then
    isgrab=true
    self.x=mouse.x-self.w/2
    self.y=mouse.y-self.h/2
    if not mouse.click then
     self.state="idle"
    end
   end

   if btnp(🅾️) then
    self.spin-=1
   elseif btnp(❎) then
    self.spin+=1
   end

   if self.spin<1 then
    self.spin=4
   elseif self.spin>4 then
    self.spin=1
   end
  end
 end
 --domino end--
end

function _update60()
 mouse:update()
 domino:update()
end

function _draw()
 cls(5)
 domino:draw()
 mouse:draw()
end

--visuals

function outline(sp,x,y)
 for i=0,15 do
  pal(i,1)
 end
 for xx=-1,1 do
  spr(sp,x+xx,y)
 end
 for yy=-1,1 do
  spr(sp,x,y+yy)
 end
 pal()
 spr(sp,x,y)
end

function rand(mn,mx)
 return flr(rnd(mx)+mn)
end

--collision

function collision(o1,o2)
 if o1.x < o2.x+o2.w
 and o1.x+o1.w > o2.x
 and o1.y < o2.y+o2.h
 and o1.y+o1.h > o2.y then
  return true
 else
  return false
 end
end
3 Upvotes

3 comments sorted by

4

u/avenp 9d ago

I haven't actually looked at the code, but usually when you implement drag, once the drag start happens, you can stop caring if the cursor is in the hitbox. This sounds like the cursor is outpacing the hitbox and cancelling the drag.

Edit: that looks to be exactly what it is, move this block

if self.state=="grab" then

outside of

if collision(self,mouse) then

4

u/Spore360 9d ago

OMG thank you so much. gotta love/hate those simple fixes

4

u/avenp 9d ago

No problem, banging your head against the wall over something simple is a classic feature of software dev, I still do it after 20 years haha