Instance variables, and overriding superclass functions

Hi

I’m new to Codea, and Lua… but I am really enjoying it.

I have a question about inheritance.

I want to create a class that encapsulates a physics body, and draws a sprite where the body is. To do this, I created a base class, which includes a string for the desired sprite.

The problem is that if I create two objects, each from a different subclass the sprite string always changes to that of the last object that was instantiated.

Block base class

Block = class()

body = nil
srcSprite = nil

function Block:init(x, y, w, h, aSprite)
    self.body = physics.body(POLYGON, vec2(0,0), vec2(0,h), vec2(w,h), vec2(w,0))
    self.body.x = x
    self.body.y = y
    self.type = STATIC
    srcSprite = aSprite
end

function Block:draw()
    pushMatrix()
    translate(self.body.x, self.body.y)
    sprite(srcSprite, 0, 0)
    popMatrix()
end

Subclass 1

WoodBlock = class(Block)

function WoodBlock:init(x, y, w, h)
    -- you can accept and set parameters here
    Block.init(self, x, y, w, h, "Planet Cute:Wood Block")
end

function WoodBlock:draw()
    Block.draw(self)
end

Subclass 2

GrassBlock = class(Block)

function GrassBlock:init(x, y, w, h)
    -- you can accept and set parameters here
    Block.init(self, x, y, w, h, "Planet Cute:Grass Block")
end

function GrassBlock:draw()
    Block.draw(self)
end

Main

supportedOrientations(LANDSCAPE_ANY)

woodBlock = nil
grassBlock=nil

function setup()
    woodBlock = WoodBlock(0, 0, 101, 160)
    grassBlock = GrassBlock(400, 0, 101, 160)
end

function draw()
    woodBlock:draw()
    grassBlock:draw()
end

Both blocks will show the second image (grass). If I switch the order in setup(), they both show the wood sprite.

Please help.

Your Block base class needs to store its members on its table, rather than globally.

Note that srcSprite is moved to self.srcSprite

Block = class()

function Block:init(x, y, w, h, aSprite)
    self.body = physics.body(POLYGON, vec2(0,0), vec2(0,h), vec2(w,h), vec2(w,0))
    self.body.x = x
    self.body.y = y
    self.type = STATIC
    self.srcSprite = aSprite
end

function Block:draw()
    pushMatrix()
    translate(self.body.x, self.body.y)
    sprite(self.srcSprite, 0, 0)
    popMatrix()
end

```


The behaviour you were seeing had the last-instantiated class overwriting the srcSprite global variable.

Of course (feels dumb now). Too obvious! Thank you. :slight_smile:

@nomore

See the changes and additions I made. (changed) (added)


Block = class()

body = nil
srcSprite = nil

function Block:init(x, y, w, h, aSprite)
    self.body = physics.body(POLYGON, vec2(0,0), vec2(0,h), vec2(w,h), vec2(w,0))
    self.body.x = x
    self.body.y = y
    self.body.type = STATIC    -- changed
    self.srcSprite = aSprite    -- changed
end

function Block:draw()
    pushMatrix()
    translate(self.body.x, self.body.y)
    sprite(self.srcSprite, 0, 0)    --changed
    popMatrix()
end
--Subclass 1

WoodBlock = class(Block)

function WoodBlock:init(x, y, w, h)
    -- you can accept and set parameters here
    Block.init(self, x, y, w, h, "Planet Cute:Wood Block")
end

function WoodBlock:draw()
    Block.draw(self)
end
--Subclass 2

GrassBlock = class(Block)

function GrassBlock:init(x, y, w, h)
    -- you can accept and set parameters here
    Block.init(self, x, y, w, h, "Planet Cute:Grass Block")
end

function GrassBlock:draw()
    Block.draw(self)
end
--Main

supportedOrientations(LANDSCAPE_ANY)

woodBlock = nil
grassBlock=nil

function setup()
    woodBlock = WoodBlock(100, 0, 101, 160)    -- changed
    grassBlock = GrassBlock(400, 0, 101, 160)
end

function draw()
    background(40,40,50)    --added
    woodBlock:draw()
    grassBlock:draw()
end

@dave1701. Thanks for the clarifications.

This may be obvious, but unless you need to take additional steps, the WoodBlock:draw() and GrassBlock:draw() functions aren’t needed.