1

I have a bone arrow image that rotates. If it reaches a certain timer I want it to stop rotating on one side and start rotating the other. If the other side reaches its timer it should goes back and forth, back and forth, like this short gameplay video.

I don't know why it stops when its timer2 turn at the end.

# in my main loop

if timer < 60:
    timer += 1
    bow.angle += 1
else:
    if timer2 < 80:
        timer2 += 1
        bow.angle -= 1
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Habib Ismail
  • 69
  • 5
  • 16
  • 1
    Are you restarting timer? Because when timer equals to 60 you need to restart it to 0 to go in if statement – K.Doruk Jan 05 '21 at 05:31
  • But if you actually want to do this forever (per your title), you should reset timers after timer2 reaches 80. Or else use % modulo. (But eventually timer will become a very long int.) So this doesn't fully answer the question. – smci Jan 05 '21 at 06:28
  • So you want `bow.angle` to go from 0 up to 60, then down to 40, then up to 60, down to 40..., right? – smci Jan 05 '21 at 07:35

2 Answers2

3

Use the muodulo (%) operator to change the direction by an certain interval:

At initialization:

timer = 0
dir = 1

In the application loop:

if timer >= 60 and timer % 20 == 0:
    dir *= -1
bow.angle += dir
timer += 1
if timer >= 100:
    timer = 60

Alternatively set the timer to 60 when it reaches 100:

if timer < 60:
    bow.angle += 1
else:
    bow.angle -= 1
timer += 1
if timer >= 80:
    timer = 40
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • If the OP actually wants to do this forever (per your title), you should reset timers after timer2 reaches 80. Or else use % modulo. (But eventually timer will become a very long int.) – smci Jan 05 '21 at 06:29
  • This is a memory leak. There is a very obvious downside of large integers that they take arbitrarily much memory, so if our target machine had 32b words, you'd overflow 2**31 ~ 2e9 in 68 years; but if you counted milliseconds, only 24.9 days. This is relying on [Python 3 doing arbitrary-length ints](https://stackoverflow.com/questions/7604966/maximum-and-minimum-values-for-ints), and also most architectures being 64b. But for realtime code on a 32b system this is sloppy and will bite you. (And obviously timer2 isn't needed, just one timer; I was writing this in terms the OP would understand.) – smci Jan 05 '21 at 07:19
  • Rabbid76 you meant `timer` not `timer1`. Also, I don't understand why you reset at 100, instead of the OP's (60+80)=140. And I think you want to reset to 0, per the OP *"go back and forth"*. – smci Jan 05 '21 at 07:28
  • @smci No I don't want to reset it to 0. I want to move it up to 60 an then change the angle in steps of 20. the code is fine and accepted. – Rabbid76 Jan 05 '21 at 07:29
  • Rabbi76 I'm not insulting you, the OP's intent is not clear, it only says *"go back and forth"* without specifying the periods. Seems they want bow.angle to go up to 60, then down to 40, then up to 60, down to 40. You could add a note explaining why you reset timer to 40. – smci Jan 05 '21 at 07:34
  • @smci Because it has to go alternately up and down by 20. – Rabbid76 Jan 05 '21 at 07:37
1

It stops because you aren't resetting timer or timer2. You need to reset them to zero after they are done making their movements. I also combined your else and if into an elif.

if timer < 60:
    timer += 1
    bow.angle += 1
elif timer2 < 80:
    timer2 += 1
    bow.angle -= 1
else:  # reset both timers
    timer = 0
    timer2 = 0
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
mazore
  • 984
  • 5
  • 11