HaxeFlixel 2 player game: make input code cleaner I'm makeing two-player game. player1 can play with the WASD keys, and player2 can play with the arrow keys.

PlayState.hx

package;

import flixel.FlxState;

class PlayState extends FlxState
{
    //basic global varible
    var WindowWidth:Int = 640;
    var WindowHeight:Int = 480;

    //sprites
    var player1:Player;
    var player2:Player;

    override public function create():Void
    {

        player1 = new Player(50, WindowHeight / 2 - 50);
        add(player1);


        player2 = new Player(590, WindowHeight / 2 - 50);
        add(player2);

        super.create();
    }

    override public function update(elapsed:Float):Void
    {
        player1.update();
        player2.update();
        super.update(elapsed);
    }
}


Player.hx

package;

import flixel.FlxSprite;
import flixel.FlxG;
import flixel.util.FlxColor;

class Player extends FlxSprite
{
    public function new(X:Float,Y:Float)
    {
        super(X,Y);
        makeGraphic(20,100,FlxColor.WHITE);
    }

    override public function update(elapsed:Float):Void
    {

        super.update(elapsed);
    }
}


In this code, I made a player class. This class is used by both player1 and player2 instances. 

Currently both players are moved by the arrow keys. But I want to make two players using different keys (arrow keys and WASD keys).

I'm considering two solutions, but I think the both ways are not perfect. It smells of bad code.

Solution 1:
Make player1 and player2 classes. They extend the Player class and override the update() method. 

class Player1 extends Player
{
    override public function update(elapsed:Float):Void
    {
        //make player1 move by wasd keys.
        super.update(elapsed);
    }
}
class Player1 extends Player
{
    override public function update(elapsed:Float):Void
    {
        //make player2 move by arrow keys.
        super.update(elapsed);
    }
}


But if I add the code in update(), there will be duplicated code. I want to make two player is completely identical, only different location and keyboard.

Solution 2:
Receive argument in update() function which key will use, and use it.

override public function update(elapsed:Float, upkey, downkey, rightkey, leftkey):Void
{
    //I will write it psuedo code
    if(upkey.pressed):
        move up
    if(downkey.pressed):
        move down
    if(leftkey.pressed):
        move left
    if(rightkey.pressed):
        move right
    super.update(elapsed);
}


But it have to additional argument in the update() function. And I think it makes the code more complex.

To me, both seem like bad code. What can I do?
Parametrizing the keys seems like the correct solution to me. The subclassing approach leads to code duplication and inflexibility. However, you should not do that by adding parameters to update() - in fact, you can't, because the function signature of an overriden method has to match. You would get a compiler error:

Field update overloads parent class with different or incomplete type
Different number of function arguments

Since it's 4 parameters that are closely related to each other, you might want to bundle them in a structure. By using the FlxG.keys.anyPressed() API, which takes an array of keys, we could in theory also allow multiple keys per input:
package;

import flixel.FlxG;
import flixel.FlxSprite;
import flixel.util.FlxColor;
import flixel.input.keyboard.FlxKey;

class Player extends FlxSprite
{
    var keys:PlayerKeys;

    public function new(x:Float, y:Float, keys:PlayerKeys)
    {
        super(x, y);
        makeGraphic(20, 100, FlxColor.WHITE);
    }

    override public function update(elapsed:Float):Void
    {
        if (FlxG.keys.anyPressed(keys.up)) { /* move up */ }
        if (FlxG.keys.anyPressed(keys.down)) { /* move down */ }
        if (FlxG.keys.anyPressed(keys.left)) { /* move left */ }
        if (FlxG.keys.anyPressed(keys.right)) { /* move right */ }

        super.update(elapsed);
    }
}

typedef PlayerKeys = {
    up:Array&lt;FlxKey&gt;,
    down:Array&lt;FlxKey&gt;,
    left:Array&lt;FlxKey&gt;,
    right:Array&lt;FlxKey&gt;
}

And to construct the player instances:
player1 = new Player(x, y, {up: [UP], down: [DOWN], left: [LEFT], right: [RIGHT]});
player2 = new Player(x, y, {up: [W], down: [S], left: [A], right: [D]});


There's two other issues with your code:

You update() your players manually in PlayState - Flixel already does that when you call super.update(), since you've add()ed the players to the state. This means the players end up being updated twice per frame.
You manually added variables for WindowWidth and WindowHeight, which are already available globally via FlxG.width and FlxG.height.