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