Game Maker GML洪水填充方法 - 处于死胡同

时间:2015-03-03 10:15:00

标签: queue flood-fill game-maker gml

我正在尝试在Game Maker的GML中实现泛洪填充脚本并且已经走到了尽头。在尝试了3个小时来修复我认为填充地板块的简单解决方案之后,我正在寻求这个问题的帮助。我正在测试是否已将瓷砖添加到瓷砖列表中以及它是否会与墙碰撞(因此10行的collision_rectangle功能;这些只是测试地砖是否会与墙重叠)。对不起,这些占用了大量不必要的空间并且搞砸了代码,我在GML中找不到另一种方法。如果这里有人熟悉GML中的数据结构并且知道我做错了什么,请说出来!你会保存我的项目!

代码:

// 2 arrays: one with x values of each tile, one with y values of each

tile_locations_x = ds_list_create();
tile_locations_y = ds_list_create();

tile_stack_x = ds_stack_create();
tile_stack_y = ds_stack_create();

ds_stack_push(tile_stack_x, obj_player.x);
ds_stack_push(tile_stack_y, obj_player.y);

// iterator for "for" loops
var i;

while (!ds_stack_empty(tile_stack_x)) {
    test_location_x = ds_stack_pop(tile_stack_x);
    test_location_y = ds_stack_pop(tile_stack_y);
    ds_list_add(tile_locations_x, test_location_x);
    ds_list_add(tile_locations_y, test_location_y);
    tile_add(bg_floortiles, 0, 0, 16, 16, test_location_x, test_location_y, 99999);

    // Add the 4 cardinal directions to the stack after checking if they're already in the list

    // left of point
    testpoint_x = test_location_x - 16;
    testpoint_y = test_location_y;
    // Check point testpoint_x, testpoint_y is valid
    valid = true;
    // Check added location list first, then check stack because the same location stackd multiple times doesn't work
    for (i = 0; i < ds_list_size(tile_locations_x); i += 1) {
        if (ds_list_find_value(tile_locations_x, i) == testpoint_x && ds_list_find_value(tile_locations_y, i) == testpoint_y) {
            valid = false;
            break;
        }
    }
    if (valid) {
        precise_collision_check = true;
        if (    collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_horizontal, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_vertical, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal4, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector4, precise_collision_check, true) == noone) {
            ds_stack_push(tile_stack_x, testpoint_x);
            ds_stack_push(tile_stack_y, testpoint_y);
        }
    }

    // right of point
    testpoint_x = test_location_x + 16;
    testpoint_y = test_location_y;
    // Check point testpoint_x, testpoint_y is valid
    valid = true;
    // Check added location list first, then check stack because the same location stackd multiple times doesn't work
    for (i = 0; i < ds_list_size(tile_locations_x); i += 1) {
        if (ds_list_find_value(tile_locations_x, i) == testpoint_x && ds_list_find_value(tile_locations_y, i) == testpoint_y) {
            valid = false;
            break;
        }
    }
    if (valid) {
        precise_collision_check = true;
        if (    collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_horizontal, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_vertical, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal4, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector4, precise_collision_check, true) == noone) {
            ds_stack_push(tile_stack_x, testpoint_x);
            ds_stack_push(tile_stack_y, testpoint_y);
        }
    }

    // above point
    testpoint_x = test_location_x;
    testpoint_y = test_location_y - 16;
    // Check point testpoint_x, testpoint_y is valid
    valid = true;
    // Check added location list first, then check stack because the same location stackd multiple times doesn't work
    for (i = 0; i < ds_list_size(tile_locations_x); i += 1) {
        if (ds_list_find_value(tile_locations_x, i) == testpoint_x && ds_list_find_value(tile_locations_y, i) == testpoint_y) {
            valid = false;
            break;
        }
    }
    if (valid) {
        precise_collision_check = true;
        if (    collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_horizontal, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_vertical, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal4, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector4, precise_collision_check, true) == noone) {
            ds_stack_push(tile_stack_x, testpoint_x);
            ds_stack_push(tile_stack_y, testpoint_y);
        }
    }

    // below point
    testpoint_x = test_location_x;
    testpoint_y = test_location_y + 16;
    // Check point testpoint_x, testpoint_y is valid
    valid = true;
    // Check added location list first, then check stack because the same location stackd multiple times doesn't work
    for (i = 0; i < ds_list_size(tile_locations_x); i += 1) {
        if (ds_list_find_value(tile_locations_x, i) == testpoint_x && ds_list_find_value(tile_locations_y, i) == testpoint_y) {
            valid = false;
            break;
        }
    }
    if (valid) {
        precise_collision_check = true;
        if (    collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_horizontal, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_vertical, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonal4, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector1, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector2, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector3, precise_collision_check, true) == noone && 
                collision_rectangle(testpoint_x, testpoint_y, testpoint_x + 16, testpoint_y + 16,  obj_diagonalconnector4, precise_collision_check, true) == noone) {
            ds_stack_push(tile_stack_x, testpoint_x);
            ds_stack_push(tile_stack_y, testpoint_y);
        }
    }
}
ds_list_destroy(tile_locations_x);
ds_list_destroy(tile_locations_y);
ds_stack_destroy(tile_stack_x);
ds_stack_destroy(tile_stack_y);

这可能是我忽视的一些小问题;我只想要第二个意见。提前谢谢你的帮助!

-Neil

0 个答案:

没有答案