Page 1 of 1

How to draw and code a state machine? (pictures!)

Posted: Fri Sep 07, 2018 6:13 am
by xThomas
I don't know how to make a state machine the correct way. But I wanted to write out possible states and try anyway.

Deck - has the states idle, fetching and empty. idle responds to a click which turns its state to fetching. fetching takes 0.2 seconds to transition back to idle while tweening, but instantly sets state to empty if that was the last card.

Notes: The tween from click happens as soon as fetching begins. I wasn't sure how to show that, but you can hopefully see that for .2 seconds the tween will animate from the fetching state to the idle state. The tween animates when going from fetching to empty too, but the state transition is instant.

the card states, I'm not entirely sure on. but i think it's sort of clear? if its idle, it responds to mousepressed. if its selected, it repsonds to moving and released. if its moving, it responds only to released, by going to the played card function (that used the ellipse for state for some reason, but split lines would have been more better. There are some points where it can go back to idle, or to a you win screen

I know I'm missing something, and I don't know how to code this exactly anyway

https://love2d.org/imgmirrur/rSWR2Df.html

some pics of what i was thinking of

Re: How to draw and code a state machine? (pictures!)

Posted: Fri Sep 07, 2018 5:43 pm
by pgimeno
A state machine isn't really anything complicated, and your approach seems good. Just have a variable for the state, which can be in the form of a string per state for maximum clarity, and implement the transitions and checks in the code.

The state machine for the deck that you mention in your message seems OK to me, assuming you don't want the user to click while the card is being dealt. A schematic implementation could go like this:

Code: Select all

local deckState

function love.load()
  deckState = "idle" -- do this also on game start
end

function love.mousepressed(x, y, b)
  if deckState == "idle" then
    if b == 1 and x, y within the deck's coords then
        deckState = "fetching"
        create a new card to draw
        initialize tween values
    end
  end
end

function love.update(dt)
  if state == "fetching" then
    update tween values
    if tween has ended then
      if deck is empty then
        deckState = "empty"
      else
        deckState = "idle"
      end
    end
  end
end
The card movement state machine is not so clear, as you seem to be mixing program flow with states. I think that from moving it should go to idle, you don't need a "played card" state. Actions, when needed, typically happen in state transitions, e.g. the tweening above is triggered by the state transition from idle to fetching.

It's also unclear to me why you need the 'holding' state. I don't think it's necessary. Just idle ----(mousepressed)---> moving and moving ---(mousereleased)---> idle should suffice. In mousemoved you would only move the card if the state is 'moving'. In the state transition from idle to moving you would capture which card is being moved, and in the state transition from moving to idle you would check if that move is legal, and possibly return the card to its original position if not (which may require another tweening, with another associated state to prevent the card from being played while tweening).