Finite State Machines

i’ve already read reefwings tutorial on finite state machines (http://codeatuts.blogspot.com.au/2012/07/tutorial-5-finite-state-machines.html) and have attempted to create my own using clases. So far what i have i suspect is that the touch function continues running even after i stop it however this may not be the case. My code so far:

Main:

-- Class State

function setup()
    white = White()
    red = Red()
    blue = Blue()
    state = 1
end

function draw()
    if state == 1 then
        white:draw()
    elseif state == 2 then
        red:draw()
    elseif state == 3 then
        blue:draw()
    end
end

function touched(touch)
    if state == 1 then
        white:touched(touch)
        if white.changeToRed == true then
            state = 2
        elseif white.changeToBlue == true then
            state = 3
        end
    elseif state == 2 then
        red:touched(touch)
        if red.changeBack then
            state = 1
        end
    elseif state == 3 then
        blue:touched(touch)
        if blue.changeBack then
            state = 1
        end
    end
end

White:

White = class()

function White:init()
    self.timeToChange = false
end

function White:draw()
    background(255, 255, 255, 255)
    fill(0, 0, 0, 255)
    stroke(0, 255, 245, 255)
    strokeWidth(5)
    font("AmericanTypewriter-Light")
    fontSize(50)
    text("To Red", WIDTH/4, HEIGHT/2)
    text("To Blue", (WIDTH/4)*3, HEIGHT/2)
    line(WIDTH/2, HEIGHT, WIDTH/2, 0)
end

function White:touched(touch)
    if touch.x < WIDTH/2 then
        self.changeToRed = true
    elseif touch.x > WIDTH/2 then
        self.changeToBlue = true
    end
end

Red:

Red = class()

function Red:init()
end

function Red:draw()
    background(255, 0, 0, 255)
end

function Red:touched(touch)
    if touch.x > WIDTH/2 then
        self.changeBack = true
    end
end

Blue:

Blue = class()

function Blue:init()
end

function Blue:draw()
    background(0, 0, 255, 255)
end

function Blue:touched(touch)
    if touch.x < WIDTH/2 then
        self.changeBack = true
    end
end

will getting rid of the white class and putting the necessary “menu” code in main fix the draw/touch problem?

Hey @Jmv38 The python language is similar in many parts of the syntax, however the actual language contains much, much more rules of syntax than lua. THis however is not necessarily a bad thing but rather something to keep in mind. Concerning the creation of graphics, it can get difficult to create something complex. However most graphical interfaces are actually quite manageable.

@Jmv38 - I’ve used both Python and Lua - ( Python at Work and Lua for fun! ) and In my view at a basic level they are very similar. I think you’d get the gist of Python quite quickly if you’re an experienced Lua guy. Python is generally a bit more pedantic and less forgiving than Lua (e.g. ‘Indenting’ of code blocks is part of its syntactic structure, which takes some getting used too!). I do find Lua faster and more compact than Python, although Pythons advanced string handling and extensive library of third party ‘modules’ is really really useful.

I still prefer coding in Lua/Codea for graphics/games type stuff - especially if I want to knock something up quickly. :slight_smile:

I good comparison of both is here: http://lua-users.org/wiki/LuaVersusPython

I suspect your problem is that your touched function gets called twice, once when you press, and once when you let go, so your changes get reversed. You need to trap just the second touch event (when the user lets go), which is when touch.state==ENDED. See below

I’ve also simplified your Main code by putting the colour objects in a table

function setup()
    states={White(),Red(),Blue()}
    state = 1
end

function draw()
    states[state]:draw()
end

function touched(touch)
    if touch.state==ENDED then state=states[state]:touched(touch) end
end
--------------------
White = class()

function White:init()
    self.timeToChange = false
end

function White:draw()
    background(255, 255, 255, 255)
    fill(0, 0, 0, 255)
    stroke(0, 255, 245, 255)
    strokeWidth(5)
    font("AmericanTypewriter-Light")
    fontSize(50)
    text("To Red", WIDTH/4, HEIGHT/2)
    text("To Blue", (WIDTH/4)*3, HEIGHT/2)
    line(WIDTH/2, HEIGHT, WIDTH/2, 0)
end

function White:touched(touch)
    if touch.x < WIDTH/2 then return 2
    elseif touch.x > WIDTH/2 then return 3
    end
end
--------------
Red = class()

function Red:draw()
    background(255, 0, 0, 255)
end

function Red:touched(touch)
    return 1
end
--------------
Blue = class()

function Blue:draw()
    background(0, 0, 255, 255)
end

function Blue:touched(touch)
    return 1
end

thanks @ignatz but one thing that perplexes me is that you didnt create an instance of blue red or white but instead referenced the actual class. Why is this possible and is this recommended?

Hi @dalorbi
I see you are pretty much involved in pythonista forum. I am more and more attracted to pythonista because of the amazing things one can do there (ie: script to download youtube…!!, control home electronics…). Python langage seems very similar to lua, could you comment on that? How much effort do you think it should be for me to learn that langage new for me? I think codea has some advance in the graphics field, but when one uses python to make a graphic app, do we hit very fast an annoying limit, or is it ok?

@dalorbi - actually, I did create instances of red, white and blue, in this line

states={White(),Red(),Blue()}

It assigns an instance of White to states[1], Red to states[2], etc

Doing it in a table makes the draw and touched code a bit simpler, that’s all

Thank you both for these answers.
I carefully read your link @andymac3d and find it excellent. So good to read such high quality collective work!