Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 23 of 23

Thread: switching button controls from one function to another

  1. #1
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431

    switching button controls from one function to another

    ok guys I'm having a problem that ive been trying to fix for days. I wrote a menu function for a game I'm working on, that when called brings up a short menu graphic with button controls to move a cursor up and down the menu. But when I open up the menu the new controls don't move the cursor but moves the player instead. Because both menu and player functions use the same up and down buttins. Ive tried else if statements, ive tried moving the set of controls in the function, ive looked up a lot keywords like break and switch but cannot find the answer I need.

    Can someone please help me solve this. I'm learning but I have no idea how to fix it.

    here is the menu function. I need help with calling the menu as well. it works by giving menu the define of "int menu_1 = 1, then pressing the A button changes the integer by adding up. But this makes the menu calling erratic making me have to push the button several times to get the menu to come back up after the first time. I could remove the addition parts so it comes open just by pressing A but then it kills it when a is released and I cant figure that out either.

    Code:
    void Menu(){
    if (ButtonA.fallingEdge()){
                menu_1 = menu_1 + 1;}
    
    
    else if(menu_1 == 3){
     tft.writeRectNBPP(16,0,114,32,4,itemmenutop,palette);
      tft.writeRectNBPP(16,32,114,16,4,itemmenu2,palette);
       tft.writeRectNBPP(16,48,114,160,4,itemmenu3,palette);
       tft.writeRectNBPP(16,208,114,16,4,itemmenu4,palette);
    }
    
    else if(menu_1 >= 5){
              menu_1 = 1;}
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (ButtonUp.fallingEdge()){
         tft.writeRectNBPP(cursor_x,cursor_y,16,16,4,cursordot2,palette);
         cursor_y -= 16;
    //     if(checkcolision())
         {
          cursor_y += 16;} 
         }
         if(cursor_y <= 32){
            cursor_y = 32;}
              
    //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Down///////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
     if (ButtonDown.fallingEdge()){
       tft.writeRectNBPP(cursor_x, cursor_y,16,16,4,cursordot2,palette);
       cursor_y += 16;
    //    if(checkcolision())
        {
        cursor_y -= 16;}
        }
        if(cursor_y >= 224){
           cursor_y = 224;}
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }
    now here is the function that controls the player movement...
    Code:
    void drawplayer() {
    ///////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////camera controls////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    // Clamp cameraX
    if(cameraX < cameraXMin)
    {
      cameraX = cameraXMin;
    }
    else if(cameraX > cameraXMax)
    {
       cameraX = cameraXMax;
    }
    
    // Clamp cameraY
    if(cameraY < cameraYMin)
    {
      cameraY = cameraYMin;
    }
    else if(cameraY > cameraYMax)
    {
       cameraY = cameraYMax;  
    }
    
    // Check if player is beyond X boundary
    if(player_x < playerXMin)
    {
      cameraX += cameraXSpeed;
      if(cameraX > cameraXMin && cameraX < cameraXMax)
      {
        player_x = playerXMin;
      }
    }
    else if(player_x > playerXMax)
    {
      cameraX -= cameraXSpeed;
      if(cameraX > cameraXMin && cameraX < cameraXMax)
      {
        player_x = playerXMax;
      }
    }
    
    // Check if player is beyond Y boundary
    if(player_y < playerYMin)
    {
      cameraY += cameraYSpeed;
      if(cameraY > cameraYMin && cameraY < cameraYMax)
      {
        player_y = playerYMin;
      }
    }
    else if(player_y > playerYMax)
    {
      cameraY -= cameraYSpeed;
      if(cameraY > cameraYMin && cameraY < cameraYMax)
      {
        player_y = playerYMax;
      }
    }
    //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Palette////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
     palette[0] = 0;
           palette[1] = BLACK;
                 palette[2] = BLUE;
                       palette[3] = BROWN;
                             palette[4] = DARKGREEN;
                                  palette[5] = GREY;
                                        palette[6] = PINK;
                                              palette[7] = RED;
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////                                                
                                               palette[8] = BEIGE;
                                         palette[9] = GREEN;
                                   palette[a]= DARKGREY;
                             palette[b] = LIGHTGREY;
                       palette[c] = YELLOW; 
                 palette[d] = PURPLE; 
           palette[e] = WHITE;
     palette[f] = ORANGE;
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Tilemap/////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    /////// top center rock formation
            
            if(room == 1){
      tft.drawTilemap(cameraX, cameraY, imperialbasin, spritesheet, palette);}
       else if(room == 2){
      tft.drawTilemap(cameraX, cameraY, dungeon1, spritesheet, palette);}
       else if(room == 3){
      tft.drawTilemap(cameraX, cameraY, arakeen, spritesheet, palette);}
       else if(room == 4){
      tft.drawTilemap(cameraX, cameraY, arakeen1l1, spritesheet, palette);}
       else if(room == 5){
      tft.drawTilemap(cameraX, cameraY, arakeen1l2, spritesheet, palette);}
       else if(room == 6){
      tft.drawTilemap(cameraX, cameraY, arakeen2l1, spritesheet, palette);}
       else if(room == 7){
      tft.drawTilemap(cameraX, cameraY, arakeen2l2, spritesheet, palette);}
       else if(room == 8){
      tft.drawTilemap(cameraX, cameraY, arakeen2l3, spritesheet, palette);}
       else if(room == 9){
      tft.drawTilemap(cameraX, cameraY, arakeen3, spritesheet, palette);}
       else if(room == 10){
      tft.drawTilemap(cameraX, cameraY, arakeen4l1, spritesheet, palette);}
       else if(room == 11){
      tft.drawTilemap(cameraX, cameraY, arakeen4l2, spritesheet, palette);}
       else if(room == 12){
      tft.drawTilemap(cameraX, cameraY, arakeen4l3, spritesheet, palette);}
       else if(room == 13){
      tft.drawTilemap(cameraX, cameraY, arakeen5l1, spritesheet, palette);}
       else if(room == 14){
      tft.drawTilemap(cameraX, cameraY, arakeen5b1, spritesheet, palette);}
       else if(room == 15){
      tft.drawTilemap(cameraX, cameraY, arakeen5b2, spritesheet, palette);}
       else if(room == 16){
      tft.drawTilemap(cameraX, cameraY, arakeen5l2, spritesheet, palette);}
       else if(room == 17){
      tft.drawTilemap(cameraX, cameraY, arakeen5l3, spritesheet, palette);}
       else if(room == 18){
      tft.drawTilemap(cameraX, cameraY, arakeen6l1, spritesheet, palette);}
       else if(room == 19){
      tft.drawTilemap(cameraX, cameraY, arakeen6l2, spritesheet, palette);}
       else if(room == 20){
      tft.drawTilemap(cameraX, cameraY, arakeen7, spritesheet, palette);}
       else if(room == 21){
      tft.drawTilemap(cameraX, cameraY, arakeen8, spritesheet, palette);}
       else if(room == 22){
      tft.drawTilemap(cameraX, cameraY, arakeen9, spritesheet, palette);}
       else if(room == 23){
      tft.drawTilemap(cameraX, cameraY, arakeen10, spritesheet, palette);}
       else if(room == 24){
      tft.drawTilemap(cameraX, cameraY, dungeon2, spritesheet, palette);}
       else if(room == 25){
      tft.drawTilemap(cameraX, cameraY, village2, spritesheet, palette);}
       else if(room == 26){
      tft.drawTilemap(cameraX, cameraY, village2r1, spritesheet, palette);}
       else if(room == 27){
      tft.drawTilemap(cameraX, cameraY, village2r2, spritesheet, palette);}
       else if(room == 28){
      tft.drawTilemap(cameraX, cameraY, village2r3, spritesheet, palette);}
       else if(room == 29){
      tft.drawTilemap(cameraX, cameraY, village2r4, spritesheet, palette);}
       else if(room == 30){
      tft.drawTilemap(cameraX, cameraY, village2r5, spritesheet, palette);}
       else if(room == 31){
      tft.drawTilemap(cameraX, cameraY, village2r6, spritesheet, palette);}
       else if(room == 32){
      tft.drawTilemap(cameraX, cameraY, village2r7, spritesheet, palette);}
       else if(room == 33){
      tft.drawTilemap(cameraX, cameraY, village2r8l1, spritesheet, palette);}
       else if(room == 34){
      tft.drawTilemap(cameraX, cameraY, village2r8l2, spritesheet, palette);}
       else if(room == 35){
      tft.drawTilemap(cameraX, cameraY, dungeon3, spritesheet, palette);}
       else if(room == 36){
      tft.drawTilemap(cameraX, cameraY, village3, spritesheet, palette);}
       else if(room == 37){
      tft.drawTilemap(cameraX, cameraY, village3r1, spritesheet, palette);}
       else if(room == 38){
      tft.drawTilemap(cameraX, cameraY, village3r2, spritesheet, palette);}
       else if(room == 39){
      tft.drawTilemap(cameraX, cameraY, village3r3, spritesheet, palette);}
       else if(room == 40){
      tft.drawTilemap(cameraX, cameraY, village3r4, spritesheet, palette);}
       else if(room == 41){
      tft.drawTilemap(cameraX, cameraY, village3r5, spritesheet, palette);}
       else if(room == 42){
      tft.drawTilemap(cameraX, cameraY, village3r6l1, spritesheet, palette);}
       else if(room == 43){
      tft.drawTilemap(cameraX, cameraY, village3r6l2, spritesheet, palette);}
       else if(room == 44){
      tft.drawTilemap(cameraX, cameraY, dungeon4, spritesheet, palette);}
       else if(room == 45){
      tft.drawTilemap(cameraX, cameraY, desertp1, spritesheet, palette);}
    
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////Buttons Repeat//////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////  
           if (ButtonUp.update());
                   if (ButtonDown.update());
                           if (ButtonLeft.update());
                                 if (ButtonRight.update());
                                           if (ButtonA.update());
                                                  if (ButtonB.update());
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
                                                  ButtonUp.rebounce(10);
                                         ButtonDown.rebounce(10);
                                  ButtonLeft.rebounce(10);
                          ButtonRight.rebounce(10);
     //              ButtonA.rebounce(10);
              ButtonA.rebounce(10);
    ///////////////////////////////////////////////////////////////////////////////
    ////////////////////////////Up/////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    if (ButtonUp.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulrearwa,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulrearwb,palette);
        player_direction = 1;
        player_y -= 4;
        if(checkcolision())
        {
            player_y += 4;} 
        }
         if(player_y <= 16){
            player_y = 16;}  
    
    //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Down///////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    if (ButtonDown.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulfrontwa,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulfrontwb,palette);
        player_direction = 2;
        player_y += 4;
        if(checkcolision())
        {
           player_y -=4;}
        }
        if(player_y >= 224){
           player_y = 224;}
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////Left////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    if (ButtonLeft.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulleftw,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulleft,palette);
        player_direction = 3;
        player_x -= 4;
        if(checkcolision())
       {
          player_x += 4;}  
       }
       if(player_x >= 304){
          player_x = 304;}    
    /////////////////////////////////////////////////////////////////////////////
    ////////////////////////////Right////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    if (ButtonRight.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulrightw,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulright,palette);
        player_direction = 4;
        player_x += 4;
      if(checkcolision())
      {
        player_x -= 4;}
      }
                if(player_x <= 16){
                  player_x = 16;}
    ///////////////////////////////////////////////////////////////////////////////     
    //////////////////////////////PLAYER DIRECTION/////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    if (player_direction == 1){
      tft.writeRectNBPP(player_x, player_y,16,16,4,paulrear,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 2){
       tft.writeRectNBPP(player_x, player_y,16,16,4,paulfront,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 3){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulleft,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 4){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulright,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////        
    /////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////for use with movey blocks////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 5){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulrearwa,palette);
    }     
    else if (player_direction == 6){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulfrontwa,palette);
    }     
    else if (player_direction == 7){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulleftw,palette);
    }          
    else if (player_direction == 8){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulrightw,palette); 
    }          
    };
    so as you can see I need to make up several button control systems that I can separate so only the called function uses a certain set of buttons

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,441
    Saw this posted on your other thread - and snippets here don't let me show for sure.

    But: Where "ButtonA.fallingEdge()" is done for Player Control - that needs to be disabled or redirected when the MENU is to be displayed.

    I don't know where that code resides - somehow that needs to be taken care of:
    > If menu active all xxx.fallingEdge() test and response comes from MENU code { This code must terminate MENU mode when done. }
    > else MENU not active then button input moves the player as it is. { this code activates MENU mode }

  3. #3
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    ok here is the repository for the game as it is now...

    https://github.com/Duhjoker/Pokedune

    I actually posted both functions that deal with the button controls. ButtonA.fallingEdge() opens the menu and has nothing to do with any player stuff. Its the up and down and left and right buttons I'm worried about. I understand the problem as you described but don't know how to do so. like i said ive looked up and tried a lot of stuff but I cant seem to shut the first set off for the second set of controls.

    both functions get called from the void loop. I tried adding if else statements for the function drawplayer() and menu()
    Last edited by Duhjoker; 12-09-2017 at 02:00 AM.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,441
    Quick search on github shows these places taking buttons - the places taking the button input - assuming they all read using the same fallingEdge() detection will point to the area to be changed.

    It other player move buttons are not fallingEdge() detected - those are the things to isolate and 'ignore' when in menu mode.

    Click image for larger version. 

Name:	GameMenu.PNG 
Views:	30 
Size:	40.6 KB 
ID:	12197

  5. #5
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    ok what about using a state else if?


    Code:
    if(state == drawplayer){
    drawplayer();
    }
    
    else if(state == menu){
    Menu();
    Maybe instead of using drawplayer() and menu() straight up like listed but move the whole function over to the ino file
    Last edited by Duhjoker; 12-09-2017 at 06:33 AM.

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,441
    Quote Originally Posted by Duhjoker View Post
    ok what about using a state else if?
    ...
    Yes, something like that if drawplayer is where player input and updates are done. As noted assuming drawplayer() sets state = menu, then in Menu() when done it sets state=drawplayer.

  7. #7
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    I found an arduboy game demo for an rpg that I'm looking and from which the state stuff comes from. Heres the void loop...
    Code:
    #define STATE_TITLE 0
    #define STATE_ENTERNAME 1
    #define STATE_GAMEPLAY 2
    #define STATE_SHOP 3
    #define STATE_BATTLE 4
    #define STATE_TRANSITION 5
    #define STATE_GAMEOVER 6
    #define NONE 255
    
    bool menuIsVisible = false;
    bool menuIsSpecific = false;
    
    #include "Arglib.h"
    #include "Title.h"
    #include "Item.h"
    #include "Player.h"
    #include "Map.h"
    #include "Trigger.h"
    #include "Text.h"
    #include "Menu.h"
    #include "Shop.h"
    #include "Battle.h"
    
    Arduboy arduboy;
    
    byte state = STATE_TITLE;
    byte nextState = STATE_ENTERNAME;
    
    byte randomCounter = 0;
    
    byte buttons = 0;
    
    void setup()
    {
      arduboy.start();
      arduboy.setFrameRate(60);
      
      resetPlayer();
    }
    
    void loop() 
    {
      if(!arduboy.nextFrame()) return;
       arduboy.clearDisplay();
    
      if(state == STATE_TITLE)
      {
        arduboy.drawBitmap(10, 8, title, 109, 16, WHITE);
    
        if(checkLoad())
        {
          drawText(labelContinue, 40, 32, WHITE, ALIGN_LEFT);
    
          if(getButtonDown(UP_BUTTON) || getButtonDown(DOWN_BUTTON))
          {
            titleChoice = (titleChoice)?0:1;
          }
        }
        
        drawText(labelNewGame, 40, (checkLoad())?44:32, WHITE, ALIGN_LEFT);
        arduboy.drawBitmap(34, 32 + (titleChoice * 12), font[43], 5, 5, WHITE);
    
        if(arduboy.pressed(B_BUTTON))
        {
          if(checkLoad() && titleChoice == 0)
          {
            load();
            nextState = STATE_GAMEPLAY;
          }
          else nextState = STATE_ENTERNAME;
          
          state = STATE_TRANSITION;
          titleChoice = 0;
        }
      }
      else if(state == STATE_ENTERNAME) doEnterName();
      else if(state == STATE_GAMEPLAY)
      {    
        if(battleStartEffectCounter > 0)
        {
          if(--battleStartEffectCounter % 4 == 0) battleStartEffectToggle = !battleStartEffectToggle;   
          if(battleStartEffectToggle) arduboy.fillRect(0, 0, 128, 64, WHITE);
    
          if(battleStartEffectCounter == 0)
          {
            state = STATE_TRANSITION;
            nextState = STATE_BATTLE;
          }
        }
        else
        {
          if(!textboxIsVisible && !menuIsVisible)
          {
            updatePlayer();
            updateScene();
          }
        }
    
        if(!menuIsSpecific)
        {
          drawScene();
          drawPlayer();
        }
      }
      else if(state == STATE_SHOP)
      {
        drawText((shopState == SHOPSTATE_BUY)?labelShopBuy:labelShopSell, 4, 2, WHITE, ALIGN_LEFT);
    
        generateGoldText();
        drawText(dynamicText, 120, 2, WHITE, ALIGN_RIGHT);
        
        arduboy.fillRect(0, 10, 128, 36, WHITE);
        doItemList();
    
        if(!textboxIsVisible && getButtonDown(A_BUTTON)) state = STATE_GAMEPLAY;
      }
      else if(state == STATE_BATTLE)
      {
        drawBattle();
        updateBattle();
      }
      else if(state == STATE_GAMEOVER)
      {
        drawText(labelGameOver, 37, 26, WHITE, ALIGN_LEFT);
    
        if(arduboy.pressed(B_BUTTON))
        {
          nextState = STATE_TITLE;
          state = STATE_TRANSITION;
        }
      }
      else if(state == STATE_TRANSITION)
      {
        arduboy.display();
        delay(800);
        state = nextState;
      }
      
      if(menuIsVisible) doMenu();
      if(textboxIsVisible) doTextbox();
    
      if(state != STATE_TRANSITION) arduboy.display();
    }
    what I don't understand is how to transistion between states. And I don't understand how this works with the menu is specific and menu is visible

    https://github.com/TEAMarg/ID-46-Arduventure

  8. #8
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    ok I tried some thing simple and it compiles and runs. Plus it kills the cursor everytime the up and down buttons are pressed outside the menu call which was one of the problems I was having. So it seems as if it has separated the functions but Hitting the A button refuses to bring up the menu. I think this has something to do with state transitions. Maybe Menu should be first so it stays visible then overlay the rest of the game over the menu?
    Code:
    #include <GrafxT3.h>
    #include <SPIN.h>
    #include <SPI.h>
    #include <Bounce.h>
    //#include "Battle.h"
    #include "Player.h"
    #include "World.h"
    #include "Monsters.h"
    
    #define STATE_Player 0
    #define STATE_Menu 1
    #define STATE_Transition 3
    
    byte state = STATE_Player;
    byte nextState = STATE_Menu;
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    #define TFT_DC  9
    #define TFT_CS 10
    #define TFT_RST 7
    #define TFT_SCK 13
    #define TFT_MISO 39
    #define TFT_MOSI 11
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    uint8_t use_fb = 1;
    uint8_t use_clip_rect = 0;
    uint8_t use_set_origin = 0;
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    GrafxT3 tft = GrafxT3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO, &SPIN);
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Set-up//////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    
    void setup() {
      while (!Serial && (millis() < 4000)) ;
      Serial.begin(115200);
      tft.begin();
      tft.setRotation(1);
      tft.fillScreen(BLACK);
      //tft.setFrameRate(60);
      tft.persistence = false;
       pinMode(buttonUp, INPUT_PULLUP);
       pinMode(buttonDown, INPUT_PULLUP);
       pinMode(buttonLeft, INPUT_PULLUP);
       pinMode(buttonRight, INPUT_PULLUP);
       pinMode(buttonS, INPUT_PULLUP);
       pinMode(buttonX, INPUT_PULLUP);
       pinMode(buttonY, INPUT_PULLUP);
       pinMode(buttonA, INPUT_PULLUP);
       pinMode(buttonB, INPUT_PULLUP);
       pinMode(buttonT, INPUT_PULLUP); 
       SPI.setMISO(39);
         tft.useFrameBuffer(use_fb);
     
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////Loop////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    void loop(void) {
    
    if(state == STATE_Player){
    drawplayer();}
    if(state == STATE_Menu){
    Menu();}
    
    ///drawbattle(player_x, player_y);
      tft.updateScreen();
     
    }

  9. #9
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    Ok I think I Know how to change states Kind of. But I still cant get the menu to popup.

    Code:
     void loop(void) {
    
    if(state == STATE_Player){
    drawplayer();
       state = STATE_Player;
            nextState = STATE_Transition;
    }
    else if(state == STATE_Menu){
    Menu();
    state = STATE_Menu;
    }
    
    else if(state == STATE_Transition){
        state = nextState;
      }
     
    ///drawbattle(player_x, player_y);
      tft.updateScreen();
     
       }
    can you see what I'm doing wrong?

  10. #10
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    I still cant figure out why I cant activate the menu when using states. I saw that the function page was not included in the ino so I fixed that as well but I still cant get the menu to come up.

    Also is there an example for using one digital button to toggle a function. I saw one that uses three pins (input pin output pin and ground) but I don't know if it would work that way?

    https://github.com/Duhjoker/Pokedune

  11. #11
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,599
    usually if i use something for multifunction i set up all the different controls in the same function separated by a uint_8 switch statement, where when you write the uint8_t value, the button uses the actions in the proper switch statement.
    for readability purposes you could add enums, or even instead of switch statements you can use else if conditions on the uint8_t

    ex, 1 == control menu, 2 == control game, if your in the menu of the game you set the var to 1, and everything under that function will be controlled accordingly, when you exit the menu to the game, have your code set the variable to 2, this restores player controls function(obviously if you know when your menu is open or not (known state) itll be easy to set the control variable...)

  12. #12
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    ok let me ask for a clarification......

    Create a function, we will call it controls so void controls(). And in this function I add an else if loop. So I can give it if variable A = player use this set of controls and list the controls then do an else if variable B = menu use this set of controls? Or since I have state set up already I can name the if statements if state = State_player else if state = state_menu

  13. #13
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,599
    yes and yes so state would be the variable you use that the control loop operated its subfunctions with

  14. #14
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    Ok I have restructured the program a lil to add the else if thing to the controls. Then I ended up having to put the function in my ino file instead of its own header.
    Code:
    #include <GrafxT3.h>
    #include <SPIN.h>
    #include <SPI.h>
    #include <Bounce.h>
    #include "Variables.h"
    #include "Player.h"
    #include "World.h"
    #include "Monsters.h"
    #include "Menu.h"
    
    
    #define STATE_Player 1
    #define STATE_Menu 0
    ////#define STATE_Transition 3
    
    byte state = STATE_Menu;
    byte nextState = STATE_Player;
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    #define TFT_DC  9
    #define TFT_CS 10
    #define TFT_RST 7
    #define TFT_SCK 13
    #define TFT_MISO 39
    #define TFT_MOSI 11
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    uint8_t use_fb = 1;
    uint8_t use_clip_rect = 0;
    uint8_t use_set_origin = 0;
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    GrafxT3 tft = GrafxT3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO, &SPIN);
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Set-up//////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    
    void setup() {
      while (!Serial && (millis() < 4000)) ;
      Serial.begin(115200);
      tft.begin();
      tft.setRotation(1);
      tft.fillScreen(BLACK);
      //tft.setFrameRate(60);
      tft.persistence = false;
       pinMode(buttonUp, INPUT_PULLUP);
       pinMode(buttonDown, INPUT_PULLUP);
       pinMode(buttonLeft, INPUT_PULLUP);
       pinMode(buttonRight, INPUT_PULLUP);
       pinMode(buttonS, INPUT_PULLUP);
       pinMode(buttonX, INPUT_PULLUP);
       pinMode(buttonY, INPUT_PULLUP);
       pinMode(buttonA, INPUT_PULLUP);
       pinMode(buttonB, INPUT_PULLUP);
       pinMode(buttonT, INPUT_PULLUP); 
       SPI.setMISO(39);
         tft.useFrameBuffer(use_fb);
     
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////Loop////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    void loop(void) {
    
    if(state == STATE_Menu){
    Menu();
       state = STATE_Menu;
            nextState = STATE_Player;
    }
    else if(state == STATE_Player){
     drawplayer();
         state = STATE_Player;
    //      nextState = STATE_Menu;   
     }
    
    if(nextState != state) state = nextState;
      
    
      tft.updateScreen();
     
     }
    
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////controls//////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void controls(){
      //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Palette////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
     palette[0] = 0;
           palette[1] = BLACK;
                 palette[2] = BLUE;
                       palette[3] = BROWN;
                             palette[4] = DARKGREEN;
                                  palette[5] = GREY;
                                        palette[6] = PINK;
                                              palette[7] = RED;
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////                                                
                                               palette[8] = BEIGE;
                                         palette[9] = GREEN;
                                   palette[a]= DARKGREY;
                             palette[b] = LIGHTGREY;
                       palette[c] = YELLOW; 
                 palette[d] = PURPLE; 
           palette[e] = WHITE;
     palette[f] = ORANGE;
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////Buttons Repeat//////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////  
           if (ButtonUp.update());
                   if (ButtonDown.update());
                           if (ButtonLeft.update());
                                 if (ButtonRight.update());
                                           if (ButtonA.update());
                                                  if (ButtonB.update());
    ///////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
                                                  ButtonUp.rebounce(10);
                                         ButtonDown.rebounce(10);
                                  ButtonLeft.rebounce(10);
                          ButtonRight.rebounce(10);
                   ButtonA.rebounce(10);
              ButtonB.rebounce(10);
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    if(state == STATE_Player){
    
    ///////////////////////////////////////////////////////////////////////////////
    ////////////////////////////Up/////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    if (ButtonUp.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulrearwa,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulrearwb,palette);
        player_direction = 1;
        player_y -= 4;
        if(checkcolision())
        {
            player_y += 4;} 
        }
         if(player_y <= 16){
            player_y = 16;}  
    
    //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Down///////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    if (ButtonDown.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulfrontwa,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulfrontwb,palette);
        player_direction = 2;
        player_y += 4;
        if(checkcolision())
        {
           player_y -=4;}
        }
        if(player_y >= 224){
           player_y = 224;}
    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////Left////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    if (ButtonLeft.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulleftw,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulleft,palette);
        player_direction = 3;
        player_x -= 4;
        if(checkcolision())
       {
          player_x += 4;}  
       }
       if(player_x >= 304){
          player_x = 304;}    
    /////////////////////////////////////////////////////////////////////////////
    ////////////////////////////Right////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    if (ButtonRight.fallingEdge()){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulrightw,palette);
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulright,palette);
        player_direction = 4;
        player_x += 4;
      if(checkcolision())
      {
        player_x -= 4;}
      }
                if(player_x <= 16){
                  player_x = 16;}
    ///////////////////////////////////////////////////////////////////////////////     
    //////////////////////////////PLAYER DIRECTION/////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////
    if (player_direction == 1){
      tft.writeRectNBPP(player_x, player_y,16,16,4,paulrear,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 2){
       tft.writeRectNBPP(player_x, player_y,16,16,4,paulfront,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 3){
        tft.writeRectNBPP(player_x, player_y,16,16,4,paulleft,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 4){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulright,palette);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////        
    /////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////for use with movey blocks////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////
    else if (player_direction == 5){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulrearwa,palette);
    }     
    else if (player_direction == 6){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulfrontwa,palette);
    }     
    else if (player_direction == 7){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulleftw,palette);
    }          
    else if (player_direction == 8){
         tft.writeRectNBPP(player_x, player_y,16,16,4,paulrightw,palette); 
         }          
     }
    ///////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////// 
    else if(state == STATE_Menu){
    
    if (ButtonUp.fallingEdge()){
         tft.writeRectNBPP(cursor_x,cursor_y,16,16,4,cursordot2,palette);
         cursor_y -= 16;
    //     if(checkcolision())
         {
          cursor_y += 16;} 
         }
         if(cursor_y <= 32){
            cursor_y = 32;}
              
    //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////Down///////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
     if (ButtonDown.fallingEdge()){
       tft.writeRectNBPP(cursor_x, cursor_y,16,16,4,cursordot2,palette);
       cursor_y += 16;
    //    if(checkcolision())
        {
        cursor_y -= 16;}
        }
        if(cursor_y >= 224){
           cursor_y = 224;}
       }
     }
    now I'm trying to figure out where to add the controls function. do I nest them in the functions that use controls or do I add them to the void loop for each state

    Edit ::: adding the controls function to each state in the loop gives me controls but now I cant seem to get the menu to pop up

    updated::::https://github.com/Duhjoker/Pokedune
    Last edited by Duhjoker; 12-12-2017 at 07:55 AM.

  15. #15
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,441
    Noted before - it is up to the STATE_Player section to set the MENU state, and the MENU state to exit by returning to STATE_Player. Does that get to the answer?

    Those button presses as defined must be recognized and acted on - stop player and draw menu - and exit menu and resume player.

    Very special cases to swap the state and do any screen updates and depending on menu functions offered it will change, resume, exit or restart the game.

  16. #16
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    ok well I had marked out the next state part in the player state so it didn't have a way to change it.
    Code:
    void loop(void) {
    
    if(state == STATE_Menu){
    Menu();
    controls();
       state = STATE_Menu;
            nextState = STATE_Player;
    }
    else if(state == STATE_Player){
     drawplayer();
     controls();
         state = STATE_Player;
          nextState = STATE_Menu;   ////////////// this was commented out
     }
    
    if(nextState != state) state = nextState;
      
    
      tft.updateScreen();
     
     }
    What is happening now is that the menu comes on and flashes between the player screen and the menu when A is pressed and I still haven't found the proper way to toggle it on and off using the A button. But I was having a problem with the menu staying open any way.

    On the controls.... when the console is powered and the program starts the controls slow annoyingly to point that the characters is barely moving. That's at all times. when the menu comes on and starts its flashing the cursor appears but does not move.


    if I add and else to this line in the void loop
    Code:
     if(nextState != state) state = nextState;
    the console goes to black screen and the menu can be called but it wont turn off and no control of the cursor. Lol I don't understand why the controls are still acting screwy. its messing with my logic
    Last edited by Duhjoker; 12-12-2017 at 09:03 PM.

  17. #17
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    2,599
    it flashes because the mcu is so fast when you press the button it can toggle the state thousands of times, you will need to handle that (without delays hopefully) using millis() to ignore for a few seconds after activate and never switch until let go of button.

    as a test, you could put a delay(1000); as a test when changing state to see if it switches properly. note: holding it down after one sec will toggle it again, but this is a test right now to check if it enters menu and player properly

  18. #18
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    I found a toggle example on an Arduino page and I was trying something like this....

    Code:
    void Menu(){
    //if (ButtonA.fallingEdge()){
    
    if(digitalRead(buttonA) ==  HIGH){
      Button = 1 - Button;
    }  
    
    if (Button == 1 && OldButton == 0){
      
     tft.writeRectNBPP(0,0,136,20,4,menul1,palette);
      tft.writeRectNBPP(0,20,136,40,4,menul2,palette);
       tft.writeRectNBPP(0,60,136,40,4,menul3,palette);
        tft.writeRectNBPP(0,100,136,40,4,menul4,palette);
         tft.writeRectNBPP(0,140,136,40,4,menul5,palette);
          tft.writeRectNBPP(0,180,136,40,4,menul6,palette);
           tft.writeRectNBPP(0,220,136,20,4,menul7,palette);
            tft.writeRectNBPP(136,0,184,26,4,menur1,palette);
             tft.writeRectNBPP(136,26,184,16,4,menur2,palette);
              tft.writeRectNBPP(136,42,184,16,4,menur2,palette);
               tft.writeRectNBPP(136,58,184,16,4,menur2,palette);
              tft.writeRectNBPP(136,74,184,16,4,menur2,palette);
             tft.writeRectNBPP(136,90,184,16,4,menur2,palette);
            tft.writeRectNBPP(136,106,184,16,4,menur2,palette);
           tft.writeRectNBPP(136,122,184,16,4,menur2,palette);
          tft.writeRectNBPP(136,138,184,16,4,menur2,palette);
         tft.writeRectNBPP(136,154,184,16,4,menur2,palette);
        tft.writeRectNBPP(136,170,184,16,4,menur2,palette);
       tft.writeRectNBPP(136,186,184,16,4,menur2,palette);
      tft.writeRectNBPP(136,202,184,16,4,menur2,palette);
     tft.writeRectNBPP(136,218,184,22,4,menur3,palette);
     delay(500);
      }
     if (Button == 0 && OldButton == 1){
      drawplayer();
     delay(500);
     }
    
     OldButton = Button;
    }
    But its giving me an error about drawplayer saying it hasn't been declared. I have Player.h included in my menu header. I tried to fix it by changing void drawplayer to a bool drawplayer(void) but it wont include draw player

    post 5
    https://forum.arduino.cc/index.php?topic=58284.0

  19. #19
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    ugghh. I haven't made any progress but ive been busy making some much needed changes. The main thing was changing my player stuff to a structure. For some reason I though that might help with the controls switch. I also added a collision system to the menu function for when I get the controls to work. I left the do it parts empty but I should be able to save check and load the player structure(game).

    Ive tried about 5 different things tonight as well to toggle the menu on and off when hitting the A button then hitting the A button again to turn it off.

    https://github.com/Duhjoker/Pokedune

    Edit:::

    Adding a delay as suggested produces an erratic effect with the menu coming on for a flash ramdomly when A button is pressed.

    I also tried giving each set of controls thier own function then adding the appropriate function to the appropriate state after calling the function like its done now.

    On the toggle menu part it seems like i could add drawplayer() after a second button press but that doesnt work either.
    Last edited by Duhjoker; 12-13-2017 at 07:49 AM.

  20. #20
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    Ok I'm out of knowledgeable options I'm still trying to get the cursor to move but it wont. The weird part is that the cursor does show up when in menu mode and down or up are pressed and disappears when in player mode. This tells me the function is partially working but not as it should. So the question is what is letting the player move but not the cursor. I checked my end points up and down so the cursor doesn't go off the screen and corrected those coordinates thinking it might help. Idk this is beyond my understanding of how things work.

    I did add a delay between the menu and player state and while it looked erratic to me because I set it at 2 seconds it performed the delay when hitting the A button. Maybe some one could take a look at the program? maybe I'm missing something or have something I shouldn't. Links hints anything.

    https://github.com/Duhjoker/Pokedune

  21. #21
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    All right guys ive read up on program structure, function structure and variable structures, My latest fail was this lil bit of code. it was supposed to check for the state then use the proper function to either move the cursor or move the player.


    Code:
    void ButtonOutputs() {
      //start with decoding the buttons we just read in the readInputs() function
     if (state == STATE_Menu){
    ButtonUp.update(); ButtonUp.rebounce(10);ButtonDown.update(); ButtonDown.rebounce(10) ;ButtonA.update(); ButtonA.rebounce(10);
        if(ButtonUp.fallingEdge()){cursorUp();}
        if(ButtonDown.fallingEdge()){ cursorDown();}
    //    if(ButtonA.fallingEdge()) {state = STATE_Player;}
      }
    else if (state == STATE_Player){
    ButtonUp.update(); ButtonUp.rebounce(10); ButtonDown.update(); ButtonDown.rebounce(10);ButtonLeft.update(); ButtonLeft.rebounce(10);
    ButtonRight.update(); ButtonRight.rebounce(10);ButtonA.update(); ButtonA.rebounce(10);
        //we're in the normal player-movement mode...
        if(ButtonUp.fallingEdge()) {playerUp();}
        if(ButtonDown.fallingEdge()) {playerDown();}
        if(ButtonLeft.fallingEdge()) {playerLeft();}
        if(ButtonRight.fallingEdge()) {playerRight();}
    //    if(ButtonA.fallingEdge()) {state = STATE_Menu;}
         }
    }
    I'm wondering if something like this might work....
    Code:
    else if((state == State_Menu  &&  (ButtonUp.fallingEdge)){ movecursor}
    I'm up for any ideas though

  22. #22
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    ok guys what am I missing? Why cant I get the button functions to pause for others?
    Code:
    void controls(){
    ButtonUp.update(); ButtonUp.rebounce(10); ButtonDown.update(); ButtonDown.rebounce(10);ButtonLeft.update();
    ButtonLeft.rebounce(10);ButtonRight.update(); ButtonRight.rebounce(10); ButtonA.update(); ButtonA.rebounce(10);
      
    if ((ButtonUp.fallingEdge() && state == STATE_Menu)){cursorUp();}
    else if ((ButtonDown.fallingEdge() && state == STATE_Menu)){cursorDown();}
    /////////////////////////////////////////////////////////////////////////
    else if ((ButtonUp.fallingEdge() && state == STATE_Player)){playerUp();}
    else if ((ButtonDown.fallingEdge() && state == STATE_Player)){playerDown();}
    else if ((ButtonLeft.fallingEdge() && state == STATE_Player)){playerLeft();}
    else if ((ButtonRight.fallingEdge() && state == STATE_Player)){playerRight();}
    }

  23. #23
    Senior Member Duhjoker's Avatar
    Join Date
    Aug 2016
    Posts
    431
    Once i removed the timer on one of my functions, it started working right. Are there timers pre-installed or do i need a crystal to use them? My updateAll command uses timers as well in millis but ive never gotten to work when dropping functions in it. Theres a definite reason i ask that pertains to the thread.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •