Programando con Love 2D – Física de bola que rebota contra suelo

Con el framework Love2D podemos crear nuestra propia física para los objetos o tirar de las funciones que ya trae el framework para generar mundos en los que tenemos gravedad y los objetos ciertas propiedades.

Lo mejor antes de nada es ver un ejemplo no sin antes decir que para saber como compilar love 0.10.2 puedes mirar este articulo y si deseas ver otros ejemplos de como hacer cosas mirar estos otros.

Veamos un ejemplo en un gif animado (que no muestra realmente como se mueve pero si un poco y al que le he quitado el fondo azul para que ocupe menos) y luego el código:

function love.load()
	love.graphics.setBackgroundColor(104, 136, 248) --set the background color to blue
        love.window.setFullscreen(true, "desktop") -- set the window to fullscreen

        screen = {}
        screen.w, screen.h = love.graphics.getDimensions()
        screen.wc = screen.w / 2 -- x center screen
        screen.hc = screen.h / 2 -- y center screen

	gravity_x = 0	
	gravity_y = 9.81
	size_meter = 64

	love.physics.setMeter(size_meter)
	world = love.physics.newWorld(gravity_x, gravity_y*size_meter, true)
 
	objeto = {}

	objeto.bola = {}
	objeto.bola.body = love.physics.newBody(world, screen.wc, screen.hc, "dynamic")
	objeto.bola.radio = 30
	objeto.bola.shape = love.physics.newCircleShape(objeto.bola.radio)
	objeto.bola.fixture = love.physics.newFixture(objeto.bola.body, objeto.bola.shape, 1)
	objeto.bola.fixture:setRestitution(0.9)

	objeto.suelo = {}
	objeto.suelo.alto = 50
	objeto.suelo.ancho = screen.w
	objeto.suelo.body = love.physics.newBody(world, screen.wc, screen.h-(objeto.suelo.alto/2))
	objeto.suelo.shape = love.physics.newRectangleShape(screen.w, objeto.suelo.alto)
	objeto.suelo.fixture = love.physics.newFixture(objeto.suelo.body, objeto.suelo.shape);
  
end
 
 
function love.update(dt)
	world:update(dt) --this puts the world into motion
end
 
function love.draw()

	love.graphics.setColor(255, 0, 0)
	love.graphics.circle("fill", objeto.bola.body:getX(), objeto.bola.body:getY(), objeto.bola.shape:getRadius())

	love.graphics.setColor(0, 255, 0)
	love.graphics.polygon("fill", objeto.suelo.body:getWorldPoints(objeto.suelo.shape:getPoints()))

end

Vamos por partes.

	love.graphics.setBackgroundColor(104, 136, 248) --set the background color to blue
        love.window.setFullscreen(true, "desktop") -- set the window to fullscreen

Colocamos el fondo a color azul (en el gif he comentado esa línea para que ocupase menos y por eso se ve negro).
Colocamos la ventana en pantalla completa y como no sabemos que pantalla tendrá otra persona necesitamos conocer esa información.

        screen = {}
        screen.w, screen.h = love.graphics.getDimensions()
        screen.wc = screen.w / 2 -- x center screen
        screen.hc = screen.h / 2 -- y center screen

Información que pasamos a una tabla que nos servirá para realizar de paso unos sencillos cálculos que necesitaremos. Conseguimos el ancho y alto de la pantalla y lo almacenamos a screen.w (el ancho) y screen.h (el alto).
Luego sacamos el punto medio del ancho y el alto para saber el centro de la pantalla. Eso lo almacenamos en screen.wc y en screen.hc

Como vamos a necesitar una serie de valores para la física del mundo que vamos a crear es bueno dejarla fijada en una variable por si deseamos durante el juego luego alterar esos valores.

	gravity_x = 0	
	gravity_y = 9.81
	size_meter = 64

Podríamos tener gravedad en el eje x y en el eje y. Yo he puesto esos valores a 0 para gravity_x y a 9.81 para gravity_y que será el valor que atraerá hacia abajo los objetos en caso de ser positivo. Si el valor fuese -9.81 la bola subiría hacia arriba.
size_meter será el valor en pixeles que tendrá un metro. 64px en este caso.

	love.physics.setMeter(size_meter)
	world = love.physics.newWorld(gravity_x, gravity_y*size_meter, true)

Con love.physics.setMeter(size_meter) estamos indicando el valor de 64px para un metro.
La otra línea será para crear el mundo en el que la gravedad será solamente en el eje y ya que gravity_x es 0.

¿Hasta aquí todo bien?, ¿Todo correcto? y yo que me alegro.

        objeto = {}

	objeto.bola = {}
	objeto.bola.body = love.physics.newBody(world, screen.wc, screen.hc, "dynamic")
	objeto.bola.radio = 30
	objeto.bola.shape = love.physics.newCircleShape(objeto.bola.radio)
	objeto.bola.fixture = love.physics.newFixture(objeto.bola.body, objeto.bola.shape, 1)
	objeto.bola.fixture:setRestitution(0.9)

Ahora vamos a por los objetos. Primero declaramos la tabla objeto y luego meteremos dentro objetos como bola, suelo, …

Es importante declarar los cuerpos (body) de esos objetos indicando donde estarán inicialmente en el mundo (we are the world, we are… en fin).
objeto.bola.body será una pelota colocada en el centro del mundo (y eso como hemos calculado antes está en screen.wc y screen.hc ). Esa pelota tendrá una forma/figura/silueta (shape) que en este caso será un circulo de radio 30px (60px de diámetro para los de la LOGSE).
Crearemos el fixture y con fixture:setRestitution(0.9) indicaremos el rebote de la pelota en este caso.

Si nos fijamos en el siguiente objeto, el del suelo veremos que es algo diferente:

	objeto.suelo = {}
	objeto.suelo.alto = 50
	objeto.suelo.ancho = screen.w
	objeto.suelo.body = love.physics.newBody(world, screen.wc, screen.h-(objeto.suelo.alto/2))
	objeto.suelo.shape = love.physics.newRectangleShape(screen.w, objeto.suelo.alto)
	objeto.suelo.fixture = love.physics.newFixture(objeto.suelo.body, objeto.suelo.shape);

En este le hemos dado un ancho y alto para que cuando creamos la/el shape tenga el tamaño. Lo hemos colocado abajo de la pantalla dividiendo el alto del objeto suelo entre 2 y luego restando el total de alto de la pantalla (screen.h). Hemos dividido entre 2 el alto del objeto suelo ya que el newbody se ha de indicar el punto medio del objeto para posicionarlo.

El contenido de la función draw ya lo hemos visto muchas veces en otros posts. Allí simplemente dibujamos con el color que queramos los objetos. Lo interesante estará en:

function love.update(dt)
	world:update(dt) --this puts the world into motion
end

Con eso simplemente “el mundo comienza a andar”. Aquí es el sitio en el que posiblemente podamos meter los movimientos de teclas cuando presionamos izquierda, derecha, etc…

Si más o menos se entiende dejo un ejemplo que viene en la wiki de love2d y que es en el que me he basado. Un ejemplo más complejo con más objetos y en el que podemos mover la bola:
https://love2d.org/wiki/Tutorial:Physics

próximo Publicación

Atrás Publicación

Dejar una contestacion

© 2018 [ MIERDA TV ]

Tema de Anders Norén