1
$\begingroup$

I have the following script(pistonMover.py) which runs in the Blender "game engine" mode and I want to stop the game engine when posdiff is less than 0.0001.

import bge
import COM
import time as t

def calc_com():
    obj_list_real = []
    for item in bge.logic.getCurrentScene().objects:            
        try:
            if item.name.startswith('Cube') and item.name != 'Cube.004':
                temp_dict = {}
                temp_dict['x'] = item.worldPosition.x
                temp_dict['y'] = item.worldPosition.y
                temp_dict['z'] = item.worldPosition.z                   
                temp_dict['mass'] = item.mass
                #temp_dict['name'] = item.name
                obj_list_real.append(temp_dict)
            if item.name.startswith('obj_'):
                temp_dict = {}
                temp_dict['x'] = item.worldPosition.x
                temp_dict['y'] = item.worldPosition.y
                temp_dict['z'] = item.worldPosition.z                     
                temp_dict['mass'] = item.mass
                obj_list_real.append(temp_dict)
        except AttributeError:
            pass    
    com = COM.COM(obj_list_real)
    return com

def getPistonpos():
    pistonpos = 0
    for item in bge.logic.getCurrentScene().objects:
        if item.name == "Cylinder":
            pistonpos = item.worldPosition.y
            break
    return pistonpos

def main():
    cont = bge.logic.getCurrentController()
    player = cont.owner
    scene = bge.logic.getCurrentScene()
    keyboard = bge.logic.keyboard
    player.localPosition.y -=0.1
    pistonpos = 0
    flag = False
    try:
        pistonpos = bge.logic.globalDict['pistonpos']
        flag = True
    except KeyError:
        bge.logic.globalDict['pistonpos'] = getPistonpos()
    posdiff = abs(getPistonpos() - pistonpos)
    if posdiff < 0.0001 and flag:
        print(posdiff)
    bge.logic.globalDict['pistonpos'] = getPistonpos()
    if bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.DOWNARROWKEY]:
        calc_com()



main()

I have tested this script and works perfectly but, I was unable to find a way to stop game engine anywhere. Also, I invoke this script using bpy.ops.wm.blenderplayer_start() from Blender in "render mode" using another script called "renderer.py". I want to do this since I want to run this simulation for 100 times and as I said, I want to stop it upon reaching a condition in every simulation. Here's how my game logic looks like. enter image description here Thanks in advance!

$\endgroup$
3
$\begingroup$

It's very simple, you just have to connect a Game Actuator to your script Controller and set it to "Quit Game".

Add this actuator to your script by doing this:

gameactu = cont.actuators['Game']

if posdiff < 0.0001: # You can also try 0.0002
    cont.activate(gameactu) # I just try it works.

Here a picture:

Quit game

You can do this without the Actuator, see the manual.

$\endgroup$
1
$\begingroup$

... Or just call bge.logic.endGame() ...

Be mindful that the game will take a few secs to close, so unless you do something like:

d = GameLogic.globalDict
if 'shutdown' in d:
    print('Shutting down...')
    bge.logic.endGame()
else:
    *Your code here*
    if <its time to quit>:
        d['shutdown']=True 

your code might run again.

$\endgroup$
  • 1
    $\begingroup$ thanks, this very simple but elegant answer has really gotten buried. $\endgroup$ – Frederick Aug 2 at 0:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.