Player Movement

In this page we will explain how the game sees player inputs and how we handle the case of multi-key inputs so the player can move smoothly and in all 8 directions (N, NE, E, SE, S, SW, W, NW).

The game handles multi-key inputs to move the player through the function below. It compares whatever keys are being pressed down to a Tuple list of Keyboard.Keys and a corresponding 2D vector that is added to a local Vector2. That local Vector2 is passed to the MoveVector() function. MoveVector() updates the player's collider and picture on the screen. If there is no player input, then nothing is added to the temporary Vector2, and ResetMoveSpeed() is called.

Private Tuple<Key, Vector2>[] moveKeys = new Tuple<Key, Vector2>[] {
    Tuple.Create(Key.A,     new Vector2(-1, 0)), //West
    Tuple.Create(Key.D,     new Vector2(+1, 0)), //East
    Tuple.Create(Key.W,     new Vector2(0, -1)), //North
    Tuple.Create(Key.S,     new Vector2(0, +1)), //South
};

private void playerMove() {
    if (pause == false) {
        Vector2 moveDir = new Vector2(0, 0);

        foreach (Tuple<Key, Vector2> keyBind in this.moveKeys) {
            if (Keyboard.IsKeyDown(keyBind.Item1)) {
                moveDir = new Vector2(moveDir.x + keyBind.Item2.x, moveDir.y + keyBind.Item2.y);
            }
        }

        if (moveDir.Equals(new Vector2(0, 0))) {
            player.ResetMoveSpeed();
        }
        else {
            player.MoveVector(moveDir);
        }
    }
}

Here are the function that handle moving the player object on the screen. Whenever the player presses keys to move, their intended move direction is stored by MoveVector() (or ResetMoveSpeed() in the case of no inputs). The move function is what actually updates the player's position, and moves their collider accordingly.

public void Move() {
    LastPosition = Position;
    Position = new Vector2(Position.x + MoveSpeed.x, Position.y + MoveSpeed.y);
    Collider.MovePosition((int)Position.x, (int)Position.y);
}

public void MoveBack() {
    Position = LastPosition;
}

public void MoveVector(Vector2 vector) {
    MoveSpeed = new Vector2(GO_INC * vector.x, GO_INC * vector.y);
}

public void ResetMoveSpeed() {
    MoveSpeed = new Vector2(0, 0);
}

Here in FrmLevel, the game updates the player's position every game tick and moves the player's sprite accordingly. This function also prevents the player from moving through walls.

private void tmrPlayerMove_Tick(object sender, EventArgs e) {
    // move player
    if (!HaltMove) { 
        player.Move(); 
    }

    // check collision with walls
    if (HitAWall(player)) {
        player.MoveBack();
    }

    // update player's picture box
    picPlayer.Location = new Point((int)player.Position.x, (int)player.Position.y);
}

private void FrmLevel_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e) {          
    displayPauseMenu();
    playerMove();
}

private void FrmLevel_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {            
    displayPauseMenu();
    playerMove();
}

Last updated