Delay sensor in python(UPBGE)

I wanted to know if it’s possible to create something like this.
just an example:

def Function():
    if def Function positive: 
        activate: Delay(like Delay sensor in logicbricks)            
            when Delay ends execute something: print("hello world")

this?


def delay(cont):
    
    own = cont.owner
    sens = cont.sensors['Delay']
    
    if sens.positive:
        #do stuff
    else:
        #do something when not positive

#edit

I am not sure that you can wait on a delay sensor, but you can make a timer and use that to time/delay things
anyway i think this is more in your direction.


def somethingthatispositive():
    return True

def delay(cont):
    
    own = cont.owner
    sens = cont.sensors['Delay']
    
    activated = somethingthatispositive()
    
    if activated:
        sens.activate()
    else:
        sens.deactivate()
1 Like

It would be nice to have checkbox in delay sensor which will activate\deactivate sending negative signal when delay ends. :slight_smile:

not exactly, I’m already using this method, I want to use only python,
I’m using the components in UPBGE

Then simply build yourself a timer and use that for the delay. Then you can do like:


if timer < 5:
    print('in delay waitingroom')
    return
elif timer >= 5:
    #outside waitingroom and do stuff when delay is passed

well, i did it, but is there any way to simplify this?

this code is a type of state change, I’m trying to convert most Logic Bricks to use in UPBGE components to use in my game

import bge
from collections import OrderedDict

class test(bge.types.KX_PythonComponent):
    args = OrderedDict([ ("", 0) ])
    def start(self, args):
        self.estado = 2 ## object state
        self.timer = 0
        self.timer2 = 0
    def update(self):
######### STATES ##########        
        def function1():
            print("state 1")
            if self.timer < 50:
                self.timer += 1
                return
            elif self.timer >= 50: 
                self.estado = 2
                self.timer = 0  
            
        def function2():
            print("state 2!")
            
            if self.timer2 < 50:
                self.timer2 += 1
                return
            elif self.timer2 >= 50: 
                self.estado = 1
                self.timer2 = 0             
###############################        
        list = {"1":function1,"2":function2}
        cmd = 0
        
        if self.estado == 1:
            cmd = "1"    
        if self.estado == 2:
            cmd = "2"          
       
        
        if cmd in list:
            list[cmd]()

UPBGE 0.2.3 Component module.test

it’s a class, anyway it depends on what you like/want.

i would do something like this:

def timer_handler(timer = 0, wait_time = 50)

    if timer < wait_time:
        timer + = 1
        return False
    elif timer >= wait_time:
        timer = 0    
        return True

and then simply pass the timer and waittime to it like:


timer1 = time_handler(self.timer1, 50)
timer2 = time_handler(self.timer2, 100)
1 Like

I just did it
code:

import bge
from collections import OrderedDict

class test(bge.types.KX_PythonComponent):
    args = OrderedDict([ ("", 0) ])
    def start(self, args):
        self.estado = 2
        self.timer = 0
    def update(self):
######### STATES ##########        
        ####### delay function
        def delay_state(x, timer, object_state):
            if self.timer < x:
                self.timer += 1
                return
            elif self.timer >= x: 
                self.estado = object_state
                self.timer = 0  
        
        
        def function1():
            print("state 1")
            delay_state(50, self.timer, 2)
            
        def function2():
            print("state 2!")
            delay_state(50, self.timer, 1)
                     
###############################        
        list = {"1":function1,"2":function2}
        cmd = 0
        
        if self.estado == 1:
            cmd = "1"    
        if self.estado == 2:
            cmd = "2"          
       
        
        if cmd in list:
            list[cmd]()

1 Like

you can shorten your state machine as well:


        list = {"1":function1,"2":function2}

        cmd = self.estado
        if cmd in list:
            list[cmd]()

I tried this but it does not seem to work

hmm should work, try this:


        list = {"1":function1,"2":function2}

        cmd = self.get('estado', 0)
        if cmd in list:
            list[cmd]()

Not sure if you can grab atributed with get() function, but it will try to grab estado, if it can’t grab it it will use the default value indicated here as 0

1 Like

I made all references to Estado become strings, now it’s working
current code:

import bge
from collections import OrderedDict

class test(bge.types.KX_PythonComponent):
    args = OrderedDict([ ("", 0) ])
    def start(self, args):
        self.estado = "2"
        self.timer = 0
    def update(self):
######### STATES ##########        
        ####### delay function
        def delay_state(x, timer, object_state):
            if self.timer < x:
                self.timer += 1
                return
            elif self.timer >= x: 
                self.estado = object_state
                self.timer = 0  
        
        
        def function1():
            print("state 1")
            delay_state(50, self.timer, "2")
            
        def function2():
            print("state 2!")
            delay_state(50, self.timer, "1")
                     
###############################        

        list = {"1":function1,"2":function2}

        cmd = self.estado
        if cmd in list:
            list[cmd]()
        
        
1 Like

Note that your timer doesn’t take timescale into account. If you slow down or speed up the simulation, it’ll still tick at the same rate.

NINJAEDIT: yikes! I forgot to add the formula.

self.timer += 1*bge.logic.getTimeScale()
1 Like

Thank you Liebranca.

this is pretty easy to do.

example.

import time

class Delay:
    def __init__(self,delay):
        self.start = time.time()
        self.delay = delay
        
    def get(self):
        now = time.time()
        delta = now - self.start
        
        if delta > self.delay:
            return True
        else:
            return False
        

delay = Delay(2)

while True:
    d = delay.get()
    
    if d:
        print("Done!")
        break