Error With my code

Hi, I’ve written a code for make a button and pressed it but it doesn’t work.
I don’t know why ’
Main :



-- Test

-- Use this function to perform your initial setup
function setup()
    print("Hello World!")
    local x = 200
    local y = 200
    local h = 50
    local w = 100
    parameter("x", 50, 1000)
    parameter("y", 50, 1000)
    parameter("h", 5, 200)
    parameter("w", 10, 400)
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    setbutton(x,y,w,h)
    local push=push(x,y,h,w)
    if push == 1 then
    print("Button pressed !")
    end
    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    
end

Roundrect :


function setbutton(x,y,h,w)
    
    stroke(216, 119, 44, 255)
    rect(x,y,h,w)
    
    
end

function push(x,y,h,w)
    
    local tx
    local ty
    if touch.x== nil then
        tx = 0
        ty = 0
    else
        touch.x = tx
        touch.y = ty
    end
        if tx>x and tx<x+w and ty>y and ty<y+h then
            return 1
        end
    
    
       
end

This code return this error :

error : error : [ string " function setbutton( x,y,h,w) …"] attempt to index global ‘touch’ (a nil value)

Thanks for explain me this error.

I believe it is because you defined your x,y,h, and w as local variables, then tried to use them outside of the function where they were defined. Comment out the local lines.

When you touch the viewer, Codea itself tries to call a function named touched(touch) (if it exists). So your code needs to be something like the following:


function setup() -- Called once by Codea
    parameter("x", 50, 1000, 200)
    parameter("y", 50, 1000, 200)
    parameter("h", 5, 200, 50)
    parameter("w", 10, 400, 100)
    strokeWidth(5)
end

function draw() -- Called by Codea up to 60 times a second
    background(40, 40, 50) -- Clear the viewer to a dark colour
    setbutton(x, y, w, h)     -- Call the function that draws the button
end

function touched(touch) -- Called by Codea when viewer is touched
    local tx = touch.x
    local ty = touch.y
    if tx>x and tx<x+w and ty>y and ty<y+h then
        print("Button pressed !")
    end
end

-- Your helper function that draws the button
function setbutton(x, y, h, w)
    stroke(216, 119, 44, 255)
    rect(x, y, h, w)
end

@eloi67 well done on trying to work this out from scratch yourself. If @jlslate and @mpilgrem suggestions haven’t help you solve the issue then have a look at:

http://codeatuts.blogspot.com.au/2012/06/tutorial-3-simple-button-class.html

Thanks for all your answers . My code work now !

But when I tried to modify the function to modify colors when call the function, there is an other error :


function setup()
    parameter("x", 50, 1000, 200)
    parameter("y", 50, 1000, 200)
    parameter("h", 5, 200, 50)
    parameter("w", 10, 400, 100)
    pressed = false
    strokeWidth(5)
    he=950
    parameter("button_color[1]", 100, 255, 0)
    parameter("button_color[2]", 50, 255, 0)
    parameter("button_color[3]", 150, 255, 0)
    parameter("button_color[4]", 255, 255, 0)
end

function draw()
    background(40, 40, 50)
    setbutton(x, y, w, h, button_color)
    if pressed then 
        font("ArialRoundedMTBold")
        ok = true
        he = he - 30
        pressed = false
    end
    if ok then
        font("AmericanTypewriter-CondensedBold")
        text("BUTTON PRESSED!", WIDTH/2, he)
    end
    if he < y then
        he = 950
    end
end

function touched(touch)
    local tx = touch.x
    local ty = touch.y
    if tx>x and tx<x+w and ty>y and ty<y+h then
        pressed = true
    end
end

function setbutton(x,y,h,w,button_color)
    stroke(button_color[1], button_color[2], button_color[3], button_color[4])
    rect(x,y,h,w)
end

Error: error: [ string “function setup() …”] :42: attemp to index local ‘button_color’ ( a nil value )

Hi @ eloi67
Might not be the best solution but the following works

You need to define button_color as an array up front, so after he=950 add

button_color={}

And in the set button function change the references from [x] to x where x is the position in the table/array. E.g button_color[1] becomes button_color_1_

I’m not sure why square bracket referencing doesn’t work but this reflects the variable name on the left hand pane with the adjusters.

Also you may wish to change the parameter to iparameter as the colour components will only be integers.

Finally the parameter values should run 0,255,y where y is your default value. You have it the other way round at the moment

One other code :


function setup()

    print("test")
    buttoncog.x = 0
    buttoncog.y = 0
    buttoncog.w = 1000
    buttoncog.h = 1000
    
end

function draw()
    
    background(89, 176, 90, 255)
    
end

function touched(touch)
    pressbutton(buttoncog, touch)
end
    
function pressbutton(buttonco, touch)
    
    if touch.x > buttonco.x and touch.x < buttonco.x + buttonco_w_ and touch.y > buttonco.y
    and touch.y < buttonco.y + buttonco.y then
    print("great")
    end
    
end

One other error : Error: error: [ string “function setup() …”] :4: attemp to index local ‘buttoncolorg’ ( a nil value )

buttoncolorg = {} (or buttoncog = {} - the error message and the code are a bit out of step on the name)

You need to initialise tables before you can start assigning values to it.

This code :


function setup()

    print("test")
    buttoncog = {}
    buttoncog.x = 0
    buttoncog.y = 0
    buttoncog.w = 1000
    buttoncog.h = 1000
    
end

function draw()
    
    background(89, 176, 90, 255)
    
end

function touched(touch)
    pressbutton(buttoncog, touch)
end
    
function pressbutton(buttonco, touch)
    
    if touch.x > buttonco.x and touch.x < buttonco.x + buttonco.w and touch.y > buttonco.y
    and touch.y < buttonco.y + buttonco.y then
    print("great")
    end
    
end

Must print " great " when I touch on the screen but it doesn’t . Why ?

Hah — that was really hard to spot.

Your last test in the if statement checks for:

touch.y < buttonco.y + buttonco.y

Should be

touch.y < buttonco.y + buttonco.h

Thank you very much ! It work now .

Good evening !
I did a test with class :
Menu :


Menu = class()

function Menu:init(namebutton,x,y,w,h,r)
    -- you can accept and set parameters here
    self.namebutton = namebutton
    self.x = x
    self.y = y
    self.h = h
    self.w = w
    self.r = r
end

function Menu:draw()
    -- Codea does not automatically call this method
    setbutton(self.x, self.y, self.w, self.h, self.r)
    fill()
    font("Arial-BoldMT")
    text(self.namebutton, self.y + 5, self.x + 5)
end

function Menu:touched(touch)
    -- Codea does not automatically call this method
end


function  setbutton(x,y,w,h,r) 

    stroke(255, 0, 1, 255)
    fill(255, 0, 0, 255)
    insetPos = vec2(x+r,y+r)
    insetSize = vec2(w-2*r,h-2*r)
        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
        
end

Button :


test = class(Menu)

function test:init()
    
    Menu.init(self, "test", 100, 100, 100, 50, 30)
    
end

Main :



-- Firecracker War

-- Use this function to perform your initial setup
function setup()
    print("Hello World!")
    strokeWidth(5)
    d = test()
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    d:draw()
    background(40, 40, 50)
    -- Do your drawing here
    
end

This code must draw a rectangle , but it doesn’t . An idea ?

Possibly because you draw the background after the other stuff so it goes on top. Try swapping those statements and see if that helps.