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