int clearance(const SDL_Rect& tile, const TileMap& map, const std::vector<SDL_Rect> colliders) { auto hitsBoundary = [&](const SDL_Rect& tile) { return tile.x + tile.w > map.wp || tile.y + tile.h > map.hp; }; auto expand = [&](int range) { for (int c = 0; c < range; c++) { for (int r = 0; r < range; r++) { SDL_Rect neighbor{ tile.x + (map.tileW * c), tile.y + (map.tileH * r), map.tileW, map.tileH }; auto it = std::find_if(colliders.begin(), colliders.end(), [&](const SDL_Rect& collider) { return collidesWith(neighbor, collider); }); if (it != colliders.end() || hitsBoundary(neighbor)) return false; } } return true; }; int result = 1; int range = 2; while (expand(range++)) result++; return result; }
bool Entity::inViewport() { glm::vec2 viewportSize = _game->getGameplayScreen()->getMainCamera()->getViewportSize() / _game->getGameplayScreen()->getMainCamera()->getScale(); glm::vec2 cameraPosition = _game->getGameplayScreen()->getMainCamera()->getPosition() / _game->getGameplayScreen()->getMainCamera()->getZoom(); return collidesWith(viewportSize.x, viewportSize.y, cameraPosition); }
bool Entity::collidesWith(Entity* anotherEntity) { b2Vec2 bPosition = anotherEntity->getBody()->GetPosition(); bool result = collidesWith(anotherEntity->_width, anotherEntity->_height, glm::vec2(bPosition.x, bPosition.y)); if(result) { anotherEntity->setColor(Ess2D::ColorRGBA8(235, 0, 0, 255)); } else { anotherEntity->setColor(Ess2D::ColorRGBA8(255, 255, 255, 255)); } return result; }
void EnemyProjectile::move(float delta, std::vector<LevelObject*> levelObjects) { m_xPos += m_xVel * delta; m_yPos += m_yVel * delta; for(unsigned int a = 0; a < levelObjects.size(); a++) { if(collidesWith(levelObjects[a])) { m_isDead = true; break; } } }
void Floater::moveBy(double dx, double dy) { if (!isEnabled()) return; QCanvasItemList l = collisions(false); for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it) { CanvasItem *item = dynamic_cast<CanvasItem *>(*it); if (!noUpdateZ && item && item->canBeMovedByOthers()) item->updateZ(this); if ((*it)->z() >= z()) { if (item && item->canBeMovedByOthers() && collidesWith(*it)) { if ((*it)->rtti() == Rtti_Ball) { //((Ball *)(*it))->setState(Rolling); (*it)->moveBy(dx, dy); if (game && game->hasFocus() && !game->isEditing() && game->curBall() == (Ball *)(*it)) game->ballMoved(); } else if ((*it)->rtti() != Rtti_Putter) (*it)->moveBy(dx, dy); } } } point->dontMove(); point->move(x() + width(), y() + height()); // this call must come after we have tested for collisions, otherwise we skip them when saving! // that's a bad thing QCanvasRectangle::moveBy(dx, dy); // because we don't do Bridge::moveBy(); topWall->move(x(), y()); botWall->move(x(), y() - 1); leftWall->move(x(), y()); rightWall->move(x(), y()); if (game && game->isEditing()) game->updateHighlighter(); }
bool OverlapFilterCallback::needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const { bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); //add some additional logic here that modified 'collides' if (collides) { btCollisionObject* bt_collision_object0 = (btCollisionObject*) proxy0->m_clientObject; btCollisionObject* bt_collision_object1 = (btCollisionObject*) proxy1->m_clientObject; if ((bt_collision_object0->getUserPointer() == NULL) || (bt_collision_object1->getUserPointer() == NULL)) { return false; } auto element0 = static_cast< Element* >(bt_collision_object0->getUserPointer()); auto element1 = static_cast< Element* >(bt_collision_object1->getUserPointer()); collides = collides && element0->collidesWith(element1); } return collides; }
bool BoundingBoxSet::collidesWith(const BoundingBoxSet otherBoxSet, const glm::vec3 thisOffset, const glm::vec3 thisRotation, const glm::vec3 otherOffset, const glm::vec3 otherRotation) const { bool collides = false; glm::mat4 rotationMatrix = glm::rotate( glm::rotate( glm::rotate(glm::mat4x4(1.0f), otherRotation.z, glm::vec3(0.0f, 0.0f, -1.0f)), otherRotation.x, glm::vec3(-1.0f, 0.0f, 0.0f)), otherRotation.y, glm::vec3(0.0f, -1.0f, 0.0f)); for (auto vertex = otherBoxSet.vertices.begin(); vertex != otherBoxSet.vertices.end(); ++vertex) { glm::vec4 otherCoords(vertex->at(0), vertex->at(1), vertex->at(2), 1.0f); glm::vec4 rotatedOtherCoords; rotatedOtherCoords = rotationMatrix * otherCoords; rotatedOtherCoords.x += otherOffset.x; rotatedOtherCoords.y += otherOffset.y; rotatedOtherCoords.z += otherOffset.z; if (collidesWith(glm::vec3(rotatedOtherCoords.x, rotatedOtherCoords.y, rotatedOtherCoords.z), thisOffset, thisRotation)) { collides = true; break; } } return collides; }
void Player::move(float delta, std::vector<LevelObject*> levelObjects) { m_delta = delta; m_groundMarked = false; m_yVel += getGravityDistance(delta); float m_yMove = delta * m_yVel; m_yPos += m_yMove; updateBoxes(); for(unsigned int a = 0; a < levelObjects.size(); a++) { if(collidesWith(levelObjects[a])) { m_yPos -= m_yMove; if(m_yMove > 0.0f) { m_isOnGround = true; m_groundMarked = true; m_jumping = false; } updateBoxes(); m_yVel = 0.0f; break; } } if(!m_groundMarked) { m_isOnGround = false; } /* Set the x-speed */ if(m_knockedBack) { if(m_direction == DIR_LEFT) { m_xVel -= delta * SettingsManager::getSettings()->PLAYER_KNOCKBACK_SPEED_X_DECREASE; if(m_xVel <= 0.0f) { m_xVel = 0.0f; m_knockedBack = false; } } else if(m_direction == DIR_RIGHT) { m_xVel += delta * SettingsManager::getSettings()->PLAYER_KNOCKBACK_SPEED_X_DECREASE; if(m_xVel >= 0.0f) { m_xVel = 0.0f; m_knockedBack = false; } } float m_xMove = delta * m_xVel; m_xPos += m_xMove; for(unsigned int a = 0; a < levelObjects.size(); a++) { if(m_xVel == 0) { while(collidesWith(levelObjects[a])) { if(m_direction == DIR_LEFT) { m_xPos -= 1; } else if(m_direction == DIR_RIGHT) { m_xPos += 1; } updateBoxes(); } } else if(collidesWith(levelObjects[a])) { m_xPos -= m_xMove; m_xVel = 0.0f; updateBoxes(); break; } } updateBoxes(); } else { if(m_markedForHalt && !m_isBlocking) { if(m_xVel > 0.0f) { m_xVel -= SettingsManager::getSettings()->PLAYER_SPEED_SIDE_HALTING * delta; if(m_xVel < 0.0f){m_xVel = 0.0f;} float m_xMove = delta * m_xVel; m_xPos += m_xMove; updateBoxes(); for(unsigned int a = 0; a < levelObjects.size(); a++) { if(collidesWith(levelObjects[a])) { m_xPos -= m_xMove; m_xVel = 0.0f; updateBoxes(); break; } } } else { m_xVel += SettingsManager::getSettings()->PLAYER_SPEED_SIDE_HALTING * delta; if(m_xVel > 0.0f){m_xVel = 0.0f;} float m_xMove = delta * m_xVel; m_xPos += m_xMove; updateBoxes(); for(unsigned int a = 0; a < levelObjects.size(); a++) { if(collidesWith(levelObjects[a])) { m_xPos -= m_xMove; m_xVel = 0.0f; updateBoxes(); break; } } } } else if(!m_isBlocking) { float m_xMove = delta * m_xVel; m_xPos += m_xMove; updateBoxes(); for(unsigned int a = 0; a < levelObjects.size(); a++) { if(collidesWith(levelObjects[a])) { m_xPos -= m_xMove; m_xVel = 0.0f; updateBoxes(); break; } } } } updateBoxes(); }
std::vector<TileNode> getNeighborhood(const TileNode& node, const SDL_Rect& finalNode, const TileMap& map, const std::vector<SDL_Rect> colliders) { std::vector<TileNode> neighbourhood; auto inBounds = [&](const SDL_Rect& rect) { return rect.x >= 0 && rect.x + rect.w <= map.wp && rect.y >= 0 && rect.y + rect.h <= map.hp; }; for (int r = 0; r < 3; r++) { for (int c = 0; c < 3; c++) { if (r == 1 && c == 1) // its the center node continue; SDL_Rect rect{ node.rect.x + (int)((c - 1) * node.rect.w), node.rect.y + (int)((r - 1) * node.rect.h), node.rect.w, node.rect.h }; if (inBounds(rect)) { auto it = std::find_if(colliders.begin(), colliders.end(), [&](const SDL_Rect& collider) { return collidesWith(rect, collider); }); if (it == colliders.end()) { bool diagonal = (r == 0 && c == 0) || (r == 0 && c == 2) || (r == 2 && c == 0) || (r == 2 && c == 2); bool skip = false; if (diagonal) // check if the diagonal tile has a collider neighbour, if so skip it. { for (int r1 = 0; r1 < 3; r1++) { for (int c1 = 0; c1 < 3; c1++) { if (r1 == 1 && c1 == 1) // its the center node continue; SDL_Rect rect1{ rect.x + (int)((c1 - 1) * rect.w), rect.y + (int)((r1 - 1) * rect.h), rect.w, node.rect.h }; auto it1 = std::find_if(colliders.begin(), colliders.end(), [&](const SDL_Rect& collider) { return collidesWith(rect1, collider); }); skip = it1 != colliders.end(); if (skip) break; } if (skip) break; } } if (!skip) { TileNode neighbourNode; neighbourNode.rect = rect; neighbourNode.g = (diagonal ? 14 : 10) + node.g; neighbourNode.h = manhattanHeuristic(rect, finalNode, map) * 10; neighbourNode.parent = (TileNode *)&node; neighbourhood.push_back(neighbourNode); } } } } } return neighbourhood; }
void BuyState::receive(const InputEvent &input) { #ifdef ANDROID_BUILD int x, y; switch (input.evt_.type) { case SDL_KEYUP: if (input.evt_.key.keysym.sym == SDLK_AC_BACK) { game_.toPop_ = name(); } break; case SDL_FINGERUP: game_.toPop_ = name(); break; case SDL_FINGERDOWN: case SDL_FINGERMOTION: x = input.evt_.tfinger.x * game_.screen_width_; y = input.evt_.tfinger.y * game_.screen_height_; SDL_Rect mouseRect{ x, y, 10, 10 }; SDL_Rect turretRect = getRect(turret_); if (!collidesWith(mouseRect, turretRect)) { Game::getInstance().toPop_ = name(); } else { if(!gamePlay_->paused_ && gamePlay_->playerGold_ >= ti_.cost_) { gamePlay_->paused_ = true; Game::getInstance().toPop_ = name(); Game::getInstance().pushState(std::make_shared<TurretTrackState>(ti_, gamePlay_, x ,y)); } } } #else int x, y; switch (input.evt_.type) { case SDL_KEYUP: if (input.evt_.key.keysym.sym == SDLK_AC_BACK) { game_.toPop_ = name(); } break; case SDL_MOUSEBUTTONUP: SDL_GetMouseState(&x, &y); switch (input.evt_.button.button) { case SDL_BUTTON_LEFT: if(!gamePlay_->paused_ && gamePlay_->playerGold_ >= ti_.cost_) { gamePlay_->paused_ = true; Game::getInstance().toPop_ = name(); Game::getInstance().pushState(std::make_shared<TurretTrackState>(ti_, gamePlay_, x ,y)); } break; } } #endif }
//Fixed_TimeStep gets passed to each entity via elapsed void Entity::Update(float elapsed, std::vector<Entity> entities){ //loop through vector of entities to check collisions //adjust position and velocity(?) depending on collisions if (!isStatic){ //check if an object is dynamic (and needs to be updated) switch (entityType){ case TYPE_PLAYER: if (velocity_y != 0.0f || velocity_x != 0.0f){ collidedBottom = false; collidedTop = false; collidedLeft = false; collidedRight = false; } if (collidedBottom == true){ acceleration_y = 0.0; velocity_y = 0.0f; } else if (acceleration_y > 0){ acceleration_y = -gravity_y; } else{ acceleration_y = gravity_y; } velocity_x = lerp(velocity_x, 0.0f, elapsed * friction_x); velocity_y = lerp(velocity_y, 0.0f, elapsed * friction_y); velocity_x += acceleration_x * elapsed; velocity_y += acceleration_y * elapsed; //WIP Assigment 04 Penetration adjustments y += velocity_y * elapsed; //Checking collision with static entities on y axis for (int i = 0; i < entities.size(); i++){ Entity * tempEntity = &(entities[i]); if (tempEntity->isStatic == true){ if (collidesWith(tempEntity)){ float penetration = fabs(fabs(y - tempEntity->y) - height / 2.0f - tempEntity->height / 2.0f); if (y > tempEntity->y){ y += penetration + 0.0001; collidedBottom = true; } else{ y -= penetration + 0.0001; collidedTop = true; } velocity_y = 0.0f; } } } x += velocity_x * elapsed; // Checking collision with static entities on x axis for (int i = 0; i < entities.size(); i++){ Entity * tempEntity = &(entities[i]); if (tempEntity->isStatic == true){ if (collidesWith(tempEntity)){ float penetration = fabs(fabs(x - tempEntity->x) - width / 2.0f - tempEntity->width / 2.0f); if (x > tempEntity->x){ x += penetration + 0.0001; collidedLeft = true; } else{ x -= penetration + 0.0001; collidedRight = true; } velocity_x = 0.0f; } } } //check collision with sides /*if (x + 2 * width >= 3.5f && velocity_x > 0){ x = 3.5f - 2 * width; } else if (x - 2 * width <= -3.5f && velocity_x < 0){ x = -3.5f + 2 * width; } //check collision with top and bottom if (y + 2 * height >= 1.75f && velocity_y > 0){ y = 1.75f - 2 * height; } else if (y - 2 * height <= -1.75f && velocity_y < 0){ y = -1.75f + 2 * height; }*/ //WIP Entity Interaction //check list of entities and do something based on their type //check collision with enemies for (int i = 0; i < entities.size(); i++){ //check if player collides with a non-player entity if (collidesWith(&(entities[i]))){ if (entities[i].entityType == TYPE_ENEMY){ entities[i].visible = false; visible = false; } } else{ // not intersecting } } break; case TYPE_ENEMY: x += velocity_x * elapsed; //check collision with sides if (x + 2 * width >= 3.5f){ y -= height * 4; x = 3.0f; velocity_x = -velocity_x; } else if (x - 2 * width <= -3.5){ y -= height * 4; x = -3.0f; velocity_x = -velocity_x; } break; case TYPE_BULLET: // Bullet::timeAlive += fixedElapsed; //x += sin(rotation) * speed * elapsed; y += velocity_y * elapsed; for (int i = 0; i < entities.size(); i++){ //check if bullet collides with an entity if (collidesWith(&(entities[i]))){ //intersecting if (entities[i].entityType == TYPE_ENEMY){ entities[i].visible = false; visible = false; } } else{ // not intersecting } } break; } } }