Search code examples
listfor-loopcollision-detectionglmgame-maker

ds_list Not working as inteded in game maker studio


The problem with my code occurs when i try to use a ds list for all my targets. It seems like it wont register a thing, i don't know what i am doing wrong, i have tried everything i know. When i display the values for the ds list its always 0, even tho the collision id i put in to the list has a value. also the collision id default at -4 when It's not colliding with anything for some reason.

here is the code that assign the value to the ds list.

//get all enemys in area
current_coli = collision_circle(x, y, tower_range, obj_enemys, 0, 1);
if (current_coli != noone){
    ds_list_add(collision_list, current_coli);
}

Here is the code I'm trying to use the ds list in witch dose nothing.

var i
for (i = 0; i < ds_list_size(collision_list) + 1; i++){
    target_test = ds_list_find_value(collision_list, i);
if (instance_exists(target_test) and (rectangle_in_circle(target_test.x - 7, target_test.y - 7, target_test.x + 7, target_test.y + 7, x, y, tower_range) > 0))
    {
      target = ds_list_find_value(collision_list, i);
      target.show_hp_bar = true;
      target.path_speed = target.path_speed * ((100 - slow)/100)
      show_debug_message(other.target); 
    }else{
        target.path_speed = target.start_speed; 
        ds_list_delete(collision_list, i);  
    }
} 

I can't execute that code because of the ds list containing nothing. As i said before, the "current_coli" gives the id of the object, but it dose not store it to the ds list for some reason, "target_test" is always unidentified and the ds list "collision_list" is always 0. the code is inside a object step event that have a stationary place on the map and apply the effect to a enemy object that is inside its collision radius.


Solution

  • This is wrong:

    //get all enemys in area
    current_coli = collision_circle(x, y, tower_range, obj_enemys, 0, 1);
    if (current_coli != noone){
        ds_list_add(collision_list, current_coli);
    }
    

    collision_circle returns only one (least) ID, not all IDs. You can to do something like this:

    with obj_enemys
    {
        if point_distance(x, y, other.x, other.y) < other.tower_range
        {
            ds_list_add(other.collision_list, id);
        }
    }
    

    And

    var i
    for (i = 0; i < ds_list_size(collision_list) + 1; i++)
    

    also wrong. Right:

    for (var i=0; i<ds_list_size(collision_list); i++)
    
    1. You can write var inside for.

    2. You don't need +1.

    One more thing. When you do

    ds_list_delete(collision_list, i);
    

    It changes data and breaks your for loop. For example, you can decrease i after deleting.

    ds_list_delete(collision_list, i);
    i--;
    

    or same in one line

    ds_list_delete(collision_list, i--);