How can I change the direction of a drawn sprite?

D

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);
}
 

Tthecreator

Your Creator!
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.
 
M

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.
 
D

Den

Guest
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.
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.
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?
 
M

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?
 
D

Den

Guest
Could you please post a pic of whats going on?
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.
 
M

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
 
D

Den

Guest
Let me kno
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);
}
 
M

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;
}
 
D

Den

Guest
Give me the code where you are moving the enemy please
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;
}
 
M

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:
  • Like
Reactions: Den

Murzy

Member
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...
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);
 
  • Like
Reactions: Den
D

Den

Guest
You might want to cleanup the code a bit more, and add the other inbuilt variables as well.
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.
 

Murzy

Member
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.
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);
 
  • Like
Reactions: Den
D

Den

Guest
Might be the last line of the code
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:

Murzy

Member
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?
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.
 
Top