Inheritance problems

I’ve been scratching my head on this one for a while so I’ve taken the step of stripping back my code to the bare minimum so people can have a go at spot the bug. I am trying to get some specific menus to work as a subclass of a broader Button class and even though I’ve got this working in some other part of my code (deleted here for brevity) the touched function just isn’t being called properly this time. I wonder if it’s a problem with the way I’m using the scene manager that I shamelessly copied from an old post on here. Any ideas, anyone? I’ve tried making all sorts of changes without success.



--# Main



-- Use this function to perform your initial setup
function setup()
    supportedOrientations(PORTRAIT)
    displayMode(OVERLAY)

    sceneManager = SceneManager({MapScreen()})

end

-- This function gets called once every frame
function draw()
    sceneManager:draw()
end

function touched(touch)
    sceneManager:touched(touch)
end

function keyboard(key)
    sceneManager:keyboard(key)
end

function textTop(str,x,y)
    local w,h = textSize(str)
    text(str,x,y-h)
    
end

--# Button
Button = class()

function Button:init(displayName)

    -- you can accept and set parameters here

    self.displayName = displayName
    
    self.pos = vec2(0,0)
    self.size = vec2(0,0)
    self.action = nil
    self.color = color(190, 143, 65, 255)

end

function Button:draw()

    pushStyle()

    fill(self.color)

    font("Baskerville-SemiBold")
    fontSize(25)
    
    -- use display name for size

    local w,h = textSize(self.displayName)
    w = w + 30
    h = h + 20
    

    RoundRect(self.pos.x-w/2,
              self.pos.y-h/2,
              w,h,15)
            
    self.size = vec2(w,h)


        
    textMode(CENTER)
    fill(54, 65, 96, 255)
    text(self.displayName,self.pos.x+2,self.pos.y-2)
    fill(255, 255, 255, 255)
    text(self.displayName,self.pos.x,self.pos.y)
    


    popStyle()

end

function Button:hit(p)


    local l = self.pos.x - self.size.x/2
    local r = self.pos.x + self.size.x/2
    local t = self.pos.y + self.size.y/2
    local b = self.pos.y - self.size.y/2

    if p.x > l and p.x < r and
       p.y > b and p.y < t then
        return true
    end
    return false
end

function Button:touched(touch)

    -- Codea does not automatically call this method
    -- print("wooeee2!")
    if touch.state == ENDED and
       self:hit(vec2(touch.x,touch.y)) then
        if self.action then
            self.action()
        end
    end
    

end

--# SceneManager
SceneManager = class()

function SceneManager:init(scenes)
    -- you can accept and set parameters here
    self.scenes = scenes
    if (table.maxn(self.scenes) > 0) then
        self.currentScene = scenes[1]
    end
end

function SceneManager:addScene(scene)
    table.insert(self.scenes, scene)
    if (table.max (self.scenes) == 1) then
        self.currentScene = scenes[1]
    end
end


function SceneManager:switchScene(newScene)
    faderclockreset()
        
    if (self.currentScene.onExit) then
        self.currentScene:onExit()
    end
    
    self.currentScene = self.scenes[newScene]
    
    if (self.currentScene.onEnter) then
        self.currentScene:onEnter()
    end
end


function SceneManager:update()
    if (self.currentScene.update) then
        self.currentScene:update()
    end
end


function SceneManager:draw()
    if (self.currentScene.draw) then
        self.currentScene:draw()
    end
end

function SceneManager:touched(touch)
    if (self.currentScene.touched) then
        self.currentScene:touched(touch)
    end
end

function SceneManager:keyboard(key)
    if (self.currentScene.keyboard) then
        self.currentScene:keyboard(key)
    end
end
--# MapScreen
MapScreen = class()

-- Map

-- Use this function to perform your initial setup
function MapScreen:init()

    map_leftbut = MapMenu(2)
    map_rightbut = MapMenu(3)
    map_leftbut.pos = vec2(150, 200)
    map_rightbut.pos = vec2(WIDTH-150, 200)
    
end

function MapScreen:onEnter()
    
end

function MapScreen:draw()
    background(255, 255, 255, 255)
    self:drawButtons()
end

function MapScreen:drawButtons()
    pushStyle()
    
    map_leftbut:draw()
    map_rightbut:draw()
    
    popStyle()
end

function MapScreen:onExit()
    
end


function MapScreen:touched(touch)
    
    map_leftbut:touched(touch)
    map_rightbut:touched(touch)
    
end


MapMenu = class(button)


function MapMenu:init(displayName)
    Button.init(self, displayName)
    self.displayName = displayName

    
    self.action = function() print("HELLO!") end
    
end


function MapMenu:draw()
    -- Codea does not automatically call this method
    pushStyle()
    fill(73, 125, 30, 255)
    
    font("Baskerville-SemiBold")
    fontSize(25)
    textWrapWidth(140)
    textAlign(CENTER)
    -- use display name for size
    
    local x,y = textSize(self.displayName)
    w = 180
    h = 150
    
    
    RoundRect(self.pos.x-w/2,
    self.pos.y-h/2,
    w,h,15)
    
    self.size = vec2(w,h)
    
    textMode(CENTER)
    fill(96, 63, 54, 255)
    text(self.displayName,self.pos.x+2,self.pos.y+y-2)
    fill(235, 232, 226, 255)
    text(self.displayName,self.pos.x,self.pos.y+y)
    
    popStyle()
end



--# RoundRect
function RoundRect(x,y,w,h,r)
    pushStyle()
    pushMatrix()
    insetPos = vec2(x+r,y+r)
    insetSize = vec2(w-2*r,h-2*r)
    
    --Copy fill into stroke
    local red,green,blue,a = fill()
    stroke(red,green,blue,a)
    
    noSmooth()
    rectMode(CORNER)
    rect(insetPos.x,insetPos.y,insetSize.x,insetSize.y)
    
    if r > 0 then
        smooth()
        lineCapMode(ROUND)
        strokeWidth(r*2)

        line(insetPos.x, insetPos.y, 
             insetPos.x + insetSize.x, insetPos.y)
        line(insetPos.x, insetPos.y,
             insetPos.x, insetPos.y + insetSize.y)
        line(insetPos.x, insetPos.y + insetSize.y,
             insetPos.x + insetSize.x, insetPos.y + insetSize.y)
        line(insetPos.x + insetSize.x, insetPos.y,
             insetPos.x + insetSize.x, insetPos.y + insetSize.y)            
    end
    popMatrix()
    popStyle()
end

You say class(button), but the variable name of the class you want to have as the parent is Button (CaSe SeNsItIvE)

I haven’t tried the code, but try using MapMenu = class(Button)

argh! So simple! How embarrassing. I’ll just have to add that to my debug checklist. Thank you, it was exactly that.