You are not logged in.
Pages: 1
Don't remember seeing any GM script that can do that soo... here it is
/// draw_sprite_bent(vf, spr, img, x, y, around_x, around_y, bend_angle, segments, xscale, yscale, rot, color, alpha)
//
// returns nothing
//
// vf vertex format, get it with get_vf()
// spr sprite index, real
// img image index, real
// x draw it here, real
// y draw it here, real
// around_x bend the sprite around this x position, real
// around_y bend the sprite around this y position, real
// bend_angle apply angle, real
// segments the more segments, the better quality (but lower performance), real
// xscale scale on the x axis, real
// yscale scale on the y axis, real
// rot rotation of the final drawn texture (does not affect actual bending and around_x/y position), real
// color colour
// alpha alpha, real
//
// *note*
// create the "vf" variable in the Create event or create it once somewhere and make it global
// there is no need to keep recreating it every step
//
// the default number of segments is around 20 but more will be required for larger bend angles
//
// if the sprite is a png with alpha around DON'T FORGET TO TICK THE "Separate texture page" BUTTON
// otherwise it will mess the sprite up
//
/// GMLscripts.com/license
function draw_sprite_bent(vf, spr, img, x, y, around_x, around_y, bend_angle, segments, xscale, yscale, rot, color, alpha) {
var spr_w = sprite_get_width(spr);
var spr_h = sprite_get_height(spr);
var xoff = sprite_get_xoffset(spr) * xscale;
var yoff = sprite_get_yoffset(spr) * yscale;
var prec = max(2, round(segments));
var step = spr_h / prec;
var angle_step = bend_angle / prec;
// split the sprite into triangles with UVs
var uv = [];
var c_len = 0;
uv[c_len++] = [1, 0];
var on_right = false;
for(var h = 0; h < spr_h + step * 0.5; h += step) {
uv[c_len++] = [real(on_right), h/spr_h];
on_right = !on_right;
}
uv[c_len++] = [real(on_right), 1];
// rotate the triangles around pivot and save their coordinates
var counter = 0;
var angl = 0;
var coords = [];
c_len = 0;
for(var i = array_length(uv)-1; i > -1; i--) {
var u = uv[i][0];
var v = uv[i][1];
var pivot_x = (around_x - (x - xoff)) / xscale;
var pivot_y = (around_y - (y - yoff)) / yscale;
var pdr = point_direction(pivot_x, pivot_y, u * spr_w, v * spr_h);
var pds = point_distance(pivot_x, pivot_y, u * spr_w, v * spr_h);
var xx = pivot_x + lengthdir_x(pds, pdr + angl);
var yy = pivot_y + lengthdir_y(pds, pdr + angl);
coords[c_len++] = [xx * xscale, yy * yscale, (counter == 1), u, v];
if counter == 2 {
counter = 0;
if i == 0 break;
i += 2;
angl += angle_step;
}
else counter++;
}
// draw it
var b = vertex_create_buffer();
vertex_begin(b, vf);
for(var i = 0; i < array_length(coords); i++) {
if i == clamp(i, 2, array_length(coords)-3) {
var c_prev = coords[i-2];
var c_next = coords[i+2];
if c_prev[2] coords[i] = [ c_prev[0], c_prev[1], false, coords[i][3], coords[i][4] ];
if c_next[2] coords[i] = [ c_next[0], c_next[1], false, coords[i][3], coords[i][4] ];
}
var xx = coords[i][0] - xoff;
var yy = coords[i][1] - yoff;
if rot != 0 {
var pdr = point_direction(0, 0, xx, yy);
var pds = point_distance(0, 0, xx, yy);
xx = lengthdir_x(pds, pdr + rot);
yy = lengthdir_y(pds, pdr + rot);
}
vertex_position(b, x + xx, y + yy);
vertex_colour(b, color, alpha);
vertex_texcoord(b, coords[i][3], coords[i][4]);
}
vertex_end(b);
vertex_submit(b, pr_trianglelist, sprite_get_texture(spr, img));
}
function get_vf() {
vertex_format_begin();
vertex_format_add_position();
vertex_format_add_colour();
vertex_format_add_textcoord();
return vertex_format_end();
}
The green dot is around_x and around_y attached to the mouse cursor
Adjusting the bend_angle with mouse wheel
40 segments
Last edited by maras (2021-09-10 08:21:00)
I'm on the official GM discord > maras#5104
Offline
Pages: 1