Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Substituting multiple inputs for a function with one function?

Tags:

function

lua

I am trying to see if I can simplify input by using a function that produces more than one output for use with another function. Is there any way I can do this? Do I HAVE to make a function to return single variables for each input?

--here is a snippet of what im trying to do (for a game)
--Result is the same for game environment and lua demo.

en = {
box ={x=1,y=2,w=3}
}
sw = {
box = {x=1,y=2,w=3}
}

function en.getbox()
return en.box.x,en.box.y,en.box.w,en.box.w
end

function sw.getbox()
return sw.box.x,sw.box.y,sw.box.w,sw.box.w
end

function sw.getvis()
return true
end

function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
  return x1 < x2+w2 and
         x2 < x1+w1 and
         y1 < y2+h2 and
         y2 < y1+h1
end

if CheckCollision(en.getbox(),sw.getbox()) == true then
        if sw.getvis() == true then
            en.alive = false
        end
    end

print(tostring(en.alive))

I am expecting the enemy (en) to die (en.alive = false) but I am getting the error: input:25: attempt to perform arithmetic on a nil value (local 'w2')

like image 482
Heatso Avatar asked Jan 28 '26 22:01

Heatso


1 Answers

You can find an explaination for the issue you are seeing here: Programming in Lua: 5.1 – Multiple Results

I suggest you read the whole page but here is a relevant section

A function call that is not the last element in the list always produces one result:

x,y = foo2(), 20 -- x='a', y=20

x,y = foo0(), 20, 30 -- x=nil, y=20, 30 is discarded


I suggest the following changes to get your code working. wrap your output from getbox into a table with clear keys that make it easy to understand.

  function en.getbox()
    return {
      x = en.box.x,
      y = en.box.y,
      w = en.box.w,
      h = en.box.w
    }
  end

  function sw.getbox()
    return {
      x = sw.box.x,
      y = sw.box.y,
      w = sw.box.w,
      h = sw.box.w
    }
  end

  function CheckCollision(o1, o2)

    return o1.x < o2.x + o2.w and
    o2.x < o1.x + o1.w and
    o1.y < o2.y + o2.h and
    o2.y < o1.y + o1.h
  end

Alternatively you can wrap the output of getbox "on the fly" like:

function CheckCollision(o1, o2)

  return o1[1] < o2[1] + o2[3] and
         o2[1] < o1[1] + o1[3] and
         o1[2] < o2[2] + o2[4] and
         o2[2] < o1[2] + o1[4]
end

if CheckCollision({en.getbox()},  {sw.getbox()}) == true then
        if sw.getvis() == true then
            en.alive = false
        end
end

I do strongly encourage the first option over the last. The last option leads to code that is harder to follow and should be accompanied by clear comments explaining it.

like image 113
Nifim Avatar answered Jan 30 '26 17:01

Nifim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!