| @@ -0,0 +1,94 @@ | |||
| --[[ | |||
| 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,6 @@ | |||
| rm game.love | |||
| rm game.zip | |||
| zip -r game * | |||
| mv game.zip game.love | |||
| love game.love | |||
| rm game.love | |||
| @@ -0,0 +1,24 @@ | |||
| edible = Class{} | |||
| function edible:init( y , x , fat ) | |||
| self.RED = 255 | |||
| self.GREEN = 255 | |||
| self.BLUE = 255 | |||
| self.x = x | |||
| self.y = y | |||
| self.width = fat | |||
| self.height = fat | |||
| self.fat = fat | |||
| self.dead = false | |||
| end | |||
| function edible:update(dt) | |||
| end | |||
| function edible:render() | |||
| love.graphics.setColor(self.fat*20/200, 0, 0, 1) | |||
| love.graphics.circle('line', self.x, self.y, self.fat) | |||
| love.graphics.setColor(255, 255, 255, 255) | |||
| end | |||
| @@ -0,0 +1,111 @@ | |||
| life = Class{} | |||
| function life:init( y , x , fat ) | |||
| self.RED = 255 | |||
| self.GREEN = 255 | |||
| self.BLUE = 255 | |||
| self.x = x | |||
| self.y = y | |||
| self.width = fat | |||
| self.height = fat | |||
| self.fat = fat | |||
| self.dead = false | |||
| self.multiplycounter = 1 | |||
| self.closest = 999999 | |||
| end | |||
| function life:update(dt) | |||
| if not self.dead then | |||
| if self.fat - self.width < -self.width*0.3 then | |||
| self.dead = true | |||
| end | |||
| self.fat = self.fat - self.width*0.0001*dt | |||
| if not self:checkIfEating() then | |||
| self:lookForFood(dt) | |||
| end | |||
| if self.width > 30 then | |||
| table.insert(bugs, life(self.y+self.width, self.x+self.width, self.fat/2)) | |||
| self.width = self.width/2 | |||
| self.fat = self.fat/2 | |||
| end | |||
| end | |||
| print(self.fat) | |||
| end | |||
| function life:lookForFood(dt) | |||
| self.closest = 9000000 | |||
| local sx, sy = self.x, self.y | |||
| print("looking for food...") | |||
| for i, food in ipairs(edibles) do | |||
| if math.sqrt((self.x - food.x)^2 + (self.y-food.y)^2) < self.closest then | |||
| self.closest = math.sqrt((self.x - food.x)^2 + (self.y-food.y)^2) | |||
| sx, sy = food.x, food.y | |||
| print("going to " .. i) | |||
| end | |||
| end | |||
| self:goTo(sx, sy, dt) | |||
| end | |||
| function life:goTo(x, y, dt) | |||
| self.speed = (10 + self.fat * 0.5 ) | |||
| if (x-self.x) ~= 0 then | |||
| self.m = (y-self.y)/(x-self.x) | |||
| if y-self.y > 0 then | |||
| self.m = math.abs(self.m) | |||
| elseif y-self.y < 0 and self.m > 0 then | |||
| self.m = -self.m | |||
| end | |||
| else | |||
| if y-self.y > 0 then | |||
| self.m = 1 | |||
| elseif y-self.y < 0 then | |||
| self.m = -1 | |||
| else | |||
| self.m = 0 | |||
| end | |||
| end | |||
| if self.m > 1 or self.m < -1 then | |||
| self.speed = math.abs(self.speed / (self.m)) | |||
| end | |||
| if (self.x < x) then | |||
| self.x = self.x + self.speed * dt | |||
| self.y = self.y + (self.speed* self.m * dt ) | |||
| print("go right" .. self.fat ..x .. " " ..y ) | |||
| elseif self.x > x then | |||
| self.x = self.x - self.speed* dt | |||
| self.y = self.y + (self.speed* self.m * dt ) | |||
| print("go left" .. self.fat ..x .. " " ..y) | |||
| else | |||
| self.y = self.y + (self.speed* self.m * dt ) | |||
| print("go vertical" .. self.fat ..x .. " " ..y) | |||
| end | |||
| --if (self.y < y) then | |||
| -- self.y = self.y + (10 * dt + self.fat * 0.5 * dt) | |||
| -- print("go down" .. self.fat) | |||
| --elseif self.y > y then | |||
| -- print("go up" .. self.fat) | |||
| -- self.y = self.y - (10 * dt + self.fat * 0.5 * dt) | |||
| --end | |||
| self.fat = self.fat - self.fat * self.width * 0.0003 * dt | |||
| print(self.m .. " " .. self.speed * self.m) | |||
| print((self.speed* self.m * dt )) | |||
| end | |||
| function life:checkIfEating() | |||
| for i, food in ipairs(edibles) do | |||
| if math.abs(self.x - food.x) < 10 and math.abs(self.y-food.y) < 10 then | |||
| self.fat = self.fat + food.fat | |||
| self.width = self.width + food.fat/2 | |||
| table.remove(edibles, i) | |||
| print("yum") | |||
| return true | |||
| end | |||
| end | |||
| return false | |||
| end | |||
| function life:render() | |||
| love.graphics.setColor(self.RED, self.GREEN, self.BLUE, self.fat*20/200) | |||
| love.graphics.circle('fill', self.x, self.y, self.width) | |||
| love.graphics.setColor(255, 255, 255, 255) | |||
| end | |||
| @@ -0,0 +1,50 @@ | |||
| VIRTUAL_WIDTH = 1280 | |||
| VIRTUAL_HEIGHT = 720 | |||
| WINDOW_WIDTH = 1280 | |||
| WINDOW_HEIGHT = 720 | |||
| Class = require 'class' | |||
| require 'simpleScale' | |||
| require 'life' | |||
| require 'edible' | |||
| bugs = {} | |||
| edibles = {} | |||
| function love.load() | |||
| math.randomseed(os.time()) | |||
| smallfont = love.graphics.newFont("font.ttf", 25) | |||
| love.keyboard.setKeyRepeat(true) | |||
| simpleScale.setWindow(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT) | |||
| table.insert(bugs, life(VIRTUAL_HEIGHT/2, VIRTUAL_WIDTH/2, 10)) | |||
| table.insert(edibles, edible(20, VIRTUAL_WIDTH/2+5, 4)) | |||
| end | |||
| function love.update(dt) | |||
| love.window.setTitle(#bugs) | |||
| for i, bug in ipairs(bugs) do | |||
| bug:update(dt) | |||
| end | |||
| regulator() | |||
| end | |||
| function regulator() | |||
| for i, bug in ipairs(bugs) do | |||
| if bug.dead then | |||
| table.insert(edibles, edible(bug.y, bug.x, bug.fat)) | |||
| table.remove(bugs, i) | |||
| end | |||
| end | |||
| if #edibles < #bugs/3 then | |||
| table.insert(edibles, edible(math.random(0, VIRTUAL_HEIGHT), math.random(0, VIRTUAL_WIDTH), 10)) | |||
| end | |||
| end | |||
| function love.draw() | |||
| simpleScale.set() | |||
| love.graphics.clear(0,0,0,1) | |||
| for i, bug in ipairs(bugs) do | |||
| bug:render(dt) | |||
| end | |||
| for i, edible in ipairs(edibles) do | |||
| edible:render(dt) | |||
| end | |||
| love.graphics.setColor(1,1,1,1) | |||
| love.graphics.setFont(smallfont) | |||
| simpleScale.unSet() | |||
| end | |||
| @@ -0,0 +1,7 @@ | |||
| # Kinda Life. | |||
| This is not a game, just a simulation I made because I had nothing better to do. Run in Lua, I guess you could use | |||
| ``` | |||
| ./debuggame.sh | |||
| ``` | |||
| Although idk | |||
| @@ -0,0 +1,123 @@ | |||
| simpleScale = {} | |||
| --Your Game's Aspect Ratio | |||
| local gAspectRatio | |||
| --The Window's Aspect Ratio | |||
| local wAspectRatio | |||
| --The scale between the game and the window's aspect ratio | |||
| simpleScale.scale = 1 | |||
| local xt, yt = 0, 0, 1 | |||
| local gameW, gameH, windowW, windowH = 800, 600, 800, 600 | |||
| -- Declares your game's width and height, and sets the window size/settings | |||
| -- To be used instead of love.window.setMode | |||
| -- [gw] and [gh] are the width and height of the initial game | |||
| -- [sw] and [sh] (optional) are the width and height of the final window | |||
| -- [settings] (optional) are settings for love.window.setMode | |||
| function simpleScale.setWindow(gw, gh, sw, sh, settings) | |||
| sw = sw or gw | |||
| sh = sh or gh | |||
| gAspectRatio = gw/gh | |||
| gameW = gw | |||
| gameH = gh | |||
| simpleScale.updateWindow(sw, sh, settings) | |||
| end | |||
| -- Updates the Window size/settings | |||
| -- To be used instead of love.window.setMode | |||
| -- [sw] and [sh] are the width and height of the new Window | |||
| -- [settings] (optional) are settings for love.window.setMode | |||
| function simpleScale.updateWindow(sw, sh, settings) | |||
| love.window.setMode(sw, sh, settings) | |||
| windowW, windowH = love.graphics.getWidth(), love.graphics.getHeight() | |||
| wAspectRatio = windowW/windowH | |||
| --Window aspect ratio is TALLER than game | |||
| if gAspectRatio > wAspectRatio then | |||
| scale = windowW/gameW | |||
| xt = 0 | |||
| yt = windowH/2 - (scale*gameH)/2 | |||
| --Window aspect ratio is WIDER than game | |||
| elseif gAspectRatio < wAspectRatio then | |||
| scale = windowH/gameH | |||
| xt = windowW/2 - (scale*gameW)/2 | |||
| yt = 0 | |||
| --Window and game aspect ratios are EQUAL | |||
| else | |||
| scale = windowW/gameW | |||
| xt = 0 | |||
| yt = 0 | |||
| end | |||
| simpleScale.scale = scale | |||
| end | |||
| -- If you screen is resizable on drag, you'll need to call this to make sure | |||
| -- the appropriate screen values stay updated | |||
| -- You can call it on love.update() with no trouble | |||
| function simpleScale.resizeUpdate() | |||
| windowW, windowH = love.graphics.getWidth(), love.graphics.getHeight() | |||
| wAspectRatio = windowW/windowH | |||
| --Window aspect ratio is TALLER than game | |||
| if gAspectRatio > wAspectRatio then | |||
| scale = windowW/gameW | |||
| xt = 0 | |||
| yt = windowH/2 - (scale*gameH)/2 | |||
| --Window aspect ratio is WIDER than game | |||
| elseif gAspectRatio < wAspectRatio then | |||
| scale = windowH/gameH | |||
| xt = windowW/2 - (scale*gameW)/2 | |||
| yt = 0 | |||
| --Window and game aspect ratios are EQUAL | |||
| else | |||
| scale = windowW/gameW | |||
| xt = 0 | |||
| yt = 0 | |||
| end | |||
| simpleScale.scale = scale | |||
| end | |||
| -- Transforms the game's window relative to the entire window | |||
| -- Call this at the beginning of love.draw() | |||
| function simpleScale.set() | |||
| love.graphics.push() | |||
| love.graphics.translate(xt, yt) | |||
| love.graphics.scale(scale, scale) | |||
| end | |||
| -- Untransforms the game's window | |||
| -- Call this at the end of love.draw | |||
| -- You can optionally make the letterboxes a specific color by passing | |||
| -- [color] (optional) a table of color values | |||
| function simpleScale.unSet(color) | |||
| love.graphics.scale(1/scale, 1/scale) | |||
| love.graphics.translate(-xt, -yt) | |||
| love.graphics.pop() | |||
| --Draw the Letterboxes | |||
| local r,g,b,a = love.graphics.getColor() | |||
| local originalColor = love.graphics.getColor() | |||
| local boxColor | |||
| if color == nil then | |||
| boxColor = {0,0,0} | |||
| else | |||
| boxColor = color | |||
| end | |||
| love.graphics.setColor(boxColor) | |||
| --Horizontal bars | |||
| if gAspectRatio > wAspectRatio then | |||
| love.graphics.rectangle("fill", 0, 0, windowW, math.abs((gameH*scale - (windowH))/2)) | |||
| love.graphics.rectangle("fill", 0, windowH, windowW, -math.abs((gameH*scale - (windowH))/2)) | |||
| --Vertical bars | |||
| elseif gAspectRatio < wAspectRatio then | |||
| love.graphics.rectangle("fill", 0, 0, math.abs((gameW*scale - (windowW))/2),windowH) | |||
| love.graphics.rectangle("fill", windowW, 0, -math.abs((gameW*scale - (windowW))/2),windowH) | |||
| end | |||
| love.graphics.setColor(r,g,b,a) | |||
| end | |||