- Reestructuració completa

This commit is contained in:
2026-03-12 21:04:15 +01:00
parent 6c5d7a305a
commit 88de5f262b
27 changed files with 696 additions and 707 deletions

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

@@ -0,0 +1,183 @@
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 = false,
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=2 },
{ frame={x=38,y=0,w=15,h=16}, offset={normal={x=5,y=0}}, wait=4 },
}
},
}

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

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

@@ -0,0 +1,232 @@
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 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) == 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
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+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+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
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) ) 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 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
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

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

@@ -0,0 +1,49 @@
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()
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

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

View File

@@ -0,0 +1,36 @@
function ia.update_sucubo(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()
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

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

@@ -0,0 +1,14 @@
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", label="sucubo", visual={x=0, y=64, 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

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

@@ -0,0 +1,26 @@
score = {
points = 0,
color = 28,
zoom = 1,
surf = nil,
} local me = score
function me.init()
me.points = 0
me.surf = surf.load("gfx/sprites.gif")
end
function me.draw()
draw.rectf(0,0,160,8,1)
draw.text(string.format("%03d", me.points),1,1,me.color)
surf.source(me.surf)
if sprites.hero.keys["verda"] then draw.surf(16,48,16,8, 32,-1) end
if sprites.hero.keys["groga"] then draw.surf(16,56,16,8, 32,-1) end
if sprites.hero.keys["roja"] then draw.surf(32,48,16,8, 32,-1) end
if sprites.hero.keys["blava"] then draw.surf(32,56,16,8, 32,-1) 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 28 or 14 end)
end

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

@@ -0,0 +1,218 @@
require "animations"
require "templates"
sprites = {
hero = nil,
list = {},
pause_ia = false,
}
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.remove_out_of_room()
--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
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)
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))
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

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

@@ -0,0 +1,152 @@
ia = {}
require "ia.*"
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 = 0,
enemy = true,
room = options.room,
ia = ia.update_sucubo
}
else
error("Template not recognized")
end
--sprite.room = rooms.current()
print("creat sprite de tipus "..type)
return sprite
end