Además de gráficos y sonidos, hay un elemento importante a mostrar en pantalla para la interacción del jugador y la presentación de información, el texto.

En esta ocasión veremos como utilizar distintas fuentes de letra para escribir en pantalla.

En la última entrada de esta serie, implementamos la detección de colisiones que permite controlar el impacto de los lasers contra los enemigos.

Si bien todavía nos queda dar la capacidad de disparo a las naves invasoras e implementar a su vez dichas colisiones, por ahora daremos un respiro y veremos algo más sencillo.

Cómo implementar la escritura por pantalla con fuentes de letra personalizadas y acordes a nuestro juego en tamaño y estilo.

Elección de la fuente de letra, ttf

Este tema es cuestión de gustos, las fuentes se guardan de forma general como archivos ttf o en archivos de imagen.

En OpenGameArt puedes descargar fuentes para tus juegos, para este ejemplo he utilizado la KenVector que puedes descargar aquí.

También está incluida entre los recursos del juego en los fuentes

Como utilizar la fuente

Con love2d podemos cargar directamente el ttf con la función love.graphics.newFont(<«path al archivo ttf»>, <tamaño fuente>):

font = love.graphics.newFont("recursos/Bonus/kenvector_future2.ttf", 30)

Ya solo queda indicar al juego que la utilice:

love.graphics.setFont(font)

Esto puedes hacerlo durante la inicialización de objetos del juego al cargar sonidos, imágenes…

Por último, escribimos en la función update.draw():

love.graphics.print("kills", 30, 10)	
love.graphics.print("lvl 1", WINDOWW-160, 10)

Una vez definida la fuente, será la utilizada siempre por print(). En el caso de utilizar distintos fuentes será necesario ir cambiando antes de cada impresión.

A continuación el código con los últimos cambios:

function xInit()
	print("altaruru intro a love2d")
	print("ESCAPE TO QUIT")	
  -- recupera dimensiones de la ventana
	WINDOWH = love.graphics.getHeight()
	WINDOWW = love.graphics.getWidth()		
	-- inicia aleatorios:
	math.randomseed(os.time()) -- random initialize	
	pause_down = false
	pngs_visible = true
	circle_visible = true
end

function xloadobjs()
	
	font = love.graphics.newFont("recursos/Bonus/kenvector_future2.ttf", 30)
	love.graphics.setFont(font)
	background = {}
	background.image = love.graphics.newImage('recursos/Backgrounds/blue.png')
	background.W = background.image:getWidth()
	background.H = background.image:getHeight()
	background.sound=love.audio.newSource("recursos/musica/space1.mp3")

	laserblue01 = {}
	laserblue01.image = love.graphics.newImage("recursos/PNG/Lasers/laserBlue01.png")
	laserblue01.W = laserblue01.image:getWidth()
	laserblue01.H = laserblue01.image:getHeight()
	laserblue01.sound=love.audio.newSource("recursos/Bonus/sfx_laser1.ogg", "static")

	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-10 -- posicion inicial y
	xpuntocentral(player1)
	player1.R = player1.W/2 -- radio aprox para pruebas
	player1.v = 300 --velocidad de la nave
	player1.ctrshoot = -1 -- control de disparos
	player1.kills = 0
	player1.level = 1
	-- tabla lasers
	player1.lasers={}	

	-- tabla de aliens
	aliens = {}
	-- crea aliens por defecto
	xnewalien(0)
	xnewalien(1)		
	xnewalien(2)
end

function xnewalien(fila)
	alien1 = {}
	alien1.image = love.graphics.newImage("recursos/PNG/Enemies/enemyBlack1.png")
	alien1.fila=fila;
	alien1.W = alien1.image:getWidth() -- ancho de la nave
	alien1.H = alien1.image:getHeight() -- alto de la nave
	alien1.x = math.random(1,WINDOWW-alien1.H) -- posicion inicial x
	alien1.y = 36 + (fila*alien1.H) -- posicion inicial y
	xpuntocentral(alien1)
	alien1.R = alien1.W*0.5 -- radio aprox para pruebas	
	alien1.v = 100 + (5*math.random(10,40)) --velocidad de la nave variable, entre 150 y 300 a intervalos de 5
	alien1.xdir = 1 -- afecta al sentido del movimiento en el eje X. 1derecha, -1izquierda
	-- tabla lasers
	alien1.lasers={}
	-- inserta en la tabla
	table.insert(aliens, alien1)
end

function xdistancia(obj1, obj2)	
	-- utiliza el punto central de cada objeto
	d=math.sqrt(math.pow(obj2.cx-obj1.cx,2)+math.pow(obj2.cy-obj1.cy,2))	
	return d
end
function xpuntocentral(obj)
	-- debe actualizar siempre que hay movimiento
	obj.cx = obj.x + obj.W/2 --punto central X para calculo de colisiones
	obj.cy = obj.y + obj.H/2 --punto central Y para calculo de colisiones	
end
function xpuntocentralL(obj)
	-- debe actualizar siempre que hay movimiento
	obj.cx = obj.x + obj.W/2 --punto central X para calculo de colisiones
	obj.cy = obj.y + obj.H*0.2 --punto central Y para calculo de colisiones	
