What is the role of the scene in Cocos2d?
The scene instantiates layers, like for instance a GameEngineLayer, a HUDLayer, etc.
I guess the GameEngineLayer class can be identical between scenes, but there will of cause be different objects in different scenes.
In scene1 there may be one Santa, and one Rudolf, whereas in scene2 there are just two Santa. Shall scene1 instantiate a santa, and one rudolf and pass them in a list of game objects to its instance of the gameEngine? And scene two instantiate two santa following the same pattern?
Shall the scenes also pass a list of events down to their respective gameEngine instance with time stamped events? For instance that santa shall feed Rudolf after a one minute?
Is the responsibility of the scene to do these kind of things?
I've started with a cocos2d/box2d game one week ago, so I'm a beginner. I've read lots of examples, but they usually code everything in a HelloWorldLayer class. :)
Added example:
http://www.raywenderlich.com/4666/how-to-create-a-hud-layer-with-cocos2d
The scene is defined inside ActionLayer.mm. Why?? Why not have Scene1.m that instantiates the ActionLayer?
The only reason why there's a CCScene in cocos2d is because CCDirector requires it as the base class for methods like runWithScene and replaceScene. Other than that, CCScene, CCLayer and CCNode are virtually identical to each other.
You can give scenes, layers, nodes, sprites, etc. any role you want.
But typically the Scene assumes the role of the state manager of the currently active game objects (nodes). A common use case is to declare the scene a singleton so that any child node can access the scene's base methods, for example to send other unrelated nodes messages, or to check if the game is over, and so on.
For propagating events I'm in favor of passing events down, since there's no easy way to pass events up as there is in UIKit. However it depends on what kind of events and what type of design you prefer.
Whether Santa sends a message to Rudolf in order to feed it, or Rudolf frequently asking Santa whether it is has something to eat, is also up to you. There are pros and cons to both approaches.
The reason why many examples instantiate the CCScene object inside the CCLayer class is simply because of that requirement of Cocos2D having to have a scene. Personally I think it's a bad case of a bad example that has become a de facto standard over the years. It would have been better to always create a CCScene class, and inside that create all the layers and other nodes that you want. It would have made the relation between scenes and layers and other nodes more obvious. As it is, there's many many projects out there whose scene class simply does nothing but contain a single layer that runs all the code.
Related
I have a sprite which has a lot of animations to do on different key press events.
For example when i press the right arrow key. It will run the following animations:
Startrun, run, Endrun
While the run cycles depends wether or not the key is still being pressed.
I thought about maintaining some kind of an actions queue, and to have a method that will be called each update and just run those actions in order.
In order to stick to a good design. I thought about a fitting design pattern.
composite? Observer?
What is the best practice here?
Would really like to hear your thoughts or even some examples.
Thanks
Koby
This question is subjective, and every developer will have his flavor of implementation. However I will give my 2 cents about it.
My way (please note the subjective "my" ) would be something like :
Sprite Manager
singleton abstract factory which creates sprites from sprite files
also servers as Object pool of sprites
Sprite
composition of sprite frames and Sprite Animation(s)
Sprite animation
aggregation of sprite frames
GameObject
aggregation of sprite , position and other fun stuff
has an UpdateFunction called on main loop
PlayerObject
derivation of GameObject
state machine implemented in it
LocalPlayer
derivation of PlayerObject
registers as observer to InputManager
RemotePlayer
derivation of PlayerObject
registers as observer to Socket
I am fairly new to VTK and I really enjoy using it.
Now, I want to interact with multiple objects independently. For example, if I have 5 objects in a render window, I want to only move, rotate and interact with the one selected object; whilst the rest of the 4 objects stay where it is.
At the moment, the camera is doing the magic and as I rotate the independent object, other objects move at the same time and I don't want that to happen.
I also want to store all the objects in memory.
I intend to use C++.
This is my sort of class structure...
class ScreenObjects
{
vtkActor (LinkedList); // I intend on using a linkedlist to store all the actors
public:
ScreenObjects(); // Constructor. Initializes vtkActor to null.
void readSTLFile(); // Reads the STL File
bool setObject(); // Sets current object, so you can only interact with the selected object
}
I am missing quite a lot of functions and detail in my class, as I don't know what else to include that would be of use. I was also thinking of joining two objects together, but again, I don't know how to incorporate that in my class; any information on that would be appreciated.
Would really appreciate it if I could be given ideas. This is something of big interest to me and it would really mean a lot to me, and I mean this deep down from my heart.
First of all you should read some tutorials and presentations like this one for example:
http://www.cs.rpi.edu/~cutler/classes/visualization/F10/lectures/03_interaction.pdf
I say that cause it looks like you're currently just moving the camera.
Then you should look into the VTK examples. They are very helpful for all VTK classes.
Especially for your problem have a look at:
http://www.vtk.org/Wiki/VTK/Examples/Cxx/Interaction/Picking
Basicly you have to create a vtkRenderWindowInteractor derived class to get the mouse events (onMouseDown,onMouseUp,onMouseMove,...).
And a vtkPropPicker to shoot a ray from your mouse position into the 3D view and get the vtkActor.
Now you can store onMouseDown inside your vtkRenderWindowInteractor derived class the vtkActor you'd like to move and the currentMouse position. When the user release the mouse (onMouseUp) just get the new mouse position and use the difference of the onMouseDown/onMouseUp positions to modify the vtkActor position.
I am at the start of my cocos2d adventure, and have some ideological questions to ask. I am making a small space-shooter game, am I right to use the following class structure?
Scene
Background Layer
Infinite parallax background
Game Layer
Space ships
Bullets
Control Layer
Joystick
Buttons
and a followup question — what is the best practice in accessing objects from other layers? For example, when the joystick is updated, it must rotate the space ship and move the background. Both of these are in other layers. Is there some recommended way to go about this or should I simply get the desired objects by Tag and operate on them?
Cocos is a big singleton-based system, which may not appeal to some developers but is often used in Cocos apps and is the fundamental architecture of the framework. If you have one main scene and many subsequent layers added to that scene, and you want controls from one layer to affect sprites or logic on other layers, there really is nothing wrong with making your main scene a singleton and sending the information from the joystick layer back to the scene to handle for manipulating other layers or sprites. I do this all the the time and this technique is used in countless Cocos tutorials in books and online, so you can feel that you aren't breaking too many rules if you do it this way (and it's also quite easy to do).
If you instead choose to use pointers in one layer to send data to other layers, this can get you into a lot of trouble since one node should never own another node that it doesn't have a specific parent-child relationship with. Doing so can cause crashes and problems with the native Cocos cleanup methods when you remove scenes later, and potentially leak memory. You could use a weak reference in such a case instead, but that is still dependent on one layer expecting another layer to always be around, which may not be the case.
Sending data back to the main game scene to then dispatch and use accordingly is really efficient.
This seems like a perfectly reasonable way to arrange your objects, this is a method I use.
For accessing objects, I would keep an explicit reference to the object as a member variable and use it directly. (Using tags isn't a bad option, I just find it can get a little messy).
#interface Class1 : NSObject
{
CCLayer *backgroundLayer;
CCLayer *contentLayer;
CCLayer *hudLayer;
CCSprite *objectIMayNeedToUseOnBackgroundLayer;
CCNode *objectIMayNeedToUseOnContentLayer;
}
Regarding tags, one method I use to make sure the tag numbers I'm assigning are unique is define an enum as follows:
typedef enum
{
kTag_BackgroundLayer = 100,
kTag_BackgroundImage,
kTag_GameLayer = 200,
kTag_BadGuy,
kTag_GoodGuy,
kTag_Obstacle,
kTag_ControlLayer = 300
kTag_Joystick,
kTag_Buttons
};
Most times I'll also just set zOrder and tag properties of CCNodes (i.e. CCSprites, CCLabelTTFs, etc.) the same, so you can actually use the enum to define your zOrder, too.
Im in the middle of creating my first iPhone game - I have a background in OOP and in particular C++ so I had some questions with regards to how best to logically setup layers while maintaining functionality.
Currently I WANT for my game to have three main layers:
HUDLayer (All static objects on the screen are here - game controls, User score, pause button etc.)
PlayLayer (The Player, the main game loop and all of the game logic here)
Level Layer (The level images and the level physics objects that the player interacts with, and the background music specific to this level)
Notice I used the word WANT here - because for the life of me im constantly having to move logical objects around just to work within what appears to be Cocos2d's and spacemanagers structure.
Below are just some of the issues that I'm facing
I would like for my PlayLayer to be the scene thats loaded by the director - but if I do that then all of the HUDLayer objects get covered behind the PlayLayer, and dont stay in place like they should, hence the HUDLayer is my scene and I have had to do that just to make it work
I would like to play the background music (via simpleAudioEngine playBackgroundMusic) in the LEVEL layer because I want different levels to have different music. So far the ONLY way I have gotten background music to work is to have it in the TOP most layer i.e. in this case the HUDLayer
Because of the fact that I have to use an instance of the SpaceManagerCocos2d object to create physics bodies - it seems like my level layer has to be killed and just incorporated within my PlayLayer otherwise im having a nightmare of a time attempting to detect collisions between the player and the level.
Am I missing something very obvious here? is there a core understanding of layers that Im just not getting? More and more I feel like im being pushed by the framework to build the whole game inside of a single class and just to use layers as scenes.
Is anyone else having these problems? Am I approaching the architecture of the game wrong? Any help would really be appreciated.
Thanks in advance guys!
Well, each game is different. There are many good discussions on the cocos2d forums about architecture, some people prefer to use an MVC approach, some like using an Actor metaphor to contain physics objects, etc.
Here's my approach:
Use two CCLayer objects (GameLayer and HUDLayer) as child nodes of one CCScene (GameScene). These are the "view" objects.
Create a GameController singleton that can make changes to the game state (also stored in GameController, or in a separate file.) You could also subclass CCScene and call that your controller.
GameLayer is in charge of rendering the graphics of the game level and all actors in it; it also handles getting game input via touch events.
HUDLayer is placed at a higher z-index than the GameLayer and obviously has all of the CCSprite objects for the HUD and buttons.
Interaction between the HUDLayer and the GameLayer is managed via the GameController.
GameController does all of the state changing and game actions.
That's just my approach because it worked for my current game, and it by no means is the definitive answer.
I'd suggest that you look into using an Actor paradigm for your physics objects -- SpaceManager does a decent job, but you don't necessarily always want physics objects to extend CCSprite.
I'm trying to do a small and simple GUI in C++ (with SDL). I'm experimenting with the Composite pattern to have a flexible solution.
I've got a Widget class, with Component objects : for instance, there is a PaintingComponent ; if I want to draw a box, I'll use a PaintingBoxComponent, that inherits from the PaintingComponent.
The ideal Widget class would look a bit like that :
Class Widget
{
private:
vector<Component*> myComponents;
public:
// A small number of methods able to communicate with the component
// without knowing their types
}
My question is simple : what is the best way to activate this component when I need it ?
I first went with a "display" function in the Widget class. But I see two problems :
1°) I'm losing the pure polymorphism of "Compoonent" in Widget, since I'm forced to declare a particular component of the widget as PaintingComponent. I can deal with this, since it's logical that a Widget should be displayed.
2°) More troublesome, I need to pass information between my main programm and my PaintingComponent. Either I pass the SDL_Surface* screen to the PaintingComponent, and it paints the image it drew on it, or I give to my component a reference to the object that need to receive the image it has drawn (and this object will paint the image on the screen). In both cases, Widget will have to handle the data, and will have to know what a SDL_Surface* is. I'm loosing the loose coupling, and I don't want that.
Then, I considered using a "Visitor" pattern, but I'm not used to it and before I try to implement it, I'd like to have your advice.
How would you proceed to have a flexible and solid solution in this case ? Thanks in advance !
If you plan to change graphic system later, you could implement this pattern. Visitor goes to root node, then recursively to all children, drawing them on some surface (known only to Visitor itself). You can gather "display list" with that, then optimize it before drawing (for example, on OpenGL apply z-sorting (lower z first).