Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualKhatharr

Posted 26 January 2013 - 12:15 AM

I anticipated your animation speed problem when I was making my previous post but figured I'd wait until you asked. (It's the next issue to arise in the logical order of what you're doing here.)

 

Simply use an animation step that is a multiple of the number of your animation frame count and then select the frame by integer division. This is going to get progressively more difficult if you don't either rearrange your sprite sheet or else abstract the positioning so that you can refer to the direction and animation separately. This function is already really big.

 

Check this out:

enum DIRECTION {
  DIR_DOWN = 0,
  DIR_LEFT,
  DIR_RIGHT,
  DIR_UP,
  DIR_NONE
};

const int ANIMATION_FRAMES = 4;
const int ANIMATION_RATE = 15; //play with this number to control animation speed
const int ANIMSTEP_MAX = ANIMATION_FRAMES * ANIMATION_RATE;

DIRECTION dir4(Uint8* keystate) {
  if(keystate[SDLK_DOWN])  {return DIR_DOWN;}
  if(keystate[SDLK_LEFT])  {return DIR_LEFT;}
  if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
  if(keystate[SDLK_UP])    {return DIR_UP;}
  return DIR_NONE;
}

DIRECTION direction = DIR_DOWN;
int animstep = 0;

static void player_movement(void) {
  //This should really be called from outside and handed in.
  //You want the same control state for the whole logical frame.
  Uint8* keystate = SDL_GetKeyState(NULL);
  DIRECTION dir = dir4(keystate);
  if(dir == DIR_NONE) {
    animstep = 0;
    return;
  }
  direction = dir;
  ++animstep;
  animstep %= ANIMATION_MAX;
  switch(direction) {
    case DIR_DOWN:  player_y += speed; break;
    case DIR_UP:    player_y -= speed; break;
    case DIR_RIGHT: player_x += speed; break;
    case DIR_LEFT:  player_x -= speed; break;
  }
}

After running player_movement your direction will be in 'direction'.
The frame of animation to render for that direction will be 'animstep / ANIMATION_RATE'.
 

dir4() imposes an order of precedence on your direction buttons, but that's really a pretty common thing in 4-direction schemes. If you really feel the need to direct according to the last button pressed then you can create a precedence function that reacts to key events and rewrite dir4() to prioritize that direction:

 

int priorityState = SDLK_DOWN;
DIRECTION priorityDir = DIR_DOWN;

void react_to_key_event() {
  if(control_event.type == SDL_KEYDOWN) {
    switch(control_event.key.keysym.sym) {
      case SDLK_DOWN:
        priorityState = SDLK_DOWN;
        priorityDir = DIR_DOWN;
        break;
      case SDLK_LEFT:
        priorityState = SDLK_LEFT;
        priorityDir = DIR_LEFT;
        break;
      case SDLK_RIGHT:
        priorityState = SDLK_RIGHT;
        priorityDir = DIR_RIGHT;
        break;
      case SDLK_UP:
        priorityState = SDLK_UP;
        priorityDir = DIR_UP;
        break;
    }
  }
}

DIRECTION dir4(Uint8* keystate) {
  if(keystate[priorityState]) {return priorityDir;}
  if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
  if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
  if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
  if(keystate[SDLK_UP]) {return DIR_UP;}
  return DIR_NONE;
}

 

Driving input by control events is heavy on the simulation (movement must be processed for every message) and reliant on the rate at which messages are generated and etc. While the code above times the animation based on the framerate, it's in the correct format to be adjusted to a variable timestep if and when you decide to do so. The best practice is to break the system up such that all inputs (not just control input but network input and etc as well) are available, then captured at their current state and passed through a single logical frame.


#6Khatharr

Posted 26 January 2013 - 12:11 AM

I anticipated your animation speed problem when I was making my previous post but figured I'd wait until you asked. (It's the next issue to arise in the logical order of what you're doing here.)

 

Simply use an animation step that is a multiple of the number of your animation frame count and then select the frame by integer division. This is going to get progressively more difficult if you don't either rearrange your sprite sheet or else abstract the positioning so that you can refer to the direction and animation separately. This function is already really big.

 

Check this out:

enum DIRECTION {
  DIR_DOWN = 0,
  DIR_LEFT,
  DIR_RIGHT,
  DIR_UP,
  DIR_NONE
};

const int ANIMATION_FRAMES = 4;
const int ANIMATION_RATE = 15; //play with this number to control animation speed
const int ANIMSTEP_MAX = ANIMATION_FRAMES * ANIMATION_RATE;

DIRECTION dir4(Uint8* keystate) {
  if(keystate[SDLK_DOWN])  {return DIR_DOWN;}
  if(keystate[SDLK_LEFT])  {return DIR_LEFT;}
  if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
  if(keystate[SDLK_UP])    {return DIR_UP;}
  return DIR_NONE;
}

DIRECTION direction = DIR_DOWN;
int animstep = 0;

static void player_movement(void) {
  //This should really be called from outside and handed in.
  //You want the same control state for the whole logical frame.
  Uint8* keystate = SDL_GetKeyState(NULL);
  DIRECTION dir = dir4(keystate);
  if(dir == DIR_NONE) {
    animstep = 0;
    return;
  }
  direction = dir;
  ++animstep;
  animstep %= ANIMATION_MAX;
  switch(direction) {
    case DIR_DOWN:  player_y += speed; break;
    case DIR_UP:    player_y -= speed; break;
    case DIR_RIGHT: player_x += speed; break;
    case DIR_LEFT:  player_x -= speed; break;
  }
}

After running player_movement your direction will be in 'direction'.
The frame of animation to render for that direction will be 'animstep / ANIMATION_RATE'.
 

dir4() imposes an order of precedence on your direction buttons, but that's really a pretty common thing in 4-direction schemes. If you really feel the need to direct according to the last button pressed then you can create a precedence function that reacts to key events and rewrite dir4() to prioritize that direction:

 

int priorityState = SDLK_DOWN;
int priorityDir = DIR_DOWN;

void react_to_key_event() {
  if(control_event.type == SDL_KEYDOWN) {
    switch(control_event.key.keysym.sym) {
      case SDLK_DOWN:
        priorityState = SDLK_DOWN;
        priorityDir = DIR_DOWN;
        break;
      case SDLK_LEFT:
        priorityState = SDLK_LEFT;
        priorityDir = SDLK_LEFT;
        break;
      case SDLK_RIGHT:
        priorityState = SDLK_RIGHT;
        priorityDir = SDLK_RIGHT;
        break;
      case SDLK_UP:
        priorityState = SDLK_UP;
        priorityDir = SDLK_UP;
        break;
    }
  }
}

DIRECTION dir4(Uint8* keystate) {
  if(keystate[priorityState]) {return priorityDir;}
  if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
  if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
  if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
  if(keystate[SDLK_UP]) {return DIR_UP;}
  return DIR_NONE;
}

 

Driving input by control events is heavy on the simulation (movement must be processed for every message) and reliant on the rate at which messages are generated and etc. While the code above times the animation based on the framerate, it's in the correct format to be adjusted to a variable timestep if and when you decide to do so. The best practice is to break the system up such that all inputs (not just control input but network input and etc as well) are available, then captured at their current state and passed through a single logical frame.


#5Khatharr

Posted 26 January 2013 - 12:03 AM

I anticipated your animation speed problem when I was making my previous post but figured I'd wait until you asked. (It's the next issue to arise in the logical order of what you're doing here.)

 

Simply use an animation step that is a multiple of the number of your animation frame count and then select the frame by integer division. This is going to get progressively more difficult if you don't either rearrange your sprite sheet or else abstract the positioning so that you can refer to the direction and animation separately. This function is already really big.

 

Check this out:

enum DIRECTION {
  DIR_DOWN = 0,
  DIR_LEFT,
  DIR_RIGHT,
  DIR_UP,
  DIR_NONE
};

const int ANIMATION_FRAMES = 4;
const int ANIMATION_RATE = 15; //play with this number to control animation speed
const int ANIMSTEP_MAX = ANIMATION_FRAMES * ANIMATION_RATE;

DIRECTION dir4(Uint8* keystate) {
  if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
  if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
  if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
  if(keystate[SDLK_UP]) {return DIR_UP;}
  return DIR_NONE;
}

DIRECTION direction = DIR_DOWN;
int animstep = 0;

static void player_movement(void) {
  //This should really be called from outside and handed in.
  //You want the same control state for the whole logical frame.
  Uint8* keystate = SDL_GetKeyState(NULL);
  DIRECTION dir = dir4(keystate);
  if(dir == DIR_NONE) {animstep = 0;}
  else {
    direction = dir;
    ++animstep;
    animstep %= ANIMATION_MAX;
  }
}

After running player_movement your direction will be in 'direction'.
The frame of animation to render for that direction will be 'animstep / ANIMATION_RATE'.
 

dir4() imposes an order of precedence on your direction buttons, but that's really a pretty common thing in 4-direction schemes. If you really feel the need to direct according to the last button pressed then you can create a precedence function that reacts to key events and rewrite dir4() to prioritize that direction:

 

int priorityState = SDLK_DOWN;
int priorityDir = DIR_DOWN;

void react_to_key_event() {
  if(control_event.type == SDL_KEYDOWN) {
    switch(control_event.key.keysym.sym) {
      case SDLK_DOWN:
        priorityState = SDLK_DOWN;
        priorityDir = DIR_DOWN;
        break;
      case SDLK_LEFT:
        priorityState = SDLK_LEFT;
        priorityDir = SDLK_LEFT;
        break;
      case SDLK_RIGHT:
        priorityState = SDLK_RIGHT;
        priorityDir = SDLK_RIGHT;
        break;
      case SDLK_UP:
        priorityState = SDLK_UP;
        priorityDir = SDLK_UP;
        break;
    }
  }
}

DIRECTION dir4(Uint8* keystate) {
  if(keystate[priorityState]) {return priorityDir;}
  if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
  if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
  if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
  if(keystate[SDLK_UP]) {return DIR_UP;}
  return DIR_NONE;
}

 

Driving input by control events is heavy on the simulation (movement must be processed for every message) and reliant on the rate at which messages are generated and etc. While the code above times the animation based on the framerate, it's in the correct format to be adjusted to a variable timestep if and when you decide to do so. The best practice is to break the system up such that all inputs (not just control input but network input and etc as well) are available, then captured at their current state and passed through a single logical frame.


#4Khatharr

Posted 26 January 2013 - 12:03 AM

<p>I anticipated your animation speed problem when I was making my previous post but figured I'd wait until you asked. (It's the next issue to arise in the logical order of what you're doing here.)</p>
<p>&nbsp;</p>
<p>Simply use an animation step that is a multiple of the number of your animation frame count and then select the frame by integer division. This is going to get progressively more difficult if you don't either rearrange your sprite sheet or else abstract the positioning so that you can refer to the direction and animation separately. This function is already really big.</p>
<p>&nbsp;</p>
<p>Check this out:</p>
<pre class="_prettyXprint">
enum DIRECTION {
DIR_DOWN = 0,
DIR_LEFT,
DIR_RIGHT,
DIR_UP,
DIR_NONE
};

const int ANIMATION_FRAMES = 4;
const int ANIMATION_RATE = 15; //play with this number to control animation speed
const int ANIMSTEP_MAX = ANIMATION_FRAMES * ANIMATION_RATE;

DIRECTION dir4(Uint8* keystate) {
if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
if(keystate[SDLK_UP]) {return DIR_UP;}
return DIR_NONE;
}

DIRECTION direction = DIR_DOWN;
int animstep = 0;

static void player_movement(void) {
//This should really be called from outside and handed in.
//You want the same control state for the whole logical frame.
Uint8* keystate = SDL_GetKeyState(NULL);
DIRECTION dir = dir4(keystate);
if(dir == DIR_NONE) {animstep = 0;}
else {
direction = dir;
++animstep;
animstep %= ANIMATION_MAX;
}
}

</pre>
<p>After running player_movement your direction will be in 'direction'.<br />
The frame of animation to render for that direction will be 'animstep / ANIMATION_RATE'.<br />
&nbsp;</p>
<p>dir4() imposes an order of precedence on your direction buttons, but that's really a pretty common thing in 4-direction schemes. If you really feel the need to direct according to the last button pressed then you can create a precedence function that reacts to key events and rewrite dir4() to prioritize that direction:</p>
<p>&nbsp;</p>
<pre class="_prettyXprint">
int priorityState = SDLK_DOWN;
int priorityDir = DIR_DOWN;

void react_to_key_event() {
if(control_event.type == SDL_KEYDOWN) {
switch(control_event.key.keysym.sym) {
case SDLK_DOWN:
priorityState = SDLK_DOWN;
priorityDir = DIR_DOWN;
break;
case SDLK_LEFT:
priorityState = SDLK_LEFT;
priorityDir = SDLK_LEFT;
break;
case SDLK_RIGHT:
priorityState = SDLK_RIGHT;
priorityDir = SDLK_RIGHT;
break;
case SDLK_UP:
priorityState = SDLK_UP;
priorityDir = SDLK_UP;
break;
}
}
}

DIRECTION dir4(Uint8* keystate) {
if(keystate[priorityState]) {return priorityDir;}
if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
if(keystate[SDLK_UP]) {return DIR_UP;}
return DIR_NONE;
}
</pre>
<p>&nbsp;</p>
<p>Driving input by control events is heavy on the simulation (movement must be processed for every message) and reliant on the rate at which messages are generated and etc. While the code above times the animation based on the framerate, it's in the correct format to be adjusted to a variable timestep if and when you decide to do so. The best practice is to break the system up such that all inputs (not just control input but network input and etc as well) are available, then captured at their current state and passed through a single logical frame.</p>

