How to add objects once in range from dictionary?

OpenWorlds.zip (379.6 KB)
Got the blend file up for whenever you have time to look at it. I tried to integrate code you posted, but it broke the file.

You reference the object again later using own[‘Grid’] after they are deleted.

Instead use own[‘Data’] and kdtree index and the kdtree returned point

Um what does that mean?

I looked at your file and can’t figure out what you are trying to do with all the emp cubes.

please try and make a min file with just the minimum of what you need.

what should happen

1.on init we build a tree of objects and save a list of the data from these objects
we delete these objects at this step*

2.after this we use the tree to get the data that was stored in the object back from the list we store fill the stuff the object we deleted had stored in it.

Okay I will work on that and add notes to the script too

Finished
OpenWorld_Object_manger.zip (382.7 KB)

What I am trying to do is make a way to make an Openworld game. The file works right, but is not efficient enough to to that. Basically this file is the kx_tree_bubble script mixed with the pooling script you made and a data retrievement system I made.

the blue glowing blocks every are quick testers to see how many objects the world can hold. Your kx_tree_bubble example only used emptys in the editor , but its hard to build a world like that so only at runtime I turn all the object in the scene I want into emptys with the contains_data in them but that slows down the game with dephgraph. So I was wondering how to just leave out the emptys and take the data out of the contains data in a range of the objects world position read from a dictionary the code above you posted seemed like the idea of what I want so I tried to edit your kx_tree_bubble to do use it but it doesn’t work. everytime it gets to the Tree part after deleting object there is an error, data has been freed, if I put own[‘Data’] inside of own[‘Grid’] I get an error. Is there a way to edit you kx_tree_bubble to leave out the emptys and just read from the contains_data stored in script?

    data = []
    for ob in own.scene.objects:
        if 'Contains_Data' in ob:
            if 'EMP' not in ob:
                grid.append(ob.worldPosition)
                data.append( ob['Containts_Data'])
                ob.endObject()
       
    own['Data']=data
    
    Tree =kdtree.KDTree((len(grid)))
    i=0
    for point in grid:
        Tree.insert(point.worldPosition  ,i) # < This part
        i+=1
    Tree.balance()
    own['Grid']=grid
    own['Tree']=Tree
    
    own['Filled']={}

Everytime I run this I get this error

Blender Game Engine Started
Error: Python(Cube), Python script error
Traceback (most recent call last):
  File "gamelogic_simple.py", line 102, in <module>
  File "gamelogic_simple.py", line 60, in main
AttributeError: 'Vector' object has no attribute 'worldPosition'
Blender Game Engine Finished

I have tried to fix it but have no idea what I am doing does anyone know how to fix this?

The vector is the world position already.

1 Like

Okay I fixed that error thank you, but once I get to the Else statement in the kx_bubble file it tells me TypeError: ‘int’ object is not subscriptable
(I am trying to edit it to read from contains_data without the emptys)

Got rid of the errors in the console but the script does not work quite right with the near part.

import bge,ast
from mathutils import kdtree, Vector 


def main():
    
    cont = bge.logic.getCurrentController()
    own = cont.owner
    if 'Grid' not in own:

        grid = []
        data = []
        for ob in own.scene.objects:
            if 'Contains_Data' in ob:
                grid.append(ob.worldPosition)
                data.append(ob['Contains_Data'])
                ob.endObject()
        own['Data']=data 
                  
        Tree =kdtree.KDTree((len(grid)))
        i=0
        for point in grid:
            Tree.insert(point  ,i)
            i+=1
        Tree.balance()
        own['Grid']=grid
        own['Tree']=Tree
        
        own['Filled']={}
    else:
        R = 8
        near = own['Tree'].find(own.worldPosition) 
        if near[2]<R*.7:   

            if near[1] not in own['Filled']:
                own['Filled'][near[1]]=[]
                data = own['Data'][near[1]]
                data = ast.literal_eval(data)
                
                for obj in data:
                    added = own.scene.addObject(obj[0],own.scene.objects['Empty'],0)
                    added.worldPosition = near[0] + Vector(obj[1] )
                    own['Filled'][near[1]].append(added)

                      
        elif near[2]>R*.8:
            if near[1] in own['Filled']:
                for obj in own['Filled'][near[1]]:
                    if not obj.invalid:
                        obj.endObject()
                del own['Filled'][near[1]]         


main()

The objects spawn strange

What’s the difference between kdtree.find_range() and kdtree.find()?

Find is only 1 point(closest)

Find_range() is all points in a radius returned in order of distance

1 Like

Oh that explains it. The code above works almost perfectly
except for the near = own[‘Tree’].find(own.worldPosition) acts differently
from the near = own[‘Tree’].find_range(own.worldPosition,R) first script.

.find = 1 position/tile closest to player/mouseclick or whatever you use
.find_range = list with muliple positions/tiles in a radius from your player/mouseclick or whatever you use

Also keep in mijnd with .find_range the corner tiles are further away, so if you want to include that then range 1 should be range 1.49 (little less then 1.5x tile size)so you are 100% sure to grab corner tiles aswell. (1 unit north-east is a lil bit bigger then 1 unit north )

1 Like

Thank you. Does anyone know how to fix
'<' not supported between instances of 'tuple' and 'float'
That error pops up everytime I switch the .find and .find_range in the code.

tuple = a list like [1,2,3,4] (.find_range)
float = 0.123456 (.find)

you can’t compare the two you need to subtract data from the list first.

list_a = [1,2,3,4]
print(list_a[1])

outcome is 2 (0= 1, 1=2, 3= 4, etc)

1 Like

Thanks soon much @BluePrintRandom @Cotaks and @Musa for all of the help I have finally got it working properly!

1 Like