2017-07-09 188 views
-2

当我的角色(飞扬的小鸟)接触到障碍物时,它将转向游戏场景。问题是它显示了一个GAMEOVER现场,但同时出现的0xC0000005:访问冲突写入位置0x00000034

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

要翻译:

0x0FBE9B95在(libcocos2d_2015.dll)(FlappyBird.exe下)抛出异常0000005:访问冲突写入位置0x00000034。

但是,当我隐藏所有背景以及_scheduleUpdate()_时,异常消失! (还没有出现在现场......但知道物理学还在这里,我笨鸟先飞可降至地面,转向GAMEOVER场景) 这里是我的程序:

(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中出现异常!

这是非常非常奇怪的......希望有人能帮助我。 :(

+0

AFAIK,这意味着你正在访问你不拥有的内存。这是太多的代码,希望我们能够通过你,虽然你真的需要把问题缩小到一个[MCVE]。 – Carcigenicate

+1

从错误信息这是Windows的圣人。真的,最好的做法是使用Visual Studio调试程序逐步执行程序,并缩小尝试写入不属于您的内存的位置。 – paisanco

+0

嗨@Carcigenicate,谢谢你的回复。我明白,但是我有太多的代码在这里发布......而异常窗口实际上是用中文编写的,所以我不能直接发布它......我正在考虑其他方式来澄清我的情况。感谢你能理解。 –

回答

0

删除sprite->release(),这条线会导致异常。Sprite类是已经自动释放对象,一旦产生了在自动释放池中注册。

因此,呼吁replaceScene()时,所有对象应不会被调用将会被释放,但是它不能引用自动释放池中的精灵,因为它已经被行sprite->release()释放并且导致错误。