1
General / How to keep the player on the grid, with smooth movement?
« on: June 10, 2021, 09:39:50 am »
Hi!
I want to remake the Xonix game.
I want my player (the yellow creature, Pikachu) to be able to move only "from cell to cell", so it can't stay in between.
The following situation is unwanted, because the player stands in the middle of a cell(s).
The green area is where I stepped.
How can I make the player move smoothly only within the cells?
(it already scaled to the size of the cell)
Controller Class:
Player class:
void Player::update(float deltaTime)
{
sf::Vector2f movement(0.0f, 0.0f);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
movement.x -= m_speed * deltaTime;
m_row = 0;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
movement.x += m_speed * deltaTime;
m_row = 1;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
movement.y += m_speed * deltaTime;
m_row = 2;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
movement.y -= m_speed * deltaTime;
m_row = 3;
}
else // stay in place
{
m_row = 2;
}
if (movement.x > 0.0f) // we moved right
m_dir = Direction::Right;
else if (movement.x < 0.0f)
m_dir = Direction::Left;
else if (movement.y > 0.0f) // we moved down
m_dir = Direction::Down;
else if (movement.y < 0.0f)
m_dir = Direction::Up;
else
m_dir = Direction::Stay;
Object::update(m_row, deltaTime, m_dir);
m_sprite.move(movement);
}
Object class:
Animation class:
void Animation::update(int row, float deltaTime, Direction dir)
{
m_currentImage.y = row;
m_totalTime += deltaTime;
if (m_totalTime >= m_switchTime)
{
m_totalTime -= m_switchTime;
m_currentImage.x++;
if (m_currentImage.x >= m_imageCount.x)
m_currentImage.x = 0;
}
uvRect.left = m_currentImage.x * uvRect.width;
uvRect.top = m_currentImage.y * uvRect.height;
}
Collision handler: (it is not complete yet )
Thank you very much!
I want to remake the Xonix game.
I want my player (the yellow creature, Pikachu) to be able to move only "from cell to cell", so it can't stay in between.
The following situation is unwanted, because the player stands in the middle of a cell(s).
The green area is where I stepped.
How can I make the player move smoothly only within the cells?
(it already scaled to the size of the cell)
Controller Class:
while (window.isOpen())
{
if (auto event = sf::Event{}; window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
m_board.handleCollisions();
deltaTime = clock.restart().asSeconds();
window.clear(sf::Color::White);
m_board.updateObjects(deltaTime);
drawObjects(window, m_windowType);
window.display();
}
{
if (auto event = sf::Event{}; window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
m_board.handleCollisions();
deltaTime = clock.restart().asSeconds();
window.clear(sf::Color::White);
m_board.updateObjects(deltaTime);
drawObjects(window, m_windowType);
window.display();
}
Player class:
void Player::update(float deltaTime)
{
sf::Vector2f movement(0.0f, 0.0f);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
movement.x -= m_speed * deltaTime;
m_row = 0;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
movement.x += m_speed * deltaTime;
m_row = 1;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
movement.y += m_speed * deltaTime;
m_row = 2;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
movement.y -= m_speed * deltaTime;
m_row = 3;
}
else // stay in place
{
m_row = 2;
}
if (movement.x > 0.0f) // we moved right
m_dir = Direction::Right;
else if (movement.x < 0.0f)
m_dir = Direction::Left;
else if (movement.y > 0.0f) // we moved down
m_dir = Direction::Down;
else if (movement.y < 0.0f)
m_dir = Direction::Up;
else
m_dir = Direction::Stay;
Object::update(m_row, deltaTime, m_dir);
m_sprite.move(movement);
}
Object class:
{
m_animation.update(row, deltaTime, dir);
m_sprite.setTextureRect(m_animation.uvRect);
}
m_animation.update(row, deltaTime, dir);
m_sprite.setTextureRect(m_animation.uvRect);
}
Animation class:
void Animation::update(int row, float deltaTime, Direction dir)
{
m_currentImage.y = row;
m_totalTime += deltaTime;
if (m_totalTime >= m_switchTime)
{
m_totalTime -= m_switchTime;
m_currentImage.x++;
if (m_currentImage.x >= m_imageCount.x)
m_currentImage.x = 0;
}
uvRect.left = m_currentImage.x * uvRect.width;
uvRect.top = m_currentImage.y * uvRect.height;
}
Collision handler: (it is not complete yet )
void playerTile(Object& player,
Object& tile)
{
Player& p = static_cast<Player&>(player);
Tile& t = static_cast<Tile&>(tile);
switch (t.getOccupationStatus())
{
case Occupation::Free:
t.setOccupied(Occupation::Potential);
break;
case Occupation::Potential:
// p.incPlayerHPBy(-1);
break;
case Occupation::Occupied:
//p.closedArea(); // ----- to be added :)
case Occupation::TrappedArea:
break;
}
}
Object& tile)
{
Player& p = static_cast<Player&>(player);
Tile& t = static_cast<Tile&>(tile);
switch (t.getOccupationStatus())
{
case Occupation::Free:
t.setOccupied(Occupation::Potential);
break;
case Occupation::Potential:
// p.incPlayerHPBy(-1);
break;
case Occupation::Occupied:
//p.closedArea(); // ----- to be added :)
case Occupation::TrappedArea:
break;
}
}
Thank you very much!