Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making an turnbased RPG and I wanted to add a traditional multiple enemy system where a user could attack different enemies when it's there turn. I started by making a list of everybody who is going to attack and having that as the turn order. My question is how do I go through that list, and for every enemy that attacks display the damage they did and wait for the user input to continue to the next enemy.

Getting it to process all the attacks is easy, but a computer will do it in milliseconds and I need it to wait for the user input to continue.

I have started the following code:

for (int i = 0; i < turnOrder.Count; i++)
{
     if (turnOrder[i].isMonster)
     {
          ProcessEnemyChoice(enemyToAttack);
     }
     else if (turnOrder[i].isMonster == false)
     {
          ProcessUserChoice(enemyToAttack);
     }
     //enemyToAttack is assigned as a the enemy the user selected
}

I tried a do-while loop but that stopped my program from doing any updating, which makes sense. I'm at a loss here and any input from the geniuses here would be much appreciated.

share|improve this question
    
I don't have much time but the problem is that this ties up your main loop, which also drives your display updates I'm guessing. You want to turn this into a subroutine that immediately removes choices processed, add a routine to see if any user input is available and if not then return from this subroutine immediately, else process one user choice (subject to immediate removal) and return. The next call in from your main loop will catch the next things to process, etc... –  Patrick Hughes May 27 '12 at 3:19
add comment

2 Answers

up vote 2 down vote accepted

I tried a do-while loop but that stopped my program from doing any updating

You don't need to do a while loop to wait for the input. You just maintain a global gamestate and whos_turn_is_it so that you know what to do on each update loop:

public override void Update(GameTime gameTime)
{
    if(gamestate == WAIT_FOR_INPUT)
    {
        if(turnOrder[whos_turn_is_it].IsMonster == false)
        {
            if(UserInput != null)
            {
                ProcessUserChoice(UserInput);
                gamestate = WAIT_FOR_ANIMATION;
            }
        }
        else if(turnOrder[whos_turn_is_it].IsMonster)
        {
            ProcessEnemyChoice();
            gamestate = WAIT_FOR_ANIMATION;
        }        
    }

    // Do the animations
    // idle animation, NPC movement, fight/heatlh bar animation
    ProcessAnimations(gameTime);
}

public void ProcessAnimations(GameTime gameTime)
{
    // an example of health animation (as a form of input feedback)
    player.current_health += (player.current_health - player.health_after_fight) / 20.0f

    // an example of 2D graphic animation
    player.current_sprite_index = (int)(gameTime.ElapsedTime * player.animation.fps);

    // we need to stop the animation and current state after sometime when input feedback complete
    if(player.current_health - player.health_after_fight < 0.001f && player.current_sprite_index == player.sprite_frame_count_max)
    {
        whos_turn_is_it++; // next person's turn since our animation is now done.
        gamestate = WAIT_FOR_INPUT;
    }

    // do animations for other stuff
    DoOtherAnimationUpdate();
}
share|improve this answer
    
Yes! That's works perfectly. I can increment who is attacking by one every click and if it's greater than the list count I send it back to decide the input. Thanks a lot! –  Thegluestickman May 27 '12 at 15:21
add comment

Since it's turn based, of course a single turn will take as much time as the slowest player spends to send input. You don't need to wait for everything else just for turn-related stuff.

If you want to make it independent form user input, then you have basically two options: 1- assign a max amount of time to act (the same situation as a real life chess game)

2- use some sort of real time system with filling action bars (like many RPGs do).

Using an action bar (the fill rate will depend on the unit's initiative) you'll get you a dynamic stack of actions and the game will solve the top action for each time step.

The game won't ever have to wait (beyond a defined amount), but a player that takes ages to decide his/her move could lose server actions.

Edit: Since there 1 human player, the enemies are considered AI players. The above still applies.

What should the human player be able to do while the cpu is computing? If you let the user send the next input while the cpu decides, the user won't be able to see the current turn result so it could be risky or simply wrong.

Or if your problem is just that the game hangs up completely, you just need to avoid having the AI loop inside the main game loop. That's just a common multi-threading problem. Look at this to get some more details (answers cover AI updates) :

http://stackoverflow.com/questions/1941573/multithreading-in-xna-game

share|improve this answer
    
The input is solely based on one user, so when the player decides all the enemies choose as well. –  Thegluestickman May 27 '12 at 13:54
    
I'll edit to keep it clear. –  Darkwings May 27 '12 at 14:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.