Struggling to understand

I’m struggling to understand codea, below is the code, goal: player is triangle, push one button to turn left push the other to turn right, however the touch function doesn’t respond as expected?

– Use this function to perform your initial setup
function setup()
viewer.mode = FULLSCREEN
rectMode(CENTER)

local y = 200
local l = WIDTH / 6
local r = l * 4.25
local s = 70

player = Player()


btn1 = Button(r, y, s, s, player, "left")
btn2 = Button(r + 100, y, s, s, player, "right")

end

– This function gets called once every frame
function draw()
– This sets a dark background color
background(40, 40, 50)

player:draw()

btn1:draw()
btn2:draw()

-- Do your drawing here

end

function touched(touch)

btn1:touched(touch)
btn2:touched(touch)

end

Player = class()

function Player:init()
– you can accept and set parameters here
self.x = 0
self.y = 0
self.dx = WIDTH/2
self.dy = HEIGHT/2
self.ps = 60/2
self.r = 0
self.playermesh = mesh()
self.dir = “stop”

self.playermesh.vertices = {vec2(self.x, self.y + self.ps), vec2(self.x - self.ps, self.y - self.ps), vec2(self.x + self.ps, self.y - self.ps)}

end

function Player:draw()
– Codea does not automatically call this method
pushStyle()
fill(255, 0, 15)

pushMatrix()
translate(self.dx, self.dy)
if self.dir == "right" then
    self.r = self.r - 4
    print(self.dir)
end
if self.dir == "left" then
    self.r = self.r + 4
    print(self.dir)
end
rotate(self.r)
self.playermesh:draw()
popMatrix()
popStyle()

end

function Player:touched(touch)
– Codea does not automatically call this method
end

function Player:update(dir)
if dir == “right” then
self.dir = dir
end
if dir == “left” then
self.dir = dir
print(self.dir)
end
if dir == “stop” then
self.dir = dir
end
end

Button = class()

function Button:init(x, y, h, w, action, dir)
– you can accept and set parameters here
self.x = x
self.y = y
self.h = h
self.w = w
self.pressed = false
self.action = action
self.dir = dir
end

function Button:draw()
– Codea does not automatically call this method

pushStyle()
rectMode(CENTER)

if self.pressed then
    fill(233, 233, 80)
else
    fill(80, 233, 101)
end
rect(self.x, self.y, self.w, self.h)
popStyle()

end

function Button:hit(x, y)
return x < self.x + self.w/2 and x > self.x - self.w/2 and y > self.y - self.h/2 and y < self.y + self.h/2
end

function Button:touched(touch)
– Codea does not automatically call this method
if touch.state == BEGAN then
self.pressed = self:hit(touch.x, touch.y)
self.action:update(self.dir)
elseif touch.state == ENDED then
self.pressed = self:hit(touch.x, touch.y)
self.action:update(“stop”)
end
end

hi @Dlna4cert - welcome to the community. You’ve obviously picked up on Codea pretty well, I think the problem here is that your definition for the rotation value results in a value with one sign instead of two.

It took me a while to load your project as you have embedded the code multiple times. I took the liberty of rehashing it and posted it below for anyone who would like to check it out and feed back suggestions.


viewer.mode = FULLSCREEN
function setup()
    --
    rectMode(CENTER)
    local y = 200
    local l = WIDTH / 6
    local r = l * 4.25
    local s = 70
                
    player = Player()
                    
    btn1 = Button(r, y, s, s, player, "left")
    btn2 = Button(r + 100, y, s, s, player, "right")
end
        
function draw()
    -- 
    background(40, 40, 50)
                
    player:draw()
                
    btn1:draw()
    btn2:draw()       
        
end
            
function touched(touch)
    --     
    btn1:touched(touch)
    btn2:touched(touch)     
end
            
Player = class()
            
function Player:init()
    -- you can accept and set parameters here
    self.x = 0
    self.y = 0
    self.dx = WIDTH/2
    self.dy = HEIGHT/2
    self.ps = 60/2
    self.r = 0
    self.playermesh = mesh()
    self.dir = "stop"
                    
    self.playermesh.vertices = {vec2(self.x, self.y + self.ps), vec2(self.x - self.ps, self.y - self.ps), vec2(self.x + self.ps, self.y - self.ps)
    }
end
                
function Player:draw()
    -- 
    pushStyle()
        fill(255, 0, 15)
        pushMatrix()
            translate(self.dx, self.dy)
            if self.dir == "right" then
                self.r = self.r - 4
                print(self.dir)
            end
            if self.dir == "left" then
                self.r = self.r + 4
                print(self.dir)
            end
            rotate(self.r)
            self.playermesh:draw()
        popMatrix()
    popStyle()            
end
                
function Player:touched(touch)
    --
end
                
function Player:update(dir)
    --
    if dir == "right" then
        self.dir = dir
        self.r = self.r - 4
    end
    if dir == "left" then
        self.dir = dir
        self.r = self.r + 4
        print(self.dir)
    end
    if dir == "stop" then
        self.dir = dir
    end
end
                
Button = class()
                
function Button:init(x, y, h, w, action, dir)
    --
    self.x = x
    self.y = y
    self.h = h
    self.w = w
    self.pressed = false
    self.action = action
    self.dir = dir
end
                
function Button:draw()
    --         
    pushStyle()
        rectMode(CENTER)             
        if self.pressed then
            fill(233, 233, 80)
        else
            fill(80, 233, 101)
        end
        rect(self.x, self.y, self.w, self.h)
    popStyle()
end
                
function Button:hit(x, y)
    --
    return x < self.x + self.w/2 and x > self.x - self.w/2 and y > self.y - self.h/2 and y < self.y + self.h/2
end
                
function Button:touched(touch)
    --
    if touch.state == BEGAN then
        self.pressed = self:hit(touch.x, touch.y)
        self.action:update(self.dir)
    elseif touch.state == ENDED then
        self.pressed = self:hit(touch.x, touch.y)
        self.action:update("stop")
    end
end     

I’ll post a few suggestions later when I can see the best way forward with this.

Well as per usual taking a break I realized my mistakes, simple programming errors, here is the corrected code. For anyone interested.


--# Main
viewer.mode = FULLSCREEN
function setup()
    --
    rectMode(CENTER)
    local y = 200
    local l = WIDTH / 6
    local r = l * 4.25
    local s = 70
    
    player = Player()
    
    btn1 = Button(r, y, s, s, player, "left")
    btn2 = Button(r + 100, y, s, s, player, "right")
end

function draw()
    -- 
    background(40, 40, 50)
    
    player:draw()
    
    btn1:draw()
    btn2:draw()       
    
end

function touched(touch)
    --     
    btn1:touched(touch)
    btn2:touched(touch)     
end

Player = class()

function Player:init()
    -- you can accept and set parameters here
    self.x = 0
    self.y = 0
    self.dx = WIDTH/2
    self.dy = HEIGHT/2
    self.ps = 60/2
    self.r = 0
    self.playermesh = mesh()
    self.dir = "stop"
    
    self.playermesh.vertices = {vec2(self.x, self.y + self.ps), vec2(self.x - self.ps, self.y - self.ps), vec2(self.x + self.ps, self.y - self.ps)
    }
end

function Player:draw()
    -- 
    pushStyle()
    fill(255, 0, 15)
    pushMatrix()
    translate(self.dx, self.dy)
    if self.dir == "right" then
        self.r = self.r - 4
    end
    if self.dir == "left" then
        self.r = self.r + 4
    end
    rotate(self.r)
    self.playermesh:draw()
    popMatrix()
    popStyle()            
end

function Player:touched(touch)
    --
end

function Player:update(dir)
    --
    if dir == "right" then
        self.dir = dir
    end
    if dir == "left" then
        self.dir = dir
    end
    if dir == "stop" then
        self.dir = dir
    end
end

Button = class()

function Button:init(x, y, h, w, action, ndir)
    --
    self.x = x
    self.y = y
    self.h = h
    self.w = w
    self.pressed = false
    self.action = action
    self.dir = ndir
end

function Button:draw()
    --         
    pushStyle()
    rectMode(CENTER)             
    if self.pressed then
        fill(233, 233, 80)
    else
        fill(80, 233, 101)
    end
    rect(self.x, self.y, self.w, self.h)
    popStyle()
end

function Button:hit(x, y)
    --
    return x < self.x + self.w/2 and x > self.x - self.w/2 and y > self.y - self.h/2 and y < self.y + self.h/2
end

function Button:touched(touch)
    --
    if touch.state == BEGAN then
        self.pressed = self:hit(touch.x, touch.y)
        if self.pressed then
            self.action:update(self.dir)
        end
    else 
        if touch.state == ENDED then
            self.pressed = false
            self.action:update("stop")
        end
    end
end

@Dlna4cert your corrected touched function still has a bug in it. Though, it’s not detrimental to your project in its current incarnation.

        -- the condition just tests for touch ended.
        -- This will be true for both buttons, so update("stop")
        -- will always be called twice on touch lift. 
        if touch.state == ENDED then
            self.pressed = false
            self.action:update("stop")
        end

Here is a corrected version:

        -- the condition now only tests for touch ended IF
        -- it was the button pressed on BEGAN
        if self.pressed and touch.state == ENDED then
            self.pressed = false
            self.action:update("stop")
        end