Unable to use variables from another class in a class

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
moziL2D
Prole
Posts: 2
Joined: Tue Aug 11, 2020 11:02 pm

Unable to use variables from another class in a class

Post by moziL2D »

Im somewhat new to programming, and Im trying to make a game like dodger. Under my Player.lua class, I am able to calculate collisions for the borders of the window, however, trying to reference the location of the obstacle to make sure the player cannot phase through the obstacle does not work and returns the following error: attempt to index global 'obstacle' (a nil value). I have already imported the obstacle class to the player class, but it still returns nil. Thanks for the help.

P.S. Dont mind the messy code, its the only way I was able to make some things work due to the fact I cant figure out how to use variables from classes in other classes.
Attachments
dodger.love
(23.07 KiB) Downloaded 142 times
User avatar
Nikki
Citizen
Posts: 87
Joined: Wed Jan 25, 2017 5:42 pm

Re: Unable to use variables from another class in a class

Post by Nikki »

when you want to use a variable in some code you have to have access to that variable
- one way would be by having that variable global, in your main function you have a love.load()
with these 2 variables

Code: Select all

obstacle1
obstacle2
so if you would use either obstacle1 or obstacel2 in that Player:update() function it would work

another option is passing the variable you are interrested in

so in your main you add it like so

Code: Select all

player:update(dt, obstacle1)

and in your player.lua you change the signature likes so

Code: Select all

function Player:update(dt, obstacle)
then you can keep writing 'obstacle' it will be obstacle1 in this specific case, if youd passed obstacle2 then that would be obstacle in the Player:update function.

My personal tip however would be to try and rewrite this code to become less Object oriented and more procedural/data oriented instead.
Just make an array of obstacles in your main,
and in the main you also take care of updating , collision checking and rendering the obstacles and player.

I might be an old fart, but i believe when you are new to programming immediately fussing around with classes will set you up properly to learn a lot of wrong things. which will take a lot of time to unlearn.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Unable to use variables from another class in a class

Post by ReFreezed »

To expand on what Nikki is saying, the problem is that you're trying to refer to an obstacle but there's no code that says what the 'obstacle' name means. Let's review what's happening is different parts of the program! I hope this helps with understanding how programming in Lua and LÖVE works (though you probably already understand some things here already). "..." represents parts I skipped over.

Code: Select all

-- main.lua
Class = require 'class'
...
require 'Player'
require 'Obstacle'
In main.lua we're telling Lua to run the contents of class.lua, Player.lua and Obstacle.lua. We're also saying that 'Class' is a global that refers to what the class module returns. We don't need to know how the class module works - we only need to know that we can call 'Class' to create something that represents a class, which is what we're doing in some other files. All good so far.

Code: Select all

-- Obstacle.lua
Obstacle = Class{}
In Obstacle.lua we're creating a global object called 'Obstacle' that represents a unique "class". Then we define some functions that we attach to the Obstacle class. (We may call these functions "methods" as it's the appropriate term used in object oriented programming for this situation).

We're doing very similar things in Player.lua: we create a global 'Player' and define some methods.

Code: Select all

-- main.lua
function love.load()
	...
	player = Player()
	obstacle1 = Obstacle()
	obstacle2 = Obstacle()
end
Back to main.lua. We're now defining the function love.load which is a function that the LÖVE framework knows about and will automatically execute at an appropriate time (before love.update etc. are called).

When LÖVE calls love.load we're creating some globals, namely 'player', 'obstacle1' and 'obstacle2' (and some other things that I skipped over). Those are instances of the classes we were defining in Obstacle.lua and Player.lua. Again, we don't need to know how exactly classes or instances work internally (which is defined in class.lua) more than that we call Obstacle() to create instances of the Obstacle class and that the methods we defined earlier can operate on these instances (for example, Obstacle:collision() can operate on Obstacle instances).

What we probably want to do here after creating the instances is make an array that contains references to all the obstacles so that the player can check collisions against all of them:

Code: Select all

obstacle1 = Obstacle()
obstacle2 = Obstacle()

obstacles = {}
table.insert(obstacles, obstacle1)
table.insert(obstacles, obstacle2)
If we jump to where the error was, in player:update(), instead of trying to reference the non-existent 'obstacle' (with a lower-case O) we can loop over all the obstacles, which we can now easily do after having created the global 'obstacles' array!

Code: Select all

function Player:update(dt)
	...
	--obstacle collisions
	for index, obstacle in ipairs(obstacles) do
		if self.x == obstacle.x then
			...
		end
		...
	end
	...
end
Note that 'self' refers to the instance of the Player class (which is actually an invisible first argument to the called method). Let's quickly look at that too:

Code: Select all

-- main.lua
function love.update(dt)
	...
	player:update(dt)
	...
end
What's happening here is that we call the 'update' method on the Player class, with the 'player' instance representing 'self' inside Player:update().

In summary, the error happened because we don't define any local or global value called 'obstacle'. (We do define the global 'Obstacle' but that's irrelevant here.) The error could have been fixed by replacing 'obstacle' with 'obstacle1' or 'obstacle2', but since the player probably care about all obstacles we created a globally accessible array containing a reference to all obstacles we created. There are other problems too, and more things that can be done, but I'll leave those for you to find.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
moziL2D
Prole
Posts: 2
Joined: Tue Aug 11, 2020 11:02 pm

Re: Unable to use variables from another class in a class

Post by moziL2D »

Alright, thanks for the help!
Post Reply

Who is online

Users browsing this forum: Amazon [Bot], Google [Bot] and 7 guests