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, state = templates.ALIVE, jumping = 0, light = 100, light_ox = 8, light_oy = 8, cooldown = 0, jump_throttle = 0, lives = 4, keys = {}, 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_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, 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) 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, hero_hit = function(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("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, hero_give_key = function(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, lights_out = function() 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, update_mummy = function(spr) 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, 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) 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, update_torxa = function(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, update_clau = function(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, update_porta = function(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, 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() 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+11 then game.change_room(0,1) else if sprites.hero.cooldown % 2 == 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 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>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 -- 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+11 then game.change_room(0,1) else if sprites.hero.pos.y >= 742 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>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 (app.update == editor.update) and (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 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, draw_sprite = function(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, 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.mode(draw.NORMAL) draw.surf(sx, sy, w, h, x, y, w, h, f) end }