Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- engine.lua
- Version: 1.1
- Author: MegaLoler
- Email: megaloler9000@gmail.com
- A game engine for Love that manages game scenes and entities.
- If requires that you use the class.lua file:
- require("class.lua")
- Make sure you have this in your code:
- require("engine.lua")
- Create a game by creating a subclass of the Engine class.
- MyGame = engine.newClass(engine.Engine)
- Define the setup method:
- function MyGame:setup()
- -- Initalize your game here.
- end
- Make sure to call the setGame function of your game class in your main.lua:
- MyGame:setGame() -- This will make the game engine take over.
- Create a scene by subclassing the Entity class:
- TestScene = newClass(engine.Entity)
- Define the setup, update, draw, and any other methods that you wish:
- function TestScene:setup() ... end
- function TestScene:update(dt) ... end
- function TestScene:draw() ... end
- Call the setScene method somewhere in your game's setup method to set the inital scene on launch:
- self:setScene(TestScene) -- Pass the class itself, not an instance of it
- --]]
- require("class")
- engine = {} -- Engine package
- -- Love wrappers
- function love.load()
- engine.game:load()
- end
- function love.quit()
- engine.game:quit()
- end
- function love.focus(f)
- engine.game:focus(f)
- end
- function love.keypressed(key, unicode)
- engine.game:keypressed(key, unicode)
- end
- function love.keyreleased(key)
- engine.game:keyreleased(key)
- end
- function love.mousepressed(x, y, button)
- engine.game:mousepressed(x, y, button)
- end
- function love.mousereleased(x, y, button)
- engine.game:mousereleased(x, y, button)
- end
- function love.update(dt)
- engine.game:update(dt)
- end
- function love.draw()
- engine.game:draw()
- end
- -- Engine class
- engine.Engine = newClass()
- function engine.Engine:init()
- self:setSize()
- self:setTitle()
- self.focused = true
- self.fading = false
- self.fade = 1
- self.fadeSpeed = 0.5
- self.fadeColor = {255, 255, 255}
- self:setScene(engine.Entity)
- end
- -- Sets the engine subclass to load
- function engine.Engine:setGame()
- engine.game = self:new()
- end
- -- Engine methods
- function engine.Engine:setTitle(title)
- self.title = title or "Game Engine"
- love.graphics.setCaption(self.title)
- end
- function engine.Engine:setSize(width, height)
- self.width = width or 640
- self.height = height or 480
- love.graphics.setMode(self.width, self.height)
- if self.scene then self:positionScene() end
- end
- function engine.Engine:fadeToScene(scene, ...)
- self.fadeTo = scene
- self.fadeArgs = ...
- self.fading = true
- end
- function engine.Engine:setScene(scene, ...)
- if self.scene then self.scene:destroy() end
- self.scene = scene:new(self)
- self:positionScene()
- self.scene:setup(...)
- end
- function engine.Engine:toggleFullscreen()
- love.graphics.toggleFullscreen()
- end
- -- Wrapped Love functions
- function engine.Engine:load()
- self:setup()
- end
- function engine.Engine:quit()
- end
- function engine.Engine:focus(f)
- self.focused = f
- end
- function engine.Engine:keypressed(key, unicode)
- self.scene:onkeypressed(key, unicode)
- end
- function engine.Engine:keyreleased(key)
- self.scene:onkeyreleased(key)
- end
- function engine.Engine:mousepressed(x, y, button)
- self.scene:onmousepressed(x, y, button)
- end
- function engine.Engine:mousereleased(x, y, button)
- self.scene:onmousereleased(x, y, button)
- end
- function engine.Engine:update(dt)
- if self.fading then
- if self.fade >= 1 then
- self.fade = 1
- self.fading = false
- self:setScene(self.fadeTo, self.fadeArgs)
- else
- self.fade = self.fade + self.fadeSpeed * dt
- if self.fade > 1 then self.fade = 1 end
- end
- else
- if self.fade <= 0 then
- self.fade = 0
- else
- self.fade = self.fade - self.fadeSpeed * dt
- if self.fade < 0 then self.fade = 0 end
- end
- end
- self.scene:masterUpdate(dt)
- end
- function engine.Engine:draw()
- self.scene:render()
- love.graphics.setCanvas()
- self.scene:postRender()
- self:drawFade()
- end
- -- Private methods
- function engine.Engine:positionScene()
- self.scene:setPosition(self.width / 2, self.height / 2)
- end
- function engine.Engine:drawFade()
- love.graphics.setBlendMode("alpha")
- love.graphics.setColor(self.fadeColor[1], self.fadeColor[2], self.fadeColor[3], (math.cos((1 - self.fade) * math.pi) + 1) * 127)
- love.graphics.polygon("fill", 0, 0, self.width, 0, self.width, self.height, 0, self.height)
- end
- -- Virtual methods
- function engine.Engine:setup()
- end
- -- Entity class
- engine.Entity = newClass()
- function engine.Entity:init(engine)
- self.engine = engine
- self:setSize()
- self:setPosition()
- self:setOrientation()
- self:setScale()
- self:setColor()
- self.children = {}
- self.selectable = false
- self.selected = false
- end
- function engine.Entity:addChild(child, ...)
- table.insert(self.children, child)
- child:setup(...)
- end
- function engine.Entity:removeChild(child)
- table.remove(self.children, child)
- child:destroy()
- end
- function engine.Entity:setColor(color)
- self.color = color or {255, 255, 255}
- end
- function engine.Entity:setPosition(x, y)
- self.x = x or 0
- self.y = y or 0
- end
- function engine.Entity:setOrientation(r)
- self.orientation = r or 0
- end
- function engine.Entity:setScale(x, y)
- self.scaleX = x or 1
- self.scaleY = y or 1
- end
- function engine.Entity:setSize(width, height)
- self.width = width or self.engine.width
- self.height = height or self.engine.height
- self.canvas = love.graphics.newCanvas(self.width, self.height)
- end
- function engine.Entity:masterUpdate(dt)
- for k, v in pairs(self.children) do
- v:masterUpdate(dt)
- end
- self:update(dt)
- end
- function engine.Entity:render()
- love.graphics.setCanvas(self.canvas)
- love.graphics.setColor(love.graphics.getBackgroundColor())
- love.graphics.setBlendMode("alpha")
- love.graphics.polygon("fill", 0, 0, self.width, 0, self.width, self.height, 0, self.height)
- self:preDraw()
- for k, v in pairs(self.children) do
- v:render()
- love.graphics.setCanvas(self.canvas)
- v:postRender()
- end
- self:draw()
- end
- function engine.Entity:postRender()
- love.graphics.setBlendMode("alpha")
- love.graphics.setColor(self.color[1], self.color[2], self.color[3])
- love.graphics.drawq(self.canvas, love.graphics.newQuad(0, 0, self.width, self.height, self.width, self.height), self.x, self.y , self.orientation, self.scaleX, self.scaleY, self.width / 2, self.height / 2)
- end
- function engine.Entity:onkeypressed(key, unicode)
- self:keypressed(key, unicode)
- if self.selectedChild then self.selectedChild:onkeypressed(key, unicode) end
- end
- function engine.Entity:onkeyreleased(key)
- self:keyreleased(key)
- if self.selectedChild then self.selectedChild:onkeyreleased(key) end
- end
- function engine.Entity:onmousepressed(x, y, button)
- self:mousepressed(x, y, button)
- if self.selectedChild then self.selectedChild.selected = false end
- self.selectedChild = self:getChildAtLocation(x, y)
- if self.selectedChild and not self.selectedChild.selectable then self.selectedChild = nil end
- if self.selectedChild then
- self.selectedChild.selected = true
- x, y = self:localCoordsToChildCoords(x, y, self.selectedChild)
- self.selectedChild:onmousepressed(x, y, button)
- end
- end
- function engine.Entity:onmousereleased(x, y, button)
- self:mousereleased(x, y, button)
- if self.selectedChild then
- x, y = self:localCoordsToChildCoords(x, y, self.selectedChild)
- self.selectedChild:onmousereleased(x, y, button)
- end
- end
- -- Private methods
- function engine.Entity:inBounds(x, y)
- return x >= 0 and x < self.width and y >= 0 and y < self.height
- end
- function engine.Entity:getChildAtLocation(x, y)
- for i = 1, #self.children do
- local child = self.children[#self.children - (i - 1)]
- local cx, cy = self:localCoordsToChildCoords(x, y, child)
- if child:inBounds(cx, cy) then return child end
- end
- end
- function engine.Entity:localCoordsToChildCoords(x, y, child)
- x = (x - child.x) / child.scaleX
- y = (y - child.y) / child.scaleY
- distance = math.sqrt((x * x) + (y * y))
- angle = math.atan2(y, x) - child.orientation
- x = math.cos(angle) * distance
- y = math.sin(angle) * distance
- x = x + child.width / 2
- y = y + child.height / 2
- return x, y
- end
- -- Virtual methods
- function engine.Entity:setup(...)
- end
- function engine.Entity:destroy()
- end
- function engine.Entity:keypressed(key, unicode)
- end
- function engine.Entity:keyreleased(key)
- end
- function engine.Entity:mousepressed(x, y, button)
- end
- function engine.Entity:mousereleased(x, y, button)
- end
- function engine.Entity:update(dt)
- end
- function engine.Entity:preDraw()
- end
- function engine.Entity:draw()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement