Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Yet another problem with animations....

This thread is locked; no one can reply to it. rss feed Print
Yet another problem with animations....
miguel meza
Member #5,447
January 2005

well, in my 2D fighting game (DBZ hyper dimension clon), i have some problems with the logic when animating a character:

I do something like this when animating a fighter, for example when he jumps (this is onlye a test code, i am going to do a fine method to save code):

stretch_sprite(buffer, background, 0, screenY1, SCREEN_WIDTH ,screenY2);
masked_blit(gokuss1, buffer, 96*2, 96*2,  100,150,  96,96);  // jumps
blit(buffer, screen, 0,0,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
rest(50);
clear_bitmap(buffer); // Clear the contents of the buffer bitmap 

stretch_sprite(buffer, background, 0, screenY1, SCREEN_WIDTH ,screenY2);
masked_blit(gokuss1, buffer, 96*2, 96*2,  100,200,  96,96);  // goes down  
blit(buffer, screen, 0,0,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
rest(50);
clear_bitmap(buffer); // Clear the contents of the buffer bitmap 

the problem is:
if i don put the "rest(time)" code, the animation looks extremely fast and ugly.

And if i put that code, the game CANT do any other thing. For example,that the enemy attacks me when i jump.

What should i do?
what is the logic of that?

thanks...

Elverion
Member #6,239
September 2005
avatar

Look into allegro timers. Using rest to adjust the speed of your game is a no-no.

Second of all, make the character an object or struct. When they are jumping, you want to do something like y = y - 2; (this is a very poor jump...search the forum for more in-depth jump stuff). Once you're into your draw section, you masked_blit the sprite onto the characters x and y coordinates (give or take some offset values).

--
SolarStrike Software - MicroMacro home - Automation software.

Archon
Member #4,195
January 2004
avatar

If your 'rest(50)' actually worked like you'd like, it'd actually just have 50 millisecond gaps between the animations, but it would differ depending on the number of sprites to draw.

What you really want is to prioritise the processing and only then, the drawing. Use a timer to increment about 30 times per second. When the ticks are above 0, decrement it by one and then do your processing. When the processing ticks remaining is 0, then do the drawing.

miguel meza
Member #5,447
January 2005

i dont understand very good...

i have this bitmap:
http://www.blackwind.com.mx/gokuSS1move.bmp

i already created my class for sprites, and for drawing i use this:

sprGoku.drawSprite( sprGoku.m_partX, sprGoku.m_partY, sprGoku.m_posX , sprGoku.m_posY );

that mainly does this:

masked_blit( m_bitmap, g_buffer,  partX, partY,  posX, posY, m_sizeX, m_sizeY );

i subdivided my bitmap in parts of 96*96
so for example:
partX1, partY1 will be the goku standing.
and partX2, partY2 will be the goku standing electrified....

i already use timers:

1void MainLoop()
2{
3g_EndGame = false;
4 
5while ( !g_EndGame)
6{
7// for the TIMER
8while( g_speed_counter > 0 )
9{
10if ( key[KEY_ESC] )
11{
12g_EndGame = true;
13}
14// all the logic, collisions and math of the game
15DoGameLogic();
16g_speed_counter--;
17}
18// draw everything
19RenderScene();
20 
21if ( g_EndGame )
22QuitGame();// destroy sound and bitmaps
23}
24}

in my "Do GameLogic" i do this:

void DoGameLogic()
{    
  CheckCollision(); // does nothing in this moment  
  if( keypressed() )
    CheckMovement();
}

this the "short" version of CheckMovement()

void CheckMovement()
{
  if ( key[KEY_UP] )
  {
        // only set the partX1,X2...partY1,Y2....etc of the bitmaps
    CalculateJumpPos(); 
  }

and in my "renderScene" i call the method to do the JumpAnim() (if needed)
that does something like this:

1void JumpAnim()
2{
3
4 float x = sprGoku.m_posX;
5 float y = sprGoku.m_posY;
6
7 //agacha
8 sprBackground.drawBackground();
9 sprGoku.drawSprite( partX1, partY1, x, 300 );
10 rest(50);
11 clear_bitmap(g_buffer);
12 
13 // alza pierna
14 sprBackground.drawBackground();
15 sprGoku.drawSprite( partX2, partY1, x, 225 );
16 rest(60);
17 clear_bitmap(g_buffer);
18 
19 // cambio de rodilla
20 sprBackground.drawBackground();
21 sprGoku.drawSprite( partX3, partY1, x, 150 );
22 rest(60);
23 clear_bitmap(g_buffer);
24 
25 // cambio 2 de rodilla y baja
26 sprBackground.drawBackground();
27 sprGoku.drawSprite( partX4, partY1, x, 225 );
28 rest(60);
29 clear_bitmap(g_buffer);
30 
31 // alza pierna y baja
32 sprBackground.drawBackground();
33 sprGoku.drawSprite( partX5, partY1, x, 300 );
34 rest(60);
35 clear_bitmap(g_buffer);
36}

so now that you know what am i doing........
how do i solve my problem??

miran
Member #2,407
June 2002

Get rid of rest(). Use timers instead. What you're doing now is you draw your sprites and in between wait more than a quarter of a second. This will give you roughly 3 FPS at best.

EDIT: Actually I misunderstood. Do this:

while (not done) {
   if (timer ticked) {
      // get input, update player position, etc.
      do_game_logic()
   }

   if (need to redraw) {
      // here you don't update player position or animation sequence or anything like
      // that. you just draw the current frame at the current position.
      redraw_entire_scene()
   }
}

--
sig used to be here

miguel meza
Member #5,447
January 2005

ok, i got it.
now i have more problems....

there will be a time when i need to flip the sprite.

but there isnt a method to do that with blit or masked blit (which i need to draw only a part of the image).

Allegro only has the draw_sprite_h_flip(bmp, sprite, posX, posY); but that doesnt works for me, because it will draw ALL the image.

what can i do?
i have 2 ideas (which i DONT like)

1.- Create a sub_bitmap that will be the part of the image i want to draw, and then i can use the draw_sprite_h_flip. BUT i will have to create the sub_bitmap every time the character move, which i think it could cause a BIG slowdown... or no?

2.- Have another image with the "parts" flipped horizontally.

Isnt there any other solution?

Archon
Member #4,195
January 2004
avatar

Quote:

2.- Have another image with the "parts" flipped horizontally.

From your two choices, this would be the better one.
You could have two BITMAP*s, which are just the flipped version of eachother, or you could have a single bitmap with the same image underneath. This way, all you do for the source_y of masked_blit is to use it as normal... But if the character is facing the other direction, then source_y equals the original source_y + (original BITMAP* height).

miguel meza
Member #5,447
January 2005

thanks.
I had to do that, was the easyest way (in programming).
Fireworks, photoshop and paint are saving me hehe....

Go to: