Attack Speed and Delay

Started by
7 comments, last by L. Spiro 6 years, 1 month ago

I was wondering what are the possible ways to create a concept of attack speed in an OO-coded game such that the entity can only attack another entity after a certain delay from the previous attack?

Advertisement

currentTime >= nextAllowedAttackTime

1 minute ago, Nypyren said:

currentTime >= nextAllowedAttackTime

Is it wise to add this field into a class like "warrior", or should this be handled somehow externally?

8 hours ago, vinstap said:

Is it wise to add this field into a class like "warrior", or should this be handled somehow externally?

I would think the warrior's next time to attack would belong to the warrior, yes.

I would also not use absolute time since that makes things like time dilation and pausing annoying at best.

17 hours ago, Satharis said:

I would also not use absolute time since that makes things like time dilation and pausing annoying at best.

Yeah.  In this case 'time' can be whatever measure of time is most appropriate for your game.  It could be number of frames (integer), simulation time in seconds (float), etc.

On 3/11/2018 at 3:41 PM, Nypyren said:

currentTime >= nextAllowedAttackTime

Usually this is handled in the opposite direction.

  1. Set time until next attack is available.
    1. m_iMsUntilCanAttack = 1000000; // 1 second.
  2. Decrease value each frame.
    1. m_iMsUntilCanAttack -= iMicroSecondsThisFrame;
  3. Can attack if timer is 0 or below.
    1. bool CanAttack() const { return (m_iMsUntilCanAttack <= 0); }

Since 0 is always the boundary you don't have to keep track of a 2nd data point, and since you always check against the numeric literal 0 the code should be faster.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

On 3/12/2018 at 2:50 AM, Satharis said:

I would think the warrior's next time to attack would belong to the warrior, yes.

I would also not use absolute time since that makes things like time dilation and pausing annoying at best.

Yea, you effectively want to negate all the time that accumulates when paused. I always use this psuedocode in my scripts when dealing with a pause invariant absolute time. It's useful to write as an abstract class so inheriting classes can easily access time.


float timePaused;
float totalTimePaused = 0f;
boolean paused;

GetTime(){
	if (paused){
		return timePaused - totalTimePaused;
	} else {
		return Time.fixedTime - totalTimePaused;
	}
}

PauseGame(){
	timePaused = Time.fixedTime;
}

UnPauseGame(){
	totalTimePaused += Time.fixedTime - timePaused;
}

 

1 hour ago, samoan62 said:

Yea, you effectively want to negate all the time that accumulates when paused. I always use this psuedocode in my scripts when dealing with a pause invariant absolute time. It's useful to write as an abstract class so inheriting classes can easily access time.



float timePaused;
float totalTimePaused = 0f;
boolean paused;

GetTime(){
	if (paused){
		return timePaused - totalTimePaused;
	} else {
		return Time.fixedTime - totalTimePaused;
	}
}

PauseGame(){
	timePaused = Time.fixedTime;
}

UnPauseGame(){
	totalTimePaused += Time.fixedTime - timePaused;
}

 

This is not the way to implement pausing.

Your game timer should be a 64-bit integer that is incremented by a given number of microseconds each frame.  When paused, don't increment it.  This means you have 2 timers, as the system timer can't be paused (and is mainly used for visual effects, or a timer for anything that can't be paused).

In the context of an attack, the concept is the same: Don't update the timer if the game is paused.

As I mentioned, these timers tick down towards 0 and expire when TIME <= 0.  Since there will be many timers in the game for specific objects, the easiest way to avoid lots of special-case code and to reliably ensure that the whole scene pauses is to wrap the logical update in LogicUpdate( uint64_t _uiDelta ) or Tick( uint64_t _uiDelta ).  While the game is paused, pass 0 for _uiDelta, and every timer in the scene will behave as expected.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement