#include "IsoTilesMap.h" using namespace graphic; // base constructor, use a map to choose tiles IsoTilesMap::IsoTilesMap(int num_rows, int num_cols, int *map, TileSet * ts): Map(num_rows, num_cols) { // Tile dimensions _tile_width = ts->GetTileW(); _tile_height = ts->GetTileH(); _square_side = _tile_height * SQRT2; int half_height = _tile_height / 2; // indexes int r , c; // temporary IntPoint for tiles IntPoint constr_p; // temporary tile pointer Tile * constr_tile; // set the image origin so that the [num_rows, 0] tile have x = 0 and the [0,0] // tile have y = 0 _graphic_origin.x = ((num_rows - 1) * _tile_height); _graphic_origin.y = 0; // origin of the map _origin.x = _graphic_origin.x + _tile_height; _origin.y = _graphic_origin.y; // storing TileSet pointer _tile_set = ts; // dimensions of the map _width = (num_cols + num_rows) * _tile_height; _height = _width / 2; // number of used images _num_images = ts->GetNumImg(); // number of cells and objects _num_cells = num_cols * num_rows; _num_objects = _num_cells; for(r = 0; r < _num_rows; r++) { for(c = 0; c < _num_cols; c++) { // create a new tile constr_tile = new Tile(ts->GetImage(*(map + ((r * num_cols) + c)))); // set indexes of the new tile constr_tile->SetIndexes(r,c); // set tile isometric position constr_p.x = (c - r) * _tile_height + _graphic_origin.x; constr_p.y = (c + r) * half_height + _graphic_origin.y; constr_tile->SetPosition(constr_p); // store the tile into the tiles vector _objects.push_back(constr_tile); } } } // random map generation constructor, no map required IsoTilesMap::IsoTilesMap(int num_rows, int num_cols, TileSet * ts): Map(num_rows, num_cols) { // Tile dimensions _tile_width = ts->GetTileW(); _tile_height = ts->GetTileH(); _square_side = _tile_height * SQRT2; int half_height = _tile_height / 2; // indexes rows/cols int r , c; // random index int ind_img; // temporary IntPoint for tiles IntPoint constr_p; // temporary tile pointer Tile * constr_tile; // init random generator srand(time(NULL)); // set the origin so that the [num_rows, 0] tile have x = 0 and the [0,0] // tile have y = 0 _graphic_origin.x = ((num_rows - 1) * _tile_height); _graphic_origin.y = 0; // origin of the map _origin.x = _graphic_origin.x + _tile_height; _origin.y = _graphic_origin.y; // storing TileSet pointer _tile_set = ts; // dimensions of the map _width = (num_cols + num_rows) * _tile_height; _height = _width / 2; // number of used images _num_images = ts->GetNumImg(); // number of cells and objects _num_cells = num_cols * num_rows; _num_objects = _num_cells; for(r = 0; r < _num_rows; r++) { for(c = 0; c < _num_cols; c++) { ind_img = (rand() % _num_images); // create a new tile constr_tile = new Tile(ts->GetImage(ind_img)); // set indexes of the new tile constr_tile->SetIndexes(r,c); // set tile isometric position constr_p.x = (c - r) * _tile_height + _graphic_origin.x; constr_p.y = (c + r) * half_height + _graphic_origin.y; constr_tile->SetPosition(constr_p); // adding it to tiles vector _objects.push_back(constr_tile); } } } // blit the map on a surface void IsoTilesMap::BlitLayer(SDL_Rect limits_rect, Surface * dst_surf) { Sint16 l_limit = limits_rect.x ; Sint16 r_limit = limits_rect.x + limits_rect.w; Sint16 u_limit = limits_rect.y; Sint16 b_limit = limits_rect.y + limits_rect.h; Image * cur_img; Tile * cur_tile; IntPoint p; FloatPoint * start, * end; int s_row, s_col, e_row, e_col; // compute start row => top, right corner start = iso2scr(r_limit, u_limit, _origin.x, _origin.y); s_row = (int)(start->y / _square_side) - 1; if(s_row < 0) s_row = 0; delete start; // compute start col => top, left corner start = iso2scr(l_limit, u_limit, _origin.x, _origin.y); s_col = (int)(start->x / _square_side) - 1; if(s_col < 0) s_col = 0; delete start; // compute end row => bottom, left corner end = iso2scr(l_limit, b_limit, _origin.x, _origin.y); // row and col of the end IntPoint e_row = (int)(end->y / _square_side) + 1; if(e_row > _num_rows) e_row = _num_rows; delete end; // compute end col => bottom, right corner end = iso2scr(r_limit, b_limit, _origin.x, _origin.y); e_col = (int)(end->x / _square_side) + 1; if(e_col > _num_cols) e_col = _num_cols; delete end; for(int r = s_row; r < e_row ; r++) { for(int c = s_col; c < e_col; c++) { cur_tile = (Tile *) _objects[(r * _num_cols) + c]; p.x = cur_tile->GetX(); p.y = cur_tile->GetY(); //check if this tile need to be blitted if( cur_tile->IsVisible() && (p.x + _tile_width >= l_limit) && (p.x <= r_limit) && (p.y + _tile_height >= u_limit) && (p.y <= b_limit)) { cur_img = cur_tile->GetImage(); //set blit position of the image cur_img->SetPosition(p.x - l_limit, p.y - u_limit); blitter->Blit(cur_img, dst_surf); } } } } // check if a IntPoint is inside the map passing 2 int bool IsoTilesMap::IsInsideMap(Sint16 x, Sint16 y) { FloatPoint * scr; int row, col; IntPoint iso; iso.x = x; iso.y = y; scr = iso2scr(iso, _origin); // outside the map if(scr->x < 0 || scr->y < 0) { delete scr; return false; } // row and col of the IntPoint row = (int)(scr->y / _square_side); col = (int)(scr->x / _square_side); delete scr; // outside the map if(row >= _num_rows || col >= _num_cols) return false; // inside the map return true; } // return the cell indexes of the selected point if the selection is inside the // map, NULL otherwise CellInd * IsoTilesMap::GetCell(Sint16 x, Sint16 y) { FloatPoint * scr; IntPoint iso; CellInd * ind = new CellInd; iso.x = x; iso.y = y; scr = iso2scr(iso, _origin); // outside the map if(scr->x < 0 || scr->y < 0) { delete scr; delete ind; return NULL; } // row and col of the IntPoint ind->row = (int)(scr->y / _square_side); ind->col = (int)(scr->x / _square_side); delete scr; // outside the map if(ind->row >= _num_rows || ind->col >= _num_cols) return NULL; // inside the map, return indexes return ind; } // vertical flip of the layer void IsoTilesMap::VFlip() { // temporary tile pointer Tile * temp_tile; Tile * tile1; Tile * tile2; IntPoint temp_pos; int ind1, ind2; int h_rows = _num_rows / 2; for(int r = 0; r < h_rows; r++) { for(int c = 0; c < _num_cols; c++) { ind1 = (r * _num_cols) + c; ind2 = ((_num_rows - 1 - r) * _num_cols) + (_num_cols - 1 - c); tile1 = (Tile *) _objects[ind1]; tile2 = (Tile *) _objects[ind2]; // swap opposite elements temp_tile = tile1; _objects[ind1] = tile2; _objects[ind2] = temp_tile; // store tile1 position temp_pos.x = tile1->GetX(); temp_pos.y = tile1->GetY(); // swap position between tile1 and tile2 tile1->SetIndexes(r, c); tile1->SetPosition(tile2->GetX(), tile2->GetY()); tile2->SetIndexes((_num_rows - 1 - r), (_num_cols - 1 - c)); tile2->SetPosition(temp_pos); } } }