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