Jump to content
  • Advertisement

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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;
}

 

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!