• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Changing the origin of a sprite drawn with draw_sprite_part_ext?

S

Shameful

Guest
Hi, I've been using draw_sprite_part_ext to pull sprites off of a sprite sheet for a costume changing aspect of my game. As you know draw_sprite_part_ext places the origin of the drawn sprite part in the upper left hand corner at 0,0. This hadn't been an issue for me until I began trying to add some flare by manipulating the xscale and yscale of these sprites for jiggly effects. Because of the fixed 0,0 origin, everything just gets bunched up in the upper left hand corner.
current and desired origins.png
Is there any way to change the origin of these sprite parts to bottom center, rather than upper left? Any help would be appreciated, Thanks in advance.
 

Fern

Member
You can use this dandy script I made to draw it from the preferred offset.

Code:
/// @arg sprite,subimg,x,y,xscale,yscale,rot,color,alpha,origin_x,origin_y
 
var
_x_offset = (sprite_get_xoffset(argument0) - argument9) * argument4,
_y_offset = (sprite_get_yoffset(argument0) - argument10) * argument5;
 
draw_sprite_ext(
    argument0,
    argument1,
    (argument2 - 1) + lengthdir_x(_x_offset,argument6) + lengthdir_x(_y_offset,argument6 - 90),
    (argument3 - 1) + lengthdir_y(_x_offset,argument6) + lengthdir_y(_y_offset,argument6 - 90),
    argument4,
    argument5,
    argument6,
    argument7,
    argument8
);
 
S

Shameful

Guest
I fiddled with your script for a while, but alas I cannot get it to work with draw_sprite_part. I might not being doing it correctly though.
I put your code in a script and plugged in the sprite sheet, and it drew the whole sprite sheet.
Code:
(offset_fixer being what I named your script)
ba = spritesheet

offset_fixer(ba, image_index, x, y + (21 - 21 * yscale) * 0.25, facing * xscale, yscale, image_angle,c_white, image_alpha, 21, -41);
Then I tried plugging the draw_sprite_ext into the spite slot, and while it drew the part of the sprite sheet I wanted, it was unable to change the origin of the sprite part. Oddly enough, it too drew the entire sprite sheet, at the origin I wanted, and it had the x and y scale squish and squash properties I was going for, but the piece I had specifically selected was entirely unaffected by x and y scale adjustment.
Screenshot_2.png
Code:
ba = sprite sheet
bx = x corner of a specific quadrant on the sprite sheet
by = y corner of a specific quadrant on the sprite sheet
42 = width and height of said quadrant

offset_fixer(draw_sprite_part(ba, image_index, bx, by, 42, 42, x, y),image_index, thisobj.x, thisobj.y + (21 - 21 * yscale) * 0.25, facing * xscale, yscale, image_angle,c_white, image_alpha, 21, 40);
Then I modified your script to accept draw_sprite_part_ext instead of draw_sprite_ext, but that only yielded a blank screen.

Code:
/// @description  offset_fixer(sprite, subimg, left, top, width, height, x, y, xscale, yscale, color, alpha, origin_x, origin_y);
/// @param      sprite
/// @param     subimg
/// @param        left
/// @param         top
/// @param      width
/// @param     height
/// @param           x
/// @param           y
/// @param      xscale
/// @param      yscale
/// @param      color
/// @param      alpha
/// @param   origin_x
/// @param   origin_y

var
_x_offset = (sprite_get_xoffset(argument0) - argument12) * argument8,
_y_offset = (sprite_get_yoffset(argument0) - argument13) * argument9,
_rot     = image_angle;

draw_sprite_part_ext(
    argument0,
    argument1,
   argument2,
   argument3,
   argument4,
   argument5,
    (argument6 - 1) + lengthdir_x(_x_offset,_rot) + lengthdir_x(_y_offset,_rot - 90),
    (argument7 - 1) + lengthdir_y(_x_offset,_rot) + lengthdir_y(_y_offset,_rot - 90),
    argument8,
    argument9,
    argument10,
    argument11
);
/////////////////////////////////////////////////
offset_fixer1(ba,image_index, bx, by, 42, 42, thisobj.x, thisobj.y, facing * xscale, yscale, c_white, image_alpha, 21, 41);
I'm lost. Any help or suggestions would be greatly appreciated.
 

Fern

Member
Ok so you can use draw_sprite_part_ext() but I'd recommend you use draw_sprite_general() instead. You can plug it in and use my script.

I happened to have GM open when I saw this so quickly tossed this together for you. Hope this helps! (I didn't test this so forgive me if I overlooked something)

Also I went ahead and just used the full width/height of the sprite in this script but you can easily add 2 arguments and replace sprite_get_width() and sprite_get_height() with those arguments.

Code:
/// @arg sprite,subimg,x,y,xscale,yscale,rot,color,alpha,origin_x,origin_y
 
var
_x_offset = (sprite_get_xoffset(argument0) - argument9) * argument4,
_y_offset = (sprite_get_yoffset(argument0) - argument10) * argument5;
 
draw_sprite_general(
    argument0,
    argument1,
    0,
    0,
    sprite_get_width(argument0),
    sprite_get_height(argument0),
    (argument2 - 1) + lengthdir_x(_x_offset,argument6) + lengthdir_x(_y_offset,argument6 - 90),
    (argument3 - 1) + lengthdir_y(_x_offset,argument6) + lengthdir_y(_y_offset,argument6 - 90),
    argument4,
    argument5,
    argument6,
    argument7,
    argument7,
    argument7,
    argument7,
    argument8
);
 
S

Shameful

Guest
Sorry friend, that also draws nothing. The more I mess with it the more I think the problem might be that sprite_get_xoffset and sprite_get_yoffset only get the x offset of the entire sprite sheet instead of the area that is actually being drawn. I was thinking I might be able to use layer_get_sprite_ID, but even if there is a unique ID for the sprite part being drawn, It won't exist until after it is already drawn at the 0,0 origin. I think I'll have to approach this from an entirely different direction. I appreciate you trying to help me.
 
Sorry friend, that also draws nothing.
That is probably because you are calling draw_sprite_part as part of the call to the script and expecting that to pass a partial sprite into the script, but the sraw_sprite_part function does not return anything so it will not pass anything into the script for the sprite to draw. I suspect that you will need to just pass the full sprite and let the script do what it has to.
 
Top