Muy bien, ya dominamos lo necesario de C/C++, y somos capaces de mostrar sprites y fondos en pantalla. Es hora de darle chicha a nuestros proyectos. Este tutorial trata completamente de las matemáticas básicas para darle vida a los mundos que creemos: desde velocidades distintas a diversos objetos a crear una gravedad para que todo en el aire caiga. Al fin y al cabo, para todo lo que queramos hacer en la DS (y en cualquier plataforma que programemos), tendrá que ser a base de cálculos matemáticos.
Antes de nada, y como tenemos por costumbre, habrá que repasar viejos conceptos y aprender otros nuevos. Éstos son los conceptos que necesariamente tendremos que conocer para seguir este tutorial:
Muy bien, metámonos de lleno en el tutorial al que más intríngulis tiene de todos, y el que más útil os será. Intentaré ir poco a poco, de lo más sencillo a lo más complicado.
Los números aleatorios siempre son bastante necesarios. Pueden tener 12347907982 utilidades, desde tirar un dado a manejar una IA.
Si queremos obtener un número aleatorio, una línea nos lo hace todo:
PA_Rand(); //Con esto, obtenemos un número aleatorio. Para usarlo, almacenadlo en una variable.
Vale, una línea sencilla, pero con pros y contras.
¿Cómo evitar estos contras? La solución es fácil, pero requiere aprender más código.
PA_RandMin(mínimo); //Limita el número obtenido. Con esta función obtendrás un //número mayor o igual que mínimo. PA_RandMax(máximo); //Limita el número obtenido. Con esta función el número estará //entre 0 y el máximo dado. PA_RandMinMax(mínimo,máximo); //Limita totalmente el número. Este estará entre //el mínimo y el máximo dado, ambos incluidos. PA_InitRand(); //Inicia el sistema Random. El número que se obtenga con las funciones //anteriores se basará en la fecha y hora de la DS.
Las tres primeras no creo que haga falta explicarlas, se entienden bien. Sin embargo, en la última, he de indicar varias cosas. La primera y más importante, es que no existe aparato tecnológico capaz de generar un número completamente aleatorio. Únicamente sistemas matemáticos para "simular" que el número obtenido es aleatorio. Para esto, en las ecuaciones se incluyen elementos totalmente variables. ¿Qué elemento más variable existe que la fecha y la hora? Usando estas funciones, el número que obtengamos con cualquiera de las funciones anteriores será siempre totalmente aleatorio. Bueno, para obtener exactamente el mismo número debereis ejecutar el código exactamente el mismo día a la misma hora. Algo no muy probable, ¿no? ;)
Antes de que me vengan dudas, indico que esta función se tiene que almacenar en una variable (cosa lógica porque genera un número). Así:
u32 variable=PA_Rand();
IMPORTANTE: ¡Ojo con los emuladores! Cuando ejecutes un emulador (iDeaS, DeSMuMe...), éste tendrá por defecto la fecha a 1 de enero a las 00:00, por lo que el número aleatorio que devuelva será el mismo si el aleatorio se genera al iniciar el programa. Así que mejor probad en la DS los números aleatorios, porque los emuladores no servirán de mucho...
Para todo aquel adentrado y bien adentrado en este mundillo, sabrá que las variables float y double no son las más digeribles para cálculos en la DS (bueno, para la DS o para cualquier aparato tecnológico). Si no, pues ya lo he dicho yo xD.
¿Qué supone esto? Que si queremos hacer desplazamientos lentos, a menos de 1 píxel/frame, pues a narices que necesitaremos usar decimales, osease floats. Con un sprite/fondo, no hay mucho problema, pero si son muchos será un suplicio para el sistema, si además tiene que estar realizando otros cálculos a la par. Resulta evidente la necesidad de buscar alternativas.
Para este método, tremendísimamente efectivo, nos basaremos en una verdad:
Un número entero será siempre infinitamente más rápido de operar que un decimal
Y aquí entra en juego el punto fijo. Para la explicación, compararemos nuestro sistema matemático humano (la numeración decimal, usando 10 caracteres, de 0 a 9), con el sistema matemático del byte* (del byte, no del bit).
*NOTA: Este término es de mi invención, para que comprendáis el por qué de sus valores.
¿Cuál es el sistema del byte? Pues que el número 1 en el sistema decimal equivale a 256 en el del byte, valor máximo alcanzado por un byte u8.
Dejémonos de tecnicismos, y comencemos con las comparaciones. Centrémonos en esta realidad: 1=256 (explicado en el párrafo anterior). De aquí sacamos que:
1+1=256+256 -> 1*2=2*256 -> 2=512 1+1+1=256+256+256 -> 1*3=3*256 -> 3=768 1+1+1+...=256+256+256+... -> 1*n=n*256
Traduciendo, si queremos un número n, multiplicamos éste por 256. Sencillito, ¿no? Ahora si os digo que, matemáticamente hablando, el comando <<8 equivale a multiplicar por 256, el código se vuelve aún más simple, es cambiar *256 por <<8.
Pero claro, nuestra intención era conseguir números menores de 1 sin usar decimales. Y multiplicando por 256, decimales no conseguimos. Peeeroooo...
1*0.5=0.5*256 -> 0.5=128
Con esto ya tenemos un número menor de 1, ¡y sin decimales!
Pero claro, esto es una "transformación", una conversión. Aquí usamos euros, lo pasamos a dólares, pero a la hora de gastarlo, tendremos que volverlo a pasar a euros. Pero hemos evitado realizar cálculos con el euro, que era lo que nos "ralentizaba".
En resumen:
Para pasar a punto fijo: 256*n=n<<8 Para usar el valor en funciones: n>>8=n/256
Y por último, una comparación de un código con ambos métodos, el decimal y el del byte.
float variable_decimal; //Como siempre, s32 variable_byte; //declaramos variables. variable_decimal+=0.25; variable_byte+=0.25<<8; //NOTA: 0.25<<8=0.25*256=64 PA_SetSpriteAnimX(0,0,variable_decimal); PA_SetSpriteAnimX(0,1,variable_byte>>8); //NOTA: variable_byte>>8=variable_byte/256
Vale, tenemos un control del sprite completo para arriba, abajo, derecha e izquierda, y una mezcla de ambas. Para la mayoría de juegos, es más que suficiente. Pero, en la vida real, no nos movemos sólo en cuatro direcciones, no miramos sólo en cuatro direcciones. Podemos movernos y mirar hacia cualquier dirección, concretamente 360º (vamos a despreciar la tercera dimensión de nuestro mundo, la altura).
Bueno, pues los sprites no van a quedarse cortos. ¿Qué utilidad tiene esto? Pues podéis hacer una ruleta, podéis hacer un shooter (arriba camina, y con izquierda y derecha va girando), podéis hacer una rotonda en un juego de coches... Aunque no lo parezca, los ángulos los necesitaremos en más de una situación. Pero claro, calcular el ángulo no es fácil. ¿Seguro? Aquí entra la magia de la trigonometría.
Bueeno, no voy a dar por supuesto que habéis dado esto en Matemáticas, pero tampoco os voy a explicar toda la trigonometría :P. La teoría que voy a dar sobre esto va a ser muuy básica, lo justo para entender este apartado. No esperéis nada más, pues la trigonometría dara para mucho más.
PD: Es muy recomendable que le echéis un vistazo al ejemplo /palib/examples/Math/AngleSinCos, compilándolo, para que tengais clara la idea del resultado.
Cualquier ángulo de cualquier tamaño puede ser dibujado en una círcunferencia, tal que el centro de ésta sea el vértice de dicho ángulo, y éste forme un triángulo rectángulo. Basándonos en esta definición, observemos el siguiente dibujo:
Antes de nada, y como abréis notado ya, en la DS no se usan grados para medir los ángulos. Se miden en píxels (como casi todo en la DS, vaya), y la equivalencia es la siguiente:
90º=128 píxels
Por tanto, si el lado derecho de la pantalla es el ángulo 0º (o 0 píxels), 90º son 128 píxels, 180º son 256, y 270º son 384. Tened en cuenta que un ángulo de 360º (512 píxels), vendría a ser un ángulo 0.
Aparte de esto, por norma general, el centro de la circunferencia se considerará siempre la posición inicial del sprite.
Teniendo en cuenta estos detalles, pasemos al intríngulis de la cuestión.
Esto es incluso más simple que el punto fijo :P. Pero había que tener claros los conceptos que aclaré en la circunferencia goniométrica.
¿Qué es el Seno y el Coseno? Pues una relación entre dos coordenadas, concretamente, y como ya se dijo, entre la posición inicial del sprite y la final. Imaginemos un ángulo de 45º (64 píxels), que vendría a ser la diagonal. Pues si cogemos esa diagonal, podemos dividirlo en un movimiento horizontal, y otro vertical. Una L, vamos. Pues bien, el Seno y el Coseno vendría a ser la velocidad, tanto X como Y, con la que el sprite se aleja/acerca respecto a su posición inicial. Por tanto, como cualquier velocidad, hay que sumarla a la posición para que el sprite se mueva, sabiendo que:
Y ahora os estaréis diciendo "No me fastidies, ¿tengo que memorizarme el Seno y Coseno de cada grado que quiera usar?" Y yo os respondo: "¡Tranquilos, aquí llega PAlib al rescate!". Con estas dos funciones, ya tenemos la vida resuelta:
PA_Sin(ángulo); //Esta función devuelve el Seno del ángulo que le demos, entre -255 y 255 (un s16) PA_Cos(ángulo); //Esta función devuelve el Coseno del ángulo indicado, un valor entre -255 y 255. (un s16
La cuestión del ángulo, se puede conseguir de mil maneras. Recomiendo usar Pad.Held Left y Right para modificar el ángulo.
Un último detalle: El motivo de que el seno y el coseno sean valores comprendidos entre +/- 256, es por el hecho de que está preparado para usar en punto fijo. No os olvidéis de luego mover el byte a la derecha (>>8), para que el movimiento sea correcto.
Jeje, ahora sí que "sus vía crujir vivos" (Gracias José Mota :) ).
Definimos gravedad como la fuerza con la que un cuerpo con masa atrae y es atraído por otro(s). Coloquialmente hablando, la gravedad es la rapidez con la que caemos al suelo.
De ese concepto va todo este apartado: todo lo que sube, baja. Organicemos nuestras ideas antes de nada.
ATENCIÓN, estamos considerando el caso de que queráis una gravedad similar a la de la Tierra. Estas ideas pueden variar un poco o mucho de las que tengáis en mente para vuestros proyectos (podéis hacer que el sprite caiga leeeentamente, o que haga un supersalto de 5 pisos).
¿Listos? Vamos a adaptar estas ideas a la simulación en la DS.
Como es la idea más usada y extendida, vamos a tratar la gravedad hacia abajo. Considero que tenéis suficiente cabeza para saber qué hay que modificar en el código para que caiga hacia otra dirección.
Vayamos por partes: una aceleración hacia abajo (eje Y, número positivo), modifica una velocidad Y, aumentándola a cada frame. La velocidad de cada frame, modifica la posición Y de un sprite. Cuando un sprite está en una determinada coordenada Y, la velocidad es 0 (nula), lo que vendría a ser el suelo.
¿Lo tenéis claro? Recordad que si no entendéis, siempre podéis indicarlo para que modifique mi explicación ;).
Muy bien, crearemos nuestras variables:
s32 spritey; //Con esta variable controlaremos la posición y del sprite s32 vel_y; //Con esta variable le daremos velocidad y al sprite u16 despegue=1000; //La velocidad inicial del salto (el impulso que cogemos al saltar) u8 gravedad=32; //Esta constante será la que arrastre hacia abajo el sprite. #define FLOOR (190-32)<<8 //Definimos el suelo (el punto y donde el sprite dejaría de caer abajo)
Si os fijasteis, en el anterior código hago uso de un define. Pero, ¿qué es un define? Pues viene a ser una orden dada al compilador, para que nos sustituya una cadena de caracteres por otros caracteres o valores que establezcamos previamente.
Los define por lo general se ponen junto a los include, pero se pueden localizar en cualquier parte del código. Recomiendo ponerlos junto a los include mientras no se dominen.
#define FLOOR 150<<8
Después de esta línea, cada vez que en el código se encuentre la secuencia de caracteres FLOOR, se sustituirá por 150<<8 (está en punto fijo, iros acostumbrando a esto). Imaginemos que, por casualidades del destino, tenemos esto en el código:
(Es una situación ficticia, es para que os hagáis una idea)
if(Pad.Newpress.A) { PA_SetSpriteY(0,0,FLOOR); } AFLOORAMIENTO;
Si se sustituye FLOOR por 150<<8, en realidad tenemos esto:
if(Pad.Newpress.A) { PA_SetSpriteY(0,0,150<<8); } A150<<8AMIENTO;
En el primer caso, usamos correctamente el objetivo del define, que es usar palabras en lugar de números, así no tendremos que memorizar el número al que queremos poner el suelo, y no reservamos espacio para variables.
En el segundo caso, que sería un mal uso, aunque pocas veces os pasará. Si el compilador se encuentra la secuencia de caracteres por algún lado, sustituirá por lo indicado sin excepción. Es por ello que lo recomendable es usar caracteres en mayúsculas, y que estéis seguros de que no sustituirá en lugares no deseados.
Bien, tenemos el concepto de gravedad, y tenemos las variables. Ahora vamos a programar.
/*Aquí comienza todo. Con esta acción, al pulsar A, el sprite saltará, siempre que éste se encuentre en el suelo que definimos antes.*/ if((spritey>=FLOOR) && Pad.Newpress.A) { vel_y=-despegue; //La velocidad comienza. Es negativa, para que el sprite vaya para arriba. } /*Estos cálculos se realizarán siempre. Porque la gravedad nunca deja de actuar, ¿no?*/ vel_y+=gravedad; //La velocidad aumenta con la gravedad. spritey+=vel_y; //La posición del sprite cambia dependiendo de la velocidad. /*Y, por último, mientras el sprite está en el suelo, no se mueve*/ if(spritey>=FLOOR) { vel_y=0; //Velocidad nula, para que el sprite no se mueva. spritey=FLOOR; //La posición y es el suelo, para cuando aterrice el sprite no se nos "entierre" } PA_SetSpriteY(1,0,spritey>>8); //Evidentemente, la posición del sprite debe actualizarse :P.
Y aquí, chicos, llega el quiz de todo este apartado. Habíamos visto unas ideas previas, si mal no recordáis:
"Cuanta más masa tenga el cuerpo atraído, con más fuerza (velocidad) caerá al suelo (lo conocido como peso)."
Por tanto, cuanto más pese el sprite (supuestamente), más le costará despegar del suelo. Por tanto, se le dará un despegue menor. Resultado: el sprite se levanta menos del suelo.
"Todo objeto es atraído en la misma dirección. Por lo general, hacia abajo (podéis hacer que caiga en otras direcciones, como hacia la derecha, por ejemplo)"
Cambiar la dirección del suelo es fácil. Simplemente es cambiar el signo de la gravedad y del despegue para que caiga hacia arriba, cambiar la dirección de Y a X para la derecha, y cambiar la dirección de Y a X y el signo para la izquierda. Todo con el suelo debidamente indicado, claro.
NOTA FINAL: Tanto el despegue como la gravedad son valores orientativos, yo les pongo 1000 y 32 porque son los valores más cómodos para mí. Os recomiendo que vayais al ejemplo de gravedad de PAlib (/devkitpro/palib/examples/Math/Gravity), compileis el ejemplo, abrais el .nds y juguéis con las variables despegue y gravedad hasta dar con los números que más os atraigan.
Y con este último apartado aprenderemos a interactuar entre sprites. Venga, no neguéis que estábais deseando llegar a esta parte xD.
Por existir, existen diversos métodos de detectar colisiones. Por el momento, aprenderemos dos clases: colisión circular y colisión por cajas.
El porqué de este nombre viene del hecho de considerar los sprites como circunferencias. Técnicamente este tipo de colisión se puede usar para colisiones entre dos sprites cuadrados (8x8, 16x16, 32x32 y 64x64), aunque yo lo recomiendo sólo para sprites de pelotas, balones, etc., más que nada porque con otros tipos no les suele quedar muy bien el efecto.
El sistema es simple: para que dos circunferencias choquen, los centros tienen que estar a menos distancia que la suma de sus radios. Para ello, lo recomendable es tener una variable que indique el centro del sprite (sería la posición del sprite + la mitad de su tamaño).
Muy bien, pasemos al código:
if(((centrox1-centrox2)<(radio1+radio2) //Si la diferencia de posiciones X es menor a la suma de radios (por la derecha), || (centrox1-centrox2)>(radio1+radio2)) //O menor por la izquierda && ((centroy1-centroy2)<(radio1+radio2) //Y la diferencia de posiciones Y es menor a la suma de radios (por arriba) || (centroy1-centroy2)>(radio1+radio2))) //O menor por abajo //Hay colisión else //No hay
Este código es simple, y creo que se entiende. Los valores de los radios y centros varían dependiendo del tamaño del sprite, pero por las dudas os las indico aquí:
//Sprite 8x8 centrox=posicionx+3; centroy=posiciony+3; radio=8; //Sprite 16x16 centrox=posicionx+7; centroy=posiciony+7; radio=8; //Sprite 32x32 centrox=posicionx+15; centroy=posiciony+15; radio=16; //Sprite 64x64 centrox=posicionx+31; centroy=posiciony+31; radio=32;
NOTA: Este método detecta la colisión. La consecuencia de ésta la tendréis que programar vosotros.
Este ya es el método general. Como el propio nombre indica, para este tipo de colisión consideraremos los sprites como cajas.
Bueno, este método quizá no sea exacto de narices, pero oye, nos hace un apaño bastante bueno. Y reconocedlo, estabais deseando que tocase explicar esto, pillines xD.
Si entendisteis las colisiones circulares, esto no tiene ningún secreto para vosotros, pues viene a ser lo mismo con la diferencia de que la distancia del centro del sprite al borde no es la misma en todas las direcciones. Y esto nos hace usar una táctica "adaptada".
El sistema es simple, simplemente teneis que conocer la posición de los 4 lados del sprite.
lateralizq=posicionx; //El lado izquierdo es la posición X 0 del sprite. Por tanto, es equivalente a la posición X de este. lateralder=posicionx+ancho; //El lado derecho es la posición X del sprite más su ancho. lateralarr=posiciony; //El lado de arriba es la posición Y 0 del sprite. Por tanto, es equivalente a la posición Y de este. lateralaba=posiciony+alto; //El lado de abajo es la posición Y del sprite más su alto.
Bien, pasemos al código:
//Código cedido por Cheleon if(((lateralizq1<=lateralder2 && lateralizq1>=lateralizq2) //Si el lateral izquierdo del sprite 1 está entre //el lateral derecho y el izquierdo de 2 || (lateralizq1<=lateralder2 && lateralder1>=lateralizq2)) //O el lateral derecho del sprite 1 está entre //el lateral derecho y el izquierdo de 2 && ((lateralarr1<=lateralaba2 && lateralarr1>=lateralarr2) //Y el lateral de arriba del sprite 1 está entre //el lateral de arriba y el de abajo de 2 || (lateralaba1<=lateralaba2 && lateralaba1>=lateralarr2))) //O el lateral de abajo del sprite 1 está entre //el lateral de arriba y el de abajo de 2 //¡Colisión!
Si sustituímos en la imaginación las variables lateral por los sprites y sus lados, y los chocamos entre ellos, veremos el porqué de todo este rollo (que lo cierto un poquito lo es, pero también es fácil de razonar).
En todo caso, nos puede surgir una duda: ¿Por qué el mismo código para los 4 lados? ¿No bastaría con dar, por ejemplo, arriba y derecha? Error.
La razón es simple, por muy lógico que pueda parecer el "ahorrarnos" calcular dos lados. Imaginad dos cuadrados, uno se acerca a la izquierda del otro. Si no tenemos calculada la colisión para el lado izquierdo, cuando este lado toque el sprite no pasaría nada. Los cuadrados se van solapando, hasta que al final, el lado derecho también toca el otro cuadrado. Y entonces se detecta colisión. ¡Pero realmente no era colisión, realmente los cuadrados ya estaban solapados!
Y con esto doy por finiquitada la serie de tutoriales de PAlib básico. Esto es lo mínimo que hay que saber para adentrarnos en el mundo de la programación gracias a la ayuda que nos brinda PAlib. Ahora la recopilación seguirá otros derroteros: sabeis lo suficiente para intentar ir un poco más allá. A partir de hoy, dad por inaugurada la serie de tutoriales de PAlib medio.
Un Saludo seguidores de mis tutoriales.
Comentarios
Gracias
Fantasticos tutoriales. Con lo que has expliado me voy a poner a trabajr en un juego. Saludos !!!
Fe de erratas
He cambiado el código de colisión del tutorial por el aportado de Cheleon, confiamos en que este código sea el definitivo para el tutorial. No obstante recordad que las colisiones son un mundo y el código indicado no deja de ser orientativo.
Salu2
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.
La colision por cajas esta
La colision por cajas esta mal
tu tienes esto
y es esto
EDITO: Código cedido por cheleon :P ><
cuando van a empezar los
cuando van a empezar los tutoriales de palib medio?
Mi sprite no "salta"
pues eso que e colocado todos los códigos, todas las variables bien, y sin embargo mi sprite no se eleva. alguien me puede ayudar?
gracias
¿Podrías poner el código? PD:
¿Podrías poner el código?
PD: Tenemos un foro de programación donde puedes preguntar también estas dudas.
Salu2TS!
Este es el código
// Includes
#include <PA9.h> // Include for PA_Lib
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
#define FLOOR (190-32)<<8
s32 x;
s32 spritey;
s32 vel_y;
u16 despegue=1000;
u8 gravedad=32;
// Function: main()
int main(void)
{
PA_Init(); // Initializes PA_Lib
PA_InitVBL(); // Initializes a standard VBL
PA_LoadSpritePal(0,1,(void*)ash_Pal);
PA_CreateSprite(0,1,(void*)sprite2_Sprite, OBJ_SIZE_64X64,1,1,10,100);
PA_SetSpriteHflip(0,1,1);
// Infinite loop to keep the program running
while (1)
{
if((spritey>=FLOOR) && Pad.Newpress.A)
{
vel_y=-despegue;
}
if(spritey>=FLOOR)
{
vel_y=0;
spritey=FLOOR;
}
if(Pad.Newpress.Left)
{
PA_SetSpriteHflip(0,1,0);
PA_StartSpriteAnim(0,1,1,6,6);
}
if(Pad.Released.Left)
{
PA_StopSpriteAnim(0,1);
PA_SetSpriteAnim(0,1,0);
}
if(Pad.Newpress.Right)
{
PA_SetSpriteHflip(0,1,1);
PA_StartSpriteAnim(0,1,1,6,6);
}
if(Pad.Released.Right)
{
PA_StopSpriteAnim(0,1);
PA_SetSpriteAnim(0,1,0);
}
x+=Pad.Held.Right-Pad.Held.Left;
PA_SetSpriteX(0,1,x);
vel_y+=gravedad;
spritey+=vel_y;
PA_SetSpriteY(1,0,spritey>>8);
PA_WaitForVBL();
}
return 0;
} // End of main()
Coloca
las líneas
entre el despegue y la detección del suelo. Así:
¿Por qué esto debe ser así? Pues por el sencillo motivo, de que no va a saltar nunca. Cuando pulsas A, y el sprite está en FLOOR o por debajo, vel_y adquiere un valor. Si se sigue tu código, la NDS interpreta lo siguiente: el if(sprite_y>=FLOOR). En ese momento, recuerda, sprite_y sigue valiendo más o igual a FLOOR. Se cumple la sentencia, por tanto, entra al bucle. Y ahí la hemos liado, porque en ese bucle nos encontramos con la línea vel_y=0. Conclusión, el sprite no se mueve.
Ahora veamos el código puesto por mí. Cambiamos de sitio las líneas indicadas al principio del comentario. Se pulsa A, sprite_y es igual a FLOOR (cosa que nos garantiza if(sprite_y>=FLOOR) sprite_y=FLOOR;), y vel_y=-despegue. Después, entramos en las siguientes líneas: a vel_y se le resta la gravedad, y luego, se suma al sprite_y. Como es un número negativo, sprite_y decrece, y, por tanto, ya no es igual a FLOOR. Por tanto, no se entra en el bucle if(sprite_y>=FLOOR) hasta que se cumpla, y esta situación no se dará hasta la caída del salto.
Ten bastante cuidado con la sintaxis que empleas en tus códigos; como puedes ver, cambiar de sitio un par de operaciones la cosa cambia.
Salu2
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.
Corregido
el código de colisiones por cajas, debido a un despiste mío con un conector && no funcionaba. Gracias a Draco el dragon por indicarme el fallo y ayudarme a corregirlo.
Salu2
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.
Cual es el código de si yo
Cual es el código de si yo toco un sprite con el stylus sucede una condicion. Por ejemplo:
While(1)
{
if(código de si el sprite es tocado)
{
PA_InitText(1,2);
PA_OutputSimpleText(1,5,5,"sprite tocado");
}
PA_WaitForVBL();
}
A que os mola la firma!!!
Una cosa
El PA_InitText procura dejarlo siempre fuera del while, la accion que necesitas es PA_SpriteTouched(numero_Sprite), en if quedaria:
if(PA_SpriteTouched(numero sprite)){
Salu2
Pongo: if(PA_SpriteTouched(0_
Pongo:
if(PA_SpriteTouched(0_sprite))
{
PA_InitText(1,2);
PA_InitText(0,2);
PA_OutputSimpleText(1,15,5,"sprite tocado");
PA_OutputSimpleText(0,3,20,"B para volver");
}
Y me da este error:
error: invalid suffix "_sprite" on integer constant
A que os mola la firma!!!
Borra
el "_sprite" que sobra. El número que hay que poner es el que le asignas tú al sprite al crearlo: PA_CreateSprite(pantalla,nºsprite,(void*)nombresprite_Sprite,OBJ_SIZE_tamXxtamY,nºcolor,nºpaleta,posiciónx,posicióny);
Salu2
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.
Desde aquí
pido disculpas a todos los users por la tardanza al realizar este tutorial (una friolera de 3 meses), espero que sea de vuestro agrado, y dad por hecho que habrá más y mejor.
Salu2
Para recibir ayuda por parte de otros usuarios más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda que accediendo al Manual del perfecto forero y las Normas de la Comunidad aprenderás trucos para resolver tus dudas antes.
Muchas gracias por este gran tuto
Disculpas??
Si, encima de que los haces, te van a exigir cuando hacerlos.
Muy buen tuto, muchas gracias por hacerlo :)
Seguro que me sirve en poco tiempo :) :)
¿Quieres estar totalmente informado sobre el universo 3DS? Visita Magic3DS.
También puedes estar al tanto de toda la actualidad de 3DS en Twitter: @Magic3DS
Jaja no importa se perdona
Jaja no importa se perdona después de ver el trabajo que has echo Enorawena. Esto va a servir a más de uno #include <YO> Salu2TS y gran trabajo.