best way to do collision

So I want to make an adventure game but I dont want to do a text game, I want there to be some "graphics" so I want to write a map generator, which shouldnt be too difficult, but what i struggle most with is collision. The code below is fully working except for the collision. Now, if i have tons of things that need collision, my assumption is that I need a function that checks the collision of any object, but its the actual checking of the collision between the player and object that I struggle with, could anyone please help me?

There is no code for checking the collision between objects because I deleted it a while ago, this is a project i started like 5 months ago and just opened.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <iostream>
#include <string>

int main()
{
	char character = 'O';
	const char mapTile = '-';
	char boulder = 'G';
	const int mapX = 12;
	const int mapY = 23;
	char gameMap[mapX][mapY];

	int playerXCoord = 0;
	int playerYCoord = 0;

	int boulderX = 5;
	int boulderY = 5;

	int choice{};

	while (choice != -1)
	{
		for (int i = 0; i < mapX; i++)
		{
			for (int j = 0; j < mapY; j++)
			{
				gameMap[i][j] = mapTile;
				gameMap[boulderX][boulderY] = boulder;
				gameMap[playerXCoord][playerYCoord] = character;
				std::cout << gameMap[i][j];
			}
			std::cout << std::endl;
		}

		std::cout << "Player X: " << playerXCoord << "\n";
		std::cout << "Player Y: " << playerYCoord << "\n\n";

		std::cout << "Which direction would you like to move in?\n";
		std::cout << "1) Up\n";
		std::cout << "2) Down\n";
		std::cout << "3) Left\n";
		std::cout << "4) Right\n";

		std::cin >> choice;

		switch (choice)
		{
		case 1:
			if (playerXCoord < 1)
			{
				std::cout << "Cannot go Up anymore\n";
			}
			else
			{
				playerXCoord -= 1;
			}
			break;
		case 2:
			if (playerXCoord == mapX - 1)
			{
				std::cout << "Cannot go in Down anymore\n";
			}
			else
			{
				playerXCoord += 1;
			}
			break;
		case 3:
			if (playerYCoord < 1)
			{
				std::cout << "Cannot go Left anymore\n";
			}
			else
			{
				playerYCoord -= 1;
			}
			break;
		case 4:
			if (playerYCoord == mapY - 1)
			{
				std::cout << "Cannot go Right anymore\n";
			}
			else
			{
				playerYCoord += 1;
			}
			break;
		default:
			std::cout << "Error\n";
		}
	}

	return 0;
}
Last edited on
You have to test if the new player coordinates collide with an object at the new coordinates, and only if there is no collision, you need to move your player to the new coordinates. So you need to test the collision before you apply the player's move.

1
2
3
4
5
6
bool isMoveValid( char[] gameMap, int newPlayerXCoord, int newPlayerYCoord)
{
    if( gameMap[newPlayerXCoord][newPlayerYCoord] == boulder ) return false;
    // ... make other collision tests...
    return true;
}

Last edited on
collision detection is a big topic.
for a simple program with 'some graphics' that sounds like it is a 2-d program, you can make this fairly simple. One easy way is to just take the centers of the objects as x,y coordinates and check the distance between the 2 points. If it is less than some amount, they hit each other.
So I want to make an adventure game but I dont want to do a text game

I guess you do this either for fun or for learning purposes,
my post may be off topic but working on a game without which ever game engine is just to much of a work to do.
Yeah, its for fun and learning. Im going to make a text game, then a game using console ascii graphics, then a 2d game using SFML. I figure doing things in steps will be better for learning, as the concepts are the same when making a 2d graphics game as they are a 2d console ascii graphics game more or less. I figured out the collision, however, it gets the objects position instead of me being able to just put in the char and it figures out where it is and applies collision to it. I made a few boulders and they all have collision. I was thinking there is two ways to approach this, I can make it test for a char and it figures out where its position is and applies the collision to it, or i can make a vector of pairs and input x and y values into that and then iterate over it when calling collision to check which object is being collided with. Not really sure which way to go.
Last edited on
Ok so I went the route of having a vector that contains a list of collidable objects and it works perfectly, any char i add to the list is collidable at any position on the map. my question now is can any of this code be simplified or made clearer?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <string>
#include <vector>

