I'm not sure if the title is exactly an accurate representation of what I'm actually trying to ask, but that was the best I could think of. I am experiencing an issue with my character class. I have developed a system so that he can perform chain attacks, and something that was important to me was that 1)button presses during the process of an attack wouldn't interrupt the character, and 2) at the same time, button presses should be stored so that the player can smoothly queue up chain attacks in the middle of one so that gameplay doesn't feel rigid or unresponsive.
This all begins when the player presses the punch button. Upon pressing the punch button, the game checks the state of the dpad at the moment of the button press, and then translates the resulting combined buttons into an int which I use as an enumerator relating to a punch method for the character. The enumerator is placed into a List so that the next time the character's Update() method is called, it will execute the next punch in the list. It only executes the next punch if my character is flagged with acceptInput as true. All attacks flag acceptInput as false, to prevent the interruption of attacks, and then at the end of an attack, acceptInput is set back to true. While accepting input, all other actions are polled for, i.e. jumping, running, etc.
In runtime, if I attack, and then queue up another attack behind it (by pressing forward+punch) I can see the second attack visibly execute, which should flag acceptInput as false, yet it gets interrupted and my character will stop punching and start running if I am still holding down the dpad.
Included is some code for context.
This is the input region for my character.
//Placed this outside the if (acceptInput) tree because I want it
//to be taken into account whether we are accepting input or not.
//This will queue up attacks, which will only be executed if we are accepting input.
//This creates a desired effect that helps control the character in a
// smoother fashion for the player.
if (Input.justPressed(buttonManager.Punch))
{
int dpadPressed = Input.DpadState(0);
if (attackBuffer.Count() < 1)
{
attackBuffer.Add(CheckPunch(dpadPressed));
}
else
{
attackBuffer.Clear();
attackBuffer.Add(CheckPunch(dpadPressed));
}
}
if (acceptInput)
{
if (attackBuffer.Count() > 0)
{
ExecutePunch(attackBuffer[0]);
attackBuffer.RemoveAt(0);
}
//If D-Pad left is being held down.
if (Input.DpadDirectionHeld(0, buttonManager.Left))
{
flipped = false;
if (onGround)
{
newAnimation = "run";
}
velocity = new Vector2(velocity.X - acceleration, velocity.Y);
if (walking == true && velocity.X <= -walkSpeed)
{
velocity.X = -walkSpeed;
}
else if (walking == false && velocity.X <= -maxSpeed)
{
velocity.X = -maxSpeed;
}
}
//If D-Pad right is being held down.
if (Input.DpadDirectionHeld(0, buttonManager.Right))
{
flipped = true;
if (onGround)
{
newAnimation = "run";
}
velocity = new Vector2(velocity.X + acceleration, velocity.Y);
if (walking == true && velocity.X >= walkSpeed)
{
velocity.X = walkSpeed;
}
else if (walking == false && velocity.X >= maxSpeed)
{
velocity.X = maxSpeed;
}
}
//If jump/accept button is pressed.
if (Input.justPressed(buttonManager.JumpAccept))
{
if (onGround)
{
Jump();
}
}
//If toggle element next button is pressed.
if (Input.justPressed(buttonManager.ToggleElementNext))
{
if (elements.Count != 0)
{
elementInUse++;
if (elementInUse >= elements.Count)
{
elementInUse = 0;
}
}
}
//If toggle element last button is pressed.
if (Input.justPressed(buttonManager.ToggleElementLast))
{
if (elements.Count != 0)
{
elementInUse--;
if (elementInUse < 0)
{
elementInUse = Convert.ToSByte(elements.Count() - 1);
}
}
}
//If character is in the process of jumping.
if (jumping == true)
{
if (Input.heldDown(buttonManager.JumpAccept))
{
velocity.Y -= fallSpeed.Y;
maxJumpTime -= elapsed;
}
if (Input.justReleased(buttonManager.JumpAccept) || maxJumpTime <= 0)
{
jumping = false;
maxJumpTime = 0;
}
}
//Won't execute abilities if input isn't being accepted.
foreach (PlayerAbility ability in playerAbilities)
{
if (buffer.Matches(ability))
{
if (onGround)
{
ability.Activate();
}
if (!onGround && ability.UsableInAir)
{
ability.Activate();
}
else if (!onGround && !ability.UsableInAir)
{
buffer.Clear();
}
}
}
}
When the attackBuffer calls ExecutePunch(int) method, ExecutePunch() will call one of the following methods:
private void NeutralPunch1() //0
{
acceptInput = false;
busy = true;
newAnimation = "punch1";
numberOfAttacks++;
timeSinceLastAttack = 0;
}
private void ForwardPunch2(bool toLeft) //true == 7, false == 4
{
forwardPunch2Timer = 0f;
acceptInput = false;
busy = true;
newAnimation = "punch2begin";
numberOfAttacks++;
timeSinceLastAttack = 0;
if (toLeft)
{
velocity.X -= 800;
}
if (!toLeft)
{
velocity.X += 800;
}
}
I assume the attack is being interrupted due to the fact that ExecutePunch() is in the same if statement as running, but I haven't been able to find a suitable way to stop this happening.
Thank you ahead of time for reading this, I apologize for it having become so long winded.