• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Creating objects with lists

U

Ukaygee

Guest
Hey, so in my game, I have a list. The entirety of the list is being drawn using this code:
Code:
var yy = y+5;
var xx = x+10;
var incval = 32;
for (var i = 0; i < ds_list_size(date); i++)
{
    DrawAlignColour(fa_left,fa_top,c_black);
    draw_text(xx,yy,ds_list_find_value(list,i));
    yy += incval;
}
Now, what I want is for a check mark object to be created at the side of every entry of the list, I want the check marks to be able to remove the corresponding item in the list and itself... I have tried messing around with code for hours, but I can't seem to find anything that works.

I would want it to look like this
upload_2018-6-17_10-57-52.png
(So far, I have done this by adding the line "draw_sprite(sCheckMark,0,xx+(sprite_width-25),yy); )

Does anyone have any ideas?
Thanks!
 
The check mark is an object, and you create an instance of it for each entry on the list. Give it a reference to the object with the list, and what position it refers to. When the list is complete you could just loop through every entry, and as you do so - create the check mark, and set it's variable 'position' to be the current number in the for loop. I will treat it as there being two objects:

list_object
check_mark_object

and list_object (which only has one instance present in the room) has a list called 'list'

// within list_object
Code:
size = ds_list_size(list_object.list)
for (a = 0; a < size; a++)
{
check_inst = instance_create(whatever, whatever, check_mark_obj);
check_inst.position = a;
}

within check mark object
//create
Code:
position = undefined;
// mouse button released event - works when the mouse is over the sprite of the check mark object
Code:
ds_list_delete(list_object.list, position);
with (check_mark_obj)  // all current instances on that object - compare themselves to the instance calling the code
{
if position > other.position
{
position -=1;
}
}
instance_destroy();
This is rough code, but it ought to remove the position in the list that the clicked on object has. Then tell all the others, that are later than it in the list, to reduce their value of 'position' by one. The list will shrink, and their value should reflect that. Then the instance that was clicked on destroys itself. You would then want the remaining instances to alter their x / y position so that they are properly being placed next to their new list position.

I haven't yet tested this, but am reasonably sure that's it.
 

Alexx

Member
Ninjad!
As you know where the sprite is drawn you can check whether the mouse cursor is over the sprite, and perform a check when the mouse button is pressed.

Alternatively you could create an object at the sprite's position for each option. and check that way.

Personally, I would go for the first option, though more math would be involved.
 
Ninjad!
As you know where the sprite is drawn you can check whether the mouse cursor is over the sprite, and perform a check when the mouse button is pressed.

Alternatively you could create an object at the sprite's position for each option. and check that way.

Personally, I would go for the first option, though more math would be involved.
That never occurred to me...

If they get the dimensions of the list, and know how it is "split" when drawn, then they could just be able to figure out which entry the mouse is next to (if they're using the mouse). I think:

// mouse button released
if mouse_y > y + 5
{list_position = (mouse_y - (y + 5)) div 32;
ds_list_delete(list, list_position);}

might do the trick....??

@Ukaygee
I have just taken the values from your code above. yy = y + 5, and then it is incremented by 32. So the point where list position zero is drawn is between:
y + 5
and
y + 5 + 32
Then every other list position is being drawn at 32 pixels after that.

My code is getting the distance between the mouse' y position and the start point of where you're drawing the list from. div 32 returns how many times 32 will go into that number.

Then take that number as the position in the list. If the distance was larger than 0, but less than 32, the number would be 0. If it was a distance of 59, then the number would be 1. And so on.

It has:
if mouse_y > y + 5

so that it only works when the mouse' y position is larger than the starting y position of the object drawing the list.
 
Last edited:

DesArts

Member
Yeah it would be best to not use an object for each tick, huge waste and not very flexible at all (for example if you want to scroll the list, much easier if you're just drawing them in one go, just add an offset value).

As said above, get the mouse's list position by div the mouse_y by the list item height, and optionally check if the mouse_x is over the checkbox area also.
If that is true, and mouse is clicking, do whatever ya wanna do.
 
@Desix
It's funny - the simpler option probably wouldn't have occurred to me, and I'd have gone down the convoluted path. But the suggestion of using math by Alexx just triggered an understanding, and then when you see it, it's so straightforward....
 

Alexx

Member
If you go down that route, you could create your own system for checking the mouse's position relative to the sprite, or have a look at
Code:
point_in_rectangle(px, py, x1, y1, x2, y2)
in the manual.

If your list will be static, I'd suggest
Code:
point_in_rectangle
.
If you want scrolling of the list, a manual approach may be better.
 
U

Ukaygee

Guest
Thank you very much @Alexx and @Desix, it worked perfectly!

@the_dude_abides, thank you so much for your suggestion, and I would've gone with it, but seeing as my lists could get rather large, I think the other option won't cause as much lag.

Thank you all! :)
 
Top