HaxeFlixel 2 player game: make input code cleaner

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












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?







share|improve this question





















  • Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
    – greybeard
    Feb 10 at 14:17










  • (I read currently both players are moved by arrow key as I do have working code, not shown in Player.update() because irrelevant here.)
    – greybeard
    Feb 10 at 14:20

















up vote
3
down vote

favorite












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?







share|improve this question





















  • Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
    – greybeard
    Feb 10 at 14:17










  • (I read currently both players are moved by arrow key as I do have working code, not shown in Player.update() because irrelevant here.)
    – greybeard
    Feb 10 at 14:20













up vote
3
down vote

favorite









up vote
3
down vote

favorite











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?







share|improve this question













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?









share|improve this question












share|improve this question




share|improve this question








edited Feb 10 at 14:42









Daniel

4,1132836




4,1132836









asked Feb 10 at 13:22









jun

183




183











  • Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
    – greybeard
    Feb 10 at 14:17










  • (I read currently both players are moved by arrow key as I do have working code, not shown in Player.update() because irrelevant here.)
    – greybeard
    Feb 10 at 14:20

















  • Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
    – greybeard
    Feb 10 at 14:17










  • (I read currently both players are moved by arrow key as I do have working code, not shown in Player.update() because irrelevant here.)
    – greybeard
    Feb 10 at 14:20
















Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
– greybeard
Feb 10 at 14:17




Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
– greybeard
Feb 10 at 14:17












(I read currently both players are moved by arrow key as I do have working code, not shown in Player.update() because irrelevant here.)
– greybeard
Feb 10 at 14:20





(I read currently both players are moved by arrow key as I do have working code, not shown in Player.update() because irrelevant here.)
– greybeard
Feb 10 at 14:20











1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










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<FlxKey>,
down:Array<FlxKey>,
left:Array<FlxKey>,
right:Array<FlxKey>



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.





share|improve this answer





















  • thank you so much. i really appreciate. it was lot of help.
    – jun
    Feb 10 at 14:22










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187252%2fhaxeflixel-2-player-game-make-input-code-cleaner%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










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<FlxKey>,
down:Array<FlxKey>,
left:Array<FlxKey>,
right:Array<FlxKey>



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.





share|improve this answer





















  • thank you so much. i really appreciate. it was lot of help.
    – jun
    Feb 10 at 14:22














up vote
2
down vote



accepted










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<FlxKey>,
down:Array<FlxKey>,
left:Array<FlxKey>,
right:Array<FlxKey>



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.





share|improve this answer





















  • thank you so much. i really appreciate. it was lot of help.
    – jun
    Feb 10 at 14:22












up vote
2
down vote



accepted







up vote
2
down vote



accepted






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<FlxKey>,
down:Array<FlxKey>,
left:Array<FlxKey>,
right:Array<FlxKey>



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.





share|improve this answer













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<FlxKey>,
down:Array<FlxKey>,
left:Array<FlxKey>,
right:Array<FlxKey>



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.






share|improve this answer













share|improve this answer



share|improve this answer











answered Feb 10 at 13:59









Gama11

1384




1384











  • thank you so much. i really appreciate. it was lot of help.
    – jun
    Feb 10 at 14:22
















  • thank you so much. i really appreciate. it was lot of help.
    – jun
    Feb 10 at 14:22















thank you so much. i really appreciate. it was lot of help.
– jun
Feb 10 at 14:22




thank you so much. i really appreciate. it was lot of help.
– jun
Feb 10 at 14:22












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f187252%2fhaxeflixel-2-player-game-make-input-code-cleaner%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Python Lists

Aion

JavaScript Array Iteration Methods