Sign in to follow this  
armond

Allegro: Game runs too fast on other machines

Recommended Posts

armond    168
I followed a tutorial on how to use timers. Unfortunately, It only worked with the movement of my player ship. Eveything else (the background, enemies and bullets) all run so fast... Why is this? I'm posting the source code, it's still messy since I'm only trying things out and some comments might still be in it.
#include <allegro.h>
//#include <iostream>
#include <string>
#include <vector>

#include "enemy.h"
#include "kingskull.h"
#include "bullet.h"

volatile long speedCounter = 0;

const int GAME_WIDTH = 640;
const int GAME_HEIGHT = 480;

const int X_MIN = 0;
const int Y_MIN = 0;

const int X_MAX = 640;
const int Y_MAX = 480;

const int PLAYER_MIN_X = 0;
const int PLAYER_MIN_Y = 20;
const int PLAYER_MAX_X = 570;
const int PLAYER_MAX_Y = 450;

const int MAX_BULLET_NUM = 1;

const int FIRE_DELAY = 2;
int fireDelayIndex = 2;
int bulletIndex = 0;

BITMAP *buffer;

BITMAP *ship;

BITMAP *bg;

BITMAP *kingSkull[3];

BITMAP *kingSkullSprite;

BITMAP *bulletSprite;

BITMAP *spaceJunkSprite;

BITMAP *enemySprite;
BITMAP *enemyDeadSprite;

//Enemy *enemy;
Enemy *kingSkullEnemy;

//Enemy *minnions[10];

int minnionCount = 0;

PACKFILE *bgMap;

int x = 0;
int y = 20;

int shipSpeed = 3;

int speed = 2;


int player_life = 200;

int bgX = 0;
int bgY = 0;
int bgSpeed = 1;

int animationIndex = 0;
int animationDelay = 0;

std::vector<Enemy> enemyList;
std::vector<Bullet> bullets;

int initAlleg();

void blitBuffer();
void moveBg();
void incrementSpeedCounter();
void drawLifeBar(int life, BITMAP * &bitmap);

short int isCollide(Bullet &b, Enemy &e);
short int isHit(int x, int y, Enemy &e); 

