Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- [Class] Screen
- @version 0.2, 2017-02-20
- @author TheOddByte
- --]]
- local Screen = {}
- Screen.__index = Screen
- --[[
- Get the widest character of the font
- @param object font, "The font object"
- @return int width, "The width of the widest character"
- --]]
- local function getWidth( font )
- local width = 0
- for i = 32, 127 do
- local w = font:getWidth( string.char( i ) )
- if w > width then
- width = w
- end
- end
- return width
- end
- --[[
- Automatically scales a font to fit into the pixelWidth and pixelHeight
- depending on the grid dimensions.
- @param string font, "The path of the font"
- @param int width, "The width of the grid"
- @param int height, "The height of the grid"
- @param int pixelWidth, "The actual width of the virtual screen"
- @param int pixelHeight, "The actual height of the virtual screen"
- @return int scale, int fontWidth, int fontHeight
- --]]
- local function autoScale( font, width, height, pixelWidth, pixelHeight )
- local scale = 1
- local Font
- while true do
- Font = love.graphics.newFont( font, scale );
- local fWidth = getWidth( Font )
- local fHeight = Font:getHeight()
- local w, h = fWidth*width, fHeight*height
- if w < pixelWidth and h < pixelHeight then
- scale = scale + 1
- else
- if w > pixelWidth or h > pixelHeight then
- scale = scale - 1
- end
- break
- end
- end
- local fWidth = getWidth( Font )
- local fHeight = Font:getHeight()
- return scale, fWidth, fHeight
- end
- --[[
- Creates a new screen object
- @param string font, "The path of the font"
- @param int width, "The width of the grid"
- @param int height, "The height of the grid"
- @param int pixelWidth, "The actual width of the virtual screen"
- @param int pixelHeight, "The actual height of the virtual screen"
- @return object screen, "The screen object"
- --]]
- Screen.new = function( font, x, y, width, height, pixelWidth, pixelHeight )
- local fontsize, fW, fH = autoScale( font, width, height, pixelWidth, pixelHeight )
- local screen = {
- grid = {};
- background = { 0, 0, 0 };
- rWidth = pixelWidth;
- rHeight = pixelHeight;
- width = width;
- height = height;
- fontsize = fontsize;
- fW = fW;
- fH = fH;
- x = x;
- y = y;
- shader = "none";
- cursor = {
- x = 1;
- y = 1;
- show = false;
- blink = false;
- time = 0;
- rate = 0.5;
- };
- font_path = font;
- font = love.graphics.newFont( font, fontsize );
- background = { 30, 30, 30, 255 };
- foreground = { 255, 255, 255, 255 };
- }
- for x = 1, screen.width do
- screen.grid[x] = {}
- for y = 1, screen.height do
- screen.grid[x][y] = { char = " ", background = screen.background, foreground = screen.foreground }
- end
- end
- return setmetatable( screen, Screen )
- end
- --[[
- Sets the current background color of the screen
- @param table color, "The color to set, example { 255, 255, 255, 255 }"
- --]]
- function Screen:setBackgroundColor( color )
- self.background = color
- end
- --[[
- Gets the current background color of the screen
- @param table color, "The color to set, example { 255, 255, 255, 255 }"
- --]]
- function Screen:getBackground()
- return self.background
- end
- --[[
- Sets the current text color of the screen
- @param table color, "The color to set, example { 255, 255, 255, 255 }"
- --]]
- function Screen:setTextColor( color )
- self.foreground = color
- end
- --[[
- Gets the current text color of the screen
- @param table color, "The color to set, example { 255, 255, 255, 255 }"
- --]]
- function Screen:getTextColor()
- return self.foreground
- end
- --[[
- Sets the grid dimension
- @param int width, "The width of the grid"
- @param int height, "The height of the grid"
- --]]
- function Screen:setResolution( width, height )
- local size, fW, fH = autoScale( self.font_path, width, height, self.rHeight, self.rWidth )
- self.font = love.graphics.newFont( self.font_path, size )
- self.fW = fW
- self.fH = fH
- end
- --[[
- Gets the grid dimension
- @return int width, int height
- --]]
- function Screen:getResolution()
- return self.width, self.height
- end
- --[[
- Update the screen to match the new width and height
- @param int width, "The new width in pixels"
- @param int height, "The new height in pixels"
- --]]
- function Screen:refresh( width, height )
- self.rWidth = width
- self.rHeight = height
- local size, fW, fH = autoScale( self.font_path, self.width, self.height, self.rHeight, self.rWidth )
- self.font = love.graphics.newFont( self.font_path, size )
- self.fW = fW
- self.fH = fH
- end
- function Screen:setShader( shader )
- shader = type( shader ) == "string" and shader or "none"
- self.shader = shader
- end
- --[[
- Sets the font to use
- @param string font_path, "The path of the font to set"
- --]]
- function Screen:setFont( font_path )
- self.font_path = font_path
- local size, fW, fH = autoScale( self.font_path, self.width, self.height, self.rHeight, self.rWidth )
- self.font = love.graphics.newFont( self.font_path, size )
- self.fW = fW
- self.fH = fH
- end
- --[[
- Gets the current font the screen is using
- --]]
- function Screen:getFont()
- return self.font
- end
- --[[
- Sets cursor blink to be enabled or disabled
- @param boolean bool, "Whether or not cursor blink is enabled"
- --]]
- function Screen:setBlink( bool )
- self.cursor.blink = type( bool ) == "boolean" and bool or self.cursor.blink
- self.cursor.show = not self.cursor.blink and false or self.cursor.show
- end
- --[[
- Gets whether or no cursor blink is enabled
- @return boolean blink, "The state of cursor blink"
- --]]
- function Screen:getBlink()
- return self.cursor.blink
- end
- --[[
- Writes at the specified position on the screen
- @param string text, "The text to write"
- @param int x, "The x position"
- @param int y, "The y position"
- --]]
- function Screen:writeAt( text, x, y )
- self.cursor.y = y
- self.cursor.x = x
- for i = 1, #text do
- if x <= self.width and y <= self.height then
- self.grid[x + (i-1)][y] = { char = text:sub( i, i ), background = self.background, foreground = self.foreground }
- self.cursor.x = self.cursor.x + 1
- end
- end
- end
- --[[
- Writes text at the current cursor position
- @param string text, "The text to write"
- --]]
- function Screen:write( text )
- self:writeAt( text, self.cursor.x, self.cursor.y )
- end
- --[[
- Centers text on the screen at the give y position
- @param string text, "The text to write"
- @param int y, "The y position to write at"
- --]]
- function Screen:center( text, y )
- self:writeAt( text, math.ceil( (self.width-#text)/2 ), y )
- end
- function Screen:midpoint( text, x1, x2, y )
- self:writeAt( text, math.ceil( ((x1 + x2)-#text)/2 ), y )
- end
- --[[
- Converts a grid position to the real position on the screen
- @param int x, "The x position in the grid"
- @param int y, "The y position in the grid"
- --]]
- function Screen:getRealPos( x, y )
- return self.x + ( (x-1)*self.fW ), self.y + ( (y-1)*self.fH )
- end
- --[[
- Converts a real position to a grid position
- @param int x, "The x position"
- @param int y, "The y position"
- --]]
- function Screen:getGridPos( x, y )
- --# Loop and check every grid position
- for gX = 1, self.width do
- for gY = 1, self.height do
- local _x, _y = self:getRealPos( gX, gY )
- if x >= _x and x <= _x + self.fW and y >= _y and y <= _y + self.fH then
- return gX, gY
- end
- end
- end
- end
- --[[
- Clears the screen
- --]]
- function Screen:clear()
- for x = 1, self.width do
- self.grid[x] = {}
- for y = 1, self.height do
- self.grid[x][y] = { char = " ", background = self.background, foreground = self.foreground }
- end
- end
- end
- --[[
- Clears a line on the screen, either the current cursor position
- or the given line
- @param int line, "The line to clear, this one is optional"
- --]]
- function Screen:clearLine( line )
- for x = 1, self.width do
- self.screen[x][self.y] = { char = " ", background = self.background, foreground = self.foreground }
- end
- end
- --[[
- Renders the screen to the screen.
- --]]
- function Screen:render()
- shaders:set( 1, self.shader )
- shaders:predraw()
- love.graphics.setFont( self.font )
- for x = 1, #self.grid do
- for y = 1, #self.grid[x] do
- local t = self.grid[x][y]
- local rX, rY = self:getRealPos( x, y )
- love.graphics.setColor( unpack( t.background ) )
- love.graphics.rectangle("fill", rX, rY, self.fW, self.fH)
- love.graphics.setColor( unpack( t.foreground ) )
- love.graphics.print( t.char, rX, rY )
- end
- end
- --# Draw the cursor( if it's enabled )
- if self.cursor.blink and self.cursor.show then
- love.graphics.setColor(255, 255, 255, 255)
- local rX, rY = self:getRealPos( self.cursor.x, self.cursor.y )
- love.graphics.setColor( {255,255,255,255} )
- love.graphics.rectangle( "fill", rX, rY, self.fW, self.fH )
- end
- shaders:postdraw()
- shaders:set( 1, "none" )
- end
- function Screen:update( dt )
- if self.cursor.blink then
- self.cursor.time = self.cursor.time + dt
- if self.cursor.time >= self.cursor.rate then
- self.cursor.time = 0;
- self.cursor.show = not self.cursor.show
- end
- end
- end
- return Screen
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement