Bien! Ya tenemos nuestra flamante nave y podemos controlarla por teclado. ¿Pero que es una nave sin cañones láser con los que freír a los enemigos?. Vamos a darle potencia de fuego.

Aquí tienes en enlace a los fuentes de esta entrada incluyendo los recursos, imgs, …

En la carpeta recursos/PNG/Lasers hay gran variedad de imágenes png de láser para nuestras naves.

En la entrada anterior, lección IV, hicimos explicamos brevemente que son las Tablas y su uso para facilitar la programación y hacer un código más limpio y legible. Esa introducción nos viene al pelo porque para implementar disparos es necesario que utilicemos tablas.

Veamos el código paso a paso

Cargamos la imagen del láser e inicializamos variables. Vamos a xloadobjs() y añadimos las siguientes lineas:

laserblue01 = {}
laserblue01.image = love.graphics.newImage("recursos/PNG/Lasers/laserBlue01.png")
laserblue01.W = laserblue01.image:getWidth()
laserblue01.H = laserblue01.image:getHeight()

Como vés es similar a la carga de otras imágenes realizada anteriormente:

  1. Creamos Tabla.
  2. Cargamos imagen desde archivo png.
  3. Guardamos los valores de ancho y alto en variables W y H. Es más eficiente que llamar a una función cada vez que necesitamos el dato.

Los lasers son elementos asociados a la nave que los dispara, por ello, la información de los mismos vamos a guardarla dentro de nuestra tabla player1{}

El número de disparos será variable, desde 0 a N dependiendo del momento de la partida. Para ello, usaremos otra tabla, la tabla lasers, y la vamos a crear dentro de la tabla player1.

Una tabla puede contener variables y otras tablas.

Añadimos la declaración de la tabla lasers al final de la función xloadobjs()

player1.lasers={}

Ahora, creamos a la función que hará el disparo al pulsar la tecla de disparo, la llamaremos xplayershoot():

function xplayershoot()
  laser={}  -- crea tabla laser
  laser.x= player1.x + (player1.W/2) - (laserblue01.W/2)
  laser.y= player1.y - laserblue01.H
  table.insert(player1.lasers, laser)
end

Hacemos lo siguiente:

  1. Creamos una tabla láser que tendrá la posición del disparo.
  2. Inicializamos coordenadas. El disparo sale de la nave por lo que utilizamos las coordenadas de la propia nave para calcular:
    • x = (coordenada X de la nave) + (mitad ancho de la nave) – (mitad ancho láser)
    • y = coordenada Y de la nave – (alto del láser)
  3. Insertamos tabla láser como elemento de la tabla lasers de player1.
    • table.insert(player1.lasers, laser)
    • La función table.insert permite insertar una tabla en otra.

Ahora asociamos la pulsación de la tecla «Espacio» con el disparo:

En la función love.keypressed(key) inserta las siguientes lineas

if key == " " then		
	xplayershoot()
end

Perfecto! ya tenemos casi todo hecho. Al pulsar la tecla «Espacio» va a crearse un disparo. Ahora vamos a mostrarlo por pantalla.

Vamos a la función love.draw() e inserta las siguientes lineas al final:

-- Draw lasers
for _,l in pairs(player1.lasers) do
	love.graphics.draw(laserblue01.image, l.x, l.y)
end

Genial! nuestra nave ya dispara!

Sin embargo el laser no se mueve! falta darle movimiento. para ello vamos a crear una función que se ejecute desde love.update() para que actualice la posición del laser. La llamaremos xmovelasers():

function xmovelasers(dt)
  for ldel, laser in ipairs(player1.lasers) do
    if laser.y < 0 then
      -- si llega a la parte superior de la ventana se elimina
      table.remove(player1.lasers, ldel)
    else
      laser.y= laser.y - 500 * dt
    end
  end
end

