master
a327ex 2021-02-21 23:54:50 -03:00
parent 9d3f777342
commit 2ff3cb9445
41 changed files with 318 additions and 55 deletions

View File

@ -13,6 +13,7 @@ function Arena:on_enter(from, level)
self.level = level or 1
self.main = Group():set_as_physics_world(32, 0, 0, {'player', 'enemy', 'projectile', 'enemy_projectile'})
self.post_main = Group()
self.effects = Group()
self.ui = Group():no_camera()
self.main:disable_collision_between('player', 'player')
@ -44,16 +45,17 @@ function Arena:on_enter(from, level)
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x2, -40, gw + 40, gh + 40), color = bg[-1]}
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]}
Wall{group = self.main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(-40, -40, self.x1, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x2, -40, gw + 40, gh + 40), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, -40, self.x2, self.y1), color = bg[-1]}
WallCover{group = self.post_main, vertices = math.to_rectangle_vertices(self.x1, self.y2, self.x2, gh + 40), color = bg[-1]}
self.player = Player{group = self.main, x = gw/2, y = gh/2, leader = true, character = 'scout'}
--self.player:add_follower(Player{group = self.main, character = 'scout'})
--[[
self.player = Player{group = self.main, x = gw/2, y = gh/2, leader = true, character = 'swordsman'}
self.player:add_follower(Player{group = self.main, character = 'archer'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
self.player:add_follower(Player{group = self.main, character = 'vagrant'})
]]--
self.player:add_follower(Player{group = self.main, character = 'cleric'})
self.player:add_follower(Player{group = self.main, character = 'scout'})
self.player:add_follower(Player{group = self.main, character = 'wizard'})
self.win_condition = random:table{'time', 'enemy_kill', 'wave'}
if self.win_condition == 'wave' then
@ -68,9 +70,11 @@ function Arena:on_enter(from, level)
self.start_time = 3
self.t:after(1, function()
self.t:every(1, function()
if self.start_time > 1 then alert1:play{volume = 0.5} end
self.start_time = self.start_time - 1
self.hfx:use('condition1', 0.25, 200, 10)
end, 3, function()
alert1:play{pitch = 1.2, volume = 0.5}
camera:shake(4, 0.25)
SpawnEffect{group = self.effects, x = gw/2, y = gh/2 - 48}
self.wave = 0
@ -101,9 +105,11 @@ function Arena:on_enter(from, level)
self.start_time = 3
self.t:after(1, function()
self.t:every(1, function()
if self.start_time > 1 then alert1:play{volume = 0.5} end
self.start_time = self.start_time - 1
self.hfx:use('condition1', 0.25, 200, 10)
end, 3, function()
alert1:play{pitch = 1.2, volume = 0.5}
camera:shake(4, 0.25)
SpawnEffect{group = self.effects, x = gw/2, y = gh/2 - 48}
self:spawn_distributed_enemies()
@ -127,9 +133,11 @@ function Arena:on_enter(from, level)
self.start_time = 3
self.t:after(1, function()
self.t:every(1, function()
if self.start_time > 1 then alert1:play{volume = 0.5} end
self.start_time = self.start_time - 1
self.hfx:use('condition1', 0.25, 200, 10)
end, 3, function()
alert1:play{pitch = 1.2, volume = 0.5}
camera:shake(4, 0.25)
SpawnEffect{group = self.effects, x = gw/2, y = gh/2 - 48}
self.t:every(1, function()
@ -152,6 +160,7 @@ end
function Arena:update(dt)
self:update_game_object(dt*slow_amount)
self.main:update(dt*slow_amount)
self.post_main:update(dt*slow_amount)
self.effects:update(dt*slow_amount)
self.ui:update(dt*slow_amount)
@ -179,6 +188,7 @@ end
function Arena:draw()
self.main:draw()
self.post_main:draw()
self.effects:draw()
self.ui:draw()
@ -279,6 +289,7 @@ function Arena:spawn_n_enemies(p, j, n)
self.t:every(0.1, function()
local o = self.spawn_offsets[(self.t:get_every_iteration('spawn_enemies_' .. j) % 5) + 1]
SpawnEffect{group = self.effects, x = p.x + o.x, y = p.y + o.y, action = function(x, y)
spawn1:play{pitch = random:float(0.8, 1.2), volume = 0.15}
if self.level == 1 then
Seeker{group = self.main, x = x, y = y, character = 'seeker'}
elseif self.level == 2 then

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -90,3 +90,10 @@ The classes are:
I'm not sure what I should focus on next. I know that there's sounds left to add, but after that I should probably start doing the actual game progression, but for that I think need a bunch more characters.
I should probably try to think of a cast of maybe 15-20 characters (however that number should be as low as possible) that fills up the current classes to their multiple levels. Levels possible are: 1, 2, 3, 2/4, 2/4/6 and 3/6.
# Day 5 - 21/02/21
Sounds done for everything. Surprising to me how much sounds added to the game and helped me sell all the different attacks way better than with just graphics.
I should probably make it a habit to add sounds earlier rather than later from now on.
Tomorrow I should probably ideaguy the full set of characters and classes that I'll need so that the game is playable and start on implementing those additional characters as well as some class bonuses.

View File

@ -59,11 +59,29 @@ function Seeker:on_collision_enter(other, contact)
other:push(random:float(10, 15), other:angle_to_object(self))
HitCircle{group = main.current.effects, x = x, y = y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = x, y = y, color = self.color} end
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end
end
end
function Seeker:hit(damage)
if self.dead then return end
self.hfx:use('hit', 0.25, 200, 10)
self:show_hp()
local actual_damage = self:calculate_damage(damage)
self.hp = self.hp - actual_damage
if self.hp <= 0 then
self.dead = true
for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
main.current:enemy_killed()
_G[random:table{'enemy_die1', 'enemy_die2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.5}
end
end
function Seeker:push(f, r)
self.being_pushed = true
self.steering_enabled = false

View File

@ -167,6 +167,7 @@ end
function Group:add(object)
local class = getmetatable(object)
object.group = self
if not object.id then object.id = random:uid() end
self.objects.by_id[object.id] = object
if not self.objects.by_class[class] then self.objects.by_class[class] = {} end

View File

@ -14,6 +14,34 @@ function init()
input:bind('move_up', {'w', 'up'})
input:bind('move_down', {'s', 'down'})
sfx_tag = {tags = {sfx}}
shoot1 = Sound('Shooting Projectile (Classic) 11.ogg', s)
archer1 = Sound('Releasing Bow String 1.ogg', s)
wizard1 = Sound('Wind Bolt 20.ogg', s)
swordsman1 = Sound('Heavy sword woosh 1.ogg', s)
swordsman2 = Sound('Heavy sword woosh 19.ogg', s)
scout1 = Sound('Throwing Knife (Thrown) 3.ogg', s)
scout2 = Sound('Throwing Knife (Thrown) 4.ogg', s)
arrow_hit_wall1 = Sound('Arrow Impact wood 3.ogg', s)
arrow_hit_wall2 = Sound('Arrow Impact wood 1.ogg', s)
hit1 = Sound('Player Takes Damage 17.ogg', s)
hit2 = Sound('Body Head (Headshot) 1.ogg', s)
hit3 = Sound('Kick 16.ogg', s)
proj_hit_wall1 = Sound('Player Takes Damage 2.ogg', s)
enemy_die1 = Sound('Bloody punches 7.ogg', s)
enemy_die2 = Sound('Bloody punches 10.ogg', s)
magic_area1 = Sound('Fire bolt 10.ogg', s)
magic_hit1 = Sound('Shadow Punch 1.ogg', s)
magic_die1 = Sound('Magical Impact 27.ogg', s)
knife_hit_wall1 = Sound('Shield Impacts Sword 1.ogg', s)
player_hit1 = Sound('Body Fall 2.ogg', s)
player_hit2 = Sound('Body Fall 18.ogg', s)
player_hit_wall1 = Sound('Wood Heavy 5.ogg', s)
pop1 = Sound('Pop sounds 10.ogg', s)
heal1 = Sound('Buff 3.ogg', s)
spawn1 = Sound('Buff 13.ogg', s)
alert1 = Sound('Alert sounds 3.ogg', s)
main = Main()
main:add(Arena'arena')
main:go_to'arena'

View File

@ -1,8 +1,73 @@
WallKnife = Object:extend()
WallKnife:implement(GameObject)
WallKnife:implement(Physics)
function WallKnife:init(args)
self:init_game_object(args)
self:set_as_rectangle(10, 4, 'dynamic', 'projectile')
self.hfx:add('hit', 1)
self.hfx:use('hit', 0.25)
self.t:tween({0.8, 1.6}, self, {v = 0}, math.linear, function()
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end)
end)
self.vr = self.r
self.dvr = random:table{random:float(-8*math.pi, -4*math.pi), random:float(4*math.pi, 8*math.pi)}
end
function WallKnife:update(dt)
self:update_game_object(dt)
self:set_angle(self.r)
self:move_along_angle(self.v, self.r)
self.vr = self.vr + self.dvr*dt
end
function WallKnife:draw()
if self.hidden then return end
graphics.push(self.x, self.y, self.vr, self.hfx.hit.x, self.hfx.hit.x)
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
end
WallArrow = Object:extend()
WallArrow:implement(GameObject)
function WallArrow:init(args)
self:init_game_object(args)
self.shape = Rectangle(self.x, self.y, 10, 4)
self.hfx:add('hit', 1)
self.hfx:use('hit', 0.25)
self.t:after({0.8, 2}, function()
self.t:every_immediate(0.05, function() self.hidden = not self.hidden end, 7, function() self.dead = true end)
end)
end
function WallArrow:update(dt)
self:update_game_object(dt)
end
function WallArrow:draw()
if self.hidden then return end
graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x)
graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color)
graphics.pop()
end
Unit = Object:extend()
function Unit:init_unit()
self.hfx:add('hit', 1)
self.hfx:add('shoot', 1)
self.hp_bar = HPBar{group = main.current.effects, parent = self}
self.heal_bar = HealBar{group = main.current.effects, parent = self}
end
@ -16,6 +81,7 @@ function Unit:bounce(nx, ny)
self:set_velocity(-vx, vy)
self.r = math.pi - self.r
end
return self.r
end
@ -25,32 +91,9 @@ function Unit:show_hp(n)
end
function Unit:hit(damage)
if self.dead then return end
self.hfx:use('hit', 0.25, 200, 10)
self:show_hp()
local actual_damage = self:calculate_damage(damage)
self.hp = self.hp - actual_damage
if self:is(Player) then
if actual_damage >= 20 then
camera:shake(2, 1)
slow(0.25, 1)
else
camera:shake(2, 0.5)
end
end
if self.hp <= 0 then
self.dead = true
for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
if table.any(main.current.enemies, function(v) return self:is(v) end) then
main.current:enemy_killed()
end
end
function Unit:show_heal(n)
self.heal_bar.hidden = false
self.t:after(n or 4, function() self.heal_bar.hidden = true end, 'heal_bar')
end
@ -155,6 +198,35 @@ end
HealBar = Object:extend()
HealBar:implement(GameObject)
HealBar:implement(Parent)
function HealBar:init(args)
self:init_game_object(args)
self.hidden = true
self.color = green[0]
self.color_transparent = Color(self.color.r, self.color.g, self.color.b, 0.2)
end
function HealBar:update(dt)
self:update_game_object(dt)
self:follow_parent_exclusively()
end
function HealBar:draw()
if self.hidden then return end
local p = self.parent
graphics.push(p.x, p.y, 0, p.hfx.hit.x, p.hfx.hit.x)
graphics.rectangle(p.x, p.y, 1.25*p.shape.w, 1.25*p.shape.h, 2, 2, self.color_transparent)
graphics.rectangle(p.x, p.y, 1.25*p.shape.w, 1.25*p.shape.h, 2, 2, self.color, 1)
graphics.pop()
end
HPBar = Object:extend()
HPBar:implement(GameObject)
HPBar:implement(Parent)

View File

@ -30,7 +30,7 @@ function Player:init(args)
self.t:every(3, function()
local enemies = self:get_objects_in_shape(self.attack_sensor, main.current.enemies)
if enemies and #enemies > 0 then
self:attack()
self:attack(96)
end
end, nil, nil, 'attack')
@ -40,7 +40,7 @@ function Player:init(args)
self.visual_shape = 'rectangle'
self.classes = {'mage'}
self.attack_sensor = Circle(self.x, self.y, 64)
self.attack_sensor = Circle(self.x, self.y, 128)
self.t:every(2, function()
local closest_enemy = self:get_closest_object_in_shape(self.attack_sensor, main.current.enemies)
if closest_enemy then
@ -75,6 +75,25 @@ function Player:init(args)
self:shoot(self:angle_to_object(closest_enemy), {chain = 3})
end
end, nil, nil, 'shoot')
elseif self.character == 'cleric' then
self.color = green[0]
self:set_as_rectangle(9, 9, 'dynamic', 'player')
self.visual_shape = 'rectangle'
self.classes = {'healer'}
self.last_heal_time = love.timer.getTime()
self.t:every(2, function()
local followers
local leader = (self.leader and self) or self.parent
if self.leader then followers = self.followers else followers = self.parent.followers end
if (table.any(followers, function(v) return v.hp <= 0.5*v.max_hp end) or (leader.hp <= 0.5*leader.max_hp)) and love.timer.getTime() - self.last_heal_time > 6 then
self.last_heal_time = love.timer.getTime()
if self.leader then self:heal(0.1*self.max_hp) else self.parent:heal(0.1*self.parent.max_hp) end
for _, f in ipairs(followers) do f:heal(0.1*f.max_hp) end
heal1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end)
end
self:calculate_stats(true)
@ -93,9 +112,7 @@ function Player:update(dt)
self:update_game_object(dt)
self:calculate_stats()
if self.character == 'archer' then print(self.aspd_m) end
self.attack_sensor:move_to(self.x, self.y)
if self.attack_sensor then self.attack_sensor:move_to(self.x, self.y) end
self.t:set_every_multiplier('shoot', self.aspd_m)
self.t:set_every_multiplier('attack', self.aspd_m)
@ -136,6 +153,7 @@ function Player:update(dt)
self:set_position(p.x, p.y)
self.r = p.r
if not self.following then
spawn1:play{pitch = random:float(0.8, 1.2), volume = 0.15}
for i = 1, random:int(3, 4) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 10, color = fg[0]}:scale_down(0.3):change_color(0.5, self.color)
self.following = true
@ -161,9 +179,22 @@ function Player:on_collision_enter(other, contact)
local x, y = contact:getPositions()
if other:is(Wall) then
self.hfx:use('hit', 0.5, 200, 10, 0.1)
camera:spring_shake(2, math.pi - self.r)
self:bounce(contact:getNormal())
if self.leader then
self.hfx:use('hit', 0.5, 200, 10, 0.1)
camera:spring_shake(2, math.pi - self.r)
self:bounce(contact:getNormal())
local r = random:float(0.9, 1.1)
player_hit_wall1:play{pitch = r, volume = 0.1}
pop1:play{pitch = r, volume = 0.2}
for i, f in ipairs(self.followers) do
trigger:after(i*0.002*self.v, function()
f.hfx:use('hit', 0.5, 200, 10, 0.1)
player_hit_wall1:play{pitch = r + 0.025*i, volume = 0.1}
pop1:play{pitch = r + 0.05*i, volume = 0.2}
end)
end
end
elseif table.any(main.current.enemies, function(v) return other:is(v) end) then
other:push(random:float(25, 35), self:angle_to_object(other))
@ -176,6 +207,36 @@ function Player:on_collision_enter(other, contact)
end
function Player:hit(damage)
if self.dead then return end
self.hfx:use('hit', 0.25, 200, 10)
self:show_hp()
local actual_damage = self:calculate_damage(damage)
self.hp = self.hp - actual_damage
_G[random:table{'player_hit1', 'player_hit2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
camera:shake(4, 0.5)
if self.hp <= 0 then
slow(0.25, 1)
self.dead = true
for i = 1, random:int(4, 6) do HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color} end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 12}:scale_down(0.3):change_color(0.5, self.color)
end
end
function Player:heal(amount)
local hp = self.hp
self.hfx:use('hit', 0.25, 200, 10)
self:show_hp(1.5)
self:show_heal(1.5)
self.hp = self.hp + amount
if self.hp > self.max_hp then self.hp = self.max_hp end
end
function Player:add_follower(unit)
table.insert(self.followers, unit)
unit.parent = self
@ -187,16 +248,30 @@ function Player:shoot(r, mods)
camera:spring_shake(2, r)
self.hfx:use('shoot', 0.25)
HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r), y = self.y + 0.8*self.shape.w*math.sin(r), rs = 6}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg}
local t = {group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), v = 250, r = r, color = self.color, dmg = self.dmg, character = self.character}
Projectile(table.merge(t, mods or {}))
if self.character == 'vagrant' then
shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.3}
elseif self.character == 'archer' then
archer1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
elseif self.character == 'wizard' then
wizard1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
elseif self.character == 'scout' then
_G[random:table{'scout1', 'scout2'}]:play{pitch = random:float(0.95, 1.05), volume = 0.5}
end
end
function Player:attack(mods)
function Player:attack(area, mods)
camera:shake(2, 0.5)
self.hfx:use('shoot', 0.25)
local t = {group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.area_size_m*64, color = self.color, dmg = self.area_dmg_m*self.dmg}
local t = {group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.area_size_m*(area or 64), color = self.color, dmg = self.area_dmg_m*self.dmg, character = self.character}
Area(table.merge(t, mods or {}))
if self.character == 'swordsman' then
_G[random:table{'swordsman1', 'swordsman2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.75}
end
end
@ -238,8 +313,8 @@ function Projectile:die(x, y, r, n)
HitCircle{group = main.current.effects, x = x, y = y}:scale_down()
self.dead = true
if self.wizard then
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.wizard.area_size_m*32, color = self.color, dmg = self.wizard.area_dmg_m*self.dmg}
if self.character == 'wizard' then
Area{group = main.current.effects, x = self.x, y = self.y, r = self.r, w = self.wizard.area_size_m*32, color = self.color, dmg = self.wizard.area_dmg_m*self.dmg, character = self.character}
end
end
@ -254,7 +329,24 @@ function Projectile:on_collision_enter(other, contact)
else r = 0 end
if other:is(Wall) then
self:die(x, y, r, random:int(2, 3))
if self.character == 'archer' then
self:die(x, y, r, 0)
_G[random:table{'arrow_hit_wall1', 'arrow_hit_wall2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.2}
WallArrow{group = main.current.main, x = x, y = y, r = self.r, color = self.color}
elseif self.character == 'scout' then
self:die(x, y, r, 0)
knife_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
local r = Unit.bounce(self, nx, ny)
trigger:after(0.01, function()
WallKnife{group = main.current.main, x = x, y = y, r = r, v = self.v*0.1, color = self.color}
end)
elseif self.character == 'wizard' then
self:die(x, y, r, random:int(2, 3))
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.075}
else
self:die(x, y, r, random:int(2, 3))
proj_hit_wall1:play{pitch = random:float(0.9, 1.1), volume = 0.2}
end
end
end
@ -274,11 +366,19 @@ function Projectile:on_trigger_enter(other, contact)
if object then
self.r = self:angle_to_object(object)
self.v = self.v*1.25
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color}
HitParticle{group = main.current.effects, x = self.x, y = self.y, color = other.color}
end
end
HitCircle{group = main.current.effects, x = self.x, y = self.y, rs = 6, color = fg[0], duration = 0.1}
HitParticle{group = main.current.effects, x = self.x, y = self.y, color = self.color}
HitParticle{group = main.current.effects, x = self.x, y = self.y, color = other.color}
end
if self.character == 'archer' or self.character == 'scout' then
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
elseif self.character == 'wizard' then
magic_area1:play{pitch = random:float(0.95, 1.05), volume = 0.15}
else
hit3:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end
other:hit(self.dmg)
end
@ -298,6 +398,11 @@ function Area:init(args)
HitCircle{group = main.current.effects, x = enemy.x, y = enemy.y, rs = 6, color = fg[0], duration = 0.1}
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = self.color} end
for i = 1, 2 do HitParticle{group = main.current.effects, x = enemy.x, y = enemy.y, color = enemy.color} end
if self.character == 'wizard' then
magic_hit1:play{pitch = random:float(0.95, 1.05), volume = 0.5}
elseif self.character == 'swordsman' then
hit2:play{pitch = random:float(0.95, 1.05), volume = 0.35}
end
end
self.color = fg[0]

View File

@ -7,7 +7,6 @@ function shared_init()
fg_alt = ColorRamp(Color'#b0a89f', 0.025),
yellow = ColorRamp(Color'#facf00', 0.025),
orange = ColorRamp(Color'#f07021', 0.025),
yellow_orange = ColorRamp(Color(245, 160, 16), 0.025),
blue = ColorRamp(Color'#019bd6', 0.025),
green = ColorRamp(Color'#8bbf40', 0.025),
red = ColorRamp(Color'#e91d39', 0.025),
@ -663,3 +662,24 @@ end
function Wall:draw()
self.shape:draw(self.color)
end
WallCover = Object:extend()
WallCover:implement(GameObject)
function WallCover:init(args)
self:init_game_object(args)
self.shape = Polygon(self.vertices)
self.color = self.color or fg[0]
end
function WallCover:update(dt)
self:update_game_object(dt)
end
function WallCover:draw()
self.shape:draw(self.color)
end

7
todo
View File

@ -1,9 +1,10 @@
Vagrant: shoots an ethereal projectile at any nearby enemy that deals physical and magical damage, medium range
Scout: throws a knife that chains 3 times at any nearby enemy, small range
Cleric: heals every unit when any one drops below 50% HP
Swordsman: deals physical damage in an area around the unit, small range
Swordsman: deals physical damage in a medium area around the unit, small range
Archer: shoots an arrow that pierces at any nearby enemy, very long range
Wizard: shoots a projectile at any nearby enemy and deals AoE magical damage on contact, small range, AoE has very small range
Wizard: shoots a projectile at any nearby enemy and deals AoE magical damage on contact, long range, AoE has very small range
Engineer: drops a turret that shoots secondary projectiles very fast, medium range
Ranger: yellow, buff attack speed
@ -27,4 +28,4 @@ Defense -> if defense >= 0 then dmg_m = 100/(100+defense) else dmg_m = 2-100/(10
* Stats: attack speed, damage, area
* One or a few of the characters
* Port over enemy spawn logic from SHOOTRX
Sounds
* Sounds