| @@ -0,0 +1,33 @@ | |||||
| # Questionable Örbital Mechanics | |||||
| ## What is this? | |||||
| Questionable Örbital Mechanics - or as i like to call it: *QÖM* - is an open-source Space Simulation "Game" written in Lua using the Löve game engine. | |||||
| For now it is very basic, as it is still heavily in development. | |||||
| ## How do i play this game? | |||||
| In order to play this game you need to ... | |||||
| 1) ...have the Lua (5.4.3) programming language installed | |||||
| 1) ...have the Löve (11.3) game engine installed | |||||
| For now this is the only way to play this game. In future there will be binary versions availabe. | |||||
| ### Installing Lua | |||||
| Arch Linux: | |||||
| `sudo pacman -S lua` | |||||
| Windows: | |||||
| https://www.lua.org/download.html | |||||
| ### Installing Love | |||||
| Arch Linux: | |||||
| `sudo pacman -S love` | |||||
| Windows: | |||||
| https://love2d.org | |||||
| ## What's new? | |||||
| *here will come changelogs in future* | |||||
| @@ -0,0 +1,40 @@ | |||||
| controls = { | |||||
| -- Player Flight Controls: | |||||
| flight = { | |||||
| -- Respawn on Starting Location: | |||||
| reset = "r", | |||||
| -- Change Throttle: | |||||
| throttle = { | |||||
| up = "lshift", | |||||
| down = "lctrl", | |||||
| full = "y", | |||||
| none = "x" | |||||
| }, | |||||
| -- Directional Thrust: | |||||
| thrust = { | |||||
| up = "w", | |||||
| down = "s", | |||||
| left = "a", | |||||
| right = "d" | |||||
| }, | |||||
| -- Time Warp Controls: | |||||
| warp = { | |||||
| reset = "-", | |||||
| down = ",", | |||||
| up = "." | |||||
| } | |||||
| }, | |||||
| -- Player Camera Controls: | |||||
| camera = { | |||||
| zoom = { | |||||
| reset = 3 -- (Middle Mouse Button) | |||||
| } | |||||
| } | |||||
| } | |||||
| return controls | |||||
| @@ -0,0 +1,9 @@ | |||||
| info = {} | |||||
| info.name = "Questionable Örbital Mechanics" | |||||
| info.version = "0.0.2_dev" | |||||
| info.authors = { | |||||
| "NiroUwU" | |||||
| } | |||||
| return info | |||||
| @@ -0,0 +1,10 @@ | |||||
| planetdata = { | |||||
| { | |||||
| x = 0, y = 50000, | |||||
| r = 12000, m = 5e14, | |||||
| name = "Testos", | |||||
| colour = {42, 04, 20} | |||||
| } | |||||
| } | |||||
| return planetdata | |||||
| @@ -0,0 +1,21 @@ | |||||
| -- List of all dependancies to import to main file | |||||
| -- Libraries: | |||||
| require "libraries" | |||||
| -- General Data: | |||||
| info = require "data/info" | |||||
| controls = require "data/controls" | |||||
| texture = require "textures/textures" | |||||
| -- Game Source: | |||||
| calc = require "src/calc" | |||||
| font = require "src/font" | |||||
| -- Game Classes: | |||||
| require "src/class/Player" | |||||
| require "src/class/Gui" | |||||
| require "src/class/Planet" | |||||
| -- Game Data: | |||||
| planetdata = require "data/planetdata" | |||||
| @@ -0,0 +1,216 @@ | |||||
| --[[ | |||||
| Copyright (c) 2010-2015 Matthias Richter | |||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| of this software and associated documentation files (the "Software"), to deal | |||||
| in the Software without restriction, including without limitation the rights | |||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| copies of the Software, and to permit persons to whom the Software is | |||||
| furnished to do so, subject to the following conditions: | |||||
| The above copyright notice and this permission notice shall be included in | |||||
| all copies or substantial portions of the Software. | |||||
| Except as contained in this notice, the name(s) of the above copyright holders | |||||
| shall not be used in advertising or otherwise to promote the sale, use or | |||||
| other dealings in this Software without prior written authorization. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||||
| THE SOFTWARE. | |||||
| ]]-- | |||||
| local _PATH = (...):match('^(.*[%./])[^%.%/]+$') or '' | |||||
| local cos, sin = math.cos, math.sin | |||||
| local camera = {} | |||||
| camera.__index = camera | |||||
| -- Movement interpolators (for camera locking/windowing) | |||||
| camera.smooth = {} | |||||
| function camera.smooth.none() | |||||
| return function(dx,dy) return dx,dy end | |||||
| end | |||||
| function camera.smooth.linear(speed) | |||||
| assert(type(speed) == "number", "Invalid parameter: speed = "..tostring(speed)) | |||||
| return function(dx,dy, s) | |||||
| -- normalize direction | |||||
| local d = math.sqrt(dx*dx+dy*dy) | |||||
| local dts = math.min((s or speed) * love.timer.getDelta(), d) -- prevent overshooting the goal | |||||
| if d > 0 then | |||||
| dx,dy = dx/d, dy/d | |||||
| end | |||||
| return dx*dts, dy*dts | |||||
| end | |||||
| end | |||||
| function camera.smooth.damped(stiffness) | |||||
| assert(type(stiffness) == "number", "Invalid parameter: stiffness = "..tostring(stiffness)) | |||||
| return function(dx,dy, s) | |||||
| local dts = love.timer.getDelta() * (s or stiffness) | |||||
| return dx*dts, dy*dts | |||||
| end | |||||
| end | |||||
| local function new(x,y, zoom, rot, smoother) | |||||
| x,y = x or love.graphics.getWidth()/2, y or love.graphics.getHeight()/2 | |||||
| zoom = zoom or 1 | |||||
| rot = rot or 0 | |||||
| smoother = smoother or camera.smooth.none() -- for locking, see below | |||||
| return setmetatable({x = x, y = y, scale = zoom, rot = rot, smoother = smoother}, camera) | |||||
| end | |||||
| function camera:lookAt(x,y) | |||||
| self.x, self.y = x, y | |||||
| return self | |||||
| end | |||||
| function camera:move(dx,dy) | |||||
| self.x, self.y = self.x + dx, self.y + dy | |||||
| return self | |||||
| end | |||||
| function camera:position() | |||||
| return self.x, self.y | |||||
| end | |||||
| function camera:rotate(phi) | |||||
| self.rot = self.rot + phi | |||||
| return self | |||||
| end | |||||
| function camera:rotateTo(phi) | |||||
| self.rot = phi | |||||
| return self | |||||
| end | |||||
| function camera:zoom(mul) | |||||
| self.scale = self.scale * mul | |||||
| return self | |||||
| end | |||||
| function camera:zoomTo(zoom) | |||||
| self.scale = zoom | |||||
| return self | |||||
| end | |||||
| function camera:attach(x,y,w,h, noclip) | |||||
| x,y = x or 0, y or 0 | |||||
| w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight() | |||||
| self._sx,self._sy,self._sw,self._sh = love.graphics.getScissor() | |||||
| if not noclip then | |||||
| love.graphics.setScissor(x,y,w,h) | |||||
| end | |||||
| local cx,cy = x+w/2, y+h/2 | |||||
| love.graphics.push() | |||||
| love.graphics.translate(cx, cy) | |||||
| love.graphics.scale(self.scale) | |||||
| love.graphics.rotate(self.rot) | |||||
| love.graphics.translate(-self.x, -self.y) | |||||
| end | |||||
| function camera:detach() | |||||
| love.graphics.pop() | |||||
| love.graphics.setScissor(self._sx,self._sy,self._sw,self._sh) | |||||
| end | |||||
| function camera:draw(...) | |||||
| local x,y,w,h,noclip,func | |||||
| local nargs = select("#", ...) | |||||
| if nargs == 1 then | |||||
| func = ... | |||||
| elseif nargs == 5 then | |||||
| x,y,w,h,func = ... | |||||
| elseif nargs == 6 then | |||||
| x,y,w,h,noclip,func = ... | |||||
| else | |||||
| error("Invalid arguments to camera:draw()") | |||||
| end | |||||
| self:attach(x,y,w,h,noclip) | |||||
| func() | |||||
| self:detach() | |||||
| end | |||||
| -- world coordinates to camera coordinates | |||||
| function camera:cameraCoords(x,y, ox,oy,w,h) | |||||
| ox, oy = ox or 0, oy or 0 | |||||
| w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight() | |||||
| -- x,y = ((x,y) - (self.x, self.y)):rotated(self.rot) * self.scale + center | |||||
| local c,s = cos(self.rot), sin(self.rot) | |||||
| x,y = x - self.x, y - self.y | |||||
| x,y = c*x - s*y, s*x + c*y | |||||
| return x*self.scale + w/2 + ox, y*self.scale + h/2 + oy | |||||
| end | |||||
| -- camera coordinates to world coordinates | |||||
| function camera:worldCoords(x,y, ox,oy,w,h) | |||||
| ox, oy = ox or 0, oy or 0 | |||||
| w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight() | |||||
| -- x,y = (((x,y) - center) / self.scale):rotated(-self.rot) + (self.x,self.y) | |||||
| local c,s = cos(-self.rot), sin(-self.rot) | |||||
| x,y = (x - w/2 - ox) / self.scale, (y - h/2 - oy) / self.scale | |||||
| x,y = c*x - s*y, s*x + c*y | |||||
| return x+self.x, y+self.y | |||||
| end | |||||
| function camera:mousePosition(ox,oy,w,h) | |||||
| local mx,my = love.mouse.getPosition() | |||||
| return self:worldCoords(mx,my, ox,oy,w,h) | |||||
| end | |||||
| -- camera scrolling utilities | |||||
| function camera:lockX(x, smoother, ...) | |||||
| local dx, dy = (smoother or self.smoother)(x - self.x, self.y, ...) | |||||
| self.x = self.x + dx | |||||
| return self | |||||
| end | |||||
| function camera:lockY(y, smoother, ...) | |||||
| local dx, dy = (smoother or self.smoother)(self.x, y - self.y, ...) | |||||
| self.y = self.y + dy | |||||
| return self | |||||
| end | |||||
| function camera:lockPosition(x,y, smoother, ...) | |||||
| return self:move((smoother or self.smoother)(x - self.x, y - self.y, ...)) | |||||
| end | |||||
| function camera:lockWindow(x, y, x_min, x_max, y_min, y_max, smoother, ...) | |||||
| -- figure out displacement in camera coordinates | |||||
| x,y = self:cameraCoords(x,y) | |||||
| local dx, dy = 0,0 | |||||
| if x < x_min then | |||||
| dx = x - x_min | |||||
| elseif x > x_max then | |||||
| dx = x - x_max | |||||
| end | |||||
| if y < y_min then | |||||
| dy = y - y_min | |||||
| elseif y > y_max then | |||||
| dy = y - y_max | |||||
| end | |||||
| -- transform displacement to movement in world coordinates | |||||
| local c,s = cos(-self.rot), sin(-self.rot) | |||||
| dx,dy = (c*dx - s*dy) / self.scale, (s*dx + c*dy) / self.scale | |||||
| -- move | |||||
| self:move((smoother or self.smoother)(dx,dy,...)) | |||||
| end | |||||
| -- the module | |||||
| return setmetatable({new = new, smooth = camera.smooth}, | |||||
| {__call = function(_, ...) return new(...) end}) | |||||
| @@ -0,0 +1,98 @@ | |||||
| --[[ | |||||
| Copyright (c) 2010-2013 Matthias Richter | |||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| of this software and associated documentation files (the "Software"), to deal | |||||
| in the Software without restriction, including without limitation the rights | |||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| copies of the Software, and to permit persons to whom the Software is | |||||
| furnished to do so, subject to the following conditions: | |||||
| The above copyright notice and this permission notice shall be included in | |||||
| all copies or substantial portions of the Software. | |||||
| Except as contained in this notice, the name(s) of the above copyright holders | |||||
| shall not be used in advertising or otherwise to promote the sale, use or | |||||
| other dealings in this Software without prior written authorization. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||||
| THE SOFTWARE. | |||||
| ]]-- | |||||
| local function include_helper(to, from, seen) | |||||
| if from == nil then | |||||
| return to | |||||
| elseif type(from) ~= 'table' then | |||||
| return from | |||||
| elseif seen[from] then | |||||
| return seen[from] | |||||
| end | |||||
| seen[from] = to | |||||
| for k,v in pairs(from) do | |||||
| k = include_helper({}, k, seen) -- keys might also be tables | |||||
| if to[k] == nil then | |||||
| to[k] = include_helper({}, v, seen) | |||||
| end | |||||
| end | |||||
| return to | |||||
| end | |||||
| -- deeply copies `other' into `class'. keys in `other' that are already | |||||
| -- defined in `class' are omitted | |||||
| local function include(class, other) | |||||
| return include_helper(class, other, {}) | |||||
| end | |||||
| -- returns a deep copy of `other' | |||||
| local function clone(other) | |||||
| return setmetatable(include({}, other), getmetatable(other)) | |||||
| end | |||||
| local function new(class) | |||||
| -- mixins | |||||
| class = class or {} -- class can be nil | |||||
| local inc = class.__includes or {} | |||||
| if getmetatable(inc) then inc = {inc} end | |||||
| for _, other in ipairs(inc) do | |||||
| if type(other) == "string" then | |||||
| other = _G[other] | |||||
| end | |||||
| include(class, other) | |||||
| end | |||||
| -- class implementation | |||||
| class.__index = class | |||||
| class.init = class.init or class[1] or function() end | |||||
| class.include = class.include or include | |||||
| class.clone = class.clone or clone | |||||
| -- constructor call | |||||
| return setmetatable(class, {__call = function(c, ...) | |||||
| local o = setmetatable({}, c) | |||||
| o:init(...) | |||||
| return o | |||||
| end}) | |||||
| end | |||||
| -- interface for cross class-system compatibility (see https://github.com/bartbes/Class-Commons). | |||||
| if class_commons ~= false and not common then | |||||
| common = {} | |||||
| function common.class(name, prototype, parent) | |||||
| return new{__includes = {prototype, parent}} | |||||
| end | |||||
| function common.instance(class, ...) | |||||
| return class(...) | |||||
| end | |||||
| end | |||||
| -- the module | |||||
| return setmetatable({new = new, include = include, clone = clone}, | |||||
| {__call = function(_,...) return new(...) end}) | |||||
| @@ -0,0 +1,133 @@ | |||||
| -- color.lua | |||||
| -------------------------------------------------------------------------------- | |||||
| -- A super-simple way to make colored text output in Lua. | |||||
| -- To use, simply print out things from this module, then print out some text. | |||||
| -- | |||||
| -- Example: | |||||
| -- print(color.bg.green .. color.fg.RED .. "This is bright red on green") | |||||
| -- print(color.invert .. "This is inverted..." .. color.reset .. " And this isn't.") | |||||
| -- print(color.fg(0xDE) .. color.bg(0xEE) .. "You can use xterm-256 colors too!" .. color.reset) | |||||
| -- print("And also " .. color.bold .. "BOLD" .. color.normal .. " if you want.") | |||||
| -- print(color.bold .. color.fg.BLUE .. color.bg.blue .. "Miss your " .. color.fg.RED .. "C-64" .. color.fg.BLUE .. "?" .. color.reset) | |||||
| -- | |||||
| -- You can see all these examples in action by calling color.test() | |||||
| -- | |||||
| -- Can't pick a good color scheme? Look at a handy chart: | |||||
| -- print(color.chart()) | |||||
| -- | |||||
| -- If you want to add anything to this, check out the Wikipedia page on ANSI control codes: | |||||
| -- http://en.wikipedia.org/wiki/ANSI_escape_code | |||||
| -------------------------------------------------------------------------------- | |||||
| -- Copyright (C) 2012 Ross Andrews | |||||
| -- | |||||
| -- This program is free software: you can redistribute it and/or modify | |||||
| -- it under the terms of the GNU Lesser General Public License as published by | |||||
| -- the Free Software Foundation, either version 3 of the License, or | |||||
| -- (at your option) any later version. | |||||
| -- | |||||
| -- This program is distributed in the hope that it will be useful, | |||||
| -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| -- GNU General Public License for more details. | |||||
| -- | |||||
| -- You should have received a copy of the GNU Lesser General Public License | |||||
| -- along with this program. If not, see <http://www.gnu.org/licenses/lgpl.txt>. | |||||
| -------------------------------------------------------------------------------- | |||||
| -- A note about licensing: | |||||
| -- | |||||
| -- The LGPL isn't really intended to be used with non-compiled libraries. The way | |||||
| -- I interpret derivative works of this library is this: if you don't modify this | |||||
| -- file, and the program it's embedded in doesn't modify the Lua table it defines, | |||||
| -- then you can distribute it with a program under any license. If you do either | |||||
| -- of those things, then you've created a derivative work of this library and you | |||||
| -- have to release the modifications you made under this same license. | |||||
| local color = { _NAME = "color" } | |||||
| local _M = color | |||||
| local esc = string.char(27, 91) | |||||
| local names = {'black', 'red', 'green', 'yellow', 'blue', 'pink', 'cyan', 'white'} | |||||
| local hi_names = {'BLACK', 'RED', 'GREEN', 'YELLOW', 'BLUE', 'PINK', 'CYAN', 'WHITE'} | |||||
| color.fg, color.bg = {}, {} | |||||
| for i, name in ipairs(names) do | |||||
| color.fg[name] = esc .. tostring(30+i-1) .. 'm' | |||||
| _M[name] = color.fg[name] | |||||
| color.bg[name] = esc .. tostring(40+i-1) .. 'm' | |||||
| end | |||||
| for i, name in ipairs(hi_names) do | |||||
| color.fg[name] = esc .. tostring(90+i-1) .. 'm' | |||||
| _M[name] = color.fg[name] | |||||
| color.bg[name] = esc .. tostring(100+i-1) .. 'm' | |||||
| end | |||||
| local function fg256(_,n) | |||||
| return esc .. "38;5;" .. n .. 'm' | |||||
| end | |||||
| local function bg256(_,n) | |||||
| return esc .. "48;5;" .. n .. 'm' | |||||
| end | |||||
| setmetatable(color.fg, {__call = fg256}) | |||||
| setmetatable(color.bg, {__call = bg256}) | |||||
| color.reset = esc .. '0m' | |||||
| color.clear = esc .. '2J' | |||||
| color.bold = esc .. '1m' | |||||
| color.faint = esc .. '2m' | |||||
| color.normal = esc .. '22m' | |||||
| color.invert = esc .. '7m' | |||||
| color.underline = esc .. '4m' | |||||
| color.hide = esc .. '?25l' | |||||
| color.show = esc .. '?25h' | |||||
| function color.move(x, y) | |||||
| return esc .. y .. ';' .. x .. 'H' | |||||
| end | |||||
| color.home = color.move(1, 1) | |||||
| -------------------------------------------------- | |||||
| function color.chart(ch,col) | |||||
| local cols = '0123456789abcdef' | |||||
| ch = ch or ' ' | |||||
| col = col or color.fg.black | |||||
| local str = color.reset .. color.bg.WHITE .. col | |||||
| for y = 0, 15 do | |||||
| for x = 0, 15 do | |||||
| local lbl = cols:sub(x+1, x+1) | |||||
| if x == 0 then lbl = cols:sub(y+1, y+1) end | |||||
| str = str .. color.bg.black .. color.fg.WHITE .. lbl | |||||
| str = str .. color.bg(x+y*16) .. col .. ch | |||||
| end | |||||
| str = str .. color.reset .. "\n" | |||||
| end | |||||
| return str .. color.reset | |||||
| end | |||||
| function color.test() | |||||
| print(color.reset .. color.bg.green .. color.fg.RED .. "This is bright red on green" .. color.reset) | |||||
| print(color.invert .. "This is inverted..." .. color.reset .. " And this isn't.") | |||||
| print(color.fg(0xDE) .. color.bg(0xEE) .. "You can use xterm-256 colors too!" .. color.reset) | |||||
| print("And also " .. color.bold .. "BOLD" .. color.normal .. " if you want.") | |||||
| print(color.bold .. color.fg.BLUE .. color.bg.blue .. "Miss your " .. color.fg.RED .. "C-64" .. color.fg.BLUE .. "?" .. color.reset) | |||||
| print("Try printing " .. color.underline .. _M._NAME .. ".chart()" .. color.reset) | |||||
| end | |||||
| return color | |||||
| @@ -0,0 +1,6 @@ | |||||
| -- Credit: https://github.com/randrews/color | |||||
| clr = require "lib/color" | |||||
| -- Credit: https://github.com/vrld/hump/ | |||||
| Class = require "lib/class" | |||||
| Camera = require "lib/camera" | |||||
| @@ -0,0 +1,126 @@ | |||||
| require "import" | |||||
| -- Debugging / Logging: | |||||
| debug = calc.debug | |||||
| calc.isDebug = true | |||||
| function love.load() | |||||
| -- Declaration: | |||||
| love.window.setTitle(info.name.." - v"..info.version) | |||||
| width, height = love.graphics.getDimensions() | |||||
| cam = Camera() | |||||
| zoomlevel = 1 | |||||
| -- Loading: | |||||
| planet = {} | |||||
| loadPlanets() | |||||
| local spawnPlanet = planet[1] | |||||
| player = Player(spawnPlanet.x, spawnPlanet.y-spawnPlanet.r-1) | |||||
| gui = Gui(1) | |||||
| end | |||||
| -- Planets: | |||||
| function loadPlanets() | |||||
| debug("Planets in planet table: "..#planetdata) | |||||
| for i=1, #planetdata do | |||||
| local p = planetdata[i] | |||||
| debug(p.name.." is loading") | |||||
| table.insert(planet, i, | |||||
| Planet( | |||||
| -- Planet Data Assignment: | |||||
| p.x, p.y, | |||||
| p.r, p.m, | |||||
| p.name, | |||||
| p.colour | |||||
| ) | |||||
| ) | |||||
| debug(p.name.." is loaded") | |||||
| end | |||||
| debug("Planets loaded: "..#planet) | |||||
| end | |||||
| function updatePlanets() | |||||
| for i=1, #planet do | |||||
| planet[i]:update() | |||||
| end | |||||
| end | |||||
| function drawPlanets() | |||||
| for i=1, #planet do | |||||
| planet[i]:draw() | |||||
| end | |||||
| end | |||||
| -- Camera | |||||
| function cameraControls() | |||||
| local zooming = 0.01 | |||||
| function love.wheelmoved(x, y) | |||||
| if y > 0 then | |||||
| -- Zoom in: | |||||
| zoomlevel = zoomlevel + zooming | |||||
| elseif y < 0 then | |||||
| -- Zoom out: | |||||
| zoomlevel = zoomlevel - zooming | |||||
| end | |||||
| end | |||||
| -- Reset Zoom: | |||||
| if love.mouse.isDown(3) then | |||||
| zoomlevel = 1 | |||||
| end | |||||
| -- Zoom Limit: | |||||
| local max = 4 | |||||
| local min = 0.001 | |||||
| if zoomlevel < min then | |||||
| zoomlevel = min | |||||
| end | |||||
| if zoomlevel > max then | |||||
| zoomlevel = max | |||||
| end | |||||
| --debug(zoomlevel) | |||||
| cam:zoomTo(zoomlevel) | |||||
| end | |||||
| -- MAIN | |||||
| function love.update(dt) | |||||
| -- Game Objects: | |||||
| updatePlanets() | |||||
| player:update(dt) | |||||
| -- Gui: | |||||
| gui:update(dt) | |||||
| -- Camera: | |||||
| cam:lookAt(player.x, player.y) | |||||
| cameraControls() | |||||
| end | |||||
| function love.draw() | |||||
| cam:attach() | |||||
| -- Game Objects: | |||||
| drawPlanets() | |||||
| player:draw() | |||||
| -- Camera Zoom Player Location Indicator: OVERWORK SOON PLS KAY; IT UGLY | |||||
| if zoomlevel < 0.3 then | |||||
| love.graphics.setColor(1, 1, 1, 0.2) | |||||
| love.graphics.circle("fill", player.x, player.y, (1/zoomlevel)*10) | |||||
| end | |||||
| cam:detach() | |||||
| -- Gui: | |||||
| gui:draw() | |||||
| end | |||||
| @@ -0,0 +1,3 @@ | |||||
| #!/bin/bash | |||||
| chmod +x -R ./ | |||||
| love $( pwd ) | |||||
| @@ -0,0 +1,40 @@ | |||||
| calc = {} | |||||
| -- G-Constant | |||||
| calc.G = 6.67e-11 -- TWEAKABLE FOR LATER DEPENDING ON SCALE!!!!!!!!!!! | |||||
| -- Development debugging/logging thing | |||||
| function calc.debug(text) | |||||
| if calc.isDebug then | |||||
| local cDev = clr.fg.RED | |||||
| local cText = clr.fg.YELLOW | |||||
| local cReset = clr.reset | |||||
| print(cDev.."DEV: "..cText..text..cReset) | |||||
| end | |||||
| end | |||||
| -- 0-255 colour to 0-1 colour (returns a table) | |||||
| function calc.colour(r, g, b) | |||||
| return { r/255, g/255, b/255 } | |||||
| end | |||||
| -- 0-255 colour value to 0-1 colour value | |||||
| function calc.c(value) | |||||
| return value/255 | |||||
| end | |||||
| -- Distance Formula: | |||||
| function calc.distance(x1, y1, x2, y2) | |||||
| return math.sqrt( (x2 - x1)^2 + (y2 - y1)^2 ) | |||||
| end | |||||
| -- Calculates the gravitational pull between two objects: | |||||
| function calc.gPull(obj1, obj2) | |||||
| local dist = calc.distance(obj1.x, obj1.y, obj2.x, obj2.y) | |||||
| local grav = calc.G * (obj1.m * obj2.m) / dist^2 | |||||
| return grav | |||||
| end | |||||
| return calc | |||||
| @@ -0,0 +1,62 @@ | |||||
| Gui = Class {} | |||||
| function Gui:init(tempScale) | |||||
| self.scale = tempScale | |||||
| end | |||||
| -- FUNCTIONS | |||||
| function Gui:drawSpeed() | |||||
| local speed = player:getSpeed() | |||||
| -- Drawing | |||||
| love.graphics.setColor(1, 1, 1) | |||||
| love.graphics.printf(speed, 5, 45, width, "left") | |||||
| end | |||||
| function Gui:drawWarp() | |||||
| local warp = player.warpspeed | |||||
| love.graphics.setColor(1, 1, 1) | |||||
| love.graphics.printf("Warp Speed: x"..warp, 5, 5, width, "left") | |||||
| end | |||||
| function Gui:drawThrottle() | |||||
| local offset = 15 | |||||
| local border = 10 | |||||
| local w,h = 60, 140 | |||||
| local x, y = 0, height-h | |||||
| x, y = x+offset, y-offset | |||||
| -- Draw Border: | |||||
| local BDcol = 0.1 | |||||
| love.graphics.setColor(BDcol, BDcol, BDcol) | |||||
| love.graphics.rectangle("fill", x, y, w, h) | |||||
| x, y = x+border, y+border | |||||
| w, h = w-border*2, h-border*2 | |||||
| -- Draw Background: | |||||
| local BGcol = 0.4 | |||||
| love.graphics.setColor(BGcol, BGcol, BGcol) | |||||
| love.graphics.rectangle("fill", x, y, w, h) | |||||
| -- Draw Throttle: | |||||
| love.graphics.setColor(1, 1, 1) | |||||
| local change = h*player.throttle | |||||
| love.graphics.rectangle("fill", x, (y+h)-change, w, change) | |||||
| end | |||||
| -- MAIN | |||||
| function Gui:update(dt) | |||||
| end | |||||
| function Gui:draw() | |||||
| self:drawThrottle() | |||||
| self:drawWarp() | |||||
| self:drawSpeed() | |||||
| end | |||||
| @@ -0,0 +1,5 @@ | |||||
| Menubutton = Class {} | |||||
| function Menubutton:init(tempX, tempY, tempW, tempH) | |||||
| end | |||||
| @@ -0,0 +1,33 @@ | |||||
| Planet = Class {} | |||||
| function Planet:init(tempX, tempY, tempR, tempM, tempName, tempC) | |||||
| -- Planet Position | |||||
| self.x = tempX | |||||
| self.y = tempY | |||||
| -- Planet Radius and Mass | |||||
| self.r = tempR | |||||
| self.m = tempM | |||||
| -- Planet Data: | |||||
| self.name = tempName | |||||
| self.colour = tempC | |||||
| end | |||||
| -- FUNCTIONS | |||||
| -- MAIN | |||||
| function Planet:update(dt) | |||||
| end | |||||
| function Planet:draw() | |||||
| local col = self.colour | |||||
| love.graphics.setColor(calc.c(col[1]), calc.c(col[2]), calc.c(col[3])) | |||||
| love.graphics.circle("fill", self.x, self.y, self.r) | |||||
| end | |||||
| @@ -0,0 +1,227 @@ | |||||
| Player = Class {} | |||||
| function Player:init(tempX, tempY) | |||||
| -- Position: (variable) | |||||
| self.x = tempX | |||||
| self.y = tempY | |||||
| -- Starting Position: (constant) | |||||
| self.xStart = tempX | |||||
| self.yStart = tempY | |||||
| -- Speed: | |||||
| self.xSpeed = 0 | |||||
| self.ySpeed = 0 | |||||
| -- Speed Change: (throttle 0 - 1; variable) (speed; constant (max speed change)) | |||||
| self.throttle = 0.5 | |||||
| self.speed = 0.05 | |||||
| -- Time Warping: | |||||
| self.warpspeed = 1 | |||||
| self.warpLimit = 10 | |||||
| -- Cooldown Between Clicking: | |||||
| self.warpCoolDown = 30 | |||||
| self.coolDown = 0 | |||||
| -- Landings: | |||||
| self.impacttolerance = 0.5 | |||||
| self.landingspeed = 0 | |||||
| -- Mass: | |||||
| self.m = 1 | |||||
| end | |||||
| -- FUNCTIONS | |||||
| function Player:throttleControls() | |||||
| local change = 0.01 | |||||
| local max, min = 1, 0 | |||||
| -- Throttle up | |||||
| if love.keyboard.isDown(controls.flight.throttle.up) then | |||||
| self.throttle = self.throttle + change | |||||
| end | |||||
| -- Throttle down | |||||
| if love.keyboard.isDown(controls.flight.throttle.down) then | |||||
| self.throttle = self.throttle - change | |||||
| end | |||||
| -- Throttle max | |||||
| if love.keyboard.isDown(controls.flight.throttle.full) then | |||||
| self.throttle = max | |||||
| end | |||||
| -- Throttle None | |||||
| if love.keyboard.isDown(controls.flight.throttle.none) then | |||||
| self.throttle = min | |||||
| end | |||||
| -- Throttle Limiter: | |||||
| if self.throttle < 0 then | |||||
| self.throttle = 0 | |||||
| elseif self.throttle > 1 then | |||||
| self.throttle = 1 | |||||
| end | |||||
| end | |||||
| function Player:reset() | |||||
| self.x = self.xStart | |||||
| self.y = self.yStart | |||||
| self.xSpeed = 0 | |||||
| self.ySpeed = 0 | |||||
| end | |||||
| function Player:flightControls() | |||||
| -- Movement: | |||||
| local speedChange = self.speed * self.throttle | |||||
| -- Directional Thrust: | |||||
| if love.keyboard.isDown(controls.flight.thrust.up)then | |||||
| self.ySpeed = self.ySpeed - speedChange | |||||
| debug("Player control: up") | |||||
| end | |||||
| if love.keyboard.isDown(controls.flight.thrust.down) then | |||||
| self.ySpeed = self.ySpeed + speedChange | |||||
| debug("Player control: down") | |||||
| end | |||||
| if love.keyboard.isDown(controls.flight.thrust.left) then | |||||
| self.xSpeed = self.xSpeed - speedChange | |||||
| debug("Player control: left") | |||||
| end | |||||
| if love.keyboard.isDown(controls.flight.thrust.right) then | |||||
| self.xSpeed = self.xSpeed + speedChange | |||||
| debug("Player control: right") | |||||
| end | |||||
| -- Reset: | |||||
| if love.keyboard.isDown(controls.flight.reset) then | |||||
| self:reset() | |||||
| debug("Player control: reset") | |||||
| end | |||||
| end | |||||
| function Player:getSpeed() | |||||
| local x, y = self.xSpeed, self.ySpeed | |||||
| if x < 0 then | |||||
| x = -x | |||||
| end | |||||
| if y < 0 then | |||||
| y = -y | |||||
| end | |||||
| return x+y | |||||
| end | |||||
| function Player:isLanded() | |||||
| local landed = false | |||||
| for i=1, #planet do | |||||
| local pla = planet[i] | |||||
| if calc.distance(self.x, self.y, pla.x, pla.y) <= pla.r then | |||||
| landed = true | |||||
| end | |||||
| end | |||||
| -- Save Landing Speed: | |||||
| if landed then | |||||
| self.landingspeed = self:getSpeed() | |||||
| --debug("Landing speed: "..self.landingspeed) | |||||
| end | |||||
| return landed | |||||
| end | |||||
| function Player:gravity() | |||||
| if self:isLanded() then | |||||
| -- Player is landed: | |||||
| self.xSpeed, self.ySpeed = 0, 0 | |||||
| else | |||||
| -- Player is not landed: | |||||
| for i=1, #planet do | |||||
| local pla = planet[i] | |||||
| local grav = calc.gPull(self, pla) | |||||
| local dist = calc.distance(self.x, self.y, pla.x, pla.y) | |||||
| local pull = 20/dist * grav | |||||
| self.xSpeed = self.xSpeed + (pla.x - self.x)*pull | |||||
| self.ySpeed = self.ySpeed + (pla.y - self.y)*pull | |||||
| end | |||||
| end | |||||
| end | |||||
| function Player:timewarp() | |||||
| local step = 1 | |||||
| -- Time Warp Limits: | |||||
| local min = 1 | |||||
| local max = self.warpLimit | |||||
| -- Decrease Warp | |||||
| if love.keyboard.isDown(controls.flight.warp.down) and self.coolDown <= 0 then | |||||
| self.warpspeed = self.warpspeed - step | |||||
| self.coolDown = self.warpCoolDown | |||||
| end | |||||
| -- Increase Warp | |||||
| if love.keyboard.isDown(controls.flight.warp.up) and self.coolDown <= 0 then | |||||
| self.warpspeed = self.warpspeed + step | |||||
| self.coolDown = self.warpCoolDown | |||||
| end | |||||
| -- Reset Warp | |||||
| if love.keyboard.isDown(controls.flight.warp.reset) then | |||||
| self.warpspeed = min | |||||
| end | |||||
| -- Value Correction | |||||
| if self.warpspeed < min then | |||||
| self.warpspeed = min | |||||
| elseif self.warpspeed > max then | |||||
| self.warpspeed = max | |||||
| end | |||||
| return self.warpspeed | |||||
| end | |||||
| function Player:updatePosition() | |||||
| self.x = self.x + self.xSpeed | |||||
| self.y = self.y + self.ySpeed | |||||
| end | |||||
| -- MAIN | |||||
| function Player:update(dt) | |||||
| --debug(self.warpspeed) | |||||
| self:timewarp() | |||||
| for i=1, self.warpspeed do | |||||
| self:gravity() | |||||
| self:flightControls() | |||||
| self:updatePosition() | |||||
| end | |||||
| self:throttleControls() | |||||
| self.coolDown = self.coolDown - 1 | |||||
| end | |||||
| function Player:draw() | |||||
| local x, y = self.x, self.y | |||||
| local dist = 10 | |||||
| -- Funky arrow type form | |||||
| local vertices = { | |||||
| -- Top | |||||
| x, y-dist, | |||||
| -- Left Bottom | |||||
| x-dist, y+dist, | |||||
| -- Middle Down | |||||
| x, y+dist/2, | |||||
| -- Right Bottom | |||||
| x+dist, y+dist | |||||
| } | |||||
| love.graphics.setColor(0.5, 0.5, 0.7) | |||||
| love.graphics.polygon("fill", vertices) | |||||
| love.graphics.setColor(1, 0, 0) | |||||
| love.graphics.circle("fill", x, y, 5, 20) | |||||
| end | |||||
| @@ -0,0 +1 @@ | |||||
| default = love.graphics.setNewFont(20) | |||||
| @@ -0,0 +1,3 @@ | |||||
| texture = {} | |||||
| return texture | |||||