HaxeFlixel 2 player game: make input code cleaner

Clash 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?
haxe haxeflixel
add a comment |Â
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?
haxe haxeflixel
Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
â greybeard
Feb 10 at 14:17
(I readcurrently both players are moved by arrow keyas I do have working code, not shown inPlayer.update()because irrelevant here.)
â greybeard
Feb 10 at 14:20
add a comment |Â
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?
haxe haxeflixel
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?
haxe haxeflixel
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 readcurrently both players are moved by arrow keyas I do have working code, not shown inPlayer.update()because irrelevant here.)
â greybeard
Feb 10 at 14:20
add a comment |Â
Please use a spelling checker. In the code snippets, try not to waste (vertical) space.
â greybeard
Feb 10 at 14:17
(I readcurrently both players are moved by arrow keyas I do have working code, not shown inPlayer.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
add a comment |Â
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 inPlayState- Flixel already does that when you callsuper.update(), since you'veadd()ed the players to the state. This means the players end up being updated twice per frame. - You manually added variables for
WindowWidthandWindowHeight, which are already available globally viaFlxG.widthandFlxG.height.
thank you so much. i really appreciate. it was lot of help.
â jun
Feb 10 at 14:22
add a comment |Â
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 inPlayState- Flixel already does that when you callsuper.update(), since you'veadd()ed the players to the state. This means the players end up being updated twice per frame. - You manually added variables for
WindowWidthandWindowHeight, which are already available globally viaFlxG.widthandFlxG.height.
thank you so much. i really appreciate. it was lot of help.
â jun
Feb 10 at 14:22
add a comment |Â
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 inPlayState- Flixel already does that when you callsuper.update(), since you'veadd()ed the players to the state. This means the players end up being updated twice per frame. - You manually added variables for
WindowWidthandWindowHeight, which are already available globally viaFlxG.widthandFlxG.height.
thank you so much. i really appreciate. it was lot of help.
â jun
Feb 10 at 14:22
add a comment |Â
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 inPlayState- Flixel already does that when you callsuper.update(), since you'veadd()ed the players to the state. This means the players end up being updated twice per frame. - You manually added variables for
WindowWidthandWindowHeight, which are already available globally viaFlxG.widthandFlxG.height.
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 inPlayState- Flixel already does that when you callsuper.update(), since you'veadd()ed the players to the state. This means the players end up being updated twice per frame. - You manually added variables for
WindowWidthandWindowHeight, which are already available globally viaFlxG.widthandFlxG.height.
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
add a comment |Â
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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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 keyas I do have working code, not shown inPlayer.update()because irrelevant here.)â greybeard
Feb 10 at 14:20