0xC0000005:访问冲突写入位置0x00000034

时间:2017-07-09 15:59:41

标签: c++ cocos2d-iphone

当我的角色(飞扬的小鸟)接触到障碍物时,它将转向游戏场景。问题是肯定它出现了游戏场景,但同时出现了

  

0x0FBE9B95(libcocos2d_2015.dll)中(于FlappyBird.exe)掷回例外状况:0xC0000005:读取位置0x00000034时发生存取违规。

翻译:

  (libcocos2d_2015.dll)中的<0x> 0x0FBE9B95(在FlappyBird.exe下)抛出异常0xC0000005:访问冲突写入位置0x00000034。

然而,当我隐藏所有背景内容以及_scheduleUpdate()_时,异常消失了! (也没有任何事情发生在现场...但是知道物理仍在这里,我的飞鸟可以倒地并转向游戏场景) 这是我的计划:

(GameScene.cpp)

#include "GameScene.h"
#include "GameOverScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
#include "Defination.h"

USING_NS_CC;

using namespace cocostudio::timeline;

Scene* GameScene::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::createWithPhysics();
    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

    // 'layer' is an autorelease object
    auto layer = GameScene::create();
    layer->setPhysicsWorld(scene->getPhysicsWorld());

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool GameScene::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }

    auto visibleSize = Director::getInstance()->getVisibleSize();
    auto origin = Director::getInstance()->getVisibleOrigin();

    /*Set screen boundary so that characters will not move outside screen*/
    auto edgeBody = PhysicsBody::createEdgeBox(visibleSize, 
    PHYSICSBODY_MATERIAL_DEFAULT, 3);
    edgeBody->setCollisionBitmask(OBSTACLE_COLLISION_BITMASK);
    edgeBody->setContactTestBitmask(true);
    auto edgeNode = Node::create();

    edgeNode->setPhysicsBody(edgeBody);
    edgeNode->setPosition(Point(visibleSize.width / 2 + origin.x, 
    visibleSize.height / 2 + origin.y));

    this->addChild(edgeNode);

    /*BG*/
    bgLayer = Layer::create();

    bgTotalWidth = 0;
    auto sprite = Sprite::create("bg1.png");
    float bgScale = visibleSize.height / sprite->getContentSize().height;
    float bgWidth = sprite->getContentSize().width * bgScale;
    sprite->release();
    allSpriteScale = bgScale;

    while (bgTotalWidth < visibleSize.width + bgWidth) {
        auto bgSprite = Sprite::create("bg1.png");
        bgSprite->setAnchorPoint(Vec2(0, 0));
        bgSprite->setPosition(Point(origin.x + bgTotalWidth, origin.y));
        bgSprite->setScale(bgScale);

        auto scrollAction = RepeatForever::create(MoveBy::create(1, Vec2(-
        BACKGROUND_MOVE_SPEED, 0)));
        bgSprite->runAction(scrollAction);

        bgLayer->addChild(bgSprite);

        bgTotalWidth += bgWidth;
    }

    this->addChild(bgLayer, 0);

    /*Pipe*/
    pipe = Pipe::Pipe(allSpriteScale);
    pipeLayer = Layer::create();
    this->addChild(pipeLayer, 1);

    /*Flappy Bird*/
    playerLayer = Layer::create();
    this->addChild(playerLayer, 2);
    bird = &FlappyBird::FlappyBird(allSpriteScale, playerLayer);

    /*Scheduler*/
    scheduleUpdate(); //Enable update
    schedule(schedule_selector(GameScene::spawnPipe), PIPE_SPAWN_INTERVAL);

    auto collisionListener = EventListenerPhysicsContact::create();
    collisionListener->onContactBegin = 
    CC_CALLBACK_1(GameScene::onContactBegin, this);
    Director::getInstance()->getEventDispatcher()-
    >addEventListenerWithSceneGraphPriority(collisionListener, this);

    return true;
}

void GameScene::update(float delta) {
    /*BG Update*/
    for each (Sprite* sp in bgLayer->getChildren())
    {
        if (sp->getPositionX() <= -(sp->getContentSize().width * sp-
    >getScaleX())) {
            sp->setPosition(Point(bgTotalWidth + sp->getPositionX(), 0));
            break;
        }
      }
    }

  void GameScene::spawnPipe(float delta) {
    pipe.Spawn(pipeLayer);
 }

bool GameScene::onContactBegin(PhysicsContact &contact)
{
    PhysicsBody* a = contact.getShapeA()->getBody();
    PhysicsBody* b = contact.getShapeB()->getBody();

    if ( (a->getCollisionBitmask() == FLAPPYBIRD_COLLISION_BITMASK && b-
  >getCollisionBitmask() == OBSTACLE_COLLISION_BITMASK) ||
        (b->getCollisionBitmask() == FLAPPYBIRD_COLLISION_BITMASK && a-
  >getCollisionBitmask() == OBSTACLE_COLLISION_BITMASK)
        ) 
    {


        auto gameoverScene = GameOverScene::createScene();
        Director::getInstance()-
   >replaceScene(TransitionFade::create(SCENE_TRANSITION_DURATION, 
   gameoverScene));
    }

    return true;
   }

Visual Studio指示的压缩行在main.cpp中:

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // create the application instance
    AppDelegate app;
    return Application::getInstance()->run(); // Crush here
}

另一个有趣的事情,我几乎无法改变我的代码!在_init()_中,如果我隐藏了定义我的背景精灵动作的两行(逻辑上不会影响其他人),我的GameScene会出现异常!

非常非常奇怪......希望有人可以帮助我。 :(

1 个答案:

答案 0 :(得分:0)

删除sprite->release(),此行会导致异常。 Sprite类已经是一个自动释放对象,并在生成后在自动释放池中注册。

因此,当调用replaceScene()时,不会被调用的所有对象都将被释放。但是,它无法在自动释放池中引用sprite,因为它已由行sprite->release()释放并导致错误。