I'm pretty new to blender and I'm trying to move an agent (in this case, a cube) randomly in bge. This is what my code looks like at this point:

import bge
import random
from mathutils import Vector

def main(): 
    cont = bge.logic.getCurrentController()
    owner = cont.owner
    function = cont.sensors["Always"]

    width = bge.render.getWindowWidth()
    height = bge.render.getWindowHeight()

    def set_object_pos(width, height): 
        owner.localPosition.x = random.randint(-1*width, width)*0.007
        owner.localPosition.y = random.randint(-1*height, height)*0.007

    current_frame = 0

    loopnumber = range(100)
    loopnumberlist = []
    for number in loopnumber: 

    for number in loopnumberlist: 
        set_object_pos(width, height)          
        print (owner.localPosition.x, owner.localPosition.y)
        current_frame += 1 
        number += 1

I just randomly created a loop because it would only print out 1 location no matter for how long the simulation ran. The problem I'm running into at this point is that the script will print out random locations but only moves the agent the first time the loop is run....any way to get the cube to move every time the loop is run? Or, better, is there any way to just call this function every frame? I thought using the Always controller would help but it hasn't worked that well...




I think you do not understand the concept of the BGE logic. In your Python code you describe the behavior within a single frame. This means it runs exactly once per game loop iteration.

Your loop will not executed "over time". It will run within one frame resulting in overriding the object location and printing to console 100 times. The effect is: 100 messages per frame and a waste of processing time (as only the last location change will be visible).


Design the code in a way that it describes ONE iteration rather than 100. Run the code when you want to change the location. This might be

  • constantly (Always with true level triggering),
  • at key press (keyboard sensor)
  • random interval (timer property + property sensor + random actuator) ...

here is a sample code - demo.py

import bge
import random

def setAtRandomPosition(): 
    if not allSensorsArePositive():
    owner = bge.logic.getCurrentController().owner

    owner.localPosition.x = random.randint(-10, 10)
    owner.localPosition.y = random.randint(-10, 10)

def allSensorsArePositive():
    for sensor in bge.logic.getCurrentController().sensors:
        if not sensor.positive:
            return False
    return True

call it with Module mode: demo.setAtRandomPosition

I hard-coded the limits from -10 to +10. You see this code is very simple as you only care one frame. How you keep the object within the camera frustum is up to you.

Try this with an Always Sensor [True Level Triggering] Frequency: 20 Always with Python controller

or use the keyboard sensor to set a new position at each press enter image description here

I hope it helps you


In the Always sensor, activate true level triggering. It is the most left button. Hover above it and you ll see.It will work afterwards.

  • $\begingroup$ oh wow, thank you so much! It works now :) Is there any way to change the speed at which it functions/slow down the framerate? $\endgroup$
    – 29374819
    Jul 17 '15 at 22:18
  • $\begingroup$ Add "bge.logic.setLogicTicRate(1.0)" below "current_frame = 0". Be careful it affects all the logic bricks. I guess there are tons of ways to do this. $\endgroup$
    – Lev
    Jul 17 '15 at 22:29
  • $\begingroup$ instead you can change the frequency of the always brick $\endgroup$
    – Chebhou
    Jul 17 '15 at 23:56
  • $\begingroup$ How do you do that? $\endgroup$
    – 29374819
    Jul 21 '15 at 17:34

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.