I see that certain texts always seem to subclass CCSprite. I read somewhere that开发者_如何学C it is not good to do that and that it is better to start with something basic. I wanted to find out what the pro game developers do in terms of game structure. That is subclass CCSprite or add CCSprite in a NSObject class ETC.
I hope my question makes sense.
My preference is to subclass CCNode almost exclusively.
I would only ever subclass CCSprite, CCLabel and other internal Cocos2D classes if I needed the sprite, label or whatever to behave slightly differently from the base implementation. And subclassing would be a last resort measure if a category is insufficient. What most Cocos2D developers apparently don't understand is that CCSprite is in itself a complete class that does not need to be extended (subclassed) for representing game objects. But it's all too easy to fall into this habit because by creating a CCSprite subclass you get the visuals and you have a container for your game logic code. It's just not very OOP to do so.
If you think about it, as soon as you add some sort of game logic code to a CCSprite, it's not really just a CCSprite anymore, or is it? One good way to think about it is this: if you subclass a class (name it MyClass) and add custom code to it, would it make a lot of sense to subclass MyClass for other purposes, too? If not, then you shouldn't subclass.
To go with the widely used OOP analogy of the "Car" class: you subclass "Car" to make more specialized but still generic classes like "SportsCar", "Truck", "Van" but you wouldn't subclass "Car" to create a "Porsche 911 V-Turbo Model 6". Why not? Because the "SportsCar" class has all the aspects to create an instance of a SportsCar that then becomes a "Porsche 911 V-Turbo Model 6".
The other thing you have to consider is that a "Porsche 911 V-Turbo Model 6" would be a highly specialized class which doesn't have any other purpose than to define what that very specific car is about. It wouldn't make any sense to subclass the "Porsche 911" class because it has essentially lost its generic attributes and replaced them with very specific implementation details. If you have a class that you can't reasonably subclass any further, you've created a dead-end in your class hierarchy and are essentially writing functional code, not object-oriented code. Still, it's ok for simple games but it'll come back to haunt you if you dare to do more.
To summarize: you would subclass CCSprite only if your intention is to make a more specialized but still generally useable type of CCSprite. One example for that would be CCLabelTTF, which subclasses from CCSprite. It only adds the ability to create the CCSprite texture at runtime from a font and string. Another example for subclassing CCSprite would be if you needed a CCSprite that would update its texture from Google Maps to resemble a maps tile based on longitude and latitude coordinates and zoom level. It would still essentially be a dumb object whose only purpose is to display a rectangular image at a certain position. That's what a CCSprite is. A dumb object that displays a texture at a certain position.
The question really is about this: is ("is a") your game object a sprite, or does it have ("has a") a sprite for its visual representation? The answer should always be the latter. The common rule for subclassing is the "is a" relationship, in case of "has a" it's time for the composite pattern. If in doubt, and both seem to apply, always err on the "has a" side because that always works.
Why would I say that a game object is not a sprite, but has a sprite? Clearly both are applicable. The answer: the game object "is a" sprite only as long as it can be represented by a single sprite and nothing else. But in fact, your game object might have to be represented by multiple sprites, or a sprite, a label and some particle effects. That means the "is a" relationship is much more likely to break as the app is being developed, and that means additional refactoring work.
By using a CCNode as the base class for your game objects, and adding the visual nodes onto that base node, you can also use the base node as the controller object for the game object's view(s). Which means it'll better conform to the Model-View-Controller (MVC) pattern.
Finally I wouldn't subclass NSObject for anything that should be in the cocos2d view hierarchy, or keeps a reference to something that's in the cocos2d view hierarchy. For the simple reason that NSObject subclasses don't offer any of the standard features of a CCNode (scheduling, adding child nodes, relative positioning of child nodes) and most importantly, it's difficult to use NSObject subclasses together with Cocos2D's rather automatic memory management of node classes.
Without going into detail, the simple rule is that if a subclass has an instance variable that is a Cocos2D node, it should itself be a Cocos2D node so that memory management and all other aspects are easy and foolproof. As far as Cocos2D is concerned, the CCNode class is the root class for the view hierarchy, so it resembles the UIResponder class with the ability to take on the role of the UIView and/or UIViewController classes (both subclass from UIResponder by the way) on occassions.
In short: subclass CCNode, then use composition/aggregation pattern for the visual aspects of the class.
Your question definitely makes sense.
It's fundamentaly an architecture question. If your game is mainly based on "animation", I'd go for subclassing CCSprite. If your game is mainly based on some logic, maybe a RPG or whatever else, then the screen representation is in fact just one of the possible views of the game state. Therefore, it should be, in my opinion, part of an object in the tree of objects that represents your game state.
In other words: if your game state is essentially a scene, then subclass CCSprite, because Cocos2D is probably way better than you at managing scenes. If your game state is "something else", you probably should consider building your own representation of that state, and make your sprite part of your game object. This will also allow you to "switch" graphics engines if you decide to change rendering. For example, you might be doing a RPG with a 2D representation in Cocos2D. After a while, you show your demo to Ubisoft and they fall in love with it and give you 20 million dollars to finish it, but they request a 3D rendering. If you went for subclassing CCSprite, you have to redo all the game. If you went for integrating the CCSprite/CCNode in a NSObject-derived class, you're good to go.
Of course, that example is slightly exaggerated for the purpose of ... example :D
If you have this question at this venture of your Cocos2D journey, subclass CCSprite and be done with it. You will not be creating anything right now that will require the advanced techniques of fine-tuned classes. I say this not as an insult to your abilities, but as a person who once had this question.
When you start to wonder if you need to rewrite the OpenGL method calls of CCNode, then you'll be at a point where you'll need to carefully consider your subclassing options. Subclassing CCSprite grants you all the methods and properties of everything lower, giving you the ability to discover, learn, and move forward.
In short: subclass CCSprite.
in my opinion, object in game is not sprite. Sprite is representation for object, it's mean you need create GameObject subclass NSObject ( maybe CCNode)..
To summarize: subclass NSObject or CCSprite is class structure, you need using your code style.
精彩评论