![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
Help with bomb creating in my bomberman. |
Lostforever
Member #7,253
May 2006
|
I'ts been some time since I posted here, till now I've been managing to RTFM to solve my multiple problems, but since I've been over a week stuck on the same one, I guess I'll let you guys have a look at it so you can (hopefully) tell me what's wrong. Now, to business. I've been making the typical all-round bomberman, just to learn how to use pointers, and how memory management works, and on the part of dynamically creating my bombs when the player preses the space key, a weird bug hapens. You can place the first bomb, and afther that the game keeps running, but if the player tries to move in all but one specific direction, he stops being able to move and ends up stuck on top of the bomb, though nothing else hapens. And obviously, he can't place any more bombs. here's the bit of code relevant to the issue.
Thats more or less it, and I think that's all the code needed for helping me out, if anyone needs more, pray tell, and I'll upload the whole project (it's quite small anyway). I sincerely hope you guys can help me, cause inin spitef myself, I still get lost when playing with the PC's memory. Cheers, and thanks!! |
Richard Phipps
Member #1,632
November 2001
![]() |
It's probably because the tile underneath the player is marked as a bomb and hence not-walkable. |
Lostforever
Member #7,253
May 2006
|
Sadlly, I'ts not so simple a bug, if you look closelly you'll see that the Pj:moverse function checks the surrounding 4 tiles to see if it can move, it doesnt care for the actual_position_tile, I designed it this way specifically for the bomb placing. I gess that me using spanish words as variables doesnt help much either... Anyway, thanks for triying! *^_^* |
count
Member #5,401
January 2005
|
Without looking at the code that wold have been my first guess, too. You probably wrote the game that way, that the player can´t walk ON placed bombs. Try to disable collision checking with bombs and see if movemnt works then. [EDIT] But you could still try to disable collision detection and see what happens.
|
Indeterminatus
Member #737
November 2000
![]() |
What's the difference between celda_actual[cX] and I? Are you using two different coordinate systems? If so, the problem might be in the synchronisation of the two. (Just check where you change I and J, respectively). _______________________________ |
count
Member #5,401
January 2005
|
Where do you calculate cX and cY? I only see mapa.celda[I][J].estado = Con_Bomba; Am I missing something?
|
Lostforever
Member #7,253
May 2006
|
Hum, my bad, I'll just upload the whole code so you people can look at it at ease, It's not too long anyhow. 1///-- Clases.h --////
2#ifndef clases
3#define clases
4
5#define map_w 21
6#define map_h 19
7#define MAX_BOMBS 10
8/*Falta hacer un pj que se mueva por la pantalla sin meterse en el muro.*/
9
10class Celda
11{
12 public:
13 int x, y, ID;
14 char estado;
15};
16
17class Mapa
18{
19 public:
20 Celda celda[map_w][map_h];
21 void crear_mapa();
22 void dibujar_mapa();
23 void destruir_mapa();
24};
25
26class Una_Bomba
27{
28 public:
29 Una_Bomba();
30 ~Una_Bomba();
31 void colocar(int, int, int);
32 void explotar();
33
34 private:
35
36 int tiempo_a_explotar;
37 int potencia;
38 int coordenada[2];
39};
40
41class Pj
42{
43 public:
44 Pj(int);
45 ~Pj();
46 int moverse();
47 void dibujarse();
48 void crear_pj();
49 void poner_bomba();
50
51 private:
52 BITMAP *dibu_pj;
53 int *celda_actual[5];
54 char *celda_derecha, *celda_izquierda, *celda_arriba, *celda_abajo;
55 int inicio, I, J, max_bombas, bombas_actuales, poder;
56 Una_Bomba * puntero_a_bomba;
57 Una_Bomba* bomba[MAX_BOMBS];
58};
59
60//"So I was walking and I saw this prostitute, then I asked how much. She said for 300 bucks; she'd do anything. I said Bitch, paint my house." -Cafiene
61#endif
1///---interfaz_clases.h---///
2#ifndef interfaz_clases
3#define interfaz_clases
4
5#include "clases.h"
6/*aui los funcionamientos de las clases, enpezando por el mapa*/
7#define map_w 21
8#define map_h 19
9#define tam_celda 32
10#define ein if(bombas_actuales==1) textout_ex(buffer, font, "Pues si", 0, 180, makecol(255,0,0), -1); else textout_ex(buffer, font, "Pues no", 0, 200, makecol(255,0,0), -1);
11
12
13enum {Pisable, Caja, Muro, Con_Bomba};
14enum {cID, cX, cY, cEstado};
15extern BITMAP *buffer, *del_mapa, *fondo_mapa, *el_muro, *la_caja, *mapa_pj, *dibu_bomba, *dibu_fuego;
16extern PALETTE palette;
17extern volatile int tiempo1;
18
19Mapa mapa;
20Pj player1(378);
21//I was about to take over the world, but then I was distracted by something...shiny. oOOohHh...shhiinnny....
22
23void Mapa::crear_mapa()
24{
25int i, j, random =0, ident =0;
26 for(i=0; i < map_w; i++)
27 {
28 for(j=0; j < map_h; j++)
29 {
30 mapa.celda<i>[j].x=i*32;
31 mapa.celda<i>[j].y=j*32;
32
33 random = rand()%2;
34
35 if (j==0 || i==0 || i==map_w-1 || j==map_h-1) mapa.celda<i>[j].estado = Muro; // Si esta en los bordes, se considera muro
36 else if (i%2==0 && j%2==0) mapa.celda<i>[j].estado = Muro; // Hay muros en zonas pares, para hacer una estructura de pasillos
37 else mapa.celda<i>[j].estado = random; // Elige entre 0 y 1 (pisable, o con caja)
38
39 mapa.celda<i>[j].ID = ident;
40 ident++; // La ID
41 }
42 }
43 mapa.celda[1][1].estado = Pisable;
44 mapa.celda[2][1].estado = Pisable;
45 mapa.celda[1][2].estado = Pisable;
46 mapa.celda[map_w-3][map_h-2].estado = Pisable;
47 mapa.celda[map_w-2][map_h-3].estado = Pisable;
48 mapa.celda[map_w-2][map_h-2].estado = Pisable; //Nos aseguramos q los pjs aparezcan en pisable
49}
50 //...don't question my logic. ¬¬
51 //Pop! goes the kitten... and other fun microwave games :P
52void Mapa::dibujar_mapa()
53{
54int i, j;
55draw_sprite(del_mapa, fondo_mapa, tam_celda, tam_celda); //Fondo del mapa
56
57 for(i=0; i < map_w; i++) //Dibujar, segun el estado de la celda, muro o caja si es necesario
58 {
59 for(j=0; j < map_h; j++)
60 {
61 if (mapa.celda<i>[j].estado == Muro)
62 {
63 draw_sprite(del_mapa, el_muro, mapa.celda<i>[j].x,mapa.celda<i>[j].y);
64 }
65 if (mapa.celda<i>[j].estado == Caja)
66 {
67 draw_sprite(del_mapa, la_caja, mapa.celda<i>[j].x,mapa.celda<i>[j].y);
68 }
69 if (mapa.celda<i>[j].estado == Con_Bomba)
70 {
71 draw_sprite(del_mapa, dibu_bomba, mapa.celda<i>[j].x,mapa.celda<i>[j].y);
72 }
73 }
74 }
75draw_sprite(buffer, del_mapa, 80, 80); //Pasar el dibu al buffer
76
77}
78//I cannot be held responsible for further messages, as apparently, my cats have learned to type... - VickyUWE
79
80void Mapa::destruir_mapa() //Autoexplicativo
81{
82 destroy_bitmap(del_mapa);
83 destroy_bitmap(fondo_mapa);
84 destroy_bitmap(el_muro);
85 destroy_bitmap(la_caja);
86}
87
88Pj::Pj(int pos_ini)
89{
90for(int i=0; i<5; i++) {celda_actual<i> = new int; *celda_actual<i> = 0;}
91celda_arriba = new char;
92celda_abajo = new char;
93celda_derecha = new char;
94celda_izquierda = new char;
95*celda_actual[5] = 0;
96*celda_arriba = 0;
97*celda_abajo = 0;
98*celda_derecha = 0;
99*celda_izquierda = 0;
100inicio = pos_ini;
101I=0;
102J=0;
103max_bombas = 3;
104bombas_actuales=0;
105for(int i; i< MAX_BOMBS; i++) { bomba<i>=0; }
106poder = 3;
107}
108
109Pj::~Pj()
110{
111delete[] celda_actual;
112delete celda_arriba ;
113delete celda_abajo;
114delete celda_izquierda;
115delete celda_derecha;
116delete[] bomba;
117}
118
119//"Before you criticize someone, you should walk a mile in their shoes. That way, when you criticize them, you're a mile away and you have their shoes. - Bluelance"
120void Pj::crear_pj()
121{
122int ii=0, jj=0;
123bool flag1 = false;
124
125for(ii=0; ii< map_w; ii++) // Con este apaño, celda actual apunta a la celda donde empieza
126 {
127 for(jj=0; jj<map_h; jj++)
128 {
129 if(mapa.celda[ii][jj].ID == inicio) {flag1 = true; break;}
130 }
131 if(flag1) break;
132 }
133
134 I = ii;
135 J = jj;
136 celda_actual[cID] = &mapa.celda[I][J].ID; // Sabe su ID,
137 celda_actual[cX] = &mapa.celda[I][J].x; // x,
138 celda_actual[cY] = &mapa.celda[I][J].y; // y,
139 celda_actual[cEstado] = (int*)&mapa.celda[I][J].estado; // estado.
140
141 celda_arriba = &mapa.celda[I][J-1].estado; // Y averiguamos el estado de las otras
142 celda_abajo = &mapa.celda[I][J+1].estado; // celdas circundantes
143 celda_izquierda = &mapa.celda[I-1][J].estado;
144 celda_derecha = &mapa.celda[I+1][J].estado;
145
146 dibu_pj = create_bitmap(tam_celda,tam_celda); // Crear el bitmap del dibu
147 clear_to_color(dibu_pj, makecol(255, 0, 255));
148 dibu_pj = load_bitmap("imagenes/dibu_pj.pcx", palette);
149
150}
151
152
153int Pj::moverse()
154{
155 if(tiempo1 == 1)
156 {
157 tiempo1=0;
158 if(*celda_arriba == Pisable && key[KEY_UP]) { J--; }
159 if(*celda_abajo == Pisable && key[KEY_DOWN]) { J++; }
160 if(*celda_izquierda == Pisable && key[KEY_LEFT]) { I--; }
161 if(*celda_derecha == Pisable && key[KEY_RIGHT]) { I++; }
162
163 }
164
165 celda_actual[cID] = &mapa.celda[I][J].ID; //Sabe su ID,
166 celda_actual[cX] = &mapa.celda[I][J].x; // x,
167 celda_actual[cY] = &mapa.celda[I][J].y; // y.
168
169 celda_arriba = &mapa.celda[I][J-1].estado; //Y averiguamos el estado de las otras
170 celda_abajo = &mapa.celda[I][J+1].estado; //celdas circundantes
171 celda_izquierda = &mapa.celda[I-1][J].estado;
172 celda_derecha = &mapa.celda[I+1][J].estado;
173
174 return *celda_actual[cID];
175}
176
177
178void Pj::dibujarse()
179{
180 clear_to_color(mapa_pj, makecol(255, 0, 255));
181 draw_sprite(mapa_pj, dibu_pj,*celda_actual[cX],*celda_actual[cY]);
182 draw_sprite(buffer, mapa_pj, 80, 80);
183
184 ein
185}
186
187void Pj::poner_bomba()
188{
189/*
190Player le da a la tecla de poner bomba,
191se mira cuantas bombas tiene puestas el pj,
192si tiene menos del maximo, y la celda actual es estado != bomba,
193se guarda la posicionactual del pj
194en el momento de poner la bomba (posi_bomba[nºbombas][coordenada (x o y)])
195esa celda pasa a estado == bomba,
196se conecta el timer, a los 5 secs la bomba explota
197*/
198if(key[KEY_SPACE] && bombas_actuales < max_bombas && *celda_actual[cEstado] != Con_Bomba)
199 {
200 puntero_a_bomba = new Una_Bomba;
201 puntero_a_bomba->colocar(poder, (int)*celda_actual[cX], (int)*celda_actual[cY]);
202 bomba[bombas_actuales] = puntero_a_bomba;
203
204 mapa.celda[I][J].estado = Con_Bomba;
205 bombas_actuales++;
206 }
207}
208
209
210void Una_Bomba::colocar(int poder_act, int coord_x_act, int coord_y_act)
211{
212 potencia = poder_act;
213 coordenada[0] = coord_x_act;
214 coordenada[1] = coord_y_act;
215}
216
217Una_Bomba::Una_Bomba(){}
218Una_Bomba::~Una_Bomba(){}
219
220#endif
1/// --- base.ccp --- ///
2#include "interfaz_clases.h"
3#include <time.h>
4
5BITMAP *raton, *buffer, *del_mapa, *fondo_mapa, *el_muro, *la_caja, *mapa_pj, *dibu_bomba, *dibu_fuego;
6PALETTE palette;
7
8void iniciartodo();
9void salir();
10bool done = false;
11
12volatile int tiempo1 = 0;
13void ticker(void)
14{
15 tiempo1=1;
16}
17END_OF_FUNCTION(ticker)
18
19void iniciartodo()
20{
21 allegro_init();
22 install_keyboard();
23 install_mouse();
24 set_color_depth(32);
25 set_gfx_mode(GFX_AUTODETECT, 1024, 768, 0, 0);
26
27 install_timer();
28 LOCK_FUNCTION(ticker);
29 LOCK_VARIABLE(tiempo1);
30 install_int_ex(ticker, BPS_TO_TIMER(15));
31
32
33 srand ( time(NULL) ); /* initialize random generator */
34
35 buffer = create_bitmap(SCREEN_W, SCREEN_H);
36 raton = create_bitmap(SCREEN_W, SCREEN_H);
37 clear(buffer);
38 clear_to_color(raton, makecol(255, 0, 255));
39
40 del_mapa = create_bitmap(map_w * tam_celda, map_h * tam_celda); //crea el bitmap del_mapa
41 clear_to_color(del_mapa, makecol(255, 0, 255)); // y lo limpia a transparente
42
43 mapa_pj = create_bitmap(map_w * tam_celda, map_h * tam_celda);
44 clear_to_color(mapa_pj, makecol(255, 0, 255));
45
46 fondo_mapa = create_bitmap(map_w-1 * tam_celda, map_h-1 * tam_celda); //Crea el bitmap del fondo del mapa
47 //clear_to_color(fondo_mapa, makecol(255, 0, 255)); //Porque no funciona el clear? da error de ejcucion
48 fondo_mapa = load_bitmap("imagenes/fondo.pcx", palette); //y carga la imagen del fondo
49
50 el_muro = create_bitmap(tam_celda,tam_celda);
51 clear_to_color(el_muro, makecol(255, 0, 255));
52 el_muro = load_bitmap("imagenes/muro.pcx", palette);
53
54 la_caja = create_bitmap(tam_celda,tam_celda);
55 clear_to_color(la_caja, makecol(255, 0, 255));
56 la_caja = load_bitmap("imagenes/caja.pcx", palette);
57
58 dibu_bomba = create_bitmap(tam_celda,tam_celda);
59 clear_to_color(dibu_bomba, makecol(255, 0, 255));
60 dibu_bomba = load_bitmap("imagenes/bomba.pcx", palette);
61
62
63 show_mouse(raton);
64
65}
66
67//Why can't Mr. Fork and Mrs. Eletrical outlet be friends?
68void salir() { if (key[KEY_ESC]) done = true;}
69
70int main()
71{
72 iniciartodo();
73 mapa.crear_mapa();
74 player1.crear_pj();
75
76 while (!done)
77 {
78 clear(buffer);
79 player1.moverse();
80 player1.poner_bomba();
81
82 mapa.dibujar_mapa();
83 player1.dibujarse();
84 draw_sprite(buffer, raton,0,0);
85 blit(buffer, screen,0,0,0,0,SCREEN_W,SCREEN_H);
86
87 salir();
88 }
89
90 mapa.destruir_mapa();
91 destroy_bitmap(raton);
92 destroy_bitmap(buffer);
93 return 0;
94}
95END_OF_MAIN()
Hum, please just ignore unaccountable comments, it's just personal joke with a fried (and the ARE funny xD, not mine though). The answer is in the interfaz_clases.h file with all probability, but, much easier to understand everything if I upload all the files. On a side note, as I'm still a beginner to all kinds of programing, and to making games and so on, if you spot any other problems, or find prettier solutions (which shouldn't be hard considering this code...) to anything I've done, point them out Cheers, and thanks for lending me some of your time solve this problem. (_/) [EDIT] |
count
Member #5,401
January 2005
|
when you use this: enum {cID, cX, cY, cEstado}; This, celda_actual[cX] = &mapa.celda[I][J].x; // x, celda_actual[cY] = &mapa.celda[I][J].y; // y. will always equal this celda_actual[1] = &mapa.celda[I][J].x; // x, celda_actual[2] = &mapa.celda[I][J].y; // y. Is that what you want?
|
Lostforever
Member #7,253
May 2006
|
Yes, indeed, I'ts only I find it clearer to use names in the [] rather than numbers, but I still think the bug is in the memory management issue of the void Pj::poner_bomba() function. Anyway, thanks for cheking. *^_^* |
Kauhiz
Member #4,798
July 2004
|
I'm having a hard time reading the code, the Spanish keeps confusing me --- |
Lostforever
Member #7,253
May 2006
|
nope, you can't keep on placing bobms |
Erkle
Member #3,493
May 2003
![]() |
What direction?
If the writing above has offended you, you've read it wrong.....fool. |
Kauhiz
Member #4,798
July 2004
|
Are you supposed to be able to place more bombs? --- |
Lostforever
Member #7,253
May 2006
|
Upwards is the only direction that works, and yes, you are suposed to be able to set more bombs, as shown below:
In short, it can and should be able to set 2 more bombs. Hey, I really apreciate you guys mulling over my code, cookies for the first one who finds out whats wrong *^_^* |
count
Member #5,401
January 2005
|
I'm telling you how I understand your code. Please say if I'm right. Here you check wheter field_left, field_right... are passable and if so move to the field. And here you give field_left ... the type of the sourunding fields. Right? celda_arriba = &mapa.celda[I][J-1].estado; //Y averiguamos el estado de las otras celda_abajo = &mapa.celda[I][J+1].estado; //celdas circundantes celda_izquierda = &mapa.celda[I-1][J].estado; celda_derecha = &mapa.celda[I+1][J].estado; The possible field types are enum {Pisable, Caja, Muro, Con_Bomba}; Shouldn't then this char *celda_derecha, *celda_izquierda, *celda_arriba, *celda_abajo; look like this int celda_derecha, celda_izquierda, celda_arriba, celda_abajo;
I'm absolutely not sure if this is related to your problem. EDIT
|
Lostforever
Member #7,253
May 2006
|
As far as I know (but I might be wrong, not too unusual) char takes up less memory than int (0 to 255 I seem to remember) and as I'm only going to use up to 10 different states or so, I din't think I'd need an full int. Thanks for cheking anyhow. *^_^* |
count
Member #5,401
January 2005
|
you are totaly right! My brain doesn't work that good the last few days [EDIT] but you are using char *c;
|
Lostforever
Member #7,253
May 2006
|
Well, as I said somewere at the begginign of this whole bussines, I started the whole bomberman project just to learn about pointers, son cant say much there xD And back to the begining, I still think the void Pj::poner_bomba() function does something fishy somewere whith the memory. But that might just be me, and as I have absolutely no idea what it may be... Cheers and thanks for raking your brains for me Christopher. *^_^* |
count
Member #5,401
January 2005
|
but if you want to use characters not numbers this happens. char char = 'a'; this is ok (equals a number, like int) char *string = 'd'; wrong So I thought that there is another difference? I never got that difference between those two, so maybe I'm wrong again. No I will wait till the experts come and solve your problem.
|
Audric
Member #907
January 2001
|
EDIT: int Pj::moverse() { if(mapa.celda[I] [J-1].estado == Pisable && key[KEY_UP]) { J--; } if(mapa.celda[I] [J+1].estado == Pisable && key[KEY_DOWN]) { J++; } if(mapa.celda[I-1][J] .estado == Pisable && key[KEY_LEFT]) { I--; } if(mapa.celda[I+1][J] .estado == Pisable && key[KEY_RIGHT]) { I++; } celda_actual[cID] = &mapa.celda[I][J].ID; //Sabe su ID, celda_actual[cX] = &mapa.celda[I][J].x; // x, celda_actual[cY] = &mapa.celda[I][J].y; // y. return *celda_actual[cID]; } Such change SHOULD have not effect - if it makes your problem disappear or change bahaviour, it means there was something weird in the removed part. One word of general advice: you rarely need pointers to struct members which are simple numbers: For example, since ID, x and y are plain numbers, you can simply: // declare one pointer to a Cell Celda * celda_actual; // set it celda_actual = & mapa.celda[I][J]; // then you can refer to ANY property of this cell: here you read values printf("ID[%d] x[%d] y[%d]\n", celda_actual->ID, // synonym of &celda_actual.ID celda_actual->x, celda_actual->y); // here you modify them celda_actual->estado = Con_Bomba;
|
Lostforever
Member #7,253
May 2006
|
I cant chek it right now, not on my comp and also quite in a hurry, but tomorrow I'll be able to. Just wanted to thank you for such a helpfull post! So... thanks! I'll check as soon as I can to see if it solves the problem, and do what you sugest, I am aware of lots of really useles or unecesary stuff in there, but thats why people like you exist ot there, to point them out so I can rectify. Cheers and thanks!!! |
Audric
Member #907
January 2001
|
I edited above a few seconds ago |
Indeterminatus
Member #737
November 2000
![]() |
Just a small correction (and very nit-picky), sorry for derailing the topic, it just popped in my eye: Quote: celda_actual->ID, // synonym of (*celda_actual).ID
edit: To clarify: as this is apparently all about learning pointers, such small issues can possibly make a huge difference in the understanding, which is what justifies my being pedantic, imho. _______________________________ |
Lostforever
Member #7,253
May 2006
|
Hum, sorry for taking so long to reply, Audric, The pj::moverse is like that: if(*celda_arriba == Pisable && key[KEY_UP]) { J--; } to simplyfy reading (at least in spanish xD), and tiempo1 is something of the timer set up at the begginign of base.ccp (which btw, I dont know if i'ts beeing used properly, thought it does slow down movement speed for the Pj), and the: celda_arriba = &mapa.celda[I][J-1].estado; Is repointing the pointers to where they were, but as they are not your typical int or char variables (they are pointers so they dont need to check again to see the value if its changed or something like that), I gess thats not needed? (asking here). Quote:
/ declare one pointer to a Cell
I had read that in some manual, but with your example light just cliked on in my head and I understood it Indeterminatus, thanks to you too for making shure I wouldnt spend hours scrathing my head wondering what the hell was going on xD But still the error remains, that damm litle bomberman still seems to think his job is done as soon as he sets down his first bomb, anyone have any idea why this is?? Cheers everyone, and thanks again!! |
Audric
Member #907
January 2001
|
Sorry if I wasn't clear, I wrote in a hurry. In Pj::Pj(), you wrote: |
|
1
2
|