Reputation: 151
So I'm reading a book about MVC and the author create a controller (PlayerController) and put some functions for keyboard use and some for mouse use. But he just comment out every keyboard use.
It gave me a idea to create 2 controllers, PlayerMouseController and PlayerKeyboardController so I can decide how to control the player changing one line. And if I can design this way, later I can add a AIController for monsters that use the same view and model but are controlled by AI and so on...
I have my model Player and it do the physics stuff. Now I want two controller, one for mouse and other for keyboard. So I create a PlayerMouseController and PlayerKeyboardController.
The PlayerMouseController has 2 functions: processUpdate() and processMouseDown() The PlayerKeyboardController has 2 functions: processKeyDown() and processKeyUp()
I create the object like this:
_player = new Player();
_playerController = new PlayerMouseController(_player);
_playerView = new PlayerView(_player, _playerController, stage);
addChild(_playerView);
If I want to change the controller I can just change the _playerController line for this:
_playerController = new PlayerKeyboardController(_player);
And it works fine... But I dont know if the design I use is fine for a large project
To make this work I have to create a Controller class with nothing so I can extends the others controllers and my view can call all methods.
public class Controller
{
public function processKeyDown(e:KeyboardEvent):void
{
}
public function processKeyUp(e:KeyboardEvent):void
{
}
public function processUpdate(stage:Stage):void
{
}
public function processMouseDown(e:MouseEvent):void
{
}
}
In my view (PlayerView) I accept any Controller:
public function PlayerView(model:Player, controller:Controller, stage:Stage)
{
_model = model;
_controller = controller;
_stage = stage;
}
and I decide what to use based on its type:
if (_controller is PlayerKeyboardController)
{
_stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
_stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
else if (_controller is PlayerMouseController)
{
_model.addEventListener(Model.UPDATE, onUpdate);
_stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
// EVENTS PlayerKeyboardController
private function onKeyDown(e:KeyboardEvent):void
{
_controller.processKeyDown(e);
}
private function onKeyUp(e:KeyboardEvent):void
{
_controller.processKeyUp(e);
}
// EVENTS PlayerMouseController
private function onUpdate(e:Event):void
{
_controller.processUpdate(_stage);
}
private function onMouseDown(e:MouseEvent):void
{
_controller.processMouseDown(e);
}
So... this is a good idea? How should I improve??
Upvotes: 0
Views: 195
Reputation: 1954
I think as your project evolves you'll soon hit a bottleneck with this kind of approach. I'd suggest creating a general IEntityController
interface (don't be afraid of the word 'entity', it just shows that this is a game object controller, something that is parent for example of hero, enemy, etc.).
Then I'd create two separate implementations of this interface: BasicMouseController
and BasicKeyboardController
, so that I'd have two branches of these controllers with basic logic. If you need additional functionality for the Hero, you'd create a HeroMouseController
class which would extend the BasicMouseController
class and would have the advantage of calling super
methods and adding the extended functionality easily.
You'd still have the benefit of passing different controllers to the PlayerView
class as it's constructor would receive an IEntityController
as a parameter, meaning anything implementing this class can be passed in.
There are many approaches for problems like this and StackOverflow is usually not meant to give these kind of answers, as every answer to these kind of questions is subjective and this website more fit for Problem/Solution kind of posts.
Upvotes: 1