Script Information :
- Fog Effect : Display and move a surface, creating a fog moving effect.
This script is heavily inspired by the Day/Night / Fog effect tuto made by Christopho (most of the code is from the tutorial.), but this is more generalized since it use metatable (so it avoid copies over maps script.).
How it works ?
- place the script in quest_manager (or other file that regroup all metatable)
- copy/paste the script in a function that hold the map metatable.
- Place your fogs png in /sprites/fogs
- The fog surface should be higher or equal to 320x240 (or else it would do strange thing where you will need to duplicate the fog, which will result in higher map loading time and framerate issue)
- In your map script, in on_started(), add
where :
filename must be a string pointing to an existing file in /sprites/fog
speed a number (0 = immobile, higher value = faster)
angle a number between 0 and 7 (0 = right, 7 = south-east
opacity a number between 0 and 255 (0 = transparent, 255 = opaque)
- A savegame value that check if there is any fog graphic. If yes, it is drawn.
Problems :
- If you use map:on_draw(surface) in your map script, the function in the metatable is overwritten, but, this script is temporary before solarus allows shader
What's next :
- add a parameter that analyse the size of the map, if higher then 320x240, automatically multiply the surface to fit the map.
- add a boolean, if true, the fog will slightly follow the camera movement
- fade in/fade out with user custom timer. (Useful for sunrays-like fog)
This is an example of what you can do.
- Fog Effect : Display and move a surface, creating a fog moving effect.
This script is heavily inspired by the Day/Night / Fog effect tuto made by Christopho (most of the code is from the tutorial.), but this is more generalized since it use metatable (so it avoid copies over maps script.).
How it works ?
- place the script in quest_manager (or other file that regroup all metatable)
- copy/paste the script in a function that hold the map metatable.
- Place your fogs png in /sprites/fogs
- The fog surface should be higher or equal to 320x240 (or else it would do strange thing where you will need to duplicate the fog, which will result in higher map loading time and framerate issue)
- In your map script, in on_started(), add
Code (lua) Select
function map:on_started(destination)
map:display_fog("filename", speed, angle, opacity)
end
where :
filename must be a string pointing to an existing file in /sprites/fog
speed a number (0 = immobile, higher value = faster)
angle a number between 0 and 7 (0 = right, 7 = south-east
opacity a number between 0 and 255 (0 = transparent, 255 = opaque)
- A savegame value that check if there is any fog graphic. If yes, it is drawn.
Problems :
- If you use map:on_draw(surface) in your map script, the function in the metatable is overwritten, but, this script is temporary before solarus allows shader
What's next :
- add a parameter that analyse the size of the map, if higher then 320x240, automatically multiply the surface to fit the map.
- add a boolean, if true, the fog will slightly follow the camera movement
- fade in/fade out with user custom timer. (Useful for sunrays-like fog)
Code (lua) Select
function map_metatable:display_fog(fog, speed, angle, opacity)
local fog = fog or nil
local speed = speed or 1
local angle = angle or 0
local opacity = opacity or 16
if type(fog) == "string" then
self.fog = sol.surface.create("fogs/"..fog..".png")
self.fog:set_opacity(opacity)
self.fog_size_x, self.fog_size_y = self.fog:get_size()
self.fog_m = sol.movement.create("straight")
function restart_overlay_movement()
self.fog_m:set_speed(speed)
self.fog_m:set_max_distance(self.fog_size_x)
self.fog_m:set_angle(angle * math.pi / 4)
self.fog_m:start(self.fog, function()
restart_overlay_movement()
self.fog:set_xy(0,0)
end)
end
restart_overlay_movement()
self:get_game():set_value("current_fog", fog)
end
end
function map_metatable:get_current_fog()
return self:get_game():get_value("current_fog")
end
function map_metatable:on_draw(dst_surface)
local scr_x, scr_y = dst_surface:get_size()
if self:get_current_fog() ~= nil then
local camera_x, camera_y = self:get_camera_position()
local overlay_width, overlay_height = self.fog:get_size()
local x, y = camera_x, camera_y
x, y = -math.floor(x), -math.floor(y)
x = x % overlay_width - 4 * overlay_width
y = y % overlay_height - 4 * overlay_height
local dst_y = y
while dst_y < scr_y + overlay_height do
local dst_x = x
while dst_x < scr_x + overlay_width do
self.fog:draw(dst_surface, dst_x, dst_y)
dst_x = dst_x + overlay_width
end
dst_y = dst_y + overlay_height
end
end
end
function map_metatable:on_finished()
self:get_game():set_value("current_fog", nil)
end
This is an example of what you can do.