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$

2 Answers 2

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$
0
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
  • 1
    $\begingroup$ thanks, this very simple but elegant answer has really gotten buried. $\endgroup$
    – Frederick
    Commented Aug 2, 2019 at 0:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .