diff --git a/spacein.p8 b/spacein.p8 new file mode 100644 index 0000000..a21da6b --- /dev/null +++ b/spacein.p8 @@ -0,0 +1,637 @@ +pico-8 cartridge // http://www.pico-8.com +version 43 +__lua__ +-- global + +function _init() + frame_time = 0.01666666666 + state_menu = "menu" + state_play = "play" + set_state(state_menu) +end + +function _update60() + if state == state_menu then + menu_update() + elseif state == state_play then + map_update() + player_update() + enemies_update() + ufo_update() + end +end + +function _draw() + cls(1) + if state == state_menu then + menu_draw() + elseif state == state_play then + map_draw() + player_draw() + enemies_draw() + ufo_draw() + end +end + +function set_state(st) + state = st + music(-1, 100) + if state == state_menu then + menu_init() + elseif state == state_play then + map_init() + player_init() + enemies_init() + ufo_init() + end +end + +function sp2m(sp) + return (sp+4)/8 +end + +function is_collide(e1,e2) + return e2.x+e2.sx > e1.x and + e1.x+e1.sx > e2.x and + e2.y+e2.sy > e1.y and + e1.y+e1.sy > e2.y +end +-->8 +-- player + +function player_init() + pl = { + x = 0, + y = 0, + sx = 8, + sy = 8, + sp = 0x1, + lives = 3, + speed = 0, + m_speed = 1.0, + accel = 0.25, + sp_speed = 0.25, + at_tm = 0.0, + at_delay = 0.5, + proj_speed = 2, + projs = {}, + score = 0, + can_shoot = false, + } + pl_reset_pos() +end + +function player_update() + if btn(⬅️) then + pl.speed -= pl.accel + pl.sp -= pl.sp_speed + elseif btn(➡️) then + pl.speed += pl.accel + pl.sp += pl.sp_speed + else + if pl.speed < 0 then + pl.speed += pl.accel + elseif pl.speed > 0 then + pl.speed -= pl.accel + end + end + + local m_speed = btn(🅾️) and + pl.m_speed*2 or pl.m_speed + pl.speed = mid(-m_speed, + pl.speed, m_speed) + + pl.x += pl.speed + pl.x = mid(0, pl.x, 120) + + if pl.sp < 1 then + pl.sp += 2 + elseif pl.sp >= 3.0 then + pl.sp -= 2 + end + + if btn(❎) then + if pl.can_shoot and + pl.at_tm <= 0 then + pl_attack() + end + else + pl.can_shoot = true + end + + if pl.at_tm > 0 then + pl.at_tm -= frame_time + end + + for proj in all(pl.projs) do + pl_proj_update(proj) + end +end + +function player_draw() + for proj in all(pl.projs) do + spr(proj.sp, proj.x, proj.y) + end + spr(pl.sp, pl.x, pl.y) + if pl.at_tm <= 0 then + spr(0x3, pl.x, pl.y) + end + rectfill(0, 0, 128, 7, 6) + for i = 1,pl.lives do + spr(0x1, 9*i - 8, -1) + end + print( + sub("000000"..pl.score, -6), + 103, 1, 13) +end + +function pl_attack() + pl.at_tm = pl.at_delay + + local proj = { + sp = 0x4, + x = flr(pl.x)+3, + y = flr(pl.y), + sx = 2, + sy = 2, + } + add(pl.projs, proj) + sfx(0) +end + +function pl_proj_update(proj) + proj.y -= pl.proj_speed + if proj.y < -8 or + map_damage(proj) or + en_damage(proj) or + ufo_damage(proj) then + del(pl.projs, proj) + end +end + +function pl_damage(proj) + if is_collide(proj, pl) then + pl.lives -= 1 + if pl.lives > 0 then + pl_reset_pos() + sfx(4) + else + set_state(state_menu) + sfx(5) + end + return true + end + return false +end + +function pl_reset_pos() + pl.x = 60 + pl.y = 119 +end + +-->8 +-- map + +function map_init() + map_c = 6 + map_areas = {} + + foreach(get_shelter(19, 107), + function(v) + add(map_areas, v) end) + + foreach(get_shelter(49, 107), + function(v) + add(map_areas, v) end) + + foreach(get_shelter(79, 107), + function(v) + add(map_areas, v) end) + + foreach(get_shelter(109, 107), + function(v) + add(map_areas, v) end) +end + +function map_update() + +end + +function map_draw() + map() + --rectfill(0, 104, 128, 127, 12) + --rectfill(0, 127, 128, 128, 5) + + for a in all(map_areas) do + for i = 0, 15 do + if a.v & (1 << i) != 0 then + local x = a.x+i%4 + local y = a.y+i\4 + pset(x, y, map_c) + end + end + end +end + +function map_damage(proj) + local is_collided = false + + for a in all(map_areas) do + if is_collide(a, proj) and + a.v != 0 then + for i = 0, 15 do + if a.v & (1 << i) != 0 then + local p = { + x = a.x+i%4, + y = a.y+i\4, + sx = 1, + sy = 1, + } + if is_collide(p,proj) then + a.v &= ~(1 << i) + is_collided = true + end + end + end + end + end + + return is_collided +end + +function get_area(ax, ay, av) + return { + x = ax, + y = ay, + sx = 4, + sy = 4, + v = av, + } +end + +function get_shelter(x, y) + return { + get_area(x-10, y, 0xec80), + get_area(x-6, y, 0xfffe), + get_area(x-2, y, 0xffff), + get_area(x+2, y, 0xfff7), + get_area(x+6, y, 0x7310), + + get_area(x-10, y+4, 0xffff), + get_area(x-6, y+4, 0xffff), + get_area(x-2, y+4, 0xffff), + get_area(x+2, y+4, 0xffff), + get_area(x+6, y+4, 0xffff), + + get_area(x-10, y+8, 0xffff), + get_area(x-6, y+8, 0x0013), + get_area(x+2, y+8, 0x008c), + get_area(x+6, y+8, 0xffff), + } +end + +-->8 +-- enemies + +function enemies_init() + en = { + mv_left = true, + mv_speed = 0.025, + mv_speed_inc = 0.01, + mv_speed_inc_inc = 0.0005, + descent_speed = 1.0, + descent_speed_inc = 0.03, + at_tm = 1.0, + at_delay = 1.5, + at_delay_dec = -0.01, + proj_speed = 1, + projs = {}, + } + enemies = {} + local row = 1 + for ly = 9, 60, 9 do + local en_row = {} + for lx = 17, 102, 8 do + local enemy = { + x = lx, + y = ly, + sx = 8, + sx = (ly<21) and 8 + or (ly<38) and 6 or 4, + sy = 8, + sp = (ly<21) and 0x22 + or (ly<38) and 0x21 + or 0x20, + } + add(en_row, enemy) + end + enemies[row] = en_row + row += 1 + end +end + +function enemies_update() + if en.at_tm > 0 then + en.at_tm -= frame_time + end + + en_move() + + if en.at_tm <= 0 then + en.at_tm = en.at_delay + en_attack() + end + + for proj in all(en.projs) do + en_proj_update(proj) + end +end + +function enemies_draw() + for proj in all(en.projs) do + spr(proj.sp, proj.x, proj.y) + end + for row in all(enemies) do + for e in all(row) do + spr(e.sp, e.x, e.y) + end + end +end + +function en_move() + if en.mv_left then + if en_can_mv_side(true) then + en_mv_side(-en.mv_speed) + else + en_mv_down() + en.mv_left = false + end + else + if en_can_mv_side(false) then + en_mv_side(en.mv_speed) + else + en_mv_down() + en.mv_left = true + end + end +end + +function en_attack() + local e = en_random() + if e == nil then + sfx(6) + set_state(state_menu) + return + end + + sfx(2) + + local proj = { + sp = 0x24, + x = flr(e.x)+3, + y = flr(e.y), + sx = 2, + sy = 2, + } + add(en.projs, proj) +end + +function en_mv_side(speed) + for i = 1,#enemies do + for e in all(enemies[i]) do + e.x += speed + end + end +end + +function en_mv_down() + sfx(3) + for i = 1,#enemies do + for e in all(enemies[i]) do + e.y += flr(en.descent_speed) + if e.y > 101 then + sfx(8) + set_state(state_menu) + elseif e.y > 96 then + sfx(9) + end + end + end +end + +function en_can_mv_side(left) + for row in all(enemies) do + if #row != 0 then + if (left and + row[1].x <= 0) or + (not left and + row[#row].x >= 120) then + return false + end + end + end + return true +end + +function en_proj_update(proj) + proj.y += en.proj_speed + if proj.y > 128 or + map_damage(proj) or + pl_damage(proj) then + del(en.projs, proj) + end +end + +function en_random() + local rows = {} + for row in all(enemies) do + if #row != 0 then + add(rows, row) + end + end + if #rows == 0 then + return nil + end + return rnd(rnd(rows)) +end + +function en_damage(proj) + for row in all(enemies) do + for e in all(row) do + if is_collide(proj, e) then + en.mv_speed += + en.mv_speed_inc + en.mv_speed_inc += + en.mv_speed_inc_inc + en.at_delay += + en.at_delay_dec + en.descent_speed += + en.descent_speed_inc + pl.score += + e.sp==0x20 and 25 or + e.sp==0x21 and 100 or 250 + del(row, e) + sfx(1) + return true + end + end + end + return false +end + +-->8 +-- menu + +function menu_init() + menu_text = "press ❎ to play" + can_select = false +end + +function menu_update() + if btn(❎) then + if can_select then + set_state(state_play) + end + else + can_select = true + end +end + +function menu_draw() + print(menu_text, 32, 60, 6) +end + +-->8 +-- ufo + +function ufo_init() + ufo = { + exists = false, + x = 60, + y = 7, + sx = 8, + sy = 4, + dir = 1, + speed = 0.25, + speed_inc = 0.1, + tm = 15.0, + delay = 10.0, + delay_dec = -1.0, + score = 2500, + score_inc = 1000, + } +end + +function ufo_update() + if ufo.exists then + ufo.x += ufo.speed * ufo.dir + if ufo.x < -16 or + ufo.x > 136 then + uf_remove() + end + elseif ufo.tm > 0 then + ufo.tm -= frame_time + if ufo.tm <= 0 then + ufo.tm = ufo.delay + ufo.delay += ufo.delay_dec + uf_spawn() + end + end +end + +function ufo_draw() + if ufo.exists then + spr(0x1f, ufo.x, ufo.y) + end +end + +function uf_spawn() + ufo.exists = true + if rnd(1) < 0.5 then + ufo.x = -16 + ufo.dir = 1 + else + ufo.x = 136 + ufo.dir = -1 + end + music(0) +end + +function ufo_damage(proj) + if ufo.exists and + is_collide(proj, ufo) then + uf_remove() + pl.score += ufo.score + ufo.speed += ufo.speed_inc + ufo.score += ufo.score_inc + sfx(7) + return true + end + return false +end + +function uf_remove() + ufo.exists = false + music(-1, 100) +end + +__gfx__ +000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000066000000660000003b000b30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700008dd800008dd800000b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000008998000089980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000099999900999999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +007007009aaaaaa99aaaaaa900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000009aaaaaa99aaaaaa900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000005d5d5d00d5d5d5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +ccccccccccccccccc0c0c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +cccccccccccccccc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +ccccccccccccccccc0c0c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000 +cccccccccccccccc0c000c0000c000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022ee220 +ccccccccccccccccc0c0c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099aaaa99 +cccccccccccccccc0c0c0c0c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022eeee22 +ccccccccccccccccc0c0c0c0c000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +44444444cccccccccc0ccc0c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00055000055005500550055000000000980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +009aa9002ee22ee23bb33bb300000000890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +009aa90002eeee203bbbbbb300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +009aa90002eeee203bbbbbb300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0096690002266200036bb63000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +009aa900002ee20003b66b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0009900000022000003bb30000098000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000dd000000dd000000dd00000089000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +__gff__ +0000000000000000000000000000000000000000000000000000000000000000020200020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +__map__ +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1313131313131313131313131313131300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1212121212121212121212121212121200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +__sfx__ +01050000226501b64011630262002a200312003c20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +010400002e0502b050290402703024020220101f0101f0001d0001d0001d0001d0001b0001a00017000110000d0000a0000800007000070000600005000000000000000000000000000000000000000000000000 +01020000166400a630046200060000600006000060000600006000060000600006000060000600006000060000600006000060000600006000060000600006000060000600006000060000600006000060000600 +100200000c0500f04013030180201b010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0005000017650186501b65018650186401664018640186401b6401d6401f6401d6401863018630186301b6301d6301d6301d6301b6201b6201b6201b6201d6201d6201b6101b6101d6101d6101d6001b6001d600 +0106000027150241501f1501f1501d1501b150181500000024150221501d1501d1501b150181501615000000221501f1501d1501d1501b1501815016150000000000000000000000000000000000000000000000 +0006000016150181501b1501d1501f150221502415000000181501b1501d1501f150221502415027150000001b1501d1501f15022150241502715029150000000000000000000000000000000000000000000000 +000500002205024050220501d0501f0502405027050240501f0501d0501f0502405027050220501f0401b0301f020240100000000000000000000000000000000000000000000000000000000000000000000000 +0106000027253242531f2531f2531d2531b253182530020324253222531d2531d2531b253182531625300203222531f2531d2531d2531b2531825316253002030020300203002030020300203002030020300203 +d40300002411125121261312714128151291512a1512b1512c1512a1512915128151271512615125151241512415125151261512715128151291512a1512b1512c1512a151291512815127141261312512124111 +a80f00000e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e050100500e05010050 +__music__ +03 0a424344 +