C++ adding borders on monsters (C++ text-based game) - c++

void Map::Movement()
{
int ch;
switch (ch = _getch())
{
case KEY_W: //up
if (Player::posy != 1)
{
if (AboveM == false)
{
Player::posy--;
DisplayMap();
}
}
break;
case KEY_S: //down
if (Player::posy != 20)
{
if (BelowM == false)
{
Player::posy++;
DisplayMap();
}
}
break;
case KEY_A: //left
if (Player::posx != 1)
{
if (LeftM == false)
{
Player::posx--;
DisplayMap();
}
}
break;
case KEY_D: //right
if (Player::posx != 20)
{
if (RightM == false)
{
Player::posx++;
DisplayMap();
}
}
break;
I can't for the life of me figure out where to put this so that the borders for the mob will work correctly (first question I know it isn't asked well since I haven't added the rest of the code but it should be simple to figure out)I've been putting it every place I could think of the last week or so as well as trying out everything else I could that would run I either get weird random errors or it runs as if the monster as no borders at all.
if ((Player::posy = Enemy::enemyBuild::posy) && (Player::posx = Enemy::enemyBuild::posx +1))
{
bool RightM = true;
}
if ((Player::posy = Enemy::enemyBuild::posy) && (Player::posx = Enemy::enemyBuild::posx -1))
{
bool LeftM = true;
}
if ((Player::posx = Enemy::enemyBuild::posx) && (Player::posy = Enemy::enemyBuild::posy +1))
{
bool BelowM = true;
}
if ((Player::posx = Enemy::enemyBuild::posx) && (Player::posy = Enemy::enemyBuild::posy -1))
{
bool AboveM = true;
}

Related

How do you find the shortest path after the BFS algorithm?

while( !q.is_empty() )
{
loc = q.remove_from_front();
//cout << loc.row << " " << loc.col << endl;
if( (loc.row-1) >= 0) //north
{
loc2.row = loc.row-1;
loc2.col = loc.col;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
//loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc2.row][loc2.col] = '*';
break;
}
}
}
if(loc.col-1 >= 0) //West
{
loc2.row = loc.row;
loc2.col = loc.col-1;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
//loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc2.row][loc2.col] = '*';
break;
}
}
}
if(loc.row+1 < rows) //South
{
loc2.row = loc.row+1;
loc2.col = loc.col;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
// loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc2.row][loc2.col] = '*';
break;
}
}
}
if(loc.col+1 < cols) //East
{
loc2.row = loc.row;
loc2.col = loc.col+1;
if(maze[loc2.row][loc2.col] != '#' && visited[loc2.row][loc2.col] == false)
{
visited[loc2.row][loc2.col] = true;
q.add_to_back(loc2);
//loc = predecessor[loc.row][loc.col];
predecessor[loc2.row][loc2.col] = loc;
if(maze[loc2.row][loc2.col] == 'F')
{
result = 1;
maze[loc.row][loc.col] = '*';
break;
}
}
}
}
if(result == 1)
{
while()
{
//not sure...
}
}
This is my BFS algorithm and the main reason I asked this question is because the other questions similar to my own question tends to be done with vectors. I haven't learn vectors yet. What I am trying to do is to print the shortest path using '' characters to display it on valid elements. It should be in bounds, no walls visited (walls are '#' characters), and no element should be visited twice. I know that if I set my predecessor 2D array correctly, the shortest path should be displayed correctly. However, I am not sure if I did set it up correctly and how to actually fill in that path with '' characters...

How to run the functions independently on C++

I am trying to make a game on the console using C++. At the moment, I have three functions in the main.
int main() {
...
while (!level1 && !player.dead) {
drowing(l1_map);
PlayerMovements(empty, l1_map);
Enemy1Movements(enemy1, l1_map, lastloc);
cls();
}
}
The first function draws the map:
void drowing(char l1_map[26][50]) {
for (unsigned int i = 0; i < 26; i++) {
cout << endl;
for (unsigned int x = 0; x < 50; x++) {
if (x == 0) {
cout << " ";
}
//Draws the map and change colours;
//player
if (l1_map[i][x] == player.character) {
if (l1_map[player.locX][player.locY] == l1_map[enemy1.locX][enemy1.locY]) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 252);
cout << l1_map[i][x];
}
if (l1_map[player.locX][player.locY] != l1_map[enemy1.locX][enemy1.locY]) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 250);
cout << l1_map[i][x];
}
}//wall
else if (l1_map[i][x] == wall) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 128);
cout << l1_map[i][x];
}//enemy
else if (l1_map[i][x] == enemy1.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 252);
cout << l1_map[i][x];
}//empty space
else if (l1_map[i][x] == 32) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 509);
cout << l1_map[i][x];
}//key1
else if (l1_map[i][x] == key1.character && !key1.picked) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 509);
cout << l1_map[i][x];
}//key2
else if (l1_map[i][x] == key2.character && !key1.picked) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 253);
cout << l1_map[i][x];
}//key3
else if (l1_map[i][x] == key3.character && !key1.picked) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 253);
cout << l1_map[i][x];
}//doors1
else if (l1_map[i][x] == doors1.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 253);
cout << l1_map[i][x];
}//doors2
else if (l1_map[i][x] == doors2.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240);
cout << l1_map[i][x];
}//doors3
else if (l1_map[i][x] == doors3.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240);
cout << l1_map[i][x];
}//doors4
else if (l1_map[i][x] == doors3.character) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240);
cout << l1_map[i][x];
}//exit
else if (l1_map[i][x] == get_out1.character && !get_out1.open) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 139);
cout << l1_map[i][x];
}
else
{
cout << l1_map[i][x];
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
}
}
}
}
Second function allows player to move on the map using keyboard arrows:
void PlayerMovements(char& empty, char l1_map[26][50]) {
char awall = 219;
if (_kbhit()) {
switch ((_getch())) { //what button is pressed;
// move up
case 72:
if (l1_map[player.locX - 1][player.locY] != wall && l1_map[player.locX - 1][player.locY] != '[') {
player.locX--;
if (l1_map[player.locX + 1][player.locY] == player.character) {
l1_map[player.locX + 1][player.locY] = empty;
}
if (key3.locX == player.locX && key3.locY == player.locY) {
l1_map[key3.locX][key3.locY] = ' ';
}
}
break;
//move down
case 80:
if (l1_map[player.locX + 1][player.locY] != wall && l1_map[player.locX + 1][player.locY] != '[') {
player.locX++;
if (l1_map[player.locX - 1][player.locY] == player.character) {
l1_map[player.locX - 1][player.locY] = empty;
}
}
break;
case 75:
//left
if (l1_map[player.locX][player.locY - 1] != wall && l1_map[player.locX][player.locY - 1] != '[') {
player.locY--;
if (l1_map[player.locX][player.locY + 1] == player.character) {
l1_map[player.locX][player.locY + 1] = empty;
}
}
break;
case 77: // player moves right
if (l1_map[player.locX][player.locY + 1] != wall && l1_map[player.locX][player.locY + 1] != '[') {
player.locY++;
if (l1_map[player.locX][player.locY - 1] = player.character) {
l1_map[player.locX][player.locY - 1] = empty;
}
}
break;
}
}
}
Third function is the enemy that moves up and down:
int Enemy1Movements(enemy& enemy1, char l1_map[26][50], char& lastloc) {
//this_thread::sleep_for(chrono::milliseconds(500));
char empty = ' ';
bool ValidUp = false;
bool ValidDown = false;
bool ValidLeft = false;
bool ValidRight = false;
if (l1_map[enemy1.locX + 1][enemy1.locY] != wall && l1_map[enemy1.locX + 1][enemy1.locY] != '-') {
ValidDown = true;
}
if (l1_map[enemy1.locX - 1][enemy1.locY] != wall && l1_map[enemy1.locX - 1][enemy1.locY] != '-') {
ValidUp = true;
}
if (l1_map[enemy1.locX][enemy1.locY - 1] != wall && l1_map[enemy1.locX - 1][enemy1.locY] != '-') {
ValidLeft = true;
}
if (l1_map[enemy1.locX][enemy1.locY + 1] != wall && l1_map[enemy1.locX + 1][enemy1.locY] != '-') {
ValidRight = true;
}
////enemy move up and down
//////////////////////////
if (lastloc != 'u' && ValidDown) {
enemy1.locX++;
lastloc = 'd';
if (l1_map[enemy1.locX - 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX - 1][enemy1.locY] = 32;
}
}
else if (lastloc == 'd' && ValidUp) {
enemy1.locX--;
lastloc = 'u';
if (l1_map[enemy1.locX + 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX + 1][enemy1.locY] = 32;
}
}
else {
if (ValidUp) {
enemy1.locX--;
lastloc = 'u';
if (l1_map[enemy1.locX + 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX + 1][enemy1.locY] = 32;
}
}
else {
enemy1.locX++;
lastloc = 'd';
if (l1_map[enemy1.locX - 1][enemy1.locY] == enemy1.character) {
l1_map[enemy1.locX - 1][enemy1.locY] = 32;
}
}
}
return NULL;
}
What I am tryng to achieve:
I need to slow down the EnemyMovemens() function, because the enemy moves to fast. Or to make PlayerMovements() function independent from other functions.
The Problem:
I have tried to use threads. Functions like this_thread::sleep_for() and Sleep(). To put them in EnemyMovements() function. In that case, it slow down all app and my player moves very slowly.
I dont need a code, because I love to learn by myself. I just need a guidance what direction to move now.
OS: Win 10
The basic problem is that you don't having any timing in your game loop so everything is happening at the same speed. There are some good articles online that discuss game timing loops, this one for instance: http://www.koonsolo.com/news/dewitters-gameloop/ walks you through the steps from the approach you're using now to the better approach of separating your game update timing from your display timing.
That article doesn't tell you how to slow your enemy down relative to your player - one approach is to have a enemySpeed variable and use something like:
// outside main loop
int enemySlowness = 20; // adjust this as needed
int enemyMoveTimer = 0;
...
if (++enemyMoveTimer > enemySlowness)
{
Enemy1Movements(enemy1, l1_map, lastloc);
enemyMoveTime = 0;
}
There are problems with this approach, but coupled with some idea from that article should get you on the right track.

Called function clears changes of previous one

I'm working on a cellular automaton where changes happen in every rounds. Obviously, I made a loop for it - basically it works, fortunately, but if I want to add another type of cells to the map, one type of cells works, but the other doesn't do anything: the game begins and e.g. in this example, the Conway-automaton starts growing, but the red test-cells are just staying without any changes.
#define fldwidth 110
#define fldheight 140
typedef struct tiles
{
unsigned char red, green, blue;
}tiles;
const tiles TEST_ALIVE = {255,0,0};
const tiles TEST_DEAD = {50,0,0};
const tiles CONWAY_ALIVE = {0,255,0};
const tiles CONWAY_DEAD = {0,50,0};
//Maes módszere a struktúrák egyenlőségének vizsgálatára
bool equality(tiles* a, const tiles* b)
{
if (a->red == b->red && a->green == b->green && a->blue == b->blue)
{
return true;
} else {
return false;
}
}
//sejttípus 1.: tesztsejt: minden magányos vagy túlbuzgó sejt meghal
void Test(tiles arra[fldwidth][fldheight], tiles arrb[fldwidth][fldheight])
{
int a,b,i,j,counter;
for (j=1;j<fldheight-1;j++)
{
for (i=1;i<fldwidth-1;i++)
{
if (equality(&arra[i][j], &TEST_ALIVE) == true)
{
counter = -1;
} else {
counter = 0;
}
for (b=j-1;b<=j+1;b++)
{
for (a=i-1;a<=i+1;a++)
{
if (equality(&arra[a][b], &TEST_ALIVE) == true)
{
counter+=1;
}
}
}
arrb[i][j] = arra[i][j];
//itt a sejtek szabályai jönnek; mindig a születést tesszük előre, utána a halált!
if (equality(&arra[i][j], &TEST_ALIVE) == false && counter >= 2)
{
arrb[i][j] = TEST_ALIVE;
}
if (equality(&arra[i][j], &TEST_ALIVE) == true && (counter == 0 || counter > 6))
{
arrb[i][j] = TEST_DEAD;
}
}
}
}
//sejttípus 2.: Conway életjátéka
void Conway(tiles arra[fldwidth][fldheight], tiles arrb[fldwidth][fldheight])
{
int a,b,i,j,counter;
for (j=1;j<fldheight-1;j++)
{
for (i=1;i<fldwidth-1;i++)
{
if (equality(&arra[i][j], &CONWAY_ALIVE) == true)
{
counter = -1;
} else {
counter = 0;
}
for (b=j-1;b<=j+1;b++)
{
for (a=i-1;a<=i+1;a++)
{
if (equality(&arra[a][b], &CONWAY_ALIVE) == true)
{
counter+=1;
}
}
}
arrb[i][j] = arra[i][j];
//itt a sejtek szabályai jönnek; mindig a születést tesszük előre, utána a halált!
if (equality(&arra[i][j], &CONWAY_ALIVE) == false && counter == 3)
{
arrb[i][j] = CONWAY_ALIVE;
}
if (equality(&arra[i][j], &CONWAY_ALIVE) == true && (counter != 2 && counter != 3))
{
arrb[i][j] = CONWAY_DEAD;
}
}
}
}
This is content of the loop:
Test(fielda,fieldb);
Conway(fielda,fieldb);
end = false;
round++;
for (j = 0; j < fldheight; j++)
{
for (i = 0; i < fldwidth; i++)
{
fielda[i][j] = fieldb[i][j];
}
}
As I mentioned, in this example, Conway cells grow, but Test cells just stay. How to make them work simultaneously?
(I use Allegro libraries so if that has something for this problem, feel free to share with me!)
Test(fielda,fieldb); sets every cell of fieldb based on the current value of fielda. And then Conway(fielda,fieldb); sets every cell of fieldb based on the current value of fielda, overwriting fieldb so that everything Test did is gone. One way to fix this is to change your loop to:
Test(fielda,fieldb);
Conway(fieldb,fielda); //switched the parameters
end = false;
round++;
//there is no need to copy fieldb to fielda here because Conway already did
But this might not be the right fix depending on exactly how you want test and conway to interact with each other.

Called function clears changes of previous one

I'm working on a cellular automaton where changes happen in every rounds. Obviously, I made a loop for it - basically it works, fortunately, but if I want to add another type of cells to the map, the whole thing doesn't work! I mean, one type of cells works, but the other doesn't do anything: The game begins and e.g. in this example, the Conway-automaton starts growing, but the red test-cells are just staying without any changes.
These are the two functions (with predefined things):
#define fldwidth 110
#define fldheight 140
//struktúra, aztán a sejtek definíciója
typedef struct tiles
{
unsigned char red, green, blue;
}tiles;
const tiles TEST_ALIVE = {255,0,0};
const tiles TEST_DEAD = {50,0,0};
const tiles CONWAY_ALIVE = {0,255,0};
const tiles CONWAY_DEAD = {0,50,0};
//Maes módszere a struktúrák egyenlőségének vizsgálatára
bool equality(tiles* a, const tiles* b)
{
if (a->red == b->red && a->green == b->green && a->blue == b->blue)
{
return true;
} else {
return false;
}
}
//sejttípus 1.: tesztsejt: minden magányos vagy túlbuzgó sejt meghal
void Test(tiles arra[fldwidth][fldheight], tiles arrb[fldwidth][fldheight])
{
int a,b,i,j,counter;
for (j=1;j<fldheight-1;j++)
{
for (i=1;i<fldwidth-1;i++)
{
if (equality(&arra[i][j], &TEST_ALIVE) == true)
{
counter = -1;
} else {
counter = 0;
}
for (b=j-1;b<=j+1;b++)
{
for (a=i-1;a<=i+1;a++)
{
if (equality(&arra[a][b], &TEST_ALIVE) == true)
{
counter+=1;
}
}
}
arrb[i][j] = arra[i][j];
//itt a sejtek szabályai jönnek; mindig a születést tesszük előre, utána a halált!
if (equality(&arra[i][j], &TEST_ALIVE) == false && counter >= 2)
{
arrb[i][j] = TEST_ALIVE;
}
if (equality(&arra[i][j], &TEST_ALIVE) == true && (counter == 0 || counter > 6))
{
arrb[i][j] = TEST_DEAD;
}
}
}
}
//sejttípus 2.: Conway életjátéka
void Conway(tiles arra[fldwidth][fldheight], tiles arrb[fldwidth][fldheight])
{
int a,b,i,j,counter;
for (j=1;j<fldheight-1;j++)
{
for (i=1;i<fldwidth-1;i++)
{
if (equality(&arra[i][j], &CONWAY_ALIVE) == true)
{
counter = -1;
} else {
counter = 0;
}
for (b=j-1;b<=j+1;b++)
{
for (a=i-1;a<=i+1;a++)
{
if (equality(&arra[a][b], &CONWAY_ALIVE) == true)
{
counter+=1;
}
}
}
arrb[i][j] = arra[i][j];
//itt a sejtek szabályai jönnek; mindig a születést tesszük előre, utána a halált!
if (equality(&arra[i][j], &CONWAY_ALIVE) == false && counter == 3)
{
arrb[i][j] = CONWAY_ALIVE;
}
if (equality(&arra[i][j], &CONWAY_ALIVE) == true && (counter != 2 && counter != 3))
{
arrb[i][j] = CONWAY_DEAD;
}
}
}
}
and this is the loop itself:
while(!end)
{
al_wait_for_event_timed(event_queue,&asd,0.001); //várakozás
if(asd.type == ALLEGRO_EVENT_KEY_DOWN)
{
if(asd.keyboard.keycode == ALLEGRO_KEY_ENTER)
{
Test(fielda,fieldb);
Conway(fielda,fieldb);
end = false;
round++;
for (j = 0; j < fldheight; j++)
{
for (i = 0; i < fldwidth; i++)
{
fielda[i][j] = fieldb[i][j];
}
}
}
}
for (j = 0; j < fldheight; j++)
{
for (i = 0; i < fldwidth; i++)
{
al_draw_filled_rectangle(20 + (4*i), 20 + (4*j), 24 + (4*i), 24 + (4*j), al_map_rgb(fielda[i][j].red, fielda[i][j].green, fielda[i][j].blue));
}
}
}
Can you tell me what is wrong with it? Or maybe the problem is not in the loop?
Your problem is that the second function you call reverses all the changes made by the first function. That is why you see only one working.
The best way to get both working it to let each function operate only on one colour channel. Test uses only the red colour channel (both for reading and changing), while Conway uses only the green colour channel. Be prepared to see cells with different colours: these were affected by both functions.

