Files
2026-07-17 11:03:12 +03:00

638 lines
18 KiB
Lua
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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