• All, I am currently in the process of migrating domain registrations. During this time there may be some intermittent outages or slowdowns. Please contact staff if you have any questions.

Solved About character select screen and in-game continue

Question that is answered or resolved.

Mr.Q!

Well-known member
So I am making this FFight game (one more time, yes) and I am using big portraits, like in the original game...I think they are even bigger hah.
Anyways they look great, but the thing is I am willing to add a plethora of characters, and I don't want to shrink the portrait sizes, so I have to either deal with it, and everytime I want to switch characters I will have to scroll 40+ spaces eventually to get an specific dude if I feel like it, or...Is it possible to choose something like a franchise/faction before choosing a playblable character in the Character Select screen?


For example, if I choose the FFight logo in the char select screen, it will allow me to choose between Haggar, Cody and Guy, but If I select this Street Fighter logo, I would be able to choose Ryu, Ken, Guile, Honda, etc.

I am planning to have lots of characters from lots of games, so would it be possible to do this in both the character select screen and during gameplay as well? Plus, think about if I changed my mind after choosing a faction, for example, I chose MK and dang, I think I want to use an SF character, can that also allow me to go back to the faction select so I can rectify my playable character? In both the char select screen AND during gameplay?


ALSO:

I think it's already possible to add a bigger icon while continuing during gameplay that replaces the default icon, so you can have a better look on who you are choosing, right? like in the original FFight where it shows you clearly a better icon just for that specific time? I can't remember right now.


descarga.png
 
So I am making this FFight game (one more time, yes) and I am using big portraits, like in the original game...I think they are even bigger hah.
Anyways they look great, but the thing is I am willing to add a plethora of characters, and I don't want to shrink the portrait sizes, so I have to either deal with it, and everytime I want to switch characters I will have to scroll 40+ spaces eventually to get an specific dude if I feel like it, or...Is it possible to choose something like a franchise/faction before choosing a playblable character in the Character Select screen?


For example, if I choose the FFight logo in the char select screen, it will allow me to choose between Haggar, Cody and Guy, but If I select this Street Fighter logo, I would be able to choose Ryu, Ken, Guile, Honda, etc.

I am planning to have lots of characters from lots of games, so would it be possible to do this in both the character select screen and during gameplay as well? Plus, think about if I changed my mind after choosing a faction, for example, I chose MK and dang, I think I want to use an SF character, can that also allow me to go back to the faction select so I can rectify my playable character? In both the char select screen AND during gameplay?


ALSO:

I think it's already possible to add a bigger icon while continuing during gameplay that replaces the default icon, so you can have a better look on who you are choosing, right? like in the original FFight where it shows you clearly a better icon just for that specific time? I can't remember right now.


View attachment 7518
1710461032240.png

I understand the principle, but I don't know if it can be implemented as a general selection screen.

Similarly, I think it was a select feature that I saw in the arcade game Mega Man.



One method that comes to mind is to create a stage called Select, select specific characters, and move to the first stage through the end level. But somehow I think there is a better way.
I remembered this because I am currently implementing and using the menu.
 
Last edited:
I think this is best done with custom scripted select screen like I've done here:

However, although this system works well for character select, it's not developed yet for in level character select when another player(s) joins in. I also haven't tried using this for multiple stages/levels case. In Megaman Armada, player returns to character select screen after completing a stage therefore it's stable.
 
So I am making this FFight game (one more time, yes) and I am using big portraits, like in the original game...I think they are even bigger hah.
Anyways they look great, but the thing is I am willing to add a plethora of characters, and I don't want to shrink the portrait sizes, so I have to either deal with it, and everytime I want to switch characters I will have to scroll 40+ spaces eventually to get an specific dude if I feel like it, or...Is it possible to choose something like a franchise/faction before choosing a playblable character in the Character Select screen?


For example, if I choose the FFight logo in the char select screen, it will allow me to choose between Haggar, Cody and Guy, but If I select this Street Fighter logo, I would be able to choose Ryu, Ken, Guile, Honda, etc.

I am planning to have lots of characters from lots of games, so would it be possible to do this in both the character select screen and during gameplay as well? Plus, think about if I changed my mind after choosing a faction, for example, I chose MK and dang, I think I want to use an SF character, can that also allow me to go back to the faction select so I can rectify my playable character? In both the char select screen AND during gameplay?


ALSO:

I think it's already possible to add a bigger icon while continuing during gameplay that replaces the default icon, so you can have a better look on who you are choosing, right? like in the original FFight where it shows you clearly a better icon just for that specific time? I can't remember right now.


View attachment 7518
The @Bloodbane solution is perfect for the select screen, but once you have big portraits, as an alternative you could use the turbo key script. I developed it specifically for the Rebellion mode in the SORX due to the large number of characters, works in both select screen and in-game during the "joining" event.

Just hold the directional button and it will automatically be repeated with a previous defined rate. In case you want to go this way, I can post the code.

 
I understand what you're referring to. It's a group select before character select within a selected group. It seems to be almost like NBA Jams on SNES/Arcade where only a team is selected.

I think this is best done with custom scripted select screen like I've done here:

However, although this system works well for character select, it's not developed yet for in level character select when another player(s) joins in. I also haven't tried using this for multiple stages/levels case. In Megaman Armada, player returns to character select screen after completing a stage therefore it's stable.
Indeed. Even though I use Bloodbane's custom scripted select screen as a base, I do have an in-level character select screen when players join to battle.


This gives me to question you how you want your player selection style to be like since you want group select first before character select.

When you start the game with a select screen, you have the picture slots of specific groups, right? Do you want to allow up, down, left, and right to move around, or do you want to only allow left and right, for highlighting a group to select? Do you want the group slots to appear per player side or like the regular selection like Bloodbane, Kratus, and I have? If it's the former (the group slots appearing per player side), do you want it to only allow left/right keys to highlight characters? This selection idea makes me think of Street Fighter Alpha series for Style select, especially 3, as well as Street Fighter 3.
 
The @Bloodbane solution is perfect for the select screen, but once you have big portraits, as an alternative you could use the turbo key script. I developed it specifically for the Rebellion mode in the SORX due to the large number of characters, works in both select screen and in-game during the "joining" event.

Just hold the directional button and it will automatically be repeated with a previous defined rate. In case you want to go this way, I can post the code.


Since I am against using 10x10 portraits, I really like this solution. It's a 'pick your poison' situation, where you either have all of the characters on screen with easy navigation but in very little portraits , or have big portraits but with the tedious cycling process of getting into your desired character after passing through 30+.

I do like more this Turbo Key method, for sure. Plus, my game willl be for 3 players, there is no way I could keep the big portraits and having the small icons to navigate throw all the characters in a single screen, so that's why I thought about selecting a game/groove/franchise first in that same screen, and then the player could still cycle between the available characters; if the player messes up choosing the worng franchise, a designed key could take you one step back and select the franchise one more time.

It would be an interesting thing to see in the future for sure, but for now, the turbo key would fit my game more than small portraits.

How about the different icons while continuing in mid game and having alternate portraits like in FFight?
Here is an example ( at 3m 37s )

 
Last edited:
I think it's already possible to add a bigger icon while continuing during gameplay that replaces the default icon, so you can have a better look on who you are choosing, right? like in the original FFight where it shows you clearly a better icon just for that specific time? I can't remember right now.
Oh, shoots! I forgot about this one.

I don't recall anybody that has implemented a unique portrait while continuing in gameplay as you describe. All I think about for it is to replace the default icon with script having a small portrait with an existing player and a big portrait for selecting the character while continuing in gameplay (if a player doesn't exist in continue until it is selected). What's catchy the most now is the continue text with its timer from the players' sides after losing all lives. But the problem for it is this... how will you check if active players are dead during gameplay and continue screen? It seems possible along with holding a directional button that @Kratus suggested. But the timer for continuing in gameplay seems like it's telling us to pick before it automatically selects the character highlighted already. I don't know if having an automatic start without any user pressing start is allowed though.
 
I do like more this Turbo Key method, for sure
No problem, in this case I will post the codes. You can control both initial/repeat speed by editing them at the keyall/update.c

This is the keyall.c content:

C:
void main()
{//Script to increase cursor repeat rate and speed, like a turbo key
    float time    = openborvariant("elapsed_time");
    float delay    = 80; //TURBO KEY INITIAL DELAY
    int player = getlocalvar("player");
    
    //ANY DIRECTIONAL BUTTON IS HELD??
    if(    playerkeys(player, 0, "moveright")    ||
        playerkeys(player, 0, "moveleft")    ||
        playerkeys(player, 0, "moveup")        ||
        playerkeys(player, 0, "movedown")    ){

        //SET BUTTON START TIME TO CALCULATE INITIAL DELAY
        if(getglobalvar("heldStart"+player) == NULL()){
            setglobalvar("heldStart"+player, time+delay);
        }
    }
}

This is the updated.c content:

C:
void main()
{
    if(openborvariant("in_titlescreen"))
    {
        //FOR SAFETY, CLEAR ALL GLOBAL VARIABLES
        if(getglobalvar("clearAll") != NULL()){
            clearG();
        }
    }

    if(openborvariant("in_menuscreen"))
    {
        setglobalvar("clearAll", 1);
    }

    if(openborvariant("in_selectscreen"))
    {
        turboKey();
    }
    
    if(openborvariant("in_level"))
    {
        turboKey();
    }
}

void clearG()
{//Clear all global variables in the title screen
    clearglobalvar();
}

void applyTurbo(int player)
{//Script to increase cursor repeat rate and speed, like a turbo key
    float time    = openborvariant("elapsed_time"); //CURRENT TIME
    float delay    = 20; //TURBO KEY REPEAT DELAY

    //WORKS IN "CHARACTER SELECT" SCREEN
    if(openborvariant("in_selectscreen")){
        if(time > getglobalvar("heldStart"+player)){ //REACHED DEFINED DELAY??
            if(getglobalvar("heldRepeat"+player) == NULL()){
                setglobalvar("heldRepeat"+player, time+delay);
            }

            //EXECUTE THE TURBO KEY FEATURE
            if(time > getglobalvar("heldRepeat"+player)){
                changeplayerproperty(player, "newkeys", getplayerproperty(player, "keys"));
                setglobalvar("heldStart"+player, time);

                //RESET THE "HELD BUTTON" OLD VARIABLE TO ADJUST THE NEXT REPEAT
                setglobalvar("heldRepeat"+player, time+delay);
            }
        }

        //NO DIRECTIONAL BUTTON HELD?? CLEAR ALL VARIABLES
        if(getplayerproperty(player, "keys") == 0){
            setglobalvar("heldStart"+player, NULL()); //RESET BUTTON START TIME
            setglobalvar("heldRepeat"+player, NULL()); //RESET BUTTON REPEAT TIME
        }
    }

    //WORKS IN LEVEL
    if(openborvariant("in_level")){
        if(getplayerproperty(player, "joining")){ //THE PLAYER ENTERED IN THE GAME BUT THE HERO IS NOT SELECTED YET??
            if(getglobalvar("heldStart"+player) != NULL()){ //ANY DIRECTIONAL BUTTON IS HELD??
                if(time > getglobalvar("heldStart"+player)+delay*2){ //REACHED DEFINED DELAY??
                    if(    getplayerproperty(player, "keys") == openborconstant("FLAG_MOVELEFT")    ||
                        getplayerproperty(player, "keys") == openborconstant("FLAG_MOVERIGHT")    ){

                        //RESET HELD KEY STATUS
                        changeplayerproperty(player, "playkeys", getplayerproperty(player, "keys"));
                        setglobalvar("heldStart"+player, time);
                    }
                }

                //NO DIRECTIONAL BUTTON HELD?? CLEAR ALL VARIABLES
                if(getplayerproperty(player, "keys") == 0){
                    setglobalvar("heldStart"+player, NULL()); //RESET BUTTON START TIME
                    setglobalvar("heldRepeat"+player, NULL()); //RESET BUTTON REPEAT TIME
                }
            }
        }
    }
}

void turboKey()
{//Check if the defined player exists before execute any task in Turbo Key feature
    
    if(getplayerproperty(0, "name")){applyTurbo(0);}
    if(getplayerproperty(1, "name")){applyTurbo(1);}
    if(getplayerproperty(2, "name")){applyTurbo(2);}
    if(getplayerproperty(3, "name")){applyTurbo(3);}
}

How about the different icons while continuing in mid game and having alternate portraits like in FFight?
I can make some tests in this aspect, I will post here as soon as I have any progress.
 
I can make some tests in this aspect, I will post here as soon as I have any progress.
@Mr.Q! I was able to make the big icons to work if a player is joining, please replace the previous updated.c with this new one where I already adapted.
You still need to adjust the position and icon names according to your game.

C:
void main()
{
    if(openborvariant("in_titlescreen"))
    {
        if(getglobalvar("clearAll") != NULL()){
            freeAssets();
            clearG();
        }
    }

    if(openborvariant("in_menuscreen"))
    {
        setglobalvar("clearAll", 1);
    }

    if(openborvariant("in_selectscreen"))
    {
        turboKey();
    }
    
    if(openborvariant("in_level"))
    {
        turboKey();
        drawIcon();
    }
}

void clearG()
{//Clear all global variables in the title screen
    clearglobalvar();
}

void applyTurbo(int player)
{//Script to increase cursor repeat rate and speed, like a turbo key
    float time    = openborvariant("elapsed_time"); //CURRENT TIME
    float delay    = 10; //TURBO KEY REPEAT DELAY

    //WORKS IN "CHARACTER SELECT" SCREEN
    if(openborvariant("in_selectscreen")){
        if(time > getglobalvar("heldStart"+player)){ //REACHED DEFINED DELAY??
            if(getglobalvar("heldRepeat"+player) == NULL()){
                setglobalvar("heldRepeat"+player, time+delay);
            }

            //EXECUTE THE TURBO KEY FEATURE
            if(time > getglobalvar("heldRepeat"+player)){
                changeplayerproperty(player, "newkeys", getplayerproperty(player, "keys"));
                setglobalvar("heldStart"+player, time);

                //RESET THE "HELD BUTTON" OLD VARIABLE TO ADJUST THE NEXT REPEAT
                setglobalvar("heldRepeat"+player, time+delay);
            }
        }

        //NO DIRECTIONAL BUTTON IS HELD?? CLEAR ALL VARIABLES
        if(getplayerproperty(player, "keys") == 0){
            setglobalvar("heldStart"+player, NULL()); //RESET BUTTON START TIME
            setglobalvar("heldRepeat"+player, NULL()); //RESET BUTTON REPEAT TIME
        }
    }

    //WORKS IN LEVEL
    if(openborvariant("in_level")){
        if(getplayerproperty(player, "joining")){ //THE PLAYER ENTERED IN THE GAME BUT THE HERO IS NOT SELECTED YET??
            if(getglobalvar("heldStart"+player) != NULL()){ //ANY DIRECTIONAL BUTTON IS HELD??
                if(time > getglobalvar("heldStart"+player)+delay*2){ //REACHED DEFINED DELAY??
                    if(    getplayerproperty(player, "keys") == openborconstant("FLAG_MOVELEFT")    ||
                        getplayerproperty(player, "keys") == openborconstant("FLAG_MOVERIGHT")    ){

                        //RESET HELD KEY STATUS
                        changeplayerproperty(player, "playkeys", getplayerproperty(player, "keys"));
                        setglobalvar("heldStart"+player, time);
                    }
                }

                //NO DIRECTIONAL BUTTON IS HELD?? CLEAR ALL VARIABLES
                if(getplayerproperty(player, "keys") == 0){
                    setglobalvar("heldStart"+player, NULL()); //RESET BUTTON START TIME
                    setglobalvar("heldRepeat"+player, NULL()); //RESET BUTTON REPEAT TIME
                }
            }
        }
    }
}

