En principio lo pongo aqui porque estoy intentando usar la CRM32Pro con el devc++, pero si hay que moverlo se mueve.
La cosa es que estoy haciendo un pong y estaba empezando con el tema de las puntuaciones y resulta que el int que uso para llevar la cuenta no me lo incrementa. Da igual que ponga el n++ en el bucle principal o donde sea, solo me lo suma una única vez y no se porque narices lo hace.
La variable, bueno son dos pero da igual, estan declaradas como globales e inicializadas a cero. La idea era que cuando la pelota llegara al lateral de la pantalla le sumara uno, aparte de rebotar como siempre hace (esto lo quitare luego).
He revisado el codigo tropecientas veces, el unico sitio donde se pone la variable a cero es cuando se declara pero parece que lo haga cada bucle :?
Alguien sabe algo?
Harko.
La variable no incrementa ? Es esto ?
Hum... Talvez seja lo caso de no estar llegando a lo ponto onde la variable incrementa.Tentaste depurar lo programa para saber se esta realmente llegando lá ? Ou talvez lo valor esteja sendo reasignado todas as vezes...
Ademas yo no me gusta usar variables globales , a menos que seja un programa pequeno.
Desculpe pelo malo español pero no lo hablo mui bien ....
Saracchini no pasa nada ^^
Me aburro, voy a ponerlo en castellano total lo de Saracchini para que no haya problemas de lectura, aunque yo creo que se entiende muy bien no? :o
Cita de: "Saracchini"
La variable no incrementa? Es eso?
Hum...tal vez se da el caso de que no esta llegando al punto donde la variable incrementa. Intentaste depurar el programa para saber si esta realmenta llegando al punto? O tal vez el valor esta siendo reasignado todas las veces...
Además no me gusta usar variables globales, a menos que sea un programa pequeño.
Disculpa mi mal español, pero no lo hablo muy bien...
Ala, a ver que encuentro ahora pa entretenerme....
Bye
Yo insistiría en que pusieras el código aquí. Es difícil saber qué pasa cuando alguien dice: << esto falla, pero lo he revisado y está bien >>. :)
buf si pongo toooodoo el codigo se me acaba el foro, esta todo juntito jeje :P
Bueno, pongo un extracto:
//Variables globales
int p1=0, p2=0; //Puntuacion jugador
///Resto .....
int main(){//paso de poner lo de dentro ahora que me da palo XD
//voy directamente al bucle principal
while(!done){
//...
p1++;
//....
}
Cuando muestro por pantalla p1 me saca un 1 pero no sigue aumentando. Solo lo suma una vez. Lo he puesto asi porque es como lo probe al final a ver si iva, pero nada.
Harko.
Como hay dito, debe haver un condicional que no deve estar sendo satisfecto pois o codigo do jeito que esta incrementa sempre la variable "p1". Acabei de testar.
Harko,
me temo que esto es de esos casos que o pasas el codigo o poco podremos hacer...
mandamelo si quieres por email, tengo un monton de paquetes software para depurar y probar eso y ver que leches esta pasando...realmente parece muy muy raro y algo de punteros lo dudo, la probabilidad de que solo te sobreescriba esa variable y no otra cosa sin provocar un cuelgue es muy pequeño... no se, no se me ocurre nada que pueda ser...
ya sabes... "Enviar a..." jejeje
mmmmm.......... Vale, ya lo tengo.
No era cosa de la variable sino de la forma en que lo mostraba. Habia hecho varios graficos cada uno con un digito de 0 a 9 para ir mostrando las puntuaciones y cada ciclo comprovaba el valor de la puntiacion y cargaba la imagen que tocara. Lo que pasaba es que no la cambiaba, al final borrando el sprite y volviendolo a crear me deja.
void Puntuaciones(){
delete punt1;
delete punt2;
punt1= new CRM32Pro_CSprite();
punt2= new CRM32Pro_CSprite();
switch(p1){
case 0: punt1->Load(GFX_RESOURCE, "0"); break;
case 1: punt1->Load(GFX_RESOURCE, "1"); break;
case 2: punt1->Load(GFX_RESOURCE, "2"); break;
case 3: punt1->Load(GFX_RESOURCE, "3"); break;
case 4: punt1->Load(GFX_RESOURCE, "4"); break;
case 5: punt1->Load(GFX_RESOURCE, "5"); break;
case 6: punt1->Load(GFX_RESOURCE, "6"); break;
case 7: punt1->Load(GFX_RESOURCE, "7"); break;
case 8: punt1->Load(GFX_RESOURCE, "8"); break;
case 9: punt1->Load(GFX_RESOURCE, "9"); break;
}
punt1->AutoRestore(0);
punt1->SetPosition(260,10);
switch(p2){
case 0: punt2->Load(GFX_RESOURCE, "0"); break;
case 1: punt2->Load(GFX_RESOURCE, "1"); break;
case 2: punt2->Load(GFX_RESOURCE, "2"); break;
case 3: punt2->Load(GFX_RESOURCE, "3"); break;
case 4: punt2->Load(GFX_RESOURCE, "4"); break;
case 5: punt2->Load(GFX_RESOURCE, "5"); break;
case 6: punt2->Load(GFX_RESOURCE, "6"); break;
case 7: punt2->Load(GFX_RESOURCE, "7"); break;
case 8: punt2->Load(GFX_RESOURCE, "8"); break;
case 9: punt2->Load(GFX_RESOURCE, "9"); break;
}
punt2->AutoRestore(0);
punt2->SetPosition(340,10);
}
Los dos primeros deletes y news es lo que he añadido para que funcione. Me parece que sin el delete tambien funciona, pero lo dejo por si acaso.
Hay alguna otra manera de que se actualice el sprite? Y otra cosa, como puedo hacer que se borre de la pantalla el que habia antes? El dibujo del 4 es un poco mas ancho que el resto y me deja una mancha en la pantalla :roll:
Harko.
Pero eso lo haces cada frame? Cargar un archivo de disco cada frame dependiendo del número a mostrar? Es lo que entiendo al menos...
Deberías tener cargados todos los gráficos en un array de 10 elementos con los números del 0 al 9. Después para dibujar uno de ellos, basta con dibujar el que corresponda.
Por ejemplo: Numeros[p1]->Dibujar; (o lo que corresponda, claro).
Para borrar de la pantalla el anterior, seguro que tienes alguna función del estilo fillRect o similar, basta con que borres la parte que necesites.
A ver si te ayuda mientras theAzazel te responde mejor :wink:
Faça o seguinte.
1)Carga todos los sprites en un array.No creo que 10 imagens no caiban em lla RAM.
CRM32Pro_CSprite** arrayPontuacion1;
int i;
arrayPontuacion1 = new CRM32Pro_CSprite*[11];
for(i = 0; i<= 10;i++){
//carga sprites 0-10
char temp[3];
sprintf(temp,"%d",i);
arrayPontuacion1[i] = new CRM32Pro_CSprite();
arrayPontuacion1[i]->Load(GFX_RESOURCE,temp);
}
2)Em la funcion de callback de actualizacion da tela faça esto;
placarADesenhar1 = arrayPontuacion1[p1];
placarADesenhar1->Draw()
Assi no precisas cargar todos los sprites a cada vez que haces una pontuacion .Para borrar a tela basta crear um SDl_surface com als dimensiones de la tela e usar SDL_Bit para desenha-la
PS: No testei esto codigo, mas a ideia es aproximadamente esta.
Estoy achando que es melhor yo hablar portugues... qua acham ?
:?
Harko,
te voy a dar un par de collejas :P
1) me parece que estas borrando, creando y cargando un sprite cada vez que actualizas las puntuaciones..no es asi? en este caso... colleja n1!! jejeje -> Muy lento.
2) como que si quitas el delete parece que si funciona? claro! pero dejas un memory leak de narices jejeje. colleja n2!! jejeje. -> Potenciales problemas dificiles de solucionar.
Te comento, cuando creas un sprite(con new) has creado su "estructura" y el Load() solo funcionara una vez, las siguientes no te dejara puesto que ya has cargado un sprite en ella, por eso si haces otro new te dejara, porque te creara otra "estructura" nueva pero..y la anterior?? es indispensable poner un delete antes, obviamente te va a funcionar pero te iras comiendo la memoria poco a poco. Lo ves verdad?
Y la mejor solucion desde mi punto de vista es...
a) Quiero que mis digitos de puntuaciones esten animados
En este caso como te han dicho(Ager y Saracchini), utiliza un array de sprites y cargalos una sola vez al comenzar el juego y los liberas al finalizar o mejor aun...
mete en un solo sprite cada animacion de cada digito en una fila y luego vas cambiando la animacion con SelectAnim(), pones el autorestore a 1 y ahora solo llamaras al sprite Puntuacion->Draw() y pintara la animacion actual que sera tu digito y el solo se ocupara de restaurar el fondo.
b) Mis digitos de puntuacion son estaticos(no tienen ninguna animacion).
Lo mas facil es crear una fuente y dibujar con esta. Aqui tendras que redibujar tu el fondo cada vez que cambies el digito ya que no soporta autorestore pero es facil, mira el codigo del SpacePong, lo hago asi y cada vez que dibujo las puntuaciones es porque estoy dibujando todo el interfaz y asi regenero todo (con hacer esto unas veces por segundo es suficiente, incluso podrias hacerlo solo cuando algo cambie).
Creo que con esto te habre resuelto un monton de dudas y ya sabes, cualquier otra cosa, aqui estoy :). Si muchas cosas de los sprites estan casi sin documentar...pero estoy en ello, como habras visto en la v4.95 ha mejorado bastante y mas que falta :P
Saludos y dime por que opcion optaras vale?
Vale, ya he conseguido que salga todo y que el codigo quede mas bonito. Ahora solo falta encontrar la forma de borrar el numero anterior antes de poner el que toca.
Hay una funcion en sprite llamada GetSurface, pero no encuntro la manera de vaciarlo, me pide un SDL_Rect que no tengo :P (conozco la X y la Y del sprite pero no su altura y anchura). Tambien podria hacer un sprite en negro del tamaño deseado y colocarlo cada vez, no?
Estoy seguro de que debe de haber otra forma.
Harko.
Crea una SDL_surface con SDL_CreateRGBSurface, e usa SDL_FillRect para preencher com pixels negros. Feito isso usa SDL_BlitSurface para deseña-la.
OBS: No me lembro quais son los parametros destas funciones ahora... tengo que dar una olhada en la documentacion de el SDL.
Cita de: "Saracchini"Crea una SDL_surface con SDL_CreateRGBSurface, e usa SDL_FillRect para preencher com pixels negros. Feito isso usa SDL_BlitSurface para deseña-la.
OBS: No me lembro quais son los parametros destas funciones ahora... tengo que dar una olhada en la documentacion de el SDL.
Saracchini te ha dado una solucion :)
Por cierto, se puede ver algo jugable?? yo quiero verlo!!
Saludos
Siempre me ha parecido que la SDL_CreateSurface era muy rara, con eso de tener que poner las mascaras y todo :P
Vamos a ver, entonces creo una superficie con esa instruccion (no valdria hacerla con GetSurface?) y uso SDL_FillRect, dejando el segundo parametro en NULL y despues empiezan los problemas.
Aunque deje la instruccion como
surface_puntos=punt1[p1]->GetSurface();
// La unica manera de conseguir el ancho del sprite es por la superficie??
surface_extra=SDL_CreateRGBSurface(SDL_SWSURFACE,surface_puntos.w,surface_puntos.h,32,...etc...);
SDL_FillRect(surface_extra,NULL,SDL_MapRGB(surface_extra->format,0,0,0);//corregido
SDL_BlitSurface(surface_extra,NULL,surface_puntos,Null)
Y funcione, aun quedaria el problema de colocar ese bloque negro en la pantalla, no? Puede que con SDL_Flip(surface_puntos); funcione pero no se en que lugar de la pantalla lo colocaria para empezar :?.
No se, voy a probar cosas. Quizas con un FillRect directo a la surface de los puntos......
Harko.
PD: Tranquilo ya falta menos, cuando consiga que funcione esto, la bola deje de meterse por los bordes de las raquetas y salir por el otro lado dejando pegotes por ahi, lo colgare.
Bueno, al final he intentado esto:
void BorraPunt(int n){
SDL_Surface *num;
//num = new SDL_Surface();
if(n==1)
//SDL_FillRect(CRM32Pro.screen,punt1[p1],SDL_MapRGB(CRM32Pro.screen->format,0,0,0));
num = punt1[p1]->GetSurface();
if(n==2)
//SDL_FillRect(CRM32Pro.screen,punt2[p2],SDL_MapRGB(CRM32Pro.screen->format,0,0,0));
num = punt2[p2]->GetSurface();
SDL_FillRect(num,NULL,SDL_MapRGB(num->format,0,0,0));
SDL_BlitSurface(num,NULL,CRM32Pro.screen,NULL);
CRM32Pro.FreeSurface(num);
}
Pero sigue sin funcionar :(. Basicamente crea la superficie de la puntuacion que le digan, luego la rellena de negro e intento pegarla en la superficie screen. Pero no me hace ni caso.
Los FillRect de los ifs son un intento fallido de colar un CSprite como un SDL_Rect, no hagais mucho caso :P.
Harko.
Papito,tienes que usar un SDL_Rect para definir donde el placar ira ser deseñado.
segun la definicion del SDL de SDL_BlitSurface:
Citar
This performs a fast blit from the source surface to the destination surface.
Only the position is used in the dstrect (the width and height are ignored).
If either srcrect or dstrect are NULL, the entire surface (src or dst) is copied.
The final blit rectangle is saved in dstrect after all clipping is performed (srcrect is not modified).
The blit function should not be called on a locked surface.
define la posicion X e Y pela estructura SDL_rect e poñe qualquier valor en width and heigth.
E pudes usar Get_Surface para obter las informacions de la superficie utilzando os atributos de la classe SDL_surface que son:
Citar
flags - Surface flags
format - Pixel format
w, h - Width and height of the surface
pitch - Length of a surface scanline in bytes
pixels - Pointer to the actual pixel data
clip_rect - surface clip rectangle
JAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJA JAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJAJA
¡¡Lo sabia!! ¡¡No podia ser de otra manera!! Por supuesto, se me olvidaban las leyes de Murphy. Si un problema lleva mucho tiempo tocandote las narices la solucion sera la chorrada mas grande que te puedas imaginar. Al menos esta vez no ha sido un punto y coma o un parentesis XD.
Ya he solucionado el problema de los numeros y el que la pelota deje pegotes al rebotar mucho con una única linea de codigo :D
SDL_FillRect(CRM32Pro.screen,NULL,SDL_MapRGB(CRM32Pro.screen->format,0,0,0));
Esto puesto antes de los ->Draw() y todo arreglado, lo dicho una chorrada. Solo hacia falta borrar la pantalla :lol: :P
Bueno, mañana me metere con las colisiones con la barra, creo que no tendre tantos problemas :D
Harko.
PD: Gracias Saracchini, me apuntare eso seguro que me viene bien ;)
bueno...borrar cada frame la pantalla no es muy optimo pero por ahora lo puedes hacer asi, cuando vayas mas avanzando, si quieres nos ponemos y te ayudo a implementar una solucion mas optima vale? Que dicho sea de paso, si el fondo es negro, lo podras solucionar con un SDL_FillRect() pasandole el rect que ocupo tu sprite, las coordenadas x e y serian las del sprite(con GetX() y GetY()) y el tamaño del rect te lo daria GetOffset(int *,int*), asi que ya tienes la forma de hacerlo mucho mas optimo :)
ya sabes, cuelga una demo en cuanto puedas :)
Saludos
El Dev me dice que esa instruccion (GetOffset) existe, pero en la documentacion no aparece (solo aparece un GetOffset(), sin parametros, en CTile). Me puedes decir como funciona?
Harko.
Efectivamente, en la doc no aparece porque no pense que fuera util pero veo que si podria ser, hasta ahora estaba para que el EditorDPF lo utilizara pero vamos, si vas a CRM32Pro.h donde define la clase CSprite veras que estan al final y pone algo asi como "solo para EditorDPF", pues bien, voy a agregarlas a la doc y fuera, por el momento te digo como funciona:
int x,y:
mySprite->GetOffset(&x,&y);
y de ese modo, en x e y tendras el size del sprite :)
Saludos