Open vlidholt opened 11 years ago
To clarify this issue. Right now, if you want to use a controller object to control a CCNode (or subclass) you will need to write code that forwards the events that the CCNode receives.
Events include:
The code you currently have to write looks something like the following (copied from CocosDragonJS):
// Forward relevant touch events to controller (this)
this.rootNode.onTouchesBegan = function( touches, event) {
this.controller.onTouchesBegan(touches, event);
return true;
};
this.rootNode.onTouchesMoved = function( touches, event) {
this.controller.onTouchesMoved(touches, event);
return true;
};
this.rootNode.onMouseDragged = function( event) {
this.controller.onMouseDragged(event);
return true;
};
this.rootNode.onAccelerometer = function( event) {
this.controller.onAccelerometer(event);
};
// Schedule callback
this.rootNode.onUpdate = function(dt) {
this.controller.onUpdate();
};
this.rootNode.schedule(this.rootNode.onUpdate);
This code is complicated and hard to understand. Coming up with a better solution for forwarding these events would be great, and simplify things for everyone using a controller object to control a CCNode (or subclass). This is especially important if someone uses CocosBuilder, as it will use controller objects instead of subclasses. (Subclasses cannot be used as the parent class is loaded in native code.)
One solution would be to add the controller object as a delegate to CCNode and have the node forward all the events to the delegate (if such a delegate is attached). Other better solutions may exist, so please add thoughts below!
context: CCNode
should be a simple as possible. No extra logic should be added there. It is a dumb object with basic properties that might know how to render itself and nothing more.
What cocos2d needs is a much better event handler.
something like:
// Pseudo code, trying to clarify the idea
// Subscribes to scene-workflow events like: "onEnter", "onExit"
var handler = cc.EventDispatcher.subscribe( cc.EVENT_SCENE_ALL, this );
// Subscribes only to "onKeyUp" event:
var handler = cc.EventDispatcher.subscribe( cc.EVENT_KEYBOARD_KEYUP );
// Subscribes to window events like "onResize", "onMinify", "onMaximize", etc:
var handler = cc.EventDispatcher.subscribe( cc.EVENT_WINDOW_ALL, this );
Scheduler is not an event, and it is already controlled by the cc.Scheduler
object.
And MVC model could be easily be implemented with:
The Controller object, which is going to be the controller of the game, should:
cc.Scheduler
for the main loopCCLayer
should not be used as the controller, or should not have a controller.
The controller object, should be the controller of the game (or director) if you want.
Additionally, by adding a good event dispatcher object, objects could comunicate between them by using events. eg:
cc.EventDispatcher.emit("game_over", optional_data);
// will generate the "game_over", and will be consumed by:
var consumeEvent = function( event, data ) {
if( event == "game_over" ) {
do_something_data( data );
}
};
To keep in mind: Should we use an MVC pattern ? (like Cocoa and other UI stuff ) or an Entity system pattern ? (like Unity and other game engines )
I like Entity system pattern.
I like Entity System too.
Another approach: issue #64
@vlidholt I agree with you:
One solution would be to add the controller object as a delegate to CCNode and have the node forward all the events to the delegate (if such a delegate is attached).
In issue #64, CCNode CAN NOT GET and SHOULD NOT HANDLER events. Events are only sent to CCNode's component: ControllerComponent (or named as EventsComponent, EventsReceiverComponent, EventsHandlerComponent) instead. ControllerComponent can communicate with its owner node and other components. I wrote same pseudo code there.
Make it possible to have the controller object act as a delegate to CCNode. Events (such as touches, onUpdate etc) should be automatically forwarded to the delegate (controller). This would very much simplify the process of integrating CocosBuilder files with JS code.