[SOLVED] Do sprites need to be in a particular order? (sprite_index)

C

Cody Oltman

Guest
My game spawns randomly generated obstacles that choose from a list of sprites for a single "obj_walls" object ("spr_walls", "spr_walls1", "spr_walls2", etc...) and it it flips them along the x-axis (horizontally) when the player comes in contact with an "obj_flipper" object. It flips back to normal when it touches "obj_flipper" again. I'm using a state machine for the player to do this. Pretty simple mechanic.

This has been working fine with 5 sprites: "spr_walls" through "spr_walls4" and they have all been placeholders. Now that I want to change them and add more, I get issues.


Example error code when obj_player collides with obj_flipper :
Code:
Unable to find any instance for object index '7' name 'obj_aologo'
 at gml_Object_obj_controller_Step_0 (line 22) -               spr_walls11.image_xscale = -1;       
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Object_obj_controller_Step_0 (line 22)
NOTE: obj_aologo is an object with no code associated to it and it not located in any rooms. I have had similar errors referring to obj_button & obj_ui, both of which have nothing to do with the code for obj_walls


In obj_controller alarm[0]:
Code:
//Spawn Walls
var i = instance_create_layer(room_width / 2, -200, "Instances", obj_walls);
i.sprite_index = choose(spr_walls, spr_walls1, spr_walls2, spr_walls3, spr_walls4, spr_walls11);

if instance_exists(obj_walls) and i.sprite_index = spr_walls {
    instance_create_layer(room_width / 2, -380, "Instances", obj_flipper);

In obj_controller step event:
Code:
//Flip all Walls
if obj_player.state = player.flip {
    if sprite_exists(spr_walls) {
        spr_walls.image_xscale = -1;   
    }
    if sprite_exists(spr_walls1) {
        spr_walls1.image_xscale = -1;   
    }
    if sprite_exists(spr_walls2) {
        spr_walls2.image_xscale = -1;   
    }
    if sprite_exists(spr_walls3) {
        spr_walls3.image_xscale = -1;   
    }
    if sprite_exists(spr_walls4) {
        spr_walls4.image_xscale = -1;   
    }
    if sprite_exists(spr_walls11) {
        spr_walls11.image_xscale = -1;   
    }
}
In obj_flipper collision event w/ obj_player
Code:
//state = player.flip
    if obj_player.state = player.alive {
    with(obj_player) {
        obj_player.state = player.flip;
        }
    } else {
    with(obj_player) {
        obj_player.state = player.alive;
        }
    }

//Flip all Walls

if obj_player.state = player.alive {
    if sprite_exists(spr_walls) {
        spr_walls.image_xscale = 1;   
    }
    if sprite_exists(spr_walls1) {
        spr_walls1.image_xscale = 1;   
    }
    if sprite_exists(spr_walls2) {
        spr_walls2.image_xscale = 1;   
    }
    if sprite_exists(spr_walls3) {
        spr_walls3.image_xscale = 1;   
    }
    if sprite_exists(spr_walls4) {
        spr_walls4.image_xscale = 1;   
    }
    if sprite_exists(spr_walls11) {
        spr_walls11.image_xscale = 1;   
    }

}
instance_destroy();

Keep in mind that this worked perfectly fine as coded above before trying to add more sprites to choose from in the obj_controller code. I have tried multiple numbers and names besides "spr_walls11". This is just where I am at at the moment.

I have also tried calling the sprites differently as shown below and got the same kind of error message at the same time. It also worked with the first 5 sprites.
Code:
//Flip all Walls 
 if obj_player.state = player.flip {     
if sprite_exists(spr_walls or spr_walls1 or spr_walls2 or spr_walls3 or spr_walls4 or spr_walls5) {         spr_walls.image_xscale = -1;         
spr_walls1.image_xscale = -1;         
spr_walls2.image_xscale = -1;         
spr_walls3.image_xscale = -1;        
spr_walls4.image_xscale = -1;        
spr_walls5.image_xscale = -1;     
} 
}
 

Attachments

spr_walls11.image_xscale
You need to learn the difference between sprites, objects and instances. A sprite does not have image_xscale, an object has image_xscale which is used when it renders the sprite that is associated with the object. By putting "spr_walls11" that is effective translated by GMS into the id of the resource, but because you then treat it as an object GMS decides that you must be trying to refer to an object with that id. That is why you get an error about an object that you are not actually trying to use.

The docs: http://docs2.yoyogames.com/index.ht...nstances/instance_variables/image_xscale.html
This value sets the horizontal scaling applied to the sprite that has been assigned to the current instance.
if sprite_exists(spr_walls or spr_walls1 or spr_walls2 or spr_walls3 or spr_walls4 or spr_walls5)
You cannot do this either. This is invalid code. You need to look at examples of if statements, and learn that when calling a function you can only pass in the parameters that it allows. In this case sprite_exists() take 1 parameter, not multiple like you are trying to do.

Based on all the incorrect code you have in your first post I would recommend that you go and start working through some of the tutorials and read through some examples in the manual so that you get to grips with the basics of GMS. Trying to jump straight into your own game without knowing these basics will cause you a lot of problems - just like you are now finding.
 
C

Cody Oltman

Guest
I want to clarify that the code at the end is not what I am using, just something I tried to see if I could get a different result.
The game is working as intended until I add another sprite into the obj_controller code. I am confused as to why it would work with 5 sprites, but not 6.

I am new to this, but I have completed a GMS course on Udemy, and as far as I can tell, trying things out for myself and learning from my mistakes is the only way I can grow as a programmer. This is something I couldn't figure out on my own, which is why I am here.
Do you have any suggestions as to how I could go about fixing my errors?
 

NightFrost

Member
The problem is as Babia explains above how you're trying to, in obj_controller step event, set image_xscale on a sprite. The variable is a builtin instance variable, so you have to reference an instance when using it. Or you can also reference an object, which makes all instances of that object to change that variable. Sprites have no builtin variables so you will never reference them in this manner.

The reason why there's no errors with first sprites is how GM handles references as numbers under the hood. You might say obj_aologo or spr_walls4 but they too are actually variables generated on the fly that contain a numeric reference to a resource. When you attach image_xscale to a reference, like writing spr_walls1.image_xscale, GM assumes the reference is an instance or an object (because it lets you reference all instances through an object reference). It is capable of finding something because there's overlap in numbering schemes. The problem starts when it can not find an instance or an object that happens to have a same numeric identifier as spr_walls11. (The error message you showed tells that said number is 7. Your spr_wall11 is identified as sprite 7, and your obj_aologo is identified as object 7. Object 7 has no instances in the room, so image_ xscale cannot refer to anything and throws an error.)

The solution is to rewrite the code so it refers to a specific instance, or all instances through an object reference, on which you want to change image_xscale.

EDIT - if the code is running on an instance that needs to modify its own variables, you don't need a reference. Writing just image_xscale changes the instance's own variable.
 
C

Cody Oltman

Guest
Thank you very much, NightFrost, I managed to fix all of my issues with your suggestions!
 
Top