How can I change the direction of a drawn sprite?

Discussion in 'Programming' started by Den, Jan 9, 2017.

  1. Den

    Den Guest

    So I have made an outline that appears over an enemy when the mouse goes over it but I can't figure out a good way to draw the outline in the left direction without using rotate, but if I use rotate it just stretches the outline.
    I'm pretty new to drawing code so It could just be something obvious lol.

    Here's the drawing code:
    Code:
    ///Draw The Outline
    draw_self();
    
    //Set the color
    var outline_color = c_black;
    
    //Draw the sprite 1 pixel off in each direction
    if(position_meeting(mouse_x, mouse_y, Enemy_Parent)) {
    draw_sprite_ext(sprite_index, -1, x - 1, y, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, -1, x + 1, y, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, -1, x, y - 1, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, -1, x, y + 1, 1, 1, 0, outline_color, 1);
    
    //Draw the regular sprite at origin
    draw_sprite(sprite_index, -1, x, y);
    }
     
  2. Tthecreator

    Tthecreator Your Creator!

    Joined:
    Jun 20, 2016
    Posts:
    757
    What do you mean it "stretches the outline"

    What you should know when rotating is that it rotates around the sprites origin.
    That's the point you specify inside the sprite editor. Set this to the middle or your sprite, and the sprite will also spin and scale around the center point.
     
  3. Mishtiff

    Mishtiff Guest

    Hi, Tthecreator is probably correct. Go into your sprite for the enemy and be sure that you have centered out its origin. I could be wrong, but I think the simplest way to do this is just to draw 4 lines around your sprite. You can put this into a script and just send the sprites info to it.

    get the units x/y, and get the sprite size:
    var enemy_x = Enemy_Parent.x;
    var enemy_y = Enemy_Parent.y;
    var sprite_w = Enemy_Parent.sprite_width;
    var sprite_h = Enemy_Parent.sprite_height;

    Now just do the easy work:

    draw_sprite(sprite_index, -1, x, y);

    draw_set_colour(c_red);
    draw_line(x - (sprite_w/2), y - (sprite_h/2), x + (sprite_w/2), y - (sprite_h/2)); //top line -
    draw_line(x + (sprite_w/2), y - (sprite_h/2), x + (sprite_w/2), y + (sprite_h/2)); //right line -|
    draw_line(x - (sprite_w/2), y + (sprite_h/2), x + (sprite_w/2), y + (sprite_h/2)); //bottom line =|
    draw_line(x - (sprite_w/2), y + (sprite_h/2), x - (sprite_w/2), y - (sprite_h/2)); //left line |=|

    return color to whatever:
    draw_set_colour(c_white);

    Let me know if this helps.
     
  4. Den

    Den Guest

    Nah checking the origin was the first thing I did when I couldn't flip it. I'm just trying to flip the outline i'm drawing when the enemy changes direction. When the player hovers the mouse over the enemy an outline will go around the enemy's sprite
    to show that your selecting that object but the issue is when the enemy's moving left it still draws the outline of the enemy facing right, like I thought sprite index selects the current sprite no matter what way it's facing.
    Do I have to write a new line of could for the so it only draws to the left under a certain condition?
     
  5. Mishtiff

    Mishtiff Guest

    Could you please post a pic of whats going on?
    also, the code you posted above... im not sure i understand where this is being ran.
    you have this:
    ///Draw The Outline
    draw_self();

    but then you draw this if hovering:
    //Draw the regular sprite at origin
    draw_sprite(sprite_index, -1, x, y);

    can you explain a bit so i understand better?
     
  6. Den

    Den Guest

    The code I shared is being ran in the enemy's draw event and the reason I have a comment saying "Draw The Outline" is just so the draw event has a title so I know what it is. The comment itself has nothing to do with
    the draw self function lol it relates to the code in the if statement. I can't get a picture because I don't have anything to capture it with. So whats happening is when the enemy is walking to the left and the mouse hovers over it, the draw event is still just drawing the outline sprite to the right. So basically even though the enemy is in it's left walk cycle it gets drawn animating to the right when the mouse hovers over it, with the outline around it.
     
  7. Mishtiff

    Mishtiff Guest

    Ok I think I see whats going on here, lets see if im correct.

    You need to track which direction the enemy is moving. if its xspeed < 0, it is left, if its xspeed > 0 it is right. then edit your code as follow as try:

    ///Draw The Outline
    draw_self();

    //Set the color
    var outline_color = c_black;

    var dir = 0;

    if(xspeed < 0){
    dir = -1;
    }
    else{
    dir = 1;
    }

    //Draw the sprite 1 pixel off in each direction
    if(position_meeting(mouse_x, mouse_y, Enemy_Parent)) {
    draw_sprite_ext(sprite_index, dir, x - 1, y, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, dir, x + 1, y, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, dir, x, y - 1, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, dir, x, y + 1, 1, 1, 0, outline_color, 1);

    //Draw the regular sprite at origin
    draw_sprite(sprite_index, dir, x, y);
    }


    Essentially, I believe you are always drawing the sprite the same way no matter what direction they are walking in this code. If you can track what direction the sprite is walking, you can make it draw the correct way.

    Let me know
     
  8. Den

    Den Guest

    What u said makes total sense but it's still drawing the sprite facing the right lol.
    I have like triple checked my code to make sure I didn't miss something too ahah
    I don't get what's causing it, unless i'm doing something wrong when i'm
    checking the direction. Don't think I am though. (I can't check a hspeed or anything coz i use I random
    to move the enemy in a random direction)

    Here's my code just incase I am XD
    Code:
    ///Draw The Outline
    draw_self();
    var dir = 0;
    if(image_xscale == -1) {
        dir = -1;
    }else {
        dir = 1;
    }
    //Set the color
    var outline_color = c_black;
    
    //Draw the sprite 1 pixel off in each direction
    if(position_meeting(mouse_x, mouse_y, Enemy_Parent)) {
    draw_sprite_ext(sprite_index, dir, x - 1, y, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, dir, x + 1, y, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, dir, x, y - 1, 1, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, dir, x, y + 1, 1, 1, 0, outline_color, 1);
    
    //Draw the regular sprite at origin
    draw_sprite(sprite_index, dir, x, y);
    }
     
  9. Mishtiff

    Mishtiff Guest

    Give me the code where you are moving the enemy please. also, image_xscale is not what you are looking for in the check direction code.

    var dir = 0;
    if(image_xscale == -1) { //this will not work, unless you are setting the image_xscale in the STEP event to being -1 or 1.
    dir = -1;
    }else {
    dir = 1;
    }
     
  10. Den

    Den Guest

    Ohh ok I didn't know that about the image_xscale.

    The enemy's movement code:
    Code:
    ///wander_state2()
    
    if(alarm[IDLE] == -1){
        alarm[IDLE] = room_speed*irandom_range(4,6);
        random_dir = choose(1,-1);
    }
    
    x+= random_dir;
    
    //Turn sprite to the left
    if(random_dir == -1) {
        image_xscale = -1;
        sprite_index = NPC_wander;
        image_speed = .3;
    }else if(random_dir == 1) {
        image_xscale = 1;
        sprite_index = NPC_wander;
        image_speed = .3;
    }
    
    
     
  11. Mishtiff

    Mishtiff Guest

    here is the documentation for draw_sprite_ex();

    draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, image_angle, image_blend, image_alpha);

    Since you are setting the image_xscale in your step event, modify your code in draw event to the following:

    Code:
    ///Draw The Outline
    draw_self();
    
    //Set the color
    var outline_color = c_black;
    
    //Draw the sprite 1 pixel off in each direction
    if(position_meeting(mouse_x, mouse_y, Enemy_Parent)) {
    draw_sprite_ext(sprite_index, 0, x - 1, y, image_xscale, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, 0, x + 1, y, image_xscale, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, 0, x, y - 1, image_xscale, 1, 0, outline_color, 1);
    draw_sprite_ext(sprite_index, 0, x, y + 1, image_xscale, 1, 0, outline_color, 1);
    
    //Draw the regular sprite at origin
    draw_sprite(sprite_index, image_xscale, x, y);
    }
    
     
    Last edited by a moderator: Jan 10, 2017
    Den likes this.
  12. Murzy

    Murzy Member

    Joined:
    Jul 28, 2016
    Posts:
    24
    This.

    You might want to cleanup the code a bit more, and add the other inbuilt variables as well.

    Code:
    
    ///Draw The Outline
    
    //Set the color
    var outline_color = c_black;
    
    // Outline offset
    var offset = 1; // pxs
    
    var xs = image_xscale; // Horizontal scale
    var ys = image_yscale; // Vertical scale
    var rotation = image_angle; // Image rotation
    var alpha = image_alpha;
    
    //Draw the sprite 1 pixel off in each direction
    if(position_meeting(mouse_x, mouse_y, Enemy_Parent)) {
       draw_sprite_ext(sprite_index, -1, x - offset, y, xs, ys, rotation, outline_color, alpha);
       draw_sprite_ext(sprite_index, -1, x + offset, y, xs, ys, rotation, outline_color, alpha);
       draw_sprite_ext(sprite_index, -1, x, y - offset, xs, ys, rotation, outline_color, alpha);
       draw_sprite_ext(sprite_index, -1, x, y + offset, xs, ys, rotation, outline_color, alpha);
    }
    
    //Draw the regular sprite at origin
    draw_sprite(sprite_index, -1, x, y);
    
    
    
     
    Den likes this.
  13. Den

    Den Guest

    Hey thanks for the help, the drawn sprite is in the right detection now when moving left but something is interfering with the image_xscale, the enemy sprite wont flip to the left now when it's moving in a left direction lol.
    I'm trying to figure out whats causing it, it's like something is overriding the direction check in the enemy's wander state.
     
  14. Murzy

    Murzy Member

    Joined:
    Jul 28, 2016
    Posts:
    24
    Might be the last line of the code, just noticed that it isn't drawing the sprite with the correct xscale.

    Change
    Code:
    //Draw the regular sprite at origin
    draw_sprite(sprite_index, -1, x, y);
    
    To this:
    Code:
    //Draw the regular sprite at origin
    draw_self();
    
    Or if you want it to be formatted like the outline draw commands, you can use something like this
    Code:
    draw_sprite_ext(sprite_index, -1, x, y, xs, ys, rotation, outline_color, alpha);
    
     
    Den likes this.
  15. Den

    Den Guest

    Thanks man with your help I manged to do it :)
    one issue tho haha no matter what I change the colour too, it stays black.
    Is this to do with the image alpha or something?
     
    Last edited by a moderator: Jan 11, 2017
  16. Murzy

    Murzy Member

    Joined:
    Jul 28, 2016
    Posts:
    24
    Well actually, what we are doing here is image blending with a certain color, i.e. basically multiplying the existing image data with a certain color. Without going much into detail, if you want the outline to be exactly the color defined in the code, the image used in the draw call needs to be perfectly white. However, you should be seeing some kind of results with this kind of approach, which usually are "good enough". But if the image you are using is very dark, or black, this script might not work for your purposes.

    There are more complicated, shared based, solutions to overcome this problem. However, one hack that I can think of, is to create a new, duplicated, sprite that is completely white (with the same shape) and use it in the draw calls. That is, if you want to do the outline drawing this simple way.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice