Lua Class variables shared between objects

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
uniscotty
Prole
Posts: 3
Joined: Sun Jul 12, 2020 6:34 pm

Lua Class variables shared between objects

Post by uniscotty »

Hello! I've been learning Lua and trying to make an asteroid game, and I came upon this issue where I try to make two objects, their position variable is shared. I followed along with the class and inheritance examples in the Lua documentation when making entities. Previously, I had an issue where both the rock and the player ship would have shared the same position variable. This was solved by giving the child class the same-named variable, so I presume the methods were using the pos variables in the immediate class as opposed to walking up to the entity parent class and using the pos variable.

Am I organizing and instancing the objects in a bad way? I've also included my new function for the rock module.

The shared variable issue became apperent when I tried this.

Code: Select all

local rock1 = Rock:new(nil, player.pos)
print(rock1.pos.y)
local rock2 = Rock:new(nil, player.pos)
print(rock1.pos.y)
print(rock2.pos.y)
My method for creating new rocks, which apparently shares the same pos table for each of the rock objects.

Code: Select all

--------------- enemy rock module ---------------
-- inherits from entity

local entity = require "entity"
local asset = require "accessAssest"

Rock = Entity:new()
math.randomseed(69) -- nice

function Rock:new(rock, playerPos)
  rock = Entity:new(rock, xNew, yNew, angle, img)
  setmetatable(rock, self)
  self.__index = self

  self.ID = "Rock"
  self.pos = {}
  self.pos.x, self.pos.y = Rock:spawnRockPosition()
  self.angle = Rock:getAngleToPlayer(playerPos)

  -- velocity of entity in x,y
  self.maxVel = 10
  self.accelRate = 10
  self.vel   = {x = 0, y = 0}

  -- velcoity of the entity's rotation
  self.rotVel = 0
  self.maxRotVel = math.pi
  self.accelRotRate = math.pi*2

  self.rotationDir = 0

  -- changable later
  self.img = asset.getAssest("rockIMG")

  -- initilize hitbox information, a rectangle at the center of the rock
  self.hitx = self.pos.x - self.img:getWidth()/4
  self.hity = self.pos.y - self.img:getHeight()/4

  self.hitWidth  = self.img:getWidth()/2
  self.hitHeight = self.img:getHeight()/2

  return rock
end

Code: Select all

function Entity:new(entity, xNew, yNew, angle, img)
  entity = entity or {}
  setmetatable(entity, self)
  self.__index = self

  --[[
   IMPORTANT NOTE:
   Variables that children classes depend on need to be redefined in the
   new of the child class. Otherwise, it the child class uses
   the variables from the entity class. These variables are used here for the
   definition of the entity class functions.
  ]]

  -- position of entity in x,y
  self.pos = {x = 0, y = 0}

  -- velocity of entity in x,y
  self.maxVel = 300
  self.accelRate = 200
  self.vel   = {x = 0, y = 0}

  -- velcoity of the entity's rotation
  self.rotVel = 0
  self.maxRotVel = math.pi
  self.accelRotRate = math.pi*2

  -- set initial positions of entity
  self.pos.x = xNew or 0
  self.pos.y = yNew or 0

  -- EDIT INPUT OF NEW: is either nil or the img paramater, can be reset useing setImg method
  self.img = nil

  -- starting angle of entity
  self.angle = angle or math.pi

  -- draw angle

  -- insert the new entity into the entity table
  table.insert(entityTable, self)
  -- increment the stored number of entities
  entityNumber = entityNumber + 1

  return entity
end
Thank you for your time and assistance, I've been stuck on this problem for a hot second. :awesome:
Attachments
rock.lua
(3.1 KiB) Downloaded 124 times
entity.lua
(4.87 KiB) Downloaded 131 times
Last edited by uniscotty on Sun Jul 12, 2020 10:32 pm, edited 2 times in total.
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Lua Class variables shared between objects

Post by pgimeno »

You haven't provided all information (the entity.lua file is missing, so I can't know if Entity:new() is correctly defined) but take a look at this thread: https://love2d.org/forums/viewtopic.php?f=4&t=89113 in which someone had pretty much the same problem.
uniscotty
Prole
Posts: 3
Joined: Sun Jul 12, 2020 6:34 pm

Re: Lua Class variables shared between objects

Post by uniscotty »

I added the Lua files to the original post, and I'll check out the topic you posted. It does sound very similar to the issue I'm having. Thanks already!
TheHUG
Citizen
Posts: 61
Joined: Sun Apr 01, 2018 4:21 pm

Re: Lua Class variables shared between objects

Post by TheHUG »

The problem is that in Rock:new() you're setting self.pos. `self` is the object called on - i.e. Rock. the table whose values you want to set is the one you named rock (which you really ought to declare as local btw!). The result is that both rock's .pos attrib reference Rock.pos.

you make the same mistake in Entity:new() (and incidentally, you duplicate several operations that you also do in Rock.new())

you could also change your function signatures to

Code: Select all

function Rock.new(proto, playerPos)
     self = Entity:new(...)
     setmetatable(self, proto)
     proto.__index = proto
     .....
     end	
one more thing, you're currently adding Rock to the entitytable, which I assume contains in-world objects. Unless the concept of being a rock is physically reified in your game world, I'm guessing you don't want to do that. you can avoid it with

Code: Select all

 Rock = setmetatable({}, Entity). 
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 226 guests