THIS CODE ON THIS POST IS NOW OBSOLETE.
Please refer to this post (current method for movement collisions in a topdown environment):
http://www.gamedev.net/topic/657046-topdown-wall-collision-not-working/?view=findpost&p=5156335
Still having trouble, player gets stuck along the bottom of the blocks while moving to the left and pushing up (player stops moving to the left for some reason).
Using SFML simply for drawing, gameplay is implemented using basic logic
I'm currently trying to do smooth top-down collision in which I use intersecting rectangles to detect
if my player is going to be colliding with a rectangle given his velocity in x- and y-directions.
Here's my rectangle struct:
arectangle.h
struct RECTANGLE{
int left, top, right, bottom;
};
My block class:
#include <SFML/Graphics.hpp>
#pragma once
class Block{
sf::RenderWindow* window;
public:
Block(sf::RenderWindow* _wind, int _x, int _y, int _size);
sf::RectangleShape mask;
void draw();
int x, y;
int size;
};
The main importance in the block class is x, y, and size (32 in my test case).
Here's my block instances, as well as my player which gets a reference to the blocks vector: (main.cpp)
vector<Block> blocks;
Block b1(&window, 96, 32, 32);
Block b2(&window, 32, 160, 32);
Block b3(&window, 0, 0, 32);
blocks.push_back(b1);
blocks.push_back(b2);
blocks.push_back(b3);
SFMLPlayer player(&window, &blocks);
The player is situated at position 32, 32 (with size rectangle 32).
And now here's the collision code, in SFMLPlayer.cpp:
bool SFMLPlayer::IntersectRect(RECTANGLE* r1, RECTANGLE* r2)
{
return ! ( r2->left > r1->right
|| r2->right < r1->left
|| r2->top > r1->bottom
|| r2->bottom < r1->top
);
}
//Gets run at 60fps
void SFMLPlayer::update(){
int room_width = 200; //temp
int room_height = 200; //temp
int hmove, vmove;
hmove = (right - left);
vmove = (down - up);
int move_speed = 2;
bool place_meeting = false;
for(std::vector<Block>::iterator block = blocks->begin(); block != blocks->end(); ++block) {
RECTANGLE prect;
prect.left = this->x + hmove;
prect.top = this->y + vmove;
prect.right = prect.left + this->size;
prect.bottom = prect.bottom + this->size;
RECTANGLE brect;
brect.left = block->x;
brect.top = block->y;
brect.right = block->x + block->size;
brect.bottom = block->y + block->size;
if(IntersectRect(&prect, &brect)){
place_meeting = true;
break;
}
}
x += ( hmove * move_speed ) * !place_meeting;
y += ( vmove * move_speed ) * !place_meeting;
//room boundaries check
if(x + size + hmove > room_width+1){
x = room_width - size + 2;
}
if(x - hmove < 0-1){
x = -2;
}
if(y + size + vmove > room_height+1){
y = room_height - size + 2;
}
if(y - vmove < 0-1){
y = -2;
}
mask.setPosition(x, y);
}
I'm using a boolean: place_meeting() to detect if my (player + velocity) rectangle is going to hit any of the blocks using my InterSectRect(RECT*, RECT*) function.
And if it is, I set place_meeting to true and break out of the loop.
There are a few problems which I will display in an image:
I can't even get to the left side of the room, I'm blocked out by that block in the bottom left.
Its like its entire left side is expanded to the other parts of the room (as shown in the green marker line in the second picture).
After some more testing I found out that I can't get past the top part of any blocks.
I can get past the bottom parts though.
Here's three more pictures: