Exemplo n.º 1
0
void TileLayer::draw(SDL_Surface* dst) {

    const uint16_t tileSize = 25;

    // Determine the coordinate to draw the tile animation..
    uint16_t xp = this->x*tileSize;
    uint16_t yp = this->y*tileSize;

    this->getAnimation()->move(xp, yp);
    this->getAnimation()->blit(dst);

    PlayModel* playModel = PlayModel::GetInstance();

    // Redraw the Key.
    if (playModel->tileCoordHasKey(TileCoord(this->x, this->y))) {
        KeyAnim->move(xp, yp);
        KeyAnim->blit(dst);
    }

    // Redraw the Player.
    if (playModel->tileCoordHasPlayer(TileCoord(this->x, this->y))) {
        PlayerAnim->move(xp, yp);
        PlayerAnim->blit(dst);
    }

}
Exemplo n.º 2
0
TileCoord goTowards(const TileCoord &from, TileCoord towards) {
    if (from.row < towards.row)
        return TileCoord(from.row + 1, from.col);
    if (from.row > towards.row)
        return TileCoord(from.row - 1, from.col);
    if (from.col < towards.col)
        return TileCoord(from.row, from.col + 1);
    if (from.col > towards.col)
        return TileCoord(from.row, from.col - 1);
    assert(false);
}
Exemplo n.º 3
0
bool findOnMapRandomTileOfType(const MapTiles &map, const Tile &tile, int numTries, TileCoord *resultingTileLocation) {
    for (int i = 0; i < numTries; i++) {
        int row = rand() % (map.getSize().row - 2);
        int col = rand() % (map.getSize().col - 2);
        
        if (map[TileCoord(row, col)] == tile) {
            *resultingTileLocation = TileCoord(row, col);
            return true;
        }
    }
    
    return false;
}
Exemplo n.º 4
0
bool areaOnMapIsFilledWithTile(const MapTiles &map, const Tile &tile, const Area &area) {
    if (area.origin.row < 0 || area.origin.row + area.size.row >= map.getSize().row)
        return false;
    if (area.origin.col < 0 || area.origin.col + area.size.col >= map.getSize().col)
        return false;
    for (int row = area.origin.row; row < area.origin.row + area.size.row; row++)
        for (int col = area.origin.col; col < area.origin.col + area.size.col; col++)
            if (map[TileCoord(row, col)] != tile)
                return false;
    return true;
}
Exemplo n.º 5
0
void TileScene::UpdatePreviewTile(int x, int y, TileCoord origin)
{
    if(origin == TileCoord(-1, -1))
    {
        if(previewItems.contains(TileCoord(x, y)))
        {
            removeItem(previewItems[TileCoord(x, y)]);
            delete previewItems[TileCoord(x, y)];
            previewItems.remove(TileCoord(x, y));
        }

        return;
    }

    TileWidgetItem *tempTile = new TileWidgetItem;
    tempTile->setFlag(QGraphicsItem::ItemIsSelectable);

    //update its Pixmap
    tempTile->SetTilePixmap(tileController->GetTilePixmap(origin));

    //set the position
    tempTile->setPos(x * tileController->GetTileWidth(),
                     y * tileController->GetTileHeight());

    previewItems[TileCoord(x, y)] = tempTile;
    addItem(tempTile);
}
Exemplo n.º 6
0
void ConveyorAnimation::BuildConveyorAnimations() {

    ClearConveyors();

    PlayModel* playModel = PlayModel::GetInstance();

    for (int x = 0; x < PlayModel::GRID_WIDTH; x++) {

        for (int y = 0; y < PlayModel::GRID_HEIGHT; y++) {
            TileCoord tileCoord = TileCoord(x, y);

            if (playModel->isConveyor(tileCoord)) {

                if (!TileInConveyor(tileCoord)) {

                    // This TileCoord must be part of a Conveyor.  Find the
                    // start of the Conveyor.

                    TileCoord q = tileCoord;
                    TileCoord p = q;

                    if (TileInConveyor(tileCoord)) {
                        continue;
                    }

                    Direction conveyDir = playModel->getConveyorDirection(q);

                    // Initialize oppDir to something invalid to pacify
                    // compiler warnings.
                    Direction oppDir = DIRECTION_COUNT;

                    // Determine the opposite direction of this belt.
                    if (conveyDir == DIRECTION_UP) {
                        oppDir = DIRECTION_DOWN;
                    } else if (conveyDir == DIRECTION_DOWN) {
                        oppDir = DIRECTION_UP;
                    } else if (conveyDir == DIRECTION_LEFT) {
                        oppDir = DIRECTION_RIGHT;
                    } else if (conveyDir == DIRECTION_RIGHT) {
                        oppDir = DIRECTION_LEFT;
                    }

                    //std::cout << "\tOppDir: " << oppDir << std::endl;


                    // A circular conveyor is one which stretches from one
                    // border to the other, causing it it wrap-around.  We need
                    // to check for this behavior so that we can prevent
                    // infinite looping here.
                    bool circular = false;

                    // Go backwards along the belt until you hit a non-conveyor
                    // tile, or a conveyor tile which is part of another
                    // conveyor, or we find that the current belt is circular.
                    TileCoord prev = p;
                    while (    playModel->isConveyor(p)
                            && playModel->getConveyorDirection(p) == conveyDir
                            && !TileInConveyor(p)
                            && !circular) {

                        prev = p;

                        if (oppDir == DIRECTION_UP) {
                            p = playModel->getTileCoordUp(p);
                        } else if (oppDir == DIRECTION_DOWN) {
                            p = playModel->getTileCoordDown(p);
                        } else if (oppDir == DIRECTION_RIGHT) {
                            p = playModel->getTileCoordRight(p);
                        } else if (oppDir == DIRECTION_LEFT) {
                            p = playModel->getTileCoordLeft(p);
                        }

                        if (p == q) {
                            circular = true;
                        }

                    }

                    TileCoord start = p = prev;
                    std::vector<TileCoord> conveyorTiles;

                    int tileNum = 0;
                    // Now follow the conveyor from its start until a
                    // non-conveyor tile, or a conveyor tile which is part of
                    // another conveyor or if the belt is found to be circular,
                    // the start tile.
                    while (    playModel->isConveyor(p)
                            && playModel->getConveyorDirection(p) == conveyDir
                            && !TileInConveyor(p)) {

                        conveyorTiles.push_back(p);

                        tileNum++;
                        //std::cout << "\ttile #" << tileNum << " " << p->getX() << "," << p->getY() << std::endl;

                        if (conveyDir == DIRECTION_UP) {
                            p = playModel->getTileCoordUp(p);
                        } else if (conveyDir == DIRECTION_DOWN) {
                            p = playModel->getTileCoordDown(p);
                        } else if (conveyDir == DIRECTION_RIGHT) {
                            p = playModel->getTileCoordRight(p);
                        } else if (conveyDir == DIRECTION_LEFT) {
                            p = playModel->getTileCoordLeft(p);
                        }

                        if (circular) {
                            if (p == start) {
                                break;
                            }
                        }

                    }

                    // Creating a ConveyorAnimation causes it to be added to
                    // the ConveyorAnimation array.
                    new ConveyorAnimation(conveyorTiles);
                }
            }
        }
    }
}
Exemplo n.º 7
0
MapTiles *generateMap(const GenerateOptions &options) {
    srand(options.randomSeed);
    
    MapTiles *map = new MapTiles(TileCoord(options.numRows, options.numCols), options.wall);
    int numRoomsGenerated = 0;
    
    for (int numTries = 0; numTries < 100 && numRoomsGenerated < options.numRooms; numTries++) {
        TileCoord roomCenterTileLocation;
        if (!findOnMapRandomTileOfType(*map, options.wall, 100, &roomCenterTileLocation))
            break;
        
        Area room(roomCenterTileLocation, TileCoord(1, 1));
        assert(areaOnMapIsFilledWithTile(*map, options.wall, room));
        
        // Expand down until we have max room rows + 2 (the +2 is so we can retract later to have nice padding)
        while (room.size.row < options.maxRoomRows + 2 * options.padding) {
            Area proposedRoom = room;
            proposedRoom.size.row++;
            if (areaOnMapIsFilledWithTile(*map, options.wall, proposedRoom))
                room = proposedRoom;
            else
                break;
        }
        
        // Expand up until we have max room rows + 2 (we may have already gotten that many in the last while loop, which is fine
        while (room.size.row < options.maxRoomRows + 2 * options.padding) {
            Area proposedRoom = room;
            proposedRoom.origin.row--;
            proposedRoom.size.row++;
            if (areaOnMapIsFilledWithTile(*map, options.wall, proposedRoom))
                room = proposedRoom;
            else
                break;
        }
        
        // Expand down until we have max room cols + 2 (the +2 is so we can retract later to have nice padding)
        while (room.size.col < options.maxRoomCols + 2 * options.padding) {
            Area proposedRoom = room;
            proposedRoom.size.col++;
            if (areaOnMapIsFilledWithTile(*map, options.wall, proposedRoom))
                room = proposedRoom;
            else
                break;
        }
        
        // Expand up until we have max room cols + 2 (we may have already gotten that many in the last while loop, which is fine
        while (room.size.col < options.maxRoomCols + 2 * options.padding) {
            Area proposedRoom = room;
            proposedRoom.origin.col--;
            proposedRoom.size.col++;
            if (areaOnMapIsFilledWithTile(*map, options.wall, proposedRoom))
                room = proposedRoom;
            else
                break;
        }
        
        // Retract, so we have a padding of wall around the outside of the room (so no rooms touch)
        room.origin.row += options.padding;
        room.origin.col += options.padding;
        room.size.row -= 2 * options.padding;
        room.size.col -= 2 * options.padding;
        
        if (room.size.row < options.minRoomRows)
            continue;
        if (room.size.col < options.minRoomCols)
            continue;
        
        map->fillAreaWithTile(room, options.floor);
        numRoomsGenerated++;
        
    }
    
    connectAllRegions(map, options.wall, options.floor);
    
    assert(numRoomsGenerated > 0);
    
        std::cout << "Map:" << std::endl;
        for (int row = 0; row < map->getSize().row; row++) {
            for (int col = 0; col < map->getSize().col; col++) {
                std::cout << (*map)[TileCoord(row, col)].character;
            }
            std::cout << std::endl;
        }
        std::cout << "/Map" << std::endl;
    
    return map;
}
Exemplo n.º 8
0
void connectAllRegions(MapTiles *map, const Tile &WALL, const Tile &FLOOR) {
    Region ***regionsByRowCol = new Region**[map->getSize().row];
    for (int row = 0; row < map->getSize().row; row++) {
        regionsByRowCol[row] = new Region*[map->getSize().col];
        for (int col = 0; col < map->getSize().col; col++) {
            regionsByRowCol[row][col] = NULL;
        }
    }
    
    std::vector<Region *> regions;
    
//    std::cout << "Regions:" << std::endl;
    
    for (int row = 0; row < map->getSize().row; row++) {
        for (int col = 0; col < map->getSize().col; col++) {
            if ((*map)[TileCoord(row, col)] == FLOOR && regionsByRowCol[row][col] == NULL) {
                std::set<TileCoord, TileCoord::Before> *newRegion = new std::set<TileCoord, TileCoord::Before>();
//                charsByRegion[newRegion] = charsByRegion.size() + '0';
                findContiguous(*map, TileCoord(row, col), newRegion);
                
                for (Region::iterator i = newRegion->begin(), iEnd = newRegion->end(); i != iEnd; i++)
                    regionsByRowCol[i->row][i->col] = newRegion;
                
                regions.push_back(newRegion);
            }
            
//            std::cout << charsByRegion[regionsByRowCol[row][col]];
        }
//        std::cout << std::endl;
    }
//    std::cout << "/Regions" << std::endl;
    
//    std::cout << "Begin!" << std::endl;
//    for (int i = 0; i < regions.size(); i++)
//        std::cout << "region " << regions[i] << " size " << regions[i]->size() << std::endl;
    
    while (regions.size() > 1) {
        int randomRegionsIndex = rand() % (regions.size() - 1);
        Region *region1 = regions[randomRegionsIndex];
        Region *region2 = regions[randomRegionsIndex + 1];
        assert(!region1->empty());
        assert(!region2->empty());
        
        std::set<TileCoord, TileCoord::Before>::iterator iter = region2->begin();
        std::advance(iter, rand() % region2->size());
        TileCoord destination = *iter;
        
//        std::cout << "digging!" << std::endl;
        
        digTowardsButStopWhenHitAnotherRegion(map, regionsByRowCol, region1, destination);
        
//        std::cout << "After dig, before flood: " << std::endl;
//        displayRegions(*map, regionsByRowCol);
//        for (int i = 0; i < regions.size(); i++)
//            std::cout << "region " << regions[i] << " size " << regions[i]->size() << std::endl;
        
//        std::cout << "flooding!" << std::endl;
        
        findContiguous(*map, *region1->begin(), region1);
        for (Region::iterator i = region1->begin(), iEnd = region1->end(); i != iEnd; i++) {
            if (regionsByRowCol[i->row][i->col] != NULL && regionsByRowCol[i->row][i->col] != region1)
                regionsByRowCol[i->row][i->col]->erase(*i);
            regionsByRowCol[i->row][i->col] = region1;
        }
        
//        std::cout << "After flood:" << std::endl;
        
//        for (int i = 0; i < regions.size(); i++)
//            std::cout << "region " << regions[i] << " size " << regions[i]->size() << std::endl;
        
        int numRegionsNowEmpty = 0;
        for (int i = 0; i < regions.size(); ) {
//            if (regions[i]->size() == 1)
//                std::cout << *regions[i]->begin() << std::endl;
            if (regions[i]->empty()) {
                regions.erase(regions.begin() + i);
                numRegionsNowEmpty++;
            }
            else
                i++;
        }
        
        assert(numRegionsNowEmpty);
        
//        displayRegions(*map, regionsByRowCol);
    }
}