Compare commits

..

50 Commits

Author SHA1 Message Date
39d53c45aa
xp and hp brighter and closer to meters 2024-09-07 16:36:30 -07:00
5870c129eb
staggered "xp", "hp" labels in UI 2024-09-07 16:33:58 -07:00
68863280f3
stagger the bars 2024-09-07 16:17:38 -07:00
3f7c4f59c0
stretch meter area 2024-09-07 16:15:00 -07:00
804eb62ae7
p is now x in ui
"x" looks pretty bad with a drop shadow! will tweak soon anyway
2024-09-07 16:07:40 -07:00
303148876d
Remove power mechanics. Replace with XP stub.
Also a few random comments and cleanups along the way.
2024-09-07 16:04:01 -07:00
b379e47dbf
bonus shield powerup
mostly to test whether redistributing the shield and health meters works
2024-09-02 15:22:33 -07:00
4ca3913637
it's still tyrian-like so update last_tyrianlike 2024-09-02 15:09:27 -07:00
f9ba59d992
refactor mknew
saves tokens, harder to forget to use it
2024-09-02 15:08:58 -07:00
dd143060ac
squash: refactor bullets to remove enemy flag
commit ead2a7d874
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Mon Sep 2 14:45:56 2024 -0700

    fix remaining `vulcan`-family bug

commit 571412b15e
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Mon Sep 2 14:15:56 2024 -0700

    fix chasey xl offsets

commit 907bd8318c
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Mon Sep 2 14:12:35 2024 -0700

    several more fixes, now runs to the end but shot offset is wrong

commit 7170552448
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Mon Sep 2 13:41:42 2024 -0700

    first three waves of bug fixes

commit 01ab6d3969
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Mon Sep 2 12:59:49 2024 -0700

    maybe the rest of the refactor?

commit 7869192dee
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Tue Aug 20 01:21:13 2024 -0700

    partial refactor continued

commit a4658e3ef4
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Mon Aug 19 16:00:16 2024 -0700

    halfway through bullet refactor
2024-09-02 14:46:51 -07:00
60b685d94b
save a copy of vacuum_gambit.p8 as last_tyrianlike
next step is to pick a real direction -- MMBN-like (+STS-like) or
Survivors-like -- and adapt to match. I am likely to completely remove
the energy system and use permanent autofire, freeing both fire buttons
for more interesting tasks. It loses the opportunity to create a dynamic
around baiting an enemy to keep shooting so its shields don't recover,
but I don't think it loses a lot else.

Either energy management needs to become really important and the game
becomes strategic and tactical, or it needs to be a non-issue and it is
an arcade game. Tyrian itself did not make the energy system interesting
and it was just a tax, so making it interesting would be doing something
new. But I think it's a kind of "interesting" that almost nobody would
adopt unless I go _very hard_ into creating a tactical/strategic shmup.
A shmup that is actually a strange kind of RTS sounds... really cool,
actually, but I'm not at all confident I could design it.

Removing energy entirely gives us a button _and_ a meter back, which
can be used for XP (Survivors-like) or rearm time (MMBN-like).
2024-08-18 15:04:17 -07:00
cc1e7ea5b7
surive at 0hp and adjust hp values to match
Instead of doing a special case for 1HP, 0HP is survivable, ships die
at negative HP instead. all ship health is adjusted to match, assuming
the weakest shot is 0.5hp, which is currently true. the "real" game will
totally rebalance all ships and weapons anyway.

we're getting close to when I have to stop dawdling and implement the
real game, the engine is _there._
2024-08-18 14:57:29 -07:00
6b8efe3438
fix HP-only mode
it was showing the bar intended as the warning that there's no HP
under the shield. but I tried it and that bar just makes it look like
there *is* a sliver of health, which there isn't. so it's better off
without that in either mode.
2024-08-18 14:49:44 -07:00
c2668cefea
handle 0 shield and 1 max HP cases 2024-08-18 14:40:11 -07:00
eebd84544b
one hit comment now shows correct value to use
some guns do less than one damage per shot (vulcan gun does 0.5), so
Instant Death Mode needs to max at 0x0.0001, the smallest nonzero value
in Pico-8's fixed-point numeric type.

One Hit Mode is just a comment for now, but I've been uncommenting it
to test it. Note that replacing the health meter with a "!" is triggered
by max HP + max shield <= 1 because 1 hp shows an empty bar.

this needs some more special cases for low-HP ships with active shields.
2024-08-18 01:57:53 -07:00
965fc0d688
major rebalances
10s generator is too slow -- 10 seconds ago is an eternity in a shmup
and a player who has stopped firing should recover much faster. The
generator's max capacity is much lower and shield cost has been
rebalanced to match.

The Protron is much more expensive to fire, it was previously just
easy mode.

Shields now recover faster _once they start recovering_ (every second
if energy is available) but getting hit causes a "penalty cooldown"
that is much longer than the standard recovery interval. This behavior
is taken from Halo and basically every modern FPS that came after it;
it's unlike Tyrian, which had consistent shield recovery behavior.
But I think Halo's rule plays much better.
2024-08-18 01:46:39 -07:00
cc3ed20f76
fix overshield 2024-08-18 01:29:27 -07:00
fa0cff1ffc
one hit mode, fix vertmeter
full height meters overflowed p8num range
2024-08-18 01:28:12 -07:00
4f8b861cdb
okay I special cased it 2024-08-18 01:14:05 -07:00
5dc259c094
the Secret Hit Point: you have 1hp when the meter is empty
this won't work if your maxhp is 1, will need to special case that
2024-08-18 01:13:25 -07:00
51629376f2
adjust HUD
Health and shields now share one bar. one hit point is (about) the same
size in each. There is an indicator splitting the two categories of HP.
2024-08-18 01:10:20 -07:00
c5e49740c4
reorganize UI 2024-08-17 23:22:42 -07:00
59738d0376
use constraints to make chasey chase; now it is not wiggly 2024-08-16 19:48:44 -07:00
f736f50870
port improvements to autobrake_test too, excluding the weird calc_targets thing 2024-08-16 19:37:43 -07:00
ccb897af24
fix calculation 2024-08-16 19:37:05 -07:00
c130f4cf52
actually invoke calc_targets 2024-08-16 19:25:10 -07:00
cf48497432
ymin and ymax for player 2024-08-16 19:23:20 -07:00
9dc36a95ee
port ship constraints logic 2024-08-16 19:20:30 -07:00
d33d7ad6d1
xmax constraint -- imperfect but good enough 2024-07-27 18:49:48 -07:00
00678f97fd
Fix brake location calculation; was applying it to the wrong spot. 2024-07-27 17:47:29 -07:00
8fa98e3132
handle undershot and ok cases 2024-01-28 01:33:25 -08:00
5d2dafa64c
I am baffled I never noticed this before 2024-01-27 13:25:47 -08:00
bd61ca2639
remove spark stub, not worth it in the test 2024-01-20 11:52:41 -08:00
54426be303
now it actually works! 2024-01-14 20:06:09 -08:00
84a803b828
fixed it! mostly 2024-01-14 20:02:45 -08:00
a4ed50d9e2
okay now i fucked it up differently 2024-01-14 19:59:51 -08:00
a1df463a16
braking distance and visualization. bad calculation
the visualization is really helpful for showing me that I fucked up my math
2024-01-14 19:57:22 -08:00
d0a17488d0
pull out calc_velocity
also prepare constraints to change color based on whether it changed the requested thrust
2024-01-14 19:33:57 -08:00
aa25f87c46
Full debug diagnostics display for autobrake_test 2024-01-14 19:03:34 -08:00
edbde8e689
ship mover, no constraint yet 2024-01-14 18:21:10 -08:00
5b668cf9c9
empty template for autobrake test cart 2024-01-12 11:14:54 -08:00
34af172ca5
Add code-of-conduct 2023-12-30 12:50:18 -08:00
4804402f32
fix search-and-replace damage from a while back
a batch change from ship to self broke the thing that kept the player on
the screen. also spawn_goodie got missed in the migration to `_ENV` for
looking up stuff by name.
2023-12-24 21:39:52 -08:00
97ddfb876b
fix weird line break 2023-12-22 00:40:01 -08:00
fbeb313078
ignore vscode config 2023-12-21 23:30:17 -08:00
a359bc5031
duplicating the file -- preparing for major changes.
Vacuum Gambit is about to stop being a Tyrian clone. The hybrid of
Mega Man Battle Network and Slay the Spire mechanics lends itself better
to Galaga than Tyrian. updatedshmup.p8 remains an excellent basis for a
Tyrian-like shmup, especially since it has a (demo of a) level loading
engine that reads strings, and maybe I'll even implement something along
those lines someday -- but I'm about to tear it all down to build it up
again, starting with the entire model for levels and progress, followed
shortly by the "energy" system and its interaction with shields.