int main(int* argc, char* argv[])
{

    if ( initAlleg() == -1 )
    {        
        return -1;
    }
    
    while(! key[KEY_ESC] )
    {

        while (speedCounter > 0)
        {
            if ( key[KEY_UP] )
            {
                y -= shipSpeed;
            
                if (y < PLAYER_MIN_Y)
                {
                    y += shipSpeed;
                }    
            }
            if( key[KEY_DOWN] )
            {
                y += shipSpeed;
            
                if (y > PLAYER_MAX_Y)
                {
                    y -= shipSpeed;
                }    
            }
            if( key[KEY_LEFT] )
            {
                x -= shipSpeed;
            
                if (x < PLAYER_MIN_X)
                {
                    x += shipSpeed;
                }    
            }    
            if( key[KEY_RIGHT] )
            {
                x += shipSpeed;
            
                if ( x > PLAYER_MAX_X)
                {
                    x -= shipSpeed;
                }    
            }
            if( key[KEY_A] )
            {
                if ( bulletIndex < bullets.size() )
                {
                    if (bullets[bulletIndex].fireable == true)
                    {
                        bullets[bulletIndex].x = x + enemySprite->w;
                        bullets[bulletIndex].y = y;
                        bullets[bulletIndex].fireable = false;                                  
                    }
                    
                    bulletIndex ++;
                }
                else
                {
                    bulletIndex = 0;
                }             
                
            }
            
            
            speedCounter--;                       
        }       

         /*
        if (fireDelayIndex == FIRE_DELAY)
        {
            fireDelayIndex = 0;
        }
        */

        /*Draw the background first*/
        moveBg();                      

        draw_sprite(buffer, ship, x, y);

        /*Move the darn enemies!*/
        //enemy->x -= speed;
        
        /*
        if (enemy->x <= X_MIN - 50)
        {
            (*enemy).x = X_MAX;
        }
        */
        
        kingSkullEnemy->x -= speed;
        
        if (kingSkullEnemy->x <= X_MIN - 50)
        {
            kingSkullEnemy->x = X_MAX;
        }            
        
        /*Then draw them to the buffer*/
        //draw_sprite(buffer, enemySprite, enemy->getX(), enemy->getY() );
        
        /*Test Sprite Sheet*/
        //blit(testSprite, buffer, 0, 0, 0, 0, bmp->w, bmp->h);
        //blit(testSprite, buffer, 110, 80, 200, 200, 64, 70);
        //masked_blit(testSprite, buffer, 110, 80, 200, 200, 64, 70);
        
        draw_sprite(buffer, kingSkull[animationIndex], kingSkullEnemy->x, kingSkullEnemy->y);
        
        if (animationDelay == 20)
        {
            animationIndex++;
            animationDelay = 0;
        }    
        
        if (animationIndex >= 3)
        {
            animationIndex = 0;
        }    
        
        /*Increase animation(frame) delay for kingSkull*/
        animationDelay++;
    
        /*draw minions*/
        for (int i = 0; i < enemyList.size(); i++)
        {
            enemyList.at(i).x -= speed;
             
            /*                    
            if (enemyList.at(i).x <= X_MIN)
            {
                enemyList.at(i).x = X_MAX;
                enemyList[i].isDead = false;
            }
            */
            if (enemyList[i].x <= X_MIN - 50)
            {
                enemyList[i].x = X_MAX;
                
                
                enemyList[i].isDead = false;
            }            
            
            //draw_sprite(buffer, enemySprite, minnions[i]->x, minnions[i]->y);
           if ( enemyList[i].isDead == false)
           {
               /*Check if player is hit by the enemy*/
               if ( isHit(x, y, enemyList[i]) == 1)
               {
                   enemyList[i].isDead = true;
                   
                   player_life -= 10;
                   
                   if (player_life <= 50)
                   {
                       player_life = 50;
                   }    
               }    
                              
               draw_sprite(buffer, enemySprite, enemyList.at(i).x, enemyList.at(i).y);
           }  
           else
           {                                        
               draw_sprite(buffer, enemyDeadSprite, enemyList.at(i).x, enemyList.at(i).y);
           }
           
           //track the status of the enemy
           textprintf_ex(buffer, font, enemyList.at(i).x, enemyList.at(i).y, makecol(255, 100, 200), -1, "%s", enemyList[i].isDead ? "true" : "false");
                 
        }
        
        /*draw bullets*/
        for (int i = 0; i < bullets.size(); i++)
        {
            if (bullets[i].fireable == false)
            {
                bullets[i].move();
                
                if (bullets[i].x > GAME_WIDTH + 50)
                {
                    bullets[i].fireable = true;
                }
            }
            
            //draw_sprite(buffer, enemySprite, minnions[i]->x, minnions[i]->y);
            //draw_sprite(buffer, enemySprite, enemyList.at(i).x, enemyList.at(i).y);
            draw_sprite(buffer, bulletSprite, bullets[i].x, bullets[i].y);
            
            /*Collision detection with minnions*/
            /*TODO: FIX THIS*/
            
            for (int j = 0; j < enemyList.size(); j++)
            {
                if ( enemyList[j].isDead == false )
                {
                    /*
                    int ex1 = enemyList[j].x;
                    int ex2 = enemyList[j].x + enemySprite->w;
                    int ey1 = enemyList[j].y;
                    int ey2 = enemyList[j].y + enemySprite->h;
                    
                    int bx1 = bullets[i].x;
                    int bx2 = bullets[i].x + bulletSprite->w;
                    int by1 = bullets[i].y;
                    int by2 = bullets[i].y + bulletSprite->h;


                    if ( (ey2 <  by1) && (by1 > by2) && (ex2 < bx1) && (ex1 > bx2) )
                    {
                        enemyList[j].isDead = true;
                    }
                    */
                    
                    if ( isCollide(bullets[i], enemyList[j]) == 1)
                    {
                        enemyList[j].isDead = true;
                        bullets[i].fireable = true;
                        bullets[i].x = GAME_WIDTH + 100;
                        bullets[i].y = 0;
                    }            
                }    
            } 
                       
            
        }
        
        
        /*Some UI stuff... */
        textout_ex(buffer, font, "Life: ", 10, 10, makecol(0, 0, 255), -1);                        
        textout_ex(buffer, font, "Guage: ", 250, 10, makecol(0, 0, 255), -1);
        
        drawLifeBar(player_life, buffer);    
            
        textprintf_centre_ex(buffer, font, SCREEN_W/2, 176, makecol(255, 255, 255), makecol(0, 0, 0), "num=%d", speedCounter);
                
        blitBuffer();
        
        clear_bitmap(buffer);
        
        //rest(1);
    }
    
    destroy_bitmap(buffer); 
    destroy_bitmap(ship);
    destroy_bitmap(enemySprite);
    destroy_bitmap(bg);
    destroy_bitmap(kingSkullSprite);
    destroy_bitmap(spaceJunkSprite);
    destroy_bitmap(enemyDeadSprite);    
    
    destroy_bitmap(kingSkull[0]);
    destroy_bitmap(kingSkull[1]);
    destroy_bitmap(kingSkull[2]);
            
    //delete enemy;
    delete kingSkullEnemy;
    
    
    /*
    delete minnions[0];
    delete minnions[1];
    delete minnions[2];
    delete minnions[3];
    delete minnions[4];
    delete minnions[5];
    delete minnions[6];
    delete minnions[7];
    delete minnions[8];
    delete minnions[9];
    */
    
    /*
    for (int i = 0; i < enemyList.size(); i++)
    {
        enemyList.at(i);
    }
    */
    
    /*delete all elements in the vector*/
    for (std::vector<Enemy>::iterator it = enemyList.begin(); it != enemyList.end();)
    {
        //delete enemyList.at(i);
        enemyList.erase(it);
    }


    for (std::vector<Bullet>::iterator it = bullets.begin(); it != bullets.end();)
    {
        //delete enemyList.at(i);
        bullets.erase(it);
    }    
    
    enemyList.clear();
    
    allegro_exit();       
    
    return 0;
}
END_OF_MAIN()


