Controlling Player Movement for a game


Controlling Player Movement

Speaking of having the player move, you should implement this code as well. Considering that sometimes the player cannot move in a specific direction, you want to first check whether the move the player wants to make is valid and then do the move if necessary. Add the methods in Listing 8.4 to your Level class to handle these cases.
Listing 8.4. Controlling Player Movement
/// 
/// Can the player move horizontally
/// 
/// Is the player moving right
/// true if the move can be made; false otherwise
private bool CanPlayerMoveHorizontal(bool right)
{
    if ( ((playerIndex % SquareSize) == 0) && (!right))
    {
        return false;
    }
    else if ( ((playerIndex % SquareSize) == (SquareSize - 1)) && (right))
    {
        return false;
    }
    // Check to see if there is a piece in the new position
    return (blocks[playerIndex + ((right) ? 1 : -1)] != null);
}
/// 
/// Can the player move vertically
/// 
/// Is the player moving in the positive z direction
/// true if the move can be made; false otherwise
private bool CanPlayerMoveVertical(bool pos)
{
    if ( ((playerIndex / SquareSize) == 0) && (pos))
    {
        return false;
    }
    else if ( ((playerIndex / SquareSize) == (SquareSize - 1)) && (!pos))
    {
        return false;
    }
    return (blocks[playerIndex + ((pos) ? -SquareSize : SquareSize)] != null);
}
/// 
/// Update the player's position vertically
/// 
/// Is the player moving in the positive z direction
/// true if the move was made; false otherwise
public bool MovePlayerZ(bool pos)
{
    if (isGameOver)
        return false; // Nothing to do if the game is over
    currentPlayer.SetDirection(pos ? PlayerDirection.Down : PlayerDirection.Up);
    if (CanPlayerMoveVertical(pos))
    {
        // Update the block here
        if (UpdatePlayerAndBlock(false, playerIndex + ((pos) ?
                                 -SquareSize : SquareSize)))
        {
            // Update the player index
            playerIndex += (pos) ? -SquareSize : SquareSize;
            // Update the number of moves
            totalMoves++;
            return true;
        }
    }
    return false;
}
/// 
/// Update the player's position horizontally
/// 
/// Is the player moving right
/// true if the move was made; false otherwise
public bool MovePlayerX(bool right)
{
    if (isGameOver)
        return false; // Nothing to do if the game is over
    currentPlayer.SetDirection(right ? PlayerDirection.Right :
                               PlayerDirection.Left);
    if (CanPlayerMoveHorizontal(right))
    {
        // Update the block here
        if (UpdatePlayerAndBlock(false, playerIndex + ((right) ? 1 : -1)))
        {
            // Update the player index
            playerIndex += (right) ? 1 : -1;
            // Update the number of moves
            totalMoves++;
            return true;
        }
    }

    return false;
}

Two methods check whether a move is valid, one for horizontal moves (moves along the X axis) and the other for vertical moves (moves along the Z axis). Each of these methods takes a single Boolean parameter that essentially determines whether the player is attempting to move along the positive or negative direction of the appropriate axis. Depending on which axis the move is along, the code first detects whether the player is on the bounding edge and whether the player is attempting to "jump off" the edge of the board. If he is, the method returns false, signifying that the move is invalid. If the player is moving to a valid location in the square of blocks, then the move is considered valid.
The two moving methods are similar, and they take the same parameters. Obviously if the game is over, there is nothing more to do, so you can simply exit from the method. The movement methods also return Boolean values so the caller can detect whether the move was actually made. (Although the code in this book does not detect the return value, it could be used to enhance the game on your own.) Notice that before the check to see whether the move is valid, the SetDirection call is made on the player. Even if the move isn't valid, the player should still turn toward the last direction a movement was attempted. Finally, the move is actually checked for validity. Assuming it is valid, the UpdatePlayerAndBlock method from earlier is called. If this move was successful, the player index is updated, the number of total moves is incremented, and the method returns TRue, signifying that the move was made. Any other scenario results in the method returning false.
How exactly does the player move, though? Obviously, there needs to be some type of user interaction to make this happen. You have two options that will jump out at you, namely the mouse and keyboard. Although using the mouse is technically feasible, clicking on the correct block to move to could be a bit tricky. Using the keyboard makes the most sense for this situation, so that's what you do here. Just like the user interface screens, the Level class needs a method to accept keyboard events. You will find this method in Listing 8.5.
Listing 8.5. Reacting to User Input
public void OnKeyPress(System.Windows.Forms.Keys key)
{
    // Is the player trying to move?
    switch(key)
    {
        case System.Windows.Forms.Keys.Right:
            MovePlayerX(true);
            break;
        case System.Windows.Forms.Keys.Left:
            MovePlayerX(false);
            break;
        case System.Windows.Forms.Keys.Up:
            MovePlayerZ(false);
            break;
        case System.Windows.Forms.Keys.Down:
            MovePlayerZ(true);
            break;
    }
}

The only keys this method cares about are the arrow keys. If the player presses one of them, the appropriate movement method is called, with the return value ignored.

Comments

Popular Posts