void World::handleInput() { sf::Event event; while(mWindow.pollEvent(event)) { if(event.type == sf::Event::Closed) mWindow.close(); else if(event.type == sf::Event::KeyReleased) { if(event.key.code == sf::Keyboard::Escape) mGameState.pause(); } else if(event.type == sf::Event::MouseButtonPressed) { sf::Vector2i mousePos; sf::FloatRect vBounds = getViewBounds(); mousePos.x = sf::Mouse::getPosition(mWindow).x + vBounds.left; mousePos.y = sf::Mouse::getPosition(mWindow).y + vBounds.top; sf::Vector2f mousePosF(mousePos.x, mousePos.y); if(event.mouseButton.button == sf::Mouse::Left) { mousePosF.x = std::min(mousePosF.x, static_cast<float>(mWorldBounds.width - (mLevelBlockSize + mWaypointRadius))); mousePosF.x = std::max(mousePosF.x, static_cast<float>(mLevelBlockSize + mWaypointRadius)); mousePosF.y = std::min(mousePosF.y, static_cast<float>(mWorldBounds.height - (mLevelBlockSize + mWaypointRadius))); mousePosF.y = std::max(mousePosF.y, static_cast<float>(mLevelBlockSize + mWaypointRadius)); if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) { if(mDog) mDog->addToPath(mousePosF); } else { if(mDog) mDog->startNewPath(mousePosF); } } } } handleRealTimeInput(); }
// Don't rely on events for key handling; poll the keys in the main loop, so that it doesn't stutter (events are less frequent). void PlayerUnit::move(shared_ptr<sf::RenderWindow> pwin, float speedFactor) { float speed = baseSpeed * speedFactor; sf::Vector2f vel{ 0.f, 0.f }; sf::Vector2f pos = ps->getPosition(); sf::FloatRect sz = ps->getGlobalBounds(); sf::Vector2u wsize = pwin->getSize(); if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) { // Shift key is pressed; go twice as fast. speed *= 2.0f; } // Keyboard if (sf::Keyboard::isKeyPressed(sf::Keyboard::W) || sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { vel.y -= 1.0f; // UP } if (sf::Keyboard::isKeyPressed(sf::Keyboard::S) || sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { vel.y += 1.0f; // Down } if (sf::Keyboard::isKeyPressed(sf::Keyboard::A) || sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { vel.x -= 1.0f; // Left } if (sf::Keyboard::isKeyPressed(sf::Keyboard::D) || sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { vel.x += 1.0f; // Right } // Mouse if (vel.x == 0.f && vel.y == 0.f) { // Keyboard didn't change the speed, so we'll use the mouse instead, as long as its buttons aren't pressed. if (!sf::Mouse::isButtonPressed(sf::Mouse::Left) && !sf::Mouse::isButtonPressed(sf::Mouse::Right)) { sf::Vector2i mousePos = sf::Mouse::getPosition(*pwin); // Can this be outside the bounds of the current window? Does that matter? sf::Vector2f mousePosF(mousePos); // convert to float vel = mousePosF - pos; // Avoid shaking; don't move at all if the velocity is very small. const float t{ 0.1f }; // threshold if (vel.x > -t && vel.x < t && vel.y > -t && vel.y < t ) { vel.x = 0.f; vel.y = 0.f; } } } // Make sure we don't move outside the bounds of the window if (((sz.left + sz.width) >= wsize.x) && vel.x > 0.f) vel.x = 0.f; else if (sz.left <= 0 && vel.x < 0.f) vel.x = 0.f; if ((sz.top + sz.height) >= wsize.y && vel.y > 0.f) vel.y = 0.f; else if (sz.top <= 0 && vel.y < 0.f) vel.y = 0.f; // Normalize vel so you don't move twice as fast when moving diagonally. VectorNormalize(vel); ps->move(vel * speed); }