Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Help with bomb creating in my bomberman.

This thread is locked; no one can reply to it. rss feed Print
 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.

1//----- Clases --------//
2class Una_Bomba
3{
4 public:
5 Una_Bomba();
6 ~Una_Bomba();
7 void colocar(int, int, int);
8 void explotar();
9
10 private:
11
12 int tiempo_a_explotar;
13 int potencia;
14 int coordenada[2];
15};
16 
17class Pj
18{
19 public:
20 Pj(int);
21 ~Pj();
22 int moverse();
23 void dibujarse();
24 void crear_pj();
25 void poner_bomba();
26 
27 private:
28 BITMAP *dibu_pj;
29 int *celda_actual[5];
30 char *celda_derecha, *celda_izquierda, *celda_arriba, *celda_abajo;
31 int inicio, I, J, max_bombas, bombas_actuales, poder;
32 Una_Bomba * puntero_a_bomba;
33 Una_Bomba* bomba[MAX_BOMBS];
34};
35 
36//------ Clases functions ------//
37 
38 
39int Pj::moverse()
40{
41 if(tiempo1 == 1)
42 {
43 tiempo1=0;
44 if(*celda_arriba == Pisable && key[KEY_UP]) { J--; }
45 if(*celda_abajo == Pisable && key[KEY_DOWN]) { J++; }
46 if(*celda_izquierda == Pisable && key[KEY_LEFT]) { I--; }
47 if(*celda_derecha == Pisable && key[KEY_RIGHT]) { I++; }
48
49 }
50
51 celda_actual[cID] = &mapa.celda[I][J].ID; //Sabe su ID,
52 celda_actual[cX] = &mapa.celda[I][J].x; // x,
53 celda_actual[cY] = &mapa.celda[I][J].y; // y.
54
55 celda_arriba = &mapa.celda[I][J-1].estado; //Y averiguamos el estado de las otras
56 celda_abajo = &mapa.celda[I][J+1].estado; //celdas circundantes
57 celda_izquierda = &mapa.celda[I-1][J].estado;
58 celda_derecha = &mapa.celda[I+1][J].estado;
59 
60 return *celda_actual[cID];
61}
62 
63 
64void Pj::dibujarse()
65{
66 clear_to_color(mapa_pj, makecol(255, 0, 255));
67 draw_sprite(mapa_pj, dibu_pj,*celda_actual[cX],*celda_actual[cY]);
68 draw_sprite(buffer, mapa_pj, 80, 80);
69 
70}
71 
72void Pj::poner_bomba()
73{
74/*
75This is the function causing all the trouble, basically, if the player presses
76spacebar, he's under his max_bombs limit and the current_tile status is different
77of "whith_bomb", it creates a new bomb, it pases the parameters needed, and puts
78out a pointer to that bomb. Then it changes map tile's status, so the map.draw
79function can take care of the graphics, and increments the number of bombs the
80player has set.
81*/
82if(key[KEY_SPACE] && bombas_actuales < max_bombas && *celda_actual[cEstado] != Con_Bomba)
83 {
84 puntero_a_bomba = new Una_Bomba;
85 puntero_a_bomba->colocar(poder, (int)*celda_actual[cX], (int)*celda_actual[cY]);
86 bomba[bombas_actuales] = puntero_a_bomba;
87
88 mapa.celda[I][J].estado = Con_Bomba;
89 bombas_actuales++;
90 }
91}
92 
93 
94void Una_Bomba::colocar(int poder_act, int coord_x_act, int coord_y_act)
95{
96 potencia = poder_act;
97 coordenada[0] = coord_x_act;
98 coordenada[1] = coord_y_act;
99}

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
avatar

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!

*^_^*

Christopher Bludau
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.
But if the player stands ON the bomb he places, he can´t move OFF the bomb.

Try to disable collision checking with bombs and see if movemnt works then.

[EDIT]
too slow. Sorry.
Yes. The spanish makes it hard to understand the code.
I will have a closer look at the code when I'm at home.
Don't have the time to investigate it closely right now.

But you could still try to disable collision detection and see what happens.

Indeterminatus
Member #737
November 2000
avatar

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).

_______________________________
Indeterminatus. [Atomic Butcher]
si tacuisses, philosophus mansisses

Christopher Bludau
Member #5,401
January 2005

Where do you calculate cX and cY?
And where do you set the tile with the bomb on it to not passable?

I only see mapa.celda[I][J].estado = Con_Bomba;
But that sets that the tile has a bomb. Not whether it is passable or not.

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.

#SelectExpand
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

#SelectExpand
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

#SelectExpand
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 code should answer the questions posted above, and I still think the problem is in the memory management, cause I suck at that kind of things. ;P

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 ;D

Cheers, and thanks for lending me some of your time solve this problem.

(_/)
( ·.·)
(") (")

[EDIT]
While you're at it,check the timer in base.cpp cause I'm not shure if it's used that way. Thanks again!!!

Christopher Bludau
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 :-/ Based on your description, though, it doesn't sound like an issue with memory management. You said that the player can move in one direction after placing the bomb. If you move in that direction, can you then set more bombs?

---
It's Ridge Racer! RIIIIIDGE RAAAAACER!

Lostforever
Member #7,253
May 2006

nope, you can't keep on placing bobms

Erkle
Member #3,493
May 2003
avatar

What direction?

If the writing above has offended you, you've read it wrong.....fool.
And if you read that wrong it means 'All of the above is opinion and is only to be treated as such.'

Kauhiz
Member #4,798
July 2004

Are you supposed to be able to place more bombs?

---
It's Ridge Racer! RIIIIIDGE RAAAAACER!

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:

1/// From Pj::Pj ///
2max_bombas = 3;
3bombas_actuales=0;
4 
5/// From Pj::poner_bomba() ///
6 
7if(key[KEY_SPACE] && bombas_actuales < max_bombas && *celda_actual[cEstado] != Con_Bomba)
8/*So if user presses SPACE_KEY AND bombas actuales (initially 0 but it increments
9 at the end of this function) is less than max bombas (wich has a value of 3, and
10 will remain like that for a while) AND the actual cell doesn't already have a
11bomb... do all the stuff below*/
12 {
13 puntero_a_bomba = new Una_Bomba;
14 puntero_a_bomba->colocar(poder, (int)*celda_actual[cX], (int)*celda_actual[cY]);
15 bomba[bombas_actuales] = puntero_a_bomba;
16
17 mapa.celda[I][J].estado = Con_Bomba;
18 bombas_actuales++; // here is the increment I said about bombas_actuales
19 }

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 *^_^*

Christopher Bludau
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.

  if(tiempo1 == 1)
  {
   tiempo1=0;
   if(*celda_arriba    == Pisable   && key[KEY_UP])    { J--; }
   if(*celda_abajo     == Pisable   && key[KEY_DOWN])  { J++; }
   if(*celda_izquierda == Pisable   && key[KEY_LEFT])  { I--; }
   if(*celda_derecha   == Pisable   && key[KEY_RIGHT]) { I++; }
   
  }

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.
But I wondered about this anyway.

EDIT
If that would be the problem, i guess you couldn't move at all.
But I'm still wondering why it's char and not int.

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. *^_^*

Christopher Bludau
Member #5,401
January 2005

you are totaly right! My brain doesn't work that good the last few days ::)
char is -128 to 127.

[EDIT]
hey, wait.
char c; is -128 to 127.

but you are using char *c;
Isn't that a little difference?

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
As far as I can gess "pointer to char called c" should ocuppy less than the same but whith int. Anyhow, if you're asking about the program dynamics, the movement part worked fine whith the pointers set as they are (till you try to set a bomb that is) so I dont think theres much to worry about there.

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. *^_^*

Christopher Bludau
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 char = "asdj"; wrong

char *string = 'd'; wrong
char *string = "hallo"; correct (a number too???)

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.
I think my help is not leeding anywhere.

Audric
Member #907
January 2001

EDIT:
*celda_actual[5] = 0;
memory overwrite!
celda_actual has only 5 elements, labelled 0 to 4. don't try to read or write celda_actual[5].
-----------
There is one suspicious part about how you use the 4 pointers celda_abajo, celda_derecha etc.
They make you allocate 4 characters on startup, just so they don't point to void... They even force you to make something strange with tiempo1.
I don't know how much this part is ok.
You could completely remove them, as well as tiempo1, so your Pj::moverse() will look like:

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!
:D

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.
:P

Cheers and thanks!!!
(_/)
( ^.^)
(") (")

Audric
Member #907
January 2001

I edited above a few seconds ago

Indeterminatus
Member #737
November 2000
avatar

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. ;D

_______________________________
Indeterminatus. [Atomic Butcher]
si tacuisses, philosophus mansisses

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--; }
if(*celda_abajo...

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;
celda abajo ...

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
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;

I had read that in some manual, but with your example light just cliked on in my head and I understood it :) thanks!!

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!!
(PS: My offer of cookies for the first one who solves this problem, still stands!! xD)

Audric
Member #907
January 2001

Sorry if I wasn't clear, I wrote in a hurry.
celda_actual is allocated as:
int *celda_actual[5];
You can then use celda_actual[0] to celda_actual[4], ONLY. celda_actual[5] is out of your array.

In Pj::Pj(), you wrote:
for(int i=0; i<5; i++) {celda_actual<i> = new int; *celda_actual<i> = 0;}
This is fine, but later:
*celda_actual[5] = 0;
This line is wrong, and writes 0 to a random address. Enough to cause crashes or random behaviors of your program.

 1   2 


Go to: