Using state design pattern for cocos2d game - cocos2d-iphone

The game I am creating is a word puzzle game. You start out with a menu, where the user decides wether to go single player or multiplayer for instance.
If they choose Single Player then they have the option to play 3 different modes.
Practice
There is no timer
Stress
The player have to do a puzzle within 10 seconds repeatedly, until it deosn't manage to do the puzzle within the 10 seconds and they "die"
Time battle
The player has 2 mins to do as many puzzles as possible.
You see, the actual game play doesn't change but the only thing that changes is how the time is managed.
I read your articles and I found that the State pattern would fit quite nice, and now the only problem I have is how I could implement that pattern.
Should I make sub states as in a menu state abstraction and a game play abstraction or should I just create one universal game state abstraction and then ignore calls like "handleMenuSelection"?
I can't find any good tutorials online covering this in cocos2d. I can find a lot of small demos but it is hard to transform that into a big application when I have never touched a design pattern before besides the OOP design.
Btw. your links was very helpful opening up my mind for new ideas :)

Good to have one singleton class (shared object) that maintains all stats.
Example: Say MyGame is used to store all game stats.
//in MyGame.h
typedef enum
{
kGameMode_Practice = 1001,
kGameMode_Stress,
kGameMode_TimeBattle,
}GameMode;
#interface MyGame: NSObject
{
GameMode mGameMode;
int mHighScore;
}
#property(nonatomic,assign) GameMode gameMode;
  #property(nonatomic,assign) int  highScore;
+(MyGame*)sharedGameObject;
//In MyGame.mm
static MyGame *gGame = nil;
#implementation MyGame
#synthesize gameMode=mGameMode;
#synthesize highScore=mHighScore;
+(MyGame*)sharedGameObject
{
if(!gGame)
{
gGame = [[MyGame alloc] init];
}
return gGame;
}
-(void)saveData //Call this from applicationWillResignActive
{
NSUserDefaults *userDafs = [NSUserDefaults standardUserDefaults];
[userDafs setInteger:self.highScore forKey:#"highScore"];
[userDafs setInteger:self.gameMode forKey:#"gameMode"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
-(void)loadData //call this from UIApplication didFinishLaunchingWithOptions
{
NSUserDefaults *userDafs = [NSUserDefaults standardUserDefaults];
self.highScore = [userDafs integerForKey:#"highScore"]
self.gameMode = (GameMode)[userDafs integerForKey:#"gameMode"]
}
//You can set game mode on selecting menu button
[MyGame sharedGameObject].gameMode = kGameMode_Practice
//To check anywhere in the game
if([MyGame sharedGameObject].gameMode == kGameMode_Practice)
Also save these value at app termination and load same when app starts.
[[MyGame sharedGameObject] saveData];
Based on game mode you can change game play. Use single general class for game play logic and check game mode and do tweak..when u design 3 separate class for 3types then change in one needs to be updated in all files in future..so good to have general code as much as possible.

It's difficult to suggest a good design guideline given that there is very little information. Trying to guess a bit, I would suggest you to read about the Strategy Design Pattern and the State Design Pattern (another link), as it may be suitable for what you are doing, and it would be a clean way to manage multiple game modes.

Related

Implementing "begin contact" in box2d

I am working on a game in box2d. I have the following code:
for (int contact_num = 0; contact_num<contact_count; ++contact_num)
{
if (contact->IsTouching())
{
// get the colliding bodies
b2Body* bodyA = contact->GetFixtureA()->GetBody();
b2Body* bodyB = contact->GetFixtureB()->GetBody();
// check if one of the colliding objects is a censor
bool sensorA = contact->GetFixtureA()->IsSensor();
bool sensorB = contact->GetFixtureB()->IsSensor();
// do stuff, mainly handling variables
}
}
// Get next contact point
contact = contact->GetNext();
}
All of this is being called in the update function of my main class (which also contains most of the games variables). The problem is that I want the code to only be called when the two objects first collide, because otherwise something like score++ will end up skyrocketing in value as it gets updated for the collisions duration. I am aware of a "contact listener" class in box2d with the function "begin contact", but there is no good documentation that could help a beginer learn how to implement it. For example, if I add a contact listener to my main class, how do I get it to handle my score, for example, if the contact listener doesn't have access to those variables? Or where do I call "begin contact" in the first place? Sorry if these are obvious questions, but i was hoping someone could clarify these. Thank you in advance.
Here's a couple suggestions which hopefully will answer your question:
Take a look at Box2D C++ tutorials - Collision callbacks. Personally, I think it's a great tutorial on using the b2ContactListener class.
Just make your class which contains the score information inherit from b2ContactListener. That way your BeginContact method will have direct access to the score data. Presumably that'll be your "main" class. Be sure to also notify your b2World instance to use this by calling your world instance's SetContactListener method with a pointer to the score containing instance (that you'd subclassed from b2ContactListener).
If you still need more help with this, please add a comment to that effect or update your question to reflect what remains unclear.

Avoid type checking when function dependant on two distinct classes

I'm trying to code a game hub of sorts that is basically a collection of board games or games that can be easily played at the command line. (Tic Tac Toe, Connect Four, etc.) The user also has the option of making any of the two players computers. If I were making only Tic Tac Toe this wouldn't be an issue since I could just have "move" implemented in the human and computer subclass of Player and then invoke the correct one polymorphically, but with the addition of other games I'm not sure how to get away from type checking. For instance, if move is a function within player, how else other than through type checking would the function know whether to move according to the rules of Tic Tac Toe or Connect Four?
I was toying with the idea of having a separate move class with different subclasses for each scenario but I'm not sure if that's correct or how to implement it.
This is being written in C++ by the way.
If you want all games to inherit from the same game_base base class, then you need people who use these games to not "know" which game they are playing.
What do I mean? You asked
For instance, if move is a function within player, how else other than through type checking would the function know whether to move according to the rules of Tic Tac Toe or Connect Four?
Let me ask you this instead - say you did solve this problem like you described it. Now you want to add a new game (say, checkers). Will you need to change player to know how to play checkers?
If so - then your games shouldn't use inheritance (shouldn't all inherit from game_base
Why? Because basically you're saying "my player class has to have built-in all the possibilities of all the games". If that is the case, why have different games classes?
As a solution I would say something like this:
How would the human player class if it needs to move according to tic-tac-toe or connect-four? The GAME class should tell it! More than that - assume the player doesn't know the game at all! TELL the player what are the current legal moves!
An example:
class game_base{
// returns the number of players in this game.
// Doesn't change during play
virtual int num_players() = 0;
// returns the current player - the player whose turn it is now
virtual int curr_player() = 0;
// returns a string that describes (or draws) the current
// game state
virtual std::string draw_board()const = 0;
// returns all the possible legal moves the player can
// make this turn
virtual std::vector<std::string> curr_turn_possible_moves()const = 0;
// Plays the given move. Has to be one of the moves
// returned by curr_turn_possible_moves()
virtual void play(std::string move) = 0;
// returns the player who won the game, or -1 if the
// game is still ongoing
virtual int won() = 0;
};
See how you can use this game class in a way that the same player class can play all games you'd ever make!
You can even make a "check all option up to N levels deep" computer player that will work with every game!
About the computer player: You can make a "generic" computer player that tries to go N steps forward to look for a winning strategy (you need to add the option to virtual game_base *copy()const the current game state). But in reality you would need a computer player tailored for each game (that only plays that game).
So how do you do that? More importantly - how would you know which computer player to select for each game?
All computer players will inherit from a computer_player_base class (that probably has only one function play that plays the next move given a game). The trick is - if you now want to add a new computer player for a game (either for a new game, or another possible computer player for an existing game), you need a way to "register" that player. You want something that would look like:
std::vector<computer_player_base*> possible_computer_players(const game_base*game);
that returns all the possible computer players that know how to play the given game. The easiest way to do that - is to have the computer player class itself tell you if it can play the given game. So it would look something like this:
class computer_player_base{
// return true if this class knows how to play this game
// implemented using dynamic_cast - something like this:
// return dynamic_cast<connect_4*>(game) != 0;
virtual bool can_play(game_base *game) = 0;
// plays the next turn of the game
virtual void play(game_base *game) = 0;
};
Then have, e.g., a global list of all computer players to choose from
std::vector<computer_player_base*> all_computer_players
that you will fill with one of each computer player, and a function
std::vector<computer_player_base*> possible_computer_players(game_base *game)
{
std::vector<computer_player_base*> res;
for (auto p:all_computer_players)
if (p->can_play(game))
res.push_back(p);
return res;
}
How about this:
enum GameType {
TicTacToe,
ConnectFour,
SnakesLadders,
Battleships,
};
And then store GameType gt inside the game-playing object you are using. Then do a switch(gt) inside each method.

How to implement a game-loop with C++ and QtQuick

I'm developing a game with QtQuick 2 (Qt5.2) QML and C++. I want most of the game-logic in C++ (I don't want to do it with JS), and I'm trying to use QStateMachines for a lot of the logic.
Now my question is, how do I implement a proper game-loop in that scenario?
The game has for example objects that are moving from and to certain waypoints on the screen, so I think I can't do everything state/event-based. At some point I need to say "my object should move 10 pixels in direction x every second". So for example when my object is in its state "moving", it should move by a certain amount every second and then of course check for some conditions if it has to switch the state (e.g. to "attacking").
Now all the demos in the Qt-examples and on the web seem to be either fully event-based (e.g. four-in-a-row-wins-like) or written in JavaScript. So I am a bit lost here.
One idea I could find was to create a QTimer with a timer of e.g. 30ms and connect that QTimer's timeout() signal to an advance() slot of every moving object, and start that timer before 'return app.exec();'. Like this:
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance()));
timer.start(1000 / 33);
return app.exec();
and then each object (e.g. the Mouse) has a
void Mouse::advance(int step)
However, this requires a QGraphicsScene and I'm not sure how well that goes with a QtQuick/QML project on Android/iOS.
Is that a good solution? Or is my view of the problem somehow wrong and I don't need a game loop to accomplish my goal?
The solution shouldn't use any desktop-only stuff from Qt, i.e. it should work on Android, iOS and desktops.
That's the way to go: QTimer. Here you find some detailed example on it:
A typical loop for game in Qt:
int main(int argc, char* argv[]) {
// init stuff
while(game.isRunning()) {
a.processEvents(); //(a is a QApplication created during the init, should use a better name i guess)
QTime currentTime= QTime::currentTime();
int timeSinceLastUpdate = lastUpdate.msecsTo(currentTime);
while(timeSinceLastUpdate>updateTimeStep){
game.update();
timeSinceLastUpdate-=updateTimeStep;
lastUpdate=lastUpdateaddMSecs(updateTimeStep);
}
renderer.setInterpolateFraction(static_cast<float>(timeSinceLastUpdate)/static_cast<float>updateTimeStep);
renderer.renderGameObjects();
renderer.renderGUI();
renderer.swap();
}
a.exit();
return 0;
}
Source: Game loop in Qt
Making a Simple Game Loop with QTimer
Qt as a game engine
That's should be enough info for you to get started.
Usual game loop of simple game can look like this (not sure if I understand you correctly though).
Each class that represents game object have 2 public methods: update(); and render();
On each call of QTimer object you iterate over all game objects and call their update method. After it you repeat the same for render method();
In update methods each object decides what to do on game map (move/shot/stand/...) and changes its coordinates/properties. In render methods each object just draws itself on display.

Callbacks and the main game loop. Is it a good practice?

I'm writting a game using C++. I wonder how can I optimize my game loop. For example, we have some game with the main loop looks like this:
while ( gameContinue ) {
if ( SCENE == HELP_SCENE ) {
renderHelpScene();
} else if ( SCENE == SCORE_SCENE ) {
renderScoreScene();
} else if ( SCENE == MAIN_GAME_SCENE ) {
renderMainGameScene();
} // .... and many others scenes
}
I'm thinking on how to make this code faster and lighter. I think about using callbacks so we will not need many if-cases. Something like this:
typedef void (*callback_function)(void);
callback_function renderFunc;
void renderMainGameScene() {
renderFunc = renderScoreScene(); // set to another scene if we need this
}
void renderScoreScene() {
renderFunc = renderAnyAnotherSceneWeNeedNow();
}
renderFunc = renderMainGameScene();
while ( gameContinue ) {
renderFunc();
}
What do you think about it? How do you organize your main loops?
I've personally started using multi-threading. I have a thread for object updates, a thread for objects collision and a thread for drawing. Each thread loops with a while (GetMessage()) and threads send messages from one to another.
At each cycle (frame), my main loop sends a message to each thread to:
Calculate collision for modified objects
Update objects (movement, state etc.)
Draw the updated objects
That's how I do it (at least on my GDI/GDI+ games). Not sure if the best way, but so far it works like a charm :).
Helpful patterns for this kind of problem are the State Pattern and the Strategy Pattern.
As you can see they are both similar. The Strategy pattern is a bit simpler than the State, but in exchange the State Pattern is more powerful and probably better fitted for a game engine like this. You can also easily create a stack with this for example: game start -> menu -> game run -> menu.
If the parent state of the last menu is game run, the menu would look different (e.g. "Return game" instead of "Start game" in the first menu). The states can be popped and you have a easy navigation.
Using call-backs should be fine. Just be careful not to have any cyclic dependencies in your headers. Notably it's a bad idea to include the header for your controller loop anywhere other than the .cpp for the controller loop.
As for the runtime benefits, they are very small. The if-else method will not noticeably slow down your game. Alternatively, there is also the switch statement, which is preferable to a series of if-else statements in terms of code readability.

Cocos2d with ARC: what is the best implementation of singleton pattern for GameScene when having multiple levels?

EDIT: I am using ARC
In my code (based on the ShootEmUp example in this book, which I highly reccomend, source code in chapter 8 available here) I often use the trick of accessing the GameScene via:
+(GameScene*) sharedGameScene;
which returns a reference to the static instance of GameScene and is used by all children of GameScene (e.g. ShipEntity, InputLayer.. etc..) to dialog with GameScene (EDIT: aka singleton instance of GameScene).
To create multiple levels I thought of implementing a method calledsceneWithId:(int) method where I load different level data each time.
EDIT: Code snippet of init method:
-(id) initWithId:(int)sceneId
{
CCLOG(#"scene With id");
if ((self = [super init]))
{
//All common initialization happens here..
switch (sceneId) {
case 1:
[self loadFirstLevelData];
break;
case 2:
[self loadSecondLevelData];
break;
default:
[self loadSecondLevelData];
break;
}
//Other common stuff..
[self setUpCounters];
[self setUpWeaponsMenu];
[self scheduleUpdate];
[self schedule:#selector(timerUpdate:) interval:1];
InputLayerButtons* inputLayer = [InputLayerButtons node];
[self addChild:inputLayer z:1 tag:GameSceneLayerTagInput];
}
EDIT: Is that init method ok? I have found this post which uses dispatch_once. Should I do the same?
Or should I pheraps create a GameScene class and then sublcass it?
E.g. FirstGameScene : GameScene
EDIT: I have followed the advice of #LearnCocos2D and used the cleanup method, and I used it to stop a singleton object music layer to play (the MusicLayer object is initialized in AppDelegate and I meant to use it to "manage" the music across all scenes - the problem was that without stopping it in dealloc it would have kept playing the music that was loaded at init time).
-(void) loadFirstLevelData{
//HERE WILL LOAD ALL SPECIFIC ELEMENTS: ENEMIES, BONUSES etc..
//AS WELL AS THE MUSIC FOR THE LEVEL
[[MusicLayer sharedMusicLayer] _loadMusic:#"1.mp3"];
[[MusicLayer sharedMusicLayer] playBackgroundMusicFile: #"1.mp3"];
}
-(void) cleanup
{
//Should I remove all child loaded in LoadLevelData??
CCLOG(#"cleanup GameScene");
[[MusicLayer sharedMusicLayer] stopAllMusic];
//MusicLayer is not a child of GameScene but of AppDelegate - the idea is to keep loading and unloading music files - sometimes I need to keep playing the file between scenes and hence I used the singleton pattern for this as well..
[super cleanup];
}
But I still have some doubts:
Is it ok to have several loadLevelData methods in GameScene class? Each method can be 200 lines long! I tried to sublcass GameScene but is a bit messy. I explain better. I imported "GameScene.h" in the header file of the subclass and by doing so I expected that if I had ovverriden only certain methods (e.g. init) I would have been able to see the various classes imported in GameScene (e.g. InputLayerButtons). It is not the case. So I probably don't understand how imports work in Objective-C
Is it ok to remove specifc children in the cleanup method? I thought that I would remove all child that are added in the LoadLevelXXXData method to reduce the memory usage.
I have set a bounty for this question but I will probably need to test the answer and re-edit as I don't have a clear enough understanding of the subject to be super precise in the question. Hope is ok.
PS: Would be great if someone would feel like sharing a UML style diagram of a Cocos2D Shooter Game where with various levels and GameScene using singleton pattern :).
I'll focus on the questions on the bottom:
Is it ok to have several loadLevelData methods in GameScene class? Each method can be 200 lines long! I tried to sublcass GameScene but
is a bit messy. I explain better. I imported "GameScene.h" in the
header file of the subclass and by doing so I expected that if I had
ovverriden only certain methods (e.g. init) I would have been able to
see the various classes imported in GameScene (e.g.
InputLayerButtons). It is not the case. So I probably don't understand
how imports work in Objective-C
There's nothing wrong with having long methods. However I suspect your loading methods perform very similar routines, so you should check if you can generalize these into subroutines. A good indicator is if several lines of code are absolutely identical except for the parameters or variable names. The best practice is to write identical code only once, and execute it many times with varying parameters.
The #import statement is used to allow the compiler to "see" other classes. Without importing other header files, you couldn't use that class' methods and properties without the compiler complaining.
2 . Is it ok to remove specifc children in the cleanup method? I thought that I would remove all child that are added in the
LoadLevelXXXData method to reduce the memory usage.
It makes no sense to remove children during cleanup. Cocos2D removes all children during cleanup automatically.
If that does not seem to be the case for you, you have a retain cycle somewhere that prevents child nodes from deallocating.
sorry for answering this but I have been experimenting and decided to:
not use the singleton pattern for GameScene
use, insteada a singleton object to keep all shared data
My implementation draft for the GameScene (now called ShooterScene) is the following (I followed some advices in a cocos2d-iphone forum post as well as this other one ):
#import "ShooterScene.h"
#import "LevelData.h"
#import "HudLayer.h"
#interface ShooterScene (PrivateMethods)
-(void) loadGameArtFile;
#end
#implementation ShooterScene
+ (id) sceneWithId:(int)sceneId
{
CCScene *scene = [CCScene node];
ShooterScene * shooterLayer = [ShooterScene node];
[scene addChild:shooterLayer];
[shooterLayer loadGameArtFile];
LevelData * levelData = [LevelData node];
[shooterLayer addChild:levelData];
switch (sceneId) {
case 1:
[levelData loadLevelDataOne];
break;
case 2:
[levelData loadLevelDataOne];
break;
default:
break;
}
HudLayer * hud = [HudLayer node];
[hud setUpPauseMenu];
[shooterLayer addChild:hud];
return scene;
}
I am using the update method of ShooterScene to manage the all the game events (E.g. spawning, checking collisions, moving the background layer). I haven't put the full implementation here as is still work in progress, but is just to have an idea of the type of answer I am finding useful.