Allegro 5 platformer collision problem

This is my first platformer game I've made. Also, I'm a beginner to Allegro and c++ so the code is probably bad. Collision works fine except for a little problem. When you collide with the bottom of a box the screen shakes a little. It's because of the camera I think. I'm pretty sure that it getting messed up because in the if statement it needs to be player.y - player.boundY <= boxes[i].y + boxes[i].height instead of player.y - player.boundY < boxes[i].y + boxes[i].height, but if I do that the left and right collision gets messed up. This is the collision part of my code.

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
void Collide(Map boxes[], int size, Player &player, bool keys[], Particle particles[], int &particleNum, int maxParticles, Enemy enemy[], int maxEnemies, float *cameraPos) {
	for (int i = 0; i < size; i++) {
			if (player.x + player.boundX > boxes[i].x &&
				player.x - player.boundX < boxes[i].x + boxes[i].width &&
				player.y + player.boundY >= boxes[i].y &&
				player.y - player.boundY < boxes[i].y + boxes[i].height &&
				boxes[i].solid && boxes[i].active) {
					if (player.y + player.boundY >= boxes[i].y && player.prevY + player.boundY <= boxes[i].y && player.alive) {
						if (boxes[i].image == 6 && player.velY > 0) {
							for (int r = 0; r < 300; r++)
								NewParticles(particles, maxParticles, player.x, player.y, particleNum, 1, rand() % 255, rand() % 255, rand() % 255,
									rand() % 20 - 10, rand() % 20 - 10, rand() % 5 + 2, 1, rand() % 2, 1);

							player.deadTimer = 100;
							player.alive = false;
						}
						if (player.frame >= 4 && player.frame <= 5 || !keys[LEFT] && !keys[RIGHT] && abs(player.velX) < 1 ||player.frame == 6)
							player.frame = 0;
						if (abs(player.velX) > 1 && !player.frame >= 1 && !player.frame <= 3)
							player.frame = 1;
						player.velY = 0;
						player.jump = true;
						player.y = boxes[i].y - player.boundY;
						if (keys[RIGHT] && player.velX > 2 || keys[LEFT] && player.velX < -2)
							if (rand() % 10 == 0)
								NewParticles(particles, maxParticles, player.x, player.y + player.boundY - 1, particleNum, 1, boxes[i].color1, boxes[i].color2, boxes[i].color3, 50, 20, 1, 1, true, 1);
					}
					else if (player.x + player.boundX > boxes[i].x && player.prevX + player.boundX <= boxes[i].x && boxes[i].image != 6) {
						player.velX = 0;
						player.x = boxes[i].x - player.boundX;
						if (keys[RIGHT] && player.velY > 0) {
							player.velY = 0;
							player.jump = true;
							if (rand() % 10 == 0)
								NewParticles(particles, maxParticles, player.x + player.boundX, player.y + player.boundY - 1, particleNum, 1, boxes[i].color1, boxes[i].color2, boxes[i].color3, 50, 20, 1, 1, true, 1);
						}
					}
					else if (player.x - player.boundX < boxes[i].x + boxes[i].width && player.prevX - player.boundX >= boxes[i].x + boxes[i].width && boxes[i].image != 6) {
						player.velX = 0;
						player.x = boxes[i].x + boxes[i].width + player.boundX;
						if (keys[LEFT] && player.velY > 0) {
							player.velY = 0;
							player.jump = true;
							if (rand() % 10 == 0)
								NewParticles(particles, maxParticles, player.x - player.boundX, player.y + player.boundY - 1, particleNum, 1, boxes[i].color1, boxes[i].color2, boxes[i].color3, 50, 20, 1, 1, true, 1);
						}
					}
					else if (player.y - player.boundY < boxes[i].y + boxes[i].height && player.prevY - player.boundY <= boxes[i].y + boxes[i].height && boxes[i].image != 6 && player.velY < -1) {
						player.velY = 0;
						player.y = boxes[i].y + boxes[i].height + player.boundY;
					}
			}
		}
What a nightmare, that code could do with refactoring. The player class could probably handle some of that logic internally.
There isn't a player class. What is so bad about the code? Is there a better way to do the collision?
closed account (N36fSL3A)
You aren't using a good style is what he means.
What would be a better way of doing it?
There isn't a player class
void Collide(Map boxes[], int size, Player &player,
wot

The problem is that it's extremely difficult to maintain your stylistic choices, and as a result, makes it practically impossible to do anything dynamic.

For instance, what if I want to add more players? Would you copy and paste everything?

Here would be my suggestion, but you mentioned that you are a beginner, so don't let it intimidate you, and feel free to ignore it.

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
#include <cmath>

template<typename _Ty>
class vec2 {
public :
	vec2() {x=y=0;}
	vec2(_Ty X, _Ty Y) {x=X; y=Y;}
	_Ty x, y;

};

class vec2f : public vec2<float> {};

class Body {
public :
	Body() {dim.x=dim.y=1.0;}
	vec2f pos, dim, vel;//position, dimensions and velocity

};

class Client : public Body {
public :
	Client() {}
	virtual void update()=0;
	bool isColliding(const Body& body, vec2f& collisionVector);

};

class Player : public Client {
public :
	Player() {}
	void update() {}

};

//note, this pseudo-code only works with two dimensions. It also only checks if there is a collision, but doesn't handle it (but it modifies a collisionVector to do the handling).
//it also only works when the width and height dimensions are half lengths of the bounding boxes. In other words, if dim=vec2(1.0, 1.0), then the bounding box is 2x2 units

bool Client::isColliding(const Body& body, vec2f& collisionVector) {
	float xIntersect = (dim.x+body.dim.x)-(fabs(dim.x-body.dim.x));
	float yIntersect = (dim.y+body.dim.y)-(fabs(dim.y-body.dim.y));

	if(xIntersect<=0 || yIntersect<=0) {return false;}

	if(xIntersect <= yIntersect) {
		collisionVector.x += xIntersect*(dim.x<body.dim.x?-1.0:1.0);
	}else {
		collisionVector.y += yIntersect*(dim.y<body.dim.y?-1.0:1.0);
	}
	return true;
}
Last edited on
Yaaaa... I understand about 20% of that. I haven't really learned about classes much and not vectors at all. Instead I have a player struct.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct Player
{
	int maxSpeed;
	float x;
	float y;
	float prevX;
	float prevY;
	int boundX;
	int boundY;
	float velX;
	float velY;
	float gravity;
	int jumpSpeed;
	bool jump;
	bool jumpCheck;
	int deadTimer;
	bool alive;
	int frame;
	int maxFrame;
	int frameDelay;
	int framedir;
	int startFrameDelay;
	int dir;
}player; 
Last edited on
closed account (N36fSL3A)
You don't know what a mathematical vector is? I think you should hold off this project for a bit and refresh your knowledge on geometry.
Topic archived. No new replies allowed.