XNA project - who is in charge of drawing? - xna

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

Related

TPlane versus TImage3D?

I have an DelphiXE4 application made with FMX.
I want to have flat textured objects (no thickness) where I can zoom and move the whole scene on the screen.
(hint : Think about pictures on a wall)
I started with a TForm3D to implement TImage3D components with bitmap assigned. It works well!
BUT I've tested with the TPlane component, I can do the same thing and achieve the same result.
The question is : What is the difference between these 2 components TImage3D & TPlane ?
This will help me to choose the right one for my - current and further - needs.
FMX documents and wiki doesn't really help here !
The best way to think about these things is to look at the inheritance path.
TImage3D derives from TAbstractLayer and so it can generally be used like a 3D layer. TAbstractLayer derives from TControl3D but also implements IAlignableObject and IAlignRoot.
TPlane derives from TCustomMesh which derives from TShape3D which also comes from TControl3D.
I guess in brief a TPlane is simply a specific 3D shape - I haven't poured through the FMX source code but I would guess that it must be more lightweight than TImage3D. A TPlane is just a flat surface that can be manipulated in 3D space.
A TImage3D, however, by means of IAlignableObject, etc, has access to a number of built-in methods and features that allow it to interact as a 3D UI object - to align itself to other IAlignableObjects, to define margins, bounds, and anchors, etc, to define how it places itself in, or fills, space with respect to other IAlignableObjects.
Which to use depends on what you are doing. If you want the image to be a part of a 3D scene, then TPlane probably makes most sense. If you want it to be part of a 3D UI; that is to say that the image is part of a 3D space with other controls, user-interface elements, etc, then TImage3D probably makes most sense.
A TImage3D may not have access, at the same time, to certain methods that operate on TCustomMesh - a TImage probably doesn't expose its mesh (ie: can't be generically modified by 3D transforms, etc, where the input must be a TCustomMesh), while a TPlane, being a 3D primitive rather than a locked-down UI control, would be rather more malleable in that regard.

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

XNA Resizing Model Inside a Model

I have created a XNA game background as a model, but it contains more models inside. For example: "ground contains a ball". Now, what I want to do is go inside the Ground and retrieve the ball and resize it.
Is there a possibility of doing this or do I need to import ground and ball separately and then resize it (I would prefer this to be the last option)?
I think what you mean is that you want to scale a specific ModelMesh inside a model. This can be done using a Matrix array, which will contain transforms specific to individual meshes. Something like this:
//In the class for the background, or the game class if there isn't one
Matrix[] specificTransforms;
//Initialize the array however you want, and assign the specific matrix for the ball to its corresponding index
//Loop through the meshes like usual but add this below your code that multiplies the transform matrices:
if (specificTransforms[(put your iterator variable here)] != null)
{
(put your BasicEffect here).World *= specificTransforms[put your iterator variable here];
}
This will combine the world matrix for the mesh with the specific transformation that you want to apply to the ball.
This is not the best way of doing it, and it would be easier to give you an example if you post the code that you're using. Unless you do that, there is no guarantee that this will work.

Retrieving path segments from ID2D1PathGeometry

I'm currently trying to write a little game engine in C# using SlimDX just for fun.
I want my world to be destructable, so I have to be able to modify my map. My map is currently vector based, represented by an ID2D1PathGeometry (PathGeometry in SlimDX) object. This object is modified, using the CombineWithGeometry method of ID2D1Geometry (Geometry in SlimDX).
For reasonable collision detection, I need knowledge about the exact shape of my ID2D1PathGeometry object, for instance for calculating angles of balls bouncing of the walls.
So, is it possible to access all or specific (per location) segements/lines/points of my ID2D1PathGeometry object? Or are there other, better ways to accomplish my goals, e.g. storing all lines and shapes additionaly in another data structure?
Please note that bitmap based maps are not the way to go here, since I don't want to have memory as a constraint on the map size.
with best regards, Emi
There is no way to retrieve just the geometry segments that are close to a certain point, but there is a way to retrieve all geometry segments.
Implement a class that inherits from ID2D1SimplifiedGeometrySink.
Create an instance of that class and pass it to ID2D1Geometry::Simplify.
More info and example are here How to Retrieve Geometry Data by Extending ID2D1SimplifiedGeometrySink
If you are interested in retrieving only portion close to a certain point, perhaps you'd like to:
Create rectangular geometry surrounding the point of interest.
Intersect it with your geometry via ID2D1Geometry::CombineWithGeometry using D2D1_COMBINE_MODE==D2D1_COMBINE_MODE_INTERSECT.
Get sink of the intersected geometry using the method above.
More info: ID2D1Geometry::CombineWithGeometry method

Should I subclass CCSprite, CCNode, or NSObject?

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.

Resources