int initAlleg()
{
    allegro_init();
    install_keyboard();
   
    install_timer();

    set_color_depth(16);    

    if ( set_gfx_mode(GFX_AUTODETECT, GAME_WIDTH, GAME_HEIGHT, 0, 0) != 0 )
    {
        allegro_message("Graphics Mode Could Not Be Set!: %s", allegro_error);
        return -1;
    }
    
    
    buffer = create_bitmap(GAME_WIDTH, GAME_HEIGHT);

    ship = load_bitmap("ship.bmp", NULL);
    enemySprite = load_bitmap("enemy1.bmp", NULL);

    //bg = load_bitmap("space.bmp", NULL);
    bg = load_bitmap("bg.bmp", NULL);


    bulletSprite = load_bitmap("bullet.bmp", NULL);
    
    //testSprite = load_bitmap("actraiser_tanzra_sheet.bmp", NULL);
    
    kingSkullSprite = load_bitmap("kingskull.bmp", NULL);
    
    //masked_blit(testSprite, kingSkull[0], 110, 80, 200, 200, 64, 70);
    //masked_blit(testSprite, kingSkull[1], 110, 80, 200, 200, 64, 70);
    //masked_blit(testSprite, kingSkull[2], 110, 80, 200, 200, 64, 70);
    kingSkull[0] = create_sub_bitmap(kingSkullSprite, 0, 0, 50, 100);
    kingSkull[1] = create_sub_bitmap(kingSkullSprite, 50, 0, 50, 100);
    kingSkull[2] = create_sub_bitmap(kingSkullSprite, 100, 0, 50, 100);
    
    spaceJunkSprite = load_bitmap("spacejunk.bmp", NULL);
    enemyDeadSprite = create_sub_bitmap(spaceJunkSprite, 34, 75, 39, 30);
    
    bgMap = pack_fopen("bgmap.txt", "r"); 

    if (!bgMap)
    {
        //abort_on_error("Couldn't open binary data!");
        allegro_message("COULD NOT OPEN FILE!: %s", allegro_error);
    }    
    
    /*char buf[256];
 
    while (pack_fgets(buf, sizeof(buf), bgMap)) 
    {
	  Process input line.
    }
    */
    
    /*Create an enemy object*/
    //enemy = new Enemy(X_MAX, 240);
    kingSkullEnemy = new Enemy(X_MAX, 390);
    
    std::string mapLine;
    
    char buf[255];
    
    while ( pack_feof(bgMap) == 0)
    {
          mapLine = pack_fgets(buf, sizeof(buf), bgMap);
          
          
          int tempX = 0;
          
          for (int i = 0; i < mapLine.length(); i++)
          {
              
              //tempX += (SCREEN_W + bg->w);
              
              if ( mapLine.at(i) == 'x')
              {
                   //minnions[minnionCount] = new Enemy(x, (rand() % Y_MAX) + 1);                   
                   //enemyList.push_back(new Enemy(tempX, (rand() % Y_MAX) + 1) );
                   enemyList.push_back(* new Enemy(tempX, (rand() % Y_MAX) + 1) );
              }
              else
              {
                   tempX += bg->w;    
              }
              
          }
    }
    
    for(int i = 0; i < MAX_BULLET_NUM; i++)
    {
        bullets.push_back(* new Bullet(GAME_WIDTH + 100, 0, x, y, 10, true) );
    }

    pack_fclose(bgMap);
    
    LOCK_VARIABLE(speedCounter);
    LOCK_FUNCTION(incrementSpeedCounter);
 
    //install_int_ex(incrementSpeedCounter, BPS_TO_TIMER(60) );
    install_int(incrementSpeedCounter, 10);           
}

