| @@ -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 | |||