Can AI be cleared by using the bricks after a task has been completed?


(Cotaks) #21

i would change it a tiny bit


cont = bge.logic.getCurrentController()

enemies = [object for object in own.scene.objects if 'enemy' in object]

if not range(len(enemies)):
    print('-! All enemies have died')

making use of the build-in mechanics (faster)

or even without range check:


cont = bge.logic.getCurrentController()

enemies = [object for object in own.scene.objects if 'enemy' in object]

if not enemies:
    print('-! All enemies have died')

but then again you would loop trough all objects every frame so better to update when needed


def update_enemies(cont):    
    
    own = cont.owner
    own['enemy_list'] = [object for object in own.scene.objects if 'enemy' in object]


def check_for_enemies(cont):
    
    own = cont.owner
    
    if not 'enemy_list' in own:
        update_enemies(cont)
        
    if not own['enemy_list']:
        print('-! All enemies have died')
    
    elif own['enemy_list']:
        print('- There are some enemies left\n-> ' + str(own['enemy_list']))

Now it’s build for single or true pulse, and you can update the enemies when needed, when you add more or when you kill an enemy. (or simply remove the killed enemy from the list, list.remove(object) and you only have to update it when you add new/more enemies)


(modelinblender) #22

So how could try this code, I select a cube object of my AI, and then what exactly, paste the code into a text file?


(Liebranca) #23

Create the text file, paste the code. If you link the text file to a python controller, the code will be executed on each positive tick of any sensors connected to it.
Python controllers can be run in two modes: script and module.
Script runs the entire code. So just select the textfile with the code you want to run.
Module runs only a single definition (def). You have to specify name of textfile and definition, like so

NINJA EDIT: you have to save the textfile with .py extension (eg textfile_name.py) to run it in module mode.


(modelinblender) #24

I tried checkenemies.py as seen, not sure what is suppose to exactly occur, once the AI has been removed, there is no change in the scene, only one AI has the code linked, that shouldn’t

matter?


(Liebranca) #25

Hi, I just randomly hopped in the thread and decided to throw in an example on python controller basics because why not. All that snippet does is generate a list of objects with property “enemy” and print out to console whether any such objects exist within the scene.

If the object running the code is ended, code stops running.
You want to check your enemy count/win conditions on a separate object, that won’t be deleted by the player shooting at it, so that it continues to execute for the duration of the level.

Totally bruteforce, one can totally do,

if not own['enemy_list']:
    bge.logic.getCurrentScene().replace("NameOfNextScene")

But then you’re swapping scenes instantly, as soon as all the AI has been cleared. No complex win condition or “playerone you’re awesome” popups or whatever.

Honestly just give python a spin, it’s easy. If you can make an idea of what the script is doing that makes life better.


(modelinblender) #26

I don’t know python, that was why i started this thread to see if it was possible using the bricks.

Somebody on here helped me with one file using python, didn’t have the exact result I hoped for, but never mind, it has worked with a few effects missing.

I need a program that does what I need to do in order to get a mission mini game working, with that example I can use that to may be add or edit an existing file.

Thanks.


(Cotaks) #27

better to use:own.scene.replace('win_screen')
No need to use the bge module.

@modelinblender
This is a global check script, put it on an empty, not on enemies/player (on something that is not kill able).

if you add enemies before game start, then you should run this in true pulse.
if you want a check mechanism, like pressing a button before checking, then put it on the button in single pulse.

so empty->always true->scriptname.check_for_win_conditions (added lose check as well)
every enemy needs a property ‘enemy’ (no quotes), player needs property ‘health’. Add 2 scenes ‘win_screen’, ‘lose_screen’.

if you kill all it will replace the game scene with the ‘win_screen’ scene. if player gets killed it will replace the scene with ‘lose_screen’.


def update_enemies(cont):    
    
    own = cont.owner
    own['enemy_list'] = [object for object in own.scene.objects if 'enemy' in object]


def check_for_win_conditions(cont):
    
    own = cont.owner
    
    #enemies
    if not 'enemy_list' in own:
        update_enemies(cont)
        
    if not own['enemy_list']:
        print('-! All enemies have died')
        own.scene.replace('win_screen')    
    
    elif own['enemy_list']:
        print('- There are some enemies left\n-> ' + str(own['enemy_list']))
        
    #player
    player = own.scene.objects['player']
    
    if player['health'] <= 0:
        print('You died! you lose...')
        own.scene.replace('lose_screen')

(modelinblender) #28

Okay, I have the windows 10 system on, I will try this right now.


(modelinblender) #29

Hmm, I guess there is no need for anything on the AI or FP to get into a new scene?

I called the new scene win_screen

Obviously I have done something right, I tried the pulse on the always no change, and even before adding the scene bricks, which I don’t need.


(Cotaks) #30


(modelinblender) #31

I made a few changes, must the name be exact of the script name? Or well change to checkenemies. etc instead of simply checkenemies?

Tried the name changes, no change, and sure I have the two different screens available. Player has the property, and enemy has the property.


(Cotaks) #32

In script the def … don’t change that put that text in the python module, exactly how i drawed on the screenshot, outlining those parts where meant as an indication, you combine that the and get the python name. so do what arrows say not the thin lines.and restore the scriptname as well


(modelinblender) #33

I have done what is displayed.


(Cotaks) #34

in script, remove the checkenemies. at def…


(modelinblender) #35

def check_for_win_conditions(cont):

This is what is should be, well that hasn’t changed the file.


(Cotaks) #36

hit window, toggle system console, copy/paste to here


(Cotaks) #37

Here a working example.
check_for_win_conditions.blend (505.9 KB)

i did remove this part:


    elif own['enemy_list']:
        print('- There are some enemies left\n-> ' + str(own['enemy_list']))

Because you don’t need it and it keeps printing that there are enemies left, so better of without that part.


(modelinblender) #38

I removed the code, no change. I have also tried your example file, I start the engine, but nothing seems to happen, left click button? Well okay removed the number, and it loads, but for my example not sure how to solve the problem.

Could there be a conflict with the bricks in the file and the code?


(Cotaks) #39
def update_enemies(cont):    
    
    own = cont.owner
    own['enemy_list'] = [object for object in own.scene.objects if 'enemy' in object]


def check_for_win_conditions(cont): 
    
    own = cont.owner
    
    #enemies
    update_enemies(cont)
        
    if not own['enemy_list']:
        print('-! All enemies have died')
        own.scene.replace('win_screen')    

    #player
    player = own.scene.objects['FP']
    
    if player['health'] <= 0:
        print('You died! you lose...')
        own.scene.replace('lose_screen')

i removed this, you need to update it every frame.


if not 'enemy_list' in own:

Also script name is wrong, player name is wrong as well, fix that, replace code with above and it works, don’t forget win/lose screen needs a camera and render set to game engine.


(modelinblender) #40

checkenemies. check_for_win_conditions.py

That is the script name^

Player is player and enemy is enemy, a property is all that is needed?

checkenemies.check_for_win_conditions is in the module, as for frame?

Does the script need to be assigned to the cameras? I tried an always and module brick, no change in that,

Not sure what is error with this.