Cocos 2DX CPP中的迷宫生成

时间:2020-02-22 10:11:17

标签: android c++ cocos2d-x

我正在尝试在cocos2dx cpp框架中创建一个迷宫生成器。使用递归backtracker算法来实现。 Iam kinda做到了,但不确定我错过了哪里。我得到的迷宫不是迷宫,它只是一个封闭的单元。你能告诉我我想念的地方吗,下面是我的代码

GameScene.cpp

    #include "GameScene.h"
    #include "SimpleAudioEngine.h"
    #include "Globals.h"
    
    USING_NS_CC;
    
    std::vector<Cell> Globals::grid;
    // std::stack<Cell> Globals::mainStack;
    
    Scene* GameScene::createScene()
    {
        return GameScene::create();
    }
    
    // Print useful error message instead of segfaulting when files are not there.
    static void problemLoading(const char* filename)
    {
        printf("Error while loading: %s\n", filename);
        printf("Depending on how you compiled you might have to add 'Resources/' in front of 
     filenames in GameSceneScene.cpp\n");
    }
    
    bool GameScene::init()
    {
        if ( !Scene::init() )
        {
            return false;
        }
    
        auto visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
        //Middle position ==> sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, 
         
        visibleSize.height/2 + origin.y));
    
        auto label = Label::createWithTTF("Hello!", "fonts/Marker Felt.ttf", 24);
        if (label == nullptr)
        {
            problemLoading("'fonts/Marker Felt.ttf'");
        }
        else
        {
            label->setPosition(Vec2(origin.x + visibleSize.width/2,
                                    origin.y + visibleSize.height - 
                                    label->getContentSize().height));
            this->addChild(label, 1);
        }
    
        GameScene::buildLayouts();
        this->scheduleUpdate();
        // GameScene::initBoard();
        // GameScene::start();
    
        return true;
    }
    
    // void GameScene::start(float dt) {
    // }
    
    void GameScene::update(float dt)
    {
    
        cocos2d::log("{jj} drawing");
        int cols = 4; //round(BOARD_WIDTH / GRID_SIZE);
        int rows = 4; //round(BOARD_HEIGHT /GRID_SIZE);
    
        Cell* next;
    
        std::stack<Cell> mainStack; 
    
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                Cell cell(i, j);
                Globals::grid.push_back(cell);
                cocos2d::log("{cell} cell col -- %d", cell.col);
                cocos2d::log("{cell} cell row -- %d", cell.row);
            }
        }
    
        currentGrid = &Globals::grid[0];
        bool mazeGenerated = false;
    
        //step 1
        currentGrid->visited = true;
        
        while(mazeGenerated == false) {
            cocos2d::log("{lo} Generating --");
    
            
            Cell *nextCell = currentGrid->checkNeighbors(rows, cols);
    
            // cocos2d::log("{lo} next cell nextCell -- %d", nextCell);
    
            if (nextCell != nullptr) {
                cocos2d::log("{lo} Entering valid index --");
    
                for (int i = 0; i < Globals::grid.size(); i++)
                {
                    if (nextCell ->col == Globals::grid[i].col && nextCell->row == 
                        Globals::grid[i].row) {
                        //step 2
                        mainStack.push(*currentGrid);
                        Globals::grid[i].visited = true;
    
                        //step 3
                        currentGrid->removeWalls(&Globals::grid[i]);
                        next = &Globals::grid[i];
    
                    }
                }
    
                currentGrid->removeWalls(next);
    
                next->drawCell(this->main_scroll_view);
                //step 4
                currentGrid = next;
            } else  {
                if  (!mainStack.empty()) {
                    currentGrid = &mainStack.top();
                    mainStack.pop();
                } else {
                    mazeGenerated = true;
                    cocos2d::log("{lo} maze generated --");
                }
            }
        }
    
        // GameScene::drawBoard();
    }
    
    void GameScene::drawBoard()
    {
        for (int i = 0; i < Globals::grid.size(); i++) {
            Globals::grid[i].drawCell(this->main_scroll_view);
        }
    }
    
    void GameScene::buildLayouts()
    {
        auto visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
        this->main_layout = cocos2d::ui::Layout::create();
        this->main_layout->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); 
        this->main_layout->setBackGroundColor(Color3B::WHITE);
        this->main_layout->setLayoutType(ui::Layout::Type::VERTICAL);
        this->main_layout->setContentSize(Size(visibleSize.width , visibleSize.height  ));
        this->main_layout->setPosition(Vec2(origin.x + visibleSize.width/2, origin.y + 
        visibleSize.height/2));
        this->main_layout->setAnchorPoint(Vec2(0.5, 0.5));
    
        this->addChild(main_layout);


    Size scollFrameSize = Size(this->main_layout->getContentSize().width , 
                                 this->main_layout->getContentSize().height);
    this->main_scroll_view = cocos2d::ui::ScrollView::create();
    this->main_scroll_view->setContentSize(scollFrameSize);
    this->main_scroll_view-> 
          setBackGroundColorType(cocos2d::ui::Layout::BackGroundColorType::SOLID);
    this->main_scroll_view->setBackGroundColor(Color3B(200, 200, 200));
    this->main_scroll_view->setPosition(Vec2(0, 0));
    this->main_scroll_view->setDirection(cocos2d::ui::ScrollView::Direction::BOTH);
    this->main_scroll_view->setBounceEnabled(true);
    this->main_scroll_view->setTouchEnabled(true);
    auto containerSize = Size(scollFrameSize.width*2, scollFrameSize.height + 100);
    this->main_scroll_view->setInnerContainerSize(containerSize);

    this->main_layout->addChild(this->main_scroll_view);
}


#Cell.cpp

    #include "Cell.h"
    #include "cocos2d.h"
    #include "GameScene.h"
    #include "Globals.h"
    
    
    // constructor
    Cell::Cell(int i, int j): row(i), col(j)
    {
    };
    
    
    
    // bool Cell.walls[] = { true, true, true   , true };
    
    void Cell::drawCell(cocos2d::ui::Layout *parent)
    {
        int x = col * WIDTH;
        int y = row * WIDTH;
    
        auto visibleSize = cocos2d::Director::getInstance()->getVisibleSize();
        cocos2d::Vec2 origin = cocos2d::Director::getInstance()->getVisibleOrigin();
    
        int parent_width = parent->getContentSize().width;
        int parent_height = parent->getContentSize().height;
    
    
     //    if (visited) {
        //  auto rectNode = cocos2d::DrawNode::create();
        //  cocos2d::Vec2 rectangle[4];
        //  rectangle[0] = cocos2d::Vec2(x, y);
        //  rectangle[1] = cocos2d::Vec2(x+WIDTH, y);
        //  rectangle[2] = cocos2d::Vec2(x+WIDTH, y+ HEIGHT);
        //  rectangle[3] = cocos2d::Vec2(x, y+HEIGHT);
    
        //  // cocos2d::Color4F::ORANGE;
        //  rectNode->drawPolygon(rectangle, 4, cocos2d::Color4F::ORANGE, 1, 
         cocos2d::Color4F::ORANGE);
        //  parent->addChild(rectNode);
        // }
        
        auto drawNode = cocos2d::DrawNode::create();
    
        if (walls[0]) {
            drawNode->drawLine(cocos2d::Vec2(x , y + HEIGHT), cocos2d::Vec2(x + WIDTH, y + 
        HEIGHT), cocos2d::Color4F::GREEN); //top
        }
    
        if (walls[1]) {
            drawNode->drawLine(cocos2d::Vec2(x + WIDTH, y), cocos2d::Vec2( x + WIDTH, y + 
        HEIGHT), cocos2d::Color4F::BLUE); //right
        }
    
        if (walls[2]) {
            drawNode->drawLine(cocos2d::Vec2(x, y), cocos2d::Vec2(x + WIDTH, y), 
        cocos2d::Color4F::RED); //bottom
        }
    
        if (walls[3]) {
            drawNode->drawLine(cocos2d::Vec2(x, y ), cocos2d::Vec2(x, y +HEIGHT), 
         cocos2d::Color4F::BLACK); // left
        }
    
        // drawNode->setPosition(cocos2d::Vec2(parent_width/2 + origin.x, parent_height/2 + 
         origin.y));
        // this->setAnchorPoint(cocos2d::Vec2(0.5, 0.5));
        parent->addChild(drawNode);
    }
    
    int Cell::getIndex(int colId, int rowId,  int rows, int cols)
    {
        if ( colId < 0 || rowId < 0 || colId > 4 - 1 || rowId > 4 - 1) {
            return -1;
        }
    
        return colId + rowId * 4 ;
    }
    
    Cell* Cell::checkNeighbors( int rows, int cols) {
    
        std::vector<Cell> neighbors;
    
        int top_index, right_index, bottom_index, left_index;
    
        top_index    = Cell::getIndex(col, row + 1, rows, cols );
        right_index  = Cell::getIndex(col + 1, row, rows, cols );
        bottom_index = Cell::getIndex(col, row  - 1, rows, cols );
        left_index   = Cell::getIndex(col - 1, row, rows, cols);
    
        if (top_index != -1) {
            Cell top     = Globals::grid[top_index];
    
            if (!top.visited) {
                cocos2d::log("{lo} top here");
                neighbors.push_back(top);
            }
        }
        
        if (right_index != -1) {
            Cell right = Globals::grid[right_index];
    
            if (!right.visited) {
                cocos2d::log("{lo} right here");
                neighbors.push_back(right);
            }
        }
    
        if (bottom_index != -1) {
            Cell bottom = Globals::grid[bottom_index];
    
            if (!bottom.visited) {
                cocos2d::log("{lo} bottom here");
                neighbors.push_back(bottom);
            }
        }
    
        if (left_index != -1) {
            Cell left = Globals::grid[left_index];
    
            if (!left.visited) {
                cocos2d::log("{lo} left here");
                neighbors.push_back(left);
            }
        }
    
        if (neighbors.size() > 0) {
            srand(time(NULL)); // needed to give random number at change of time
            int randomIndex = round(rand() % neighbors.size());
            return &neighbors[randomIndex];
        } else {
            return nullptr;
        }
    }
    
    
    void Cell::removeWalls(Cell *next)
    {
        int x = this->row - next->row;
    
        cocos2d::log("{kk} x is %d", x);
                
    
        if (x == 1) {
            this->walls[1] = false;
            next->walls[3] = false;
        } else if (x == -1) {
            this->walls[3] = false;
            next->walls[1] = false;
        }
    
        int y = this->col - next->col;
        cocos2d::log("{kk} y is %d", y);
    
        if (y == 1) {
            this->walls[0] = false;
            next->walls[2] = false;
        } else if (y == -1) {
            this->walls[2] = false;
            next->walls[0] = false;
        }
    }

一个单元格是一个带有线条的块,如果需要,我会画线。

0 个答案:

没有答案
相关问题