(long-term plan: shields will auto-recover after every "flotilla", but
health will be more difficult to recover. Player shots will be limited
entirely by ammo and cooldown, replacing the "burst throughput" vs.
"sustain throughput" system created by the generator, although some
enemy firing patterns may recreate that behavior.)

(plan for the "level" system: create Galaga-style flotillas. I think
ship behaviors can reasonably be declared in the 8 bits available in
sprite flags, meaning I can program simple enemies entirely from the
sprite sheet and draw flotillas on the map.)
2023-12-21 13:09:33 -08:00
cdf517c51c
fix missing self plumbing 2023-12-20 18:16:55 -08:00
9aac99ef30
replace grab_butts with act
marshaling through a table is a waste of time, the duplication betweeen
positive and negative thrust vectors is pointless, and pre-multiplying
thrust complicates "stay in a box" goals later on.
2023-12-20 18:14:39 -08:00
5fef5bad00
Squash level_parser into main: parse levels in CSV
commit b91ebeb775
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 13:33:00 2023 -0800

    fix boss

    it works now except for a square being drawn in the shield. good enough

commit ab687f8f6d
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 13:23:29 2023 -0800

    adjust spawning

    now it runs for a little tiny bit!

commit bef95df6a1
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 13:18:20 2023 -0800

    typo

commit 24435a3c15
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 13:18:01 2023 -0800

    move guns before ships

commit 0c3a36f1fd
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 13:15:34 2023 -0800

    defer zap_gun creation until it exists

commit a39c419e5f
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 13:13:51 2023 -0800

    fix mknew

commit 9ef762268f
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 13:04:13 2023 -0800

    many assorted syntax errors

commit e50f516b11
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 12:00:34 2023 -0800

    allow strings when spawning guns

commit f9e28fa0e2
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 11:59:20 2023 -0800

    fix missing paren

commit 38a054dec1
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 11:48:08 2023 -0800

    candidate conversion to csv for level format

commit fd391ff3bc
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 11:40:11 2023 -0800

    use _ENV to get rid of level_events and spawns

commit fbd9f97429
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Wed Dec 20 11:33:59 2023 -0800

    maybe fix the level parser

commit 2a61e8b5d6
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Sun Oct 15 21:09:12 2023 -0700

    partial conversion to CSV-based levels, does not run yet

commit 4ccbe1dc35
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Fri Oct 13 01:02:43 2023 -0700

    okay honestly this all can and should just be CSVs

commit b536d2c987
Author: Kistaro Windrider <kistaro@gmail.com>
Date:   Sun Oct 8 00:41:24 2023 -0700

    base for representing a level as a string
2023-12-20 14:09:07 -08:00
2bbc4e598c
clean up macOS garbage 2023-12-19 16:26:11 -08:00
7 changed files with 4625 additions and 79 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.DS_Store
.vscode/settings.json

244
autobrake_test.p8 Normal file
View File

@ -0,0 +1,244 @@
pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
-- vacuum gambit automatic brake test
-- by kistaro windrider
function usplit(str)
return unpack(split(str))
end
function csv(s)
local ret = split(s, "\n")
for i, v in ipairs(ret) do
ret[i] = type(v) == "string" and split(v) or { v }
end
return ret
end
-- generate standard "overlay"
-- constructor for type tt.
-- if more is defined, generated
-- new calls more(ret) after
-- ret is definitely not nil
-- before calling setmetatable.
-- use to initialize mutables.
--
-- if there was a previous new,
-- it is invoked on the new
-- object *after* more, because
-- this works better with the
-- `more` impls i use.
function mknew(tt, more)
local mt, oldnew = { __index = tt }, tt.new
tt.new = function(ret)
if (not ret) ret = {}
if (more) more(ret)
if (oldnew) oldnew(ret)
setmetatable(ret, mt)
return ret
end
end
function _init()
pal(1,129,1)
the_ship = ship.new()
constraints:setup()
slomo = 1
sloc = 0
reroll()
end
function reroll()
frames=0
sloc=0
the_ship:reroll()
end
function _update60()
if (btnp(4)) reroll()
if (btnp(5)) constraints:cycle()
if (btnp(3)) slomo <<= 1
if (btnp(2)) slomo >>= 1
slomo = (slomo < 1) and 1 or (slomo > 8192) and 8192 or slomo
sloc += 1
if sloc >= slomo then
frames += 1
the_ship:update()
sloc=0
end
end
function _draw()
cls(1)
constraints:draw()
the_ship:draw()
print("frames: " .. frames, 4, 64, 7)
print("speed: 1/" .. slomo, 8, 70, 7)
print("thrust: ".. actual_t, 4, 80, 7)
meter(80, 80, 128, 84, actual_t/the_ship.thrust/2)
print("dx: ".. the_ship.dx, 20, 86, 7)
meter(80, 86, 128, 90, the_ship.dx/the_ship.maxspd/2)
print("x: "..the_ship.x, 24, 92, 7)
print("bx: "..gbx, 20, 98, 7)
print("xmin:"..tostr(constraints.xmin), 12, 108, 7)
print("xmax:"..tostr(constraints.xmax), 12, 114, 7)
end
function meter(x0, y0, x1, y1, frac)
local c = 11
if frac < 0 then
frac = -frac
c = 8
end
local range = x1-x0
local midpoint = x0 + (range/2)
rectfill(x0, y0-1, x0, y1+1, 13)
rectfill(midpoint, y0-1, midpoint, y1 + 1, 13)
local width = range * frac
if (width ~= 0) rectfill(x0, y0, x0 + width, y1, c)
end
-->8
-- ship
ship = {
maxspd=4,
thrust=0.25,
drag=0.0625,
y=32,
}
mknew(ship)
function ship:reroll()
self.x=rnd(128)
self.dx=rnd(2*self.maxspd)-self.maxspd
end
function ship:draw()
if self.x < -7 then
spr(2, 0, self.y-7)
spr(2, 0, self.y+8)
elseif self.x > 127 then
spr(2, 120, self.y-7, 1, 1, true)
spr(2, 120, self.y+8, 1, 1, true)
else
spr(1,self.x,self.y)
end
--if (self.dx == 0) return
local bd, f = brake_dist(self.dx, self.thrust + self.drag)
gbx = self.x+bd
spr(3, gbx-2,self.y-2)
print(tostr(f), gbx-2, self.y - 8, 14)
end
function calc_velocity(v0, t, vmax, drag)
v0 = mid(v0 + t, vmax, -vmax)
return v0 - mid(drag, -drag, v0)
end
function ship:update()
local t = btn(0) and -1 or btn(1) and 1 or 0
t *= self.thrust
t = constraints:constrain(self, t)
-- t = constraints:constrain(self, t)
-- t = constraints:constrain(self, t)
local s = calc_velocity(self.dx, t, self.maxspd, self.drag)
self.x += s
self.dx = s
actual_t = t
end
-->8
-- constraints
constraints = {
ymin=20,
ymax=52,
color=10
}
function constraints:constrain(s, want)
self.color=10
if (not self.xmin) return want
-- bmx: brake max
local v1, bmx = calc_velocity(s.dx, want, s.maxspd, s.drag), s.thrust + s.drag
local bd, bf = brake_dist(v1, bmx)
local bx, txm = s.x + bd + v1, self.xmax
if bx < self.xmin then
-- predicted brake point left
-- of xmin; apply max reverse
-- thrust, treat xmin as our
-- max target, and handle
-- overbraking by coalescing
-- with past +xmax case
self.color = 9
want = s.thrust
txm = self.xmin
v1 = calc_velocity(s.dx, want, s.maxspd, s.drag)
bd, bf = brake_dist(v1, bmx)
bx = bd + s.x + v1
end
if (bx <= txm) return want
self.color = 8
local overage = bx - txm
want -= overage/max(bf,1)
if (want < -s.thrust) want = -s.thrust
return want
end
function brake_dist(v0, brake_max)
local tri_frames = abs(v0\brake_max)
local chunks = tri_frames * (tri_frames - 1) >> 1
local chunk_zone = chunks * brake_max
local overage = abs(v0) - tri_frames * brake_max
return (chunk_zone + overage * (tri_frames + 1)) * sgn(v0), (overage > 0) and tri_frames + 1 or tri_frames
end
function constraints:cycle()
if self.ctype=="bounds" then
self.ctype="point"
elseif self.ctype=="point" then
self.ctype="off"
else
self.ctype="bounds"
end
self:setup()
end
function constraints:setup()
if self.ctype=="point" then
self.xmin = 64
self.xmax = 64
elseif self.ctype=="bounds" then
self.xmin = 32
self.xmax = 96
else
self.xmin = nil
self.xmax = nil
end
end
function constraints:draw()
if (not self.xmin) return
rect(self.xmin, self.ymin, self.xmax, self.ymax, self.color)
end
-->8
-- fx
-- todo: spark ring buffer
__gfx__
000000008000000000080000a000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000006666000080000009090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000067777600800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000675555758008888009090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000006750007508000000a000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000067777500080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000005555000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

1
code-of-conduct.md Normal file
View File

@ -0,0 +1 @@
Trans rights.

View File

@ -75,7 +75,7 @@ function updategame()
edeaths = {} edeaths = {}
for ip, ps in ipairs(pships) do for ip, ps in ipairs(pships) do
for ie, eb in ipairs(ebullets) do for ie, eb in ipairs(ebullets) do
if collides(hurtobx(ps), hurtbox(eb)) then if collides(hurtbox(ps), hurtbox(eb)) then
if (eb:hitship(ps)) add(edeaths, ie) if (eb:hitship(ps)) add(edeaths, ie)
if ps:hitbullet(eb) then if ps:hitbullet(eb) then
add(pdeaths, ip) add(pdeaths, ip)

2162
last_tyrianlike.p8 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -397,23 +397,6 @@ function dropshadow(str, x, y, col)
print(str, x, y, col) print(str, x, y, col)
end end
function grab_p1_butts()
if state ~= game then
local r = {0,0,0,0,0}
r[0] = 0
return r
end
local b = btn()
return {
[0]=b&0x1,
[1]=(b&0x2)>>1,
[2]=(b&0x4)>>2,
[3]=(b&0x8)>>3,
[4]=(b&0x10)>>4,
[5]=(b&0x20)>>5
}
end
-->8 -->8
--ship behavior --ship behavior
@ -448,19 +431,19 @@ end
function ship_m:move() function ship_m:move()
self:refresh_shield() self:refresh_shield()
self.power = min(self.max_power, self.power + self.generator) self.power = min(self.max_power, self.power + self.generator)
butt = self:grab_butts() local dx, dy, shoot_spec, shoot_main = self:act()
if (butt[5] > 0) self:maybe_shoot(self.main_gun) if (shoot_main) self:maybe_shoot(self.main_gun)
if (butt[4] > 0) self:maybe_shoot(self.special_gun) if (shoot_spec) self:maybe_shoot(self.special_gun)
if (butt[0]-butt[1] ~= 0 or butt[2]-butt[3] ~= 0) spark(self.sparks, self.x + 4*self.size, self.y + 4*self.size, butt, self.thrust, self.sparkodds) if (dx ~= 0 or dy ~= 0) spark(self.sparks, self.x + 4*self.size, self.y + 4*self.size, dx*2.5, dy*2.5, self.sparkodds)
self.xmomentum += (self.thrust * butt[1]) - (self.thrust * butt[0]) self.xmomentum += dx
self.ymomentum += (self.thrust * butt[3]) - (self.thrust * butt[2]) self.ymomentum += dy
self.xmomentum = mid(-self.maxspd, self.maxspd, self.xmomentum) self.xmomentum = mid(-self.maxspd, self.maxspd, self.xmomentum)
self.ymomentum = mid(-self.maxspd, self.maxspd, self.ymomentum) self.ymomentum = mid(-self.maxspd, self.maxspd, self.ymomentum)
self.x += self.xmomentum self.x += self.xmomentum
self.y += self.ymomentum self.y += self.ymomentum
if self == primary_self then if self == primary_ship then
self.x = mid(0, 112 - 8 * self.size, self.x) self.x = mid(0, 112 - 8 * self.size, self.x)
self.y = mid(0, 128 - 8 * self.size, self.y) self.y = mid(0, 128 - 8 * self.size, self.y)
end end
@ -869,16 +852,18 @@ player = ship_m.new{
thrust = 0.25, -- momentum added from button thrust = 0.25, -- momentum added from button
drag = 0.125, -- momentum lost per frame drag = 0.125, -- momentum lost per frame
slip = false, -- does not slide down screen slip = false, -- does not slide down screen
grab_butts = function(self) -- fetch buttons act = function(self) -- fetch buttons
local butts = grab_p1_butts() local b,th = btn(),self.thrust
if butts[0] == butts[1] then local blr = b&0x3
self.sprite = 1 if blr == 1 then
elseif butts[0] > 0 then self.sprite=17
self.sprite = 17 elseif blr==2 then
self.sprite=18
else else
self.sprite = 18 self.sprite=1
end end
return butts --dx, dy, shoot_spec, shoot_main
return (((b&0x2)>>1) - (b&0x1)) * th, (((b&0x8)>>3) - ((b&0x4)>>2)) * th, (b&0x10) > 0, (b&0x20) > 0
end end
} }
mknew(player, mknew(player,
@ -912,18 +897,12 @@ frownie = ship_m.new{
thrust = 0.12, -- momentum added from button thrust = 0.12, -- momentum added from button
drag = 0.07, -- momentum lost per frame drag = 0.07, -- momentum lost per frame
slip = true, slip = true,
grab_butts = function(discard_self) act = function(self)
-- buttons are effectively analog local tstate,dx = (1 + flr(4*t() + 0.5)) % 6,0
-- and negative buttons work just fine! if (tstate==1 or tstate==2) dx=-self.thrust
local butts = {} if (tstate>=4) dx=self.thrust
local tstate = (1 + flr(4*t() + 0.5)) % 6 return dx,0,false,false
butts[0] = ((tstate==1 or tstate==2) and 1) or 0 end,
butts[1] = ((tstate==4 or tstate==5) and 1) or 0
for b=2, 5 do
butts[b]=0
end
return butts
end, -- button fetch algorithm
} }
mknew(frownie) mknew(frownie)
@ -962,10 +941,9 @@ spewy = frownie.new{
generator=0.5, generator=0.5,
fire_off_x=4, fire_off_x=4,
fire_off_y = 7, fire_off_y = 7,
grab_butts=function() act=function(self)
local butts=frownie.grab_butts() local dx,dy,shoot_spec=frownie.act(self)
butts[5]=1 return dx, dy, shoot_spec, true
return butts
end end
} }
mknew(spewy, function(ship) mknew(spewy, function(ship)
@ -1000,12 +978,11 @@ mknew(chasey, function(ship)
ship.main_gun=ship.main_gun or zap_gun.new{enemy=true} ship.main_gun=ship.main_gun or zap_gun.new{enemy=true}
end) end)
function chasey:grab_butts() function chasey:act()
local butts = {[0]=0,0,0,0,0,0} local dx = 0
if (self.x < primary_ship.x) butts[1] = 1 if (self.x < primary_ship.x) dx=self.thrust
if (self.x > primary_ship.x) butts[0] = 1 if (self.x > primary_ship.x) dx=-self.thrust
if (self.x - 16 < primary_ship.x and self.x + 16 > primary_ship.x) butts[5] = 1 return dx, 0, false, self.x - 16 < primary_ship.x and self.x + 16 > primary_ship.x
return butts
end end
xl_chasey=chasey.new{ xl_chasey=chasey.new{
@ -1021,10 +998,10 @@ xl_chasey=chasey.new{
shield = 5, shield = 5,
boss = true, boss = true,
slip = false, slip = false,
grab_butts = function(self) act = function(self)
local butts = chasey.grab_butts(self) local dx,dy,shoot_spec,shoot_main = chasey.act(self)
if (self.y < 4) butts[3] = 1 if (self.y < 4) dy=self.thrust
return butts return dx,dy,shoot_spec,shoot_main
end, end,
draw = function(self) draw = function(self)
if(self.fx_pal) pal(self.fx_pal) if(self.fx_pal) pal(self.fx_pal)
@ -1308,7 +1285,7 @@ end
function spawn_goodie(goodie_name, x, y, sz) function spawn_goodie(goodie_name, x, y, sz)
if (not goodie_name or #goodie_name == 0) return if (not goodie_name or #goodie_name == 0) return
local sh = sz and sz/2 or 0 local sh = sz and sz/2 or 0
goodies[goodie_name].new{}:spawn_at(x+sh,y+sh) _ENV[goodie_name].new{}:spawn_at(x+sh,y+sh)
end end
function multi(times, interval, fnm, ...) function multi(times, interval, fnm, ...)
@ -1510,18 +1487,12 @@ like a player pushing buttons.
the player ship actually reads the player ship actually reads
buttons for this. buttons for this.
grab_butts - ship thrust control act -- returns new acceleration:
based on btn() api. returns a dx, dy, shoot_spec, shoot_main.
table indexed from 0..5 with dx and dy are change in momentum
0 to not push this button and 1 in px/frame. this is controls
to push it. ships can use only -- friction is handled in
fractional or out-of-range ship:move (`drag` value).
numbers to get varying amounts
of thrust, including using
negative numbers for thrust in
the opposite direction. 4 and 5
just check for nonzeroness to
attempt to fire.
ships hitting another ship take ships hitting another ship take
1 damage per frame of overlap. 1 damage per frame of overlap.
@ -1800,9 +1771,7 @@ function boom(x,y,boominess,is_boss)
local boombonus = min(0.05 * boominess, 1.25) local boombonus = min(0.05 * boominess, 1.25)
for _=1,boominess do for _=1,boominess do
local angle = rnd(1) local angle = rnd(1)
local butts = {0, sin(angle), 0} spark(sp,x+4,y+4,cos(angle), sin(angle),boombase+rnd(boombonus),1, true)
butts[0] = cos(angle)
spark(sp,x+4,y+4,butts,boombase+rnd(boombonus),1, true)
end end
return return
end end
@ -1822,17 +1791,16 @@ function spark_particle:draw()
pset(self.x,self.y,self.sprs[self.sidx]) pset(self.x,self.y,self.sprs[self.sidx])
end end
function spark(sprs, x, y, butts, thrust, odds, fg) function spark(sprs, x, y, dx, dy, odds, fg)
if (sprs==nil or flr(rnd(odds)) ~= 0) return if (sprs==nil or flr(rnd(odds)) ~= 0) return
thrust *= 2.5
local target = fg and intangibles_fg or intangibles_bg local target = fg and intangibles_fg or intangibles_bg
target:push_back(spark_particle.new{ target:push_back(spark_particle.new{
x = x + rnd(4) - 2, x = x + rnd(4) - 2,
y = y + rnd(4) - 2, y = y + rnd(4) - 2,
sprs = sprs, sprs = sprs,
sidx = 1, sidx = 1,
dx = (butts[0] - butts[1]) * thrust + rnd(2) - 1, dx = dx + rnd(2) - 1,
dy = (butts[2] - butts[3]) * thrust + rnd(2) - 1, dy = dy + rnd(2) - 1,
}) })
end end
-->8 -->8

2169
vacuum_gambit.p8 Normal file

File diff suppressed because it is too large Load Diff