简体   繁体   中英

Difficulty understanding how data is passed

So I'm trying to have a strobe like effect on a game I'm building and the way I currently have it it's destroying my frame rate because the sleep function is also applying to the draw function. Can someone explain why this happens? And the logic that I'm failing to understand. Why can't I just have the return happen every .5 seconds without it affecting the .1 sleep I have in my hue function?

Here's a crude demonstration of what the code kind of does.

from random import randint
import time
def rand_intr():
    r = randint(1,256)
    time.sleep(.5)
    return r

def rand_intg():
    g = randint(1,256)
    time.sleep(.5)
    return g

def rand_intb():
    b = randint(1,256)
    time.sleep(.5)
    return b

def hue():
    r = rand_intr()
    g = rand_intg()
    b = rand_intb()
    print(r, g, b)
    print('test')
    time.sleep(.01)

while True:
    hue()

The sleep function blocks the main thread. This means rand_intg does not run until rand_intr "wakes up" from its sleep. Similarly, rand_intb has to wait for rand_intg , and hue has to wait for all the previous 3 functions. This means the total time hue has to wait before it can do any work is at least the amount of time needed to complete rand_intr , rand_intg , and rand_intb .

We can understand what is happening if we modify your example slightly and look at the output.

from random import randint
import time

def log_entry_exit(f):
    def wrapped():
        print("Entered {}".format(f.__name__))
        result = f()
        print("Leaving {}".format(f.__name__))
        return result
    return wrapped

@log_entry_exit
def rand_intr():
    r = randint(1,256)
    time.sleep(.5)
    return r

@log_entry_exit
def rand_intg():
    g = randint(1,256)
    time.sleep(.5)
    return g

@log_entry_exit
def rand_intb():
    b = randint(1,256)
    time.sleep(.5)
    return b

def hue():
    r = rand_intr()
    g = rand_intg()
    b = rand_intb()
    print(r, g, b)
    print('test')
    time.sleep(.01)

while True:
    hue()

Here I just modified your functions to print a message when we enter and exit each function.

The output is

Entered rand_intr
Leaving rand_intr
Entered rand_intg
Leaving rand_intg
Entered rand_intb
Leaving rand_intb
172 206 115
test
Entered rand_intr
Leaving rand_intr
Entered rand_intg
Leaving rand_intg
Entered rand_intb
Leaving rand_intb
240 33 135
test
...

Here, the effect of each sleep on hue can be seen clearly. You don't get to print the rgb values or "test" until the previous functions have completed.

What you can do is to call your hue function periodically using a timer callback, and then modify the rgb values according to some pattern. See this stackoverflow question on executing periodic actions for an example on how to periodically execute a function using a basic time-based mechanism.

Edit

Based on your comment to @jasonharper

If you call hue every 60 seconds, it does not make sense if your calls to the functions that generate the random rgb values occur at a faster rate because any changes in the intervening time will not be seen in hue .

What you can do is call hue every 60 seconds, then generate your rgb values to have whatever pattern in there.

Modifying the answer by @kev in the post I linked to above,

import time, threading
def update():
    # Do whatever you want here. 
    # This function will be called again in 60 seconds.
    # ...

    hue()

    # Whatever other things you want to do
    # ...

    threading.Timer(60.0, update).start()

def hue():
    r = rand_intr()
    g = rand_intg()
    b = rand_intb()
    print(r, g, b)
    # Don't call sleep.

if __name__ == "__main__":
    update()

Now you should only call update once , possibly in some startup part of your code and remove all the calls to sleep in your functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM