Ho creato uno o due giochetti in pixelart ed uno dei problemi che ho dovuto affrontare è stato... "scalare" la grafica per evitare di fare un "gioco per formiche".
Questo è un piccolo tutorial che spiega cosa serve fare per gestire "scaling" (più avanti ci sarà un post sul fullscreen).
Per prima cosa, è necessario scegliere una dimensione "standard" da cui partire. Per ottenere il miglior effetto di "scaling", bisogna che la grafica di arrivo (ad esempio, la risoluzione -ormai standard- 1920x1080) sia un moltiplicatore esatto della grafica di partenza.
Le due opzioni più sensate sono il x3 ed il x4, che hanno rispettivamente le seguenti dimensioni:
x3 640x360
x4 480x270
x5 384x216
Nota: si può ovviamente lavorare ad un progetto con risoluzioni iniziali "standard", ad esempio 640x480, bisogna però "ridurre" il moltiplicatore e gestire il translate.
La prima cosa da fare è inserire il filtro "nearest" per disegnare i pixel senza "blur". Questo va fatto prima di qualsiasi aggiunta di asset (creati con newImage), in questo modo tutto sarà "nitido":
love.graphics.setDefaultFilter("nearest", "nearest")
Definiamo, a questo punto, una dimensione standard (quella utilizzata per il gioco, di norma indicata come "virtuale" -VR-) e la dimensione "finale" in finestra:
DIM_VR = {
W = 384 ,
H = 216
}
DIM = {
W = 384 * 2 ,
H = 216 * 2
}
Per far partire il gioco alla dimensione corretta, impostare gli stessi valori di DIM anche nel love.conf(t):
function love.conf(t)
t.window.width = 384
t.window.height = 216
end
Eventualmente, si possono impostare gli stessi valori nel love.load():
function love.load()
local w, h, flags = love.window.getMode()
if w ~= DIM.W or h ~= DIM.H then
love.window.setMode(DIM.W, DIM.H, flags)
end
end
Concentriamoci sul love.draw(t), dove andremo a "sistemare" la scala della grafica.
Per disegnare correttamente il tutto, useremo un "buffer" e "scaleremo" quello.
I passaggi necessari sono questi:
- recupero delle dimensioni della finestra
- creazione del canvas
- calcolo della scala come "moltiplicatore intero"
- impostazione del canvas
- impostazione della scala
- eventuale traslazione per disegnare il tutto
- disegno della schermata di gioco
- chiusura del canvas
- disegno a video del tutto
Il codice, quindi, è:
function love.draw(dt)
-- dimensioni finestra
local screenSizeX, screenSizeY = love.graphics.getDimensions()
-- creazione canvas
local framebuffer = love.graphics.newCanvas(screenSizeX, screenSizeY)
-- calcolo scala
local scale = math.floor(math.min(screenSizeX / DIM_VR.W, screenSizeY / DIM_VR.H))
-- gestione del canvas e scala
love.graphics.setCanvas(framebuffer)
love.graphics.push()
love.graphics.scale(scale, scale)
-- gestione del translate
trans_x = (screenSizeX - DIM_VR.W * scale) / 2
trans_y = (screenSizeY - DIM_VR.H * scale) / 2
love.graphics.translate(trans_x, trans_y)
-- DISEGNO DELLA SCHERMATA DI GIOCO
love.graphics.draw(Asset)
-- reset
love.graphics.setCanvas()
love.graphics.pop()
-- disegno del canvas
love.graphics.draw(framebuffer, 0, 0)
end
Innestando questo codice, il sistema disegnerà la pagina della dimensione voluta in modo "scalato". Se la scala effettiva non è "intera", il disegno verrà centrato nella schermata.
Nota: a questo punto bisogna solo ricordarsi che l'intera grafica è "scalata", per cui se si utilizza il mouse come input, per ottenere la posizione corretta è necessario dividere il valore di X e Y per la scala!
Nessun commento:
Posta un commento