Anuncios Google

Tutorial: ¡desplazamientos de imágenes/texto en diagonal!

Ayer estaba en la cama, sin nada de sueño y con la PSP en la mano, y se me ocurrió ponerme a investigar algo que llevaba queriendo hacer desde hace mucho tiempo: desplazamientos x,y en diagonal. Si bien es cierto que si aumentamos una cantidad de x y otra en y sale un desplazamiento así, pero no está controlado. También es cierto que con la trigonometría se consigue (ya me enseñaron algo coders como xerpi o deviante, pero no llegué a entenderlo), prefiero hacerlo de un modo menos "avanzado", ya que no he dado trigonometría en mi vida jejeje

Por ello, anoche me puse a despejar formulas con datos de ejemplo y llegué a la siguiente consideración:

"Voy a dar un ejemplo de x1, y1 y sus correspondientes puntos a donde queremos llevarlos: x2, y2 a una velocidad determinada para x, pero no para y. Y en realidad, ¡con saber la velocidad que deben llevar para que coincidan en un punto en un momento determinado ya está hecho!"

Y me puse a ello:

// Tenemos un punto x1 y otro y1 de una imagen/texto:
 
x1 = 1 // Le doy el valor 1 como ejemplo, puede ser cualquiera.
y1 = 1 // Lo mismo digo ;D
velx = 7 // Esta es la velocidad que llevará a nuestra x1 a convertirse en las dos variables de destino siguientes:
 
x2 = 30
y2 = 60
vely = ??? // Esto es exactamente lo que quiero averiguar… ¡veamos como!

Ese es el razonamiento, dos puntos x1,y1 a los que al aumentar cierta cantidad a uno y otro, llegarán a cruzarse al mismo tiempo en los puntos x2,y2 que queramos. Si os parece dificil no os preocupeis, ahora os esclareceré todo ;D

Sigamos:

// Tenemos que 7 multiplicado x veces y sumado a la 1 nos da 30. Esto en forma de ecuación sería:
 
7v+1=30 // "v" es veces que se debe multiplicar la velocidad y sumarla al origen para obtener el punto final.
 
// Despejamos y tenemos:
 
v=(30-1)/7
 
// Es decir:
 
v=(x2-x1)/velx

Eso es para la v, y una vez hallado seguimos:

// Llamemos vely a la velocidad INCOGNITA (que no conocemos) y hagamos lo mismo que antes ;D
 
vely*v+1 = 60
 
// Descompongamos con el valor completo de "v" y despejemos la única incógnita que tenemos: vely
 
vely=60-1/(30-1/7)
 
// ¡Ya lo tenemos!

¡Ya la tenemos! Y ahora, vamos a construir una formula válida para tooooodos los casos ;D

// Unimos todos los datos y los metemos en variables y tenemos que…
 
vely=y2-y1/(x2-x1/velx)

Esta es la formula válida.

¿Y como lo aplicamos en el código? Pues así ;D

imagen = image.load("RUTA");
imagenx = 20;
imageny = 30;
 
function crearVelocidady(x1,x2,y1,y2,velx)
    vely = y2-y1/(x2-x1/velx)
    return vely
end
 
vely = crearVelocidady(1,30,1,60,7); -- Esto almacena la velocidad correspondiente en la variable que queramos, yo en este caso para no variar he puesto vely.
 
function mover(x1,x2,y1,y2,velx) -- No suelo programar en español, pero es para que se entienda sin problemas :D
    if x1 > x2 then mayorx = true
    elseif x1 < x2 then mayorx = false end
    if y1 > y2 then mayory = true
    elseif y1 < y2 then mayory = false end -- Esto comprueba si el numero es mayor o menor para hacer el tope de más adelante ;D
 
    x1 = x1+velx;
    y1 = y1+vely;
 
    if x1 >= x2 and mayorx == false then x1 = x2 end
    if x1 <= x2 and mayorx then x1 = x2 end
    if y1 >= y2 and mayory == false then y1 = y2 end
    if y1 <= y2 and mayory then y1 = y2 end
end

Ahí he creado la imagen, le he asignado x e y y además he creado una función que devuelve la velocidad necesaria de y y la propia función que desplaza la imagen.

Nota: la primera función debe realizarse fuera del bucle y la segunda dentro del bucle.

Y para terminar, hacemos nuestro while :D

while true do
     imagen:blit(imagenx,imageny);
     mover(imagenx,30,imageny,60,7);
screen.flip();
end

Y eso provocaría que al lanzar el programa se desplace solo. Pero... ¿y si quisieramos moverla solo cuando pulsemos cuadrado?

Entonces, se tendría que usar un estado:

estadoImagen = 0; -- 0 es normal y 1 es moverse.
 
while true do
controls.read(); -- Añadimos la lectura de controles...
imagen:blit(imagenx,imageny);
     if estadoImagen == 1 then -- Si el estado es igual a 1 entonces...
          mover(imagenx,30,imageny,60,7); -- Llamar a la función mover :D
     end
 
     if controls.press("square") then -- Y si se pulsa cuadrado entonces...
          estadoImagen = 1; -- ¡El estado es 1 y se mueve!
     end
screen.flip();
end

Eso provocará que al pulsarse cuadrado se mueva.

Nota: los estados deben "ifearse" dentro del bucle while, porque si se "ifean" fuera lo que provocará es que si se pulsa cuadrado no pasará absolutamente nada, ya que la comprobación de dicho botón no es periodica (en un bucle), sino en un momento determinado, aparte...

Gracias a barney77 por informarme de este error, ya que creía mal con respecto a lo segundo...

Nota 2: para hacer lo mismo con los textos, solo haz lo mismo pero en vez de imprimir la imagen, imprimes el texto con las coordenas y listo ;D

