draw_sprite image_speed problem

Pfap

Member
So I set up my game pretty much using all the built in variables.

I want to change which sprite is drawn, but I don't want to change sprite_index because I use the value of sprite_index for my games logic.


I thought a work around would be to just draw the sprite change I need, but then when I change image_speed it is not affecting the sprite being drawn.




Code:
//create event

sprite_index = my_sprite;


sprite_control = sprite_index;


image_index = 0;
image_speed = 0;


Code:
//draw event

//essentially being used as draw_self()
draw_sprite(sprite_control, image_index, x, y);
Code:
//tap event



//this changes the sprite but not the sprite's image_speed
sprite_control = my_other_sprite;
image_speed = 5;

Any ideas on how to fix this without going through and changing how I use the sprite_index variable in my logic?




EDIT:
I just tried it with image_speed = 5 and it works, but anything lower than image_speed = 3 nd it just sits there. Any ideas why?
 
T

TinyGamesLab

Guest
You can add manually to your image_index at the step/draw event and have it loop using the following code:
Code:
if image_index == 3 {
image_index = 0
}
You can always have your image_index be another variable that gets added at the step or draw event. (Create a new variable at the create event and use it as "image_index".)
I'm on my phone but if I recall correctly you can keep adding to your new variable that your sprite frame will loop through without a problem.
A similar problem was posted and solved before:
https://forum.yoyogames.com/index.p...ion-to-cycle-through-sprite-sub-images.30734/
 

jo-thijs

Member
So I set up my game pretty much using all the built in variables.

I want to change which sprite is drawn, but I don't want to change sprite_index because I use the value of sprite_index for my games logic.


I thought a work around would be to just draw the sprite change I need, but then when I change image_speed it is not affecting the sprite being drawn.




Code:
//create event

sprite_index = my_sprite;


sprite_control = sprite_index;


image_index = 0;
image_speed = 0;


Code:
//draw event

//essentially being used as draw_self()
draw_sprite(sprite_control, image_index, x, y);
Code:
//tap event



//this changes the sprite but not the sprite's image_speed
sprite_control = my_other_sprite;
image_speed = 5;

Any ideas on how to fix this without going through and changing how I use the sprite_index variable in my logic?
Yes, use a variable image_control and in the end step event, set it to:
Code:
var image_delta;
switch sprite_get_speed_type(sprite_control) {
case spritespeed_framespersecond:
    image_delta = sprite_get_speed(sprite_control) * delta_time / 1000000;
    break;
case spritespeed_framespergameframe:
    image_delta = sprite_get_speed(sprite_control);
    break;
default:
    image_delta = 1;
}

image_control = (image_control + image_delta * image_speed) mod sprite_get_number(sprite_control);
However, if you're aleady now experiencing that the way you have build your logic on sprite_index hinders you,
then that's a sign that you should change your logic.
The odds are it'll hinder you in the future again and fixing it will keep getting more difficult (usually).

Why is your logic so dependent on the value of sprite_index?
Because of collisions?
Because of determining state?
 
Last edited:
D

dugtrioramen

Guest
So I set up my game pretty much using all the built in variables.

I want to change which sprite is drawn, but I don't want to change sprite_index because I use the value of sprite_index for my games logic.


I thought a work around would be to just draw the sprite change I need, but then when I change image_speed it is not affecting the sprite being drawn.




Code:
//create event

sprite_index = my_sprite;


sprite_control = sprite_index;


image_index = 0;
image_speed = 0;


Code:
//draw event

//essentially being used as draw_self()
draw_sprite(sprite_control, image_index, x, y);
Code:
//tap event



//this changes the sprite but not the sprite's image_speed
sprite_control = my_other_sprite;
image_speed = 5;

Any ideas on how to fix this without going through and changing how I use the sprite_index variable in my logic?




EDIT:
I just tried it with image_speed = 5 and it works, but anything lower than image_speed = 3 nd it just sits there. Any ideas why?
The reason it's not working is probably because image_index value loops between 0 and the number of the last frame of the sprite_index. So if you try use an image_index that is bigger than the amount of frames of sprite_index, image_index will go back to the beginning. That's bad because you are not using sprite_index, so your sprite could have a different number of frames than the sprite_index. But you are also using image_index, which only cares about sprite_index.

You have to use a variable for the image index instead.
Let's say Create Event:
image_control = 0

At the end of the step event:
image_control += image_speed
 

Pfap

Member
Yes, use a variable image_control and in the end step event, set it to:
Code:
var image_delta;
switch sprite_get_speed_type(sprite_control) {
case spritespeed_framespersecond:
    image_delta = sprite_get_speed(sprite_control) * delta_time / 1000000;
    break;
case spritespeed_framespergameframe:
    image_delta = sprite_get_speed(sprite_control);
    break;
default:
    image_delta = 1;
}

image_control = (image_control + image_delta * image_speed) mod sprite_get_number(sprite_control);
However, if you're aleady now experiencing that the way you have build your logic on sprite_index hinders you,
then that's a sign that you should change your logic.
The odds are it'll hinder you in the future again and fixing it will keep getting more difficult (usually).

Why is your logic so dependent on the value of sprite_index?
Because of collisions?
Because of determining state?


I normally like to use the built in variables mainly as a design aid.

I'm using a lot of code like this:

Code:
//the sprite list contains actual sprite indexes which  my instances get set to and I have later code that is dependent on the value of sprite index not changing 
ds_grid_set(global.order_grid,b,v,sprite_get_name(ds_list_find_value(sprite_list,j)));
I've decided I will go through and instead set some variable that is consistent and doesn't change maybe original_sprite = ds_list_find_value(sprite_list,j) and then use the built in variables to solely be used for animations and the like.
 

jo-thijs

Member
I normally like to use the built in variables mainly as a design aid.

I'm using a lot of code like this:

Code:
//the sprite list contains actual sprite indexes which  my instances get set to and I have later code that is dependent on the value of sprite index not changing
ds_grid_set(global.order_grid,b,v,sprite_get_name(ds_list_find_value(sprite_list,j)));
I've decided I will go through and instead set some variable that is consistent and doesn't change maybe original_sprite = ds_list_find_value(sprite_list,j) and then use the built in variables to solely be used for animations and the like.
Sounds like a good idea.
I don't see how that example depends on sprite_index though.

Also, you can shorten that code using accessors to:
Code:
//the sprite list contains actual sprite indexes which  my instances get set to and I have later code that is dependent on the value of sprite index not changing
global.order_grid[# b, v] = sprite_get_name(sprite_list[|j]);
 
W

Wraithious

Guest
Another way to do it is make a variable such as animationNumber, (EDITED OUT IMAGE_SINGLE AS YOU DON'T NEED IT IF JUST DRAWING YOUR SPRITE and use the built in variable image_single which directly accesses the sub images as whole numbers.) In your step event increment the animationNumber variable untill it is the same value as image_number and set it back to 0, (or with this system you can animate any part of your image by starting, then capping at whatever sub images you want) then draw your sprite with animationNumber as the sub image value. an example could be, say you want to walk left, and your sprite has 16 sub images, in the order of 0 - 3 is right, 4 - 7 is down, 8 - 11 is left and 12 - 15 is up:
create event:
Code:
animationNumber=0;
imgControl=-1; //use to set sub image to start/change the animation, -1=first run, 0=right, 1=down, 2=left, 3=up
step event:
Code:
if (right==1) {
    if (imgControl != 0) {
        imgControl = 0;
        animationNumber=0;
    }
    animationNumber += 1;
    if animationNumber > 3 animationNumber=0;
}

if (down==1) {
    if (imgControl != 1) {
        imgControl = 1;
        animationNumber=4;
    }
    animationNumber += 1;
    if animationNumber > 7 animationNumber=4;
}
Code:
if (left==1) {
    if (imgControl != 2) {
        imgControl = 2;
        animationNumber=8;
    }
    animationNumber += 1;
    if animationNumber > 11 animationNumber=8;
}
Code:
if (up==1) {
    if (imgControl != 3) {
        imgControl = 3;
        animationNumber=12;
    }
    animationNumber += 1;
    if animationNumber > 15 animationNumber=12;
}
Draw event:
Code:
draw_sprite(spr_Cha1,animationNumber,Cha1.x,Cha1.y);
And of course you may want to be able to dynamically change the animation speed, and can do so with a timer and speed variables, example:
create event:
Code:
animationNumber=0;
imgControl=-1; //use to set sub image to start/change the animation, -1=first run, 0=right, 1=down, 2=left, 3=up
aniSpeed=4; //You can change this variable anywhere in code to change the animation speed dynamically
aniTimer = aniSpeed;
canAni=0;
step event:
Code:
if aniTimer >0 aniTimer -=1;
if aniTimer = 0 canAni=1;

if (right==1) {
    if (imgControl != 0) {
        imgControl = 0;
        animationNumber=0;
    }
    if (canAni=1) {
        animationNumber += 1;
        if animationNumber > 3 animationNumber=0;
        canAni = 0;
        aniTimer = aniSpeed;
    }
}

if (down==1) {
    if (imgControl != 1) {
        imgControl = 1;
        animationNumber=4;
    }
    if (canAni=1) {
        animationNumber += 1;
        if animationNumber > 7 animationNumber=4;
        canAni = 0;
        aniTimer = aniSpeed;
    }
}

if (left==1) {
    if (imgControl != 2) {
        imgControl = 2;
        animationNumber=8;
    }
    if (canAni=1) {
        animationNumber += 1;
        if animationNumber > 11 animationNumber=8;
        canAni = 0;
        aniTimer = aniSpeed;
    }
}

if (up==1) {
    if (imgControl != 3) {
        imgControl = 3;
        animationNumber=12;
    }
    if (canAni=1) {
        animationNumber += 1;
        if animationNumber > 15 animationNumber=12;
        canAni = 0;
        aniTimer = aniSpeed;
    }
}
Draw event:
Code:
draw_sprite(spr_Cha1,animationNumber,Cha1.x,Cha1.y);
 
Last edited by a moderator:

Pfap

Member
Another way to do it is make a variable such as animationNumber, and use the built in variable image_single which directly accesses the sub images as whole numbers. In your step event increment the animationNumber variable untill it is the same value as image number and set it back to 0, (or with this system you can animate any part of your image by starting, then capping at whatever sub images you want) then draw your sprite with animationNumber as the sub image value. an example could be, say you want to walk left, and your sprite has 4 sub images right, 4 down, 4 left and 4 up:
create event:
Code:
animationNumber=0;
imgControl=-1; //use to set sub image to start/change the animation, -1=first run, 0=right, 1=down, 2=left, 3=up
step event:
Code:
if (right==1) {
    if (imgControl != 0) {
        imgControl = 0;
        image_single=0;
    }
    animationNumber += 1;
    if animationNumber > 3 animationNumber=0;
}

if (down==1) {
    if (imgControl != 1) {
        imgControl = 1;
        image_single=4;
    }
    animationNumber += 1;
    if animationNumber > 7 animationNumber=4;
}
Code:
if (left==1) {
    if (imgControl != 2) {
        imgControl = 2;
        image_single=8;
    }
    animationNumber += 1;
    if animationNumber > 11 animationNumber=8;
}
Code:
if (up==1) {
    if (imgControl != 3) {
        imgControl = 3;
        image_single=12;
    }
    animationNumber += 1;
    if animationNumber > 15 animationNumber=12;
}
Draw event:
Code:
draw_sprite(spr_Cha1,animationNumber,Cha1.x,Cha1.y);


Cool, that opens up a whole pandora's box lol. You mean image_number though, right? Thanks for your reply it really has me thinking about ways to get more control of the structure of not only code, but also sprites.
 
W

Wraithious

Guest
Cool, that opens up a whole pandora's box lol. You mean image_number though, right? Thanks for your reply it really has me thinking about ways to get more control of the structure of not only code, but also sprites.
Actually it's image_single, it's a hidden built in variable I use all the time instead of image_index, I just find it much easier to control my animations with.

Actually in my above examples you don't even need to use image_single at all, you can replace all those image_single calls with that animationNumber variable because you are only using it to draw with. (EDITED my above post to correct that error)
In other cases if you wanted to control the object's actual image I'd change all the animationNumber variables to image_single. sorry about that.
 
Last edited by a moderator:
Top