La ilusión del movimiento
Para dibujar el rectángulo en otro lugar de la pantalla o cambiar su posición simplemente se modifica sus coordenadas (x, y). Para crear la ilusión del movimiento del rectángulo en la pantalla, se borra el rectángulo anterior y luego se dibuja uno en la nueva posición bastante cerca. La estrategia en SFML es dibujar-borrar-dibujar y se repite indeterminadamente hasta conseguir cierta condición controlada por una sentencia while (mientra que). Ésta sentencia, ejecuta una sección de código mientras la condición dada sea verdadera, de lo contrario sale del bucle y continua con el código siguiente después del bloque while es decir después de la llave '}' . Una condición while tiene la siguiente estructura
while
(condición)
sentencias
En los programas SFML de los ejemplos realizados en las entradas anteriores hay una sentencia de control principal while en cuyo cuerpo (cuerpo del while) se escriben todas las sentencias para dibujar. Dichas sentencias se ejecutan hasta que la condición dentro de los paréntesis sea falsa; es decir que hasta que la ventana es cerrada. Dicho bucle es el que vamos a utilizar para colocar todas nuestras sentencias, que en este caso van a realizar una animación de una figura como un circulo que emula una pelota o balón rebotando en la pantalla.
while (ventana.isOpen())
{
1 Aquí escuchamos los eventos para captar cuando el usuario cierre la ventana
2 Limpiamos la pantalla
3 Cambiar los valores de las coordenadas
x,y
4 Pasamos las nuevas coordenadas
x,y al objeto circulo
5 Dibujamos en la ventana el circulo en la coordenada que recibió en la sentencia anterior
6 Mostramos la ventana en la pantalla del computador
}
Análisis y detalles del movimiento.
Básicamente las sentencias anteriores son las que necesitamos para crear una animación de una figura simple en 2D. Pero antes de empezar a escribir el código vamos a analizar los detalles del movimiento de la figura en la pantalla.
Movimiento en linea recta y el rebote en los bordes de la ventana
Primero, vamos a crear una pantalla con un tamaño de 800 x 600 píxeles (ver figura 3). Ejemplo, si queremos desplazar la figura desde la coordenada 0,0 hasta la coordenada 300,300 debemos incrementar equitativa y progresivamente los valores de x, y. Ahora, si seguimos incrementando los valores de x y y hasta que el valor de x >= 800 o y >= 600 la pelota simplemente desaparece de la pantalla.
Incrementando de uno en uno a las coordenadas x y y es decir x = x + 1, y = y + 1 tenemos:
x = 0,1,2,3,4,...,600,601,602,...799,800....
y = 0,1,2,3,4,...,
600,601,602,...799,800...
La figura desaparece de la ventana cuando
y >= 600
Como vemos, el incremento tanto para
x como para
y es
de
1. Si inicialmente la figura está en la coordenada (0,0) y el incremento de
x y
y al mismo tiempo es de
+1 (pixel).
El desplazamiento de la figura es en linea recta diagonal hacia abajo. Cuando
y es igual o mayor a 600 la figura empieza a estar fuera del rango de la ventana creada con un tamaño de 800x600 píxeles y empieza a desaparecer.
Para evitar que la figura se dibuje fuera de los limites del tamaño de la ventana, establecemos limites a su trayectoria y la encerramos en 4 paredes o bordes de la ventana establecida. Para ello usamos las sentencias de control que ofrece el lenguaje con las condiciones necesarias para cada limite:
izquierdo <=0.
derecho>=800.
arriba<=0.
abajo>=600.
Al cumplirse algunas de estas condiciones simplemente invertimos la dirección del objeto en movimiento, cambiando el signo del incremento de la variable correspondiente
x o
y, es decir, de
+1 a
-1 o de -
1 a
+1.
En C++ y en otros lenguajes de programación existen las sentencias de control como "if", que estable una condición, que de ser cierta, ejecuta las instrucciones dentro del cuerpo de la condición, ejemplo:
if (x <= pared_izq)
xincremento = abs(xincremento);
if (x >= pared_der)
xincremento =-xincremento;
if (y <= techo)
yincremento = abs(yincremento);
if (y >= piso)
yincremento =-yincremento;
El bloque de condiciones anteriores garantiza que la figura (pelota) se mantenga rebotando dentro de los limites establecido por los valores de las paredes, techo y piso.
Ahora hay dos detalles adicionales: primero, para convertir un numero positivo en negativo colocamos el signo menos (-) al lado del numero o variable (-xincremento) y en segundo lugar para convertir un numero negativo en positivo usamos la función de valor absoluto abs(valor).
La trayectoria de la figura en una
ventana de lados diferentes debe verse como la figura 3.
Figura 3
Si la
ventana es de lados iguales la trayectoria de la figura será la misma ida vuelta como muestra la
figura 4, ya que el limite de
x y
y son iguales si parte 0,0 y con incremento iguales para ambas variables.
Para que la trayectoria cambie, sólo basta con darle valores diferentes a los incrementos de las variables
x, y. También a medida que aumente el valor de incremento también aumenta la velocidad del movimiento de la figura.
Figura 4
Velocidad de los fotogramas
Hay un detalle técnico importante que hay que tomar en cuenta y es el control de la velocidad de los fotogramas, debido a que el ciclo de borrado y dibujo es tan rápido que probablemente no veamos nada en la pantalla. Para ello sincronizamos la frecuencia vertical del monitor que es aproximadamente 60 fotogramas por segundo.
¿Como hacemos eso?, simplemente usamos las sentencias que proporciona SFML para tal fin y la escribimos justo después de crear la ventana:
ventana.setVerticalSyncEnabled(true);
otras veces necesitamos que se ejecute a velocidades diferentes y podemos usar la siguiente sentencia:
ventana.setFramerateLimit(30);
Si esta información te fue útil dale un plus +1, sigue este blog y así estas ayudando a que otros consigan la información compártela...
Ahora el código fuente completo
El código fuente (Versión 1.0 )
#include <SFML/Graphics.hpp>
i
nt main()
{
// creamos la ventana de 800x600 pixeles
sf::RenderWindow ventana(sf::VideoMode(800, 600), "Ventana de Dibujo");
// Definimos las variables
int x = 1, y = 1;// coordenadas
int incremento_x = 5, incremento_y = 5;
int limite_izquierdo = 0, limite_derecho = 800;
int limite_superior = 0, limite_inferior = 600;
//creamos un objeto circulo con un radio 10
// y definimos su color verde
sf::CircleShape circulo1(10);
circulo1.setFillColor(sf::Color::Green);
// ejecutar el programa mientras la ventana esté abierta
while (ventana.isOpen())
{
//verificamos todos los eventos de la ventana
sf::Event evento;
while (ventana.pollEvent(evento))
{
// "cierre solicitado" evento: cerramos la ventana
if (evento.type == sf::Event::Closed)
ventana.close();
}
// limpiamos la ventana con el color negro
ventana.clear(sf::Color::Black);
// verificamos los bordes de la ventana y cambiamos
// el signo de los incrementos
if (x <= limite_izquierdo)
incremento_x = abs(incremento_x);
if (x >= limite_derecho)
incremento_x =-incremento_x;
if (y <= limite_superior)
incremento_y = abs(incremento_y);
if (y >= limite_inferior)
incremento_y =- incremento_y;
x = x + incremento_x;
y = y + incremento_y;
//pasamos las coordenadas actuales (x,y) al objeto circulo1
circulo1.setPosition(x,y);
// dibujamos el circulo en la ventana
ventana.draw(circulo1);
// mostramos ventana en la pantalla
ventana.display();
}
return 0;
}
Hace tiempo que buscaba este ejemplo. Gracias por compartir
ResponderEliminarMuchas gracias, excelente aporte, un abrazo
ResponderEliminarFunciona para turbp c++?
ResponderEliminarSi te refieres a SFML, lo he podido probar en :
Eliminarcodeblocks:
https://intelligenciavirtual.blogspot.com/2014/09/instalar-codeblocks-en-windows.html
Visual Studio:
https://intelligenciavirtual.blogspot.com/2018/11/como-instalar-sfmf-25-en-visual-studio.html
Linux:
https://intelligenciavirtual.blogspot.com/2016/06/instalar-sfml-en-linux-debian.html