Toggle between states

Discussion in 'Learning Javascript' started by Padramyr, Apr 13, 2019.

  1. Padramyr

    Padramyr Veteran Veteran

    Messages:
    91
    Likes Received:
    75
    Location:
    Germany
    First Language:
    German
    Primarily Uses:
    RMMV
    Hey there! :)

    I'm working on my own custom menu at the moment and it's going fine so far. But I would like to implement that the states are not shown beside each other. Instead they should be displayed on a single square and toggle at a set frame speed. The problem is that I can't figure out how to do that.

    I know how I can draw the icons I just need to know how to toggle between them. The construct looks like this at the moment:
    Window_MenuStatus.prototype.drawStates = function(actor, x, y, width) {
    if (actor.allIcons().length > 1) {
    var icons = actor.allIcons();
    for (var i = 0; i < icons.length; i++) {
    this.drawIcon(icons, x, y + 2);
    //this.refreshStates();
    }
    }
    else {
    var icons = actor.allIcons();
    for (var i = 0; i < icons.length; i++) {
    this.drawIcon(icons, x, y + 2);
    }
    }
    };


    The "refreshStates" part is just there because I wasn't sure if it must be refreshed in the same function or in a different one. And it's possible that this code is just plain BS, I'm still learning and looking the things up as I need them xD

    So, if someone could tell me how I can toggle between the states or give me at least a hint which commands I would need that would be great :)
     
    #1
  2. gstv87

    gstv87 Veteran Veteran

    Messages:
    1,674
    Likes Received:
    693
    First Language:
    Spanish
    Primarily Uses:
    RMVXA
    object.visible = !object.visible
    that would toggle visibility in one instruction.
    BUT, the icons themselves are not toggle-able objects, they're just images, so you'll need to either encapsulate them into a small window and toggle that, or change the images' opacity, for which you'd probably need an additional check.
    and, when handling flashing images, checks are refreshes take processor time and may cause lag.

    hook up a counter into the window's refresh function ("refresh" or "update"), and count update frames up.
    on a maximum, reset the counter, and on the reset, toggle visibility.
    that will space the updates to that section apart X frames (depending on the check to the counter), but you'll have to start always from visible, so make sure you call the draw routine once when you open the window, and then toggle on and off with the refresh routine.

    "toggling" icons is nothing more than either drawing them, or not drawing them at all (because, they're not objects that can be hidden).
    so, that's what you have to manage: calling the drawing function or not.... and when "not", deleting what was drawn.
    and for that, you need to space out the calls, and for that the only constant clock you have is the update routine.
     
    #2
  3. Trace

    Trace A Rieri Fan :3 Member

    Messages:
    7
    Likes Received:
    6
    First Language:
    Indonesia
    Primarily Uses:
    RMMV
    Warning: this is example for 1 actor party

    You need update method, and an object variable to do that

    First you set up the object variable in the initialize function
    let's say I made
    this._indexIcon = 0 --> for icon use
    this._wait = 0 --> for waiting use
    in the initialize function of your Window_MenuStatus

    then, use that object variable as index to point out the iconId in the actor.allIcons() array
    Code:
    Window_MenuStatus.prototype.drawStates = function(actor, x, y, width) {
      if (actor.allIcons().length < 1) return //prevent error of empty array
      var iconId = actor.allIcons()[this._indexIcon];
      this.drawIcon(iconId, x, y + 2);
    };

    After that move on to Update function

    use this._wait to wait for several frame

    Code:
    var anotherAlias = Window_MenuStatus.prototype.update;
    Window_MenuStatus.prototype.update = function() {
      anotherAlias.call(this);
      this._wait += 1;
      if (this._wait === 30) { //wait 30 frame before it's refresh
        this._indexIcon += 1; //add the index to move into the next icon
        if (this._indexIcon > $gameParty.members()[0].allIcons().length) { //checks if it's not bigger than the array length
          this._indexIcon = 0; //bring it back to 0
        }
        this.refresh();
        this._wait = 0; //reset the wait timer
      }
    }
    voila, your menustatus will refresh after 30 frames and changes the icon from one to another

    If you have more party members, you have to change how this._indexIcon works, maybe put that index in each of the actor
    :>

    like this
    Code:
    var someAlias = Game_Actor.prototype.initMembers;
    Game_Actor.prototype.initMembers = function() {
      someAlias.call(this);
      this._indexIcon = 0;
    };
    

    so the update method will evolve to this
    Code:
    Window_MenuStatus.prototype.drawStates = function(actor, x, y, width) {
      if (actor.allIcons().length < 1) return //prevent error of empty array
      var iconId = actor.allIcons()[actor._indexIcon];
      this.drawIcon(iconId, x, y + 2);
    };
    
    var anotherAlias = Window_MenuStatus.prototype.update;
    Window_MenuStatus.prototype.update = function() {
      anotherAlias.call(this);
      this._wait += 1;
      if (this._wait === 30) { //wait 30 frame before it's refresh
        var members = $gameParty.members();
        for (var i = 0;i < members.length;i++) {
          var actor = members;
          actor._indexIcon += 1;
          if (this._indexIcon > $gameParty.members()[0].allIcons().length) { //checks if it's not bigger than the array length
            this._indexIcon = 0; //bring it back to 0
          }
        }
        this.refresh();
        this._wait = 0; //reset the wait timer
      }
    }
    

    Long run explanation :kaoblush:
    hope it runs well since I run all of that only in my mind :kaojoy:
     
    Last edited: Jun 18, 2019
    #3
  4. Trihan

    Trihan Speedy Scripter Veteran

    Messages:
    1,483
    Likes Received:
    974
    Location:
    Buckie, Scotland
    First Language:
    English
    Let's say you want to display the next icon every 2 seconds, or 120 frames. What you want to do is set a temp variable to 120 at the beginning of drawStates, and an index set to 0, then have an if statement check that the variable is > 0. If it is, subtract 1 from it. If not, increment index by 1. If the index is now greater than the length of icons, set it back to 0. Then just draw the element in icons corresponding to index. That'll cycle through them all.
     
    #4
  5. Nilom

    Nilom Veteran Veteran

    Messages:
    178
    Likes Received:
    38
    First Language:
    German
    Primarily Uses:
    RMMV
    On a Game Design basis I would suggest against this idea. It will be annoying to have to wait all the time to see all the states of all the characters. It would hide information that was well shown before.
    About how many states can a character maximally have in your game?
    Perhaps there is another way how you could implement this?
     
    #5

Share This Page