I made a Zora enemy recently, who shoots three aligned fireballs.
It is essentially the same as ALTTP, except that the fireballs bounce when the hero hits them with the sword (but this feature can easily be removed if you want the real ALTTP behavior).
enemies/zora_water.lua:
-- A water enemy who shoots fireballs.
local enemy = ...
local sprite
function enemy:on_created()
enemy:set_life(1)
enemy:set_damage(2)
enemy:set_obstacle_behavior("swimming")
enemy:set_pushed_back_when_hurt(false)
enemy:set_size(16, 16)
enemy:set_origin(8, 13)
sprite = enemy:create_sprite("enemies/" .. enemy:get_breed())
function sprite:on_animation_finished(animation)
if animation == "shooting" then
sprite:set_animation("walking")
end
end
end
function enemy:on_restarted()
local sprite = enemy:get_sprite()
local hero = enemy:get_map():get_hero()
sol.timer.start(enemy, 3000, function()
if enemy:get_distance(hero) < 300 then
sol.audio.play_sound("zora")
sprite:set_animation("shooting")
enemy:create_enemy({
breed = "fireball_red_small",
})
end
return true -- Repeat the timer.
end)
end
enemies/fireball_red_small.lua
-- 3 fireballs shot by enemies like Zora and that go toward the hero.
-- They can be hit with the sword, this changes their direction.
local enemy = ...
local sprites = {}
function enemy:on_created()
enemy:set_life(1)
enemy:set_damage(1)
enemy:set_minimum_shield_needed(2) -- Shield 2 can block fireballs.
enemy:set_size(8, 8)
enemy:set_origin(4, 4)
enemy:set_can_hurt_hero_running(true)
enemy:set_obstacle_behavior("flying")
enemy:set_invincible()
enemy:set_attack_consequence("sword", "custom")
for i = 0, 2 do
sprites[#sprites + 1] = enemy:create_sprite("enemies/" .. enemy:get_breed())
end
end
local function go(angle)
local movement = sol.movement.create("straight")
movement:set_speed(192)
movement:set_angle(angle)
movement:set_smooth(false)
function movement:on_obstacle_reached()
enemy:remove()
end
-- Compute the coordinate offset of follower sprites.
local x = -math.cos(angle) * 10
local y = math.sin(angle) * 10
sprites[2]:set_xy(x, y)
sprites[3]:set_xy(2 * x, 2 * y)
sprites[2]:set_animation("following_1")
sprites[3]:set_animation("following_2")
movement:start(enemy)
end
function enemy:on_restarted()
local hero = enemy:get_map():get_hero()
local angle = enemy:get_angle(hero:get_center_position())
go(angle)
end
-- Destroy the fireball when the hero is touched.
function enemy:on_attacking_hero(hero, enemy_sprite)
hero:start_hurt(enemy, enemy_sprite, enemy:get_damage())
enemy:remove()
end
-- Change the direction of the movement when hit with the sword.
function enemy:on_custom_attack_received(attack, sprite)
if attack == "sword" and sprite == sprites[1] then
local hero = enemy:get_map():get_hero()
local movement = enemy:get_movement()
if movement == nil then
return
end
local old_angle = movement:get_angle()
local angle
local hero_direction = hero:get_direction()
if hero_direction == 0 or hero_direction == 2 then
angle = math.pi - old_angle
else
angle = 2 * math.pi - old_angle
end
go(angle)
sol.audio.play_sound("enemy_hurt")
-- The trailing fireballs are now on the hero: don't attack temporarily
enemy:set_can_attack(false)
sol.timer.start(enemy, 500, function()
enemy:set_can_attack(true)
end)
end
end
Sprites are attached.
Hi Chris!
I finally finished my scripts for the beam, which may also be useful. I made 3 different types of beams (with lots of parameters that can be customized):
-Curved beam (actually not a beam). It throws each time a particle towards the position of the hero. It can make a pause after certain number of particles are thrown.
-Straight beam. This always makes a pause after a certain number of particles is thrown. Each time this throws particles, these are thrown aligned, towards the direction where the hero was.
-Moving beam. This one is a bit different. This is a continuous straight beam (it does not pause, and all particles are aligned in the same straight line). The straight line points towards a moving target, which moves towards the hero at certain speed (when the line has changed the direction, which happens when the target moves, the particles' position is changed so that they still form a line).
The three scripts work using another script called beam_particle.lua, which creates the beam particles.
Again, I put the link to my repository.
https://github.com/Diarandor