Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Timer to control rate of fire

Author
Message
Anruth
15
Years of Service
User Offline
Joined: 20th Dec 2010
Location:
Posted: 18th Aug 2013 10:57
I'm tring to use the timer to control the rate of fire.
Not sure why this code isn't working.

Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 18th Aug 2013 13:06 Edited at: 18th Aug 2013 13:06


Anruth
15
Years of Service
User Offline
Joined: 20th Dec 2010
Location:
Posted: 19th Aug 2013 21:15
Yep, that worked. Just some faulty logic om my part.

Thanks Mage.
Anruth
15
Years of Service
User Offline
Joined: 20th Dec 2010
Location:
Posted: 19th Aug 2013 21:15
Yep, that worked. Just some faulty logic on my part.

Thanks Mage.
MrValentine
AGK Backer
15
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 20th Aug 2013 13:41
Nice work mage!

Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 21st Aug 2013 09:20 Edited at: 21st Aug 2013 09:26
I should have mentioned that the code will fail if the game is left running too long without firing. Such as if the game was left paused overnight or perhaps a day or 2 longer then that. Or if the computer is put into sleep mode / hibernate for that length of time.

I am talking about a roll over to 0 and not the negative number glitch. I off hand can't remember how long it takes the timer to roll over to 0.

Anyway you can end up in situations where Timer() is less than the last firing time. If this happens then you'll need to wait several days before you can shoot again, otherwise restart the game.

You can add ABS() to the computation to prevent this from happening.



I chose not to mention this before since some people swear against using abs() in time computations. I didn't want to get into another squabble with someone.

Glad I could help.

Chris Tate
DBPro Master
17
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 21st Aug 2013 14:37 Edited at: 21st Aug 2013 14:44
It seems the Timer() function draws the time from when the system was turned on. Therefore what the Mage pointed out could cause the issue if the system had been running for many days.

2147483647 is the maximum positive return value for the system time in integer form; which amounts to 596 hours, which is 24 days. I'm not sure of many people who leave the PC on for that long; even servers need a regular reboot to refresh themselves; however perhaps there are people who leave their PC's on for 24 days, and if they run your program on the 59th minute of the 23rd hour of the 23rd day then they might hit some trouble.

I do not know if the timer continues to tick while hibernating; something I have not tested .

I always thought the Timer() rolls back to -2147483646 due to the issue that occured with this persons DBP program.

The ABS solution sounds interesting; my current solution was to prompt the user to reboot the system before commencing with the game an hour before the roll over.

Although I indeed use the method Mage uses; written this way:



Sometimes the Matrix1 ticker is prefered:





Two advantages of the manual approach is that the delay can be used in expressive calculations; and do not share the 214400 or so ticker limit (I believe it is).

The good thing about tickers is their object orientated nature; being able to share the ticker with other objects rather seamlessly.

Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 21st Aug 2013 17:12 Edited at: 21st Aug 2013 17:13
Small Correction: The code fails on the negative number rollover and not the 0 rollover. The > operation treats negative timer() as truly negative. So if last fire time is still positive, it'll be many days before you can fire again.

ABS() does correct the issue. But both methods can be exploited by players using any available pause feature the game might have.

Best choice for a pro game, use a counter that counts up using TBM code. Reset/Zero the TBM code before resuming gameplay.

Thanks for looking into it.

Chris Tate
DBPro Master
17
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 21st Aug 2013 17:34
Yeah that's true

Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 21st Aug 2013 21:12 Edited at: 21st Aug 2013 21:27
hyper-coding* solution:

This version doesn't use the timer.

*hyper-coding — modifying perfectly good code to produce interesting, but not necessarily better, alternatives.

[edit]

With a bit of maths juggling we could change:
k= keystate(fireKey)*(k+1) - (k>fireRate)*k
to
k= keystate(fireKey) + k*(keystate(fireKey)-(k>fireRate))
Cutting out a multiplication, but adding an extra keystate() call.



The gluteus-maximus mammary-gland formally known as OBese87.
Chris Tate
DBPro Master
17
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 21st Aug 2013 22:46
Interesting... Looks like my viewport editor camera movement procedure.

So how could that be used to limit the fire operation to 10 shots per second for instance?

Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 22nd Aug 2013 01:11 Edited at: 22nd Aug 2013 04:22
Quote: "So how could that be used to limit the fire operation to 10 shots per second for instance?"

With a bit of head scratching and code alteration.




The gluteus-maximus mammary-gland formally known as OBese87.
Chris Tate
DBPro Master
17
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 22nd Aug 2013 02:32
Fair enough

Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 22nd Aug 2013 05:18
lol there's that timer again.

MadBit
VIP Member
Gold Codemaster
17
Years of Service
User Offline
Joined: 25th Jun 2009
Location: Germany
Posted: 22nd Aug 2013 10:28
Hmm, this looks like a contest

I've modified Libervurto entry, to check an overflow of the timer and a little bit more. I work ever with elapsed time per frame to control movements, shot rates and others. If you pause a game you must set only elapsed_time to zero.

Her my entry:


Share your knowledge. It's a way to achieve immortality. (Tenzin Gyatso)
Pixie-Particle-Engine
Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 22nd Aug 2013 12:04
Quote: "I've modified Libervurto entry, to check an overflow of the timer and a little bit more. I work ever with elapsed time per frame to control movements, shot rates and others. If you pause a game you must set only elapsed_time to zero."

You both are very clever, and gave good helpful examples.

But... your approach with the elapsed time reset is not a good idea in practice. This code is likely going to be buried in the bowels of your program and there is likely to be other controls with timing variables also.

The problem comes when you un-pause the game and you suddenly have all these variables hiding everywhere that need to be reset. There is no elegant way to tell this piece of code (which is likely in a separate function) that the game was just un-paused. You'd need some sort of hack job to do it. You are setting up an inelegant system by doing this.

You need to reset your TBM code when un-pausing anyway or everyone and thing will lag jump through walls, etc. So calculate elapsed time by using the TBM code. It wraps things up perfectly.

Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 22nd Aug 2013 12:07 Edited at: 22nd Aug 2013 12:09
Anyone thought of using Dword?

Also, Timer() can be inaccurate, use IanM's Matrix Hitimer() instead

"Get in the Van!" - Van B
Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 22nd Aug 2013 12:46 Edited at: 22nd Aug 2013 12:49
Couldn't you just do this for unpausing, seeing as when you pause the problem is that last record time to the current time would become huge so just don't pause the times. Instead keep them the same meaning that there's Zero difference between them and everything would move at a rate of Zero when paused, and when unpaused the difference between frames would be the same as if it was never paused.



Also note that Hitimer() starts from 0

"Get in the Van!" - Van B
Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 22nd Aug 2013 13:28
I'm not able to test you code at this time.

However, the problem is this code isn't likely to be in the same area of the program as the code pausing/un-pausing the game. Getting a message to this function that the game was just un-paused is a problem.

TBM code is supposed to correct this kind of problem. One reset globally fixes all timing issues.

Sasuke
20
Years of Service
User Offline
Joined: 2nd Dec 2005
Location: Milton Keynes UK
Posted: 22nd Aug 2013 13:42 Edited at: 22nd Aug 2013 13:57
It wouldn't matter where you set it up, as long as on pause the next frame time calc reads:

newTick = hitimer()
lastTick = newTick

and when unparsed it's goes back to normal:

lastTick = newTick
newTick = hitimer()



Edit: Better Code, whats good there is you can have different rates of speed using getTMB and setting it's factor. That way you could slow down only part of a scene why everything is moving normally and many other things you could do with different TMB's rates

"Get in the Van!" - Van B

Login to post a reply

Server time is: 2026-07-08 01:54:17
Your offset time is: 2026-07-08 01:54:17