Aquí estamos recorriendo la tabla lasers del player1 para mover todos los lasers. Recorremos la tabla con un bucle for.

  • El movimiento es ascendente por lo que iremos restando a la coordenada y del laser.
  • Al igual que hacemos con la nave, el movimiento debe hacerse proporcional al tiempo, aplicando dt al desplazamiento.
    • laser.y= laser.y – 500 * dt
  • Al alcanzar la parte superior de la ventana, o lo que es lo mismo cuando laser.y es menor de 0, el disparo desaparece, y se destruye.
    • table.remove(player1.lasers, ldel)

500 me ha parecido un valor bueno, podéis jugar cambiando el valor y ver como se comporta.

Más adelante, utilizaremos una variable para poder modificar la velocidad de los disparos en función del arma seleccionada.

Sólo nos queda llamar a la función xmovelasers() desde love.update(), inserta la siguiente linea al final de la función:

xmovelasers(dt)

Ahora si!! lasers cargados y listos para la batalla!

Dejo el código completo, de cualquier modo, al inicio de esta entrada está el enlace de descarga:

function xInit()
	print("altaruru intro a love2d")
	print("ESCAPE TO QUIT")	
  -- recupera dimensiones de la ventana
	WINDOWH = love.graphics.getHeight()
	WINDOWW = love.graphics.getWidth()	
end

function xloadobjs()
	background = {}
	background.image = love.graphics.newImage('recursos/Backgrounds/clouds.png')
	background.W = background.image:getWidth()
	background.H = background.image:getHeight()
	laserblue01 = {}
	laserblue01.image = love.graphics.newImage("recursos/PNG/Lasers/laserBlue01.png")
	laserblue01.W = laserblue01.image:getWidth()
	laserblue01.H = laserblue01.image:getHeight()
	
	player1 = {}
	player1.image = love.graphics.newImage("recursos/PNG/playerShip1_blue.png")
	player1.W = player1.image:getWidth() -- ancho de la nave
	player1.H = player1.image:getHeight() -- alto de la nave
	player1.x=(WINDOWW-player1.W)/2 -- posicion inicial x
	player1.y=WINDOWH-player1.H-40 -- posicion inicial y
	player1.v = 300 --velocidad de la nave
	-- tabla lasers
	player1.lasers={}
end

function love.load()
	xInit()
	xloadobjs()
end

function love.draw()
	-- Draw background  
  love.graphics.setColor(255, 255, 255)
  love.graphics.draw(background.image, 0, 0, 0, WINDOWW/background.W, WINDOWH/background.H)
	-- Draw player
  love.graphics.draw(player1.image, player1.x, player1.y)
	-- Draw lasers
	for _,l in pairs(player1.lasers) do
		love.graphics.draw(laserblue01.image, l.x, l.y)
	end

end

function xmoveplayer(x, y, dt)
	player1.x = player1.x + (x * player1.v * dt)
end	

function xmovelasers(dt)
	for ldel, laser in ipairs(player1.lasers) do
		if laser.y > -5 then
			laser.y= laser.y - 500 * dt
		else
			-- si llega a la parte superior de la ventana se elimina
			table.remove(player1.lasers, ldel)
		end
	end
end

function xplayershoot()
  laser={}
  laser.x= player1.x + (player1.W/2) - (laserblue01.W/2)
  laser.y= player1.y - laserblue01.H
  table.insert(player1.lasers, laser)
end

function love.update(dt)
	if left_down then
		xmoveplayer(-1,0,dt)
	end
	if right_down then
		xmoveplayer(1,0,dt)
	end
	xmovelasers(dt)
end

function love.keypressed(key)
  if key == 'left' then
		left_down = true
	elseif key == 'right' then
    	right_down = true
 	end
	if key == " " then		
		xplayershoot()
	end
	if key == "escape" then
		love.event.quit()
	end
end

function love.keyreleased(key, unicode)
 	if key == 'left' then
		left_down = false
	elseif key == 'right' then
   	right_down = false
	elseif key == " " then
		space_down = false
 	end
end

function love.quit()
  print("¡Hasta pronto!")
end

Espero que os guste!

Próxima entrada, como añadir sonido al juego.

Feliz código y Altaruru!

Deja tu comentario