using namespace std;

//Template for testing all collision against objects.
bool IsColliding(vector<vector<char>> gameMap, int newPlayerXCoord, int newPlayerYCoord, vector<char> obj)
{
	for (int i = 0; i < obj.size(); i++)
	{
		if (gameMap[newPlayerXCoord][newPlayerYCoord] == obj[i])
		{
			cout << "Collision" << endl;
			return true;
		}
	}
}

void Shop();

int main()
{
	char character = '*';
	const char mapTile = ' ';
	char boulder = '@';
	char tree = '^';
	char wall = '#';
	char shop = 'S';

	const int mapX = 12;
	const int mapY = 23;

	vector<vector<char>> gameMap(mapX, vector<char>(mapY, mapTile));

	int playerXCoord = 2;
	int playerYCoord = 2;


	vector<char> collidables;

	collidables.push_back(boulder);
	collidables.push_back(wall);
	collidables.push_back(tree);

	int choice{};

	while (choice != -1)
	{
		for (size_t i = 0; i < mapX; ++i)
		{
			for (size_t j = 0; j < mapY; ++j)
			{
				gameMap[i][j] = mapTile; //Re-Draw tiles so player char wont remain on movement path.
				gameMap[playerXCoord][playerYCoord] = character; //Set player on map
				gameMap[5][5] = boulder;
				gameMap[6][7] = boulder;
				gameMap[8][8] = tree;
				gameMap[4][4] = shop;
				gameMap[0][j] = wall; //Top Wall
				gameMap[i][0] = wall; //Left Wall
				gameMap[i][mapY - 1] = wall; //Right Wall
				gameMap[mapX - 1][j] = wall; //Bottom Wall
				cout << gameMap[i][j];
			}
			cout << endl;
		}

		std::cout << "Player X: " << playerXCoord << "\n";
		std::cout << "Player Y: " << playerYCoord << "\n\n";

		std::cout << "Which direction would you like to move in?\n";
		std::cout << "1) Up\n";
		std::cout << "2) Down\n";
		std::cout << "3) Left\n";
		std::cout << "4) Right\n";

		std::cin >> choice;

		if (choice == 50 && gameMap[playerXCoord][playerYCoord] == shop)
		{
			Shop();
		}

		switch (choice)
		{
		case 1:
			//Testing object collisions are set here and not in the function
			if (playerXCoord < 1 || IsColliding(gameMap, playerXCoord - 1, playerYCoord, collidables) == true)
			{
				std::cout << "Cannot go Up anymore\n";
			}
			else
			{
				playerXCoord -= 1;
			}
			break;
		case 2:
			if (playerXCoord == mapX - 1 || IsColliding(gameMap, playerXCoord + 1, playerYCoord, collidables) == true)
			{
				std::cout << "Cannot go in Down anymore\n";
			}
			else
			{
				playerXCoord += 1;
			}
			break;
		case 3:
			if (playerYCoord < 1 || IsColliding(gameMap, playerXCoord, playerYCoord - 1, collidables) == true)
			{
				std::cout << "Cannot go Left anymore\n";
			}
			else
			{
				playerYCoord -= 1;
			}
			break;
		case 4:
			if (playerYCoord == mapY - 1 || IsColliding(gameMap, playerXCoord, playerYCoord + 1, collidables) == true)
			{
				std::cout << "Cannot go Right anymore\n";
			}
			else
			{
				playerYCoord += 1;
			}
			break;
		default:
			std::cout << "Error\n";
		}
	}
	return 0;
}

void Shop()
{
	cout << "Shop Test" << endl;
}
Last edited on
Topic archived. No new replies allowed.