![]() |
|
Bounding box collision problems. |
PamperBoy
Member #15,477
January 2014
|
Hi there, Im having some trouble with the bounding box collision using allegro 5. Standing on top of the platform works. But when colide to the left side of the platform i go in the platform (but does stop in centre of it) also when i jump against the platform i either go through completly or stop in the middle of the platform. I hope i explained it good enough. if yuo have questions or need to see code just ask. note: hdir 1 right, 2 left, 0 none. vdir 1 up, 2 down 0 none also the number 1 is the platform. Here is the collision code i wrote. 1#include "Collision.h"
2
3
4Collision::Collision()
5{
6}
7
8
9Collision::~Collision()
10{
11}
12
13void Collision::Init()
14{
15 loadCounterX = loadCounterY = 0;
16 Collision::LoadCollisionMap("ColMap1.txt", 0);
17 Collision::LoadCollisionMap("ColMap2.txt", 1);
18 Collision::LoadCollisionMap("ColMap3.txt", 2);
19}
20
21void Collision::Update(ALLEGRO_DISPLAY *display, Player &player, Map &map)
22{
23 Collision::PlatformCollision(display, player, map);
24 Collision::LevelReset(player, map);
25 Collision::DirReverse(player, map);
26 Collision::LevelEnd(player, map);
27}
28
29void Collision::Draw(ALLEGRO_DISPLAY *display)
30{
31
32}
33
34void Collision::LoadCollisionMap(const char *filename, int level)
35{
36 ifstream openfile(filename);
37 if(openfile.is_open())
38 {
39 openfile >> mapSizeX >> mapSizeY;
40 while(!openfile.eof())
41 {
42 openfile >> ColMapFile[level][loadCounterX][loadCounterY];
43 loadCounterX ++;
44 if (loadCounterX >= mapSizeX)
45 {
46 loadCounterX = 0;
47 loadCounterY ++;
48 }
49 }
50 loadCounterX = loadCounterY = 0;
51 }
52 else
53 {
54 { al_show_native_message_box(NULL, "Error", "Error",
55 "Cannot find collision map file", NULL, NULL);
56 }
57
58 }
59}
60
61void Collision::PlatformCollision(ALLEGRO_DISPLAY *display, Player &player, Map &map)
62{
63 for (int i = 0; i < mapSizeX; i++)
64 {
65 for(int j = 0; j < mapSizeY; j++)
66 {
67 if(ColMapFile[map.getLevel()][i][j] == 1)
68 {
69 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
70 {
71 //no collision
72 player.platform = false;
73 }
74
75 else
76 {
77 if (player.vDir == 1)
78 {
79 player.y += player.speed * 2;
80 player.y2 = player.y + 10;
81 player.vely = 0;
82 player.platform = false;
83 player.jump = false;
84 }
85
86 if(player.vDir == 2 && player.y - player.vely <= j*blockSize)
87 {
88 player.y = j*blockSize - 10;
89 player.y2 = player.y + 10;
90 player.platform = true;
91 player.jump = true;
92 player.vely = 0;
93
94 }
95
96
97 if (player.hDir == 1 && player.platform == false)
98 {
99 player.x -= player.speed;
100 player.x2 = player.x + 10;
101 }
102
103 if (player.hDir == 2 && player.platform == false)
104 {
105 player.x += player.speed;
106 player.x2 = player.x + 10;
107 }
108 }
109 }
110 }
111 }
112
113}
114
115void Collision::LevelReset(Player &player, Map &map)
116{
117 for (int i = 0; i < mapSizeX; i++)
118 {
119 for(int j = 0; j < mapSizeY; j++)
120 {
121 if(ColMapFile[map.getLevel()][i][j] == 2)
122 {
123 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
124 {
125 //no collision
126 }
127
128 else
129 {
130 player.x = player.origX;
131 player.y = player.origY;
132
133 map.setLevel(0);
134
135 player.velx = player.speed;
136 player.hDir = 1;
137 }
138 }
139 }
140 }
141
142}
143
144void Collision::LevelEnd(Player &player, Map &map)
145{
146 for (int i = 0; i < mapSizeX; i++)
147 {
148 for(int j = 0; j < mapSizeY; j++)
149 {
150 if(ColMapFile[map.getLevel()][i][j] == 3)
151 {
152 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
153 {
154 //no collision
155 }
156
157 else
158 {
159 int level = map.getLevel();
160 level ++;
161 map.setLevel(level);
162 if(level > 2)
163 {
164 map.setLevel(0);
165 player.velx = player.speed;
166 player.hDir = 1;
167 }
168 player.x = player.origX;
169 player.y = player.origY;
170
171 //Wait 1 second (loading new map)
172 al_clear_to_color(al_map_rgb(0, 0, 0));
173 al_flip_display();
174 //al_rest(1);
175 }
176 }
177 }
178 }
179
180}
181
182void Collision::DirReverse(Player &player, Map &map)
183{
184 for (int i = 0; i < mapSizeX; i++)
185 {
186 for(int j = 0; j < mapSizeY; j++)
187 {
188 if(ColMapFile[map.getLevel()][i][j] == 4)
189 {
190 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
191 {
192 //no collision
193 }
194
195 else
196 {
197
198 player.velx = -player.speed;
199 player.hDir = 2;
200 }
201 }
202 }
203 }
204
205}
|
Dizzy Egg
Member #10,824
March 2009
![]() |
Your if/else's look a bit screwed up....at one point you say: if(x > etc etc etc) { //no collision } else { //move x/y etc etc } ...so you're saying "if there is a collision then move the player"...makes no sense!
---------------------------------------------------- |
PamperBoy
Member #15,477
January 2014
|
Then what should i do? because the player moves at a constant speed of 5 to the right. Sorry still a beginner hehe edit Also ive been trying to change the code for ages. But what ever i do the result is the same. aka nothing new happens. Also ive been looking at a tutorial, the code that was written in there is practically the same. The only difference is that it works in the tutorial... |
Dizzy Egg
Member #10,824
March 2009
![]() |
So, explain to me exactly what happens, in as much detail as possible, and I'll help you out. [edit] Also, show me the code where you draw the player, and map/tiles. [edit2] Also, show me how big your player sprite is, and how big your blocks are!
---------------------------------------------------- |
PamperBoy
Member #15,477
January 2014
|
ill explain what happens: i go to the right at a constant speed of 5. When i encouter a tile i will collide with it but it goes within the tile. and then stops in the middle. Same goes for jumping. When i jump i go either through the whole tile or stop in the middle. Here is the player class: 1#include "Player.h"
2
3
4
5
6Player::Player(void)
7{
8}
9
10
11Player::~Player(void)
12{
13}
14
15void Player::Init()
16{
17 movementPressed = false;
18 width = 10;
19 height = 10;
20 x = 100;
21 y = 450;
22 origX = x;
23 origY = y;
24 x2 = x + width;
25 y2 = y + height;
26 speed = 5;
27 jumpspeed = - (10 + (blockSize / (blockSize / 3)));
28 gravity = 1;
29 velx = vely = 0;
30 jump = platform == false;
31 hDir = 0;
32 vDir = 2;
33
34
35}
36
37void Player::Update(ALLEGRO_EVENT ev, InputManager &input)
38{
39 Player::Controls(ev, input);
40
41}
42
43void Player::Draw(ALLEGRO_DISPLAY *display)
44{
45 al_draw_filled_rectangle(x , y , x2, y2, al_map_rgb(255, 200, 0));
46 al_flip_display();
47
48}
49
50void Player::Controls(ALLEGRO_EVENT ev, InputManager &input)
51{
52 if (movementPressed == false) {
53
54 if(input.IsKeyPressed(ev, ALLEGRO_KEY_RIGHT))
55 {
56 velx = speed;
57 hDir = 1;
58 movementPressed = true;
59 //vely = 0;
60 }
61 /*
62 else if(input.IsKeyPressed(ev, ALLEGRO_KEY_LEFT))
63 {
64 velx = -speed;
65 hDir = 2;
66 }
67 */
68 }
69
70
71 if(jump == true && input.IsKeyPressed(ev, ALLEGRO_KEY_UP))
72 {
73 vely = jumpspeed;
74 platform = false;
75 jump = false;
76 }
77}
78
79void Player::SetPosition()
80{
81 if (vely >= 0)
82 {
83 vDir = 2;
84 }
85
86 if(platform == false)
87 {
88 vely += gravity;
89 }
90
91 else
92 {
93 vely = 0;
94 }
95
96 x += velx;
97 y += vely;
98 x2 = x + width;
99 y2 = y + height;
100}
Collision class: 1#include "Collision.h"
2
3
4Collision::Collision()
5{
6}
7
8
9Collision::~Collision()
10{
11}
12
13void Collision::Init()
14{
15 loadCounterX = loadCounterY = 0;
16 Collision::LoadCollisionMap("ColMap1.txt", 0);
17 Collision::LoadCollisionMap("ColMap2.txt", 1);
18 Collision::LoadCollisionMap("ColMap3.txt", 2);
19}
20
21void Collision::Update(ALLEGRO_DISPLAY *display, Player &player, Map &map)
22{
23 Collision::PlatformCollision(display, player, map);
24 Collision::LevelReset(player, map);
25 Collision::DirReverse(player, map);
26 Collision::LevelEnd(player, map);
27}
28
29void Collision::Draw(ALLEGRO_DISPLAY *display)
30{
31
32}
33
34void Collision::LoadCollisionMap(const char *filename, int level)
35{
36 ifstream openfile(filename);
37 if(openfile.is_open())
38 {
39 openfile >> mapSizeX >> mapSizeY;
40 while(!openfile.eof())
41 {
42 openfile >> ColMapFile[level][loadCounterX][loadCounterY];
43 loadCounterX ++;
44 if (loadCounterX >= mapSizeX)
45 {
46 loadCounterX = 0;
47 loadCounterY ++;
48 }
49 }
50 loadCounterX = loadCounterY = 0;
51 }
52 else
53 {
54 { al_show_native_message_box(NULL, "Error", "Error",
55 "Cannot find collision map file", NULL, NULL);
56 }
57
58 }
59}
60
61void Collision::PlatformCollision(ALLEGRO_DISPLAY *display, Player &player, Map &map)
62{
63 for (int i = 0; i < mapSizeX; i++)
64 {
65 for(int j = 0; j < mapSizeY; j++)
66 {
67 if(ColMapFile[map.getLevel()][i][j] == 1)
68 {
69 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
70 {
71 //no collision
72 player.platform = false;
73 }
74
75 else
76 {
77 if (player.vDir == 1)
78 {
79 player.y += player.speed * 2;
80 player.y2 = player.y + 10;
81 player.vely = 0;
82 player.platform = false;
83 player.jump = false;
84 }
85
86 if(player.vDir == 2 && player.y - player.vely <= j*blockSize)
87 {
88 player.y = j*blockSize - 10;
89 player.y2 = player.y + 10;
90 player.platform = true;
91 player.jump = true;
92 player.vely = 0;
93
94 }
95
96
97 if (player.hDir == 1 && player.platform == false)
98 {
99 player.x -= player.speed;
100 player.x2 = player.x ;
101 }
102
103 if (player.hDir == 2 && player.platform == false)
104 {
105 player.x += player.speed;
106 player.x2 = player.x + 10;
107 }
108 }
109 }
110 }
111 }
112}
113
114void Collision::LevelReset(Player &player, Map &map)
115{
116 for (int i = 0; i < mapSizeX; i++)
117 {
118 for(int j = 0; j < mapSizeY; j++)
119 {
120 if(ColMapFile[map.getLevel()][i][j] == 2)
121 {
122 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
123 {
124 //no collision
125 }
126
127 else
128 {
129 player.x = player.origX;
130 player.y = player.origY;
131
132 map.setLevel(0);
133
134 player.velx = player.speed;
135 player.hDir = 1;
136 }
137 }
138 }
139 }
140
141}
142
143void Collision::LevelEnd(Player &player, Map &map)
144{
145 for (int i = 0; i < mapSizeX; i++)
146 {
147 for(int j = 0; j < mapSizeY; j++)
148 {
149 if(ColMapFile[map.getLevel()][i][j] == 3)
150 {
151 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
152 {
153 //no collision
154 }
155
156 else
157 {
158 int level = map.getLevel();
159 level ++;
160 map.setLevel(level);
161 if(level > 2)
162 {
163 map.setLevel(0);
164 player.velx = player.speed;
165 player.hDir = 1;
166 }
167 player.x = player.origX;
168 player.y = player.origY;
169
170 //Wait 1 second (loading new map)
171 al_clear_to_color(al_map_rgb(0, 0, 0));
172 al_flip_display();
173 //al_rest(1);
174 }
175 }
176 }
177 }
178
179}
180
181void Collision::DirReverse(Player &player, Map &map)
182{
183 for (int i = 0; i < mapSizeX; i++)
184 {
185 for(int j = 0; j < mapSizeY; j++)
186 {
187 if(ColMapFile[map.getLevel()][i][j] == 4)
188 {
189 if(player.x > i * blockSize + blockSize || player.y > j*blockSize + blockSize || player.x2 < i*blockSize || player.y2 < j*blockSize)
190 {
191 //no collision
192 }
193
194 else
195 {
196
197 player.velx -= player.speed;
198 player.hDir = 2;
199 }
200 }
201 }
202 }
203
204}
Global.h: 1#define ScreenWidth 800
2#define ScreenHeight 600
3#define blockSize 25
|
Dizzy Egg
Member #10,824
March 2009
![]() |
Ok, first off, adding 5 pixels a time is mega fast! Can you show me your main game loop, where you call all the functions please?
---------------------------------------------------- |
PamperBoy
Member #15,477
January 2014
|
Hehe it's a freaking mess and not commented hope you can find what you are looking for XD 1#include<iostream>
2#include<allegro5\allegro5.h>
3#include<fstream>
4//#include"Map.h"
5#include"Global.h"
6#include"Player.h"
7#include"InputManager.h"
8#include"Collision.h"
9#include<allegro5\keyboard.h>
10#include "Cam.h"
11
12using namespace std;
13
14int main()
15{
16 ALLEGRO_DISPLAY *display;
17
18 const float FPS = 60.0;
19 bool done = false;
20
21 //initialize Allegro & Display. If not you get error message.
22
23 if(!al_init())
24 { al_show_native_message_box(NULL, "Error", "Error",
25 "Cannot initialize Allegro", NULL, NULL);
26 return -1;
27 }
28
29 display = al_create_display(ScreenWidth, ScreenHeight);
30
31 if(!display)
32 {
33 al_show_native_message_box(NULL, "Error", "Error",
34 "Cannot create display", NULL, NULL);
35 return -1;
36 }
37
38 //al_set_window_position(display, 200, 200); //If window doesnt appear on screen
39
40 al_init_primitives_addon();
41 al_install_keyboard();
42
43 ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS);
44 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
45 ALLEGRO_KEYBOARD_STATE keyState;
46
47 ALLEGRO_TRANSFORM camera;
48
49 al_register_event_source(event_queue, al_get_keyboard_event_source());
50 al_register_event_source(event_queue, al_get_timer_event_source(timer));
51 al_register_event_source(event_queue, al_get_display_event_source(display));
52
53 InputManager input;
54 Player player;
55 Map map;
56 Collision collision;
57 Cam cam;
58
59 map.Init();
60 player.Init();
61 collision.Init();
62 cam.Init();
63 float cameraPosition[2] = { 0, 0 };
64
65
66
67 al_start_timer(timer);
68
69while(!done)
70 {
71 ALLEGRO_EVENT ev;
72 al_wait_for_event(event_queue, &ev);
73 al_get_keyboard_state(&keyState);
74
75
76 if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
77 {
78 done = true;
79 }
80
81 else if(input.IsKeyPressed(ev, ALLEGRO_KEY_ESCAPE))
82 {
83 done = true;
84 }
85
86
87 player.Controls(ev, input);
88 map.Draw(display);
89 player.SetPosition();
90 player.Draw(display);
91 cam.Update(cameraPosition, player);
92
93 al_identity_transform(&camera);
94 al_translate_transform(&camera, -(player.x + 16) , -(player.y + 16));
95 al_translate_transform(&camera, - cameraPosition[0] + (player.x+ 16),
96 -cameraPosition[1] + (player.y + 16));
97 al_use_transform(&camera);
98
99 collision.Update(display, player, map);
100
101 }
102
103
104
105 al_destroy_display(display);
106 al_destroy_timer(timer);
107 al_destroy_event_queue(event_queue);
108
109 return 0;
110}
|
Dizzy Egg
Member #10,824
March 2009
![]() |
Ok, there's a couple of things going on here that aren't quite right; and that doesn't mean anything negative with regards to you, there's things I do wrong all the time, that's the beauty of this forum, there's so much knowledge you can just keep getting better!... ...ok, first off, do you see that you're updating your player's x & y twice each loop? Once in the player.setPosition, and also in the collision class... ...don't change the players x/y in the collision function, that's what player.setPosition is for!... ...instead, give the player class a new bool, and call it canMove...set it to true when you call the player constructor, and set it to false when you have a collision; then, in your player.setPosition, ONLY allow the change of x/y if player.canMove == true... ...after you've done that, let me know what happens! [EDIT] (You're not using the timers quite right either, and a few other bits, but let's do this a problem at a time! [EDIT2] updated!!
---------------------------------------------------- |
PamperBoy
Member #15,477
January 2014
|
lets see. I dont think i get it... (this gives me the same result. when i colide to the left side of a tile i go in there in stop in the middle.) this is an if statement in the collision.cpp 1if(player.hDir == 1 && player.platform == false)
2 {
3 player.canMove = false;
4 }
this is the player setPosition 1void Player::SetPosition()
2{
3 if (vely >= 0)
4 {
5 vDir = 2;
6 }
7
8 if(canMove == false)
9 {
10 x -= speed;
11 x2 = x + 10;
12 }
13
14 if(platform == false)
15 {
16 vely += gravity;
17 }
18
19 else
20 {
21 vely = 0;
22 }
23
24 x += velx;
25 y += vely;
26 x2 = x + width;
27 y2 = y + height;
28
29}
|
Dizzy Egg
Member #10,824
March 2009
![]() |
I suppose the best way to get this solved fast is if you can send me your code? I could compile it here and find out why it's happening, and send you back the fixed code? Because at the moment I can't see enough to understand why...!
---------------------------------------------------- |
|