Skip to content

Instantly share code, notes, and snippets.

@Achie72
Last active October 10, 2022 20:52
Show Gist options
  • Select an option

  • Save Achie72/bed8655687bb3fe86d5307ae0e25c6e0 to your computer and use it in GitHub Desktop.

Select an option

Save Achie72/bed8655687bb3fe86d5307ae0e25c6e0 to your computer and use it in GitHub Desktop.
TIC-80 shmup exoloding/shrapnel bullets
-- made for my Devtober2022 entry
-- you can read the corresponding devlog on:
-- https://ko-fi.com/post/Eng-Devtober2022-3--MORE-UPGRADES-R6R3FL67S
-- https://itch.io/jam/devtober-2022/topic/2406837/achies-devlog-shmup-game
-- cricl-rect collision from the interwebs
function collidec(_circ, _obj)
local circDX = math.abs(_circ.x - _obj.x+_obj.cw/2)
local circDY = math.abs(_circ.y - _obj.y+_obj.cw/2)
if (circDX > (_obj.cw/2 + _circ.r)) then return false end
if (circDY > (_obj.ch/2 + _circ.r)) then return false end
if (circDX <= (_obj.cw/2)) then return true end
if (circDY <= (_obj.ch/2)) then return true end
local cornerDistSQ = math.pow((circDX - _obj.cw/2),2) + math.pow((circDY - _obj.ch/2),2)
return (cornerDistSQ <= math.pow(_circ.r,2))
end
-- a stupid fast-path check for collisions that otherwise would require heavier calculations
function close_enough(obj1,obj2,dist)
if (math.abs(obj1.x-obj2.x) < dist) and (math.abs(obj1.y-obj2.y) < dist) then
return true
end
return false
end
-- explosion area creation
function add_explosion(_x,_y,_r)
local expl = {
x = _x,
y = _y,
r = _r,
life = 30 -- this is in ticks, so 1 second basically
}
table.insert(explosionAreas, expl)
end
-- simple update function for the explosion areas
for _,expl in ipairs(explosionAreas) do
if expl.life > 0 then
local spd = 3
-- reduce life, so they fade away after a certain ammount of time
expl.life = expl.life -1
-- create cute particles, as everything is better with particles
add_particle(expl.x+4,expl.y+4,math.random(0,spd)*2-spd, math.random(0,spd)*2-spd,math.random(1,3),"expl",math.random(0,1),5)
else
table.remove(explosionAreas,_)
end
end
-- after all of this, we expand the enemy - bullet collision code
-- inside the enemy update
if collide(bul, enemy) then
local damage = 1
if bul.tpe == 1 then damage = 4 end
damage_enemy(enemy, damage)
-- explosive rounds
table.remove(bullets,_)
if upgrades[10] > 0 then
-- we have a set base radius that will increase with each explosion round
-- you picked during the run
local r = 20*(1+upgrades[10]/10)
add_explosion(enemy.x+4,enemy.y+4,r)
end
end
-- and finish it off with the explosive area check
for id,expl in ipairs(explosionAreas) do
-- since we are doing a few calculation i added
-- a stupid little fast path. This ensures if
-- the enemy is really far from the explosion
-- we don't even consider the possibility of
-- the damaging effect
if close_enough(enemy,expl,20) then
if collidec(expl,enemy) then
-- created a new helper function as well for
-- damage effects
damage_enemy(enemy,1)
end
end
end
-- with this we can call the damage effect from multiple checks
-- with this one helper, and check everything in one place
function damage_enemy(_enemy,_damage)
-- the inFrames is just added to the enemies
-- and if it grater then zero, we decrement it
-- each frame. This way you can't melt enemies with
-- aoe affects damaging them on each frame
-- (basicall every 30th of a second) which is stupid fast
if (_enemy.invFrames == 0) then
_enemy.hp = _enemy.hp - (_damage*(1+upgrades[7]/10))
_enemy.damaged = 90
_enemy.invFrames = 10
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment