Compare commits

..

39 Commits

Author SHA1 Message Date
5b4e4be005 - [NEW] Més gràfics
- [NEW] Retocs en habitacions
2026-03-26 17:46:32 +01:00
8b33e35114 - [FIX] Color mal ficat en algúns gifs
- [NEW] Més tiles
- [NEW] Habitacions al 53%
2026-03-26 13:21:27 +01:00
9c9092d19b - [NEW] Berserk implementat
- [NEW] Millorats detalls en habitacions
- [NEW] Habitacions al 44%
2026-03-25 13:42:30 +01:00
4e7a50879e - [NEW] Més tiles
- [FIX] L'heroi se clavaba en les pareds quan li pegaven
- [NEW] Alguns fondos enhancechats
- [FIX] Augmentada la velocitat de Nemesio
- [NEW] Shortcuts de teclat per a canviar de mode a l'editor
- [NEW] Habitacions al 40%
2026-03-24 19:01:32 +01:00
c1f5f92dae - [FIX] Ajustats alguns "edge cases" de algunes habitacions
- [FIX] Ajustada la diferència de cadència entre gotes
- [FIX] Ajustat el nivell de l'aigua, que fallaba l'ultima linia
2026-03-24 13:58:07 +01:00
cee6ade851 - [FIX] La rata no pasaba per un hueco de 8 pixels de alt
- [FIX] Al tornar de l'editor, resetejar hero.invisible
- [NEW] Habitacions al 38%
2026-03-24 13:36:20 +01:00
50f2710986 - [FIX] l'heroi podia clavar-se pel tile de dalt d'una corda 2026-03-24 13:11:48 +01:00
8853bca713 - [NEW] Un montó de tiles nous
- [FIX] No es podía botar des de la corda
- [NEW] Habitacions al 34%
2026-03-24 12:29:58 +01:00
af269366c2 - [NEW] Alguna habitació més i retocts en altres 2026-03-23 22:45:02 +01:00
a98a46a3d2 - [NEW] guardem una safe_pos al entrar en cada habitació
- [FIX] Al morir, o tornar al editor, se reseteja l'heroi
- [FIX] Ja no canvia d'habitació al asomar el cabet per dalt al botar
- [NEW] Més habitacions (21%)
2026-03-23 18:46:27 +01:00
130c5d62e1 - [WIP] Més habitacions 2026-03-23 14:01:54 +01:00
edd07509d0 - [NEW] Marcador millorat i funcionant 2026-03-23 13:02:38 +01:00
7090a6134f - [NEW] Quan li peguen, Morcus pega un botet cap enrere
- [NEW] Quan peguen a l'heroi, la momia i la rata peguen la volta
2026-03-23 12:17:05 +01:00
abb3e5e048 -[NEW] Retras aleatori per a les gotes
-[FIX] Arreglada representació gràfica de les gotes en l'editor
2026-03-23 11:51:56 +01:00
53aea81265 - [NEW] Gota 2026-03-23 08:14:37 +01:00
d5c0dfddeb -[NEW] Rata acabada 2026-03-22 10:24:13 +01:00
c02c086af3 -[NEW] Nemesio acabat 2026-03-22 09:51:41 +01:00
c4da64aa1f - [WIP] Implementant a Nemesio 2026-03-13 13:16:11 +01:00
a987fb330a - [NEW] Sucubo acabat i funcionant 2026-03-13 12:13:04 +01:00
88de5f262b - Reestructuració completa 2026-03-12 21:04:15 +01:00
6c5d7a305a - Primera pasada de reorganització 2026-03-12 17:30:56 +01:00
8f185fa47c -[NEW] Gràfics del súcubo, el guardian i la inevitable gota 2026-03-11 23:09:28 +01:00
eb32f13c66 No se que he tocat del mapa, commite per si de cas 2026-03-11 16:08:31 +01:00
b20420e4eb - [FIX] Habitacions ja existents arreglades al tamany actual.
- [NEW] Més tiles
2026-03-11 14:12:01 +01:00
dd72f182ba - [FIX] Encara que es tinga un item seleccionat, es pot treballar amb els items en pantalla 2026-03-11 12:55:54 +01:00
c1c022abb8 - [FIX] app.push() i app.pop() treballaven sobre mini.update, en compte de sobre app.update
- [FIX] tweening.update() ara es crida a nivell de aplicació
- [NEW] tilepicker i itempicker adequats al nou disseny/sistema
2026-03-11 12:52:35 +01:00
333d05dfac - [FIX] Al canviar d'habitació cap a baix se rallaba
- [FIX] Al pulsar la majoria de botons en el menu, fa la acció i tanca el menú automàticament
- [FIX] Ajustada la posició d'inici de l'heroi
- [FIX] Arreglat bug raro que quan pillaves una moneda algunes momies canviaven de direcció
- [WIP] Reajustant els tiles de les habitacions al nou tamany
2026-03-11 10:59:59 +01:00
40c3dcd6d0 - [FIX] msgbox arreglat i redissenyat
- [FIX] Quan està el menu fora s'inhabiliten els shortcuts en l'editor
- [NEW] Menu nou funcionant
2026-03-11 10:21:21 +01:00
de873a7a25 - [NEW] Redimensionades les habitacions per a ocupar tota la pantalla
- [FIX] Ajustada posició inici segons nou tamany de habitacions
- [FIX] Ajustat nivell de l'aigua segons nou tamany de habitacions
- [WIP] Treballant en el nou menú
2026-03-11 07:42:24 +01:00
9dcaaa0882 - [WIP] draft dels botons de l'editor 2026-03-10 14:04:09 +01:00
f3d85fd8ae - [FIX] Les "formiguetes" en les seleccions no es veïen
- [FIX] El item seleccionat per a posar no es veia
- [NEW] Al arrastrar un item, també te "formiguetes"
2026-03-10 11:19:23 +01:00
8226236f07 - [FIX] Al tornar al editor des del joc, recuperar la paleta normal
- [FIX] Quan no es pinta el fondo, que es veja un quadrejat, com el fondo "transparent" dels editor gràfics
- [FIX] Durant el joc totes les capes han de vores, independentment del marcat en l'editor
2026-03-10 10:33:38 +01:00
d398a03fe8 - [NEW] Més tiles 2026-03-09 14:02:00 +01:00
12b322ab6b - [NEW] Claus i portes funcionant 2026-03-09 13:46:51 +01:00
f2a52570b1 - [NEW] Torxes implementades 2026-03-09 12:15:58 +01:00
aa5f29ee24 - [NEW] Spsrite de foc a meitant fer 2026-03-08 22:29:07 +01:00
4575ca1316 - [FIX] Ajustat el offset de la llum de l'heroi
- [NEW] Animacions amb o sense loop
- [NEW] L'heroi perd energia al rebre colps i al final es mor
- [NEW] L'heroi cau a l'aigua i es mor directament
- [FIX] Al caure al aigua ja no pasa a l'habitació inexistent de baix
- [NEW] L'heroi parpadeja invulnerable després de rebre un colp
2026-03-04 14:03:48 +01:00
f6b99d7924 - [FIX] Si hi ha que ficar un offset en algun frame de animació, es fà des de la propia animació, no canviant la posició del personatge
- [NEW] rooms.reload()
- [FIX] Al tornar al editor, se recarrega tot de nou
- [NEW] Si se juga des de un mini de debug comença en l'editor. Si se juga des del mini normal comença en el joc.
2026-03-04 11:08:16 +01:00
8e5599506e - [NEW] Jump throttle, per a que no parega una taladradora quan te una paret sobre el cap 2026-03-04 10:20:35 +01:00
74 changed files with 2816 additions and 1756 deletions

View File

@@ -1,109 +0,0 @@
animations = {
["hero_stand"] = {
cycle = {1},
frames = {
{ frame={x=0,y=0,w=16,h=17}, wait=4 },
}
},
["hero_jump"] = {
cycle = {1},
frames = {
{ frame={x=32,y=0,w=16,h=17}, wait=4 },
}
},
["hero_walk"] = {
cycle = {1,2,1,3},
frames = {
{ frame={x=0,y=0,w=16,h=17}, wait=4 },
{ frame={x=16,y=0,w=16,h=17}, wait=4 },
{ frame={x=32,y=0,w=16,h=17}, wait=4 }
}
},
["hero_stairs_idle"] = {
cycle = {1},
frames = {
{ frame={x=48,y=0,w=16,h=17}, wait=4 }
}
},
["hero_stairs"] = {
cycle = {1,2},
frames = {
{ frame={x=48,y=0,w=16,h=17}, wait=4 },
{ frame={x=48,y=0,w=16,h=17}, wait=4, reversed=true }
}
},
["hero_shoot"] = {
cycle = {1,2,3},
frames = {
{ frame={x=64,y=0,w=24,h=17}, wait=4 },
{ frame={x=88,y=0,w=24,h=17}, wait=2 },
{ frame={x=88,y=0,w=24,h=17}, wait=2 }
}
},
["bullet"] = {
cycle = {1},
frames = {
{ frame={x=156,y=0,w=4,h=3}, wait=4 }
}
},
["mummy_walk"] = {
cycle = {1,2,1,3},
frames = {
{ frame={x=0,y=0,w=16,h=16}, wait=4 },
{ frame={x=16,y=0,w=16,h=16}, wait=4 },
{ frame={x=32,y=0,w=16,h=16}, wait=4 }
}
},
["mummy_dying"] = {
cycle = {1,2,3,4,5,6,7,6},
frames = {
{ frame={x=48,y=0,w=16,h=16}, wait=2 },
{ frame={x=64,y=0,w=16,h=16}, wait=2 },
{ frame={x=80,y=0,w=16,h=16}, wait=2 },
{ frame={x=96,y=0,w=16,h=16}, wait=2 },
{ frame={x=112,y=0,w=16,h=16}, wait=2 },
{ frame={x=128,y=0,w=16,h=16}, wait=4 },
{ frame={x=144,y=0,w=16,h=16}, wait=2 }
}
},
["mummy_dead"] = {
cycle = {1},
frames = {
{ frame={x=128,y=0,w=16,h=16}, wait=100 },
}
},
["mummy_undying"] = {
cycle = {7,6,7,6,7,6,7,6,5,4,3,2,1},
frames = {
{ frame={x=48,y=0,w=16,h=16}, wait=2 },
{ frame={x=64,y=0,w=16,h=16}, wait=2 },
{ frame={x=80,y=0,w=16,h=16}, wait=2 },
{ frame={x=96,y=0,w=16,h=16}, wait=2 },
{ frame={x=112,y=0,w=16,h=16}, wait=2 },
{ frame={x=128,y=0,w=16,h=16}, wait=1 },
{ frame={x=160,y=0,w=16,h=16}, wait=1 }
}
},
["coin"] = {
cycle = {1,2,3,4,3,2},
frames = {
{ frame={x=0,y=0,w=8,h=8}, wait=2 },
{ frame={x=8,y=0,w=8,h=8}, wait=2 },
{ frame={x=16,y=0,w=8,h=8}, wait=2 },
{ frame={x=24,y=0,w=8,h=8}, wait=2 }
}
},
["coin_picked"] = {
cycle = {1},
frames = {
{ frame={x=32,y=0,w=13,h=7}, wait=100 },
}
},
["brick"] = {
cycle = {1},
frames = {
{ frame={x=48,y=0,w=8,h=8}, wait=100 },
}
},
}

View File

@@ -1,16 +0,0 @@
app = {
update = nil,
stack = {},
push = function(func)
table.insert(app.stack, mini.update)
mini.update = func
end,
pop = function()
if #app.stack > 0 then
mini.update = table.remove(app.stack)
end
end,
}

View File

@@ -1,363 +0,0 @@
local separators = " ()[],-+*/=<>"
local function split_by_last_separator(s)
for i = #s, 1, -1 do
local c = s:sub(i, i)
if separators:find(c, 1, true) then
if i == #s then
-- Separador al final
return s, ""
end
-- Separador en medio
return s:sub(1, i), s:sub(i + 1)
end
end
-- Sin separadores
return "", s
end
local function split_by_last_dot(s)
local last = s:match(".*()%.") -- devuelve la posición DESPUÉS del último punto
if not last then
-- No hay puntos: primera parte = cadena completa, segunda = ""
return "", s
end
-- Si el punto está al final, la segunda parte es ""
if last > #s then
return s, ""
end
-- Primera parte incluye el punto
local first = s:sub(1, last - 1)
local second = s:sub(last+1)
return first, second
end
function get_by_path(path)
local current = _G
for segment in path:gmatch("[^%.]+") do
if type(current) ~= "table" then
return nil
end
current = current[segment]
if current == nil then
--print("get_by_path: " ..segment.." es nil")
return nil
end
end
--print("get_by_path: ok")
return current
end
function entries_starting_with(s, t)
if not t then return nil end
local result = {}
for k, v in pairs(t) do
if type(k) == "string" and k:sub(1, #s) == s then
result[#result+1] = k
end
end
return result
end
console = {
command = "",
history = {},
history_pos = 0,
cursor = 50,
autocomplete_list = {},
autocomplete_prefix = "",
autocomplete_index = 1,
enable = function()
app.push(console.update)
console.command = ""
end,
update = function()
surf.target(0)
draw.rrectf(0, 92, 160, 108, 4, 1)
draw.rrect(0, 92, 160, 108, 4, 13)
draw.text(">", 2, 96, 13)
draw.text(console.command, 6, 96, 13)
if console.autocomplete_list and #console.autocomplete_list>0 then
--local num = math.min(5, #console.autocomplete_list)
--local base_y = 92-num*7
--draw.rectf(3+#console.command*4, base_y, 80, num*7, 1)
--draw.rect(3+#console.command*4, base_y, 80, num*7, 13)
--for i=1,num do
-- draw.text(console.autocomplete_list[i], 6+#console.command*4, base_y+i*7, 13)
--end
local sufix = console.autocomplete_list[console.autocomplete_index]:sub(#console.autocomplete_prefix+1)
draw.text(sufix, 6+#console.command*4, 96, 6)
end
if console.cursor > 24 then
draw.text("_", 6+#console.command*4, 96, 13)
end
console.cursor = console.cursor - 1
if console.cursor == 0 then console.cursor = 50 end
if key.press(key.ESCAPE) then
app.pop()
return
end
local should_update = false
if #console.history>0 then
if key.press(key.UP) and console.history_pos > 1 then
console.history_pos = console.history_pos - 1
console.command = console.history[console.history_pos]
should_update = true
elseif key.press(key.DOWN) and console.history_pos < #console.history then
console.history_pos = console.history_pos + 1
console.command = console.history[console.history_pos]
should_update = true
end
end
local k = key.press()
if k ~= key.UNKNOWN then
should_update = true
if k >= key.A and k <= key.Z then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. string.char(k+61)
else
console.command = console.command .. string.char(k+93)
end
elseif k == key.N0 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '='
elseif key.down(key.RALT) then
console.command = console.command .. '}'
else
console.command = console.command .. '0'
end
elseif k == key.N1 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '!'
elseif key.down(key.RALT) then
console.command = console.command .. '|'
else
console.command = console.command .. '1'
end
elseif k == key.N2 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '"'
elseif key.down(key.RALT) then
console.command = console.command .. '@'
else
console.command = console.command .. '2'
end
elseif k == key.N3 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '·'
elseif key.down(key.RALT) then
console.command = console.command .. '#'
else
console.command = console.command .. '3'
end
elseif k == key.N4 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '$'
elseif key.down(key.RALT) then
console.command = console.command .. '~'
else
console.command = console.command .. '4'
end
elseif k == key.N5 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '%'
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. '5'
end
elseif k == key.N6 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '&'
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. '6'
end
elseif k == key.N7 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '/'
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. '7'
end
elseif k == key.N8 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '('
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. '8'
end
elseif k == key.N9 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. ')'
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. '9'
end
elseif k == key.PERIOD then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. ':'
else
console.command = console.command .. '.'
end
elseif k == key.COMMA then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. ';'
else
console.command = console.command .. ','
end
elseif k == key.GRAVE then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. ' '
elseif key.down(key.RALT) then
console.command = console.command .. '\\'
else
console.command = console.command .. ' '
end
elseif k == key.EQUALS then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '¿'
else
console.command = console.command .. '¡'
end
elseif k == key.SLASH then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '_'
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. '-'
end
elseif k == key.APOSTROPHE then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '"'
elseif key.down(key.RALT) then
console.command = console.command .. '{'
else
console.command = console.command .. '\''
end
elseif k == key.SEMICOLON then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. 'Ñ'
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. 'ñ'
end
elseif k == key.BACKSLASH then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. 'Ç'
elseif key.down(key.RALT) then
console.command = console.command .. '}'
else
console.command = console.command .. 'ç'
end
elseif k == key.RIGHTBRACKET then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '*'
elseif key.down(key.RALT) then
console.command = console.command .. ']'
else
console.command = console.command .. '+'
end
elseif k == key.LEFTBRACKET then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '^'
elseif key.down(key.RALT) then
console.command = console.command .. '['
else
console.command = console.command .. '`'
end
elseif k == key.NONUSBACKSLASH then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '>'
elseif key.down(key.RALT) then
console.command = console.command .. ' '
else
console.command = console.command .. '<'
end
elseif k == key.MINUS then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
console.command = console.command .. '?'
else
console.command = console.command .. '\''
end
elseif k == key.SPACE then
console.command = console.command .. ' '
elseif k == key.BACKSPACE then
console.command = console.command:sub(1, #console.command - 1)
elseif k == key.TAB then
local sufix = console.autocomplete_list[console.autocomplete_index]:sub(#console.autocomplete_prefix+1)
console.command = console.command .. sufix
elseif k == key.RETURN then
table.insert(console.history, console.command)
console.history_pos = #console.history+1
local f,err = load(console.command)
if not f then
print("Error al compilar:", err)
else
print(f())
app.pop()
end
end
end
if should_update then
local a, b = split_by_last_separator(console.command)
if b ~= "" then
local ba, bb = split_by_last_dot(b)
console.autocomplete_prefix = bb
if ba ~= "" then
console.autocomplete_list = entries_starting_with(bb, get_by_path(ba))
--print(bb..":"..ba)
--print(#console.autocomplete_list)
else
console.autocomplete_list = entries_starting_with(bb, _G)
--print(bb..":".."golbal")
--print(#console.autocomplete_list)
end
else
console.autocomplete_prefix = ""
console.autocomplete_list = entries_starting_with("", _G)
--print("<buit>"..":".."golbal")
--print(#console.autocomplete_list)
end
end
end,
}

BIN
data/gfx/abad.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

BIN
data/gfx/berserk.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

BIN
data/gfx/blava.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

BIN
data/gfx/gota.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

BIN
data/gfx/groga.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

BIN
data/gfx/misc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 826 B

After

Width:  |  Height:  |  Size: 826 B

View File

Before

Width:  |  Height:  |  Size: 654 B

After

Width:  |  Height:  |  Size: 654 B

BIN
data/gfx/nemesio.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

BIN
data/gfx/paku.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

BIN
data/gfx/rata.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

BIN
data/gfx/roja.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

11
data/gfx/score_font.fnt Normal file
View File

@@ -0,0 +1,11 @@
bitmap=gfx/score_font.gif
48: 0 0 8 8 0 # 0
49: 8 0 8 8 0 # 1
50: 16 0 8 8 0 # 2
51: 24 0 8 8 0 # 3
52: 32 0 8 8 0 # 4
53: 40 0 8 8 0 # 5
54: 48 0 8 8 0 # 6
55: 56 0 8 8 0 # 7
56: 64 0 8 8 0 # 8
57: 72 0 8 8 0 # 9

BIN
data/gfx/score_font.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

BIN
data/gfx/sprites.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
data/gfx/sucubo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

BIN
data/gfx/tiles.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
data/gfx/torxa.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

BIN
data/gfx/verda.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

View File

@@ -1,10 +0,0 @@
items = {
[1] = {
name="mummy",
visual = {x=0,y=24,w=16,h=16}
},
[2] = {
name="coin",
visual = {x=0,y=40,w=8,h=8}
}
}

View File

@@ -1,17 +1,17 @@
require "app" require "utils.app"
require "score" require "modules.score"
require "rooms" require "modules.rooms"
require "editor" require "stages.editor"
require "game" require "stages.game"
require "palfade" require "utils.palfade"
function reload_textures() function reload_textures()
if surf_sprites then surf.free(surf_sprites) end if surf_sprites then surf.free(surf_sprites) end
surf_sprites = surf.load("sprites.gif") surf_sprites = surf.load("gfx/sprites.gif")
if surf_tiles then surf.free(surf_tiles) end if surf_tiles then surf.free(surf_tiles) end
surf_tiles = surf.load("tiles.gif") surf_tiles = surf.load("gfx/tiles.gif")
palfade.original = pal.load("tiles.gif") palfade.original = pal.load("gfx/tiles.gif")
pal.set(palfade.original) pal.set(palfade.original)
end end
@@ -21,11 +21,16 @@ function mini.init()
rooms.init() rooms.init()
shader.init("lynx.glsl") shader.init("lynx.glsl")
editor.enable() if sys.debug() then
editor.enable()
else
game.enable()
end
sprites.add_from_room(rooms.pos.x, rooms.pos.y) sprites.add_from_room(rooms.pos.x, rooms.pos.y)
end end
function mini.update() function mini.update()
tweening.update(sys.delta())
app.update() app.update()
end end

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,56 +0,0 @@
require "popup"
menu = {
current_x = 0,
init = function()
end,
draw = function()
view.origin(0,0)
view.clip()
draw.rectf(0,0,160,7,23)
draw.hline(0,7,160,16)
menu.current_x = 1
menu.option("FILE")
popup.create("FILE", 1, 8)
popup.addOption("FILE", "Play", editor.play)
popup.addOption("FILE", "Save", function() rooms.save() editor.modified=false end)
popup.addOption("FILE", "Quit", editor.quit)
menu.option("VIEW")
popup.create("VIEW", 1, 8)
popup.addOption("VIEW", "Background", function() rooms.toggle_visibility(LAYER_BACKGROUND) end)
popup.addOption("VIEW", "Shadows", function() rooms.toggle_visibility(LAYER_SHADOWS) end)
popup.addOption("VIEW", "Foreground", function() rooms.toggle_visibility(LAYER_FOREGROUND) end)
popup.addOption("VIEW", "Sprites", function() rooms.toggle_visibility(LAYER_SPRITES) end)
menu.option("EDIT")
popup.create("EDIT", 1, 8)
popup.addOption("EDIT", "Background", function() editor.layer=LAYER_BACKGROUND end)
popup.addOption("EDIT", "Foreground", function() editor.layer=LAYER_FOREGROUND end)
popup.addOption("EDIT", "Items", function() editor.layer=LAYER_ITEMS end)
--popup.addOption("EDIT", "Sprites", function() rooms.toggle_visibility(LAYER_SPRITES) end)
menu.option("TOOLS")
if editor.modified then
draw.text("*",160-5,1,8)
end
end,
option = function(label)
local next_x = menu.current_x + (#label + 2)*4
local mx, my = mouse.pos()
if my < 8 and mx >= menu.current_x and mx < next_x then
draw.rectf(menu.current_x, 0, next_x-menu.current_x, 7, 21)
if mouse.down(mouse.LEFT) then
mouse.discard()
popup.show(label)
end
end
draw.text(label,menu.current_x+4,1,28)
menu.current_x = next_x
end
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

243
data/modules/animations.lua Normal file
View File

@@ -0,0 +1,243 @@
animations = {
["hero_stand"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=0,y=0,w=16,h=17}, wait=4 },
}
},
["hero_jump"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=32,y=0,w=16,h=17}, wait=4 },
}
},
["hero_walk"] = {
cycle = {1,2,1,3},
loop = true,
frames = {
{ frame={x=0,y=0,w=16,h=17}, wait=4 },
{ frame={x=16,y=0,w=16,h=17}, wait=4 },
{ frame={x=32,y=0,w=16,h=17}, wait=4 }
}
},
["hero_stairs_idle"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=48,y=0,w=16,h=17}, wait=4 }
}
},
["hero_stairs"] = {
cycle = {1,2},
loop = true,
frames = {
{ frame={x=48,y=0,w=16,h=17}, wait=4 },
{ frame={x=48,y=0,w=16,h=17}, wait=4, reversed=true }
}
},
["hero_shoot"] = {
cycle = {1,2,3},
loop = false,
frames = {
{ frame={x=64,y=0,w=24,h=17}, offset={flipped={x=-8,y=0}}, wait=4 },
{ frame={x=88,y=0,w=24,h=17}, offset={flipped={x=-8,y=0}}, wait=2 },
{ frame={x=88,y=0,w=24,h=17}, offset={flipped={x=-8,y=0}}, wait=2 }
}
},
["bullet"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=156,y=0,w=4,h=3}, wait=4 }
}
},
["mummy_walk"] = {
cycle = {1,2,1,3},
loop = true,
frames = {
{ frame={x=0,y=0,w=16,h=16}, wait=4 },
{ frame={x=16,y=0,w=16,h=16}, wait=4 },
{ frame={x=32,y=0,w=16,h=16}, wait=4 }
}
},
["mummy_dying"] = {
cycle = {1,2,3,4,5,6,7,6},
loop = false,
frames = {
{ frame={x=48,y=0,w=16,h=16}, wait=2 },
{ frame={x=64,y=0,w=16,h=16}, wait=2 },
{ frame={x=80,y=0,w=16,h=16}, wait=2 },
{ frame={x=96,y=0,w=16,h=16}, wait=2 },
{ frame={x=112,y=0,w=16,h=16}, wait=2 },
{ frame={x=128,y=0,w=16,h=16}, wait=4 },
{ frame={x=144,y=0,w=16,h=16}, wait=2 }
}
},
["mummy_dead"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=128,y=0,w=16,h=16}, wait=100 },
}
},
["mummy_undying"] = {
cycle = {7,6,7,6,7,6,7,6,5,4,3,2,1},
loop = false,
frames = {
{ frame={x=48,y=0,w=16,h=16}, wait=2 },
{ frame={x=64,y=0,w=16,h=16}, wait=2 },
{ frame={x=80,y=0,w=16,h=16}, wait=2 },
{ frame={x=96,y=0,w=16,h=16}, wait=2 },
{ frame={x=112,y=0,w=16,h=16}, wait=2 },
{ frame={x=128,y=0,w=16,h=16}, wait=1 },
{ frame={x=160,y=0,w=16,h=16}, wait=1 }
}
},
["coin"] = {
cycle = {1,2,3,4,3,2},
loop = true,
frames = {
{ frame={x=0,y=0,w=8,h=8}, wait=2 },
{ frame={x=8,y=0,w=8,h=8}, wait=2 },
{ frame={x=16,y=0,w=8,h=8}, wait=2 },
{ frame={x=24,y=0,w=8,h=8}, wait=2 }
}
},
["coin_picked"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=32,y=0,w=13,h=7}, wait=100 },
}
},
["brick"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=48,y=0,w=8,h=8}, wait=100 },
}
},
["torxa"] = {
cycle = {1,2,3,4},
loop = true,
frames = {
{ frame={x=0,y=0,w=8,h=16}, wait=2 },
{ frame={x=8,y=0,w=8,h=16}, wait=2 },
{ frame={x=16,y=0,w=8,h=16}, wait=2 },
{ frame={x=24,y=0,w=8,h=16}, wait=2 }
}
},
["clau"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=0,y=0,w=16,h=8}, wait=100 },
}
},
["porta"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=16,y=0,w=8,h=16}, wait=100 },
}
},
["porta_obrint"] = {
cycle = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
loop = false,
frames = {
{ frame={x=16,y=1,w=8,h=15}, wait=1 },
{ frame={x=16,y=2,w=8,h=14}, wait=1 },
{ frame={x=16,y=3,w=8,h=13}, wait=1 },
{ frame={x=16,y=4,w=8,h=12}, wait=1 },
{ frame={x=16,y=5,w=8,h=11}, wait=1 },
{ frame={x=16,y=6,w=8,h=10}, wait=1 },
{ frame={x=16,y=7,w=8,h=9}, wait=1 },
{ frame={x=16,y=8,w=8,h=8}, wait=1 },
{ frame={x=16,y=9,w=8,h=7}, wait=1 },
{ frame={x=16,y=10,w=8,h=6}, wait=1 },
{ frame={x=16,y=11,w=8,h=5}, wait=1 },
{ frame={x=16,y=12,w=8,h=4}, wait=1 },
{ frame={x=16,y=13,w=8,h=3}, wait=1 },
{ frame={x=16,y=14,w=8,h=2}, wait=1 },
{ frame={x=16,y=15,w=8,h=1}, wait=1 },
}
},
["sucubo_stand"] = {
cycle = {1},
loop = true,
frames = {
{ frame={x=0,y=0,w=16,h=16}, wait=100 },
}
},
["sucubo_fire"] = {
cycle = {1,2},
loop = false,
frames = {
{ frame={x=16,y=0,w=22,h=16}, offset={normal={x=-6,y=0}}, wait=8 },
{ frame={x=38,y=0,w=15,h=16}, offset={normal={x=5,y=0},flipped={x=-4,y=0}}, wait=16 },
}
},
["palo"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=0,y=9,w=16,h=6}, wait=100 }
}
},
["nemesio"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=0,y=0,w=16,h=16}, wait=100 }
}
},
["rata"] = {
cycle = {1,2,3,4,2},
loop = true,
frames = {
{ frame={x=0,y=0,w=9,h=8}, wait=2 },
{ frame={x=9,y=0,w=9,h=8}, wait=2 },
{ frame={x=18,y=0,w=9,h=8}, wait=2 },
{ frame={x=27,y=0,w=9,h=8}, wait=2 }
}
},
["gota_generador"] = {
cycle = {1,2,3,4,5,6,7,8},
loop = true,
frames = {
{ frame={x=48,y=0,w=8,h=8}, wait=50 },
{ frame={x=48,y=0,w=8,h=8}, wait=1 },
{ frame={x=0,y=0,w=8,h=8}, wait=2 },
{ frame={x=8,y=0,w=8,h=8}, wait=2 },
{ frame={x=16,y=0,w=8,h=8}, wait=2 },
{ frame={x=24,y=0,w=8,h=8}, wait=2 },
{ frame={x=32,y=0,w=8,h=8}, wait=2 },
{ frame={x=40,y=0,w=8,h=8}, wait=2 },
}
},
["gota"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=48,y=0,w=8,h=8}, wait=100 }
}
},
["esguit"] = {
cycle = {1},
loop = false,
frames = {
{ frame={x=56,y=0,w=8,h=8}, wait=100 }
}
},
["abad"] = {
cycle = {1,2},
loop = true,
frames = {
{ frame={x=16,y=0,w=16,h=18}, offset={flipped={x=0,y=-2}}, wait=2 },
{ frame={x=32,y=0,w=16,h=18}, offset={flipped={x=0,y=-2}}, wait=2 }
}
},
}

View File

@@ -0,0 +1,58 @@
function ia.update_berserk(spr)
map.surf(rooms.surf_foreground)
if spr.state == templates.ALIVE then
if sprites.hero.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr) -- El meu aabb
local x2,y2,w2,h2 = util.aabb(sprites.hero) -- el aabb del heroi
-- Si toca al heroi...
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit()
spr.flipped = not spr.flipped
end
end
local advance = 1
if sprites.hero.pos.y == spr.pos.y-1 then advance = 2 end
if spr.flipped then
local tx, ty = (spr.pos.x+3)>>3, (spr.pos.y+15)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x - advance
else
spr.flipped = not spr.flipped
end
else
local tx, ty = (spr.pos.x+12)>>3, (spr.pos.y+15)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x + advance
else
spr.flipped = not spr.flipped
end
end
elseif spr.state == templates.DYING then
if spr.animation ~= "mummy_dying" then
sprites.set_animation(spr, "mummy_dying")
spr.surf = surf.load("gfx/mummy.gif")
else
if spr.current_frame == 8 then
sprites.set_animation(spr, "mummy_dead")
spr.state = templates.DEAD
end
end
elseif spr.state == templates.DEAD then
if spr.current_wait == 1 then
sprites.set_animation(spr, "mummy_undying")
spr.state = templates.RESURRECTING
end
elseif spr.state == templates.RESURRECTING then
if spr.current_frame == 13 then
sprites.set_animation(spr, "mummy_walk")
spr.surf = surf.load("gfx/berserk.gif")
spr.state = templates.ALIVE
end
end
end

14
data/modules/ia/brick.lua Normal file
View File

@@ -0,0 +1,14 @@
function ia.update_brick(spr)
if spr.timeout > 0 then
spr.timeout = spr.timeout - 1
if spr.timeout == 0 then
local tx, ty = spr.pos.x>>3, spr.pos.y>>3
map.tile(tx,ty,0)
end
else
spr.pos.y = spr.pos.y + 2
local tx, ty = (spr.pos.x+2)>>3, (spr.pos.y)>>3
if rooms.is_outside(tx,ty) then sprites.remove(spr) return end
end
end

View File

@@ -0,0 +1,29 @@
function ia.update_bullet(spr)
local tx, ty, ty2 = (spr.pos.x+2)>>3, (spr.pos.y+1)>>3, (spr.pos.y+2)>>3
if rooms.is_outside(tx,ty) then sprites.remove(spr) return end
local x1,y1,w1,h1 = util.aabb(spr)
for i,v in ipairs(sprites.list) do
if v.enemy and v.state ~= templates.DEAD then
local x2,y2,w2,h2 = util.aabb(v)
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
if v.state == templates.ALIVE then v.state = templates.DYING end
sprites.remove(spr)
return
end
end
end
if map.tile(tx,ty) < 16 or map.tile(tx,ty2) < 16 then
if spr.flipped then
spr.pos.x = spr.pos.x - 8
else
spr.pos.x = spr.pos.x + 8
end
else
sprites.remove(spr)
end
end

15
data/modules/ia/clau.lua Normal file
View File

@@ -0,0 +1,15 @@
function ia.update_clau(spr)
if spr.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr)
local x2,y2,w2,h2 = util.aabb(sprites.hero)
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
if sprites.hero.give_key(spr.color) then
local tx, ty = (spr.pos.x)>>3, (spr.pos.y)>>3
map.surf(rooms.surf_items)
map.tile(tx,ty,0)
sprites.remove(spr)
end
end
end
end

26
data/modules/ia/coin.lua Normal file
View File

@@ -0,0 +1,26 @@
function ia.update_coin(spr)
if spr.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr)
local x2,y2,w2,h2 = util.aabb(sprites.hero)
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
local tx, ty = (spr.pos.x)>>3, (spr.pos.y)>>3
map.surf(rooms.surf_items)
map.tile(tx,ty,0)
spr.state = templates.DYING
sprites.set_animation(spr, "coin_picked")
spr.pos.y=spr.pos.y-16
spr.pos.x=spr.pos.x-4
spr.timer = 0
score.inc(10)
return
end
elseif spr.state == templates.DYING then
spr.pos.y = spr.pos.y - 0.5
spr.timer = spr.timer + 1
if spr.timer == 32 then
sprites.remove(spr)
end
end
end

60
data/modules/ia/gota.lua Normal file
View File

@@ -0,0 +1,60 @@
function ia.update_gota(spr)
if spr.timer > 0 then
spr.timer = spr.timer-1
if spr.timer == 0 then
sprites.set_animation(spr, "gota_generador")
end
return
else
spr.invisible = nil;
if spr.current_frame==2 then
local gota = templates.create("gota_caiguent", {pos={x=spr.pos.x, y=spr.pos.y}, flipped=spr.flipped})
table.insert(sprites.list, gota)
--spr.animation_finished = nil
--spr.current_frame = 1
--spr.current_wait = 1
end
end
end
function gota_esguita(spr)
sprites.remove(spr)
table.insert(sprites.list, templates.create("gota_esguit", {pos={x=spr.pos.x, y=spr.pos.y}, dir={x= 1,y= math.random(3,5)}, flipped=spr.flipped}))
table.insert(sprites.list, templates.create("gota_esguit", {pos={x=spr.pos.x, y=spr.pos.y}, dir={x=-1,y= math.random(3,5)}, flipped=spr.flipped}))
table.insert(sprites.list, templates.create("gota_esguit", {pos={x=spr.pos.x, y=spr.pos.y}, dir={x=-1,y=-math.random(3,5)}, flipped=spr.flipped}))
table.insert(sprites.list, templates.create("gota_esguit", {pos={x=spr.pos.x, y=spr.pos.y}, dir={x= 1,y=-math.random(3,5)}, flipped=spr.flipped}))
end
function ia.update_gota_caiguent(spr)
local tx, ty = (spr.pos.x+4)>>3, (spr.pos.y+4)>>3
if rooms.is_outside(tx,ty) then sprites.remove(spr) return end
if map.tile(tx,ty) >= 16 then
gota_esguita(spr)
end
if sprites.hero.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr) -- El meu aabb
local x2,y2,w2,h2 = util.aabb(sprites.hero) -- el aabb del heroi
-- Si toca al heroi...
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit()
gota_esguita(spr)
end
end
spr.pos.y = spr.pos.y + 1
end
function ia.update_gota_esguit(spr)
local tx, ty = (spr.pos.x+4)>>3, (spr.pos.y+4)>>3
if rooms.is_outside(tx,ty) then sprites.remove(spr) return end
spr.dir.y = spr.dir.y + 1;
spr.pos.y = spr.pos.y + spr.dir.y
spr.pos.x = spr.pos.x + spr.dir.x
end

279
data/modules/ia/hero.lua Normal file
View File

@@ -0,0 +1,279 @@
function ia.update_hero()
if sprites.hero.state == templates.DEAD then
if sprites.hero.cooldown > 0 then
local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y+1)>>3
local tile_under_me1 = map.tile(tx1,ty+2)
local tile_under_me2 = map.tile(tx2,ty+2)
if tile_under_me1 == 0 and tile_under_me2 == 0 then
if rooms.pos.y<84 and ty+2>rooms.pos.y+12 then
game.change_room(0,1)
else
if sprites.hero.cooldown % 4 == 0 then
sprites.hero.pos.y = sprites.hero.pos.y + 1
end
end
end
sprites.hero.cooldown = sprites.hero.cooldown - 1
if sprites.hero.cooldown == 0 then
sprites.lights_out()
end
end
return
end
-- Update hero
local anim = "hero_stand"
local move_anim = "hero_walk"
-- Si estem en cooldown desde l'ultim dispar, decrementem el contador
if sprites.hero.cooldown > 0 then
sprites.hero.cooldown = sprites.hero.cooldown - 1
end
-- Si estem en jump_throttle desde l'ultim bot, decrementem el contador
if sprites.hero.jump_throttle > 0 then
sprites.hero.jump_throttle = sprites.hero.jump_throttle - 1
end
if sprites.hero.state == templates.DYING then
if (sprites.hero.cooldown//5) % 2 == 0 then
sprites.hero.invisible = true
else
sprites.hero.invisible = nil
end
if sprites.hero.cooldown == 0 then
sprites.hero.state = templates.ALIVE
sprites.hero.invisible = nil
end
end
-- Si li han pegat...
if sprites.hero.has_been_hit then
if sprites.hero.flipped then
local tx, ty = (sprites.hero.pos.x+12)>>3, (sprites.hero.pos.y+16)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 then
if tx>rooms.pos.x+19 then
game.change_room(1,0)
else
sprites.hero.pos.x = sprites.hero.pos.x + 1
end
end
else
local tx, ty = (sprites.hero.pos.x+3)>>3, (sprites.hero.pos.y+16)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 then
if tx<rooms.pos.x then
game.change_room(-1,0)
else
sprites.hero.pos.x = sprites.hero.pos.x - 1
end
end
end
sprites.hero.has_been_hit = sprites.hero.has_been_hit - 1
if sprites.hero.has_been_hit == 0 then
sprites.hero.has_been_hit = nil;
end
end
-- si està en l'animació de disparar, no podem fer res i eixim ja
if sprites.hero.shooting then
-- A no ser que siga l'ultim frame, en tal cas tornem a estar de peu i au
if sprites.hero.current_frame==3 then
sprites.hero.shooting = false
sprites.set_animation(sprites.hero, "hero_stand")
else
return
end
end
-- SI ESTÀ BOTANT...
if sprites.hero.jumping > 0 then
anim = "hero_jump"
move_anim = "hero_jump"
local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y)>>3
--draw.rect(tx1<<3,ty<<3,8,8,8)
--draw.rect(tx2<<3,ty<<3,8,8,28)
if map.tile(tx1,ty) < 16 and map.tile(tx2,ty) < 16 then
--if ty+1<rooms.pos.y then
-- game.change_room(0,-1)
--else
if sprites.hero.jumping > 1 then sprites.hero.pos.y = sprites.hero.pos.y - 1 end
--end
else
sprites.hero.jumping = 0
sprites.hero.jump_throttle = 10
end
sprites.hero.jumping = sprites.hero.jumping - 1
else
-- SI NO ESTÀ BOTANT...
-- SI ESTÀ EN UNES ESCALERES...
local txm, ty = (sprites.hero.pos.x+8)>>3, (sprites.hero.pos.y+8)>>3
if (map.tile(txm,ty) > 0 and map.tile(txm,ty) < 16) or (map.tile(txm,ty+1) > 0 and map.tile(txm,ty+1) < 16) then
anim = "hero_stairs_idle"
move_anim = "hero_stairs"
-- SI PULSA AMUNT...
if key.down(key.UP) or pad.down(pad.UP) then
anim = move_anim
local tx1, tx2, ty = (sprites.hero.pos.x+8)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y)>>3
if map.tile(tx1,ty) < 16 then --or map.tile(tx2,ty) < 16 then
if ty+1<rooms.pos.y then
game.change_room(0,-1)
else
sprites.hero.pos.y = sprites.hero.pos.y - 1
end
end
-- SI PULSA AVALL...
elseif key.down(key.DOWN) or pad.down(pad.DOWN) then
anim = move_anim
local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y+1)>>3
if map.tile(tx1,ty+2) < 16 or map.tile(tx2,ty+2) < 16 then
if ty+2>rooms.pos.y+12 then
game.change_room(0,1)
else
sprites.hero.pos.y = sprites.hero.pos.y + 1
end
end
end
else
-- SI NO ESTÀ EN UNES ESCALERES...
local tx1, txm, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+8)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y+1)>>3
-- SI ESTÀ CAIGUENT...
local tile_under_me1 = map.tile(tx1,ty+2)
local tile_under_me2 = map.tile(tx2,ty+2)
if tile_under_me1 == 0 and tile_under_me2 == 0 then
if rooms.pos.y<84 and ty+2>rooms.pos.y+12 then
game.change_room(0,1)
else
if sprites.hero.pos.y >= 808 then
sprites.hero.hit(0)
return
end
sprites.hero.pos.y = sprites.hero.pos.y + 2
end
else
-- SI NO ESTÀ CAIGUENT...
if tile_under_me1==84 then
map.tile(tx1,ty+2,68)
local broken_tile = templates.create("brick", {pos={x=tx1<<3, y=(ty+2)<<3}, flipped=sprites.hero.flipped})
table.insert(sprites.list, broken_tile)
end
if tile_under_me2==84 then
map.tile(tx2,ty+2,68)
local broken_tile = templates.create("brick", {pos={x=tx2<<3, y=(ty+2)<<3}, flipped=sprites.hero.flipped})
table.insert(sprites.list, broken_tile)
end
if tile_under_me1>=16 or tile_under_me1>=16 then
sprites.hero.pos.y = (ty<<3)-1
end
anim = "hero_stand"
sprites.save_safe_pos()
-- SI ESTÀ SOBRE UNES ESCALERES I POLSA AVALL...
if (map.tile(txm,ty+2) < 16 and map.tile(txm,ty+2) > 0) then
if key.down(key.DOWN) or pad.down(pad.DOWN) then
anim = "hero_stairs"
--local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y+1)>>3
--if map.tile(tx1,ty+2) < 16 or map.tile(tx2,ty+2) < 16 then
sprites.hero.pos.x = (txm << 3)-4
sprites.hero.pos.y = sprites.hero.pos.y + 1
--end
end
end
-- SI POLSA BOTAR...
if ( key.down(key.X) or pad.down(pad.A) ) and sprites.hero.jump_throttle == 0 then
sprites.hero.jumping = 17
-- SI POLSA DISPAR...
elseif (sprites.hero.cooldown==0) and (key.down(key.Z) or pad.down(pad.B)) then
sprites.hero.shooting = true
sprites.hero.cooldown = 20
local bullet = templates.create("bullet", {pos={x=sprites.hero.pos.x, y=sprites.hero.pos.y+7}, flipped=sprites.hero.flipped})
table.insert(sprites.list, bullet)
anim = "hero_shoot"
end
end
end
end
-- ESTIGA COM ESTIGA, SI POLSA ESQUERRA O DRETA...
if not sprites.hero.shooting and not sprites.hero.has_been_hit then
if key.down(key.LEFT) or pad.down(pad.LEFT) then
sprites.hero.flipped = true
anim = move_anim
local tx, ty = (sprites.hero.pos.x+3)>>3, (sprites.hero.pos.y+16)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 then
if tx<rooms.pos.x then
game.change_room(-1,0)
else
sprites.hero.pos.x = sprites.hero.pos.x - 1
end
end
elseif key.down(key.RIGHT) or pad.down(pad.RIGHT) then
sprites.hero.flipped = false
anim = move_anim
local tx, ty = (sprites.hero.pos.x+12)>>3, (sprites.hero.pos.y+16)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 then
if tx>rooms.pos.x+19 then
game.change_room(1,0)
else
sprites.hero.pos.x = sprites.hero.pos.x + 1
end
end
end
end
sprites.set_animation(sprites.hero, anim)
end
function ia.hero_hit(live)
live = live or sprites.hero.lives-1
local light_table = {[0]=20, 30, 50, 80, 100}
local red_table = {[0]=0, 0.25, 0.5, 0.75, 1}
if live==4 then
tweening.add(1,0,0.25,easing.linear,function(value,n,finished)palfade.fade_white(value)end)
else
tweening.add(1,0,0.25,easing.linear,function(value,n,finished)palfade.fade_red(value)end)
end
local start_light = light_table[sprites.hero.lives]
local start_red = red_table[sprites.hero.lives]
local end_light = light_table[live]
local end_red = red_table[live]
sprites.hero.lives = live
tweening.add(start_light,end_light,1,easing.linear,function(value,n,finished)sprites.hero.light = value end)
tweening.add(start_red,end_red,1,easing.linear,function(value,n,finished)palfade.fade_reddish(value)end)
if sprites.hero.lives == 0 then
sprites.hero.state = templates.DEAD
sprites.hero.surf = surf.load("gfx/mummy.gif")
sprites.set_animation(sprites.hero, "mummy_dying")
sprites.hero.jumping = 0
sprites.hero.cooldown = 120
elseif sprites.hero.lives < 4 then
sprites.hero.state = templates.DYING
sprites.hero.cooldown = 60
sprites.hero.shooting = false
sprites.set_animation(sprites.hero, "hero_stand")
sprites.hero.jumping = 8
sprites.hero.has_been_hit = 16
end
end
function ia.hero_give_key(color)
if sprites.hero.keys[color] then return false end
sprites.hero.keys[color] = true
tweening.add(1,0,0.25,easing.linear,function(value,n,finished)palfade.fade_white(value)end)
return true
end
function ia.hero_reset()
sprites.hero.state = templates.ALIVE
sprites.hero.invisible = nil
sprites.hero.lives = 4
sprites.hero.surf = surf.load("gfx/morcus.gif")
sprites.hero.animation = "hero_stand"
sprites.hero.current_frame = 1
sprites.hero.current_wait = 1
sprites.hero.flipped = false
sprites.hero.light = 100
sprites.hero.pos = {x=sprites.last_safe_pos.x,y=sprites.last_safe_pos.y}
end

50
data/modules/ia/mummy.lua Normal file
View File

@@ -0,0 +1,50 @@
function ia.update_mummy(spr)
map.surf(rooms.surf_foreground)
if spr.state == templates.ALIVE then
if sprites.hero.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr) -- El meu aabb
local x2,y2,w2,h2 = util.aabb(sprites.hero) -- el aabb del heroi
-- Si toca al heroi...
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit()
spr.flipped = not spr.flipped
end
end
if spr.flipped then
local tx, ty = (spr.pos.x+3)>>3, (spr.pos.y+15)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x - 1
else
spr.flipped = not spr.flipped
end
else
local tx, ty = (spr.pos.x+12)>>3, (spr.pos.y+15)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x + 1
else
spr.flipped = not spr.flipped
end
end
elseif spr.state == templates.DYING then
if spr.animation ~= "mummy_dying" then
sprites.set_animation(spr, "mummy_dying")
else
if spr.current_frame == 8 then
sprites.set_animation(spr, "mummy_dead")
spr.state = templates.DEAD
end
end
elseif spr.state == templates.DEAD then
if spr.current_wait == 1 then
sprites.set_animation(spr, "mummy_undying")
spr.state = templates.RESURRECTING
end
elseif spr.state == templates.RESURRECTING then
if spr.current_frame == 13 then
sprites.set_animation(spr, "mummy_walk")
spr.state = templates.ALIVE
end
end
end

View File

@@ -0,0 +1,48 @@
require ":utils.util"
nemesio = { STATIC = 1, FLOATING = 2 }
function ia.update_nemesio(spr)
spr.timer = spr.timer + 1
local target = {x=sprites.hero.pos.x-spr.pos.x, y=sprites.hero.pos.y-spr.pos.y}
if target.x > 0 then
spr.flipped = false
else
spr.flipped = true
end
if spr.substate == nemesio.STATIC then
spr.mode = draw.NORMAL
if spr.timer==50 then
spr.timer=0
spr.substate = nemesio.FLOATING
spr.advance = {x=0,y=0}
if math.abs(target.x) > math.abs(target.y) then
spr.advance.x = math.sign(target.x)
else
spr.advance.y = math.sign(target.y)
end
end
if sprites.hero.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr) -- El meu aabb
local x2,y2,w2,h2 = util.aabb(sprites.hero) -- el aabb del heroi
-- Si toca al heroi...
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit()
end
end
elseif spr.substate == nemesio.FLOATING then
spr.mode = draw.PATTERN
spr.pattern = 0xa5a5
spr.pos.x = spr.pos.x + spr.advance.x
spr.pos.y = spr.pos.y + spr.advance.y
if spr.timer == 32 then
spr.timer = 0
spr.substate = nemesio.STATIC
end
end
end

24
data/modules/ia/palo.lua Normal file
View File

@@ -0,0 +1,24 @@
function ia.update_palo(spr)
local tx, ty, ty2 = (spr.pos.x+2)>>3, (spr.pos.y+1)>>3, (spr.pos.y+2)>>3
if rooms.is_outside(tx,ty) then sprites.remove(spr) return end
if sprites.hero.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr) -- El meu aabb
local x2,y2,w2,h2 = util.aabb(sprites.hero) -- el aabb del heroi
-- Si toca al heroi...
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit()
end
end
spr.dy = spr.dy + spr.ay;
spr.pos.y = spr.pos.y + spr.dy
if spr.flipped then
spr.pos.x = spr.pos.x - 6
else
spr.pos.x = spr.pos.x + 6
end
end

24
data/modules/ia/porta.lua Normal file
View File

@@ -0,0 +1,24 @@
function ia.update_porta(spr)
if spr.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr)
local x2,y2,w2,h2 = util.aabb(sprites.hero)
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
if sprites.hero.keys[spr.color] then
sprites.hero.keys[spr.color] = nil
sprites.set_animation(spr, "porta_obrint")
spr.state = templates.DYING
end
end
elseif spr.state == templates.DYING then
if spr.current_frame == 15 then
local tx, ty = (spr.pos.x)>>3, (spr.pos.y)>>3
map.surf(rooms.surf_items)
map.tile(tx,ty,0)
map.surf(rooms.surf_foreground)
map.tile(tx,ty,0)
map.tile(tx,ty+1,0)
sprites.remove(spr)
end
end
end

29
data/modules/ia/rata.lua Normal file
View File

@@ -0,0 +1,29 @@
function ia.update_rata(spr)
map.surf(rooms.surf_foreground)
if sprites.hero.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr) -- El meu aabb
local x2,y2,w2,h2 = util.aabb(sprites.hero) -- el aabb del heroi
-- Si toca al heroi...
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit()
spr.flipped = not spr.flipped
end
end
if spr.flipped then
local tx, ty = (spr.pos.x-1)>>3, (spr.pos.y+7)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x - 1
else
spr.flipped = not spr.flipped
end
else
local tx, ty = (spr.pos.x+9)>>3, (spr.pos.y+7)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x + 1
else
spr.flipped = not spr.flipped
end
end
end

View File

@@ -0,0 +1,52 @@
function ia.update_sucubo(spr)
map.surf(rooms.surf_foreground)
if spr.state == templates.ALIVE then
spr.timer = spr.timer + 1
if spr.timer==100 then
sprites.set_animation(spr, "sucubo_fire")
elseif spr.timer > 100 then
if spr.current_frame == 2 then
spr.timer = 0
local palo = templates.create("palo", {pos={x=spr.pos.x, y=spr.pos.y}, flipped=spr.flipped})
table.insert(sprites.list, palo)
end
end
if spr.animation_finished then
spr.animation_finished = nil
sprites.set_animation(spr, "sucubo_stand")
end
if sprites.hero.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr) -- El meu aabb
local x2,y2,w2,h2 = util.aabb(sprites.hero) -- el aabb del heroi
-- Si toca al heroi...
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit()
end
end
elseif spr.state == templates.DYING then
if spr.animation ~= "mummy_dying" then
sprites.set_animation(spr, "mummy_dying")
spr.surf = surf.load("gfx/mummy.gif")
else
if spr.current_frame == 8 then
sprites.set_animation(spr, "mummy_dead")
spr.state = templates.DEAD
end
end
elseif spr.state == templates.DEAD then
if spr.current_wait == 1 then
sprites.set_animation(spr, "mummy_undying")
spr.state = templates.RESURRECTING
end
elseif spr.state == templates.RESURRECTING then
if spr.current_frame == 13 then
sprites.set_animation(spr, "sucubo_stand")
spr.surf = surf.load("gfx/sucubo.gif")
spr.state = templates.ALIVE
end
end
end

19
data/modules/ia/torxa.lua Normal file
View File

@@ -0,0 +1,19 @@
function ia.update_torxa(spr)
if spr.state == templates.ALIVE then
if sprites.hero.lives == 4 then return end
local x1,y1,w1,h1 = util.aabb(spr)
local x2,y2,w2,h2 = util.aabb(sprites.hero)
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
sprites.hero.hit(4)
spr.state = templates.DYING
spr.timer = 0
return
end
elseif spr.state == templates.DYING then
spr.timer = spr.timer + 1
if spr.timer == 32 then
spr.state = templates.ALIVE
end
end
end

22
data/modules/items.lua Normal file
View File

@@ -0,0 +1,22 @@
items = {
{ name="mummy", label="momia", visual={x=0, y=24, w=16, h=16} },
{ name="coin", label="moneda", visual={x=0, y=40, w=8, h=8} },
{ name="torxa", label="torxa", visual={x=0, y=48, w=8, h=16} },
{ name="clau verda", label="clau", visual={x=16, y=48, w=16, h=8} },
{ name="clau groga", label="clau", visual={x=16, y=56, w=16, h=8} },
{ name="clau roja", label="clau", visual={x=32, y=48, w=16, h=8} },
{ name="clau blava", label="clau", visual={x=32, y=56, w=16, h=8} },
{ name="porta verda", label="porta", visual={x=48, y=48, w=8, h=16} },
{ name="porta groga", label="porta", visual={x=56, y=48, w=8, h=16} },
{ name="porta roja", label="porta", visual={x=64, y=48, w=8, h=16} },
{ name="porta blava", label="porta", visual={x=72, y=48, w=8, h=16} },
{ name="sucubo 0", label="sucubo00", visual={x=0, y=64, w=16, h=16} },
{ name="sucubo 25", label="sucubo25", visual={x=0, y=64, w=16, h=16} },
{ name="sucubo 50", label="sucubo50", visual={x=0, y=64, w=16, h=16} },
{ name="sucubo 75", label="sucubo75", visual={x=0, y=64, w=16, h=16} },
{ name="nemesio", label="nemesio", visual={x=16, y=80, w=16, h=16} },
{ name="rata", label="rata", visual={x=80, y=48, w=9, h=8} },
{ name="gota", label="gota", visual={x=80, y=56, w=8, h=8} },
{ name="berserk", label="berserk", visual={x=16, y=24, w=16, h=16} },
{ name="abad", label="abad", visual={x=16, y=0, w=16, h=16} },
}

90
data/modules/menu.lua Normal file
View File

@@ -0,0 +1,90 @@
require "..utils.ui"
menu = {
hidden = true,
pos_y = 0,
selected = 1,
} local me = menu
function me.draw()
actions = {
function() editor.play() me.close() end,
function() rooms.save() editor.modified=false me.close() end,
function() editor.quit() me.close() end,
function() editor.layer=LAYER_FOREGROUND me.close() end,
function() editor.layer=LAYER_BACKGROUND me.close() end,
function() editor.layer=LAYER_ITEMS me.close() end,
function() rooms.toggle_visibility(LAYER_FOREGROUND) end,
function() rooms.toggle_visibility(LAYER_BACKGROUND) end,
function() rooms.toggle_visibility(LAYER_SHADOWS) end,
function() rooms.toggle_visibility(LAYER_ITEMS) end
}
local sel = me.selected
view.origin(0,me.pos_y)
view.clip()
local y = me.pos_y
draw.rrectf(1,0,8,8,1,21)
draw.rrectf(1,-1,8,8,1,6)
draw.hline(3,1,6,21)
draw.hline(3,3,6,21)
draw.hline(3,5,6,21)
if editor.modified then draw.rectf(6,0,2,2,8) end
if y<=0 then return end
view.origin(0,me.pos_y-24)
draw.rectf(0,0,160,24,6)
ui.pushbutton("PLAY",1,3,16,13,10,actions[1], sel==1)
ui.pushbutton("SAVE",22,3,7,22,21,actions[2], sel==2)
if editor.modified then draw.rectf(37,4,2,2,8) end
ui.pushbutton("QUIT",22,12,7,12,5,actions[3], sel==3)
draw.rrect(44,6,29,14,3,21)
draw.rectf(48,6,17,1,6)
draw.text("EDIT",49,3,21)
ui.togglebutton("F",44+3,6+3,7,14,9,15,7,editor.layer==LAYER_FOREGROUND,actions[4], sel==4)
ui.togglebutton("B",52+3,6+3,7,14,9,15,7,editor.layer==LAYER_BACKGROUND,actions[5], sel==5)
ui.togglebutton("I",60+3,6+3,7,14,9,15,7,editor.layer==LAYER_ITEMS,actions[6], sel==6)
draw.rrect(75,6,37,14,3,21)
draw.rectf(79,6,17,1,6)
draw.text("SHOW",80,3,21)
ui.togglebutton("F",75+3,6+3,7,14,9,15,7,rooms.is_visible(LAYER_FOREGROUND),actions[7], sel==7)
ui.togglebutton("B",83+3,6+3,7,14,9,15,7,rooms.is_visible(LAYER_BACKGROUND),actions[8], sel==8)
ui.togglebutton("S",91+3,6+3,7,14,9,15,7,rooms.is_visible(LAYER_SHADOWS),actions[9], sel==9)
ui.togglebutton("I",99+3,6+3,7,14,9,15,7,rooms.is_visible(LAYER_ITEMS),actions[10], sel==10)
local tab = key.press(key.TAB)
if key.press(key.ESCAPE) then
me.toggle()
elseif key.press(key.LEFT) or (tab and key.down(key.LSHIFT)) then
me.selected=me.selected-1
if me.selected < 1 then me.selected = 10 end
elseif key.press(key.RIGHT) or (tab and not key.down(key.LSHIFT)) then
me.selected=me.selected+1
if me.selected > 10 then me.selected = 1 end
elseif key.press(key.RETURN) or key.press(key.SPACE) then
actions[me.selected]()
end
end
function me.toggle()
if me.hidden then
me.hidden = false
me.selected = 1
tweening.add(0,24,0.25,easing.easeOutBounce,function(value,n,finished)me.pos_y=value end)
else
me.hidden = true
tweening.add(24,0,0.25,easing.easeOutBounce,function(value,n,finished)me.pos_y=value end)
end
end
function me.close()
if not me.hidden then
me.hidden = true
tweening.add(24,0,0.25,easing.easeOutBounce,function(value,n,finished)me.pos_y=value end)
end
end

145
data/modules/rooms.lua Normal file
View File

@@ -0,0 +1,145 @@
require "sprites"
LAYER_FOREGROUND = 1
LAYER_BACKGROUND = 2
LAYER_ITEMS = 4
LAYER_SPRITES = 8
LAYER_SHADOWS = 16
LAYER_ALL = 31
ROOM_FILE_EXT = ".gif"
rooms = {
surf_background = nil,
surf_foreground = nil,
surf_items = nil,
surf_original_items = nil,
visibility = LAYER_ALL,
pos = {x=0, y=4*13},
}
function rooms.current()
return (rooms.pos.x//20) + (rooms.pos.y//13) * 8
end
function rooms.convert(src)
local dst = surf.new(20*8,13*8)
surf.source(src)
surf.target(dst)
for ry=0,7 do
for rx=0,7 do
for ty=0,11 do
for tx=0,19 do
surf.pixel(rx*20+tx, ry*13+ty, surf.pixel(rx*20+tx, ry*12+ty))
end
end
end
end
return dst
end
function rooms.reload()
if rooms.surf_background ~= nil then surf.free(rooms.surf_background) end
rooms.surf_background = surf.load("maps/rooms_background"..ROOM_FILE_EXT)
--rooms.surf_background = surf.new(20*8,13*8)
--rooms.surf_background = rooms.convert(surf.load("rooms_background"..ROOM_FILE_EXT))
if rooms.surf_foreground ~= nil then surf.free(rooms.surf_foreground) end
rooms.surf_foreground = surf.load("maps/rooms_foreground"..ROOM_FILE_EXT)
--rooms.surf_foreground = surf.new(20*8,12*8)
--rooms.surf_foreground = rooms.convert(surf.load("rooms_foreground"..ROOM_FILE_EXT))
if rooms.surf_items ~= nil then surf.free(rooms.surf_items) end
rooms.surf_items = surf.load("maps/rooms_items"..ROOM_FILE_EXT)
--rooms.surf_items = surf.new(20*8,12*8)
--rooms.surf_items = rooms.convert(surf.load("rooms_items"..ROOM_FILE_EXT))
end
function rooms.init()
rooms.pos.x, rooms.pos.y = 0,4*13
rooms.reload()
sprites.init()
end
function rooms.save()
local p = {}
for i=0,255 do p[i] = {r=i,g=i,b=i} end
surf.save(rooms.surf_background, "data/maps/rooms_background"..ROOM_FILE_EXT, p)
surf.save(rooms.surf_foreground, "data/maps/rooms_foreground"..ROOM_FILE_EXT, p)
surf.save(rooms.surf_items, "data/maps/rooms_items"..ROOM_FILE_EXT, p)
editor.modified = false
end
function rooms.is_outside(x, y)
return x < rooms.pos.x or y < rooms.pos.y or x > rooms.pos.x + 20 or y > rooms.pos.y + 13
end
function rooms.draw()
-- Retallem la pantalla a la zona de joc
--view.clip(0,8,160,96)
-- Movem la càmara a l'habitació on estem
view.origin(-rooms.pos.x*8,-rooms.pos.y*8)
-- Pintem el background
surf.source(surf_tiles)
map.surf(rooms.surf_background)
if rooms.is_visible(LAYER_BACKGROUND) then
map.draw()
else
draw.rectf(0,0,160,96,1)
end
-- Movem 4x4 pixels la càmara per a pintar les sombres dels sprites i el foreground
view.origin(-rooms.pos.x*8+4,-rooms.pos.y*8+4)
-- Pintem el foreground de negre
map.surf(rooms.surf_foreground)
pal.subpal(0,32,1)
if rooms.is_visible(LAYER_FOREGROUND | LAYER_SHADOWS) then map.draw() end
-- Pintem els sprites de negre
if rooms.is_visible(LAYER_SPRITES | LAYER_SHADOWS) then
sprites.draw(true)
--draw.surf(0, 0, 16, 17, 20, 15, 16, 17)
end
-- Movem la càmara al lloc que toca de nou, i tornem la paleta normal
view.origin(-rooms.pos.x*8,-rooms.pos.y*8)
pal.subpal()
-- Pintem el foreground
surf.source(surf_tiles)
map.surf(rooms.surf_foreground)
if rooms.is_visible(LAYER_FOREGROUND) then map.draw() end
-- Pintem els sprites
if rooms.is_visible(LAYER_SPRITES) then
sprites.draw()
--draw.surf(0, 0, 16, 17, 20, 15, 16, 17)
end
-- Pintem la rejilla
--for y=0,12 do draw.line(0,y*8, 160, y*8, 27) end
--for x=0,20 do draw.line(x*8, 0, x*8, 104, 27) end
end
function rooms.is_visible(layer)
return (app.update==game.update) or (rooms.visibility & layer == layer)
end
function rooms.set_visibility(layer, visibility)
if visibility then
rooms.visibility = rooms.visibility | layer
else
rooms.visibility = rooms.visibility & ~layer
end
end
function rooms.toggle_visibility(layer)
if rooms.visibility & layer == layer then
rooms.visibility = rooms.visibility & ~layer
else
rooms.visibility = rooms.visibility | layer
end
end

65
data/modules/score.lua Normal file
View File

@@ -0,0 +1,65 @@
score = {
points = 0,
color = 21,
ypos = 3,
surf = nil,
font = nil
} local me = score
function me.init()
me.points = 0
me.surf = surf.load("gfx/sprites.gif")
me.font = font.load("gfx/score_font.fnt")
end
local function draw_text()
font.current(me.font)
font.spacing(0)
local txt = string.format("%03d", me.points)
draw.text(txt,2,me.ypos-1,27)
draw.text(txt,3,me.ypos-1,27)
draw.text(txt,4,me.ypos-1,27)
draw.text(txt,2,me.ypos,27)
draw.text(txt,4,me.ypos,27)
draw.text(txt,2,me.ypos+1,27)
draw.text(txt,4,me.ypos+1,27)
draw.text(txt,2,me.ypos+2,27)
draw.text(txt,3,me.ypos+2,27)
draw.text(txt,4,me.ypos+2,27)
draw.text(txt,3,me.ypos+1,1)
draw.text(txt,3,me.ypos,me.color)
font.current(font.DEFAULT)
font.spacing(1)
surf.source(me.surf)
end
local function draw_key(sx,sy,dx,dy)
pal.subpal(1,26,27)
for y=-1,1 do
for x=-1,1 do
if x~=0 and y~=0 then draw.surf(sx,sy,16,8, dx+x,dy+y) end
end
end
pal.subpal()
draw.surf(sx,sy,16,8, dx,dy)
end
function me.draw()
view.origin(0,0)
surf.target(0)
view.clip()
draw_text()
local y = 3
if sprites.hero.keys["verda"] then draw_key(16,48,140,y) y=y+8 end
if sprites.hero.keys["groga"] then draw_key(16,56,140,y) y=y+8 end
if sprites.hero.keys["roja"] then draw_key(32,48,140,y) y=y+8 end
if sprites.hero.keys["blava"] then draw_key(32,56,140,y) y=y+8 end
end
function me.inc(value)
me.points = me.points + value
tweening.add(8, 0, 0.5, easing.linear, function(val,progress,finished) me.color = (math.floor(val)&1) == 0 and 21 or 14 end)
tweening.add(5, 3, 0.5, easing.easeOutElastic, function(val,progress,finished) me.ypos = math.floor(val) end)
end

222
data/modules/sprites.lua Normal file
View File

@@ -0,0 +1,222 @@
require "animations"
require "templates"
sprites = {
hero = nil,
list = {},
pause_ia = false,
--initial_pos = { x=28, y=4*13*8+79 }
last_safe_room = 0 + 4 * 8,
last_safe_pos = { x=28, y=4*13*8+79 }
}
function sprites.remove(sprite)
for i,v in ipairs(sprites.list) do
if v == sprite then
table.remove(sprites.list, i)
print("Sprite removed: "..sprite.type)
return
end
end
end
function sprites.save_safe_pos()
local room = (rooms.pos.x//20) + (rooms.pos.y//12) * 8
if room ~= sprites.last_safe_room then
sprites.last_safe_room = room
sprites.last_safe_pos = {x=sprites.hero.pos.x, y=sprites.hero.pos.y}
end
end
function sprites.add_from_room(rx,ry)
sprites.list = {}
map.surf(rooms.surf_items)
for y = ry, ry+11 do
for x = rx, rx+19 do
if map.tile(x,y) ~= 0 then
local room = (rx//20) + (ry//12) * 8
local item = map.tile(x,y)
local flip = item > 0x7f
item = item & 0x7f
io.write("crear "..items[item].name.." en hab "..room.." ("..x..","..y..")...\n")
table.insert(sprites.list, templates.create(items[item].name, {pos={x=x*8, y=y*8},flipped=flip, room=room}))
end
end
end
end
function sprites.init()
sprites.hero = {
type = "hero",
pos = { x=28, y=4*13*8+79 },
size= { w=16, h=17 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = false,
surf = surf.load("gfx/morcus.gif"),
animation = "hero_stand",
ia = ia.update_hero,
state = templates.ALIVE,
jumping = 0,
light = 100,
light_ox = 8,
light_oy = 8,
cooldown = 0,
jump_throttle = 0,
lives = 4,
keys = {},
stairs = false,
hit = ia.hero_hit,
give_key = ia.hero_give_key
}
end
function sprites.set_animation(sprite, animation)
if sprite.animation ~= animation then
sprite.animation_finished = nil
sprite.animation = animation
sprite.current_frame = 1
local cycle = animations[sprite.animation].cycle[1]
sprite.current_wait = animations[sprite.animation].frames[cycle].wait
end
end
function sprites.update()
if not sys.beat() then return end
sprites.update_sprite(sprites.hero)
for i,v in ipairs(sprites.list) do
sprites.update_sprite(v)
end
if not sprites.pause_ia then
sprites.hero.ia()
for i,v in ipairs(sprites.list) do
v.ia(v)
end
end
end
function sprites.update_sprite(sprite)
if sprite.animation_finished then return end
sprite.current_wait = sprite.current_wait - 1
if sprite.current_wait == 0 then
if sprite.current_frame < #animations[sprite.animation].cycle then
sprite.current_frame = sprite.current_frame + 1
else
if animations[sprite.animation].loop then
sprite.current_frame = 1
else
sprite.animation_finished = true
end
end
local cycle = animations[sprite.animation].cycle[sprite.current_frame]
sprite.current_wait = animations[sprite.animation].frames[cycle].wait
end
end
function sprites.lights_out()
for i,spr in ipairs(sprites.list) do
if spr.light then
tweening.add(spr.light,0,0.5,easing.linear,
function(value,n,finished)
spr.light = value
if finished then
spr.light = nil
end
end
)
end
end
tweening.add(sprites.hero.light,0,0.5,easing.linear,
function(value,n,finished)
sprites.hero.light = value
if finished then
sprites.hero.light = nil
end
end
)
end
function sprites.draw(ignore_selected)
if app.update ~= editor.update then
surf.target(game.circ_buf)
surf.cls()
surf.target(game.back_buf)
end
editor.item_hovered = nil
local mx,my = mouse.pos()
if (app.update == editor.update) and (editor.layer~=LAYER_ITEMS) then ignore_selected = true end
for i,v in ipairs(sprites.list) do
if not ignore_selected and app.update == editor.update and mx>=v.pos.x and mx<=v.pos.x+v.size.w and my>=v.pos.y and my<=v.pos.y+v.size.h then
editor.item_hovered = i
if editor.item_dragged == editor.item_hovered then
draw.mode(draw.PATTERN)
draw.pattern(editor.ants)
end
sprites.draw_sprite_selected(v)
draw.mode(draw.NORMAL)
else
if (not ignore_selected) or (not v.no_shadow) or (app.update ~= game.update) then
sprites.draw_sprite(v)
end
end
end
sprites.draw_sprite(sprites.hero)
end
function sprites.draw_sprite(sprite)
local cycle = animations[sprite.animation].cycle[sprite.current_frame]
local frame = animations[sprite.animation].frames[cycle]
local ox, oy = 0, 0
if frame.offset then
if sprite.flipped then
if frame.offset.flipped then ox,oy = frame.offset.flipped.x,frame.offset.flipped.y end
else
if frame.offset.normal then ox,oy = frame.offset.normal.x,frame.offset.normal.y end
end
end
if not frame then
print(sprite.current_frame)
end
local reversed = frame.reversed or false
if not sprite.invisible then
surf.source(sprite.surf)
if sprite.pattern then draw.pattern(sprite.pattern) end
if sprite.mode then draw.mode(sprite.mode) end
draw.surf(frame.frame.x, frame.frame.y, frame.frame.w, frame.frame.h, sprite.pos.x+ox, sprite.pos.y+oy, frame.frame.w, frame.frame.h, (not reversed) ~= (not sprite.flipped))
draw.pattern(0xffff)
draw.mode(draw.NORMAL)
end
if cheats.showaabb then
local x,y,w,h = util.aabb(sprite)
draw.rect(x,y,w,h,8)
end
if (app.update ~= editor.update) and (sprite.light) then
game.draw_light(sprite.pos.x+sprite.light_ox, sprite.pos.y+sprite.light_oy,sprite.light)
end
end
function sprites.draw_sprite_selected(sprite)
pal.subpal(0,32,28)
local cycle = animations[sprite.animation].cycle[sprite.current_frame]
local frame = animations[sprite.animation].frames[cycle]
local reversed = frame.reversed or false
local x, y, w, h, sx, sy, f = sprite.pos.x, sprite.pos.y, frame.frame.w, frame.frame.h, frame.frame.x, frame.frame.y, (not reversed) ~= (not sprite.flipped)
surf.source(sprite.surf)
draw.surf(sx, sy, w, h, x-1, y-1, w, h, f)
draw.surf(sx, sy, w, h, x, y-1, w, h, f)
draw.surf(sx, sy, w, h, x+1, y-1, w, h, f)
draw.surf(sx, sy, w, h, x-1, y, w, h, f)
draw.surf(sx, sy, w, h, x+1, y, w, h, f)
draw.surf(sx, sy, w, h, x-1, y+1, w, h, f)
draw.surf(sx, sy, w, h, x, y, w, h, f)
draw.surf(sx, sy, w, h, x+1, y+1, w, h, f)
pal.subpal()
draw.mode(draw.NORMAL)
draw.surf(sx, sy, w, h, x, y, w, h, f)
end

287
data/modules/templates.lua Normal file
View File

@@ -0,0 +1,287 @@
ia = {}
require "ia.*"
local gota_wait = 1
templates = {
ALIVE = 0,
DYING = 1,
DEAD = 2,
RESURRECTING = 3,
} local me = templates
function me.create(type, options)
local sprite
local key, value = type:match("^(%S+)%s*(.*)$")
if key == "mummy" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=16 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/mummy.gif"),
animation = "mummy_walk",
state = me.ALIVE,
enemy = true,
room = options.room,
ia = ia.update_mummy
}
elseif key == "bullet" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=4,h=3 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/morcus.gif"),
animation = "bullet",
ia = ia.update_bullet
}
elseif key == "coin" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=8 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/misc.gif"),
animation = "coin",
state = me.ALIVE,
timer = 0,
light = 15,
light_ox = 4,
light_oy = 4,
ia = ia.update_coin
}
elseif key == "brick" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=8 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/misc.gif"),
animation = "brick",
state = me.ALIVE,
timeout = 10,
ia = ia.update_brick
}
elseif key == "torxa" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=16 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/torxa.gif"),
animation = "torxa",
state = me.ALIVE,
light = 30,
light_ox = 4,
light_oy = 4,
no_shadow = true,
ia = ia.update_torxa
}
elseif key == "clau" then
sprite = {
type = key,
color = value,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=8 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/"..value..".gif"),
animation = "clau",
state = me.ALIVE,
light = 15,
light_ox = 7,
light_oy = 4,
ia = ia.update_clau
}
elseif key == "porta" then
sprite = {
type = key,
color = value,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=16 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/"..value..".gif"),
animation = "porta",
state = me.ALIVE,
ia = ia.update_porta
}
elseif key == "sucubo" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=16 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/sucubo.gif"),
animation = "sucubo_stand",
state = me.ALIVE,
timer = tonumber(value),
enemy = true,
room = options.room,
ia = ia.update_sucubo
}
elseif key == "palo" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=6 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/misc.gif"),
animation = "palo",
dy = -4,
ay = 1,
ia = ia.update_palo
}
elseif key == "nemesio" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=16 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/nemesio.gif"),
animation = "nemesio",
state = me.ALIVE,
substate = nemesio.STATIC,
timer = 0,
enemy = true,
room = options.room,
ia = ia.update_nemesio
}
elseif key == "rata" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=9,h=8 },
bbo = { left=0, top=5, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/rata.gif"),
animation = "rata",
state = me.ALIVE,
enemy = true,
room = options.room,
ia = ia.update_rata
}
elseif key == "gota" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=8 },
bbo = { left=2, top=3, right=3, bottom=1 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/gota.gif"),
animation = "gota",
state = me.ALIVE,
enemy = true,
timer = gota_wait,
room = options.room,
ia = ia.update_gota
}
gota_wait = gota_wait + 10
if gota_wait > 40 then gota_wait = 1 end
elseif key == "gota_caiguent" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=8 },
bbo = { left=2, top=3, right=3, bottom=1 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/gota.gif"),
animation = "gota",
state = me.ALIVE,
enemy = true,
room = options.room,
ia = ia.update_gota_caiguent
}
elseif key == "gota_esguit" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
dir = options.dir,
size = { w=8,h=8 },
bbo = { left=2, top=3, right=3, bottom=1 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/gota.gif"),
animation = "esguit",
state = me.ALIVE,
enemy = true,
room = options.room,
ia = ia.update_gota_esguit
}
elseif key == "berserk" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=16 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/berserk.gif"),
animation = "mummy_walk",
state = me.ALIVE,
enemy = true,
room = options.room,
ia = ia.update_berserk
}
elseif key == "abad" then
sprite = {
type = key,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=18 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("gfx/abad.gif"),
animation = "abad",
state = me.ALIVE,
enemy = true,
room = options.room,
ia = ia.update_coin
}
else
error("Template not recognized")
end
--sprite.room = rooms.current()
print("creat sprite de tipus "..type)
return sprite
end

View File

@@ -1,73 +0,0 @@
require "ui"
require "util"
msgbox = {
title = "TITOL",
text = { "Este es el missatge.", "Pot estar en varies linies" },
buttons = { {"YES", sys.quit}, {"NO", app.pop} },
selected = 0,
w = 100,
h = 50,
show = function(title, text, buttons, default)
msgbox.selected = default or 1
msgbox.title = title
msgbox.text = text
msgbox.buttons = buttons
msgbox.w = 0
for i,v in ipairs(msgbox.text) do
local width = #v*4+8
if width > msgbox.w then msgbox.w = width end
end
msgbox.h = #msgbox.text*6+35
app.push(msgbox.update)
end,
update = function()
local top = (160-msgbox.w)//2
local left = (104-msgbox.h)//2
view.clip(top, left, msgbox.w, msgbox.h)
view.origin(top, left)
draw.outset(0, 0, msgbox.w, msgbox.h)
draw.rectf(1,1,msgbox.w-2, 7, 21)
draw.text(msgbox.title, 2, 2, 28)
local y = 12
for i,v in ipairs(msgbox.text) do
draw.text(v, 5, y, 1)
y = y + 6
end
local mx, my = mouse.pos()
local x = msgbox.w - 35
y = msgbox.h - 12
for i,v in ipairs(msgbox.buttons) do
local inside = util.inside(mx, my, {x, y, 32, 9})
draw.outset(x, y, 32, 9)
if inside then
draw.rectf(x+1,y+1,30,7,27)
if mouse.down(mouse.LEFT) then draw.inset(x, y, 32, 9) end
end
local offset = (32-#v[1]*4)//2
draw.text(v[1], x+1+offset, y+2, 1)
if (i==msgbox.selected) then
draw.rect(x-1, y-1, 34, 11, 1)
end
if mouse.press(mouse.LEFT) then
if inside then
v[2]()
end
end
x = x - 34
end
if key.press(key.ESCAPE) then
app.pop()
end
end
}

View File

@@ -1,60 +0,0 @@
palfade = {
original = {},
reddish = {},
init = function ()
for i=1,32 do
palfade.reddish[i] = {r=palfade.original[i].r, g=palfade.original[i].g, b=palfade.original[i].b}
end
end,
luminance = function(r, g, b)
return (0.2126*r + 0.7152*g + 0.0722*b)/255
end,
reddish_limit = function(r, g, b)
local t = palfade.luminance(r, g, b) / 255
local R = 255 * t
local G = g * (1 - t)
local B = b * (1 - t)
return R, G, B
end,
fade_reddish_color = function(r, g, b, f)
--local Rr, Gr, Br = palfade.reddish_limit(r, g, b)
local ff = math.min(1, f+palfade.luminance(r,g,b))
local R = math.floor(r*ff)--math.floor(r + (Rr - r) * f)
local G = math.floor(g*f)--math.floor(g + (Gr - g) * f)
local B = math.floor(b*f)--math.floor(b + (Br - b) * f)
-- local R = math.floor(r + (Rr - r) * f)
-- local G = math.floor(g + (Gr - g) * f)
-- local B = math.floor(b + (Br - b) * f)
return R, G, B
end,
fade_reddish = function(f)
for i=1,32 do
local r, g, b = palfade.fade_reddish_color(palfade.original[i].r, palfade.original[i].g, palfade.original[i].b, f)
palfade.reddish[i].r, palfade.reddish[i].g, palfade.reddish[i].b = r, g, b
pal.color(i-1,r,g,b)
end
end,
fade_red = function(f)
for i=1,32 do
local r = math.floor(palfade.reddish[i].r + (255-palfade.reddish[i].r)*f)
local g = math.floor(palfade.reddish[i].g - (palfade.reddish[i].g)*f)
local b = math.floor(palfade.reddish[i].b - (palfade.reddish[i].b)*f)
pal.color(i-1,r,g,b)
end
end,
restore = function()
pal.set(palfade.original)
end
}

View File

@@ -1,52 +0,0 @@
popup={
list = {},
old_update = nil,
current = nil,
create = function(label,x,y)
popup.list[label] = {x=x, y=y, width=50, options={}}
end,
addOption = function(parent, label, action)
popup.list[parent].options[#popup.list[parent].options+1] = { label=label, action=action }
local option_width = #label*4+4
if option_width > popup.list[parent].width then
popup.list[parent].width = option_width
end
end,
show = function(label)
popup.current = label
app.push(popup.update)
end,
update = function()
view.origin(0,0)
local mx, my = mouse.pos()
local p = popup.list[popup.current]
draw.outset(p.x, p.y, p.width, #p.options*7+2)
local y = p.y+2
for k,v in ipairs(p.options) do
local inside = util.inside(mx, my, {p.x, y-2, p.width, 7})
if inside then
draw.rectf(p.x+1, y-1, p.width-2, 7, 21)
if mouse.press(mouse.LEFT) then
app.pop()
v.action()
end
end
draw.text(v.label, p.x+2, y, 28)
y = y + 7
end
local inside = util.inside(mx, my, {p.x, p.y, p.width, #p.options*7+2})
if not inside and mouse.down(mouse.LEFT) then
mouse.discard()
app.pop()
end
if key.press(key.ESCAPE) then
app.pop()
end
end
}

View File

@@ -1,158 +0,0 @@
require "sprites"
LAYER_FOREGROUND = 1
LAYER_BACKGROUND = 2
LAYER_ITEMS = 4
LAYER_SPRITES = 8
LAYER_SHADOWS = 16
LAYER_ALL = 31
ROOM_FILE_EXT = ".gif"
rooms = {
surf_background = nil,
surf_foreground = nil,
surf_items = nil,
surf_original_items = nil,
visibility = LAYER_ALL,
pos = {x=0, y=4*12},
current = function()
return (rooms.pos.x//20) + (rooms.pos.y//12) * 8
end,
init = function()
rooms.pos.x, rooms.pos.y = 0,4*12
if rooms.surf_background ~= nil then surf.free(rooms.surf_background) end
rooms.surf_background = surf.load("rooms_background"..ROOM_FILE_EXT)
--rooms.surf_background = surf.new(20*8,12*8)
if rooms.surf_foreground ~= nil then surf.free(rooms.surf_foreground) end
rooms.surf_foreground = surf.load("rooms_foreground"..ROOM_FILE_EXT)
--rooms.surf_foreground = surf.new(20*8,12*8)
if rooms.surf_items ~= nil then surf.free(rooms.surf_items) end
rooms.surf_items = surf.load("rooms_items"..ROOM_FILE_EXT)
--rooms.surf_items = surf.new(20*8,12*8)
rooms.surf_original_items = surf.new(20*8,12*8)
rooms.update_original_items()
--surf.source(rooms.surf_items)
--surf.target(rooms.surf_original_items)
--draw.surf(0,0,160,96,0,0)
sprites.init()
--map.surf(rooms.surf_background)
--for y=0,12*8 do
-- for x=0,20*8 do
-- map.tile(x,y,38)
-- end
--end
--map.surf(rooms.surf_foreground)
--map.tile(10,10,16)
--surf.save(rooms.surf_background, "data/rooms_background.bin")
--surf.save(rooms.surf_foreground, "data/rooms_foreground.bin")
--surf.save(rooms.surf_items, "data/rooms_items.bin")
end,
save = function()
local p = {}
for i=0,255 do p[i] = {r=i,g=i,b=i} end
surf.save(rooms.surf_background, "data/rooms_background"..ROOM_FILE_EXT, p)
surf.save(rooms.surf_foreground, "data/rooms_foreground"..ROOM_FILE_EXT, p)
surf.save(rooms.surf_items, "data/rooms_items"..ROOM_FILE_EXT, p)
editor.modified = false
end,
is_outside = function(x, y)
return x < rooms.pos.x or y < rooms.pos.y or x > rooms.pos.x + 20 or y > rooms.pos.y + 12
end,
draw = function()
-- Retallem la pantalla a la zona de joc
view.clip(0,8,160,96)
-- Movem la càmara a l'habitació on estem
view.origin(-rooms.pos.x*8,-rooms.pos.y*8+8)
-- Pintem el background
surf.source(surf_tiles)
map.surf(rooms.surf_background)
if rooms.is_visible(LAYER_BACKGROUND) then
map.draw()
else
draw.rectf(0,0,160,96,1)
end
-- Movem 4x4 pixels la càmara per a pintar les sombres dels sprites i el foreground
view.origin(-rooms.pos.x*8+4,-rooms.pos.y*8+12)
-- Pintem el foreground de negre
map.surf(rooms.surf_foreground)
pal.subpal(0,32,1)
if rooms.is_visible(LAYER_FOREGROUND | LAYER_SHADOWS) then map.draw() end
-- Pintem els sprites de negre
if rooms.is_visible(LAYER_SPRITES | LAYER_SHADOWS) then
sprites.draw(true)
--draw.surf(0, 0, 16, 17, 20, 15, 16, 17)
end
-- Movem la càmara al lloc que toca de nou, i tornem la paleta normal
view.origin(-rooms.pos.x*8,-rooms.pos.y*8+8)
pal.subpal()
-- Pintem el foreground
surf.source(surf_tiles)
map.surf(rooms.surf_foreground)
if rooms.is_visible(LAYER_FOREGROUND) then map.draw() end
-- Pintem els sprites
if rooms.is_visible(LAYER_SPRITES) then
sprites.draw()
--draw.surf(0, 0, 16, 17, 20, 15, 16, 17)
end
-- Pintem la rejilla
--for y=0,12 do draw.line(0,y*8, 160, y*8, 27) end
--for x=0,20 do draw.line(x*8, 0, x*8, 104, 27) end
end,
is_visible = function(layer)
return rooms.visibility & layer == layer
end,
set_visibility = function(layer, visibility)
if visibility then
rooms.visibility = rooms.visibility | layer
else
rooms.visibility = rooms.visibility & ~layer
end
end,
toggle_visibility = function(layer)
if rooms.visibility & layer == layer then
rooms.visibility = rooms.visibility & ~layer
else
rooms.visibility = rooms.visibility | layer
end
end,
peiv = function()
pal.color(1, 1, 1, 1)
return "HOLA OTHER UNIT"
end,
retrieve_original_items = function()
surf.source(rooms.surf_original_items)
surf.target(rooms.surf_items)
draw.surf(0,0,160,96,0,0)
end,
update_original_items = function()
surf.source(rooms.surf_items)
surf.target(rooms.surf_original_items)
draw.surf(0,0,160,96,0,0)
end
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,20 +0,0 @@
score = {
points = 0,
color = 28,
zoom = 1,
init = function()
score.points = 0
end,
draw = function()
draw.rectf(0,0,160,8,1)
draw.text(string.format("%03d", score.points),0,0,score.color)
end,
inc = function(value)
print("score.inc()")
score.points = score.points + value
tweening.add(8, 0, 0.5, easing.linear, function(val,progress,finished) score.color = (math.floor(val)&1) == 0 and 28 or 14 end)
end
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,452 +0,0 @@
require "animations"
require "templates"
sprites = {
hero = nil,
list = {},
pause_ia = false,
remove = function(sprite)
for i,v in ipairs(sprites.list) do
if v == sprite then
table.remove(sprites.list, i)
print("Sprite removed: "..sprite.type)
return
end
end
end,
remove_out_of_room = function()
--print("Current room: "..rooms.current())
--for i,v in ipairs(sprites.list) do
-- if v.room ~= rooms.current() then
-- table.remove(sprites.list, i)
-- local room = v.room or 0
-- print("Sprite at room "..room.." removed: "..v.type)
-- end
--end
end,
add_from_room = function(rx,ry)
sprites.list = {}
map.surf(rooms.surf_items)
for y = ry, ry+11 do
for x = rx, rx+19 do
if map.tile(x,y) ~= 0 then
local room = (rx//20) + (ry//12) * 8
local item = map.tile(x,y)
local flip = item > 0x7f
item = item & 0x7f
io.write("crear "..items[item].name.." en hab "..room.." ("..x..","..y..")...\n")
table.insert(sprites.list, templates.create(items[item].name, {pos={x=x*8, y=y*8},flipped=flip, room=room}))
end
end
--io.write("\n")
end
end,
init = function()
sprites.hero = {
type = "hero",
pos = { x=28, y=4*12*8+71 },
size= { w=16, h=17 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = false,
surf = surf.load("morcus.gif"),
animation = "hero_stand",
ia = sprites.update_hero,
jumping = 0,
light = 100,
light_ox = 0,
light_oy = 0,
cooldown = 0,
stairs = false
}
--table.insert(sprites.list, templates.create("mummy", {pos={x=100, y=4*12*8+71},flipped=true}))
--local mummy = {
-- pos = { x=100, y=4*12*8+71 },
-- size = { w=16,h=17 },
-- bbo = { left=3, top=2, right=3, bottom=0 },
-- current_frame = 1,
-- current_wait = 1,
-- flipped = true,
-- animation = "mummy_walk",
-- ia = sprites.update_mummy
--}
--table.insert(sprites.list, mummy)
end,
set_animation=function(sprite, animation)
if sprite.animation ~= animation then
sprite.animation = animation
sprite.current_frame = 1
local cycle = animations[sprite.animation].cycle[1]
sprite.current_wait = animations[sprite.animation].frames[cycle].wait
end
end,
check_sprite_collision = function()
return false
end,
check_tile_collision = function()
end,
update = function()
if not sys.beat() then return end
sprites.update_sprite(sprites.hero)
for i,v in ipairs(sprites.list) do
sprites.update_sprite(v)
end
if not sprites.pause_ia then
sprites.hero.ia()
for i,v in ipairs(sprites.list) do
v.ia(v)
end
end
end,
update_sprite = function(sprite)
sprite.current_wait = sprite.current_wait - 1
if sprite.current_wait == 0 then
if sprite.current_frame < #animations[sprite.animation].cycle then
sprite.current_frame = sprite.current_frame + 1
else
sprite.current_frame = 1
end
local cycle = animations[sprite.animation].cycle[sprite.current_frame]
sprite.current_wait = animations[sprite.animation].frames[cycle].wait
end
end,
update_mummy = function(spr)
if spr.state == templates.ALIVE then
if spr.flipped then
local tx, ty = (spr.pos.x+3)>>3, (spr.pos.y+15)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x - 1
else
spr.flipped = not spr.flipped
end
else
local tx, ty = (spr.pos.x+12)>>3, (spr.pos.y+15)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 and map.tile(tx,ty+1) > 0 then
spr.pos.x = spr.pos.x + 1
else
spr.flipped = not spr.flipped
end
end
elseif spr.state == templates.DYING then
if spr.animation ~= "mummy_dying" then
sprites.set_animation(spr, "mummy_dying")
else
if spr.current_frame == 8 then
sprites.set_animation(spr, "mummy_dead")
spr.state = templates.DEAD
end
end
elseif spr.state == templates.DEAD then
if spr.current_wait == 1 then
sprites.set_animation(spr, "mummy_undying")
spr.state = templates.RESURRECTING
end
elseif spr.state == templates.RESURRECTING then
if spr.current_frame == 13 then
sprites.set_animation(spr, "mummy_walk")
spr.state = templates.ALIVE
end
end
end,
update_bullet = function(spr)
local tx, ty, ty2 = (spr.pos.x+2)>>3, (spr.pos.y+1)>>3, (spr.pos.y+2)>>3
if rooms.is_outside(tx,ty) then sprites.remove(spr) return end
local x1,y1,w1,h1 = util.aabb(spr)
for i,v in ipairs(sprites.list) do
if v.enemy and v.state ~= templates.DEAD then
local x2,y2,w2,h2 = util.aabb(v)
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
if v.state == templates.ALIVE then v.state = templates.DYING end
sprites.remove(spr)
return
end
end
end
if map.tile(tx,ty) < 16 or map.tile(tx,ty2) < 16 then
if spr.flipped then
spr.pos.x = spr.pos.x - 8
else
spr.pos.x = spr.pos.x + 8
end
else
sprites.remove(spr)
end
end,
update_coin = function(spr)
if spr.state == templates.ALIVE then
local x1,y1,w1,h1 = util.aabb(spr)
--for i,v in ipairs(sprites.list) do
--if v.type == "hero" then
local x2,y2,w2,h2 = util.aabb(sprites.hero)
if util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2) then
local tx, ty = (spr.pos.x)>>3, (spr.pos.y)>>3
map.surf(rooms.surf_items)
map.tile(tx,ty,0)
spr.state = templates.DYING
sprites.set_animation(spr, "coin_picked")
spr.pos.y=spr.pos.y-16
spr.pos.x=spr.pos.x-4
spr.timer = 0
score.inc(10)
return
end
--end
--end
elseif spr.state == templates.DYING then
spr.pos.y = spr.pos.y - 0.5
spr.timer = spr.timer + 1
if spr.timer == 32 then
sprites.remove(spr)
end
end
end,
update_brick = function(spr)
if spr.timeout > 0 then
spr.timeout = spr.timeout - 1
if spr.timeout == 0 then
local tx, ty = spr.pos.x>>3, spr.pos.y>>3
map.tile(tx,ty,0)
end
else
spr.pos.y = spr.pos.y + 2
local tx, ty = (spr.pos.x+2)>>3, (spr.pos.y)>>3
if rooms.is_outside(tx,ty) then sprites.remove(spr) return end
end
end,
update_hero = function()
--game.draw_light(sprites.hero.pos.x, sprites.hero.pos.y,100)
-- Update hero
local anim = "hero_stand"
local move_anim = "hero_walk"
-- Si estem en cooldown desde l'ultim dispar, decrementem el contador
if sprites.hero.cooldown > 0 then
sprites.hero.cooldown = sprites.hero.cooldown - 1
end
-- si està en l'animació de disparar, no podem fer res i eixim ja
if sprites.hero.shooting then
-- A no ser que siga l'ultim frame, en tal cas tornem a estar de peu i au
if sprites.hero.current_frame==3 then
sprites.hero.shooting = false
if sprites.hero.flipped then sprites.hero.pos.x=sprites.hero.pos.x+8 end
sprites.set_animation(sprites.hero, "hero_stand")
else
return
end
end
-- SI ESTÀ BOTANT...
if sprites.hero.jumping > 0 then
anim = "hero_jump"
move_anim = "hero_jump"
local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y)>>3
--draw.rect(tx1<<3,ty<<3,8,8,8)
--draw.rect(tx2<<3,ty<<3,8,8,28)
if map.tile(tx1,ty) == 0 and map.tile(tx2,ty) == 0 then
if ty+1<rooms.pos.y then
game.change_room(0,-1)
else
if sprites.hero.jumping > 1 then sprites.hero.pos.y = sprites.hero.pos.y - 1 end
end
else
sprites.hero.jumping = 0
end
sprites.hero.jumping = sprites.hero.jumping - 1
else
-- SI NO ESTÀ BOTANT...
-- SI ESTÀ EN UNES ESCALERES...
local txm, ty = (sprites.hero.pos.x+8)>>3, (sprites.hero.pos.y+8)>>3
if (map.tile(txm,ty) > 0 and map.tile(txm,ty) < 16) or (map.tile(txm,ty+1) > 0 and map.tile(txm,ty+1) < 16) then
anim = "hero_stairs_idle"
move_anim = "hero_stairs"
-- SI PULSA AMUNT...
if key.down(key.UP) or pad.down(pad.UP) then
anim = move_anim
local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y)>>3
if map.tile(tx1,ty) < 16 or map.tile(tx2,ty) < 16 then
if ty+1<rooms.pos.y then
game.change_room(0,-1)
else
sprites.hero.pos.y = sprites.hero.pos.y - 1
end
end
-- SI PULSA AVALL...
elseif key.down(key.DOWN) or pad.down(pad.DOWN) then
anim = move_anim
local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y+1)>>3
if map.tile(tx1,ty+2) < 16 or map.tile(tx2,ty+2) < 16 then
if ty+2>rooms.pos.y+11 then
game.change_room(0,1)
else
sprites.hero.pos.y = sprites.hero.pos.y + 1
end
end
end
else
-- SI NO ESTÀ EN UNES ESCALERES...
local tx1, txm, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+8)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y+1)>>3
--draw.rect(tx1<<3, (ty+2)<<3,8,8,8)
--draw.rect(tx2<<3, (ty+2)<<3,8,8,28)
-- SI ESTÀ CAIGUENT...
local tile_under_me1 = map.tile(tx1,ty+2)
local tile_under_me2 = map.tile(tx2,ty+2)
if tile_under_me1 == 0 and tile_under_me2 == 0 then
if ty+2>rooms.pos.y+11 then
game.change_room(0,1)
else
sprites.hero.pos.y = sprites.hero.pos.y + 2
end
else
-- SI NO ESTÀ CAIGUENT...
if tile_under_me1==84 then
map.tile(tx1,ty+2,68)
local broken_tile = templates.create("brick", {pos={x=tx1<<3, y=(ty+2)<<3}, flipped=sprites.hero.flipped})
table.insert(sprites.list, broken_tile)
end
if tile_under_me2==84 then
map.tile(tx2,ty+2,68)
local broken_tile = templates.create("brick", {pos={x=tx2<<3, y=(ty+2)<<3}, flipped=sprites.hero.flipped})
table.insert(sprites.list, broken_tile)
end
sprites.hero.pos.y = (ty<<3)-1
anim = "hero_stand"
-- SI ESTÀ SOBRE UNES ESCALERES I POLSA AVALL...
if (map.tile(txm,ty+2) < 16 and map.tile(txm,ty+2) > 0) then
if key.down(key.DOWN) or pad.down(pad.DOWN) then
anim = "hero_stairs"
--local tx1, tx2, ty = (sprites.hero.pos.x+4)>>3, (sprites.hero.pos.x+11)>>3, (sprites.hero.pos.y+1)>>3
--if map.tile(tx1,ty+2) < 16 or map.tile(tx2,ty+2) < 16 then
sprites.hero.pos.x = (txm << 3)-4
sprites.hero.pos.y = sprites.hero.pos.y + 1
--end
end
end
-- SI POLSA BOTAR...
if key.down(key.X) or pad.down(pad.A) then
sprites.hero.jumping = 17
-- SI POLSA DISPAR...
elseif (sprites.hero.cooldown==0) and (key.down(key.Z) or pad.down(pad.B)) then
sprites.hero.shooting = true
sprites.hero.cooldown = 20
local x = sprites.hero.flipped and sprites.hero.pos.x+8 or sprites.hero.pos.x-8
local bullet = templates.create("bullet", {pos={x=sprites.hero.pos.x, y=sprites.hero.pos.y+7}, flipped=sprites.hero.flipped})
table.insert(sprites.list, bullet)
if sprites.hero.flipped then sprites.hero.pos.x=sprites.hero.pos.x-8 end
anim = "hero_shoot"
end
end
end
end
-- ESTIGA COM ESTIGA, SI POLSA ESQUERRA O DRETA...
if not sprites.hero.shooting then
if key.down(key.LEFT) or pad.down(pad.LEFT) then
sprites.hero.flipped = true
anim = move_anim
local tx, ty = (sprites.hero.pos.x+3)>>3, (sprites.hero.pos.y+16)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 then
if tx<rooms.pos.x then
game.change_room(-1,0)
else
sprites.hero.pos.x = sprites.hero.pos.x - 1
end
end
elseif key.down(key.RIGHT) or pad.down(pad.RIGHT) then
sprites.hero.flipped = false
anim = move_anim
local tx, ty = (sprites.hero.pos.x+12)>>3, (sprites.hero.pos.y+16)>>3
if map.tile(tx,ty) < 16 and map.tile(tx,ty-1) < 16 then
if tx>rooms.pos.x+19 then
game.change_room(1,0)
else
sprites.hero.pos.x = sprites.hero.pos.x + 1
end
end
end
end
sprites.set_animation(sprites.hero, anim)
end,
draw = function(ignore_selected)
if app.update ~= editor.update then
surf.target(game.circ_buf)
surf.cls()
surf.target(game.back_buf)
end
editor.item_hovered = nil
local mx,my = mouse.pos()
if editor.item_selected or editor.layer~=LAYER_ITEMS then ignore_selected = true end
for i,v in ipairs(sprites.list) do
if not ignore_selected and app.update == editor.update and mx>=v.pos.x and mx<=v.pos.x+v.size.w and my>=v.pos.y and my<=v.pos.y+v.size.h then
sprites.draw_sprite_selected(v)
editor.item_hovered = i
else
sprites.draw_sprite(v)
end
end
sprites.draw_sprite(sprites.hero)
end,
draw_sprite = function(sprite)
local cycle = animations[sprite.animation].cycle[sprite.current_frame]
local frame = animations[sprite.animation].frames[cycle]
if not frame then
print(sprite.current_frame)
end
local reversed = frame.reversed or false
surf.source(sprite.surf)
draw.surf(frame.frame.x, frame.frame.y, frame.frame.w, frame.frame.h, sprite.pos.x, sprite.pos.y, frame.frame.w, frame.frame.h, (not reversed) ~= (not sprite.flipped))
if cheats.showaabb then
local x,y,w,h = util.aabb(sprite)
draw.rect(x,y,w,h,8)
end
if (app.update ~= editor.update) and (sprite.light) then
game.draw_light(sprite.pos.x+sprite.light_ox, sprite.pos.y+sprite.light_oy,sprite.light)
end
end,
draw_sprite_selected = function(sprite)
pal.subpal(0,32,28)
local cycle = animations[sprite.animation].cycle[sprite.current_frame]
local frame = animations[sprite.animation].frames[cycle]
local reversed = frame.reversed or false
local x, y, w, h, sx, sy, f = sprite.pos.x, sprite.pos.y, frame.frame.w, frame.frame.h, frame.frame.x, frame.frame.y, (not reversed) ~= (not sprite.flipped)
surf.source(sprite.surf)
draw.surf(sx, sy, w, h, x-1, y-1, w, h, f)
draw.surf(sx, sy, w, h, x, y-1, w, h, f)
draw.surf(sx, sy, w, h, x+1, y-1, w, h, f)
draw.surf(sx, sy, w, h, x-1, y, w, h, f)
draw.surf(sx, sy, w, h, x+1, y, w, h, f)
draw.surf(sx, sy, w, h, x-1, y+1, w, h, f)
draw.surf(sx, sy, w, h, x, y, w, h, f)
draw.surf(sx, sy, w, h, x+1, y+1, w, h, f)
pal.subpal()
draw.surf(sx, sy, w, h, x, y, w, h, f)
end
}

View File

@@ -1,6 +1,6 @@
require "menu" require ":modules.menu"
require "msgbox" require ":utils.msgbox"
require "items" require ":modules.items"
editor = { editor = {
@@ -14,20 +14,31 @@ editor = {
item_dragged=nil, item_dragged=nil,
dragged_start_pos=nil, dragged_start_pos=nil,
flip=false, flip=false,
msg=nil,
msg_timeout=0,
enable = function() enable = function()
app.update = editor.update app.update = editor.update
sys.beat(2) sys.beat(5)
shader.disable(); shader.disable();
pal.set(palfade.original)
end, end,
update = function() update = function()
if sys.beat() then
editor.ants = (editor.ants<<12) | (editor.ants>>4)
end
view.origin(0,0) view.origin(0,0)
surf.target(0) surf.target(0)
-- Pintar el menú (el marcador serà en el modul game.lua) -- Pintar fondo quadrejat, per si la capa background està oculta
--score.draw() for y=0,104,8 do
menu.draw() for x=0,160,8 do
local color = (((x+y)//8)%2==0) and 23 or 16
draw.rectf(x, y, 8, 8, color);
end
end
-- Pintar el mapa i sprites -- Pintar el mapa i sprites
rooms.draw() rooms.draw()
@@ -37,18 +48,16 @@ editor = {
local tx, ty = (mx>>3), (my>>3) local tx, ty = (mx>>3), (my>>3)
mx, my = tx<<3, ty<<3 mx, my = tx<<3, ty<<3
if my>=0 then if menu.hidden then
if editor.layer==LAYER_BACKGROUND or editor.layer==LAYER_FOREGROUND then if editor.layer==LAYER_BACKGROUND or editor.layer==LAYER_FOREGROUND then
if editor.selection then if editor.selection then
local rx1,ry1,rx2,ry2=editor.selection.x1<<3,editor.selection.y1<<3,editor.selection.x2<<3,editor.selection.y2<<3 local rx1,ry1,rx2,ry2=editor.selection.x1<<3,editor.selection.y1<<3,editor.selection.x2<<3,editor.selection.y2<<3
if rx1>rx2 then rx1,rx2=rx2,rx1 end if rx1>rx2 then rx1,rx2=rx2,rx1 end
if ry1>ry2 then ry1,ry2=ry2,ry1 end if ry1>ry2 then ry1,ry2=ry2,ry1 end
draw.mode(draw.PATTERN)
draw.pattern(editor.ants) draw.pattern(editor.ants)
draw.rect(rx1-1, ry1-1, rx2-rx1+10, ry2-ry1+10, 28) draw.rect(rx1-1, ry1-1, rx2-rx1+10, ry2-ry1+10, 28)
draw.pattern(0xffff) draw.mode(draw.NORMAL)
if sys.beat() then
editor.ants = (editor.ants<<12) | (editor.ants>>4)
end
else else
draw.rect(mx-1, my-1, editor.brush.w*8+2, editor.brush.h*8+2, 28) draw.rect(mx-1, my-1, editor.brush.w*8+2, editor.brush.h*8+2, 28)
draw.rect(mx, my, editor.brush.w*8, editor.brush.h*8, 1) draw.rect(mx, my, editor.brush.w*8, editor.brush.h*8, 1)
@@ -98,7 +107,7 @@ editor = {
editor.modified = true editor.modified = true
end end
if mouse.press(mouse.LEFT) then if mouse.press(mouse.LEFT) then
if editor.item_selected then if not editor.item_hovered and not editor.item_dragged and editor.item_selected then
map.surf(rooms.surf_items) map.surf(rooms.surf_items)
--print(editor.item_selected) --print(editor.item_selected)
map.tile(tx,ty,editor.item_selected) map.tile(tx,ty,editor.item_selected)
@@ -111,71 +120,88 @@ editor = {
if mouse.press(mouse.RIGHT) then if mouse.press(mouse.RIGHT) then
editor.item_selected = nil editor.item_selected = nil
end end
if editor.item_selected then if not editor.item_hovered and not editor.item_dragged and editor.item_selected then
local k = items[editor.item_selected] local k = items[editor.item_selected]
surf.source(surf_sprites)
draw.surf(k.visual.x, k.visual.y, k.visual.w, k.visual.h, mx, my, k.visual.w, k.visual.h, editor.flip) draw.surf(k.visual.x, k.visual.y, k.visual.w, k.visual.h, mx, my, k.visual.w, k.visual.h, editor.flip)
end end
end end
end
view.origin(0,0) if key.press(key.ESCAPE) then
draw.text(rooms.pos.x//20,1,96,28) --editor.quit()
draw.text(rooms.pos.y//12,5,96,28) menu.toggle()
elseif key.press(key.RIGHT) and rooms.pos.x < 20*7 then
if key.press(key.ESCAPE) then rooms.pos.x = rooms.pos.x + 20
editor.quit() sprites.add_from_room(rooms.pos.x, rooms.pos.y)
elseif key.press(key.RIGHT) and rooms.pos.x < 20*7 then elseif key.press(key.LEFT) and rooms.pos.x > 0 then
rooms.pos.x = rooms.pos.x + 20 rooms.pos.x = rooms.pos.x - 20
sprites.remove_out_of_room() sprites.add_from_room(rooms.pos.x, rooms.pos.y)
sprites.add_from_room(rooms.pos.x, rooms.pos.y) elseif key.press(key.DOWN) and rooms.pos.y < 13*7 then
elseif key.press(key.LEFT) and rooms.pos.x > 0 then rooms.pos.y = rooms.pos.y + 13
rooms.pos.x = rooms.pos.x - 20 sprites.add_from_room(rooms.pos.x, rooms.pos.y)
sprites.remove_out_of_room() elseif key.press(key.UP) and rooms.pos.y > 0 then
sprites.add_from_room(rooms.pos.x, rooms.pos.y) rooms.pos.y = rooms.pos.y - 13
elseif key.press(key.DOWN) and rooms.pos.y < 12*7 then sprites.add_from_room(rooms.pos.x, rooms.pos.y)
rooms.pos.y = rooms.pos.y + 12 elseif key.press(key.TAB) or key.press(key.ESCAPE) then
sprites.remove_out_of_room() if editor.layer==LAYER_BACKGROUND or editor.layer==LAYER_FOREGROUND then
sprites.add_from_room(rooms.pos.x, rooms.pos.y) editor.tilepicker.show()
elseif key.press(key.UP) and rooms.pos.y > 0 then else
rooms.pos.y = rooms.pos.y - 12 editor.itempicker.show()
sprites.remove_out_of_room() end
sprites.add_from_room(rooms.pos.x, rooms.pos.y) elseif key.press(key.P) then
elseif key.press(key.TAB) or key.press(key.ESCAPE) then sprites.hero.pos.x = tx*8-4
if editor.layer==LAYER_BACKGROUND or editor.layer==LAYER_FOREGROUND then sprites.hero.pos.y = ty*8-9
editor.tilepicker.show() elseif key.press(key.F9) then
else editor.play()
editor.itempicker.show() elseif key.press(key.F11) then
reload_textures()
elseif key.press(key.N1) then
editor.layer=LAYER_FOREGROUND
editor.msg="FOREGROUND"
editor.msg_timeout = 20
elseif key.press(key.N2) then
editor.layer=LAYER_BACKGROUND
editor.msg="BACKGROUND"
editor.msg_timeout = 20
elseif key.press(key.N3) then
editor.layer=LAYER_ITEMS
editor.msg="ITEMS"
editor.msg_timeout = 20
end end
elseif key.press(key.P) then
sprites.hero.pos.x = tx*8-4
sprites.hero.pos.y = ty*8-9
elseif key.press(key.F9) then
editor.play()
elseif key.press(key.F11) then
reload_textures()
end
if editor.layer==LAYER_ITEMS then if editor.layer==LAYER_ITEMS then
if key.press(key.F) then if key.press(key.F) then
if editor.item_selected then if not editor.item_hovered and editor.item_selected then
editor.flip = not editor.flip editor.flip = not editor.flip
elseif editor.item_hovered then elseif editor.item_hovered then
local sprite = sprites.list[editor.item_hovered]
sprite.flipped = not sprite.flipped
map.surf(rooms.surf_items)
local tile = map.tile(sprite.pos.x//8, sprite.pos.y//8)
if tile > 0x7f then tile = tile & 0x7f else tile = tile | 0x80 end
map.tile(sprite.pos.x//8, sprite.pos.y//8, tile)
editor.modified = true
end
end
if editor.item_hovered and key.press(key.DELETE) then
local sprite = sprites.list[editor.item_hovered] local sprite = sprites.list[editor.item_hovered]
sprite.flipped = not sprite.flipped
map.surf(rooms.surf_items) map.surf(rooms.surf_items)
local tile = map.tile(sprite.pos.x//8, sprite.pos.y//8) map.tile(sprite.pos.x//8,sprite.pos.y//8,0)
if tile > 0x7f then tile = tile & 0x7f else tile = tile | 0x80 end sprites.remove(sprite)
map.tile(sprite.pos.x//8, sprite.pos.y//8, tile)
editor.modified = true
end end
end end
if editor.item_hovered and key.press(key.DELETE) then
local sprite = sprites.list[editor.item_hovered]
map.surf(rooms.surf_items)
map.tile(sprite.pos.x//8,sprite.pos.y//8,0)
sprites.remove(sprite)
end
end end
view.origin(0,0)
draw.text(rooms.pos.x//20,1,96,28)
draw.text(rooms.pos.y//13,5,96,28)
if editor.msg_timeout > 0 then
editor.msg_timeout = editor.msg_timeout - 1
draw.text(editor.msg, 10, 96, 8)
end
menu.draw()
end, end,
create_stamp=function() create_stamp=function()
@@ -212,7 +238,7 @@ editor = {
for y=1,h do for y=1,h do
for x=1,w do for x=1,w do
local fx, fy = tx+x-1, ty+y-1 local fx, fy = tx+x-1, ty+y-1
if fx < rooms.pos.x+20 and fy < rooms.pos.y+12 then if fx < rooms.pos.x+20 and fy < rooms.pos.y+13 then
map.tile(fx,fy,editor.brush.tiles[p]) map.tile(fx,fy,editor.brush.tiles[p])
end end
p=p+1 p=p+1
@@ -222,12 +248,12 @@ editor = {
quit=function() quit=function()
if editor.modified then if editor.modified then
msgbox.show("IE MEN!", msgbox.show("SAVE CHANGES BEFORE CLOSING?",
{"Hi ha canvis sense guardar.", "Vols guardar-los abans d'eixir?"}, {"YOU HAVE UNSAVED CHANGES. IF YOU EXIT", "WITHOUT SAVING, CHANGES WILL BE LOST."},
{ {
{"Cancel", app.pop}, {"CANCEL", app.pop},
{"No", sys.quit}, {" EXIT ", sys.quit},
{"Yes", function() rooms.save() sys.quit() end} {" SAVE ", function() rooms.save() sys.quit() end}
} ) } )
else else
sys.quit() sys.quit()
@@ -249,16 +275,48 @@ editor = {
end, end,
tilepicker = { tilepicker = {
surf_back = nil,
pos_y = 24,
show = function() show = function()
if editor.tilepicker.surf_back == nil then editor.tilepicker.surf_back = surf.new(160,104) end
surf.source(0)
surf.target(editor.tilepicker.surf_back)
view.origin(0,0)
view.clip()
draw.surf(0,0,160,104,0,0)
app.push(editor.tilepicker.update_tiles) app.push(editor.tilepicker.update_tiles)
tweening.add(104,24,0.25,easing.easeOutCubic,function(value,n,finished)editor.tilepicker.pos_y=value end)
end,
close = function()
tweening.add(24,104,0.25,easing.easeInCubic,function(value,n,finished)editor.tilepicker.pos_y=value if finished then app.pop() end end)
end, end,
update_tiles = function() update_tiles = function()
surf.source(editor.tilepicker.surf_back)
surf.target(0)
view.origin(0,0) view.origin(0,0)
view.clip() view.clip()
draw.surf(0,0,160,104,0,0)
view.origin(8,editor.tilepicker.pos_y)
draw.rrect(0,-1,144,84,3,17)
draw.rrectf(0,0,144,84,3,20)
draw.text("CHOOSE TILES:",8,2,17)
view.origin(16,editor.tilepicker.pos_y+8)
-- Pintar fondo quadrejat, per si la capa background està oculta
for y=0,56,8 do
for x=0,120,8 do
local color = (((x+y)//8)%2==0) and 23 or 16
draw.rectf(x, y, 8, 8, color);
end
end
surf.source(surf_tiles) surf.source(surf_tiles)
surf.cls(1) --surf.cls(1)
draw.surf(0,0,128,128,0,0) draw.surf(0,0,128,128,0,0)
local mx, my = mouse.pos() local mx, my = mouse.pos()
@@ -275,47 +333,97 @@ editor = {
editor.brush.tiles={} editor.brush.tiles={}
editor.brush.tiles[1]=ty*16+tx editor.brush.tiles[1]=ty*16+tx
end end
app.pop() editor.tilepicker.close()
end end
if key.press(key.TAB) or key.press(key.ESCAPE) then if key.press(key.TAB) or key.press(key.ESCAPE) then
app.pop() editor.tilepicker.close()
end end
end end
}, },
itempicker = { itempicker = {
surf_back = nil,
pos_y = 24,
scroll = 0,
show = function() show = function()
if editor.itempicker.surf_back == nil then editor.itempicker.surf_back = surf.new(160,104) end
surf.source(0)
surf.target(editor.itempicker.surf_back)
view.origin(0,0)
view.clip()
draw.surf(0,0,160,104,0,0)
app.push(editor.itempicker.update_items) app.push(editor.itempicker.update_items)
tweening.add(104,24,0.25,easing.easeOutCubic,function(value,n,finished)editor.itempicker.pos_y=value end)
end,
close = function()
tweening.add(24,104,0.25,easing.easeInCubic,function(value,n,finished)editor.itempicker.pos_y=value if finished then app.pop() end end)
end, end,
update_items = function() update_items = function()
surf.source(editor.itempicker.surf_back)
surf.target(0)
view.origin(0,0) view.origin(0,0)
view.clip() view.clip()
draw.surf(0,0,160,104,0,0)
view.origin(8,editor.itempicker.pos_y)
draw.rrect(0,-1,144,84,3,17)
draw.rrectf(0,0,144,84,3,20)
draw.text("CHOOSE ITEM:",8,2,17)
view.origin(16,editor.itempicker.pos_y+8-editor.itempicker.scroll)
view.clip(16,editor.itempicker.pos_y+8,128,64)
surf.source(surf_sprites) surf.source(surf_sprites)
surf.cls(1)
local mx, my = mouse.pos() local mx, my = mouse.pos()
local x,y = 0,0 local x,y = 0,0
for i,k in pairs(items) do for i,k in pairs(items) do
local w = math.max(k.visual.w, #k.name*4) local w = math.max(k.visual.w, #k.label*4)
if x+w > 128 then
y=y+32
x=0
end
local ox = (w-k.visual.w)/2 local ox = (w-k.visual.w)/2
draw.text(k.name, x, y, 15) draw.text(k.label, x, y, 15)
draw.surf(k.visual.x, k.visual.y, k.visual.w, k.visual.h, x+ox, y+7) draw.surf(k.visual.x, k.visual.y, k.visual.w, k.visual.h, x+ox, y+7)
if mx>x and mx<x+w and my>y and my<y+7+k.visual.h then if mx>x and mx<x+w and my>y and my<y+7+k.visual.h then
draw.rect(x+ox, y+7, k.visual.w, k.visual.h, 28) draw.rect(x+ox, y+7, k.visual.w, k.visual.h, 28)
if mouse.press(mouse.LEFT) then if mouse.press(mouse.LEFT) then
editor.item_selected = i editor.item_selected = i
app.pop() editor.itempicker.close()
end end
end end
x=x+w+4 x=x+w+4
end end
y=y+32
local lift_h = math.floor(4096/y)
local lift_y = math.floor(((64-lift_h)*editor.itempicker.scroll)/(y-64))
view.origin(16,editor.itempicker.pos_y+8)
view.clip()
draw.rrectf(124,0,5,64,1,17)
draw.rrectf(124,lift_y,5,lift_h,1,2)
local mw = mouse.wheel()
editor.itempicker.scroll = editor.itempicker.scroll - mw*8
if key.press(key.TAB) or key.press(key.ESCAPE) then if key.press(key.TAB) or key.press(key.ESCAPE) then
app.pop() editor.itempicker.close()
elseif key.press(key.UP) then
editor.itempicker.scroll = editor.itempicker.scroll - 16
elseif key.press(key.DOWN) then
editor.itempicker.scroll = editor.itempicker.scroll + 16
end end
if editor.itempicker.scroll < 0 then editor.itempicker.scroll = 0 end
if editor.itempicker.scroll > y-64 then editor.itempicker.scroll = y-64 end
draw.text(tostring(editor.itempicker.scroll),20,20,1)
end end
} }
} }

View File

@@ -1,6 +1,6 @@
require "palfade" require ":utils.palfade"
require "console" require ":utils.console"
require "tweening" require ":utils.tweening"
function test() function test()
tweening.add(40, 100, 1, easing.easeOutCubic, function(value, progress, finished) sprites.hero.light = value end) tweening.add(40, 100, 1, easing.easeOutCubic, function(value, progress, finished) sprites.hero.light = value end)
@@ -37,7 +37,6 @@ game = {
end, end,
update = function() update = function()
tweening.update(sys.delta())
game.water_counter = game.water_counter + 0.05 game.water_counter = game.water_counter + 0.05
if game.fade>0 then if game.fade>0 then
@@ -52,7 +51,6 @@ game = {
surf.target(0) surf.target(0)
view.clip() view.clip()
score.draw()
surf.target(game.back_buf) surf.target(game.back_buf)
-- Pintar el mapa i sprites -- Pintar el mapa i sprites
@@ -62,8 +60,12 @@ game = {
game.apply_water() game.apply_water()
game.apply_light() game.apply_light()
score.draw()
if key.press(key.ESCAPE) or key.press(key.F9) then if key.press(key.ESCAPE) or key.press(key.F9) then
rooms.retrieve_original_items() rooms.reload()
sprites.add_from_room(rooms.pos.x, rooms.pos.y)
ia.hero_reset()
editor.enable() editor.enable()
elseif key.press(key.GRAVE) then elseif key.press(key.GRAVE) then
console.enable() console.enable()
@@ -76,7 +78,7 @@ game = {
game.chg_step = 8*4 game.chg_step = 8*4
sprites.pause_ia = true sprites.pause_ia = true
-- [TODO] Crear els sprites per als items de l'habitació a la que entrem -- [TODO] Crear els sprites per als items de l'habitació a la que entrem
sprites.add_from_room(rooms.pos.x+x*20, rooms.pos.y+y*12) sprites.add_from_room(rooms.pos.x+x*20, rooms.pos.y+y*13)
app.push(game.update_change_room) app.push(game.update_change_room)
--sys.beat(10) --sys.beat(10)
end, end,
@@ -87,13 +89,12 @@ game = {
surf.target(0) surf.target(0)
view.clip() view.clip()
score.draw()
surf.target(game.back_buf) surf.target(game.back_buf)
--view.clip() --view.clip()
-- Pintar el mapa i sprites -- Pintar el mapa i sprites
rooms.pos.x = rooms.pos.x + (game.chg_adv.x*2.5) rooms.pos.x = rooms.pos.x + (game.chg_adv.x*2.5)
rooms.pos.y = rooms.pos.y + (game.chg_adv.y*1.5) rooms.pos.y = rooms.pos.y + (game.chg_adv.y*1.625)
sprites.hero.pos.x = sprites.hero.pos.x + game.chg_adv.x sprites.hero.pos.x = sprites.hero.pos.x + game.chg_adv.x
sprites.hero.pos.y = sprites.hero.pos.y + game.chg_adv.y sprites.hero.pos.y = sprites.hero.pos.y + game.chg_adv.y
@@ -102,9 +103,10 @@ game = {
game.apply_water() game.apply_water()
game.apply_light() game.apply_light()
score.draw()
game.chg_step = game.chg_step - 1 game.chg_step = game.chg_step - 1
if game.chg_step == 0 then if game.chg_step == 0 then
sprites.remove_out_of_room()
sprites.pause_ia = false sprites.pause_ia = false
app.pop() app.pop()
--sys.beat(2) --sys.beat(2)
@@ -123,12 +125,12 @@ game = {
apply_water = function() apply_water = function()
view.origin(0,0) view.origin(0,0)
if rooms.pos.y == 84 then if rooms.pos.y == 91 then
surf.target(game.back_buf) surf.target(game.back_buf)
surf.source(game.back_buf) surf.source(game.back_buf)
for x=0,159 do for x=0,159 do
local water_level = math.sin(game.water_counter)*2 local water_level = math.sin(game.water_counter)*2
for y=96+water_level,103 do for y=88+water_level,104 do
local pixel = surf.pixel(x,y) local pixel = surf.pixel(x,y)
surf.pixel(x,y,game.water_pal[pixel+1]) surf.pixel(x,y,game.water_pal[pixel+1])
end end

View File

@@ -1,77 +0,0 @@
templates = {
ALIVE = 0,
DYING = 1,
DEAD = 2,
RESURRECTING = 3,
create = function(type, options)
local sprite
if type == "mummy" then
sprite = {
type = type,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=16,h=16 },
bbo = { left=3, top=2, right=3, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("mummy.gif"),
animation = "mummy_walk",
state = templates.ALIVE,
enemy = true,
room = options.room,
ia = sprites.update_mummy
}
elseif type == "bullet" then
sprite = {
type = type,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=4,h=3 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("morcus.gif"),
animation = "bullet",
ia = sprites.update_bullet
}
elseif type == "coin" then
sprite = {
type = type,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=8 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("misc.gif"),
animation = "coin",
state = templates.ALIVE,
light = 15,
light_ox = 4,
light_oy = 4,
ia = sprites.update_coin
}
elseif type == "brick" then
sprite = {
type = type,
pos = options.pos,--{ x=100, y=4*12*8+71 },
size = { w=8,h=8 },
bbo = { left=0, top=0, right=0, bottom=0 },
current_frame = 1,
current_wait = 1,
flipped = options.flipped,
surf = surf.load("misc.gif"),
animation = "brick",
state = templates.ALIVE,
timeout = 10,
ia = sprites.update_brick
}
else
error("Template not recognized")
end
--sprite.room = rooms.current()
print("creat sprite de tipus "..type)
return sprite
end,
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,164 +0,0 @@
local pi = math.pi
local sin = math.sin
local cos = math.cos
local abs = math.abs
local function backIn(t, s) s = s or 1.70158; return t * t * ((s + 1) * t - s) end
local function backOut(t, s) s = s or 1.70158; t = t - 1; return 1 + t * t * ((s + 1) * t + s) end
local function backInOut(t, s)
s = s or 1.70158
if t < 0.5 then
local tt = 2 * t
return (tt * tt * ((s * 1.525 + 1) * tt - s * 1.525)) / 2
else
local tt = 2 * t - 2
return (2 + tt * tt * ((s * 1.525 + 1) * tt + s * 1.525)) / 2
end
end
-- Bounce (helper)
local function bounceOut(t)
local n1 = 7.5625
local d1 = 2.75
if t < 1 / d1 then
return n1 * t * t
elseif t < 2 / d1 then
t = t - 1.5 / d1
return n1 * t * t + 0.75
elseif t < 2.5 / d1 then
t = t - 2.25 / d1
return n1 * t * t + 0.9375
else
t = t - 2.625 / d1
return n1 * t * t + 0.984375
end
end
easing = {
linear = function(t) return t end,
-- Sine
easeInSine = function(t) return 1 - cos((t * pi) / 2) end,
easeOutSine = function(t) return sin((t * pi) / 2) end,
easeInOutSine = function(t) return -(cos(pi * t) - 1) / 2 end,
-- Quad
easeInQuad = function(t) return t * t end,
easeOutQuad = function(t) return 1 - (1 - t) * (1 - t) end,
easeInOutQuad = function(t)
if t < 0.5 then return 2 * t * t end
return 1 - ((-2 * t + 2)^2) / 2
end,
-- Cubic
easeInCubic = function(t) return t * t * t end,
easeOutCubic = function(t) return 1 - ((1 - t)^3) end,
easeInOutCubic = function(t)
if t < 0.5 then return 4 * t * t * t end
return 1 - ((-2 * t + 2)^3) / 2
end,
-- Expo
easeInExpo = function(t) return (t == 0) and 0 or (2^(10 * t - 10)) end,
easeOutExpo = function(t) return (t == 1) and 1 or 1 - (2^(-10 * t)) end,
easeInOutExpo = function(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
if t < 0.5 then return (2^(20 * t - 10)) / 2 end
return (2 - (2^(-20 * t + 10))) / 2
end,
-- Back (overshoot)
easeInBack = function(t) return backIn(t) end,
easeOutBack = function(t) return backOut(t) end,
easeInOutBack = function(t) return backInOut(t) end,
-- Elastic
easeInElastic = function(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
local c4 = (2 * pi) / 3
return -(2^(10 * t - 10)) * sin((t * 10 - 10.75) * c4)
end,
easeOutElastic = function(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
local c4 = (2 * pi) / 3
return (2^(-10 * t)) * sin((t * 10 - 0.75) * c4) + 1
end,
easeInOutElastic = function(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
local c5 = (2 * pi) / 4.5
if t < 0.5 then
return -((2^(20 * t - 10)) * sin((20 * t - 11.125) * c5)) / 2
end
return ((2^(-20 * t + 10)) * sin((20 * t - 11.125) * c5)) / 2 + 1
end,
-- Bounce
easeInBounce = function(t) return 1 - bounceOut(1 - t) end,
easeOutBounce = function(t) return bounceOut(t) end,
easeInOutBounce = function(t)
if t < 0.5 then return (1 - bounceOut(1 - 2 * t)) / 2 end
return (1 + bounceOut(2 * t - 1)) / 2
end,
}
tweening = {
list = {},
add = function(from, to, duration, easingFun, callback)
local tween = {
from = from,
to = to,
duration = math.max(0.000001, duration or 0.001),
easing = easingFun,
callback = callback,
t = 0,
}
tweening.list[#tweening.list + 1] = tween
return tween
end,
update = function(dt)
if #tweening.list==0 then return end
-- iterate backwards so we can remove finished tweens safely
for i = #tweening.list, 1, -1 do
local tw = tweening.list[i]
tw.t = tw.t + (dt or 0)
local progress = tw.t / tw.duration
if progress >= 1 then
-- finished: ensure final value, call callback with finished=true, remove
local value = tw.to
if tw.callback then
-- callback(value, normalizedProgress, finished)
tw.callback(value, 1, true)
end
table.remove(tweening.list, i)
else
-- in progress
local alpha = tw.easing(progress)
local value = tw.from + (tw.to - tw.from) * alpha
if tw.callback then tw.callback(value, progress, false) end
end
end
end,
clear = function()
for i = #tweening.list, 1, -1 do table.remove(tweening.list, i) end
end,
-- Optional helper: cancel a specific tween (pass the tween returned by add)
cancel = function(tween)
for i = #tweening.list, 1, -1 do
if tweening.list[i] == tween then
table.remove(tweening.list, i)
return true
end
end
return false
end
}

View File

@@ -1,18 +0,0 @@
function draw.outset(x, y, w, h)
draw.rectf(x, y, w, h, 23)
w,h = w+x,h+y
draw.hline(x, h-1, w-1,16)
draw.vline(w-1, y, h-1,16)
draw.hline(x, y, w-1,28)
draw.vline(x, y, h-1,28)
end
function draw.inset(x, y, w, h)
draw.rectf(x, y, w, h, 23)
w,h = w+x,h+y
draw.hline(x, y, w-1,16)
draw.vline(x, y, h-1,16)
draw.hline(x, h-1, w-1,28)
draw.vline(w-1, y, h-1,28)
end

View File

@@ -1,26 +0,0 @@
util={
inside = function(x, y, rectangle)
if x >= rectangle[1] and
y >= rectangle[2] and
x < rectangle[3]+rectangle[1] and
y < rectangle[4]+rectangle[2] then
return true
else
return false
end
end,
aabb = function(sprite)
local x = sprite.pos.x + sprite.bbo.left
local y = sprite.pos.y + sprite.bbo.top
local w = sprite.size.w - sprite.bbo.right - sprite.bbo.left
local h = sprite.size.h - sprite.bbo.bottom - sprite.bbo.top
return x, y, w, h
end,
check_aabb_collision = function(x1,y1,w1,h1, x2,y2,w2,h2)
return ( x1 < x2 + w2 and x1 + w1 > x2 and y1 < y2 + h2 and y1 + h1 > y2 )
end
}

15
data/utils/app.lua Normal file
View File

@@ -0,0 +1,15 @@
app = {
update = nil,
stack = {},
}
function app.push(func)
table.insert(app.stack, app.update)
app.update = func
end
function app.pop()
if #app.stack > 0 then
app.update = table.remove(app.stack)
end
end

362
data/utils/console.lua Normal file
View File

@@ -0,0 +1,362 @@
local separators = " ()[],-+*/=<>"
local function split_by_last_separator(s)
for i = #s, 1, -1 do
local c = s:sub(i, i)
if separators:find(c, 1, true) then
if i == #s then
-- Separador al final
return s, ""
end
-- Separador en medio
return s:sub(1, i), s:sub(i + 1)
end
end
-- Sin separadores
return "", s
end
local function split_by_last_dot(s)
local last = s:match(".*()%.") -- devuelve la posición DESPUÉS del último punto
if not last then
-- No hay puntos: primera parte = cadena completa, segunda = ""
return "", s
end
-- Si el punto está al final, la segunda parte es ""
if last > #s then
return s, ""
end
-- Primera parte incluye el punto
local first = s:sub(1, last - 1)
local second = s:sub(last+1)
return first, second
end
function get_by_path(path)
local current = _G
for segment in path:gmatch("[^%.]+") do
if type(current) ~= "table" then
return nil
end
current = current[segment]
if current == nil then
--print("get_by_path: " ..segment.." es nil")
return nil
end
end
--print("get_by_path: ok")
return current
end
function entries_starting_with(s, t)
if not t then return nil end
local result = {}
for k, v in pairs(t) do
if type(k) == "string" and k:sub(1, #s) == s then
result[#result+1] = k
end
end
return result
end
console = {
command = "",
history = {},
history_pos = 0,
cursor = 50,
autocomplete_list = {},
autocomplete_prefix = "",
autocomplete_index = 1,
} local me = console
function me.enable()
app.push(me.update)
me.command = ""
end
function me.update()
surf.target(0)
draw.rrectf(0, 92, 160, 108, 4, 1)
draw.rrect(0, 92, 160, 108, 4, 13)
draw.text(">", 2, 96, 13)
draw.text(me.command, 6, 96, 13)
if me.autocomplete_list and #me.autocomplete_list>0 then
--local num = math.min(5, #me.autocomplete_list)
--local base_y = 92-num*7
--draw.rectf(3+#me.command*4, base_y, 80, num*7, 1)
--draw.rect(3+#me.command*4, base_y, 80, num*7, 13)
--for i=1,num do
-- draw.text(me.autocomplete_list[i], 6+#me.command*4, base_y+i*7, 13)
--end
local sufix = me.autocomplete_list[me.autocomplete_index]:sub(#me.autocomplete_prefix+1)
draw.text(sufix, 6+#me.command*4, 96, 6)
end
if me.cursor > 24 then
draw.text("_", 6+#me.command*4, 96, 13)
end
me.cursor = me.cursor - 1
if me.cursor == 0 then me.cursor = 50 end
if key.press(key.ESCAPE) then
app.pop()
return
end
local should_update = false
if #me.history>0 then
if key.press(key.UP) and me.history_pos > 1 then
me.history_pos = me.history_pos - 1
me.command = me.history[me.history_pos]
should_update = true
elseif key.press(key.DOWN) and me.history_pos < #me.history then
me.history_pos = me.history_pos + 1
me.command = me.history[me.history_pos]
should_update = true
end
end
local k = key.press()
if k ~= key.UNKNOWN then
should_update = true
if k >= key.A and k <= key.Z then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. string.char(k+61)
else
me.command = me.command .. string.char(k+93)
end
elseif k == key.N0 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '='
elseif key.down(key.RALT) then
me.command = me.command .. '}'
else
me.command = me.command .. '0'
end
elseif k == key.N1 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '!'
elseif key.down(key.RALT) then
me.command = me.command .. '|'
else
me.command = me.command .. '1'
end
elseif k == key.N2 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '"'
elseif key.down(key.RALT) then
me.command = me.command .. '@'
else
me.command = me.command .. '2'
end
elseif k == key.N3 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '·'
elseif key.down(key.RALT) then
me.command = me.command .. '#'
else
me.command = me.command .. '3'
end
elseif k == key.N4 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '$'
elseif key.down(key.RALT) then
me.command = me.command .. '~'
else
me.command = me.command .. '4'
end
elseif k == key.N5 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '%'
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. '5'
end
elseif k == key.N6 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '&'
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. '6'
end
elseif k == key.N7 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '/'
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. '7'
end
elseif k == key.N8 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '('
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. '8'
end
elseif k == key.N9 then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. ')'
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. '9'
end
elseif k == key.PERIOD then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. ':'
else
me.command = me.command .. '.'
end
elseif k == key.COMMA then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. ';'
else
me.command = me.command .. ','
end
elseif k == key.GRAVE then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. ' '
elseif key.down(key.RALT) then
me.command = me.command .. '\\'
else
me.command = me.command .. ' '
end
elseif k == key.EQUALS then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '¿'
else
me.command = me.command .. '¡'
end
elseif k == key.SLASH then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '_'
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. '-'
end
elseif k == key.APOSTROPHE then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '"'
elseif key.down(key.RALT) then
me.command = me.command .. '{'
else
me.command = me.command .. '\''
end
elseif k == key.SEMICOLON then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. 'Ñ'
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. 'ñ'
end
elseif k == key.BACKSLASH then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. 'Ç'
elseif key.down(key.RALT) then
me.command = me.command .. '}'
else
me.command = me.command .. 'ç'
end
elseif k == key.RIGHTBRACKET then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '*'
elseif key.down(key.RALT) then
me.command = me.command .. ']'
else
me.command = me.command .. '+'
end
elseif k == key.LEFTBRACKET then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '^'
elseif key.down(key.RALT) then
me.command = me.command .. '['
else
me.command = me.command .. '`'
end
elseif k == key.NONUSBACKSLASH then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '>'
elseif key.down(key.RALT) then
me.command = me.command .. ' '
else
me.command = me.command .. '<'
end
elseif k == key.MINUS then
if key.down(key.LSHIFT) or key.down(key.RSHIFT) then
me.command = me.command .. '?'
else
me.command = me.command .. '\''
end
elseif k == key.SPACE then
me.command = me.command .. ' '
elseif k == key.BACKSPACE then
me.command = me.command:sub(1, #me.command - 1)
elseif k == key.TAB then
local sufix = me.autocomplete_list[me.autocomplete_index]:sub(#me.autocomplete_prefix+1)
me.command = me.command .. sufix
elseif k == key.RETURN then
table.insert(me.history, me.command)
me.history_pos = #me.history+1
local f,err = load(me.command)
if not f then
print("Error al compilar:", err)
else
print(f())
app.pop()
end
end
end
if should_update then
local a, b = split_by_last_separator(me.command)
if b ~= "" then
local ba, bb = split_by_last_dot(b)
me.autocomplete_prefix = bb
if ba ~= "" then
me.autocomplete_list = entries_starting_with(bb, get_by_path(ba))
--print(bb..":"..ba)
--print(#me.autocomplete_list)
else
me.autocomplete_list = entries_starting_with(bb, _G)
--print(bb..":".."golbal")
--print(#me.autocomplete_list)
end
else
me.autocomplete_prefix = ""
me.autocomplete_list = entries_starting_with("", _G)
--print("<buit>"..":".."golbal")
--print(#me.autocomplete_list)
end
end
end

66
data/utils/msgbox.lua Normal file
View File

@@ -0,0 +1,66 @@
require "ui"
require "util"
msgbox = {
title = "TITOL",
text = { "Este es el missatge.", "Pot estar en varies linies" },
buttons = { {"YES", sys.quit}, {"NO", app.pop} },
selected = 0,
w = 100,
h = 50,
} local me = msgbox
function me.show(title, text, buttons, default)
me.selected = default or 1
me.title = title
me.text = text
me.buttons = buttons
me.w = 0
for i,v in ipairs(me.text) do
local width = #v*4+8
if width > me.w then me.w = width end
end
me.h = #me.text*6+35
app.push(me.update)
end
function me.update()
local top = (160-me.w)//2
local left = (104-me.h)//2
view.clip(top, left, me.w, me.h)
view.origin(top, left)
draw.rrectf(0,0,me.w, me.h,4,27)
--draw.rectf(1,1,me.w-2, 7, 21)
draw.text(me.title, 5, 4, 4)
local y = 14
for i,v in ipairs(me.text) do
draw.text(v, 5, y, 21)
y = y + 6
end
local mx, my = mouse.pos()
local x = me.w - 35
y = me.h - 12
for i,v in ipairs(me.buttons) do
ui.pushbutton(v[1],x,y,7,22,21,v[2],me.selected==i)
x = x - 34
end
if key.press(key.ESCAPE) then
app.pop()
elseif key.press(key.RIGHT) then
me.selected=me.selected-1
if me.selected==0 then me.selected = #me.buttons end
elseif key.press(key.LEFT) then
me.selected=me.selected+1
if me.selected>#me.buttons then me.selected = 1 end
elseif key.press(key.RETURN) then
me.buttons[me.selected][2]()
end
end

61
data/utils/palfade.lua Normal file
View File

@@ -0,0 +1,61 @@
require "util"
palfade = {
original = {},
reddish = {},
} local me = palfade
function me.init()
for i=1,32 do
me.reddish[i] = {r=me.original[i].r, g=me.original[i].g, b=me.original[i].b}
end
end
function me.reddish_limit(r, g, b)
local t = util.luminance(r, g, b) / 255
local R = 255 * t
local G = g * (1 - t)
local B = b * (1 - t)
return R, G, B
end
function me.fade_reddish_color(r, g, b, f)
local ff = math.min(1, f+util.luminance(r,g,b))
local R = math.floor(r*ff)
local G = math.floor(g*f)
local B = math.floor(b*f)
return R, G, B
end
function me.fade_reddish(f)
for i=1,32 do
local r, g, b = me.fade_reddish_color(me.original[i].r, me.original[i].g, me.original[i].b, f)
me.reddish[i].r, me.reddish[i].g, me.reddish[i].b = r, g, b
pal.color(i-1,r,g,b)
end
end
function me.fade_red(f)
for i=1,32 do
local r = math.floor(me.reddish[i].r + (255-me.reddish[i].r)*f)
local g = math.floor(me.reddish[i].g - (me.reddish[i].g)*f)
local b = math.floor(me.reddish[i].b - (me.reddish[i].b)*f)
pal.color(i-1,r,g,b)
end
end
function me.fade_white(f)
for i=1,32 do
local r = math.floor(me.reddish[i].r + (255-me.reddish[i].r)*f)
local g = math.floor(me.reddish[i].g + (255-me.reddish[i].g)*f)
local b = math.floor(me.reddish[i].b + (255-me.reddish[i].b)*f)
pal.color(i-1,r,g,b)
end
end
function me.restore()
pal.set(me.original)
end

164
data/utils/tweening.lua Normal file
View File

@@ -0,0 +1,164 @@
local pi = math.pi
local sin = math.sin
local cos = math.cos
local abs = math.abs
local function backIn(t, s) s = s or 1.70158; return t * t * ((s + 1) * t - s) end
local function backOut(t, s) s = s or 1.70158; t = t - 1; return 1 + t * t * ((s + 1) * t + s) end
local function backInOut(t, s)
s = s or 1.70158
if t < 0.5 then
local tt = 2 * t
return (tt * tt * ((s * 1.525 + 1) * tt - s * 1.525)) / 2
else
local tt = 2 * t - 2
return (2 + tt * tt * ((s * 1.525 + 1) * tt + s * 1.525)) / 2
end
end
-- Bounce (helper)
local function bounceOut(t)
local n1 = 7.5625
local d1 = 2.75
if t < 1 / d1 then
return n1 * t * t
elseif t < 2 / d1 then
t = t - 1.5 / d1
return n1 * t * t + 0.75
elseif t < 2.5 / d1 then
t = t - 2.25 / d1
return n1 * t * t + 0.9375
else
t = t - 2.625 / d1
return n1 * t * t + 0.984375
end
end
easing = {} local me = easing
function me.linear(t) return t end
-- Sine
function me.easeInSine(t) return 1 - cos((t * pi) / 2) end
function me.easeOutSine(t) return sin((t * pi) / 2) end
function me.easeInOutSine(t) return -(cos(pi * t) - 1) / 2 end
-- Quad
function me.easeInQuad(t) return t * t end
function me.easeOutQuad(t) return 1 - (1 - t) * (1 - t) end
function me.easeInOutQuad(t)
if t < 0.5 then return 2 * t * t end
return 1 - ((-2 * t + 2)^2) / 2
end
-- Cubic
function me.easeInCubic(t) return t * t * t end
function me.easeOutCubic(t) return 1 - ((1 - t)^3) end
function me.easeInOutCubic(t)
if t < 0.5 then return 4 * t * t * t end
return 1 - ((-2 * t + 2)^3) / 2
end
-- Expo
function me.easeInExpo(t) return (t == 0) and 0 or (2^(10 * t - 10)) end
function me.easeOutExpo(t) return (t == 1) and 1 or 1 - (2^(-10 * t)) end
function me.easeInOutExpo(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
if t < 0.5 then return (2^(20 * t - 10)) / 2 end
return (2 - (2^(-20 * t + 10))) / 2
end
-- Back (overshoot)
function me.easeInBack(t) return backIn(t) end
function me.easeOutBack(t) return backOut(t) end
function me.easeInOutBack(t) return backInOut(t) end
-- Elastic
function me.easeInElastic(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
local c4 = (2 * pi) / 3
return -(2^(10 * t - 10)) * sin((t * 10 - 10.75) * c4)
end
function me.easeOutElastic(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
local c4 = (2 * pi) / 3
return (2^(-10 * t)) * sin((t * 10 - 0.75) * c4) + 1
end
function me.easeInOutElastic(t)
if t == 0 then return 0 end
if t == 1 then return 1 end
local c5 = (2 * pi) / 4.5
if t < 0.5 then
return -((2^(20 * t - 10)) * sin((20 * t - 11.125) * c5)) / 2
end
return ((2^(-20 * t + 10)) * sin((20 * t - 11.125) * c5)) / 2 + 1
end
-- Bounce
function me.easeInBounce(t) return 1 - bounceOut(1 - t) end
function me.easeOutBounce(t) return bounceOut(t) end
function me.easeInOutBounce(t)
if t < 0.5 then return (1 - bounceOut(1 - 2 * t)) / 2 end
return (1 + bounceOut(2 * t - 1)) / 2
end
tweening = {
list = {},
} me = tweening
function me.add(from, to, duration, easingFun, callback)
local tween = {
from = from,
to = to,
duration = math.max(0.000001, duration or 0.001),
easing = easingFun,
callback = callback,
t = 0,
}
me.list[#me.list + 1] = tween
return tween
end
function me.update(dt)
if #me.list==0 then return end
-- iterate backwards so we can remove finished tweens safely
for i = #me.list, 1, -1 do
local tw = me.list[i]
tw.t = tw.t + (dt or 0)
local progress = tw.t / tw.duration
if progress >= 1 then
-- finished: ensure final value, call callback with finished=true, remove
local value = tw.to
if tw.callback then
-- callback(value, normalizedProgress, finished)
tw.callback(value, 1, true)
end
table.remove(me.list, i)
else
-- in progress
local alpha = tw.easing(progress)
local value = tw.from + (tw.to - tw.from) * alpha
if tw.callback then tw.callback(value, progress, false) end
end
end
end
function me.clear()
for i = #me.list, 1, -1 do table.remove(me.list, i) end
end
-- Optional helper: cancel a specific tween (pass the tween returned by add)
function me.cancel(tween)
for i = #me.list, 1, -1 do
if me.list[i] == tween then
table.remove(me.list, i)
return true
end
end
return false
end

40
data/utils/ui.lua Normal file
View File

@@ -0,0 +1,40 @@
ui = {}
function ui.pushbutton(label,x,y,h,col1,col2,callback,selected)
local size = (#label*4)-1+4
local text_y = (h-5)//2
local button_h=0
local mx, my = mouse.pos()
if mx>=x and mx<x+size and my>=y and my<y+h then
button_h = mouse.down(mouse.LEFT) and -1 or 1
if mouse.press(mouse.LEFT) then callback() end
end
draw.rrectf(x,y+1,size,h,1,col2)
draw.rrectf(x,y-button_h,size,h,1,col1)
draw.text(label,x+2,y+text_y-button_h,col2)
if selected then
draw.rrect(x-1,y-button_h-1,size+2,h+3+button_h,3,1)
end
end
function ui.togglebutton(label,x,y,h,col1,col2,dis1,dis2,state,callback,selected)
local size = (#label*4)-1+4
local text_y = (h-5)//2
local bh=0
local mx, my = mouse.pos()
if mx>=x and mx<x+size and my>=y and my<y+h then
bh = mouse.down(mouse.LEFT) and -1 or 1
if mouse.press(mouse.LEFT) then callback() end
end
if not state then
col1,col2 = dis1,dis2
else
if bh>-1 then bh=bh-1 end
end
draw.rrectf(x,y+1,size,h,1,col2)
draw.rrectf(x,y-bh,size,h,1,col1)
draw.text(label,x+2,y+text_y-bh,col2)
if selected then
draw.rrect(x-1,y-bh-1,size+2,h+3+bh,3,1)
end
end

44
data/utils/util.lua Normal file
View File

@@ -0,0 +1,44 @@
util={}
function util.inside(x, y, rectangle)
if x >= rectangle[1] and
y >= rectangle[2] and
x < rectangle[3]+rectangle[1] and
y < rectangle[4]+rectangle[2] then
return true
else
return false
end
end
function util.aabb(sprite)
local x = sprite.pos.x + sprite.bbo.left
local y = sprite.pos.y + sprite.bbo.top
local w = sprite.size.w - sprite.bbo.right - sprite.bbo.left
local h = sprite.size.h - sprite.bbo.bottom - sprite.bbo.top
return x, y, w, h
end
function util.check_aabb_collision(x1,y1,w1,h1, x2,y2,w2,h2)
return ( x1 < x2 + w2 and x1 + w1 > x2 and y1 < y2 + h2 and y1 + h1 > y2 )
end
function util.luminance(r, g, b)
return (0.2126*r + 0.7152*g + 0.0722*b)/255
end
function util.normalize(v)
local magnitud = math.sqrt(v.x * v.x + v.y * v.y)
if magnitud == 0 then
return {x = 0, y = 0} -- evita división por cero
end
return {x = v.x / magnitud, y = v.y / magnitud}
end
function math.sign(value)
if value > 0 then
return 1
else
return -1
end
end

35
paku.pal Normal file
View File

@@ -0,0 +1,35 @@
JASC-PAL
0100
32
0 0 0
0 0 0
96 57 19
79 43 36
42 35 73
125 56 64
50 83 95
115 99 87
255 0 0
130 91 49
138 101 59
162 125 81
193 108 91
123 178 78
251 205 26
153 134 117
152 135 119
197 145 84
205 158 112
232 153 115
240 189 119
65 128 160
116 173 187
190 187 178
199 176 158
251 223 155
198 194 195
255 249 228
254 255 255
28 23 48
33 10 13
26 26 17