├── README.md ├── main.lua ├── ship.png └── simpleScale.lua /README.md: -------------------------------------------------------------------------------- 1 | # simpleScale 2 | A simple library for scaling games made in [LÖVE](https://love2d.org) to any window size and aspect ratio. 3 | 4 | ![](https://thumbs.gfycat.com/CrazyShortAuklet-size_restricted.gif) 5 | 6 | Scales the game while maintaining its aspect ratio, adding vertical or horizontal letterboxes if necessary. 7 | Inspired by [TLfres](https://love2d.org/wiki/TLfres) and used in [SuperLuminauts](https://www.superluminauts.com/). 8 | 9 | TO USE: 10 | 11 | 1. Import simpleScale 12 | 13 | 2. In love.load call `simpleScale.setWindow(gameWidth, gameHeight, windowWidth, windowHeight, flags)` 14 | 15 | `gameWidth` - width of the game 16 | 17 | `gameHeight` - height of the game 18 | 19 | `windowWidth` - width of the final window 20 | 21 | `windowHeight` - height of the final window 22 | 23 | `flags` - a table of optional flags corresponding to those used in love.window.setmode https://love2d.org/wiki/love.window.setMode 24 | 25 | 3. At the start of love.draw call `simpleScale.set()` 26 | 27 | 4. At the end of love.draw call `simpleScale.unSet()` 28 | 29 | Additional Features: 30 | 31 | * To update the window again, just call `simpleScale.updateWindow(windowWidth, windowHeight, flags)` 32 | 33 | * To change the color of the letterboxes, simply call `simpleScale.unSet({r, g, b})`. Alpha values are optionally accepted as well. 34 | 35 | * If your window needs to be resizable by dragging, just call `simpleScale.resizeUpdate()` in love.update 36 | -------------------------------------------------------------------------------- /main.lua: -------------------------------------------------------------------------------- 1 | -- Example Project 2 | 3 | function love.load() 4 | love.window.setTitle("SimpleScale Demo") 5 | require "simpleScale" 6 | love.graphics.setDefaultFilter("nearest","nearest") 7 | im_ship = love.graphics.newImage("ship.png") 8 | love.graphics.setBackgroundColor(100/255,110/255,140/255) 9 | 10 | scaleType = 1 11 | width = 300 12 | height = 300 13 | windowWidth = 300 14 | widthHeight = 300 15 | fullscreen = false 16 | simpleScale.setWindow(width,height,windowWidth,widthHeight, {fullscreen = fullscreen, resizable = true}); 17 | 18 | function updateScale() 19 | simpleScale.updateWindow(windowWidth,widthHeight, {fullscreen = fullscreen, resizable = true}); 20 | end 21 | end 22 | 23 | function love.update() 24 | simpleScale.resizeUpdate() 25 | if love.keyboard.isDown("left") then 26 | windowWidth = math.max(windowWidth - 50, 50) 27 | fullscreen = false 28 | updateScale() 29 | elseif love.keyboard.isDown("right") then 30 | windowWidth = windowWidth + 50 31 | fullscreen = false 32 | updateScale() 33 | elseif love.keyboard.isDown("down") then 34 | widthHeight = math.max(widthHeight - 50, 50) 35 | fullscreen = false 36 | updateScale() 37 | elseif love.keyboard.isDown("up") then 38 | widthHeight = widthHeight + 50 39 | fullscreen = false 40 | updateScale() 41 | elseif love.keyboard.isDown("f") then 42 | fullscreen = not fullscreen 43 | updateScale() 44 | end 45 | end 46 | 47 | function love.draw() 48 | simpleScale.set() 49 | love.graphics.print("Press\nRight: Increase Width\nLeft: Decrease Width\nUp:Increase Height\nDown: Decrease Height\nF: Toggle Fullscreen", 0, 0) 50 | love.graphics.draw(im_ship,150,150,0,1,1,81/2,52/2) 51 | simpleScale.unSet() 52 | end -------------------------------------------------------------------------------- /ship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tomlum/simpleScale/f8d570548ac87dc16ff2fedc15c7232bfd46e4e7/ship.png -------------------------------------------------------------------------------- /simpleScale.lua: -------------------------------------------------------------------------------- 1 | simpleScale = {} 2 | --Your Game's Aspect Ratio 3 | local gAspectRatio 4 | --The Window's Aspect Ratio 5 | local wAspectRatio 6 | --The scale between the game and the window's aspect ratio 7 | simpleScale.scale = 1 8 | 9 | local xt, yt = 0, 0, 1 10 | local gameW, gameH, windowW, windowH = 800, 600, 800, 600 11 | 12 | -- Declares your game's width and height, and sets the window size/settings 13 | -- To be used instead of love.window.setMode 14 | -- [gw] and [gh] are the width and height of the initial game 15 | -- [sw] and [sh] (optional) are the width and height of the final window 16 | -- [settings] (optional) are settings for love.window.setMode 17 | function simpleScale.setWindow(gw, gh, sw, sh, settings) 18 | sw = sw or gw 19 | sh = sh or gh 20 | gAspectRatio = gw/gh 21 | gameW = gw 22 | gameH = gh 23 | simpleScale.updateWindow(sw, sh, settings) 24 | end 25 | 26 | -- Updates the Window size/settings 27 | -- To be used instead of love.window.setMode 28 | -- [sw] and [sh] are the width and height of the new Window 29 | -- [settings] (optional) are settings for love.window.setMode 30 | function simpleScale.updateWindow(sw, sh, settings) 31 | love.window.setMode(sw, sh, settings) 32 | windowW, windowH = love.graphics.getWidth(), love.graphics.getHeight() 33 | wAspectRatio = windowW/windowH 34 | 35 | --Window aspect ratio is TALLER than game 36 | if gAspectRatio > wAspectRatio then 37 | scale = windowW/gameW 38 | xt = 0 39 | yt = windowH/2 - (scale*gameH)/2 40 | 41 | --Window aspect ratio is WIDER than game 42 | elseif gAspectRatio < wAspectRatio then 43 | scale = windowH/gameH 44 | xt = windowW/2 - (scale*gameW)/2 45 | yt = 0 46 | 47 | --Window and game aspect ratios are EQUAL 48 | else 49 | scale = windowW/gameW 50 | 51 | xt = 0 52 | yt = 0 53 | end 54 | simpleScale.scale = scale 55 | end 56 | 57 | -- If you screen is resizable on drag, you'll need to call this to make sure 58 | -- the appropriate screen values stay updated 59 | -- You can call it on love.update() with no trouble 60 | function simpleScale.resizeUpdate() 61 | windowW, windowH = love.graphics.getWidth(), love.graphics.getHeight() 62 | wAspectRatio = windowW/windowH 63 | 64 | --Window aspect ratio is TALLER than game 65 | if gAspectRatio > wAspectRatio then 66 | scale = windowW/gameW 67 | xt = 0 68 | yt = windowH/2 - (scale*gameH)/2 69 | 70 | --Window aspect ratio is WIDER than game 71 | elseif gAspectRatio < wAspectRatio then 72 | scale = windowH/gameH 73 | xt = windowW/2 - (scale*gameW)/2 74 | yt = 0 75 | 76 | --Window and game aspect ratios are EQUAL 77 | else 78 | scale = windowW/gameW 79 | 80 | xt = 0 81 | yt = 0 82 | end 83 | simpleScale.scale = scale 84 | end 85 | 86 | -- Transforms the game's window relative to the entire window 87 | -- Call this at the beginning of love.draw() 88 | function simpleScale.set() 89 | love.graphics.push() 90 | love.graphics.translate(xt, yt) 91 | love.graphics.scale(scale, scale) 92 | end 93 | 94 | -- Untransforms the game's window 95 | -- Call this at the end of love.draw 96 | -- You can optionally make the letterboxes a specific color by passing 97 | -- [color] (optional) a table of color values 98 | function simpleScale.unSet(color) 99 | love.graphics.scale(1/scale, 1/scale) 100 | love.graphics.translate(-xt, -yt) 101 | love.graphics.pop() 102 | 103 | --Draw the Letterboxes 104 | local r,g,b,a = love.graphics.getColor() 105 | local originalColor = love.graphics.getColor() 106 | local boxColor 107 | if color == nil then 108 | boxColor = {0,0,0} 109 | else 110 | boxColor = color 111 | end 112 | love.graphics.setColor(boxColor) 113 | --Horizontal bars 114 | if gAspectRatio > wAspectRatio then 115 | love.graphics.rectangle("fill", 0, 0, windowW, math.abs((gameH*scale - (windowH))/2)) 116 | love.graphics.rectangle("fill", 0, windowH, windowW, -math.abs((gameH*scale - (windowH))/2)) 117 | --Vertical bars 118 | elseif gAspectRatio < wAspectRatio then 119 | love.graphics.rectangle("fill", 0, 0, math.abs((gameW*scale - (windowW))/2),windowH) 120 | love.graphics.rectangle("fill", windowW, 0, -math.abs((gameW*scale - (windowW))/2),windowH) 121 | end 122 | love.graphics.setColor(r,g,b,a) 123 | end --------------------------------------------------------------------------------