C++ Rectangle to rectangle Collision

I'm having a really bad time here looking for the error in my code.
My collision detection won't work here even the algorithm I searched in Google.
void PollEvents()
{
for (int i = 0;i < NUMBER_OF_BLOCKS; ++i)
{
Rectangle& a = blocks[i];
if (mouse.state == GLFW_PRESS)
{
//look for any block to grab
if (mouse.leftClick && !blocks[selectedBlock].Grab() &&
a.Hover(mouse.pos.x, mouse.pos.y))
{
//prevent grabbing another block
if (i != selectedBlock) {
selectedBlock = i;
}
a.Grab() = true;
if (a.IsTypeHorizontal()) {
diff = mouse.pos.x - a.Left();
} else {
diff = mouse.pos.y - a.Top();
}
}
if (a.Grab())
{
for (int j = 0;j < NUMBER_OF_BLOCKS; ++j)
{
//skip for any self-checking
if (i == j) continue;
Rectangle& b = blocks[j];
//check for rectangle collision
if (!a.Collide(b) || b.Collide(a)) {
//j++;
//how does this block will move.
if (a.IsTypeVertical()) {
a.SetY(mouse.pos.y - diff);
} else {
a.SetX(mouse.pos.x - diff);
}
} else {
switch (a.sideHit)
{
case UP:
//a.SetY(b.Bottom());
printf("UP\n");
break;
case DOWN:
//a.SetY(b.Top() + a.GetHeight());
printf("DOWN\n");
break;
case LEFT:
//a.SetX(b.Right());
printf("LEFT\n");
break;
case RIGHT:
//a.SetX(b.Left() - a.GetWidth());
printf("RIGHT\n");
break;
}
}
//check for bound collision
a.BoundCheck(1.f);
}
}
} else {
a.Grab() = false;
}
}
}
Collision detection:
bool Rectangle::Collide(const Rectangle& r) {
if (IsTypeHorizontal()) {
if (r.Hover(Left(), Top()) && r.Hover(Right(), Top())) {
sideHit = UP;
return true;
} else if (r.Hover(Right(), Bottom()) && r.Hover(Left(), Bottom())) {
sideHit = DOWN;
return true;
}
// } else if (r.Hover(Left(), Top())) {
// sideHit = UP;
// return true;
// } else if (r.Hover(Right(), Top())) {
// sideHit = UP;
// return true;
// } else if (r.Hover(Right(), Bottom())) {
// sideHit = DOWN;
// return true;
// } else if (r.Hover(Left(), Bottom())) {
// sideHit = DOWN;
// return true;
// }
} else {
if (r.Hover(Left(), Top()) && r.Hover(Left(), Bottom())) {
sideHit = LEFT;
return true;
} else if (r.Hover(Right(), Top()) && r.Hover(Right(), Bottom())) {
sideHit = RIGHT;
return true;
}
// } else if (r.Hover(Left(), Top())) {
// sideHit = LEFT;
// return true;
// } else if (r.Hover(Left(), Bottom())) {
// sideHit = LEFT;
// return true;
// } else if (r.Hover(Right(), Top())) {
// sideHit = RIGHT;
// return true;
// } else if (r.Hover(Right(), Bottom())) {
// sideHit = RIGHT;
// return true;
// }
}
return false;
}
Code for Hover:
inline float Hover(float X, float Y) const {
return X >= Left() &&
X <= Right() &&
Y >= Bottom() &&
Y <= Top();
}
I'm trying to make my own unblockme.
Please help me on my collision-detection. It's been 3 days now since I got stuck in this problem.
UPDATE
I have found out the problem why all rect-rect collision detection won't work in my program.
Bug:
if (!a.Collide(b)) {
//Move()
} else {
//Resolve collision
}
This one should be
if (!Rectangle::Collide(a, b)) {
//Move()
} else {
//Resolve collision
}
Making the Collide() a static member of Rectangle because, as you can see in my implementation of Collide(), it bases its decision on its own member so a.Hover(b.x, b.y) doesn't make any sense.
Hope this helps a little bit to all newbies like me.
To do rect/rect collision detection, if any of one (edges parallel to x and y axis) rect's four points is inside the other rect, we have a collision.
An easier way than to check each of the four points is to check if one X edge is between both the other rect's X edges, and if one Y edge is between both the other rect's Y edges - if both are true, we have a collision (because the two edges must meet at a point inside of the other rect). So we just check this in both directions:
bool isclamped(float mid, float A, float B)
{
if (A > B)
{
return mid >= B && mid <= A;
}
return mid >= A && mid <= B;
}
bool checkcollisiononeway(rect rectA, rect rectB)
{
if (isclamped(rectA.left, rectB.left, rectB.right)
|| isclamped(rectA.right, rectB.left, rectB.right))
&& (isclamped(rectA.bottom, rectB.bottom, rectB.top)
|| isclamped(rectA.top, rectB.bottom, rectB.top))
{
return true;
}
return false;
}
bool checkcollisionbothways(rect rectA, rect rectB)
{
return checkcollisiononeway(rectA, rectB) || checkcollisiononeway(rectB, rectA);
}
To determine the angle of collision after detecting a collision, find the angle between their two centers using atan2(rectA.y - rectB.y, rectA.x - rectB.x) (the angle is returned in radians, not in degrees)