从GameLayerScene转换到HelloWorldScene后,场景(HelloWorldScene)冻结,按钮无法点击。使用replaceScene是不对的?如何实现从主游戏返回主菜单的功能?我也使用了push和pop,但没有工作。
GameLayerScene
Scene* GameLayer::createScene(int level)
{
auto scene = Scene::create();
auto layer = GameLayer::create(level);
scene->addChild(layer);
return scene;
}
GameLayer* GameLayer::create(int level)
{
GameLayer *pRet = new GameLayer();
pRet->init(level);
pRet->autorelease();
return pRet;
}
bool GameLayer::init(int level)
{
if (!Layer::init())
return false;
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(_swallowsTouches);
touchListener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(GameLayer::onTouchCancelled, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
_level = level;
//This will be shown when the pause is pressed.
auto pauseLayer=LayerColor::create(Color4B::BLACK, WINSIZE.width, WINSIZE.height);
auto pauseLabel=Label::createWithTTF("Paused", "fonts/Marker Felt.ttf", 24);
pauseLabel->setPosition(WINSIZE.width / 2.0, (WINSIZE.height/ 2.0) + 100);
pauseLayer->addChild(pauseLabel);
// Add your required content to pauseLayer like pauseLabel
auto resumeButton = cocos2d::ui::Button::create("resume.png");
resumeButton->setPosition(Vec2(WINSIZE.width / 2.0, WINSIZE.height/ 2.0));
resumeButton->addClickEventListener([pauseLayer](Ref*){
//
if(Director::getInstance()->isPaused()) {
Director::getInstance()->resume();
pauseLayer->setVisible(false);
}
});
auto menuButton = cocos2d::ui::Button::create("menu.png");
menuButton->setPosition(Vec2(WINSIZE.width / 2.0, (WINSIZE.height/ 2.0) - 100));
menuButton->addClickEventListener([pauseLayer](Ref*){
Director::getInstance()->replaceScene(HelloWorldScene::createScene());
// Director::getInstance()->end();
});
pauseLayer->addChild(resumeButton);
pauseLayer->addChild(menuButton);
pauseLayer->setVisible(false);
pauseLayer->setOpacity(220); // so that gameplay is slightly visible
addChild(pauseLayer, ZOrder::Level);
的AppDelegate
bool AppDelegate::applicationDidFinishLaunching()
{
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview)
{
glview = GLViewImpl::create("KaratePuzzle");
director->setOpenGLView(glview);
}
director->setDisplayStats(false);
director->setAnimationInterval(1.0 / 60);
glview->setDesignResolutionSize(640, 1136, ResolutionPolicy::FIXED_WIDTH);
auto scene = HelloWorldScene::createScene();
director->runWithScene(scene);
return true;
}
HelloWorldScene
Scene* HelloWorldScene::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorldScene::create();
scene->addChild(layer);
return scene;
}
HelloWorldScene::HelloWorldScene()
{
}
HelloWorldScene::~HelloWorldScene()
{
}
bool HelloWorldScene::init()
{
if (!Layer::init()) {
return false;
}
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("battle.mp3", true);
auto director = Director::getInstance();
auto winSize = director->getWinSize();
auto background = Sprite::create("main_back.png");
background->setPosition(Vec2(winSize.width / 2.0, winSize.height / 2.0));
this->addChild(background);
auto logo = Sprite::create("logo.png");
logo->setPosition(Vec2(winSize.width / 2.0, winSize.height - 150));
this->addChild(logo);
auto menuButton = MenuItemImage::create("start.png","start.png","start.png",CC_CALLBACK_1(HelloWorldScene::ImageButton,this));
// menuButton->setPosition(Vec2(winSize.width / 2.0, winSize.height /2.0));
menuButton->setPosition(Vec2(winSize.width / 2.0, ((winSize.height /2.0) - 300)));
menuButton->setScale(1.5f);
auto blink = Sequence::create(FadeTo::create(0.5, 127),
FadeTo::create(0.5, 255),
NULL);
menuButton->runAction(RepeatForever::create(blink));
this->addChild(menuButton);
auto moreButton = MenuItemImage::create("more.png","more.png","more.png",[](Ref*sender){
std::string url = "https://play.google.com/xxx";
cocos2d::Application::getInstance()->openURL(url);
});
winSize.height /2.0));
moreButton->setPosition(Vec2(winSize.width / 2.0, 90));
this->addChild(moreButton);
auto menu = Menu::create(menuButton,moreButton, NULL);
menu->setPosition(Point(0,0));
this->addChild(menu);
return true;
}
//Click event for menuButton
void HelloWorldScene::ImageButton(cocos2d::Ref *pSender) {
// stop background music
CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic();
this->getEventDispatcher()->removeAllEventListeners();
auto delay = DelayTime::create(0.5);
auto startGame = CallFunc::create([]{
auto scene = GameLayer::createScene();
auto transition = TransitionPageTurn::create(0.5, scene, true);
Director::getInstance()->replaceScene(transition);
// CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic();
});
this->runAction(Sequence::create(delay,startGame,
NULL));
}
void HelloWorldScene::onEnterTransitionDidFinish()
{
//CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic(AudioUtils::getFileName("title").c_str());
}
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorldScene :public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
HelloWorldScene();
virtual ~HelloWorldScene();
bool init() override;
void onEnterTransitionDidFinish() override;
CREATE_FUNC(HelloWorldScene);
void ImageButton(Ref *pSender);
};
#endif // __HELLOWORLD_SCENE_H__
GameLayerScene.h
#include "cocos2d.h"
#include <random>
#include "BallSprite.h"
#include "Character.h"
class GameLayer : public cocos2d::Layer
{
protected:
enum class Direction
{
x,
y,
};
enum ZOrder
{
BgForCharacter = 0,
BgForPuzzle,
Enemy,
EnemyHp,
Char,
CharHp,
Ball,
Level,
Result,
};
std::default_random_engine _engine;
std::discrete_distribution<int> _distForBall;
std::uniform_int_distribution<int> _distForMember;
BallSprite* _movingBall;
bool _movedBall;
bool _touchable;
int _maxRemovedNo;
int _chainNumber;
std::vector<std::map<BallSprite::BallType, int>> _removeNumbers;
Character* _enemyData;
cocos2d::Sprite* _enemy;
cocos2d::ProgressTimer* _hpBarForEnemy;
cocos2d::Vector<Character*> _memberDatum;
cocos2d::Vector<cocos2d::Sprite*> _members;
cocos2d::Vector<cocos2d::ProgressTimer*> _hpBarForMembers;
int _level;
int _nextLevel;
void initBackground();
void initBalls();
BallSprite* newBalls(BallSprite::PositionIndex positionIndex, bool visible);
BallSprite* getTouchBall(cocos2d::Point touchPos, BallSprite::PositionIndex withoutPosIndex = BallSprite::PositionIndex());
void movedBall();
void checksLinedBalls();
bool existsLinedBalls();
cocos2d::Map<int, BallSprite*> getAllBalls();
bool isSameBallType(BallSprite::PositionIndex current, Direction direction);
void initBallParams();
void checkedBall(BallSprite::PositionIndex current, Direction direction);
void removeAndGenerateBalls();
void generateBalls(int xLineNum, int fallCount);
void animationBalls();
void initEnemy();
void initMembers();
void calculateDamage(int &chainNum, int &healing, int &damage, std::set<int> &attackers);
bool isAttacker(BallSprite::BallType type, Character::Element element);
void attackToEnemy(int damage, std::set<int> attackers);
void healMember(int healing);
void attackFromEnemy();
void endAnimation();
cocos2d::Spawn* vibratingAnimation(int afterHp);
void initLevelLayer();
void removeLevelLayer(float dt);
void winAnimation();
void loseAnimation();
void nextScene(float dt);
public:
GameLayer();
virtual bool init(int level);
static GameLayer* create(int level);
static cocos2d::Scene* createScene(int level = 1);
virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* unused_event);
virtual void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* unused_event);
virtual void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* unused_event);
virtual void onTouchCancelled(cocos2d::Touch* touch, cocos2d::Event* unused_event);
void PauseButton(Ref *pSender);
};
#endif
答案 0 :(得分:1)
我没有测试过您的代码,但在此声明中似乎有问题:
#include <type_traits>
#include <utility>
#include <map>
template <typename>
struct is_pair : std::false_type
{ };
template <typename T, typename U>
struct is_pair<std::pair<T, U>> : std::true_type
{ };
template<class ITR, typename = typename std::enable_if<is_pair<typename ITR::value_type>::value, ITR>::type>
decltype(auto) do_stuff(ITR && itr) {
//access of itr->second ok.
}
int main()
{
std::map<int, int> foo{
{ 1, 2 },
{ 3, 4 },
};
do_stuff(foo.begin());
return 0;
}
它会给运行时异常,因为menuButton和moreButton已经添加了。它无法再添加。
答案 1 :(得分:0)
我能够解决问题。问题是由于场景仍然暂停而没有恢复。
auto menuButton = cocos2d::ui::Button::create("menu.png");
menuButton->setPosition(Vec2(WINSIZE.width / 2.0, (WINSIZE.height/ 2.0) - 100));
menuButton->addClickEventListener([pauseLayer](Ref*){
if (Director::getInstance()->isPaused()) {
Director::getInstance()->resume();
}
Director::getInstance()->replaceScene(HelloWorldScene::createScene());
// Director::getInstance()->end();
});