end
function xcolisiones()
	-- comprobamos si alguno de nuestros laser impacta en los aliens
	-- para ello, tenemos que recorrer los lasers y los aliens
	for ldel, l in ipairs(player1.lasers) do
		--love.graphics.draw(laserblue01.image, l.x, l.y)
		for adel,a in ipairs(aliens) do
			--love.graphics.draw(a.image, a.x, a.y)
			d=xdistancia(l, a)
			if(d-60<(a.R+l.R)) then -- debug cuando estan cerca
				print(a.fila .. ">" .. d .. " * " .. a.R+l.R)
				if(d<(a.R+l.R)) then -- si la distancia entre objetos es menos que la suma de sus radios... BOOM!
					print("impacto!" .. d .. "; RadioA:" .. a.R .. ", RadioL:" ..l.R)
					player1.kills = player1.kills + 1 -- incrementa contador de muertes
					-- destruye el laser
					table.remove(player1.lasers, ldel)
					-- destruye alien
					table.remove(aliens, adel)
					break
				end
			end
		end
	end
end

function love.load()
	xInit()
	xloadobjs()
	background.sound:setVolume(0.3) -- 30% del volumen general
	background.sound:setLooping(true)
	background.sound:play()
end

function xdrawpoints()
	if not circle_visible then
		return
	end
	wpoint=6
	-- Draw player
  love.graphics.setColor(80, 255, 0)
	love.graphics.rectangle("fill", player1.cx, player1.cy, wpoint, wpoint)
	love.graphics.circle("line", player1.cx, player1.cy, player1.R)
	-- Draw enemies
  love.graphics.setColor(200, 0, 200)
	for _,a in pairs(aliens) do
		love.graphics.rectangle("fill", a.cx, a.cy, wpoint, wpoint)
		love.graphics.circle("line", a.cx, a.cy, a.R)
	end
	-- Draw lasers
  love.graphics.setColor(190, 170, 0)
	for _,l in pairs(player1.lasers) do		
		love.graphics.rectangle("fill", l.cx, l.cy, wpoint, wpoint)
		love.graphics.circle("line", l.cx, l.cy, l.R)
	end
end
function xdrawpngs()
	if not pngs_visible then
		return
	end	
		-- Draw player
  love.graphics.draw(player1.image, player1.x, player1.y)  
  love.graphics.print(player1.kills .. " kills", 30, 10)	
	love.graphics.print("lvl:" .. player1.level, WINDOWW-160, 10)	
	-- Draw enemies
	for _,a in pairs(aliens) do
		love.graphics.draw(a.image, a.x, a.y)
	end
	-- Draw lasers
	for _,l in pairs(player1.lasers) do
		love.graphics.draw(laserblue01.image, l.x, l.y)
	end
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)
	xdrawpngs()
	xdrawpoints()
end

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

-- Move Aliens
function xmovealiens(dt)
	for _,a in pairs(aliens) do				
		a.x = a.x + (a.xdir * a.v * dt)
		-- si llega a los bordes de la ventana cambia la dirección
		if a.x > WINDOWW-a.W then
			a.x = WINDOWW-a.W
			a.xdir = -1
		elseif a.x<0 then
			a.x = 0
			a.xdir = 1
		end
		xpuntocentral(a)
	end
end	

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

function xplayershoot()
	if player1.ctrshoot < 0 then
		player1.ctrshoot=200
		laser={}
		laser.W = laserblue01.W
		laser.H = laserblue01.H
		laser.x= player1.x + (player1.W/2) - (laserblue01.W/2)
		laser.y= player1.y - laserblue01.H
		laser.R = laserblue01.W/2
		table.insert(player1.lasers, laser)
		-- reproduce sonido laser
		laserblue01.sound:stop()
		laserblue01.sound:play()
	end
end

function love.update(dt)
	-- aqui ajustamos el tiempo
	dtR=dt*1
	if pause_down then
		return
	end		
	if left_down then
		xmoveplayer(-1,0,dtR)
	end
	if right_down then
		xmoveplayer(1,0,dtR)
	end
	xmovelasers(dtR)
	xmovealiens(dtR)
	xcolisiones()
	xcompruebajuego()
end

function xnewlevel()
	player1.level = player1.level + 1
	print("bien hecho!")
	xnewalien(0)
	xnewalien(1)
	xnewalien(3)	
end
function xcompruebajuego()
	if(#aliens==0) then
		xnewlevel()
	end
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 == "p" then
		-- cada pulsación de P activa o desactiva la pausa
		pause_down = not pause_down
	end
	if key == "7" then
		-- muestra oculta imagenes
		pngs_visible = not pngs_visible
	end
	if key == "8" then
		-- muestra oculta circulos detección colisiones
		circle_visible = not circle_visible
	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
	end
	if key == " " then
		space_down = false
 	end
end

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

Descarga el fuente y los recursos de esta entrada aquí:

En la próxima entrada contraataque, armamos a los aliens, les toca disparar! xD

Temario completo del curso

Saludos y feliz código!

Deja tu comentario