void blitBuffer()
{
    acquire_screen();
        
    blit(buffer, screen, 0, 0, 0, 0, GAME_WIDTH,GAME_HEIGHT);
    
    release_screen();
}

void moveBg()
{
    /*
    bgX -= bgSpeed;
    
    if (bgX + X_MAX <= X_MIN)
    {
        bgX = X_MIN;
    } 
    
    
    for (int i = -50; i < SCREEN_W; i += bg->w)
    {
        for (int j = 0; j < SCREEN_H; j += bg->h)
        {
            draw_sprite(buffer, bg, i + bgX, j);
            draw_sprite(buffer, bg, i + SCREEN_W + bgX, j);
            //draw_sprite(buffer, bg, i + bgX, j);      
        }    
    } 
    */   
    
    bgX -= bgSpeed;
    
    if ( bgX > bg->w || bgX < -(bg->w) )
    { 
        bgX = 0;
    }    
    
    for (int i = -(bg->w); i < (SCREEN_W+bg->w); i+=bg->w)
    {
        for (int j = 0; j < SCREEN_H; j += bg->h)
        {
            draw_sprite(buffer, bg, bgX+i, j);
        }    
    }
    
    //draw_sprite(buffer, bg, bgX, bgY);   
    
    /* make another copy of the bg to seemlessly create a scrolling bg*/
    
    //draw_sprite(buffer, bg, (bgX + X_MAX), bgY);
    
}  

void drawLifeBar(int life, BITMAP * &bitmap)
{
    //rect(bitmap, 50, 0, life * 2, 20, 255);
    rectfill(bitmap, 50, 0, life, 20, 255);
}    

short int isCollide(Bullet &b, Enemy &e) 
{
  
    int left1, left2;
    int right1, right2;
    int top1, top2;
    int bottom1, bottom2;

    left1 = b.x;
    left2 = e.x;
    right1 = b.x + bulletSprite->w;
    right2 = e.x + enemySprite->w;
    top1 = b.y;
    top2 = e.y;
    bottom1 = b.y + bulletSprite->h;
    bottom2 = e.y + enemySprite->h;

    if (bottom1 < top2) return(0);
    if (top1 > bottom2) return(0);

    if (right1 < left2) return(0);
    if (left1 > right2) return(0);

    return(1);

};

short int isHit(int x, int y, Enemy &e) 
{
  
    int left1, left2;
    int right1, right2;
    int top1, top2;
    int bottom1, bottom2;

    left1 = e.x;
    left2 = x;
    right1 = e.x + bulletSprite->w;
    right2 = x + enemySprite->w;
    top1 = e.y;
    top2 = y;
    bottom1 = e.y + bulletSprite->h;
    bottom2 = y + enemySprite->h;

    if (bottom1 < top2) return(0);
    if (top1 > bottom2) return(0);

    if (right1 < left2) return(0);
    if (left1 > right2) return(0);

    return(1);

};


void incrementSpeedCounter()
{
     speedCounter++;
}     
END_OF_FUNCTION(incrementSpeedCounter);


Share this post


Link to post
Share on other sites
23yrold3yrold    941
The area having its speed regulated (starting with 'while (speedCounter > 0) {' and ending with the corresponding '}') needs to encompass ALL game logic. Right now only the player movement is in there, and that's why it's all that's working.

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

Sign in to follow this