27 Commits

Author SHA1 Message Date
ead2a7d874 fix remaining vulcan-family bug 2024-09-02 14:45:56 -07:00
571412b15e fix chasey xl offsets 2024-09-02 14:15:56 -07:00
907bd8318c several more fixes, now runs to the end but shot offset is wrong 2024-09-02 14:12:35 -07:00
7170552448 first three waves of bug fixes 2024-09-02 13:41:42 -07:00
01ab6d3969 maybe the rest of the refactor? 2024-09-02 12:59:49 -07:00
7869192dee partial refactor continued 2024-08-20 01:21:13 -07:00
a4658e3ef4 halfway through bullet refactor 2024-08-19 16:00:16 -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
3 changed files with 2447 additions and 202 deletions

View File

@ -81,9 +81,10 @@ function _draw()
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, 102, 7)
print("xmax:"..tostr(constraints.xmax), 12, 108, 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)
@ -127,26 +128,24 @@ function ship:draw()
spr(1,self.x,self.y)
end
if (self.dx == 0) return
--if (self.dx == 0) return
local bd, f = brake_dist(self.dx, self.thrust + self.drag)
local bdx = self.x+bd-2
spr(3, bdx,self.y-2)
print(tostr(f), bdx, self.y - 8, 14)
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)
local v1 = v0 + t
local sg = sgn(v1)
v1 -= sg*drag
if (sgn(v1) != sg) return 0
if (abs(v1) > vmax) return sg*vmax
return v1
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
@ -170,18 +169,26 @@ function constraints:constrain(s, 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, self.xmax
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
bx = bd + s.x + v1
end
if (bx < txm) return want
if (bx <= txm) return want
self.color = 8
-- TODO: implement overshot constraint
local overage = bx - txm
want -= overage/max(bf,1)
if (want < -s.thrust) want = -s.thrust
return want
end

2164
last_tyrianlike.p8 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
pico-8 cartridge // http://www.pico-8.com
version 41
version 42
__lua__
-- vacuum gambit
-- by kistaro windrider
@ -18,6 +18,11 @@ function csv(s)
end
return ret
end
function const_fxn(x)
return function()
return x
end
end
-- generate standard "overlay"
-- constructor for type tt.
@ -118,7 +123,7 @@ end
function _init()
init_blip_pals()
wipe_level()
primary_ship.main_gun = zap_gun.new()
primary_ship.main_gun = zap_gun_p.new() -- redundant?
load_level(example_level_csv)
state = game
pal(2,129)
@ -320,6 +325,7 @@ function drawgame()
end
powcols=split"170,154,153,148,68"
shlcols = split"204,220,221"
function drawhud()
-- 112-and-right is hud zone
rectfill(112, 0, 127, 127,0x56)
@ -328,20 +334,29 @@ function drawhud()
line(113,127)
draw_gun_info("❎",1,116,3,primary_ship.main_gun)
draw_gun_info("🅾️",2,116,31,primary_ship.special_gun)
draw_gun_info("🅾️",1,116,31,primary_ship.special_gun)
dropshadow("pwr",114,59,1)
inset(114,66,125,92)
dropshadow("p h",114,59,1)
inset(114,66,119,125)
fillp(0x5a5a)
vertmeter(115,67,124,91,primary_ship.power, primary_ship.max_power, powcols)
vertmeter(115,67,118,124,primary_ship.power, primary_ship.max_power, powcols)
dropshadow("h s",114,97,1)
inset(114,104,125,125)
line(119,105,119,124,119)
line(120,105,120,125,85)
vertmeter(115,105,118,124,primary_ship.hp, primary_ship.maxhp, hpcols)
vertmeter(121,105,124,124,primary_ship.shield, primary_ship.maxshield,{204,220,221})
inset(120,66,125,125)
-- 57 px vertically
local mxs, cs, mxh, ch = primary_ship.maxshield, primary_ship.shield, primary_ship.maxhp, primary_ship.hp
if (mxs > 0) and (mxh > 0) then
local split = 57 * (mxs / (mxs + mxh)) \ 1 + 66
line(121, split, 124, split, 0xba)
vertmeter(121,67,124,split-1,cs, mxs,shlcols)
vertmeter(121,split+1,124,124,ch, mxh, hpcols)
elseif mxs > 0 then
vertmeter(121,67,124,124,cs,mxs,shlcols)
elseif mxh > 0 then
vertmeter(121,67,124,124,ch,mxh,hpcols)
else
print("!", 122, 94, 9)
print("!", 121, 93, 8)
end
fillp(0)
end
@ -368,9 +383,9 @@ function draw_gun_info(lbl,fgc,x,y,gun)
end
function vertmeter(x0,y0,x1,y1,val,maxval,cols)
if (val <= 0) return
if ((val <= 0) or (maxval <= 0)) return
local h = y1-y0
local px = -flr(-(h*val)\maxval)
local px = val/maxval * h \ 1
local ncols = #cols
local firstcol = ((h-px)*ncols\h)+1
local lastbottom = y0+(h*firstcol\ncols)
@ -408,51 +423,86 @@ ship_m = {
shield = 0,
maxshield = 0,
shieldcost = 32767.9,
shieldcooldown = 0x0.00a0,
shieldcooldown = 0x0.003c,--1s
shieldpenalty = 0x0.012c, --5s
-- default generator behavior:
-- 10 seconds for a full charge
max_power = 600,
power = 600,
generator = 1, -- power gen per frame
max_power = 120,
power = 120,
generator = 2, -- power gen per frame
slip = true, -- most enemies slide
xmomentum = 0,
ymomentum = 0,
-- xmin, xmax, ymin, ymax:
-- movement constraints
-- enforced by `constrain`.
xmin = 0, xmax = 104,
-- ymin, ymax default to nil
-- pship needs more constraint
}
mknew(ship_m)
function ship_m:die()
self.dead = true
if (self.hp <= 0) boom(self.x+self.size*4, self.y+self.size*4,12*self.size, self.boss)
if (self.hp < 0) boom(self.x+self.size*4, self.y+self.size*4,12*self.size, self.boss)
end
function ship_m:calc_velocity(v0, t)
v0 = mid(v0 + t, self.maxspd, -self.maxspd)
return v0 - mid(self.drag, -self.drag, v0)
end
function ship_m:brake_dist(v0)
local brake_max = self.thrust + self.drag
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 ship_m:constrain(p, dp, pmin, pmax, want)
if (not pmin) return want
local v1, bd, bf, bp
function calc_targets()
-- velocity after move
v1 = self:calc_velocity(dp, want)
-- brake distance and frames
bd, bf = self:brake_dist(v1)
-- brake point
bp = p + bd + v1
end
calc_targets()
if bp < pmin then
-- undershoot. max thrust,
-- then treat as overshoot
-- targeting minimum bound
want, pmax = self.thrust, pmin
calc_targets()
end
if (bp <= pmax) return want
-- spread overshoot across frames
want -= (bp - pmax)/max(bf,1)
return max(want, -self.thrust)
end
function ship_m:move()
self:refresh_shield()
self.power = min(self.max_power, self.power + self.generator)
local dx, dy, shoot_spec, shoot_main = self:act()
dx = self:constrain(self.x, self.xmomentum, self.xmin, self.xmax, dx)
dy = self:constrain(self.y, self.ymomentum, self.ymin, self.ymax, dy)
if (shoot_main) self:maybe_shoot(self.main_gun)
if (shoot_spec) self:maybe_shoot(self.special_gun)
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 += dx
self.ymomentum += dy
self.xmomentum = mid(-self.maxspd, self.maxspd, self.xmomentum)
self.ymomentum = mid(-self.maxspd, self.maxspd, self.ymomentum)
self.xmomentum = self:calc_velocity(self.xmomentum, dx)
self.ymomentum = self:calc_velocity(self.ymomentum, dy)
self.x += self.xmomentum
self.y += self.ymomentum
if self == primary_ship then
self.x = mid(0, 112 - 8 * self.size, self.x)
self.y = mid(0, 128 - 8 * self.size, self.y)
end
--friction
local d = self.drag
self.xmomentum -= mid(d, -d, self.xmomentum)
self.ymomentum -= mid(d, -d, self.ymomentum)
-- "scrolling" behavior
if self.slip then
self.y += scrollrate
@ -497,7 +547,7 @@ end
function ship_m:hitsomething(dmg)
if (dmg <= 0) return false
self.shield_refresh_ready = lframe + self.shieldcooldown
self.shield_refresh_ready = lframe + self.shieldpenalty
if self.shield >= dmg then
self.shield -= dmg
self:ow(true)
@ -506,7 +556,7 @@ function ship_m:hitsomething(dmg)
dmg -= self.shield
self.shield = 0
self.hp -= dmg
if self.hp <= 0 then
if self.hp < 0 then
self:die()
return true
end
@ -527,6 +577,7 @@ function ship_m:refresh_shield()
if (lframe < self.shield_refresh_ready) return
if (self.power < self.shieldcost) return
self.shield += 1
self.shield = min(self.shield, self.maxshield)
self.power -= self.shieldcost
self.shield_refresh_ready = lframe + self.shieldcooldown
end
@ -534,9 +585,15 @@ end
-->8
-- bullet and gun behaviors
bullet_base = {
enemyspd = 0.5
}
function player_blt_cat()
return pbullets
end
function enemy_blt_cat()
return ebullets
end
bullet_base = { }
mknew(bullet_base)
gun_base = {
@ -555,19 +612,11 @@ end
function bullet_base:move()
self.x += self.dx
if self.enemy then
self.y += self.dy
if self.y > 128 then
if (self.y > 128) or (self.y < -8 * self.height) then
self:die()
return true
end
else
self.y -= self.dy
if self.y < -8*self.height then
self:die()
return true
end
end
return false
end
@ -575,19 +624,20 @@ function bullet_base:draw()
spr(self.sprite, self.x, self.y, self.width, self.height)
end
function bullet_base:spawn_at(x, y)
self.x = x - self.center_x_off
if self.enemy then
self.dx *= self.enemyspd
self.dy *= self.enemyspd
self.y = y + self.top_y_off
ebullets:push_back(self)
else
self.y = y - (8 * self.height) + self.bottom_y_off
pbullets:push_back(self)
-- An `actually_shoot` factory
-- for trivial guns
function spawn_one(t)
return function(gun, x, y)
t.new{}:spawn_at(x, y)
end
end
function bullet_base:spawn_at(x, y)
self.x = x - self.x_off
self.y = y - self.y_off
self.category():push_back(self)
end
function gun_base:shoot(x, y)
if (lframe < self.shoot_ready) return false
if self.ammo then
@ -599,23 +649,12 @@ function gun_base:shoot(x, y)
return true
end
function gun_base:actually_shoot(x, y)
local typ = self.t
local b = typ.new{
enemy = self.enemy,
sprite = self.enemy and typ.esprite or typ.psprite,
}
b:spawn_at(x, y)
return true
end
-->8
-- bullets and guns
zap = bullet_base.new{
zap_e = bullet_base.new{
--shape
psprite = 8, --index of player ammo sprite
esprite = 9, -- index of enemy ammo sprite
sprite = 9, --index of enemy ammo sprite
width = 1, --in 8x8 blocks
height = 1,
hurt = { -- hurtbox - where this ship can be hit
@ -624,33 +663,43 @@ zap = bullet_base.new{
width = 2,
height = 8
},
center_x_off = 1, -- how to position by ship
bottom_y_off = 0,
top_y_off = 0,
x_off = 1, -- how to position by ship
y_off = 8,
damage = 1,
dx = 0, -- px/frame
dy = 8,
dy = 4,
hitship = function(_, _)
return true
end
hitship = const_fxn(true),
category = enemy_blt_cat,
}
mknew(zap)
mknew(zap_e)
zap_gun = gun_base.new{
enemy = false,
zap_p = zap_e.new{
sprite = 8,
dy = -8,
y_off = 0,
category = player_blt_cat,
}
mknew(zap_p)
zap_gun_e = gun_base.new{
power = 20, -- power consumed per shot
cooldown = 0x0.000a, -- frames between shots
ammo = nil, -- unlimited ammo - main gun
t = zap -- metatable of bullet to fire
actually_shoot = spawn_one(zap_e),
}
mknew(zap_gun)
mknew(zap_gun_e)
zap_gun_p = zap_gun_e.new{
actually_shoot = spawn_one(zap_p),
}
mknew(zap_gun_p)
blast = bullet_base.new{
--shape
psprite = 12, --index of player ammo sprite
esprite = 3, -- index of enemy ammo sprite
sprite = 12, --index of player ammo sprite
width = 1, --in 8x8 blocks
height = 1,
hurt = { -- hurtbox - where this ship can be hit
@ -659,13 +708,12 @@ blast = bullet_base.new{
width = 6,
height = 6
},
center_x_off = 4, -- how to position by ship
bottom_y_off = 0,
top_y_off = 0,
x_off = 4, -- how to position by ship
y_off = 0,
damage = 4,
dx = 0, -- px/frame
dy = 2,
dy = -2,
awaitcancel = false,
-- disable damage for 2 frames
@ -690,25 +738,24 @@ blast = bullet_base.new{
self.awaitcancel = false
end)
end
end
end,
category=player_blt_cat
}
mknew(blast)
blast_gun = gun_base.new{
icon = 13,
enemy = false,
power = 0, -- ammo, not power
power = 0, -- only cost is ammo
cooldown = 0x0.0020, -- frames between shots
ammo = 5,
maxammo = 5,
t = blast -- type of bullet to fire
actually_shoot = spawn_one(blast),
}
mknew(blast_gun)
protron = bullet_base.new{
protron_e = bullet_base.new{
--shape
psprite = 23, --index of player ammo sprite
esprite = 24, -- index of enemy ammo sprite
sprite = 24,
width = 1, --in 8x8 blocks
height = 1,
hurt = { -- hurtbox - where this ship can be hit
@ -717,56 +764,63 @@ protron = bullet_base.new{
width = 2,
height = 2
},
center_x_off = 1, -- how to position by ship
bottom_y_off = 4,
top_y_off = 0,
x_off = 1, -- how to position by ship
y_off = 4,
damage = 1,
dx = 0, -- px/frame
dy = 3,
dym = 0.5, -- gun sets dy;
-- this is mult
category = enemy_blt_cat,
}
mknew(protron)
mknew(protron_e)
protron_gun = gun_base.new{
protron_p = protron_e.new{
sprite=23,
dym = -1,
y_off = 0,
category=player_blt_cat,
}
mknew(protron_p)
protron_gun_e = gun_base.new{
icon = 25,
enemy = false,
power = 35,
power = 60,
cooldown = 0x0.000f, -- frames between shots
ammo = nil,
maxammo = nil,
actually_shoot = function(self, x, y)
local sprite = protron.psprite
if (self.enemy) sprite=protron.esprite
munition = protron_e
}
mknew(protron_gun_e)
function protron_gun_e:actually_shoot(x, y)
local m = self.munition.dym
for i=1,3 do
local b = protron.new{
enemy=self.enemy,
sprite=sprite,
dx = i,
dy = 4-i
local b = self.munition.new{
dx = i*m,
dy = (4-i)*m,
}
b:spawn_at(x,y)
local b2 = protron.new{
enemy=self.enemy,
sprite=sprite,
dx = -i,
dy = 4-i
local b2 = self.munition.new{
dx = -i*m,
dy = (4-i)*m,
}
b2:spawn_at(x,y)
end
local bup = protron.new{
enemy=self.enemy,
sprite=sprite,
dy=4
local bup = self.munition.new{
dx=0,
dy=4*m,
}
bup:spawn_at(x,y)
end
}
mknew(protron_gun)
vulcan = bullet_base.new{
protron_gun_p = protron_gun_e.new{
munition = protron_p,
}
mknew(protron_gun_p)
vulcan_e = bullet_base.new{
--shape
psprite = 22, --index of player ammo sprite
esprite = 21, -- index of enemy ammo sprite
sprite = 21,
width = 1, --in 8x8 blocks
height = 1,
hurt = { -- hurtbox - where this ship can be hit
@ -775,31 +829,37 @@ vulcan = bullet_base.new{
width = 1,
height = 4
},
center_x_off = 0.5, -- how to position by ship
bottom_y_off = 4,
top_y_off = 0,
x_off = 0.5, -- how to position by ship
y_off = 0,
damage = 0.5,
dx = 0, -- px/frame
dy = 4,
-- dx from gun
dy = 2,
category=enemy_blt_cat
}
mknew(vulcan)
mknew(vulcan_e)
vulcan_gun = gun_base.new{
vulcan_p = vulcan_e.new{
sprite=22,
y_off = 4,
dy = -4,
category=player_blt_cat
}
mknew(vulcan_p)
vulcan_gun_e = gun_base.new{
icon = 37,
enemy = false,
power = 8,
cooldown = 0x0.0002, -- frames between shots
ammo = nil,
maxammo = nil,
munition=vulcan_e,
dxs = {0.35, -0.35, -0.7, 0.7, 0.35, -0.35},
xoffs = {1, 0, -1, 1, 0, -1},
dxidx = 1,
actually_shoot = function(self, x, y)
local sprite = self.enemy and vulcan.esprite or vulcan.psprite
local b = vulcan.new{
enemy=self.enemy,
sprite=sprite,
local b = self.munition.new{
dx = self.dxs[self.dxidx],
}
b:spawn_at(self.xoffs[self.dxidx]+x,y)
@ -807,7 +867,12 @@ vulcan_gun = gun_base.new{
if (self.dxidx > #self.dxs) self.dxidx = 1
end
}
mknew(vulcan_gun)
mknew(vulcan_gun_e)
vulcan_gun_p = vulcan_gun_e.new{
munition=vulcan_p,
}
mknew(vulcan_gun_p)
-->8
--ships, including player
@ -834,8 +899,8 @@ player = ship_m.new{
maxhp = 3, -- player only; other ships never heal
shield = 2, -- regenerates, using power
maxshield = 2,
shieldcost = 300, -- power cost to refill shield
generator = 1.5, -- 1 feels too slow
shieldcost = 60, -- power cost to refill shield
generator = 2,
-- gun
main_gun = nil, -- assign at spawn time
@ -850,6 +915,7 @@ player = ship_m.new{
ymomentum = 0,
maxspd = 2.5, -- momentum cap
thrust = 0.25, -- momentum added from button
ymin = 0, ymax = 120, -- stay on screen
drag = 0.125, -- momentum lost per frame
slip = false, -- does not slide down screen
act = function(self) -- fetch buttons
@ -868,7 +934,13 @@ player = ship_m.new{
}
mknew(player,
function(p)
p.main_gun = zap_gun.new()
p.main_gun = zap_gun_p.new()
-- ONE HIT MODE
--
-- p.hp = 0
-- p.maxhp = 0
-- p.shield = 0
-- p.maxshield = 0
end
)
@ -886,7 +958,7 @@ frownie = ship_m.new{
sparkodds = 8,
-- health and power
hp = 1, -- enemy ships need no max hp
hp = 0.5, -- enemy ships need no max hp
-- position
x=60, -- x and y are for upper left corner
@ -908,7 +980,7 @@ mknew(frownie)
blocky = frownie.new{
sprite = 10,
hp = 2,
hp = 1.5,
hurt = {
x_off = 0,
y_off = 0,
@ -917,7 +989,7 @@ blocky = frownie.new{
},
ow = function(self)
if self.hp <= 1 then
if self.hp < 1 then
self.sprite = 11
else
self.sprite = 10
@ -936,7 +1008,7 @@ spewy = frownie.new{
width=8,
height=5
},
hp=1,
hp=0.5,
maxpower=70,
generator=0.5,
fire_off_x=4,
@ -947,7 +1019,7 @@ spewy = frownie.new{
end
}
mknew(spewy, function(ship)
ship.main_gun=ship.main_gun or protron_gun.new{enemy=true}
ship.main_gun=ship.main_gun or protron_gun_e.new{enemy=true}
end)
chasey = ship_m.new{
@ -961,7 +1033,7 @@ chasey = ship_m.new{
},
sparks = smokespark,
sparkodds = 8,
hp = 2,
hp = 1.5,
shield = 1,
maxshield = 1,
shieldcost = 180,
@ -975,14 +1047,13 @@ chasey = ship_m.new{
slip = true,
}
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_e.new{}
end)
function chasey:act()
local dx = 0
if (self.x < primary_ship.x) dx=self.thrust
if (self.x > primary_ship.x) dx=-self.thrust
return dx, 0, false, self.x - 16 < primary_ship.x and self.x + 16 > primary_ship.x
self.xmin = max(primary_ship.x-8, 0)
self.xmax = min(primary_ship.x + 8, 112 - 8*self.size)
return 0, 0, false, self.x - 16 < primary_ship.x and self.x + 16 > primary_ship.x
end
xl_chasey=chasey.new{
@ -994,7 +1065,9 @@ xl_chasey=chasey.new{
width = 12,
height = 10
},
hp = 20,
fire_off_x = 8,
fire_off_y = 15,
hp = 19.5,
shield = 5,
boss = true,
slip = false,
@ -1010,7 +1083,7 @@ xl_chasey=chasey.new{
end,
}
mknew(xl_chasey, function(ship)
ship.main_gun=ship.main_gun or zap_gun.new{enemy=true}
ship.main_gun=ship.main_gun or zap_gun_e.new{}
end)
-->8
-- collisions
@ -1219,9 +1292,9 @@ end
function spawn_bonus_vulcan_chasey()
local c = spawn_chasey()
c.main_gun=vulcan_gun.new{enemy=true}
c.main_gun=vulcan_gun_e.new{enemy=true}
c.die = function(self)
spawn_main_gun_at(self.x-1, self.y-1, vulcan_gun)
spawn_main_gun_at(self.x-1, self.y-1, vulcan_gun_p)
chasey.die(self)
end
c.sprite=4
@ -1324,7 +1397,7 @@ example_level_csv=[[1,spawn_frownie
310,spawn_blocking_blocky
310,spawn_blocking_blocky
311,spawn_frownie
350,spawn_main_gun_at,70,-11,protron_gun
350,spawn_main_gun_at,70,-11,protron_gun_p
401,spawn_frownie
420,spawn_blocking_frownie
430,spawn_bonus_vulcan_chasey
@ -1434,8 +1507,9 @@ bullets
shots much easier to dodge
* damage - damage per hit;
used by ships
* psprite, esprite - index of
player or enemy sprite.
* sprite - sprite index.
* x_off, y_off - renamed for
the next two vars. may revert
* center_off_x - the horizontal
centerpoint of the bullet,
for positioning when firing.
@ -1522,10 +1596,12 @@ shields - ship.shieldcost per
point of shields. shieldcooldown
is the interval between
restoring shield points, which
is reset when a ship takes
damage (regardless of whether
that damage is stopped by the
shield or not).
is reset to shieldpenalty when a
ship takes damage (regardless of
whether that damage is stopped
by the shield or not).
shieldpenalty is much worse than
shieldcooldown (hALO shield).
therefore:
* damaged ships spend power
@ -1822,7 +1898,7 @@ powerup = bullet_base.new{
-- easy to pick up
dx = 0,
dy = 1.5, -- 0.75 after enemyspd
enemy = true, -- collides with player ship
category = enemy_blt_cat, -- collides with player ship
damage = 0,
anim_speed = 2,
@ -1855,9 +1931,8 @@ repair = powerup.new{
width = 12,
height = 12
},
center_x_off = 4,
top_y_off = 0,
bottom_y_off = 0,
x_off = 4,
y_off = 0,
sprites = sheen8x8,
hitship = function(self, ship)
if (ship ~= primary_ship) return false
@ -1883,9 +1958,8 @@ gun_swap = powerup.new{
height = 16
},
-- gun = gun_type.new{}
center_x_off = 6,
top_y_off = 0,
bottom_y_off = 4,
x_off = 6,
y_off = 0,
width = 2,
height = 2,
sprites = {64, 66, 68, 70, 72, 74, 76, 78},