Should I subclass CCSprite, CCNode, or NSObject? - ios

I see that certain texts always seem to subclass CCSprite. I read somewhere that 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.

Related

UIDynamicItem with non-rectangular bounds

So I'm looking into UIKit Dynamics and the one problem I have run into is if I want to create a UIView with a custom drawRect: (for instance let's say I want to draw a triangle), there seems to be no way to specify the path of the UIView (or rather the UIDynamicItem) to be used for a UICollisionBehavior.
My goal really is to have polygons on the screen that collide with one another exactly how one would expect.
I came up with a solution of stitching multiple views together but this seems like overkill for what I want.
Is there some easy way to do this, or do I really have to stitch views together?
Dan
Watch the WWDC 2013 videos on this topic. They are very clear: for the sake of efficiency and speed, only the (rectangular) bounds of the view matter during collisions.
EDIT In iOS 9, a dynamic item can have a customized collision boundary. You can have a rectangle dictated by the frame, an ellipse dictated by the frame, or a custom shape — a convex counterclockwise simple closed UIBezierPath. The relevant properties, collisionBoundsType and (for a custom shape) collisionBoundingPath, are read-only, so you will have to subclass in order to set them.
If you really want to collide polygons, you might consider SpriteKit and its physics engine (it seems to share a lot in common with UIDynamics). It can mix with UIKit, although maybe not as smoothly as you'd like.

How to define child stages in ActionScript?

This is not really a programming question, so please let me know if I should move it somewhere else.
I want to know if there is a way to define a -parent- object (like a Panel, or a Stage inside the main Stage) that contains various elements (like TextFields), so that I can Show/Hide the parent object, and all the contained elements will be affected?
So I'm asking C#'s Panel equivalent in AS3.
Thanks !
In terms of classes that you can instantiate (ie, not abstract or base classes), you'll want either Sprite or MovieClip (as noted in your comment) ... but note that MovieClip extends Sprite, so it's best to use a Sprite unless you have a special reason not to. There is a good article on AS3 display-list programming here.
You can have a Sprite that's the child of another Sprite object. The hierarchy is unlimited. If at any level of the heirarchy you do visible = false, all the child objects in the hierarchy will also not be displayed. If you do removeChild() on an Sprite, all it's child objects will also be removed. Same thing applies for matrix transformations. You can of course, inherit from Sprite and continue the same pattern.

An iOS game using MVC, should the model has objRect while keeping its UIViewImage object in the ViewController?

A game on iOS is using this: there is a metal ball, and the ballRect is a property of the Model class, but the corresponding ball which is a UIImageView object, is a property of the ViewController class.
Can this design be made so that both ballRect and ball are properties of the Model class? In other game sample, I see only 2 properties of the ViewController class: the model object and a timer object. That's it. I wonder why this time, there are extra properties that become the ViewController class and should they go to the Model class?
It would make more sense to make a BallView that holds a pointer to a Ball (Model) and hosts an image view that shows the ball sprite. The BallView should observe the Ball's ballRect, and when that changes, update its (the BallView's) frame to match.
This arrangement would let you add other, similar relationships. For example, if there are different kinds of balls and a ball can change from one kind to another (e.g., for a temporary power-up), the BallView can observe the Ball's kind and change the image view's image whenever the Ball's kind changes.
I wrote an article on gamasutra for applying the MVC pattern in games.
It is coded in C++, but you can easily transfer the concepts to any other language.
I hope it is of use for you.
http://www.gamasutra.com/blogs/IvicaAracic/20100919/88083/Applying_the_ModelViewController_Pattern.php
Regards,
Ivica

UIView animation vs CALayers

I'm struggling with conceptualizing animations with a CALayer as opposed to UIView's own animation methods. Throw "Core Animation" into this and, well, maybe someone can articulate these concepts from a high level so I can better visualize what's happening and why I'd want to migrate UIView animations (which I'm quite familiar with now) to CALayer animations on the iPhone. Every view in Cocoa-Touch automatically gets a layer. And, it seems, you can animate one and/or the other?!? Even mix them together?!? But why? Where's the line? What's the pro/con to each?
The Core Animation Programming Guide immediately jumps into Layer & Timing Classes and I think need to take a step back and understand why these varied pieces exist and how relate to each other.
Use views for control and layers for eye candy. Layers don't receive events so it's easier to use a view for those cases, but when you want to animate a sprite or backgrounds, etc., layers make sense. Events pass right through layers to the backing view so you can have a pretty visual representation without messing up your events. Try to overlay a view that you're just using for visual representation and you'll have to pass tap events through to the underlying view yourself.
An UIView is always rendered to a CALayer. When you use UIView methods to animate a view, you are effectively manipulating the underlying CALayer.
If you need to do simple things, use the UIView methods. For more complex situatins, or if you want layers not associated with any view in particular, use CALayers.
I've done a bunch of apps in the past year. Here's my rule of thumb:
Use UIView until it doesn't do what you want.
Then move to CoreAnimation. But before you get into it too much...
If you write more than a few animations, use Cocos2D.
UIView transforms are only 2D and are restricted to that, LAyer transforms however can be 3D and you should use those if you want to do 3D stuff, UIView animation will work if you change either the UIView transform or the CALayer transform. So at a basic level, you can do a lot more manipulation when you are working with a Layer rather than the View.
I am not sure if I am misunderstanding Chris' response to "What's Cocos2D doing better? Don't you have other problems then, regarding the touch event handling and many other stuff that misses in openGL ES?"
It sounds like the answer suggests Cocos2D is not based on the OpenGL ES framework when in fact it actual is. While it is a great 2D game engine it does implement OpenGL for much of it's rendering - attached to a physics library it allows for a lot of very interesting possibilities for animation - and Chris is correct - it is a lot less coding indeed.

XNA project - who is in charge of drawing?

I am just playing around with XNA, and I have several different models I need to draw in each frame.
at the moment, the Game object holds references to all my models, and draws them one after the other. Each with his own different way of drawing - one has two separate textures, the other might be mirrored to the other side, etc.
I was wondering if it is acceptable to just add a
public void Draw(SpriteBatch spriteBatch)
method to all my models (from the BaseModel, of course), and have each class be in charge of drawing itself, or maybe I should stick to letting the classes set their data according to events (KeyboardState) on the Update method, and keep all graphic logic in the Game class.
Is there a preferred way to do this?
Generally, I have a base class that contains a BaseModel, texture data, rotation and scale data, etc. For each type of actor in the game, I create a derived class. The base class provides a Draw method that, by default, draws the model with the texture, rotation, and scale data given in the class. Derived classes can override it to draw the actor however they like.
Then, I have a DrawableGameComponent that acts as my scene graph. It contains a list of all active actor objects. In the component's Draw and Update methods, I iterate through the list of actors and call their Draw and Update methods.
That's one way of approaching it ... for the sake of completeness in this post, I'll highlight the other approach. Basically, the opposing view states that no one entity should need (or have) custom knowledge of how to render itself. An entity is merely a collection of state ... and the renderer can simply look at that state, and draw it in the correct way.
An example ... say you have a number of ships. Some go fast, some shoot rockets, some have a sattelite orbiting around it that also shoots. Your "Entity" class can have the following properties
Model VisualRepresentation
Matrix Position
Entity[] AttachedEntities
Your renderer can then iterate over your generic "List<Entity>", and
Draw the visual representation (ie. Model) of the entity using the position
Loop over the AttachedEntities and draw them (recursively).
It's obviously a simplified example ... but this way the drawing logic is completely contained in the rendering code, and only needs to concern itself with as little amount of information as possible. While the ship class can focus on the game logic itself (ie. how fast do I fly, what weapon am I using, how much energy do I have in my shields, etc.).
As far as which one is preferred, really the answer lies within your project's requirements, and what you feel comfortable with. Don't try to make a game engine before making a game ... just do whatever it takes to make your game, and then maybe you can extract the components that worked after you ship the game :-P

Resources