Skip to content

Commit 5ddd402

Browse files
committed
Added wall collision for ne and se directions
1 parent 09d15a2 commit 5ddd402

File tree

5 files changed

+91
-29
lines changed

5 files changed

+91
-29
lines changed

Player.cpp

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
#include <iostream>
2+
13
#include "Player.hpp"
24
#include <SFML/Window/Keyboard.hpp>
5+
#include <SFML/Graphics.hpp>
36

47
Player::Player()
58
: texture{},
@@ -78,34 +81,41 @@ Player::Player()
7881
sprintingWestXStart = 240; sprintingWestYStart = 3120; sprintingWestXEnd = 1440; sprintingWestYEnd = 3120;
7982
}
8083

81-
void Player::handleInput() {
84+
void Player::handleInput(std::vector<sf::FloatRect> wallBounds) {
85+
// Predict future collision
86+
sf::FloatRect nextBounds = sprite.getGlobalBounds();
87+
8288
// If both right and up key pressed then move character right and up at same time
8389
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::Right) && sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::Up) || sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::D) && sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::W)) {
8490
moving = true; northEast = true;
8591
north = false; east = false; southEast = false; south = false; southWest = false; west = false; northWest = false;
86-
sprite.move({horizontalSpeed / 1.5f, -verticalSpeed / 1.5f});
87-
// Waits for set amount of time then plays Jog north east animation
88-
timer += 0.08f;
89-
// Sprinting animation
90-
if (timer >= timerMax && sprinting) {sprite.move({horizontalSpeed / 1.5f, -verticalSpeed / 1.5f}); textureX += 240; animate(sprintingNorthEastXStart, sprintingNorthEastXEnd,
91-
sprintingNorthEastYStart, sprintingNorthEastYEnd); timer = 0.0f;}
92-
// Jog animation
93-
else if (timer >= timerMax) {textureX += 240; animate(JogNorthEastXStart, JogNorthEastXEnd,
94-
JogNorthEastYStart, JogNorthEastYEnd); timer = 0.0f;}
92+
sf::Vector2f movement{horizontalSpeed / 1.5f, -verticalSpeed / 1.5f};
93+
if (!handleCollision(movement, nextBounds, wallBounds)) {
94+
// Waits for set amount of time then plays Jog north east animation
95+
timer += 0.08f;
96+
// Sprinting animation
97+
if (timer >= timerMax && sprinting) {sprite.move({horizontalSpeed / 1.5f, -verticalSpeed / 1.5f}); textureX += 240; animate(sprintingNorthEastXStart, sprintingNorthEastXEnd,
98+
sprintingNorthEastYStart, sprintingNorthEastYEnd); timer = 0.0f;}
99+
// Jog animation
100+
else if (timer >= timerMax) {textureX += 240; animate(JogNorthEastXStart, JogNorthEastXEnd,
101+
JogNorthEastYStart, JogNorthEastYEnd); timer = 0.0f;}
102+
}
95103
}
96104
// If both right and down key pressed then move character right and down at same time
97105
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::Right) && sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::Down) || sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::D) && sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::S)) {
98106
moving = true; southEast = true;
99107
north = false; northEast = false; east = false; south = false; southWest = false; west = false; northWest = false;
100-
sprite.move({horizontalSpeed / 1.5f, verticalSpeed / 1.5f});
101-
// Waits for set amount of time then plays Jog south east animation
102-
timer += 0.08f;
103-
// Sprinting animation
104-
if (timer >= timerMax && sprinting) {sprite.move({(horizontalSpeed / 1.5f) * 3, (verticalSpeed / 1.5f) * 3}); textureX += 240; animate(sprintingSouthEastXStart, sprintingSouthEastXEnd,
105-
sprintingSouthEastYStart, sprintingSouthEastYEnd); timer = 0.0f;}
106-
// Jog animation
107-
else if (timer >= timerMax) {textureX += 240; animate(JogSouthEastXStart, JogSouthEastXEnd,
108-
JogSouthEastYStart, JogSouthEastYEnd); timer = 0.0f;}
108+
sf::Vector2f movement{horizontalSpeed / 1.5f, verticalSpeed / 1.5f};
109+
if (!handleCollision(movement, nextBounds, wallBounds)) {
110+
// Waits for set amount of time then plays Jog south east animation
111+
timer += 0.08f;
112+
// Sprinting animation
113+
if (timer >= timerMax && sprinting) {sprite.move({(horizontalSpeed / 1.5f) * 3, (verticalSpeed / 1.5f) * 3}); textureX += 240; animate(sprintingSouthEastXStart, sprintingSouthEastXEnd,
114+
sprintingSouthEastYStart, sprintingSouthEastYEnd); timer = 0.0f;}
115+
// Jog animation
116+
else if (timer >= timerMax) {textureX += 240; animate(JogSouthEastXStart, JogSouthEastXEnd,
117+
JogSouthEastYStart, JogSouthEastYEnd); timer = 0.0f;}
118+
}
109119
}
110120
// If both left and up key pressed then move character left and up at same time
111121
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::Left) && sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::Up) || sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::A) && sf::Keyboard::isKeyPressed(sf::Keyboard::Scan::W)) {
@@ -236,6 +246,39 @@ void Player::handleInput() {
236246
}
237247
}
238248

249+
bool Player::handleCollision(sf::Vector2f movement, sf::FloatRect nextBounds, std::vector<sf::FloatRect> wallBounds) {
250+
// Full movement prediction
251+
nextBounds.position += movement;
252+
253+
for (const auto& wall : wallBounds) {
254+
if (nextBounds.findIntersection(wall).has_value()) {
255+
// Try horizontal-only movement
256+
sf::Rect<float> horizontalBounds = nextBounds;
257+
horizontalBounds.position.x -= movement.x; // Undo x movement
258+
259+
if (!horizontalBounds.findIntersection(wall).has_value()) {
260+
sprite.move({0.f, movement.y}); // Slide vertically
261+
return true;
262+
}
263+
264+
// Try vertical-only movement
265+
sf::Rect<float> verticalBounds = nextBounds;
266+
verticalBounds.position.y -= movement.y; // Undo y movement
267+
268+
if (!verticalBounds.findIntersection(wall).has_value()) {
269+
sprite.move({movement.x, 0.f}); // Slide horizontally
270+
return true;
271+
}
272+
273+
std::cout << "Blocked from all sides\n";
274+
return true; // Fully blocked
275+
}
276+
}
277+
// No collision — move freely
278+
sprite.move(movement);
279+
return false;
280+
}
281+
239282
// Reusable function for animating player
240283
void Player::animate(int xStart, int xEnd, int yStart, int yEnd) {
241284
// If current texture coordinates outside of expected values then use start coordinates

Player.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
class Player {
77
public:
88
Player();
9-
void handleInput();
9+
void handleInput(std::vector<sf::FloatRect> wallBounds);
1010
void Player::sprint(bool sprint);
1111
void update();
1212
sf::Vector2f getPosition();
1313
void draw(sf::RenderWindow& window);
14+
bool handleCollision(sf::Vector2f movement, sf::FloatRect nextBounds, std::vector<sf::FloatRect> wallBounds);
1415
void animate(int xStart, int xEnd, int yStart, int yEnd);
1516
sf::Texture texture;
1617
sf::Sprite sprite;

main.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,37 @@ int main()
1717
// Create a player
1818
Player player;
1919

20-
// Create a enemy
20+
// Create enemies
2121
std::vector<Enemy> enemies;
22-
sf::Vector2<float> position1(275.f, 200.f);
22+
// Create enemy 1
23+
sf::Vector2<float> position1(275.f, 200.f); // Set coordinates
2324
Enemy enemy1(position1, sf::Color::Red);
2425
enemies.push_back(enemy1);
25-
sf::Vector2<float> position2(255.f, 220.f);
26+
// Create enemy 2
27+
sf::Vector2<float> position2(255.f, 210.f); // Set coordinates
2628
Enemy enemy2(position2, sf::Color::Red);
2729
enemies.push_back(enemy2);
2830

2931
// Create walls
3032
std::vector<sf::RectangleShape> walls;
31-
sf::RectangleShape wall(sf::Vector2f(50.f, 50.f));
32-
sf::Vector2<float> position(275.f, 200.f); // Set coordinates
33-
wall.setPosition(position);
34-
wall.setFillColor(sf::Color::Red);
35-
walls.push_back(wall);
33+
// Create wall 1
34+
sf::Vector2<float> wallPos1(275.f, 200.f); // Set coordinates
35+
sf::RectangleShape wall1(wallPos1);
36+
wall1.setOrigin(wall1.getLocalBounds().size / 2.f);
37+
wall1.setPosition(wallPos1);
38+
wall1.setFillColor(sf::Color::Red);
39+
wall1.setScale({0.5f,0.5f});
40+
walls.push_back(wall1);
41+
// Create wall 2
42+
sf::Vector2<float> wallPos2(255.f, 180.f); // Set coordinates
43+
sf::RectangleShape wall2(wallPos2);
44+
wall2.setOrigin(wall2.getLocalBounds().size / 2.f);
45+
wall2.setPosition(wallPos2);
46+
wall2.setFillColor(sf::Color::Red);
47+
wall2.setScale({0.5f,0.5f});
48+
walls.push_back(wall2);
49+
50+
std::vector<sf::FloatRect> wallBounds;
3651

3752
// Create game window
3853
sf::RenderWindow window(sf::VideoMode({800, 600}), "2D Game", sf::Style::Titlebar | sf::Style::Close);
@@ -89,7 +104,7 @@ int main()
89104
window.handleEvents(onClose, onKeyPressed, onKeyReleased);
90105

91106
// Handle player controls and enemy updates
92-
player.handleInput();
107+
player.handleInput(wallBounds);
93108
player.update();
94109

95110
// Create new window with sprites drawn in
@@ -99,6 +114,9 @@ int main()
99114
// Display walls
100115
for (const auto& wall : walls) {
101116
window.draw(wall);
117+
sf::FloatRect bounds = wall.getGlobalBounds();
118+
bounds.size = wall.getGlobalBounds().size *= 0.2f;
119+
wallBounds.push_back(bounds);
102120
}
103121
// Display and update enemies
104122
for (auto& enemy : enemies) {

main.exe

54.5 KB
Binary file not shown.

main.obj

49.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)