[SOLVED] Attempting to draw random sprites

G

GerPronouncedGrr

Guest
I'm attempting to generate random character sprites using Kenney's roguelike sprites, but am running into an issue I don't understand. Currently, I have it set up with an object, the character, and a script that draws each element in order at the x and y coordinates of the character object. I'll post both bits of code here:

DrawCharacter()
Code:
draw_set_color(c_white);
draw_sprite(sprBodies, irandom_range(0, 7), x, y);
draw_sprite(sprFeet, irandom_range(0, 11), x, y);
draw_sprite(sprLegs, irandom_range(0, 7), x, y);
draw_sprite(sprTops, irandom_range(0, 119), x, y);
draw_sprite(sprHair, irandom_range(0, 91), x, y);
draw_sprite(sprHats, irandom_range(0, 35), x, y);
draw_sprite(sprLeft_Hand, irandom_range(0, 69), x, y);
draw_sprite(sprRight_Hand, irandom_range(0, 117), x, y);
Colour is set to white because I have a drawGUI event in another object set to draw in black.

objCharacter/Step
Code:
character = instance_find(objCharacter, 1);

if (mouse_check_button_pressed(mb_left))
{
    instance_destroy(character);
    show_debug_message("Character Destroyed");
    instance_create_layer(x, y, "Instances", objCharacter);
    DrawCharacter();
    show_debug_message("Character Generated");
}
So, the behaviour that I get is that, when I click, the debug messages are shown but nothing else happens. I thought maybe I was destroying the previous instance wrong, but if I strip that code out I still get nothing. Previously, I had the sprite generation code in the draw event, but then the character was generating non-stop, impossibly fast, regardless of whether I clicked or not.
 
A

Aura

Guest
Drawing is supposed be done in a Draw event and when you're doing it via a script, the script is supposed to be called there as well. Also, sprites need to be drawn constantly... and draw_sprite() draws the sprite instead of assigning it to an instance. If you place that script in a Draw event, things would be mess up as irandom_range() would be called every step and a new random image would be drawn. So I suggest writing the system from scratch. In the character object, assign random image indexes to some variables in the Create event.

Code:
my_head = irandom(7);
my_feet = irandom(7);
If you want body parts of the same type, then use this instead:

Code:
var temp = irandom(7);
my_head = temp;
my_feet = temp;
Using the Draw event, you can do this:

Code:
draw_sprite(spr_head, my_head, x, y);
draw_sprite(spr_feet, my_feet, x, y);
Alternatively, make changes to your script and use those variables as image indexes. Just don't forget to call it in the Draw event of the character object.
 
G

GerPronouncedGrr

Guest
Yes! Excellent, thanks @Aura for your help. I had originally attempted something similar, but I didn't understand that running the randomisation in the Draw event was the problem.
 
G

GerPronouncedGrr

Guest
Hmm, now I've realized that I'm using instance_destroy wrong, or something like that. In the step event I try to find the instance ID of the character object, destroy it, then create a new instance. I moved this behaviour from the character object to a controller object, because I realized that having it in the calling object it would cause it to destroy itself. Regardless, when I generate a new sprite, the old one is not destroyed. Either I'm not finding it correctly, or not destroying it correctly.
 
G

GerPronouncedGrr

Guest
I've updated the script in question, both with @IndianaBones suggestion, and with another debug message, in an attempt to figure this out. This iteration shows that the instance ID is being incremented by 1 each time I click the mouse button, but the old sprites aren't cleared from the screen. Based on my reading of the instance_destroy documentation, I would expect the old instance to be removed from the game at the end of the calling frame.

Code:
if (mouse_check_button_pressed(mb_left))
{
    character = instance_find(objCharacter, 1);
    if (instance_exists(character))
    {
        show_debug_message(character);
        with (character)
        {
            instance_destroy();
            show_debug_message("Character Destroyed");
        }
    }
  
    instance_create_layer(66, 50, "Instances", objCharacter);
    show_debug_message("Character Generated");
}
EDIT: Interestingly, if I change the instance_find call to use the all keyword, I stop seeing the incremented instance IDs and the "Character Destroyed" debug message, and the objects still aren't destroyed.
 
Last edited by a moderator:
A

Aura

Guest
Why are you using instance_find() at all? If you want only a single instance of the character object at a time, then a simple with statement should suffice.

Code:
with (obj_Character) {
   instance_destroy();
}
instance_create_layer(66, 50, "Instances", obj_Character);
 
G

GerPronouncedGrr

Guest
This is what I originally tried, however it also doesn't destroy the old sprites as expected, which is why I tried going more complex.
 
If the character object is being destroyed correctly the sprites should no longer be drawn...unless you are not clearing the window with the background colour?..not sure if GM2 has that option in the room settings.

Also, how about saving the created character to a variable when you create it?

Code:
my_character = instance_create ....etc
Then when you want to destroy it you can just do :
Code:
with( my_character) 
{
    instance_destroy()
}
 
G

GerPronouncedGrr

Guest
It appears that clearing to background colour was the issue, thanks very much @IndianaBones! I didn't even know this was a thing :p
 
Top