Help with coding

Hello there!

I am writing a code that involves buttons.
Can someone give me a code that uses a button.

(i.e. press a button, a sound goes off)

Here’s a quick little button class that takes an img, position, size and callback:
Simply change the callback function to do whatever you want when the button is pressed


--# Main
-- Button

function setup()
    local img = readImage("Cargo Bot:Clear Button")
    testButton = Button(img, WIDTH/2, HEIGHT/2, testCallback, vec2(175, 80))
end

function draw()
    background(40, 40, 50)
    
    testButton:draw()
end

function testCallback()
    sound(DATA, "ZgBA0wBQQWEOPxISHwsfvneLED8taNS+YQB2dhJZQHNGP2Qs")
    print("You Touched the Button")
end

function touched(touch)
    testButton:touched(touch)
end
--# Button
Button = class()

function Button:init(img, x, y, callback, size)
    self.img = img
    self.x = x
    self.y = y
    self.size = size
    self.drawSize = self.size
    self.callback = callback
    self.pressed = false
    self.tint = color(127)
end

function Button:draw()
    pushStyle()
    --noSmooth()
    if self.pressed then
        tint(self.tint)
    end
    sprite(self.img, self.x, self.y, self.drawSize.x, self.drawSize.y)
    popStyle()
end

function Button:touched(touch)
    if touch.x > self.x - self.size.x/2 and touch.x < self.x + self.size.x/2 and
    touch.y > self.y - self.size.y/2 and touch.y < self.y + self.size.y/2 then
        if touch.state == BEGAN or touch.state == MOVING then
            self.pressed = true
        elseif touch.state == ENDED then
            self.pressed = false
            self.callback()
        end
    else
        self.pressed = false
    end
end

@tyguy2 If you want something smaller.


function setup()
end

function draw()
    background(40, 40, 50)
    rectMode(CENTER)
    fill(255)
    rect(WIDTH/2,HEIGHT/2,100,50)
    fill(236, 27, 27, 255)
    text("press here",WIDTH/2,HEIGHT/2)    
end

function touched(t)
    if t.state==BEGAN then
        if t.x>WIDTH/2-50 and t.x<WIDTH/2+50 and
            t.y>HEIGHT/2-25 and t.y<HEIGHT/2+25 then
                sound(SOUND_POWERUP, 7382)
        end
    end
end

@dave1707, that way works, but it ends up bigger as you add more buttons

@JakAttak I agree, but for someone just starting out, I like to show them simple code. Once they understand what it takes to do what they ask, they can move on to bigger and better things. I’m not sure if tyguy2 understands classes or how to use them, so I made it small.

Makes sense. Though from my previous encounter with him, he seems to understand classes at least enough: http://www.twolivesleft.com/Codea/Talk/discussion/3327/help-with-code#Item_19

I suggest using the excellent class there http://twolivesleft.com/Codea/Talk/discussion/comment/29909#Comment_29909

lol

How would I add buttons?

Collision box detection can be smaller:

if math.abs(self.x - touch.x) <= self.width and math.abs(self.y - touch.y) <= self.height then
    ...
end

@SkyTheCoder Your Collision Box Detection looks similar to what @West posted in the link below. It turned out that it didn’t work as expected. Look at the link below, half way down for the line of code similar to yours, but look at the last 3 discussions in the link for an example of what was actually happening.

http://twolivesleft.com/Codea/Talk/discussion/3419/basic-touch-zone-detection-how-should-it-be-re-written-to-optimise-the-code#Item_12

That’s where I got it from. I found that before they said it didn’t work. Time to recode some projects…

@SkyTheCoder Dividing self.width and self.height by 2 should fix your line of code.


if math.abs(self.x - touch.x) <= self.width/2 and math.abs(self.y - touch.y) <= self.height/2 then
    ...
end

this has completely turned from the topic question…

@tyguy2 That happens sometimes, but I didn’t want anyone to use code that wasn’t correct and then post a question asking why it doesn’t work.

nah, just messing with you guys. But seriously, how do I add more buttons?

@tyguy2 @JakAttak gave an example of a button class. Are you familiar with the use of classes. Or, would you like me to make changes to my example above to add more buttons without the use of classes. Or would you like an example using classes. You’re not giving enough info in your question.

@tyguy2 I’m off to bed, so I thought since you didn’t respond yet I would give you an example of multiple buttons using a simple class. There are 4 buttons here, each with a different size, different text, different sounds, and not lined up. I used a table for the buttons so you can add more buttons without adding any other code. To add more buttons, just copy one of the table.insert lines and paste it back and change the values. You can change the x,y location, the width, height, the name, and the sound of any button just to play around. Using a class, it is very easy to add buttons without adding a lot more code. The more complex you make the class, the more complex the button can be.


displayMode(FULLSCREEN)

function setup() 
    bTab={}    -- button table
    -- button( x, y, width, height, name, sound type, sound value )
    table.insert(bTab,button(350,600,100,50,"button 1",SOUND_HIT,1218))
    table.insert(bTab,button(500,500,150,50,"button 2",SOUND_POWERUP,15955))
    table.insert(bTab,button(200,350,100,100,"button 3",SOUND_PICKUP,37051))
    table.insert(bTab,button(500,200,100,30,"button 4",SOUND_SHOOT,48654))
end

function draw()
    background(40, 40, 50)
    for a,b in pairs(bTab) do
        b:draw()
    end
end

function touched(t)
    for a,b in pairs(bTab) do
        b:touched(t)
    end
end

button=class()

function button:init(x,y,w,h,name,st,sv)
    self.x=x    -- x position
    self.y=y    -- y position
    self.w=w    -- width
    self.h=h    -- height
    self.name=name    -- button name
    self.touch=false    -- button touched
    self.st=st    -- sound type
    self.sv=sv    -- value
end

function button:draw()
    rectMode(CENTER)
    fill(255)
    rect(self.x,self.y,self.w,self.h)
    fill(255, 0, 0, 255)
    text(self.name,self.x,self.y)
    if self.touch then
        text(self.name.." touched",self.x+150,self.y)
    end
end

function button:touched(t)
    if t.state==BEGAN then
        self.touch=false
        if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and
            t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
                self.touch=true
                sound(self.st,self.sv)
        end
    end
end

@dave1707 There’s no need to use pairs for all the buttons, you can just use ipairs since it is indexed. Using pairs on an indexed table can lead to odd orders, such as 1 3 4 2. ipairs would draw them in the order they were added.

@SkyTheCoder By definition you’re correct. I put a print statement in button.draw to print the button names, and the names printed in the correct order each time I ran the program. So it appears that pairs and ipairs are giving the same results in this case. Even if they didn’t, since the buttons don’t interact with each other, it doesn’t matter what their order is. And I don’t think anyones vision is that good that they would be able tell if the buttons displayed out of order anyways. So it really doesn’t matter.