| @@ -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 | --0.9 VARIABLES | ||||
| wallsLoadError = false | |||||
| background = love.graphics.newImage('img/background.jpg') | background = love.graphics.newImage('img/background.jpg') | ||||
| bigship = love.graphics.newImage('img/large_red_01.png') | bigship = love.graphics.newImage('img/large_red_01.png') | ||||
| backgroundScroll = 0 | backgroundScroll = 0 | ||||
| @@ -196,6 +197,10 @@ function controlChanger() | |||||
| end | end | ||||
| end | end | ||||
| function love.load() | function love.load() | ||||
| walls = {} | |||||
| love.filesystem.createDirectory( "pong" ) | |||||
| print (love.filesystem.getSaveDirectory()) | |||||
| print (love.filesystem.getIdentity( )) | |||||
| love.graphics.setDefaultFilter('nearest', 'nearest') | love.graphics.setDefaultFilter('nearest', 'nearest') | ||||
| love.keyboard.setKeyRepeat(true) | love.keyboard.setKeyRepeat(true) | ||||
| @@ -211,7 +216,10 @@ function love.load() | |||||
| testwalls = love.filesystem.load("save.lua")() | testwalls = love.filesystem.load("save.lua")() | ||||
| if testwalls ~= nil then | if testwalls ~= nil then | ||||
| walls = love.filesystem.load("save.lua")() | walls = love.filesystem.load("save.lua")() | ||||
| end | |||||
| print("Save file found") | |||||
| else | |||||
| print("No save file found!") | |||||
| end | |||||
| light = 0 | light = 0 | ||||
| image = love.graphics.newImage("Madi.png") | image = love.graphics.newImage("Madi.png") | ||||
| @@ -360,6 +368,10 @@ function love.load() | |||||
| "L", | "L", | ||||
| function() | function() | ||||
| walls = love.filesystem.load("save.lua")() | walls = love.filesystem.load("save.lua")() | ||||
| if walls == nil then | |||||
| walls = {} | |||||
| wallsLoadError = true | |||||
| end | |||||
| end | end | ||||
| ) | ) | ||||
| ) | ) | ||||
| @@ -1797,6 +1809,10 @@ function love.draw(dt) | |||||
| end | end | ||||
| end | 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() | simpleScale.unSet() | ||||
| end | end | ||||
| @@ -5,6 +5,7 @@ ship = Class{} | |||||
| function ship:init() | function ship:init() | ||||
| self.y = 0 | |||||
| self.direction = love.math.random(0, 2) | self.direction = love.math.random(0, 2) | ||||
| if self.direction == 0 then | if self.direction == 0 then | ||||
| self.y = VIRTUAL_HEIGHT + 100 | self.y = VIRTUAL_HEIGHT + 100 | ||||
| @@ -67,7 +68,7 @@ end | |||||
| function ship:render() | function ship:render() | ||||
| if self.direction ~= 0 then | 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 | else | ||||
| love.graphics.draw(self.image, self.x, self.y) | love.graphics.draw(self.image, self.x, self.y) | ||||
| end | 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 | |||||