I'm creating a game using Cocos2d-x. I'm currently creating a gameover menu, in that menu I need to be able to switch to both my menuscene and my gamescene (When I say switch to gamescene I only really only mean "to restart" the game). But circular dependencies stop me from being able to do this.
MenuScene needs to be able to useGameScene::create() in order to switch to the gamescene and the gameover menu needs to be able to use both of GameScene::create() or its restart funtion and MenuScene::create() which is giving me circular dependency problems
I can't separate my gameover menu to it's own file as I still need the GameScene dependency and GameScene would need gameover.
I can't combine them as GameScene then needs to depend on MenuScene
So my question is: How do I alternate between two scenes in cocos2d-x c++.
I read somewhere about pushing and popnig scenes in Director, but I don't really understand how that works, or if I could use that for my purpose.
Thank you in advance!
EDIT:
Now that I think about it, could I not just push mMenuScene to Director before switching to GameScene? That should work if I understand that push/pop mechanic correctly.
I think you might have a misconception of how complex this is, using the way I provided below you can and should definitely split your game over scene into its own file.
The scene replace is easy enough, just use the code below:
Including your file:
#include "MainGameScene.h"
Creating and switching scenes in your onClickListener:
auto gameOverScene = GameOverScene::createScene();
// use code below for hard replace
Director::getInstance()->replaceScene(gameOverScene );
// or use code below for transition fade replace
Director::getInstance()->replaceScene(TransitionFade::create(1, gameOverScene , Color3B(255, 255, 255)));
As for the restart functionality. I usually provide a callback to my game over scene that I call when the restart button has been clicked. Not that I ever swap out my scene completely for a mobile game over scene, but I still do it the same way regardless. So lets do steps (This assumes you seperated your game over scene into it's own file named GameOverScene :) ).
Store a function pointer in your GameOverScene.h to your reset method in MainGameScene:
std::function<void()> _resetCallback;
Set your function pointer from the main game scene, before running with the GameOverScene.
auto gameOverScene = GameOverScene::createGameOverScene();
gameOverScene->setResetCallback(std::bind(&MainGameScene::reset, this));
When your reset button is clicked, call the _resetCallback
void GameOverScene::onResetClicked(Ref* sender)
{
_resetCallback();
}
This should provide you with all the functionality you need to set up a what you want as well as remove the circular dependency that you have. I have used this way many times before and it always works. Let me know if this solution works for you.
Related
So I've been learning how to program so I can make games, and, therefor, I've been reading and watching many tutorials. Every once in a while, I'll come across code (c++) that uses a class to handle game events, but nobody has explained why they do this.
It also seems like some programming languages, like C#, automatically use a class for the program's "main."
So what I want to know is if I should be using a class for my game. Why and/or why not?
Here's an example of what this might look like:
class GAME
{
public:
void load_resources();
bool input();
void update();
void draw();
};
int main ()
{
GAME game;
while (!quit)
{
quit = game.input();
game.update();
game.draw();
}
return 0;
}
Thanks for reading.
In terms of game engine design we have something called a Scene system.
A scene normally hold all the GameObjects.
When you send the scene an event it should iterate on the gameObjects and update them all with events (update start end render postrender keyboard mouse scroll resize etch).
But in a much much simpler form of the system we at least want a game class so we can reload the level.
For example when the user enters the game it may take us a min to load all the models and textures and scripts from memory so we dont want it on our main loop we may want to load async and show a loading screen in this case we'll construct the game on another thread.
Or when the user wins and go to the next level we can unload the last level so we simply destroy the Game/Scene and create a new one of the new level.
In short: this kind of approach is used to define states of our application and manage them easily
I've been going in circles for a day now trying to get this going and I'm just getting nowhere. I'm trying to have multiple objects in the scene with individual animations and when I fire a raycast from my player and it hits one, have the UFunction(blueprintimplementableevent) go off on the object that it hits. Please help me this is absolutely stumping me.
What I would do is use a BlueprintNativeEvent. This will allow you to create an Implementation function of the stuff you want to happen in C++, as well as a blueprint implementation, which can be different for each blueprint of that object type.
It is quite simple to use as well, for example, in your character's header file:
/** Called when the player presses the fire key */
UFUNCTION(BlueprintNativeEvent, Category = "Shooting")
void OnHit();
virtual void OnHit_Implementation();
And now your Cpp:
void AMyGameCharacter::OnHit_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("OnHit_Implementation!"));
// Do whatever stuff you want to do in C++ here
}
Now over in your character / actor blueprint, just go to the event graph, right click, and add the event of type OnHit. Make sure that you make a callback to the parent OnHit event though (right click on the event and hit "Add Call to Parent Function")
If you want an example of this you can look at the C++ Battery Collector series or the docs.
My project needs so many buttons. But for each button I make, it has to load every images even though I make same buttons like this :
auto btn = cocos2d::ui::Button::create("images/bone01.png","images/bone02.png","");
I think it's very wasteful in respect of system cost. I want to make only 1 texture2d* and use it when making buttons. I searched many times with keyword, 'cocos2d-x button texture...' but there is no answer I could find. Is there any method to use texture in creating Button, or should I make a class inherited by Sprite class which contains touchEventListner and function parameters? if so, how can I start to create function to use method like this :
btn->addTouchEventListener(CC_CALLBACK_0(HelloWorld::touchBoard, this));
just a little example would be okay to me.
=============================================
I made a singleton Class and put all Buttons, and tried to use it when it's needed. But failed because Button is autoreleased when it is created, so if I use it another cpp, like :
auto appleBtn = DataClass::getInstance()->_appleBtn;
an error occurs like this :
Expression : child->_parent == nullptr
I may succeed in this way by using retain() & release(), but I would rather to use safer way.
Although I do not have any experience with cocos2d, I assume it will load this texture in memory only once, and use this information for all buttons. Isn't it possible to make a button class and inherited all the same buttons from this class? Again I have no clue how cocos2d works but any other game engine this should be possible :)
Below is what I came up with. Wonder if there's easier way to do it.
Suppose I want only menu layer to be touchable while it's up.
I put invisible layer that will swallow touches.
bool tNoTouchLayer::init()
{
if(!CCLayer::init()) {
return false;
}
setIsTouchEnabled(true);
return true;
}
void tNoTouchLayer::registerWithTouchDispatcher()
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}
bool tNoTouchLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
return true;
}
Now I can add the noTouchLayer before adding menu layer, and all touches would be stolen by noTouchLayer.
Lastly, i did find more info on this:
http://code.google.com/p/cocos2d-iphone/issues/detail?id=1033
the reason that menu items are stealing touches is because menu items have their touch priority set to the highest (lowest char value) possible...
you can change kCCMenutouchPriority to be 0 instead.
That's how you do it as far as I can tell. Note however that your code will not disable any menues added to the scene. To do that you have to remove the menu from the touch dispatcher when adding the popup and add it back again when removing the popup.
To remove a menu from the touch dispatcher you can do the following:
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(menu);
and to add it back you can do this:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(menu, kCCMenuHandlerPriority, true);
where menu is your CCMenu node.
As a tip, I created a class like the one above but I also added the popup menu to it, creating one touch blocking menu in one node. :)
this isn't exactly the answer you are looking for, but here's something up for thought:
if you're trying to do this for a pop-up, would it be possible to try to pop up a subclass of UIAlertView (one that looks the way you want it to)?
http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-uialertview-custom-graphics/
Here's another approach:
keep state of the app and which layer is "on top".
in each of your menu listeners, have them all do a check to see if the state of your current layer should allow for that menu button to be pressed.
also, you can override "addchild" to see if it's a MenuItem, and if it is a MenuItem, then have it check to see if it should be enabled. if not, return immediately instead of executing the rest of the code
If I understand your question correctly, I guess you try to do something like "pause screen" to pop up and disable all other layers.
Well, you said in your comment that you won't like to enable touch event in other areas but not your pop-up's area. Basically, I would think we should think in term of layer for easier understanding, and easier to implement.
Let's see if we have "main layer" which holds other game objects to show as its childs (assume that they also are running animation). Now you touch a button and want to pop up "pause layer". You have to do the following in order to disable all touch event from others layer + objects.
Pause layers' schedule and actions [via pauseSchedulerAndActions()]
Pause all of its game objects inside the layer (ie. enemies) [via pauseSchedulerAndActions()]
Disable CCMenu object (if any), this will ignore touch event on CCMenu related object ie.CCMenuItemImage [via setEnabled(false)]
Disable touch event for layer itself [via setTouchEnabled(false)]
The first 2 points are about stop running any schedule method, and animation.
The latter 2 points are about stop accepting touch event. You can see that CCMenu* related class maintains its own touch event separately from CCLayer, thus we need to do additional effort by set to both CCMenu* object and the layer itself.
I tried this and it works well for me. Also it's better as we don't have to involve setting dispatcher directly in my opinion.
Me and my fellow classmates decided to make a game over the summer. At first we decided to make it a text-based console app, but then I though that it would be possible to create a GUI for the game using Qt. I played around with it a bit, being able to create widgets and what-not, but was unable to do one thing. For an example, our game contains a Player class. I created a dummy player in the main.cpp and afterwards tried to make the players info to display on a label on a press of a button. After numerous attempts, the only way I was able to do it is by making the player in the mainwindow.cpp . Is there a way to display the info of a player made in the main.cpp? How would it be possible to make the data accessible by different windows, such as the battle window, inventory window, etc.
It's a good thing to let the main.cpp as lean as possible, it should not contain much code in your case.
If I understand correctly you have several windows (could be simple QWidgets with no parent or QMainWindows) running on the same QApplication and your want to share data between them ? Why not just share a Player pointer in both your windows ?
Your main.cpp will look like this:
QApplication app(argc,argv);
YourWindows1 mw1;
YourWindows2 mw2;
Player player;
mw1.setPlayer(&player);
mv2.setPlayer(&player);
mw1.show();
mw2.show();
app.exec();
A more fancy way, could be to use a singleton. This singleton could own and hold your Player instance, every windows can access this singleton statically anytime to fetch Player information. It could be something useful for you to learn.
NOTE: I don't see exactly what is the problem here, perhaps you could share more details about what's causing you trouble ...
In a typical Qt app, main.cpp is only there to start the single application UI object and then turn control over to Qt's event handler. It's possible to deviate from that model, but unless you're quite experienced with Qt it's not something that would be recommended.
I agree with the other posters in this thread in that your main function should be kept absolutely as lean as possible. You want it simply to spawn a new instance of your game, and the let the game loop or state control manager take care of the rest. It basically boils down to something like this:
class Game{
Game();
~Game();
int OnExecute();
};
int Game::OnExecute(){
while(running){
// do game stuff
}
return 0; // No errors, game closed correctly.
}
int main(int argc, char* argv[]){
Game myGame;
myGame.OnExecute();
}
All of your initialization methods/code is contained within the OnExecute function, prior to the game entering its main loop. Within that main while(running) loop, you put your calls to your per-frame Update and Rendering functions which control logic calculations like entity position, physics updating, AI updating, etc and then you render everything for that frame. This is obviously an ultra-simplistic strategy, but it definitely helped me grasp exactly how it is that game engines work.
Now, as far as Qt is concerned, I've tried exactly what you are trying and it is not easy. Qt, though it can be rigged to work for in-game interfaces and the like, seems to me to be primarily intended for use in applications more than games. It provides excellent functionality if you need simple forms and buttons in your program, but as far as custom-designed HUDs and such, you're going to want to look somewhere else in order to save yourself a great deal of hassle. There are, however, a huge number of extensible GUI libraries specifically meant for games. I would suggest looking for one based simply on OpenGL since most graphics/game engines are built upon it and would integrate quite nicely.