void turboKey()
{//Check if the defined player exists before execute any task in Turbo Key feature
    
    if(getplayerproperty(0, "name")){applyTurbo(0);}
    if(getplayerproperty(1, "name")){applyTurbo(1);}
    if(getplayerproperty(2, "name")){applyTurbo(2);}
    if(getplayerproperty(3, "name")){applyTurbo(3);}
}

void drawIcon()
{//Draw image for overlay effect in lifebar
    void player1 = getplayerproperty(0, "entity");
    void player2 = getplayerproperty(1, "entity");
    void player3 = getplayerproperty(2, "entity");
    void player4 = getplayerproperty(3, "entity");
    
    if(!openborvariant("pause")){
        iconFunction(player1, 0);
        iconFunction(player2, 1);
        iconFunction(player3, 2);
        iconFunction(player4, 3);
    }
}

void iconFunction(void player, int pIndex)
{//Script used to reduce code size

    //USED FOR PLAYERS JOINING IN A GAME
    if(getplayerproperty(pIndex, "joining")){
        void name    = getplayerproperty(pIndex, "name");
        int xPos    = 0; //BASE X POSITION
        int xDif    = 120; //DIFFERENCE BETWEEN PLAYERS
        int xAdd    = xDif*pIndex; //FORMULA TO ADD AN SPACE BETWEEN PLAYERS
        int yPos    = 0; //BASE Y POSITION
        int layer    = 900000000; //Z LAYER

        //LOAD SPRITE IF NULL
        if(getglobalvar("icon_"+name) == NULL()){
            setglobalvar("icon_"+name, loadsprite("data/sprites/icons/"+name+".gif"));
        }

        //DRAW ICON
        drawsprite(getglobalvar("icon_"+name), xPos+xAdd, yPos, layer);
    }
}

void freeAssets()
{//Free assets previously loaded

    if(getglobalvar("icon_Haggar") != NULL()){
        setglobalvar(getglobalvar("icon_Haggar"));
    }
    if(getglobalvar("icon_Cody") != NULL()){
        setglobalvar(getglobalvar("icon_Cody"));
    }
    if(getglobalvar("icon_Guy") != NULL()){
        setglobalvar(getglobalvar("icon_Guy"));
    }
}
 
@Kratus Thans for the code, and it works! I had the aid of @maxman to implement both codes and they work, but! The large icons during gameplay won't change colors when choosing an alaternate color. The regular icon is changing its color , but not the big one that I made for testing
 
Last edited:
@Kratus Thans for the code, and it works! I had the aid of @maxman to implement both codes and they work, but! The large icons during gameplay won't change colors when choosing an alaternate color:


As you can see, the regular icon is changing its color , but not the big one that I made for testing
@Mr.Q! Indeed the script was not programmed to change the icon palette (drawsprite does not manage palettes), it must be added to the code. My initial idea is to have one icon related to each palette but I will make some tests.

EDIT: Please, update the iconFunction() with this new one, I added the player's colourmap to the image name. You will need to create one icon for each palette and name them like iconHaggar0, iconHaggar1, iconHaggar2, and so on.

C:
void iconFunction(void player, int pIndex)
{//Script used to reduce code size

    //USED FOR PLAYERS JOINING IN A GAME
    if(getplayerproperty(pIndex, "joining")){
        void name   = getplayerproperty(pIndex, "name");
        int map     = getplayerproperty(pIndex, "colourmap");
        int xPos    = 0; //BASE X POSITION
        int xDif    = 120; //DIFFERENCE BETWEEN PLAYERS
        int xAdd    = xDif*pIndex; //FORMULA TO ADD AN SPACE BETWEEN PLAYERS
        int yPos    = 0; //BASE Y POSITION
        int layer   = 900000000; //Z LAYER

        //LOAD SPRITE IF NULL
        if(getglobalvar("icon_"+name+map) == NULL()){
            setglobalvar("icon_"+name+map, loadsprite("data/sprites/icons/"+name+map+".png"));
        }

        //DRAW ICON
        drawsprite(getglobalvar("icon_"+name+map), xPos+xAdd, yPos, layer);
    }
}
 
Last edited:
I'm getting a crash whenever I try to join a player in a run, just replaced the function you said, but:

void freeAssets()
{//Free assets previously loaded

if(getglobalvar("icon_Haggar") != NULL()){
setglobalvar(getglobalvar("icon_Haggar"));
}
if(getglobalvar("icon_Haggar$") != NULL()){
setglobalvar(getglobalvar("icon_Haggar$"));
}
if(getglobalvar("icon_Guy") != NULL()){
setglobalvar(getglobalvar("icon_Guy"));
}


}

Does this part stays the same? (I have 2 haggar characters btw, one is Haggar and the other is Haggar$)

Do I still need to have Haggar.gif or it should be enough with IconHaggar0.gif? BTW I am namimg the files exaclty like that, iconHaggar0.gif, iconHaggar1.gif, etc
 
Last edited:
Do I still need to have Haggar.gif or it should be enough with IconHaggar0.gif? BTW I am namimg the files exaclty like that, iconHaggar0.gif, iconHaggar1.gif, etc
In this case you need to remove the underline from the script. I adapted it for you in the new script below.
In addition, once you are using .gif and the script was looking for .png, it will cause crashes too. I suggest to check folder path too, in this case "data/sprites/icons/".

C:
void iconFunction(void player, int pIndex)
{//Script used to reduce code size

    //USED FOR PLAYERS JOINING IN A GAME
    if(getplayerproperty(pIndex, "joining")){
        void name   = getplayerproperty(pIndex, "name");
        int map     = getplayerproperty(pIndex, "colourmap");
        int xPos    = 0; //BASE X POSITION
        int xDif    = 120; //DIFFERENCE BETWEEN PLAYERS
        int xAdd    = xDif*pIndex; //FORMULA TO ADD AN SPACE BETWEEN PLAYERS
        int yPos    = 0; //BASE Y POSITION
        int layer   = 900000000; //Z LAYER

        //LOAD SPRITE IF NULL
        if(getglobalvar("icon"+name+map) == NULL()){
            setglobalvar("icon"+name+map, loadsprite("data/sprites/icons/icon"+name+map+".gif"));
        }

        //DRAW ICON
        drawsprite(getglobalvar("icon"+name+map), xPos+xAdd, yPos, layer);
    }
}
 
I fixed the freeAssets script too, the previous one I posted didn't have the correct free() function declared.

C:
void freeAssets()
{//Free assets previously loaded

    if(getglobalvar("iconHaggar0") != NULL()){
        free(getglobalvar("iconHaggar0"));
    }
    if(getglobalvar("iconHaggar1") != NULL()){
        free(getglobalvar("iconHaggar1"));
    }
    if(getglobalvar("iconGuy0") != NULL()){
        free(getglobalvar("iconGuy0"));
    }
    if(getglobalvar("iconGuy1") != NULL()){
        free(getglobalvar("iconGuy1"));
    }
}
 
Back
Top Bottom