| @@ -0,0 +1,46 @@ | |||
| --- TSerial v1.3, a simple table serializer which turns tables into Lua script | |||
| -- @author Taehl (SelfMadeSpirit@gmail.com) | |||
| TSerial = {} | |||
| --- Serializes a table into a string, in form of Lua script. | |||
| -- @param t table to be serialized (may not contain any circular reference) | |||
| -- @param drop if true, unserializable types will be silently dropped instead of raising errors | |||
| -- if drop is a function, it will be called to serialize unsupported types | |||
| -- @param indent if true, output "human readable" mode with newlines and indentation (for debug) | |||
| -- @return string recreating given table | |||
| function TSerial.pack(t, drop, indent) | |||
| assert(type(t) == "table", "Can only TSerial.pack tables.") | |||
| local s, indent = "{"..(indent and "\n" or ""), indent and math.max(type(indent)=="number" and indent or 0,0) | |||
| for k, v in pairs(t) do | |||
| local tk, tv, skip = type(k), type(v) | |||
| if tk == "boolean" then k = k and "[true]" or "[false]" | |||
| elseif tk == "string" then if string.format("%q",k) ~= '"'..k..'"' then k = '['..string.format("%q",k)..']' end | |||
| elseif tk == "number" then k = "["..k.."]" | |||
| elseif tk == "table" then k = "["..TSerial.pack(k, drop, indent and indent+1).."]" | |||
| elseif type(drop) == "function" then k = "["..string.format("%q",drop(k)).."]" | |||
| elseif drop then skip = true | |||
| else error("Attempted to TSerial.pack a table with an invalid key: "..tostring(k)) | |||
| end | |||
| if tv == "boolean" then v = v and "true" or "false" | |||
| elseif tv == "string" then v = string.format("%q", v) | |||
| elseif tv == "number" then -- no change needed | |||
| elseif tv == "table" then v = TSerial.pack(v, drop, indent and indent+1) | |||
| elseif type(drop) == "function" then v = "["..string.format("%q",drop(v)).."]" | |||
| elseif drop then skip = true | |||
| else error("Attempted to TSerial.pack a table with an invalid value: "..tostring(v)) | |||
| end | |||
| if not skip then s = s..string.rep("\t",indent or 0)..k.."="..v..","..(indent and "\n" or "") end | |||
| end | |||
| return s..string.rep("\t",(indent or 1)-1).."}" | |||
| end | |||
| --- Loads a table into memory from a string (like those output by Tserial.pack) | |||
| -- @param s a string of Lua defining a table, such as "{2,4,8,ex="ample"}" | |||
| -- @return a table recreated from the given string | |||
| function TSerial.unpack(s) | |||
| assert(type(s) == "string", "Can only TSerial.unpack strings.") | |||
| assert(loadstring("TSerial.table="..s))() | |||
| local t = TSerial.table | |||
| TSerial.table = nil | |||
| return t | |||
| end | |||
| @@ -25,6 +25,7 @@ showTouchControls = false | |||
| --0.9 VARIABLES | |||
| wallsLoadError = false | |||
| background = love.graphics.newImage('img/background.jpg') | |||
| bigship = love.graphics.newImage('img/large_red_01.png') | |||
| backgroundScroll = 0 | |||
| @@ -196,6 +197,10 @@ function controlChanger() | |||
| end | |||
| end | |||
| function love.load() | |||
| walls = {} | |||
| love.filesystem.createDirectory( "pong" ) | |||
| print (love.filesystem.getSaveDirectory()) | |||
| print (love.filesystem.getIdentity( )) | |||
| love.graphics.setDefaultFilter('nearest', 'nearest') | |||
| love.keyboard.setKeyRepeat(true) | |||
| @@ -211,7 +216,10 @@ function love.load() | |||
| testwalls = love.filesystem.load("save.lua")() | |||
| if testwalls ~= nil then | |||
| walls = love.filesystem.load("save.lua")() | |||
| end | |||
| print("Save file found") | |||
| else | |||
| print("No save file found!") | |||
| end | |||
| light = 0 | |||
| image = love.graphics.newImage("Madi.png") | |||
| @@ -360,6 +368,10 @@ function love.load() | |||
| "L", | |||
| function() | |||
| walls = love.filesystem.load("save.lua")() | |||
| if walls == nil then | |||
| walls = {} | |||
| wallsLoadError = true | |||
| end | |||
| end | |||
| ) | |||
| ) | |||
| @@ -1797,6 +1809,10 @@ function love.draw(dt) | |||
| end | |||
| end | |||
| end | |||
| if wallsLoadError then | |||
| love.graphics.setColor(1,0,0,1) | |||
| love.graphics.printf("Error loading map!", 0,0,VIRTUAL_WIDTH, "left") | |||
| end | |||
| simpleScale.unSet() | |||
| end | |||
| @@ -5,6 +5,7 @@ ship = Class{} | |||
| function ship:init() | |||
| self.y = 0 | |||
| self.direction = love.math.random(0, 2) | |||
| if self.direction == 0 then | |||
| self.y = VIRTUAL_HEIGHT + 100 | |||
| @@ -67,7 +68,7 @@ end | |||
| function ship:render() | |||
| if self.direction ~= 0 then | |||
| love.graphics.draw(self.image, self.x, self.y+self.height, 0, 1, -1) | |||
| love.graphics.draw(self.image, self.x, self.y + self.height, 0, 1, -1) | |||
| else | |||
| love.graphics.draw(self.image, self.x, self.y) | |||
| end | |||
| @@ -0,0 +1,170 @@ | |||
| function AI(target, ballCnt, diff) | |||
| currentTarget = evaluateClosestBall(target); | |||
| --print("CLOSEST TARGET IS " .. currentTarget) | |||
| if diff < 1200 then | |||
| --print ("Normal targeting ".. currentTarget .. " " .. target.x - ball[currentTarget].x .. " " .. ball[currentTarget].y - target.y) | |||
| if (ball[currentTarget].y - target.y >= target.height and math.abs(target.x - ball[currentTarget].x) < diff) then | |||
| target.dy = AI_SPEED | |||
| elseif (target.y - ball[currentTarget].y >= -target.height/2 and math.abs(target.x - ball[currentTarget].x) < diff) then | |||
| target.dy = -AI_SPEED | |||
| else | |||
| target.dy = 0 | |||
| end | |||
| else | |||
| --print("Complex targeting") | |||
| if target.x < 100 then | |||
| neededTarget = predictBall(ball[currentTarget], target.x) | |||
| --print(target.x .. " found " .. neededTarget) | |||
| if neededTarget ~= -1 then | |||
| --print("Calculated target = " .. neededTarget) | |||
| if (target.y + target.height/2 - neededTarget >= 15) then | |||
| target.dy = -AI_SPEED + (AI_SPEED - (target.y + target.height/2 - neededTarget)) | |||
| elseif (neededTarget - target.y >= target.height*0.9) then | |||
| target.dy = AI_SPEED - (AI_SPEED - (neededTarget - target.y)) | |||
| else | |||
| target.dy = 0 | |||
| end | |||
| end | |||
| else | |||
| neededTarget1 = predictBall(ball[currentTarget], target.x) | |||
| --print(target.x .. " found " .. neededTarget) | |||
| if neededTarget1 ~= -1 then | |||
| --print("Calculated target = " .. neededTarget) | |||
| if (target.y + target.height/2 - neededTarget1 >= 10) then | |||
| target.dy = -AI_SPEED + (AI_SPEED - (target.y + target.height/2 - neededTarget1)) | |||
| elseif (neededTarget1 - (target.y+target.height/2) >= 10) then | |||
| target.dy = AI_SPEED - (AI_SPEED - (neededTarget1 - target.y)) | |||
| else | |||
| target.dy = 0 | |||
| end | |||
| end | |||
| end | |||
| end | |||
| if | |||
| difficultyl == 350 and player2reverbav == true and VIRTUAL_WIDTH - ball[currentTarget].x < 90 and | |||
| math.abs(ball[currentTarget].y - targe.y) > 150 | |||
| then | |||
| sounds["time"]:play() | |||
| player2reverbav = false | |||
| timeIsSlow2 = true | |||
| originalPaddle = paddle_SPEED | |||
| originalSpeed = ballSpeed | |||
| player2reverbav = 0 | |||
| potentialnuke2 = 0 | |||
| potentialstrike2 = 0 | |||
| end | |||
| if (player2nukescore > AI_STRIKEMOD and striken == 0) then | |||
| player2striken = 1 | |||
| elseif (player2nukescore > AI_NUKEMOD and striken == 1) then | |||
| if (areanuclear == 1) then | |||
| maxspeed = maxspeed + 50 | |||
| end | |||
| sounds["nuke"]:play() | |||
| potentialstrike2 = 0 | |||
| areanuclear = 1 | |||
| ballSpeed = ballSpeed * 2 | |||
| if (synctype == 0) then | |||
| paddle_SPEED = paddle_SPEED * 2 | |||
| end | |||
| if (synctype == 1) then | |||
| paddle_SPEED = ballSpeed / 10 | |||
| end | |||
| if (synctype == 0) then | |||
| AI_SPEED = AI_SPEED * 2.2 | |||
| end | |||
| if (synctype == 1) then | |||
| AI_SPEED = ballSpeed * 1.1 / 10 | |||
| end | |||
| player2nukescore = 0 | |||
| player2reverbav = 0 | |||
| potentialnuke2 = 0 | |||
| end | |||
| end | |||
| function evaluateClosestBall(target) | |||
| local ans = 0 | |||
| local min = 99999; | |||
| for i = 1, maxBalls do | |||
| if math.abs(target.x - ball[i].x ) < min then | |||
| min = math.abs(target.x - ball[i].x) | |||
| ans = i | |||
| end | |||
| end | |||
| return ans | |||
| end | |||
| function predictBall(target, px) | |||
| --print("BALLSTATS:" .. target.x .. " " .. target.y) | |||
| if target.dx > 0 and px > 100 then | |||
| local ans = recursiveCalculations(px, target.x, target.y, target.dx, target.dy, 1) | |||
| return ans | |||
| elseif target.dx < 0 and px < 100 then | |||
| local ans = recursiveCalculations(px, target.x, target.y, target.dx, target.dy, 1) | |||
| return ans | |||
| else | |||
| --print("GO TO CENTER!!") | |||
| return VIRTUAL_HEIGHT/2 | |||
| end | |||
| end | |||
| function recursiveCalculations(px, ex, ey, edx, edy, ifspecial) | |||
| if (edy > 0) then | |||
| --print ("normal" .. ex .." " .. ey .. " " .. edx .. " " .. edy) | |||
| local time = (VIRTUAL_HEIGHT-40-ey) / (ballSpeed * edy) | |||
| local distance = math.abs(ballSpeed * edx) * time | |||
| --print("DOWNWARD" .. distance .. " " .. edx .. " " .. time .. " " .. math.abs(px-ex)) | |||
| if distance > math.abs(px - ex) then | |||
| --print("QQ") | |||
| local anstime = math.abs(px - ex) / math.abs(ballSpeed * edx) | |||
| local bonus = (ballSpeed * edy) * anstime | |||
| --print("results: " .. bonus .. " " .. edx .. " " .. anstime .. " " .. (px-ex)) | |||
| -- if (ifspecial == 0) then | |||
| local answer = ey + bonus | |||
| --love.window.setTitle(tostring(answer) .. "Basiccalc") | |||
| return ey + bonus | |||
| -- else | |||
| -- return -1 | |||
| --end | |||
| else | |||
| --print("SS") | |||
| local emulatedx = ex + distance * edx | |||
| local emulatedy = VIRTUAL_HEIGHT-40 | |||
| --print("EMULATED: " .. emulatedx .. " " .. emulatedy) | |||
| local answer = recursiveCalculations(px, emulatedx, emulatedy, edx, -edy, 0) | |||
| --print("GOT EMULATION RESULT AS " .. answer) | |||
| --love.window.setTitle(tostring(answer) .. "recursive calc bottom") | |||
| return answer | |||
| end | |||
| elseif edy == 0 then | |||
| return ey | |||
| else | |||
| --print ("inverse" .. ex .." " .. ey .. " " .. edx .. " " .. edy) | |||
| local time = (ey) / math.abs((ballSpeed * edy)) | |||
| local distance = math.abs(ballSpeed * edx) * time | |||
| --print("UPWARD" .. distance .. " " .. edx .. " " .. time .. " " .. math.abs(px-ex)) | |||
| --print("Why th efuck ") | |||
| if distance > math.abs(px - ex) then | |||
| local anstime = math.abs(px - ex) / math.abs(ballSpeed * edx) | |||
| local bonus = (ballSpeed * edy) * anstime | |||
| --print("results: " .. bonus .. " " .. edx .. " " .. anstime .. " " .. math.abs(px-ex)) | |||
| -- if (ifspecial == 0) then | |||
| local answer = ey + bonus | |||
| --love.window.setTitle(tostring(answer) .. "Basiccalc") | |||
| return answer | |||
| -- else | |||
| -- return -1 | |||
| -- end | |||
| else | |||
| local emulatedx = ex + distance * edx | |||
| local emulatedy = 0 | |||
| ----print("results: " .. bonus .. " " .. edx .. " " .. anstime .. " " .. (VIRTUAL_WIDTH-ex)) | |||
| local answer = recursiveCalculations(px, emulatedx, emulatedy, edx, -edy, 0) | |||
| --love.window.setTitle(tostring(answer) .. "recursivecalc") | |||
| return answer | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,5 @@ | |||
| VIRTUAL_WIDTH = 1280 | |||
| VIRTUAL_HEIGHT = 720 | |||
| WINDOW_WIDTH = 1280 | |||
| WINDOW_HEIGHT = 720 | |||
| isAndroid = true | |||
| @@ -0,0 +1,5 @@ | |||
| VIRTUAL_WIDTH = 1280 | |||
| VIRTUAL_HEIGHT = 720 | |||
| WINDOW_WIDTH = 1280 | |||
| WINDOW_HEIGHT = 720 | |||
| isAndroid = false | |||
| @@ -0,0 +1,20 @@ | |||
| Class = require 'class' | |||
| require 'paddle' | |||
| require 'simpleScale' | |||
| require 'TSerial' | |||
| require 'eball' | |||
| require 'fullScreener' | |||
| require 'superPowerControl' | |||
| require 'mainMenu' | |||
| require 'music' | |||
| require 'animator' | |||
| require 'src/baseGame' | |||
| require 'src/constantvars' | |||
| require 'src/menus' | |||
| require 'src/AI' | |||
| require 'src/reverseGame' | |||
| require 'explosion' | |||
| require 'ship' | |||
| tick = require 'tick' | |||
| utf8 = require("utf8") | |||
| serialize = require 'ser' | |||
| @@ -0,0 +1,3 @@ | |||
| function menumode() | |||
| dangerChecker() | |||
| end | |||
| @@ -0,0 +1,5 @@ | |||
| VIRTUAL_WIDTH = 1280 | |||
| VIRTUAL_HEIGHT = 720 | |||
| WINDOW_WIDTH = 1280 | |||
| WINDOW_HEIGHT = 720 | |||
| isAndroid = false | |||
| @@ -0,0 +1,15 @@ | |||
| function reversegame(dt) | |||
| player1.height = ballSpeed/2 | |||
| player2.height = ballSpeed/2 | |||
| if (player1.y < ball[1].y)then | |||
| player1.y = player1.y + ballSpeed/50 | |||
| elseif(player1.y > ball[1].y)then | |||
| player1.y = player1.y - ballSpeed/50 | |||
| end | |||
| if (player2.y < ball[1].y) then | |||
| player2.y = player2.y + ballSpeed/50 | |||
| elseif(player2.y > ball[1].y) then | |||
| player2.y = player2.y - ballSpeed/50 | |||
| end | |||
| end | |||
| @@ -0,0 +1,8 @@ | |||
| function powerControl(initiate, type) | |||
| if initiate == 1 and type == 'special' then | |||
| sounds["time"]:play() player1reverbav = false timeIsSlow = true originalSpeed = ballSpeed originalPaddle = paddle_SPEED player1reverbav = 0 potentialnuke1 = 0 potentialstrike1 = 0 | |||
| end | |||
| end | |||
| function powerUpdate() | |||
| end | |||
| @@ -0,0 +1,70 @@ | |||
| -- tick | |||
| -- https://github.com/bjornbytes/tick | |||
| -- MIT License | |||
| local tick = { | |||
| framerate = nil, | |||
| rate = .03, | |||
| timescale = 1, | |||
| sleep = .001, | |||
| dt = 0, | |||
| accum = 0, | |||
| tick = 1, | |||
| frame = 1 | |||
| } | |||
| local timer = love.timer | |||
| local graphics = love.graphics | |||
| love.run = function() | |||
| if not timer then | |||
| error('love.timer is required for tick') | |||
| end | |||
| if love.load then love.load(love.arg.parseGameArguments(arg), arg) end | |||
| timer.step() | |||
| local lastframe = 0 | |||
| love.update(0) | |||
| return function() | |||
| tick.dt = timer.step() * tick.timescale | |||
| tick.accum = tick.accum + tick.dt | |||
| while tick.accum >= tick.rate do | |||
| tick.accum = tick.accum - tick.rate | |||
| if love.event then | |||
| love.event.pump() | |||
| for name, a, b, c, d, e, f in love.event.poll() do | |||
| if name == 'quit' then | |||
| if not love.quit or not love.quit() then | |||
| return a or 0 | |||
| end | |||
| end | |||
| love.handlers[name](a, b, c, d, e, f) | |||
| end | |||
| end | |||
| tick.tick = tick.tick + 1 | |||
| if love.update then love.update(tick.rate) end | |||
| end | |||
| while tick.framerate and timer.getTime() - lastframe < 1 / tick.framerate do | |||
| timer.sleep(.0005) | |||
| end | |||
| lastframe = timer.getTime() | |||
| if graphics and graphics.isActive() then | |||
| graphics.origin() | |||
| graphics.clear(graphics.getBackgroundColor()) | |||
| tick.frame = tick.frame + 1 | |||
| if love.draw then love.draw() end | |||
| graphics.present() | |||
| end | |||
| timer.sleep(tick.sleep) | |||
| end | |||
| end | |||
| return tick | |||