Scope Issue?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Lacotemale
Citizen
Posts: 75
Joined: Sat Mar 08, 2014 9:01 pm

Scope Issue?

Post by Lacotemale »

Hey all,

So I've been working on a crappy RPG game for a while and progress was going well until I realized my code was just turning into a dogs dinner to put it politely. Its an absolute mess in my main and menu lua files.

I wanted to start cleaning up the main.lua file, so I've moved some collision functions into a separate Collisions.lua class/file. It doesn't work any longer and i'm not sure why. I feel like I'm having scope issues now? =/

Any help on this issue and advice for breaking up my code into more manageable chunks would be appreciated!

To test launch love file marked with fail, left click new game, then press Up arrow on your keyboard. You should get a nil error message and the line number.
Attachments
WhiteGuardian.L2D_fail.love
Fails with functions external file
(2.02 MiB) Downloaded 99 times
WhiteGuardian.L2D_working.love
This works with functions inline
(2.02 MiB) Downloaded 104 times
User avatar
pgimeno
Party member
Posts: 3549
Joined: Sun Oct 18, 2015 2:58 pm

Re: Scope Issue?

Post by pgimeno »

In the non-working one, you don't ever define collisionUp, collisionDown etc. anywhere, yet you're attempting to call these as if they were functions, which they aren't, and your code crashes for that reason. To fix it, inside your functions you need to set self.collisionUp instead of returning the result, since you don't use the returned value anyway. Then in order to check it, you would use Collisions.collisionUp etc. (note the dot and the lack of parentheses) instead of Collisions:collisionUp(...) etc. (note the colon and the parentheses).

There are other problems, though.

When calling checkUpCollision etc. with the last object checked, it will overwrite the previous setting of collisionUp etc. because if there's no collision with that last object, it will be set to false regardless of whether there was a collision with another object first. The consequence is that only the collision with that last object counts. To fix this, you set it to false once at the beginning only, and the function that checks collisions needs to set it to true when there's a collision, but not touch it when there isn't. Something like this:

Code: Select all

--- in classes/Collisions.lua ---
function Collisions:checkUpCollision(item, player)
    if Collisions:box_collision(player.x, player.y-5, player.w, player.h, item.x, item.y, item.w, item.h) and item.itemType == 100 then
        self.collisionUp = true
    end
end

--- in main.lua ---
if startGame == true then
    -- Clear all collision flags to check this round
    Collisions.collisionUp = false
    ...

    -- Check for collisions between the player and the items on the map
    for i = 1, #itemsOnMap do
        ...
            Collisions:checkUpCollision(itemsOnMap[i], player)
            ...
Another problem in the 'working' version is that 'and' has more priority than 'or', which causes this line:

Code: Select all

                if down('w') or down('up') and collisionUp== false then
to be interpreted as if it was written like this:

Code: Select all

                if down('w') or (down('up') and collisionUp== false) then
The consequence is that with w/a/s/d you skip collision tests (in your "working" version). To fix it, put parentheses around the first two conditions, like this (and also I've changed it to Collision.collisionUp as per above):

Code: Select all

                if (down('w') or down('up')) and Collision.collisionUp== false then
User avatar
Lacotemale
Citizen
Posts: 75
Joined: Sat Mar 08, 2014 9:01 pm

Re: Scope Issue?

Post by Lacotemale »

Wow, thanks dude! :awesome:

I think self was the missing piece of the puzzle. I kept trying "this.var" but I spend too long on Javascript these days and not enough time on other languages. Now time to restructure my whole codebase so I feel I can get back working on this. :ultrahappy:
User avatar
Lacotemale
Citizen
Posts: 75
Joined: Sat Mar 08, 2014 9:01 pm

Re: Scope Issue?

Post by Lacotemale »

Why does return not work from external files?

Code: Select all

Responsive {}

function Responsive:getCoordsByPercent(percentW, percentH)
	self.width, self.height = love.graphics.getDimensions( )
	self.w = (self.width/100)*percentW
	self.h = (self.height/100)*percentH
	return self.w,self.h
end
Called by:

Code: Select all

plrX, plrY = Responsive:getCoordsByPercent(50,50)
Error:
attempt to call global Responsive a nil value
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Scope Issue?

Post by s-ol »

You omitted an equals-sign (=) on the first time there, which makes it Responsive {} which is the same as Responsive({}).

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Lacotemale
Citizen
Posts: 75
Joined: Sat Mar 08, 2014 9:01 pm

Re: Scope Issue?

Post by Lacotemale »

Oh dear that was embarrassing! :oops: Thanks!
Post Reply

Who is online

Users browsing this forum: Todespreis and 81 guests