Os dejo el code de pulsar cuadrado completo ;D

imagen = image.load("RUTA");
imagenx = 20;
imageny = 30;
 
function crearVelocidady(x1,x2,y1,y2,velx)
    vely = y2-y1/(x2-x1/velx)
    return vely
end
 
vely = crearVelocidady(1,30,1,60,7); -- Esto almacena la velocidad correspondiente en la variable que queramos, yo en este caso para no variar he puesto vely.
 
function mover(x1,x2,y1,y2,velx) -- No suelo programar en español, pero es para que se entienda sin problemas :D
    if x1 > x2 then mayorx = true
    elseif x1 < x2 then mayorx = false end
    if y1 > y2 then mayory = true
    elseif y1 < y2 then mayory = false end -- Esto comprueba si el numero es mayor o menor para hacer el tope de más adelante ;D
 
    x1 = x1+velx;
    y1 = y1+vely;
 
    if x1 >= x2 and mayorx == false then x1 = x2 end
    if x1 <= x2 and mayorx then x1 = x2 end
    if y1 >= y2 and mayory == false then y1 = y2 end
    if y1 <= y2 and mayory then y1 = y2 end
end
 
estadoImagen = 0; -- 0 es normal y 1 es moverse.
 
while true do
controls.read(); -- Añadimos la lectura de controles...
imagen:blit(imagenx,imageny);
     if estadoImagen == 1 then -- Si el estado es igual a 1 entonces...
          mover(imagenx,30,imageny,60,7); -- Llamar a la función mover :D
     end
 
     if controls.press("square") then -- Y si se pulsa cuadrado entonces...
          estadoImagen = 1; -- ¡El estado es 1 y se mueve!
     end
screen.flip();
end

Espero que os sirva este tutorial para añadirle un poco más de "belleza en efectos" a vuestras aplicaciones y juegos.

Añado a parte mi foto nocturna para que veais que es verdad que se me ocurrió en la cama xD

*Que friki soy xD

Un saludo.


 

 


Anuncios Google

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de barney77

Buen tutorial, ya hacía falta

Buen tutorial, ya hacía falta algo de esto, sín duda nos muestra una vez más que la programación y las matematicas van de la mano.

Solo que tengo una duda, tú mencionas:

"Nota: los estados deben "ifearse" dentro
del bucle while, porque si se "ifean" fuera lo que provocará es que si
se pulsa cuadrado solo se moverá un poquito, y si se pulsa otro
poquito...".

¿Has comprobado si esto es cierto?, porque, pasa por mi mente, que al poner las condiciones fuera del bucle, el programa no funcionaría correctamente, es decir al presionar cuadro no pasaría nada, ya que, no hay una condición que se repita a cada pasada y compruebe si se ha presionado cuadro o no. ¿Estoy en lo cierto o no?.

Un saludo, buen tutorial dovemac.

Completamente cierto.

Tienes la razón, me estaba confundiendo con otra cosa que es sumarle al pulsar...

Gracias por el aviso, ahora lo cambio ;D

Imagen de Dioni0396

+1

Eso es cierto.

Imagen de m.rr

Gran tuyo, la verdad lo

Gran tuyo, la verdad lo andaba buscando desde hace mucho. Gracias!

De nada :D

De nada :D

Me alegro de ser útil.

Viendo este pedazo de

Viendo este pedazo de tutorial (la verdad el método este está muy logrado) me han entrado ganas de hacer un tutorial que haga lo mismo pero con trigonometría, ¿que me dices?

¡Claro! ;D

Eres libre de hacerlo, de todos modos, es solo una formula, no es ninguna librería ni nada con derechos, así que hazlo si quieres :D

Por cierto, gracias por valorar positivamente mi trabajo. Hacía ya tiempo que nadie me agradecía algún trabajo :D

Un saludo, xerpi.


 

 

Imagen de Chimecho

Um...

Por cierto, hace poco ya había puesto eso aquí. Lo único sería quitar la variable angulo (que ni la usé xD) y reemplazar la parte de trigonometría (seno y coseno) por dos puntos fijos, y ya...

Saludos!



PSP FAT [5.00 M33-6] [6.60 ME] [Hard Moded] / Nintendo Wii [4.1U] [cIOS Hermes] [D2X cIOS] / iPhone 3G [4.2.1] [BB 05.13.04] [redsn0w] / iPod Touch 4 [6.1] [evasi0n]

07/05/10: Tuve el placer de llamarle con todo derecho "N00B" a molotovi xDDD

Recuerda: Sé el intérprete -_-

Pueeees...

También es verdad, y es lo mismo sólo que más resumido. Pero una pregunta: ¿ese desplazamiento no iría cada vez más lento con respecto va llegando a su punto final? Es que tu me enseñaste uno también que era:

x1 = x1+(x2-x1)/10;
y1 = y1+(y2-y1)/10;

Un saludo ;D


 

 

Imagen de Chimecho

Nop

Como verás en el otro comentario, el cálculo de los aumentos va fuera del bucle, lo que los convierte en constantes.

En el código que pusiste ahorita, sí que va a ir disminuyendo.



PSP FAT [5.00 M33-6] [6.60 ME] [Hard Moded] / Nintendo Wii [4.1U] [cIOS Hermes] [D2X cIOS] / iPhone 3G [4.2.1] [BB 05.13.04] [redsn0w] / iPod Touch 4 [6.1] [evasi0n]

07/05/10: Tuve el placer de llamarle con todo derecho "N00B" a molotovi xDDD

Recuerda: Sé el intérprete -_-

Ahhh...

Entiendo... es como la función de calcular la velocidad... ok entiendo ;D

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.