end list

How would i endObject what is in the list when i get a certain distance?

import bge




cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = scene.objects ["player"]




own = cont.owner




list = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]




prop = own['boolean_property'] 




if not prop and own.getDistanceTo(player) > 29:




    for i in range(len(list)):   
           
       obja = scene.addObject("lung", player, 0)
       obja.worldPosition = list[i]
    
    own['boolean_property'] = True
    
if not prop and own.getDistanceTo(player) > 30:




    for i in range(len(list)):   
           
       obja = scene.endObject("lung", player, 0)
       obja.worldPosition = list[i]
    
    own['boolean_property'] = True
    

your example code is very weird…


for obj in container:
	if obj.getDistanceTo(player) > 30:
		obj.endObject()

Your little snippet does not end all the added lungs.When getting to a distance thirty.

Try storing the objects you spawn in a list, so when you use a for loop, instead of trying to end objects at worldPositions, you end objects in your actual object list.

You can start like this:

if "objList" not in owner:
    owner["objList"] = []

Then, while you’re adding objects, you can insert those objects into the list:

owner["objList"].append(scene.addObject("lung", player, 0))

Then, for the last for loop you do, you can have:

objList[i].endObject()

You mean >=30 instead of >30?
you know u can also print in the for loop the distances…

Don’t forget to manage your list if you’re deleting things in it. Otherwise you end up with lots of zombie references.

next_gen =[]
for ob in my_list:
    if ob.getDistanceTo(own) <=30:
        ob.endObject
    else:
        next_gen.append(ob)
my_list=next_gen

Note that my solution is sufficient for only working once, as was yours; if you need to further continue with the process of adding objects/checking distances, you will need to revise your solution further.

At that stage I strongly suggest to split your code. Here you do not only get two different evaluation behaviors (measuring two different distances. You perform two separate operation as well (adding and ending lungs). The code becomes really complex.

I suggest to switch to module mode and establish various functions that encapsulate the different operations.


module “lungManager.py”


import bge


#bge callable - run it via Module: lungManager.manageLungs
def manageLungs(controller):
   if isJustInCreationDistance():
       createLungs()
   
   if isJustInDeletionDistance():
       deleteLungs()


With that you look from a very high level on what should happen. The details are encapsulated into the different functions at a different place (typically at the same module, but they could be at an imported module too).

Here I would say … have fun implementing isJustInCreationDistance(), isJustInDeletionDistance(), createLungs(). You already have the according code.

But I know you are just confused right now. Therefore I show you samples.

Creation distance evaluation

 
def isJustInCreationDistance():
    owner = bge.logic.getCurrentController().owner
    player = owner.scene.objects["player"]
    currentStatus = owner.getDistanceTo(player) > 29
    lastStatus = owner.get("last creation distance evaluation", False)
    owner["last creation distance evaluation"] = currentStatus
    
    return currentStatus and currentStatus != lastStatus    

You might remember this looks pretty much the same as in post python code suddenly stopped working.

As you have at least to distance checks you need to use different internal properties (otherwise you would not be able to differentiate between the two stored evaluation states).

Indeed the code looks a bit complicated, but it runs as it is. It just needs a “import bge” statement.

Deletion distance evaluation
Now have a look at the second evaluation:


def isJustInDeletionDistance():
    owner = bge.logic.getCurrentController().owner
    player = owner.scene.objects["player"]
    currentStatus = owner.getDistanceTo(player) > 30
    lastStatus = owner.get("last deletion distance evaluation", False)
    owner["last deletion distance evaluation"] = currentStatus
    
    return currentStatus and currentStatus != lastStatus

This code looks pretty much the same as the code for creation distance evaluation. The differences are:

  • different distance to check (30 rather than 29)
  • different property name (“last deletion distance evaluation” rather than “last creation distance evaluation”)

With a bit of redesign could merge these two functions into a single one with arguments. But this is not what I wanted to show. I wanted to show that even when this “lower level” function looks complicated, you “higher level” funciton stays very simple and still expresses what should happen.

But lets continue to the next function.

Creating Lungs
my first approach is very simple.


def createLungs():
    print("create lungs")

This allows me to test if the code gets called at all (so I can test to above functions). When I’m sure it gets called as I want I can start detailing how to create lungs. Again you already did that in the mentioned thread (called actator part). So lets put it into the function.


def createLungs():
    owner = bge.logic.getCurrentController().owner
    player = owner.scene.objects["player"]

    positions = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]

    reference = player 
    for i in range(0, len(positions)):      
        addedLung = reference.scene.addObject("lung", reference, 0)
        addedLung.worldPosition = positions[i]

The benefit is the “creation” code is isolated from the distance chakes or anything else. So oyu can focus on what the code should do … create lungs.

Deleting Lungs
Here we do the same thing - test with a simple implementation


def deleteLungs():
    print("delete lungs")

How to implement that I explain with the next post.

First we need to think about what we want to do. As the name indicates we want to-> delete the lungs

According to your first approach

You would look for any object called “lung” and end it.

So lets shape this code into a proper and working form:


def deleteLungs():
    objects = bge.logic.getCurrentScene().objects
    lungs = [object for object in objects if object.name == "lung"]
    for lung in lungs:
        lung.endObject()

I suggest you test it. You will see it works perfectly fine. All lungs are gone.

You might noticed that I made an assumption while reading your code. I assumed you want to remove ALL lungs. But I do not know if that is what you really want.

So here is the question that i should have asked at the first place:

What lungs do you want to delete? If not all of them, how to differentiate?

Really i am trying to figure out how and endless runner videogame works.So i need all of them to delete.

I set it up how said.It says there is no module lungManager.Here is the blend.

Attachments

vectored plan.blend (498 KB)

Really i am trying to figure out how and endless runner videogame works.So i need all of them to delete.

This depends on what kind of runner, the most common one is very easy to setup.

In basic terms it goes like this:
Your player stands still on the spot and can only move to the left and right side.
you create a tunnel, lets say 50Bu long 10bu width and place the player a bit inside it.
Now you place a empty at the end of the tunnel, give it an animation or whatever to let the empty move up and down (within the tunnel height/width) not in the length.
This empty you let it spawn random objects (the objects the player need to avoid).

that is the very basic version.

Now that you have that setup, you can (simply) tell the addObject actuator that you place on the empty to kill the object in lets say 300 ticks.
Only thing you need now is a collision on the player, and when it collide with an object you end the player and call up the score screen.

I mean a 3d endless runner videogame.

This is a trap I often felt into.

When you get such a message have a very close look at the data it presents. It says:


Python module can't be imported - object 'Empty', controller 'Python':
ImportError: No module named 'lungManager'

Then look at the availabel Python files to find a <module name>.py file.

You have

  • “these are lungs”,
  • “Text” and
  • “lungManger.py”

That is why you need a close look. The filename is missing an “a”.

Remarks:

  • There is no game object called “player”. So you will discover other errors as the code assumes you have one in the same scene (owner.scene.objects[“player”]).
  • You need to add the other two functions [createLungs(), deleteLungs()] to the module

The above solution is simpel and does what you want.

I expected you say “end the lungs this object added before … because other objects will add lungs too”. When you want this in future so let us know. We will discuss it at that time.

I put everyting in the blend and someone edited it.Like they have deleted my posts before.

I did not put all the code on the same script.I could call the the function with module mode.I saw someone do that on youtube.