質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

COCOS2D-X

COCOS2D-Xは、 2Dゲームを手軽に開発できるフレームワークのことです。 iPhone(iOS)向け、Android等に対応しており、 実質ワンソースで開発が可能です。

Q&A

解決済

1回答

859閲覧

cocos2d-x 当たり判定時にエラー

Babelian

総合スコア4

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

COCOS2D-X

COCOS2D-Xは、 2Dゲームを手軽に開発できるフレームワークのことです。 iPhone(iOS)向け、Android等に対応しており、 実質ワンソースで開発が可能です。

0グッド

0クリップ

投稿2020/08/01 16:55

編集2020/08/02 06:25

前提・実現したいこと

「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/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

問題点は、_fruitsのforループ内の処理で、_fruits.eraseObject(fruit)を行っていることが考えられます。
_fruitsの要素を削除したため、for ループが不定になってしまったのでは...

投稿2020/11/06 10:35

akiruno-oneone

総合スコア815

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問