void Map::Render(const SVector2& offset, OtherPlayers& otherPlayers) { // Used in bounding box checks later sOffset = offset; int tiles = mMapData.GetTileAmount(); SGE::Graphics_DebugUsageBegin("Ground"); // Render Ground for (int a = 0; a < tiles; ++a) { GroundTile* pTile = &mMapData.mLayer1[a]; int type = pTile->GetType(); if (type) { const SVector2& pos = pTile->GetPosition(); mSprites[type].SetPosition(pos + offset); mSprites[type].Render(); } } SGE::Graphics_DebugUsageEnd(); SGE::Graphics_DebugUsageBegin("MaskItems"); // Render Mask for (int a = 0; a < tiles; ++a) { Tile* pTile = &mMapData.mLayer2[a]; int type = pTile->GetType(); if (type) { const SVector2& pos = pTile->GetPosition(); mSprites[type].SetPosition(pos + offset); mSprites[type].Render(); } // Render Items if (mMapData.mLayer1[a].GetItemImageNumber() > 0 && GetItemActive(a)) { SVector2 pos = SVector2(mMapData.mLayer1[a].GetPosition().y, mMapData.mLayer1[a].GetPosition().x); // Bug int type = mMapData.mLayer1[a].GetItemImageNumber(); if (type > 0 && type < mNumberOfItems) { mItemSprites[type].mSprite.SetPosition(pos + offset); mItemSprites[type].mSprite.Render(); } } } SGE::Graphics_DebugUsageEnd(); SGE::Graphics_DebugUsageBegin("NPCs"); // Render NPCS for (int a = 0; a < mNumberOfNPCS; ++a) { mNPCS[a]->Render(offset); } SGE::Graphics_DebugUsageEnd(); SGE::Graphics_DebugUsageBegin("Players"); // Render Character mCharacter.Render(offset); // Render other players otherPlayers.Render(offset); SGE::Graphics_DebugUsageEnd(); SGE::Graphics_DebugUsageBegin("Extras"); // Render Extra for (int a = 0; a < tiles; ++a) { SVector2 pos = mMapData.mLayer3[a].GetPosition(); int type = mMapData.mLayer3[a].GetType(); mSprites[type].SetPosition(pos + offset); mSprites[type].Render(); } SGE::Graphics_DebugUsageEnd(); SGE::Graphics_DebugUsageBegin("Fringe"); // Render Fringe for (int a = 0; a < tiles; ++a) { SVector2 pos = mMapData.mLayer4[a].GetPosition(); int type = mMapData.mLayer4[a].GetType(); mSprites[type].SetPosition(pos + offset); mSprites[type].Render(); } SGE::Graphics_DebugUsageEnd(); SGE::Graphics_DebugUsageBegin("WeatherPaths"); mWeather.Render(offset); mPathFinding.Render(offset); SGE::Graphics_DebugUsageEnd(); }
bool Collision::collide(sf::Sprite& obj, float dx, float dy, CollisionResult& result) { //assert(_map->tileFromPixel(obj.GetPosition().x, obj.GetPosition().y)->isWalkable()); //assert(_map->tileFromPixel(obj.GetPosition().x + obj.GetSize().x, obj.GetPosition().y)->isWalkable()); std::cout << "posx: " << obj.GetPosition().x << std::endl; std::cout << "posy: " << obj.GetPosition().y << std::endl; std::cout << "dx: " << dx << std::endl; std::cout << "dy: " << dy << std::endl; result.left = false; result.right = false; result.floor = false; result.ceil = false; result.dx = dx; result.dy = dy; if(dx != 0.f) { //if moving horizontal bool left = dx < 0; float forwardX; if(left) forwardX = obj.GetPosition().x; else forwardX = obj.GetPosition().x + obj.GetSize().x; float newX = forwardX + dx; float topY = obj.GetPosition().y + constants::COLLISION_MARGIN; float botY = obj.GetPosition().y + obj.GetSize().y - constants::COLLISION_MARGIN; Tile* topTile = _map->tileFromPixel(newX, topY); Tile* botTile = _map->tileFromPixel(newX, botY); if(!topTile->isWalkable() || !botTile->isWalkable()) { result.left = left; result.right = !left; float limit; if(left) limit = topTile->GetPosition().x + topTile->GetSize().x; else limit = topTile->GetPosition().x; result.dx = limit - forwardX; } std::cout << "res.dx=" << result.dx << std::endl; assert(left || result.dx <= dx); assert(!left || result.dx >= dx); //assert(result.dx * dx >= 0); //same direction } float objPosX = obj.GetPosition().x + result.dx; if(dy != 0.f) { //if moving vertically bool down = dy > 0; float forwardY; if(down) forwardY = obj.GetPosition().y + obj.GetSize().y; else forwardY = obj.GetPosition().y; float newY = forwardY + dy; Tile* leftTileY = _map->tileFromPixel(objPosX + constants::COLLISION_MARGIN, newY); Tile* rightTileY = _map->tileFromPixel(objPosX + obj.GetSize().x - constants::COLLISION_MARGIN, newY); if(!leftTileY->isWalkable() || !rightTileY->isWalkable()) { result.floor = down; result.ceil = !down; float limit; if(down) limit = leftTileY->GetPosition().y;// - constants::COLLISION_MARGIN; else limit = leftTileY->GetPosition().y + leftTileY->GetSize().y;// + constants::COLLISION_MARGIN; result.dy = limit - forwardY; } std::cout << "res.dy=" << result.dy << std::endl; assert(down || result.dy >= dy); assert(!down || result.dy <= dy); //assert(result.dy * dy >= 0); //same direction } return result.floor || result.ceil || result.left || result.right; }
sf::Vector2f Colisionable::evalCollisions(sf::Vector2f posOld, sf::Vector2f posNew, sf::Vector2f size){ /* float dist= sqrt((posNew.x-posOld.x)*(posNew.x-posOld.x)+(posNew.y-posOld.y)*(posNew.y-posOld.y)); while(dist>Settings::TILE_SIZE){ sf::Vector2f posOldOld = posOld; float ratio = (Settings::TILE_SIZE-1)/dist; sf::Vector2f newPosAux(((1-ratio)*posOld.x+ratio*posNew.x),((1-ratio)*posOld.y+ratio*posNew.y)); posOld = evalCollisions(posOld,newPosAux,size); if(posOldOld == posOld) return posOld; dist= sqrt((posNew.x-posOld.x)*(posNew.x-posOld.x)+(posNew.y-posOld.y)*(posNew.y-posOld.y)); }*/ sf::Vector2f pos_aux(posNew.x, posNew.y); sf::Vector2f size_aux(size.x, size.y); Map* map = Scene::getScene()->getMap(); Tile* firstT = map->getTile(pos_aux.x, pos_aux.y, 1); Tile* lastT = map->getTile(pos_aux.x+size_aux.x, pos_aux.y+size_aux.y, 1); if(firstT != nullptr && lastT != nullptr){ col_bottom = 0; col_top = 0; col_left = 0; col_right = 0; col_bottom_dist = 0; col_top_dist = 0; col_left_dist = 0; col_right_dist = 0; std::vector<Tile*> tiles_col = map->getTilesCol(pos_aux, size_aux); //std::cout << "number of cols" << tiles_col._size() << std::endl; //std::cout << "lel" << std::endl; for(int i = 0; i< tiles_col.size(); ++i){ // //comproba colisions Tile* t = tiles_col[i]; sf::Vector2f tile_size(t->getWidth(), t->getHeight()); FixColision(pos_aux, size_aux, t->GetPosition(), tile_size); } bool valid_move = true; if(bool(col_bottom) + bool(col_left) + bool(col_right) + bool(col_top) >=3) valid_move = false; if(abs(posNew.x-posOld.x) > Settings::TILE_SIZE*3 || abs(posNew.y-posOld.y) > Settings::TILE_SIZE*3) { //float dist= sqrt((posNew.x-posOld.x)*(posNew.x-posOld.x)+(posNew.y-posOld.y)*(posNew.y-posOld.y)); valid_move = false; } if(col_bottom >= col_top){ col_top = 0; posNew.y = posNew.y - col_bottom_dist; } else{ col_bottom = 0; posNew.y = posNew.y + col_top_dist; } if(col_left >= col_right){ col_right = 0; posNew.x = posNew.x + col_left_dist; } else{ col_left = 0; posNew.x = posNew.x - col_right_dist; } if(valid_move) return posNew; else { return evalCollisions(sf::Vector2f(posOld.x,posOld.y-32),sf::Vector2f(posOld.x,posOld.y-32),size); } } return posOld; }