@@ -1,46 +0,0 @@ | |||||
--- TSerial v1.3, a simple table serializer which turns tables into Lua script | |||||
TSerial = {} | |||||
--- Serializes a table into a string, in form of Lua script. | |||||
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) | |||||
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 |
@@ -17,6 +17,7 @@ function superanimator(type, param) | |||||
end | end | ||||
end | end | ||||
function staticanimatorcounter(dt) | function staticanimatorcounter(dt) | ||||
backgroundScroll = (backgroundScroll + background_scroll_speed * dt) % background_looping_point | |||||
if (gameState == 'animation') then | if (gameState == 'animation') then | ||||
time_1 = time_1 + dt | time_1 = time_1 + dt | ||||
light = 255 - time_1 * 85 | light = 255 - time_1 * 85 | ||||
@@ -50,7 +51,7 @@ function staticanimatorcounter(dt) | |||||
end | end | ||||
end | end | ||||
if player1animend then | if player1animend then | ||||
--print("DISEffect range: " .. diseffectRange[0]) | |||||
print("DISEffect range: " .. diseffectRange[0]) | |||||
diseffectRange[0] = diseffectRange[0] + dt*24 | diseffectRange[0] = diseffectRange[0] + dt*24 | ||||
if diseffectRange[0] > 50 then | if diseffectRange[0] > 50 then | ||||
effectRange[0] = 0 | effectRange[0] = 0 | ||||
@@ -67,7 +68,7 @@ function staticanimatorcounter(dt) | |||||
end | end | ||||
end | end | ||||
if player2animend then | if player2animend then | ||||
--print("DISEffect range: " .. diseffectRange[1]) | |||||
print("DISEffect range: " .. diseffectRange[1]) | |||||
diseffectRange[1] = diseffectRange[1] + dt*24 | diseffectRange[1] = diseffectRange[1] + dt*24 | ||||
if diseffectRange[1] > 50 then | if diseffectRange[1] > 50 then | ||||
effectRange[1] = 0 | effectRange[1] = 0 | ||||
@@ -78,22 +79,15 @@ function staticanimatorcounter(dt) | |||||
end | end | ||||
end | end | ||||
function staticanimator() | function staticanimator() | ||||
if player1anim then | |||||
love.graphics.setColor(140/255,70/255,70/255,1) | |||||
if player1anim or player1animend then | |||||
love.graphics.setColor(140/255,70/255,70/255,(50-diseffectRange[0])/100) | |||||
love.graphics.circle("fill", player1.x, player1.y , effectRange[0]*100, 100) | love.graphics.circle("fill", player1.x, player1.y , effectRange[0]*100, 100) | ||||
end | end | ||||
if player1animend then | |||||
love.graphics.setColor(40/255,40/255,40/255,1) | |||||
love.graphics.circle("fill", player1.x, player1.y , diseffectRange[0]*100, 100) | |||||
end | |||||
if player2anim then | |||||
love.graphics.setColor(70/255,70/255,140/255,1) | |||||
if player2anim or player2animend then | |||||
love.graphics.setColor(70/255,70/255,140/255,(50-diseffectRange[1])/100) | |||||
love.graphics.circle("fill", player2.x, player2.y , effectRange[1]*100, 100) | love.graphics.circle("fill", player2.x, player2.y , effectRange[1]*100, 100) | ||||
end | end | ||||
if player2animend then | |||||
love.graphics.setColor(40/255,40/255,40/255,1) | |||||
love.graphics.circle("fill", player2.x, player2.y , diseffectRange[1]*100, 100) | |||||
end | |||||
end | end | ||||
function animateExplosion(x, y, v, color) | function animateExplosion(x, y, v, color) | ||||
love.graphics.setColor(color) | love.graphics.setColor(color) | ||||
@@ -14,8 +14,6 @@ function eball:init(x, y, width, height) | |||||
end | end | ||||
function eball:collides(paddle) | function eball:collides(paddle) | ||||
if paddle.player == 2 and gameMode == 'practice' then return false | |||||
else | |||||
if self.x > paddle.x + paddle.width or paddle.x > self.x + self.width then | if self.x > paddle.x + paddle.width or paddle.x > self.x + self.width then | ||||
return false | return false | ||||
end | end | ||||
@@ -25,7 +23,6 @@ function eball:collides(paddle) | |||||
end | end | ||||
return true | return true | ||||
end | end | ||||
end | |||||
function eball:reset(ballnum, player) | function eball:reset(ballnum, player) | ||||
if (gameMode == 'practice') then | if (gameMode == 'practice') then | ||||
if (self.x < 1) then | if (self.x < 1) then | ||||
@@ -0,0 +1,519 @@ | |||||
--[===================================================================[-- | |||||
Copyright © 2016, 2018 Pedro Gimeno Fortea. All rights reserved. | |||||
Permission is hereby granted to everyone to copy and use this file, | |||||
for any purpose, in whole or in part, free of charge, provided this | |||||
single condition is met: The above copyright notice, together with | |||||
this permission grant and the disclaimer below, should be included | |||||
in all copies of this software or of a substantial portion of it. | |||||
THIS SOFTWARE COMES WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. | |||||
--]===================================================================]-- | |||||
-- GIF(sm) image decoder for the love2d framework, using LuaJIT + FFI. | |||||
-- Includes LZW decompression. | |||||
local ffi = require 'ffi' | |||||
local bit = require 'bit' | |||||
-- We have a "double buffer" coroutine-based consumer-producer system | |||||
-- requiring the consumer to not request large chunks at a time | |||||
-- otherwise the buffer would overflow (this is detected but it will | |||||
-- cause an assertion error). | |||||
local bytearray = ffi.typeof('uint8_t[?]') | |||||
local intarray = ffi.typeof('int[?]') | |||||
local int32ptr = ffi.typeof('int32_t *') | |||||
-- Interlaced mode table. Format: | |||||
-- {initial value for pass 1, increment for pass 1, | |||||
-- initial value for pass 2, increment for pass 2, ...} | |||||
local intertable = {0, 8, 4, 8, 2, 4, 1, 2, false} | |||||
-- Utility function for error propagation | |||||
local function coresume(co, ...) | |||||
local ok, err = coroutine.resume(co, ...) | |||||
if not ok then | |||||
error(err) | |||||
end | |||||
end | |||||
-- Consumer | |||||
local function gifread(self, length) | |||||
while self.ptr + length >= self.buflen do | |||||
coroutine.yield() -- wait for more input | |||||
end | |||||
local tmp = self.ptr | |||||
self.ptr = self.ptr + length | |||||
if tmp >= 24576 then -- this leaves 8192 as max read length (768 would probably suffice) | |||||
ffi.copy(self.buffer, self.buffer + tmp, self.buflen - tmp) | |||||
self.buflen = self.buflen - tmp | |||||
self.ptr = self.ptr - tmp | |||||
tmp = 0 | |||||
end | |||||
return tmp, length | |||||
end | |||||
-- Producer - prepare the data for the consumer | |||||
local function gifupdate(self, s) | |||||
if #s > 32768 then | |||||
-- Creating a Lua string object is an expensive operation. | |||||
-- Do it as seldom as possible. We split the input data | |||||
-- into 32K chunks. | |||||
for i = 1, #s, 32768 do | |||||
gifupdate(self, s:sub(i, i + 32767)) | |||||
end | |||||
return | |||||
end | |||||
if coroutine.status(self.decoder) == "dead" then | |||||
-- feeding data after the decoding is finished, ignore | |||||
return | |||||
end | |||||
assert(self.buflen <= 32768, "Buffer overflow") | |||||
ffi.copy(self.buffer + self.buflen, s, #s) | |||||
self.buflen = self.buflen + #s | |||||
coresume(self.decoder) | |||||
return self | |||||
end | |||||
local function gifdone(self) | |||||
-- free C memory immediately | |||||
self.buffer = false | |||||
return self | |||||
end | |||||
local function giferr(self, msg) | |||||
print(msg) | |||||
end | |||||
-- Gif decoding aux functions | |||||
local function gifpalette(palette, source, psize) | |||||
-- Read a palette, inserting alpha | |||||
for i = 0, psize - 1 do | |||||
palette[i*4] = source[i*3] | |||||
palette[i*4 + 1] = source[i*3 + 1] | |||||
palette[i*4 + 2] = source[i*3 + 2] | |||||
palette[i*4 + 3] = 255 | |||||
end | |||||
end | |||||
-- Gif decoder proper | |||||
local function gifdecoder(self) | |||||
-- Read file ID and header | |||||
local buffer = self.buffer | |||||
gifread(self, 13) | |||||
if ffi.string(self.buffer, 6) ~= 'GIF87a' | |||||
and ffi.string(self.buffer, 6) ~= 'GIF89a' | |||||
then | |||||
self:err('Invalid GIF file format') | |||||
return | |||||
end | |||||
self.width = buffer[6] + 256*buffer[7] | |||||
self.height = buffer[8] + 256*buffer[9] | |||||
local gpalettesize = buffer[10] >= 128 and bit.lshift(1, bit.band(buffer[10], 7) + 1) or 0 | |||||
local background = buffer[11] | |||||
self.aspect = ((buffer[12] == 0 and 49 or 0) + 15) / 64 | |||||
local gpalette = bytearray(256*4) | |||||
local lpalette = bytearray(256*4) | |||||
local lpalettesize | |||||
-- Read palette and set background | |||||
self.background = background -- default value | |||||
if gpalettesize > 0 then | |||||
gifread(self, gpalettesize * 3) | |||||
gifpalette(gpalette, buffer + 13, gpalettesize) | |||||
if background < gpalettesize then | |||||
self.background = {gpalette[background*4], gpalette[background*4+1], gpalette[background*4+2]} | |||||
end | |||||
end | |||||
local p | |||||
local GCE_trans = false | |||||
local GCE_dispose = 0 | |||||
local GCE_delay = 0 | |||||
-- Allocate the buffers in advance, to reuse them for every frame | |||||
local dict = bytearray(4096) | |||||
local dictptrs = intarray(4096) | |||||
local reversebuf = bytearray(4096) | |||||
repeat | |||||
-- Get block type | |||||
p = gifread(self, 1) | |||||
local blocktype = 0x3B | |||||
local blocklen | |||||
-- for simplicity (?), we fuse the block type and the extension type into | |||||
-- 'blocktype' | |||||
if buffer[p] == 0x2C then | |||||
-- Image block | |||||
blocktype = 0x2C | |||||
elseif buffer[p] == 0x21 then | |||||
-- Extension block | |||||
p = gifread(self, 1) | |||||
blocktype = buffer[p] | |||||
if blocktype == 0x2C then | |||||
-- there's no extension 2C - terminate | |||||
-- (avoids ambiguity with block type 2C) | |||||
blocktype = 0x3B | |||||
end | |||||
elseif buffer[p] ~= 0x3B then | |||||
self:err(string.format("Unknown block type: 0x%02X", buffer[p])) | |||||
break | |||||
end | |||||
if blocktype == 0x3B then | |||||
-- Trailer block or invalid block - terminate | |||||
break | |||||
elseif blocktype == 0xFF then | |||||
-- Application extension - may be loop, otherwise skip | |||||
p = gifread(self, 1) | |||||
blocklen = buffer[p] | |||||
p = gifread(self, blocklen + 1) | |||||
if blocklen >= 11 and ffi.string(buffer + p, 11) == 'NETSCAPE2.0' then | |||||
-- these *are* the androids we're looking for | |||||
p = p + blocklen | |||||
while buffer[p] ~= 0 do | |||||
local sblen = buffer[p] | |||||
p = gifread(self, sblen + 1) -- read also the next block length | |||||
if buffer[p] == 1 and sblen >= 3 then | |||||
-- looping subblock - that's for us | |||||
self.loop = buffer[p + 1] + 256 * buffer[p + 2] | |||||
end | |||||
p = p + sblen -- advance to next block | |||||
end | |||||
else | |||||
-- skip entire block | |||||
p = p + blocklen | |||||
while buffer[p] ~= 0 do | |||||
gifread(self, buffer[p]) | |||||
p = gifread(self, 1) | |||||
end | |||||
end | |||||
elseif blocktype == 0x01 or blocktype == 0xFE then | |||||
-- Text or Comment Extension - not processed by us, skip | |||||
p = gifread(self, 1) -- read length | |||||
if blocktype < 0x01 then | |||||
-- skip the block header (contains a length field) | |||||
p = gifread(self, buffer[p] + 1) + buffer[p] | |||||
-- the text extension "consumes" the GCE, so we clear it | |||||
GCE_trans = false | |||||
GCE_dispose = 0 | |||||
GCE_delay = 0 | |||||
end | |||||
while buffer[p] ~= 0 do | |||||
p = gifread(self, buffer[p] + 1) + buffer[p] | |||||
end | |||||
elseif blocktype == 0xF9 then | |||||
-- Graphic Control Extension | |||||
p = gifread(self, 1) | |||||
blocklen = buffer[p] | |||||
p = gifread(self, blocklen + 1) | |||||
if blocklen >= 4 then | |||||
GCE_delay = (buffer[p+1] + 256 * buffer[p+2]) / 100 | |||||
GCE_trans = bit.band(buffer[p], 1) ~= 0 and buffer[p + 3] | |||||
GCE_dispose = bit.rshift(bit.band(buffer[p], 0x1C), 2) | |||||
end | |||||
p = p + blocklen | |||||
while buffer[p] ~= 0 do | |||||
p = gifread(self, buffer[p] + 1) + buffer[p] | |||||
end | |||||
elseif blocktype == 0x2C then | |||||
-- Here be dragons | |||||
p = gifread(self, 9) | |||||
local x, y = buffer[p] + 256*buffer[p+1], buffer[p+2] + 256*buffer[p+3] | |||||
local w, h = buffer[p+4] + 256*buffer[p+5], buffer[p+6] + 256*buffer[p+7] | |||||
if w == 0 or h == 0 then | |||||
self:err('Zero size image') | |||||
break | |||||
end | |||||
local img = love.image.newImageData(w, h) | |||||
local dataptr = ffi.cast(int32ptr, img:getPointer()) | |||||
self.imgs[#self.imgs + 1] = GCE_dispose | |||||
self.imgs[#self.imgs + 1] = GCE_delay | |||||
self.imgs[#self.imgs + 1] = img | |||||
self.imgs[#self.imgs + 1] = x | |||||
self.imgs[#self.imgs + 1] = y | |||||
self.nimages = self.nimages + 1 | |||||
local flags = buffer[p+8] | |||||
if flags >= 128 then | |||||
-- Has local palette | |||||
lpalettesize = bit.lshift(1, bit.band(flags, 7) + 1) | |||||
p = gifread(self, lpalettesize*3) | |||||
gifpalette(lpalette, buffer + p, lpalettesize) | |||||
else | |||||
-- No local palette - copy the global palette to the local one | |||||
ffi.copy(lpalette, gpalette, gpalettesize*4) | |||||
lpalettesize = gpalettesize | |||||
end | |||||
if GCE_trans and GCE_trans < lpalettesize then | |||||
-- Clear alpha | |||||
lpalette[GCE_trans*4 + 3] = 0 | |||||
end | |||||
local interlace = bit.band(flags, 64) ~= 0 and 1 | |||||
-- LZW decoder. | |||||
-- This could really use another coroutine for | |||||
-- simplicity, as there's another producer/consumer, | |||||
-- but we won't go there. | |||||
p = gifread(self, 2) | |||||
local LZWsize = buffer[p] | |||||
p = p + 1 | |||||
if LZWsize == 0 or LZWsize > 11 then | |||||
self:err("Invalid code size") | |||||
break | |||||
end | |||||
local codebits = LZWsize + 1 | |||||
local clearcode = bit.lshift(1, LZWsize) -- End-of-stream is always clearcode+1 | |||||
local dictlen = clearcode + 2 | |||||
local bitstream, bitlen = 0, 0 | |||||
x, y = 0, 0 | |||||
local nextlenptr = p | |||||
local oldcode | |||||
local walkcode | |||||
local nrows = 0 -- counts vertical rows, used because interlacing makes the last y invalid | |||||
local row = 0 | |||||
repeat | |||||
-- Are there enough bits in curcode? Do we need to read more data? | |||||
if bitlen >= codebits and y then | |||||
-- Extract next code | |||||
local code = bit.band(bitstream, bit.lshift(1, codebits) - 1) | |||||
bitstream = bit.rshift(bitstream, codebits) | |||||
bitlen = bitlen - codebits | |||||
if code == clearcode then | |||||
codebits = LZWsize + 1 | |||||
dictlen = clearcode + 2 | |||||
oldcode = false | |||||
elseif code == clearcode + 1 then | |||||
if x ~= 0 or nrows ~= h then | |||||
self:err("Soft EOD before all rows were output") | |||||
end | |||||
-- signal end of processing | |||||
-- (further data won't be read, but we need to follow the blocks) | |||||
y = false | |||||
else | |||||
-- The dictionary is stored as a list of back pointers. | |||||
-- We need to reverse the order to output the entries. | |||||
-- We use a reverse buffer for that. | |||||
local reverseptr = 4095 | |||||
-- Is this code already in the table? | |||||
if code < dictlen then | |||||
-- Already in the table - get the string from the table | |||||
walkcode = code | |||||
while walkcode >= clearcode do | |||||
reversebuf[reverseptr] = dict[walkcode] | |||||
reverseptr = reverseptr - 1 | |||||
walkcode = dictptrs[walkcode] | |||||
end | |||||
reversebuf[reverseptr] = walkcode | |||||
-- Add to the table | |||||
if oldcode then | |||||
if dictlen < 4096 then | |||||
dictptrs[dictlen] = oldcode | |||||
dict[dictlen] = walkcode | |||||
dictlen = dictlen + 1 | |||||
if dictlen ~= 4096 and bit.band(dictlen, dictlen - 1) == 0 then | |||||
-- perfect power of two - increase code size | |||||
codebits = codebits + 1 | |||||
end | |||||
end | |||||
end | |||||
oldcode = code | |||||
else | |||||
-- Not in the table - deal with the special case | |||||
-- The compressor has created a new code, which must be the next | |||||
-- in sequence. We know what it must contain. | |||||
-- It must contain oldcode + first character of oldcode. | |||||
if code > dictlen or not oldcode or not walkcode then | |||||
self:err("Broken LZW") | |||||
break | |||||
end | |||||
-- Add to the table | |||||
if oldcode then | |||||
if dictlen < 4096 then | |||||
dictptrs[dictlen] = oldcode | |||||
dict[dictlen] = walkcode | |||||
dictlen = dictlen + 1 | |||||
if dictlen ~= 4096 and bit.band(dictlen, dictlen - 1) == 0 then | |||||
-- perfect power of two - increase code size | |||||
codebits = codebits + 1 | |||||
end | |||||
end | |||||
end | |||||
oldcode = code | |||||
walkcode = oldcode | |||||
while walkcode >= clearcode do | |||||
reversebuf[reverseptr] = dict[walkcode] | |||||
reverseptr = reverseptr - 1 | |||||
walkcode = dictptrs[walkcode] | |||||
end | |||||
reversebuf[reverseptr] = walkcode | |||||
end | |||||
if y then | |||||
for i = reverseptr, 4095 do | |||||
local c = reversebuf[i] | |||||
if c >= lpalettesize then c = 0 end | |||||
c = ffi.cast(int32ptr, lpalette)[c] | |||||
dataptr[x + row] = c | |||||
if interlace then | |||||
-- The passes 1, 2, 3, 4 correspond to the | |||||
-- values 1, 3, 5, 7 of 'interlace'. | |||||
if self.progressive and interlace < 7 and y + 1 < h then | |||||
-- In any pass but the last, there are at least 2 lines. | |||||
dataptr[x + row + w] = c | |||||
if interlace < 5 and y + 2 < h then | |||||
-- In the first two passes, there are at least 4 lines. | |||||
dataptr[x + row + w*2] = c | |||||
if y + 3 < h then | |||||
dataptr[x + row + w*3] = c | |||||
if interlace < 3 and y + 4 < h then | |||||
-- In the first pass there are 8 lines. | |||||
dataptr[x + row + w*4] = c | |||||
if y + 5 < h then | |||||
dataptr[x + row + w*5] = c | |||||
if y + 6 < h then | |||||
dataptr[x + row + w*6] = c | |||||
if y + 7 < h then | |||||
dataptr[x + row + w*7] = c | |||||
end | |||||
end | |||||
end | |||||
end | |||||
end | |||||
end | |||||
end | |||||
-- Advance pixel | |||||
x = x + 1 | |||||
if x >= w then | |||||
-- Skip to next interlaced row | |||||
x = 0 | |||||
nrows = nrows + 1 | |||||
y = y + intertable[interlace + 1] | |||||
if y >= h then | |||||
interlace = interlace + 2 | |||||
if interlace > 7 then | |||||
y = false | |||||
else | |||||
y = intertable[interlace] | |||||
end | |||||
end | |||||
if y then | |||||
row = y * w | |||||
end | |||||
end | |||||
else | |||||
-- No interlace, just increment y | |||||
x = x + 1 | |||||
if x >= w then | |||||
x = 0 | |||||
y = y + 1 | |||||
nrows = y | |||||
if y >= h then | |||||
y = false | |||||
else | |||||
row = y * w | |||||
end | |||||
end | |||||
end | |||||
end | |||||
else | |||||
-- This should not happen. | |||||
self:err('Data past the end of the image') | |||||
end | |||||
end | |||||
else | |||||
-- Not enough bits, grab 8 more | |||||
if p >= nextlenptr then | |||||
-- End of this subblock - read next subblock | |||||
assert(p == nextlenptr) | |||||
local sblen = buffer[nextlenptr] | |||||
if sblen == 0 then | |||||
-- no more data | |||||
if y then | |||||
self:err("Hard EOD before the end of the image") | |||||
end | |||||
break | |||||
end | |||||
p = gifread(self, sblen + 1) | |||||
nextlenptr = p + sblen | |||||
end | |||||
if y then | |||||
bitstream = bitstream + bit.lshift(buffer[p], bitlen) | |||||
bitlen = bitlen + 8 | |||||
p = p + 1 | |||||
else | |||||
-- end of data - fast forward to end of block | |||||
p = nextlenptr | |||||
end | |||||
end | |||||
until false | |||||
GCE_trans = false | |||||
GCE_dispose = 0 | |||||
GCE_delay = 0 | |||||
self.ncomplete = self.nimages | |||||
else | |||||
break | |||||
end | |||||
until false | |||||
end | |||||
local function gifframe(self, n) | |||||
n = (n-1) % self.nimages + 1 | |||||
return self.imgs[n*5-2], self.imgs[n*5-1], self.imgs[n*5], self.imgs[n*5-3], self.imgs[n*5-4] | |||||
end | |||||
local function gifnew(retver) | |||||
if retver == "version" then | |||||
return 0x010002 | |||||
-- else just ignore it and create the object | |||||
end | |||||
local self = { | |||||
update = gifupdate; | |||||
done = gifdone; | |||||
frame = gifframe; | |||||
err = giferr; | |||||
background = false; | |||||
width = false; | |||||
height = false; | |||||
imgs = {}; | |||||
nimages = 0; | |||||
ncomplete = 0; | |||||
buffer = bytearray(65536); | |||||
buflen = 0; | |||||
ptr = 0; | |||||
progressive = false; | |||||
loop = false; | |||||
aspect = false; | |||||
decoder = coroutine.create(gifdecoder); | |||||
} | |||||
-- pass self to the coroutine (will return immediately for lack of data) | |||||
coresume(self.decoder, self) | |||||
return self | |||||
end | |||||
return gifnew |
@@ -15,13 +15,28 @@ doubleclick1 = false | |||||
doubleclick2 = false | doubleclick2 = false | ||||
hold1 = false | hold1 = false | ||||
hold2 = false | hold2 = false | ||||
debug = true | |||||
debug = false | |||||
paused = false | paused = false | ||||
androidButtons = {} | androidButtons = {} | ||||
pauseButtons = {} | pauseButtons = {} | ||||
doneButtons = {} | doneButtons = {} | ||||
showTouchControls = false | showTouchControls = false | ||||
--GLOBAL VARIABLES | --GLOBAL VARIABLES | ||||
--0.9 VARIABLES | |||||
background = love.graphics.newImage('img/background.jpg') | |||||
bigship = love.graphics.newImage('img/large_red_01.png') | |||||
backgroundScroll = 0 | |||||
background_scroll_speed = 10 | |||||
background_looping_point = 810 | |||||
--END HERE | |||||
frameratecap = 1/60 | frameratecap = 1/60 | ||||
realtimer = 0 | realtimer = 0 | ||||
myip = "unknown" | myip = "unknown" | ||||
@@ -55,7 +70,7 @@ GREEN = 255 | |||||
IP = '45.76.95.31' | IP = '45.76.95.31' | ||||
IPnew = '45.76.95.31' | IPnew = '45.76.95.31' | ||||
BLUE = 255 | BLUE = 255 | ||||
updateTEXT = "Chalkboard Update" | |||||
updateTEXT = "Galaxy Update" | |||||
maxBalls = 1 | maxBalls = 1 | ||||
playerCount = 1 | playerCount = 1 | ||||
player1reverbav = 0 | player1reverbav = 0 | ||||
@@ -173,6 +188,7 @@ controlSettings = {} | |||||
modeSelectorButtons = {} | modeSelectorButtons = {} | ||||
pracdiff = {} | pracdiff = {} | ||||
playerCountButtons = {} | playerCountButtons = {} | ||||
ships = {} | |||||
function controlChanger() | function controlChanger() | ||||
if (gameState == "assign") then | if (gameState == "assign") then | ||||
love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255) | love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255) | ||||
@@ -180,6 +196,7 @@ function controlChanger() | |||||
end | end | ||||
end | end | ||||
function love.load() | function love.load() | ||||
love.graphics.setDefaultFilter('nearest', 'nearest') | |||||
love.keyboard.setKeyRepeat(true) | love.keyboard.setKeyRepeat(true) | ||||
tick.framerate = 60 | tick.framerate = 60 | ||||
@@ -855,6 +872,7 @@ function love.load() | |||||
-- resizable = true, | -- resizable = true, | ||||
-- vsync = true, | -- vsync = true, | ||||
--}) | --}) | ||||
love.window.setVSync( 0 ) | |||||
player1score = 0 | player1score = 0 | ||||
player2score = 0 | player2score = 0 | ||||
areanuclear = 0 | areanuclear = 0 | ||||
@@ -902,7 +920,8 @@ function love.load() | |||||
mymenu = mainMenu() | mymenu = mainMenu() | ||||
ballSpeed = 200 | ballSpeed = 200 | ||||
background_scroll_speed = ballSpeed / 20 | |||||
background_scroll_speed = ballSpeed / 20 | |||||
ballDX = math.random(2) == 1 and 100 or -100 | ballDX = math.random(2) == 1 and 100 or -100 | ||||
ballDY = math.random(-50, 50) | ballDY = math.random(-50, 50) | ||||
@@ -928,10 +947,13 @@ end | |||||
function speedControl() | function speedControl() | ||||
if (ballSpeed > maxspeed and gameState == "play") then | if (ballSpeed > maxspeed and gameState == "play") then | ||||
ballSpeed = maxspeed | ballSpeed = maxspeed | ||||
background_scroll_speed = ballSpeed / 20 | |||||
end | end | ||||
end | end | ||||
checking = 0 | |||||
function love.update(dt) | function love.update(dt) | ||||
--checking = checking + 1 | |||||
--print(checking) | |||||
--print("IMPORTANT!!!!!" .. globalState .. gameState) | --print("IMPORTANT!!!!!" .. globalState .. gameState) | ||||
for i, explosion in ipairs(explosions) do | for i, explosion in ipairs(explosions) do | ||||
explosion:update(dt) | explosion:update(dt) | ||||
@@ -944,7 +966,7 @@ function love.update(dt) | |||||
end | end | ||||
if debug then | if debug then | ||||
displayFPS() | displayFPS() | ||||
print(player2.y .. " " .. player2.goal .. " " .. player2.dy .. " " .. AI_SPEED .. " " .. paddle_SPEED .. " " .. lastSentKeyClient) | |||||
--print(player2.y .. " " .. player2.goal .. " " .. player2.dy .. " " .. AI_SPEED .. " " .. paddle_SPEED .. " " .. lastSentKeyClient) | |||||
end | end | ||||
if globalState == "base" and not paused then | if globalState == "base" and not paused then | ||||
basegame(dt) | basegame(dt) | ||||
@@ -1485,6 +1507,7 @@ function speedSetter(requesttype) | |||||
paddle_SPEED = paddle_SPEED + 5 | paddle_SPEED = paddle_SPEED + 5 | ||||
end | end | ||||
ballSpeed = ballSet | ballSpeed = ballSet | ||||
background_scroll_speed = ballSpeed / 20 | |||||
end | end | ||||
if (requesttype == "snc") then | if (requesttype == "snc") then | ||||
synctype = synctype + 1 | synctype = synctype + 1 | ||||
@@ -1525,10 +1548,12 @@ function speedSetter(requesttype) | |||||
synctext = "death is imminent" | synctext = "death is imminent" | ||||
end | end | ||||
ballSpeed = ballSet | ballSpeed = ballSet | ||||
background_scroll_speed = ballSpeed / 20 | |||||
end | end | ||||
if (requesttype == "practice") then | if (requesttype == "practice") then | ||||
if (ballSpeed > 999) then | if (ballSpeed > 999) then | ||||
ballSpeed = 200 | ballSpeed = 200 | ||||
background_scroll_speed = ballSpeed / 20 | |||||
ballSet = 200 | ballSet = 200 | ||||
end | end | ||||
if (ballSpeed > 799) then | if (ballSpeed > 799) then | ||||
@@ -1545,10 +1570,12 @@ function speedSetter(requesttype) | |||||
maxBalls = 3 | maxBalls = 3 | ||||
end | end | ||||
ballSpeed = ballSpeed + 200 | ballSpeed = ballSpeed + 200 | ||||
background_scroll_speed = ballSpeed / 20 | |||||
ballSet = ballSet + 200 | ballSet = ballSet + 200 | ||||
end | end | ||||
if (requesttype == "reset") then | if (requesttype == "reset") then | ||||
ballSpeed = 200 | ballSpeed = 200 | ||||
background_scroll_speed = ballSpeed / 20 | |||||
ballSet = 200 | ballSet = 200 | ||||
synctype = 0 | synctype = 0 | ||||
prtext = "Easy" | prtext = "Easy" | ||||
@@ -1943,6 +1970,7 @@ function resettinggenius() | |||||
player2.height = 100 | player2.height = 100 | ||||
ballSet = 200 | ballSet = 200 | ||||
ballSpeed = ballSet | ballSpeed = ballSet | ||||
background_scroll_speed = ballSpeed / 20 | |||||
player2.GREEN = 255 | player2.GREEN = 255 | ||||
player2.BLUE = 255 | player2.BLUE = 255 | ||||
player1.GREEN = 255 | player1.GREEN = 255 | ||||
@@ -2396,4 +2424,5 @@ function resetButtonX(arr) | |||||
for i, buttons in ipairs(arr) do | for i, buttons in ipairs(arr) do | ||||
buttons.x = 1290 | buttons.x = 1290 | ||||
end | end | ||||
end | |||||
end | |||||
@@ -71,7 +71,7 @@ function mainMenu:butt(gameState, VIRTUAL_WIDTH, VIRTUAL_HEIGHT, buttons, sounds | |||||
local total_height = (ev_BUTTON_HEIGHT + margin) * #buttons | local total_height = (ev_BUTTON_HEIGHT + margin) * #buttons | ||||
local ev_bx, ev_by | local ev_bx, ev_by | ||||
for i, button in ipairs(buttons) do | for i, button in ipairs(buttons) do | ||||
print("Button") | |||||
--print("Button") | |||||
button.last = button.now | button.last = button.now | ||||
ev_bx = button.x | ev_bx = button.x | ||||
if (location == 'control') then | if (location == 'control') then | ||||
@@ -0,0 +1,74 @@ | |||||
ship = Class{} | |||||
function ship:init() | |||||
self.direction = love.math.random(0, 2) | |||||
if self.direction == 0 then | |||||
self.y = VIRTUAL_HEIGHT + 100 | |||||
self.image = love.graphics.newImage('img/SPC/blue_0' .. love.math.random(1,6) .. '.png') | |||||
self.scroll = -1 * love.math.random(80, 120) - background_scroll_speed | |||||
else | |||||
self.y = -100 | |||||
self.image = love.graphics.newImage('img/SPC/red_0' .. love.math.random(1,6) .. '.png') | |||||
self.scroll = love.math.random(80, 120) - background_scroll_speed | |||||
end | |||||
self.x = love.math.random(40, VIRTUAL_WIDTH - 40) | |||||
self.width = self.image:getWidth() | |||||
self.height = self.image:getHeight() | |||||
self.destroyed = false | |||||
self.deathCounter = 0 | |||||
self.deathNumber = 1 | |||||
end | |||||
function ship:update(dt) | |||||
--print("Width " .. self.width .. " Height: " .. self.height) | |||||
if self.destroyed then | |||||
self:deathanimation(dt) | |||||
end | |||||
self.y = self.y + self.scroll * dt | |||||
--print("traveling at " .. self.y .. " " .. self.x) | |||||
for i, ball in pairs(ball) do | |||||
print("BALL IS AT: " .. ball.x .. " " .. ball.y) | |||||
print("I AM AT " .. self.x .. " " .. self.y) | |||||
if self:collides(ball) then | |||||
print("KABOOM") | |||||
self.destroyed = true | |||||
end | |||||
end | |||||
end | |||||
function ship:deathanimation(dt) | |||||
self.deathCounter = self.deathCounter + dt | |||||
if self.deathCounter > 0.1 and self.deathNumber < 12 then | |||||
self.image = love.graphics.newImage('img/SPC/Explosion/explosion-' .. self.deathNumber .. '.png') | |||||
self.deathCounter = 0 | |||||
self.deathNumber = self.deathNumber + 1 | |||||
end | |||||
end | |||||
function ship:collides(object) | |||||
if (object.y > self.y and object.y < self.y + self.height and | |||||
object.x > self.x and | |||||
object.x < self.x + self.width ) then | |||||
print("!!!!!!!!!!!!!" .. object.y .. " > " .. self.y .. " and " .. object.y .. " < " .. self.y + self.height .. " " .. object.x .. " > " .. self.x .. " and " .. object.x .. " < " .. self.x + self.width) | |||||
return true | |||||
else | |||||
return false | |||||
end | |||||
print("Shit detection") | |||||
end | |||||
function ship:render() | |||||
if self.direction ~= 0 then | |||||
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 | |||||
end |