diff --git a/updatedshmup.p8 b/updatedshmup.p8 index e3c6d28..a09aa0b 100644 --- a/updatedshmup.p8 +++ b/updatedshmup.p8 @@ -441,9 +441,147 @@ function grab_p1_butts() end -->8 ---ships, including player +--ship behavior --- XXX BOOKMARK XXX +scrollrate = 0.25 --in px/frame + +ship_m = { + + -- ships have no shield by default + shield = 0, + maxshield = 0, + shieldcost = 32767.9, + shieldcooldown = 180, + + -- default generator behavior: + -- 10 seconds for a full charge + max_power = 600, + power = 600, + generator = 1, -- power gen per frame + + invincible_until = -32768, + + slip = true, -- most enemies slide + + xmomentum = 0, + ymomentum = 0, +} + +ship_t = { + __index = 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) +end + +function ship_m:move() + self:refresh_shield() + self.power = min(self.max_power, self.power + self.generator) + butt = self:grab_butts() + if (butt[5] > 0) self:maybe_shoot(self.main_gun) + if (butt[4] > 0) 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) + self.xmomentum += (self.thrust * butt[1]) - (self.thrust * butt[0]) + self.ymomentum += (self.thrust * butt[3]) - (self.thrust * butt[2]) + self.xmomentum = mid(-self.maxspd, self.maxspd, self.xmomentum) + self.ymomentum = mid(-self.maxspd, self.maxspd, self.ymomentum) + + self.x += self.xmomentum + self.y += self.ymomentum + + if self == primary_self 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 + if self.y >= 128 then + self:die() + return true + end + end + return false +end + +function ship_m:draw() + if(self.fx_pal) pal(self.fx_pal) + spr(self.sprite, self.x, self.y, self.size, self.size) + pal() +end + +function hurtbox(ship) + local h = ship.hurt + return { + x=ship.x + h.x_off, + y=ship.y + h.y_off, + width=h.width, + height=h.height + } +end + +function ship_m:maybe_shoot(gun) + if (not gun) return + if (self.power < gun.power) return + if (not gun:shoot(self.x + self.fire_off_x, self.y + self.fire_off_y)) return + self.power -= gun.power +end + +function ship_m:hitship(other) + return self:hitsomething(1) +end + +function ship_m:hitbullet(b) + return self:hitsomething(b.damage) +end + +function ship_m:hitsomething(dmg) + if (dmg <= 0) return false + if (lframe < self.invincible_until) return false + self.shield_refresh_ready = lframe + self.shieldcooldown + if self.shield >= dmg then + self.shield -= dmg + self:ow(true) + return false + end + dmg -= self.shield + self.shield = 0 + self.hp -= dmg + if self.hp <= 0 then + self:die() + return true + end + self:ow(false) + return false +end + +function ship_m:ow(shielded) + if (shielded) then + blip(self,12,3) + return + end + blip(self, 7, 3) +end + +function ship_m:refresh_shield() + if (self.shield >= self.maxshield) return + if (lframe < self.shield_refresh_ready) return + if (self.power < self.shieldcost) return + self.shield += 1 + self.power -= self.shieldcost + self.shield_refresh_ready = lframe + self.shieldcooldown +end + +-->8 +--ships, including player function init_ship_mt() setmetatable(player, ship_t) @@ -693,145 +831,6 @@ function spawn_xl_chasey_at(x, y) return c end -->8 ---ship behavior - -scrollrate = 0.25 --in px/frame - -ship_m = { - - -- ships have no shield by default - shield = 0, - maxshield = 0, - shieldcost = 32767.9, - shieldcooldown = 180, - - -- default generator behavior: - -- 10 seconds for a full charge - max_power = 600, - power = 600, - generator = 1, -- power gen per frame - - invincible_until = -32768, - - slip = true, -- most enemies slide - - xmomentum = 0, - ymomentum = 0, -} - -ship_t = { - __index = 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) -end - -function ship_m:move() - self:refresh_shield() - self.power = min(self.max_power, self.power + self.generator) - butt = self:grab_butts() - if (butt[5] > 0) self:maybe_shoot(self.main_gun) - if (butt[4] > 0) 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) - self.xmomentum += (self.thrust * butt[1]) - (self.thrust * butt[0]) - self.ymomentum += (self.thrust * butt[3]) - (self.thrust * butt[2]) - self.xmomentum = mid(-self.maxspd, self.maxspd, self.xmomentum) - self.ymomentum = mid(-self.maxspd, self.maxspd, self.ymomentum) - - self.x += self.xmomentum - self.y += self.ymomentum - - if self == primary_self 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 - if self.y >= 128 then - self:die() - return true - end - end - return false -end - -function ship_m:draw() - if(self.fx_pal) pal(self.fx_pal) - spr(self.sprite, self.x, self.y, self.size, self.size) - pal() -end - -function hurtbox(ship) - local h = ship.hurt - return { - x=ship.x + h.x_off, - y=ship.y + h.y_off, - width=h.width, - height=h.height - } -end - -function ship_m:maybe_shoot(gun) - if (not gun) return - if (self.power < gun.power) return - if (not gun:shoot(self.x + self.fire_off_x, self.y + self.fire_off_y)) return - self.power -= gun.power -end - -function ship_m:hitship(other) - return self:hitsomething(1) -end - -function ship_m:hitbullet(b) - return self:hitsomething(b.damage) -end - -function ship_m:hitsomething(dmg) - if (dmg <= 0) return false - if (lframe < self.invincible_until) return false - self.shield_refresh_ready = lframe + self.shieldcooldown - if self.shield >= dmg then - self.shield -= dmg - self:ow(true) - return false - end - dmg -= self.shield - self.shield = 0 - self.hp -= dmg - if self.hp <= 0 then - self:die() - return true - end - self:ow(false) - return false -end - -function ship_m:ow(shielded) - if (shielded) then - blip(self,12,3) - return - end - blip(self, 7, 3) -end - -function ship_m:refresh_shield() - if (self.shield >= self.maxshield) return - if (lframe < self.shield_refresh_ready) return - if (self.power < self.shieldcost) return - self.shield += 1 - self.power -= self.shieldcost - self.shield_refresh_ready = lframe + self.shieldcooldown -end --->8 -- collisions -- box: x, y, width, height