#3Khatharr

Posted 25 January 2013 - 11:31 PM

I anticipated your animation speed problem when I was making my previous post but figured I'd wait until you asked. (It's the next issue to arise in the logical order of what you're doing here.)

 

Simply use an animation step that is a multiple of the number of your animation frame count and then select the frame by integer division. This is going to get progressively more difficult if you don't either rearrange your sprite sheet or else abstract the positioning so that you can refer to the direction and animation separately. This function is already really big.

 

Check this out:

enum DIRECTION {
  DIR_DOWN = 0,
  DIR_LEFT,
  DIR_RIGHT,
  DIR_UP,
  DIR_NONE
};

const int ANIMATION_FRAMES = 4;
const int ANIMATION_RATE = 15; //play with this number to control animation speed
const int ANIMSTEP_MAX = ANIMATION_FRAMES * ANIMATION_RATE;

DIRECTION dir4(Uint8* keystate) {
  if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
  if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
  if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
  if(keystate[SDLK_UP]) {return DIR_UP;}
  return DIR_NONE;
}

DIRECTION direction = DIR_DOWN;
int animstep = 0;

static void player_movement(void) {
  //This should really be called from outside and handed in.
  //You want the same control state for the whole logical frame.
  Uint8* keystate = SDL_GetKeyState(NULL);
  DIRECTION dir = dir4(keystate);
  if(dir == DIR_NONE) {animstep = 0;}
  else {
    direction = dir;
    ++animstep;
    animstep %= ANIMATION_MAX;
  }
}

After running player_movement your direction will be in 'direction'.
The frame of animation to render for that direction will be 'animstep / ANIMATION_RATE'.
 

dir4() imposes an order of precedence on your direction buttons, but that's really a pretty common thing in 4-direction schemes.

 

Driving input by control events is heavy on the simulation (movement must be processed for every message) and reliant on the rate at which messages are generated and etc. While the code above times the animation based on the framerate, it's in the correct format to be adjusted to a variable timestep if and when you decide to do so. The best practice is to break the system up such that all inputs (not just control input but network input and etc as well) are available, then captured at their current state and passed through a single logical frame.


#2Khatharr

Posted 25 January 2013 - 11:29 PM

<p>I anticipated your animation speed problem when I was making my previous post but figured I'd wait until you asked. (It's the next issue to arise in the logical order of what you're doing here.)</p>
<p>&nbsp;</p>
<p>Simply use an animation step that is a multiple of the number of your animation frame count and then select the frame by integer division. This is going to get progressively more difficult if you don't either rearrange your sprite sheet or else abstract the positioning so that you can refer to the direction and animation separately. This function is already really big.</p>
<p>&nbsp;</p>
<p>Check this out:</p>
<pre class="_prettyXprint">
enum DIRECTION {
DIR_DOWN = 0,
DIR_LEFT,
DIR_RIGHT,
DIR_UP,
DIR_NONE
};

const int ANIMATION_FRAMES = 4;
const int ANIMATION_RATE = 15; //play with this number to control animation speed
const int ANIMSTEP_MAX = ANIMATION_FRAMES * ANIMATION_RATE;

DIRECTION dir4(Uint8* keystate) {
if(keystate[SDLK_DOWN]) {return DIR_DOWN;}
if(keystate[SDLK_LEFT]) {return DIR_LEFT;}
if(keystate[SDLK_RIGHT]) {return DIR_RIGHT;}
if(keystate[SDLK_UP]) {return DIR_UP;}
return DIR_NONE;
}

DIRECTION direction = DIR_DOWN;
int animstep = 0;

static void player_movement(void) {
//This should really be called from outside and handed in.
//You want the same control state for the whole logical frame.
Uint8* keystate = SDL_GetKeyState(NULL);
DIRECTION dir = dir4(keystate);
if(dir == DIR_NONE) {animstep = 0;}
else {
direction = dir;
++animstep;
animstep %= ANIMATION_MAX;
}
}

</pre>
<p>After running player_movement your direction will be in 'direction'.<br />
The frame of animation to render for that direction will be 'animstep / ANIMATION_RATE'.<br />
&nbsp;</p>
<p>dir4() imposes an order of precedence on your direction buttons, but that's really a pretty common thing in 4-direction schemes.</p>
<p>&nbsp;</p>
<p>Driving input by control events is heavy on the simulation (movement must be processed for every message) and reliant on the rate at which messages are generated and etc. While the code above times the animation based on the framerate, it's in the correct format to be adjusted to a variable timestep if and when you decide to do so. The best practice is to break the system up such that all inputs (not just control input but network input and etc as well) are available, then captured at their current state and passed through a single logical frame.</p>

PARTNERS