Log In  

have you ever wanted to do z ordering, but without careful programming practices?

well i have the product for you!

introducing: the queue() and drawq() functions!

usage:

queue(--[[any function (spr, rect, pal, anything)]],{--[[array of parameters]]},--[[order index]])
use this to put things in the queue.

drawq()
no parameters here! it just bubble sorts --[[oh god]] the functions and calls them in that order,
meaning that --[[for example]], spr calls with the y pos passed as an index, will be stacked like real things, and no more characters standing on each others heads!

q={}
run this to clear the queue. this is the var which i used for queues. this is not perfect, but improvements are left as an exercise for the reader. --please post them, as i know i could do better.

anyway, the script:

function queue(f,p,o)
 add(q,{f,p,o})
end

function drawq() --improvements by @packrat!
 repeat
  local swp=true
  for l=1,#q-1 do
   if q[l][3]>q[l+1][3] then
    q[l+1],q[l]=q[l],q[l+1]
    swp=false
   end
  end
 until swp
 for d in all(q) do
  d[1](unpack(d[2]))
 end
end

here's a little example!

Cart #queuedemo-1 | 2020-08-28 | Code ▽ | Embed ▽ | No License
7

P#81298 2020-08-28 16:54 ( Edited 2020-08-28 19:31)

1

nice!

quick lua notes:

x, y = y, x
will exchange x and y without issue in lua - you don't need to explicitly create a tmp swap variable

also this feels like a really good use case for a repeat-until loop, which we love unreasonably but more importantly in this case saves tokens because swp doesn't need to be defined outside the loop

function drawq()
 repeat
  local swp=true
  for l=1,#q-1 do
   if q[l][3]>q[l+1][3] then
    q[l+1],q[l]=q[l],q[l+1]
    swp=false
   end
  end
 until swp
 for d in all(q) do
  d[1](unpack(d[2]))
 end
end

thanks again - this is way easier than what we did last time we tried to do a draw order (which, uh, we never actually got working I think)

P#81300 2020-08-28 19:05
1

@packbat nice! gotta implement that. but later, as its late.
have a nice day!

P#81302 2020-08-28 19:28
1

@packbat nevermind i implemented it. this is mostly to help people with quickly setting up z-order stuff. have fun!

P#81304 2020-08-28 19:32
1

Bubble sorting every frame is extremely costly... why don't you change for a presorted selective insertion list?

function queue(f,p,o)
 q[o]=q[o] or {}
 add(q[o],{f,p})
end

function drawq()

 for _,l in pairs(q) do
  for d in all(l) do
   d[1](unpack(d[2]))   
  end 
 end

end

With that change your demo goes from 11-12% cpu (bubble sort) to 4% cpu (presorted insertion)

There is a small issue though, you require int orders

P#81303 2020-08-28 19:32 ( Edited 2020-08-28 19:36)
1

Hmm sorry... has some issues with sorting... I will patch my suggestion ;) give me some time

P#81305 2020-08-28 19:44
2

For a small number of objects, this is indeed an option.
I have a variant that I used for my Nuklear Klone, that simply uses a sparse table of objects with the same "z-order".
It is twice as fast as using @kirbofan sort :]

Cart #wepidewade-0 | 2020-08-28 | Code ▽ | Embed ▽ | No License

P#81308 2020-08-28 20:02
2

Ok, not fully optimal... you can have a more efficient selective insert strategy but still more efficient than the bubble sort.. (around 5.5%) Only requiring an extra array for the "orders"

Cart #ninasayaye-0 | 2020-08-28 | Code ▽ | Embed ▽ | No License
2

function queue(f,p,o)
 q[o]=q[o] or {}
 add(q[o],{f,p})
 if #order==0 then 
   add(order,o)
 else 
   -- todo optimizable with better
   -- selective insertion algorithm
   local idx = 1
   for val in all(order) do
     if (val > o) break
     idx+=1
   end   
   add(order,o,idx)
 end

end

function drawq()

 for _,o in ipairs(order) do  
  for d in all(q[o]) do
   d[1](unpack(d[2]))   
  end 
 end

end
P#81309 2020-08-28 20:16 ( Edited 2020-08-28 20:24)
2

Similar variant as @slainte using a linked list - still slower than the brute force "array" version :]

Cart #najojedami-0 | 2020-08-28 | Code ▽ | Embed ▽ | No License
2

Queue API:

-- basic 2d z-ordering
-- sorted list variant by  @freds72
local q={z=-0x8000}
    function queue(f,p,o)
    local head,prev=q,q
    while head and head.z<o do
     -- swap/advance
     prev,head=head,head.next
    end
    -- insert new thing
    prev.next={f,p,z=o,next=prev.next}
end

function drawq()
    local head=q.next
    while head do
      head[1](unpack(head[2]))
      head=head.next
    end
 q={z=-0x8000}
end
P#81312 2020-08-28 20:35 ( Edited 2020-08-28 20:36)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 12:57:46 | 0.114s | Q:41