/// @function shockwave_draw();
/// @description Draw the shockwave effect
// Check for the texture surface and create as required
if !surface_exists(wave_surf)
{
// No texture surface so create it
var _num = 0;
while (!surface_exists(wave_surf))
{
if wave_view != -1
{
// A view has been apecified so create the surface the size of it
var ww = camera_get_view_width(view_camera[wave_view]);
var hh = camera_get_view_height(view_camera[wave_view]);
wave_surf = surface_create(ww, hh);
}
else
{
// No view has been specified so create the surface the size of the room
wave_surf = surface_create(room_width, room_height);
}
// Check to make sure the surface was created and show an error if it repeatedly fails
if _num++ > 25
{
show_debug_message("Shockwave: Couldn't Create Effect Surface! Destroying Instance...");
instance_destroy();
exit; // Exit the draw event to prevent errors
}
}
// Set wave texture variables
wave_surf_t = surface_get_texture(wave_surf);
wave_surf_w = surface_get_width(wave_surf);
wave_surf_h = surface_get_height(wave_surf);
// show_debug_message("Shockwave: Effect Surface Created!");
// Copy the application surface to the texture surface
surface_set_target(wave_surf);
draw_surface_stretched(application_surface, 0, 0, wave_surf_w, wave_surf_h);
surface_reset_target();
}
else
{
// Texture surface exists, so update the shockwave effect if required
if wave_update
{
surface_set_target(wave_surf);
draw_surface_stretched(application_surface, 0, 0, wave_surf_w, wave_surf_h);
surface_reset_target();
}
// Check effect radius and continue or destroy as necessary
wave_radius += wave_speed;
if (wave_radius > wave_max_radius)
{
instance_destroy();
exit;
}
// Setup local vars for drawing the primitives that the effect uses
// Note that we pre-calculate as much as possible before running the
// main draw loop so that the loop has to do as little as possible.
var _xx, _yy, _cosx, _siny, _wave_dir;
var _wave_ang = 360 / wave_segment; // The angle size of each "segment" of the wave effect
var _wave_offset_inside = max(wave_radius - wave_width, 0); // Calculate the offset from the edge of the wave inwards
var _wave_offset_outside = wave_radius + wave_width; // Calculate the offset from the edge of the wave outwards
var _wave_multi = 0; // Prepare the "counter" variable that will increment as we create vertices
var _wave_tex_x = 1 / wave_surf_w; // Calculate the pixel ratio for the texture (value between 0 - 1) on the x axis
var _wave_tex_y = 1 / wave_surf_h; // Calculate the pixel ratio for the texture (value between 0 - 1) on the y axis
// Check for the view being active and if it is store its position
// We'll use this later when calculating the texture position.
if wave_view > -1
{
var _vx = camera_get_view_x(view_camera[wave_view]);
var _vy = camera_get_view_y(view_camera[wave_view]);
}
else
{
var _vx = 0;
var _vy = 0;
}
// Start drawing to the vertex buffer
vertex_begin(wave_vb_inside, wave_vf);
vertex_begin(wave_vb_outside, wave_vf);
// Run a loop to create each vertice of the primitive that will draw the shockwave
repeat (wave_segment + 1)
{
_wave_dir = _wave_multi * _wave_ang; // Get the current drawing angle
_cosx = dcos(_wave_dir); // Precaculate x component for position (this saves using lengthdir_x everywhere in the code)
_siny = -(dsin(_wave_dir)); // Precaculate y component for position (this saves using lengthdir_y everywhere in the code)
_xx = x + (_cosx * wave_radius); // Get the x position of the vertice for the radius of the wave
_yy = y + (_siny * wave_radius); // Get the y position of the vertice for the radius of the wave
// Add radius vertices for both outer and inner rings
vertex_position(wave_vb_outside, _xx, _yy);
vertex_position(wave_vb_inside, _xx, _yy);
_xx = _xx - _vx + (_cosx * -wave_push); // Get the x texture position
_yy = _yy - _vy + (_siny * -wave_push); // Get the y texture position
// Add texture coordinates to the vertices
vertex_texcoord(wave_vb_outside, _wave_tex_x * _xx , _wave_tex_y * _yy);
vertex_texcoord(wave_vb_inside, _wave_tex_x * _xx, _wave_tex_y * _yy);
// Add colour data to the vertices
vertex_colour(wave_vb_outside, wave_blend, image_alpha);
vertex_colour(wave_vb_inside, wave_blend, image_alpha);
// Draw the outer vertices (same as above but using the offset value to offset it outwards from the wave radius)
_xx = x + (_cosx * _wave_offset_outside);
_yy = y + (_siny * _wave_offset_outside);
vertex_position(wave_vb_outside, _xx, _yy);
vertex_texcoord(wave_vb_outside, _wave_tex_x * (_xx - _vx) , _wave_tex_y * (_yy - _vy));
vertex_colour(wave_vb_outside, wave_blend, 0);
// Draw the inner vertices (same as above but using the offset value to offset it inwards from the wave radius)
_xx = x + (_cosx * _wave_offset_inside);
_yy = y + (_siny * _wave_offset_inside);
vertex_position(wave_vb_inside, _xx, _yy);
vertex_texcoord(wave_vb_inside, _wave_tex_x * (_xx - _vx) , _wave_tex_y * (_yy - _vy));
vertex_colour(wave_vb_inside, wave_blend, 0);
++_wave_multi;
}
// End the defining of the vertex buffers
vertex_end(wave_vb_inside);
vertex_end(wave_vb_outside);
// Check for additive blending (this can be removed if you never use additive blending)
if wave_additive
{
gpu_set_blendmode(bm_add);
}
// Draw the primitives in the buffers
vertex_submit(wave_vb_inside, pr_trianglestrip, wave_surf_t);
vertex_submit(wave_vb_outside, pr_trianglestrip, wave_surf_t);
// Reset additive if enabled (this can be removed if you never use additive blending)
if wave_additive
{
gpu_set_blendmode(bm_normal);
}
// Set total alpha (the wave will fade as it gets bigger)
image_alpha -= wave_alpha;
}
Comments