前提・実現したいこと
「cocos2d-xではじめるスマートフォンゲーム開発」という本を参考に、「自機とフルーツが重なったときにフルーツを消す」という当たり判定を実装したところエラーが出ました。
環境はcocos2d-x-4.0、Visual Studio 2019、Windows10です。
わかる方がいましたらよろしくお願いいたします。
発生している問題・エラーメッセージ
例外がスローされました:読み取りアクセス違反。 **_Mycont** が nullptr でした。
該当のソースコード
c++
1//MainScene.h 2#ifndef __KawazCatch__MainScene__ 3#define __KawazCatch__MainScene__ 4 5#include "cocos2d.h" 6const int WINDOW_WIDTH = 1920, WINDOW_HEIGHT = 1080; 7 8class MainScene :public cocos2d::Layer { 9protected: 10 MainScene(); 11 virtual ~MainScene(); 12 bool init() override; 13public: 14 static cocos2d::Scene* createScene(); 15 void update(float dt); 16 CREATE_FUNC(MainScene); 17 // _player変数、getPlayer()メソッド、setPlayer(Sprite*)メソッドが自動的に自動的に実装される 18 CC_SYNTHESIZE_RETAIN(cocos2d::Sprite*, _player, Player); 19 CC_SYNTHESIZE(cocos2d::Vector<cocos2d::Sprite*>, _fruits, Fruits); 20 int kra_flg, kla_flg, kua_flg, kda_flg; 21 double PLAYER_SPEED = 10.0; 22private: 23 // フルーツの種類 24 enum class FruitType 25 { 26 APPLE, 27 GRAPE, 28 ORANGE, 29 BANANA, 30 CHERRY, 31 COUNT 32 }; 33 cocos2d::Sprite* addFruit(); 34 bool removeFruit(cocos2d::Sprite* fruit); 35 void catchFruit(cocos2d::Sprite* fruit); 36}; 37#endif // !__KawazCatch__MainScene__ 38
// MainScene.cpp #include "MainScene.h" USING_NS_CC; //フルーツの画面上部からマージン(px) const int FRUIT_TOP_MARGIN = 40; const int FRUIT_SPAWM_RATE = 20; MainScene::MainScene() :_player(NULL) { kra_flg = 0, kla_flg = 0, kua_flg = 0, kda_flg = 0; } MainScene::~MainScene() { // _playerをrelease CC_SAFE_RELEASE_NULL(_player); } Scene* MainScene::createScene() { auto scene = Scene::create(); auto layer = MainScene::create(); scene->addChild(layer); return scene; } Sprite* MainScene::addFruit() { // 画面サイズ取り出し auto winSize = Director::getInstance()->getWinSize(); // フルーツの種類選択 int fruitType = rand() % static_cast<int>(FruitType::COUNT); // フルーツを作成 std::string filename = StringUtils::format("fruit%d.png", fruitType); auto fruit = Sprite::create(filename); fruit->setTag(fruitType); auto fruitSize = fruit->getContentSize(); float fruitXPos = rand() % static_cast<int>(winSize.width); fruit->setPosition(Vec2(fruitXPos, winSize.height - FRUIT_TOP_MARGIN - fruitSize.height / 2.0)); this->addChild(fruit); _fruits.pushBack(fruit); // 地面の座標 auto ground = Vec2(fruitXPos,0); auto fall = MoveTo::create(3,ground); auto remove = CallFuncN::create([this](Node* node) { auto sprite = dynamic_cast<Sprite*>(node); this->removeFruit(sprite); }); auto sequence = Sequence::Sequence::create(fall, remove, NULL); fruit->runAction(sequence); return fruit; } bool MainScene::removeFruit(cocos2d::Sprite* fruit) { if (_fruits.contains(fruit)) { _fruits.eraseObject(fruit); fruit->removeFromParent(); return true; } return false; } void MainScene::catchFruit(cocos2d::Sprite* fruit) { this->removeFruit(fruit); } void MainScene::update(float dt) { int random = rand() % FRUIT_SPAWM_RATE; if (random == 0) { this->addFruit(); } for (auto fruit : _fruits) { Vec2 busketPosition = _player->getPosition() - Vec2(0, 10); Rect boundingBox = fruit->getBoundingBox(); bool isHit = boundingBox.containsPoint(busketPosition); if (isHit) { this->catchFruit(fruit); } } if (this->kra_flg == 1&&_player->getPosition().x<WINDOW_WIDTH)_player->setPosition(_player->getPosition() + Vec2(PLAYER_SPEED, 0)); if (this->kla_flg == 1&&_player->getPosition().x>0)_player->setPosition(_player->getPosition() + Vec2(-PLAYER_SPEED, 0)); if (this->kua_flg == 1&&_player->getPosition().y<WINDOW_HEIGHT)_player->setPosition(_player->getPosition() + Vec2(0, PLAYER_SPEED)); if (this->kda_flg == 1&&_player->getPosition().y>0)_player->setPosition(_player->getPosition() + Vec2(0, -PLAYER_SPEED)); } bool MainScene::init() { if (!Layer::init()) { return false; } auto director = Director::getInstance(); auto size = director->getWinSize(); // 背景 auto background = Sprite::create("background2.png"); background->setPosition(Vec2(size.width/2.0,size.height/2.0)); this->addChild(background); // プレイヤー this->setPlayer(Sprite::create("player.png")); _player->setPosition(Vec2(size.width/2.0,size.height-445)); this->addChild(_player); // イベントリスナー auto listener = EventListenerKeyboard::create(); listener->onKeyPressed = [this](cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* keyEvent) { if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_ARROW) this->kra_flg = 1; if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_LEFT_ARROW) this->kla_flg = 1; if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_UP_ARROW) this->kua_flg = 1; if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_DOWN_ARROW) this->kda_flg = 1; }; listener->onKeyReleased = [this](cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* keyEvent) { if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_ARROW) this->kra_flg = 0; if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_LEFT_ARROW) this->kla_flg = 0; if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_UP_ARROW) this->kua_flg = 0; if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_DOWN_ARROW) this->kda_flg = 0; }; this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); this->scheduleUpdate(); return true; }
試したこと
void MainScene::catchFruit(cocos2d::Sprite* fruit)の中身をfruit->removeFromParent();だけにするとうまくいきました。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。