sdl 1.2 class constructor doesn't work somehow

Started by
8 comments, last by Heelp 8 years, 3 months ago

Guys, I have a problem with my game. The problem is that I have only one enemy. I can't make more enemies mainly because the SDL_Rect doesn't work as expected. The stuff I did: I made one SDL_Rect called 'enemybox' and I put it in class Enemy along with all other necessary stuff for the Enemy like movement, collision, rendering, etc. I have only one member from class Enemy called 'enemy1'. Ok, I created enemy2, but now I need to somehow change the SDL_Rect coordinates. Ok, after the default constructor, which is Enemy(), I made Enemy( int, int ) constructor.

It goes like this:

Enemy( int a, int b)

{

enemybox.x = a;

enemybox.y = b;

}

Now every time I initialize new enemy, I write it like this: Enemy enemy2( 300, 400) or Enemy enemy3 ( 50, 60) so I can assign the starting coordinates...but the problem is that this doesn't work. It doesnt even show anything on the screen, that means that the constructor is not working. I posted my problem in st*ckoverfl*w but nobody gave me a decent answer for beginner, the best answer was to make some virtual class and somehow inherit some stuff and its very compicated for me.
I just want to make another member of the class, assign him the x, y coordinates and everything is fine. Tell me the easiest way you know, step by step, so I can understand it. I'm struggling with this for 2 weeks and I can't do anything and it really s*cks. Any help is MUCH appreciated, really.

Advertisement

Welcome to the GD.net community. smile.png

Stack Overflow is for very specific questions, not open-ended discussions and explanations. That's what forums (like this one) are for. Most of us use both sites, because both sites serve different purposes - different tools for different jobs.

Also, if someone told you to make a derived class, they are probably wrong, since that's not what you need here. Derived classes work in similar situations, but that doesn't mean they should be used in every situation.

As a programmer, always assume it's your code that's broken, because 99.99% of the time, it's your mistake. Especially for the first 5 years of your programming journey. After five years, it's only 90% of the time your mistake, so it's still always worth assuming it's your fault, even when you become more experienced.

No, constructors are not broken. No, SDL_Rect is not broken.

Post your actual code - including the full Enemy class, with full functions, and how you are using it, and we can almost certainly tell you exactly what you are doing wrong. Specifically (but not exclusively), we need to see how and where you are using the 'enemybox' SDL_rect.

You can post code between [ code ] and [ /code ] tags (but without the spaces).

Shouldn't you also assign values to enemybox.w and enemybox.h?

Sorry for the late answer, I had pretty tough exams in university and I completely forgot about my game and my post here . Ok, the thing is, I started 'making' games ( or 'trying to make' ) 1 month ago because I have this idea for a MMORPG in which you use fire magic to kill big centaurs with your pet T-rex named Pinkie and.....................................I'm just kidding, calm down....(can't even make jokes here..........) it's just a simple iPhone app... Ok, I had a really basic C++ understanding so I needed to make small steps at learning game programming so I don't have to jump into deep waters straight away, cuz I give up too easily most of the time. The plan was structured in 3 steps.
1st step - I remake one popular flash game, so I get into how things work.
2nd step - I learn how to port games from pc to Iphone. ( I already found a set of tutorials, that's the easy part ( I think... )
3rd step - Finally make my iphone game, get two millions in cash and retire.

( mini-rant is over.)

The game is a remake of a famous flash game named Bubble Struggle 2, I used swf_pic_extractor to get all the sprites from the actual flash game because otherwise I had to spend 2 hours print-screening the sh*t out of this game. I have 1 Balloon that is bouncing ( so I have my 60 years old, nearly broken gravity function ) and I need to make 5 balloons, I'm too lazy to make 'for' loops everywhere and I also want a cleaner code.

Ok, now I'm gonna actually post my code. 1st I need to explain once again what my problem is. My problem is that I need to find a way to use 1 class to make 5-6 objects with different coordinates but using the same functions in the class.

class Balloon
{
    private:
    //Its rate of movement
    float velocityX;
    float velocityY;
 
    float accelerationY;
 
    //The weight of the bubble depends on the height of the bouncing (somehow..)
    float balloonWeight;
 
    SDL_Rect enemybox;
 
    public:
    //Initializes the variables
    Balloon();
 
    //2nd constructor with 2 arguments for coordinates
    Balloon( int, int );
 
    //Moves the foo
    void movement();
 
    //Shows the Balloon
    void show();
 
   
    //And some other functions you don't have to waste your time reading
    //Make the rect and bouncing smaller when hit
    void make_smaller();
 
    //Pushes away the balloon when hit
    void push_away();
 
};

You need to post the .cpp file also, because that's where the bug is located.

We need to see every location you use "enemybox", because that's what you are having problems with.


//Post deleted

How can i upload my cpp file here? Edit: Ok I'm going to post it here.


//The headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"
#include <string>
 
//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
 
//The frames per second
const int FRAMES_PER_SECOND = 50;
 
//The height and number of menu labels
const int NUMMENU = 3;
const int BUTTON_HEIGHT = 30;
 
//The dimensions of the foo
const int FOO_WIDTH = 40;
const int FOO_HEIGHT = 60;
 
//The dimensions of the balloon
const int BALLOON_WIDTH = 137;
 
//The dimensions of the chain
const int CHAIN_WIDTH = 10;
const int CHAIN_HEIGHT = 480;
const int CHAIN_COOLDOWN = 40;
 
const int IN = -2;
const int OUT = -1;
//The direction status of the foo
const int FOO_STILL = 0;
const int FOO_RIGHT = 1;
const int FOO_LEFT = 2;
const int FOO_DEAD = 3;
const int WEAPON_OFF = 4;
const int WEAPON_ON = 5;
 
//The flags
int weaponstatus = WEAPON_OFF;
bool quit = false;
bool dead = false;
bool pauseGame = false;
 
//The number of times the collisions between chain and bubble
int hitsNumber = 0;
int pauseTime = 0;
const int DEATH_PAUSE = 61;
 
//timer for the text
int c = 0;
 
//Main surfaces
SDL_Surface *screen = NULL;
SDL_Surface *menu[NUMMENU];
 
SDL_Surface *level[10] = { NULL };
SDL_Surface *level1bg = NULL;
 
 
//In-game sprite surfaces
SDL_Surface *stayStill = NULL;
SDL_Surface *moveLeft[20] = { NULL };
SDL_Surface *moveRight[20] = { NULL };
SDL_Surface *fooDead = NULL;
SDL_Surface *fooWeapon = NULL;
SDL_Surface *enemyBalloon[4] = { NULL };
SDL_Surface *fooverigatop = NULL;
 
//In-game text surfaces
SDL_Surface *collisionCheck = NULL;
SDL_Surface *gameOver = NULL;
SDL_Surface *finished = NULL;
 
//The event structure
SDL_Event event;
 
//The font
TTF_Font *font = NULL;
 
//The color of the font
SDL_Color textColor = { 255, 255, 255 };
SDL_Color color[2] = {{ 255, 255, 255 }, { 255, 0, 0 }};
 
//The Collision rectangles of the Foos
SDL_Rect foobox;
SDL_Rect veriga;
 
 
class Menu
{
    private:
    int x, y;
    int i, j;
    int state;
 
    //The rectangles of the menus
    SDL_Rect position[NUMMENU];
    const char* labels[NUMMENU] = {"New Game" ,"Options", "Quit"};
 
    public:
    Menu();
    int show_menu();
};
 
//The foo
class Foo
{
    private:
    //The offsets
    int offsetX;
    int offsetY;
 
    int chainoffsetX;
    int chainoffsetY;
 
    //Its rate of moving
    float velocity;
    float Yvelocity;
 
    float Yacceleration;
 
    //Its current frame
    int frame;
    int cooldown;
 
    //The flags
    int walkstatus;
 
    public:
    //Initializes the variables
    Foo();
 
    //Handles input
    void handle_events();
 
    //moves the foo
    void movement();
 
    //Handles the shooting
    void shoot();
 
    //Handles the foo when walking
    void walk_anim();
 
    //Shows the foo
    void show();
};
 
class Balloon
{
    private:
    //Its rate of movement
    float velocityX;
    float velocityY;
 
    float accelerationY;
 
    //The weight of the bubble depends on the height of the bouncing (somehow..)
    float balloonWeight;
 
    SDL_Rect enemybox;
 
    public:
    //Initializes the variables
    Balloon();
    Balloon( int, int );
 
    //Moves the foo
    void movement();
 
    //Shows the Balloon
    void show();
 
    //Make the rect and bouncing smaller when hit
    void make_smaller();
 
    //Pushes away the balloon when hit
    void push_away();
 
};
 
//The timer
class Timer
{
    private:
    //The clock time when the timer started
    int startTicks;
 
    //The ticks stored when the timer was paused
    int pausedTicks;
 
    //The timer status
    bool paused;
    bool started;
 
    public:
    //Initializes variables
    Timer();
 
    //The various clock actions
    void start();
    void stop();
    void pause();
    void unpause();
 
    //Gets the timer's time
    int get_ticks();
 
    //Checks the status of the timer
    bool is_started();
    bool is_paused();
};
 
 
SDL_Surface *load_image( std::string filename )
{
    //The image that's loaded
    SDL_Surface* loadedImage = NULL;
 
    //The optimized surface that will be used
    SDL_Surface* optimizedImage = NULL;
 
    //Load the image
    loadedImage = IMG_Load( filename.c_str() );
 
    //If the image loaded
    if( loadedImage != NULL )
    {
        //Create an optimized surface
        optimizedImage = SDL_DisplayFormat( loadedImage );
 
        //Free the old surface
        SDL_FreeSurface( loadedImage );
 
        //If the surface was optimized
        if( optimizedImage != NULL )
        {
            //Color key surface
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0, 0 ) );
        }
    }
 
    //Return the optimized surface
    return optimizedImage;
}
 
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
    //Holds offsets
    SDL_Rect offset;
 
    //Get offsets
    offset.x = x;
    offset.y = y;
 
    //Blit
    SDL_BlitSurface( source, clip, destination, &offset );
}
 
 
bool init()
{
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }
 
    //Set up the screen
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
 
    //If there was an error in setting up the screen
    if( screen == NULL )
    {
        return false;
    }
 
    //Initialize SDL_ttf
    if( TTF_Init() == -1 )
    {
        return false;
    }
 
    //Set the window caption
    SDL_WM_SetCaption( "Bubble Trouble 2", NULL );
 
    //If everything initialized fine
    return true;
}
 
bool load_files()
{
    //Load the font
    font = TTF_OpenFont( "lazy.ttf", 38 );
 
    //Load the messages
    gameOver = TTF_RenderText_Solid( font, "Game Over", textColor );
    finished = TTF_RenderText_Solid( font, "Level Completed!", textColor );
 
    //Load the menu sprites
 
    //Load the backgrounds
    level1bg = load_image("Other sprites/Background sprites/Level 1.jpg");
 
    //Load the the images while not moving
    stayStill = load_image("SpriteStayStill/StayStill.png");
    fooDead = load_image("Other sprites/Dying1.png");
 
 
    enemyBalloon[0] = load_image("Other sprites/Balloon0.png");
    enemyBalloon[1] = load_image("Other sprites/Balloon1.png");
    enemyBalloon[2] = load_image("Other sprites/Balloon2.png");
    enemyBalloon[3] = load_image("Other sprites/Balloon3.png");
 
    //Load super qka veriga
    fooWeapon = load_image("Other sprites/normalChain.png");
    fooverigatop = load_image("Other sprites/Chainpoint.png");
 
    //Load the images when moving left
    moveLeft[0] = load_image("SpritemoveLeft/moveLeft1.png");
    moveLeft[1] = load_image("SpritemoveLeft/moveLeft2.png");
    moveLeft[2] = load_image("SpritemoveLeft/moveLeft3.png");
    moveLeft[3] = load_image("SpritemoveLeft/moveLeft4.png");
    moveLeft[4] = load_image("SpritemoveLeft/moveLeft5.png");
    moveLeft[5] = load_image("SpritemoveLeft/moveLeft6.png");
    moveLeft[6] = load_image("SpritemoveLeft/moveLeft7.png");
    moveLeft[7] = load_image("SpritemoveLeft/moveLeft8.png");
    moveLeft[8] = load_image("SpritemoveLeft/moveLeft9.png");
    moveLeft[9] = load_image("SpritemoveLeft/moveLeft10.png");
    moveLeft[10] = load_image("SpritemoveLeft/moveLeft11.png");
    moveLeft[11] = load_image("SpritemoveLeft/moveLeft12.png");
    moveLeft[12] = load_image("SpritemoveLeft/moveLeft13.png");
    moveLeft[13] = load_image("SpritemoveLeft/moveLeft14.png");
    moveLeft[14] = load_image("SpritemoveLeft/moveLeft15.png");
    moveLeft[15] = load_image("SpritemoveLeft/moveLeft16.png");
    moveLeft[16] = load_image("SpritemoveLeft/moveLeft17.png");
    moveLeft[17] = load_image("SpritemoveLeft/moveLeft18.png");
    moveLeft[18] = load_image("SpritemoveLeft/moveLeft19.png");
    moveLeft[19] = load_image("SpritemoveLeft/moveLeft20.png");
 
    //Load the images when moving right
    moveRight[0] = load_image("SpritemoveRight/moveRight1.png");
    moveRight[1] = load_image("SpritemoveRight/moveRight2.png");
    moveRight[2] = load_image("SpritemoveRight/moveRight3.png");
    moveRight[3] = load_image("SpritemoveRight/moveRight4.png");
    moveRight[4] = load_image("SpritemoveRight/moveRight5.png");
    moveRight[5] = load_image("SpritemoveRight/moveRight6.png");
    moveRight[6] = load_image("SpritemoveRight/moveRight7.png");
    moveRight[7] = load_image("SpritemoveRight/moveRight8.png");
    moveRight[8] = load_image("SpritemoveRight/moveRight9.png");
    moveRight[9] = load_image("SpritemoveRight/moveRight10.png");
    moveRight[10] = load_image("SpritemoveRight/moveRight11.png");
    moveRight[11] = load_image("SpritemoveRight/moveRight12.png");
    moveRight[12] = load_image("SpritemoveRight/moveRight13.png");
    moveRight[13] = load_image("SpritemoveRight/moveRight14.png");
    moveRight[14] = load_image("SpritemoveRight/moveRight15.png");
    moveRight[15] = load_image("SpritemoveRight/moveRight16.png");
    moveRight[16] = load_image("SpritemoveRight/moveRight17.png");
    moveRight[17] = load_image("SpritemoveRight/moveRight18.png");
    moveRight[18] = load_image("SpritemoveRight/moveRight19.png");
    moveRight[19] = load_image("SpritemoveRight/moveRight20.png");
 
    //If there was a problem in loading the sprite
    for( int i=0; i<=19; i++)
    {
        if( moveLeft[i] == NULL )
        {
            return false;
        }
        if( moveRight[i] == NULL )
        {
            return false;
        }
    }
    if( stayStill == NULL || fooDead == NULL || fooWeapon == NULL || fooverigatop == NULL )
    {
        return false;
    }
    if( enemyBalloon == NULL || level1bg == NULL )
    {
        return false;
    }
 
    if( gameOver == NULL || finished == NULL )
    {
        return false;
    }
 
    //If everything loaded fine
    return true;
}
 
Menu::Menu()
{
    //Initialize coordinates
    x = y = 0;
 
    //Initialize counters
    i = j = 0;
 
 
    //Initialize 'state' to check if mouse is over Menu or not
    state = OUT;
 
    for( i=0; i<NUMMENU; i++ )
    {
        menu[i] = TTF_RenderText_Solid( font, labels[i], textColor );
        position[i].x = SCREEN_WIDTH / 2 - menu[i]->clip_rect.w/2;
        position[i].y = 3*BUTTON_HEIGHT + 50*i+1;
        position[i].w = menu[i]->clip_rect.w;
    }
}
 
int Menu::show_menu()
{
    while(1)
    {
        while( SDL_PollEvent( &event ) )
        {
            if( event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE )
            {
                return NUMMENU - 1;
            }
 
            //Check if mouse is over menu
            if( event.type == SDL_MOUSEMOTION )
            {
                x = event.motion.x;
                y = event.motion.y;
 
                for( i=0; i<NUMMENU; i++ )
                {
                    if( x>=position[i].x && x<=position[i].x+position[i].w && y>=position[i].y && y<=position[i].y+BUTTON_HEIGHT && state == OUT )
                    {
                        menu[i] = TTF_RenderText_Solid( font, labels[i], color[1] );
                        state = IN;
                    }
 
                    if( !(x>=position[i].x && x<=position[i].x+position[i].w && y>=position[i].y && y<=position[i].y+BUTTON_HEIGHT) )
                    {
                        menu[i] = TTF_RenderText_Solid( font, labels[i], color[0] );
                        state = OUT;
                    }
                }
            }
            //Check if menu is clicked
            if( event.type == SDL_MOUSEBUTTONDOWN )
            {
                x = event.button.x;
                y = event.button.y;
 
                for( i=0; i<NUMMENU; i++ )
                {
                    if( x>=position[i].x && x<=position[i].x+position[i].w && y>=position[i].y && y<=position[i].y+BUTTON_HEIGHT )
                    {
                        return i;
                    }
                }
            }
            //Apply the surfaces
            for( i=0; i<NUMMENU; i++ )
            {
                apply_surface( position[i].x, position[i].y, menu[i], screen );
            }
            //Refresh screen
            SDL_Flip(screen);
        }
    }
 
}
 
bool check_collision( SDL_Rect A, SDL_Rect B )
{
    //The sides of the rectangles
    int leftA, leftB;
    int rightA, rightB;
    int topA, topB;
    int bottomA, bottomB;
 
    //Calculate the sides of rect A
    leftA = A.x;
    rightA = A.x + A.w;
    topA = A.y;
    bottomA = A.y + A.h;
 
    //Calculate the sides of rect B
    leftB = B.x;
    rightB = B.x + B.w;
    topB = B.y;
    bottomB = B.y + B.h;
 
    //If any of the sides from A are outside of B
    if( bottomA <= topB )
    {
        return false;
    }
 
    if( topA >= bottomB )
    {
        return false;
    }
 
    if( rightA <= leftB )
    {
        return false;
    }
 
    if( leftA >= rightB )
    {
        return false;
    }
 
    //If none of the sides from A are outside B
    return true;
}
 
void close_all()
{
    //Free the surface
    for( int i=0; i<=20; i++)
    {
        SDL_FreeSurface( moveLeft[i] );
        SDL_FreeSurface( moveRight[i] );
    }
 
    //Clean the menu surfaces
    for( int i=0; i<NUMMENU; i++ )
    {
        SDL_FreeSurface( menu[i] );
    }
 
    //Clear the in-game text surfaces
    SDL_FreeSurface( gameOver );
    SDL_FreeSurface( finished );
 
    //Clean the balloon sprites
    for( int i=0; i<=3; i++)
    {
        SDL_FreeSurface( enemyBalloon[i] );
    }
 
    //Clean the other stuff
    SDL_FreeSurface( level1bg );
    SDL_FreeSurface( fooWeapon );
    SDL_FreeSurface( fooverigatop );
    SDL_FreeSurface( stayStill );
    SDL_FreeSurface( collisionCheck );
 
    //Close Font
    TTF_CloseFont( font );
 
    //Quit SDL_ttf
    TTF_Quit();
 
    //Quit SDL
    SDL_Quit();
}
 
Foo::Foo()
{
    //init the foo rect
    foobox.x = 600;
    foobox.y = SCREEN_HEIGHT - FOO_HEIGHT;
    foobox.w = FOO_WIDTH;
    foobox.h = FOO_HEIGHT;
 
    chainoffsetX = 0;
    chainoffsetY = 0;
 
    //Initialize movement variables
    velocity = 0;
    Yvelocity = 0;
    Yacceleration = 0;
 
    //Initialize animation variables
    frame = 0;
    cooldown = 0;
    walkstatus = FOO_STILL;
}
 
void Foo::handle_events()
{
    //If a key was pressed
    if( event.type == SDL_KEYDOWN )
    {
        //Set the velocity
        if( event.key.keysym.sym == SDLK_LEFT ) velocity -= FOO_WIDTH / 12;
        if( event.key.keysym.sym == SDLK_RIGHT ) velocity += FOO_WIDTH / 12;
        if( event.key.keysym.sym == SDLK_SPACE )
        {
            weaponstatus = WEAPON_ON;
            cooldown = CHAIN_COOLDOWN;
        }
    }
    //If a key was released
    else if( event.type == SDL_KEYUP )
    {
        //Set the velocity
        if( event.key.keysym.sym == SDLK_RIGHT ) velocity -= FOO_WIDTH / 12;
        if( event.key.keysym.sym == SDLK_LEFT ) velocity += FOO_WIDTH / 12;
    }
}
 
void Foo::movement()
{
    //Move
    foobox.x += velocity;
    foobox.y += Yvelocity;
 
    //Check foo-enemy collision
/*    if( check_collision( foobox, enemybox ) == true && dead == false && hitsNumber < 4 )
    {
        dead = true;//da napravq umiraneto na foo kat go 4ukne balon4o
        velocity = 9;
        Yvelocity = -8;
        pauseGame = true;
        pauseTime = DEATH_PAUSE;
    }
 
    if( dead == true )
    {
        ;
    } */
 
    //Keep the foo in bounds
    if( foobox.x + FOO_WIDTH > SCREEN_WIDTH && dead == true )
    {
        velocity *= -1.2;
        Yvelocity *= -1.8;
    }
 
    if( foobox.x + FOO_WIDTH > SCREEN_WIDTH && dead != true )
    {
        foobox.y -= Yvelocity;
        Yvelocity += Yacceleration;
    }
 
    if( foobox.x < 0 )
    {
        quit = true;
    }
}
 
void Foo::shoot()
{
    if( weaponstatus == WEAPON_ON )
    {
        if( cooldown == CHAIN_COOLDOWN )
        {
            //Set the chain coordinates
            chainoffsetX = foobox.x + FOO_WIDTH / 3;
            chainoffsetY = foobox.y + FOO_HEIGHT / 3;
        }
 
        //Get the chain coordinates
        veriga.x = chainoffsetX;
        veriga.y = chainoffsetY;
        veriga.w = CHAIN_WIDTH;
        veriga.h = CHAIN_HEIGHT;
 
        //Cant explain this...
        cooldown --;
        chainoffsetY = 12 * cooldown;
    }
 
    if( cooldown == 0 )
    {
        weaponstatus = WEAPON_OFF;
    }
}
 
void Foo::walk_anim()
{
        //If Foo is moving left
    if( velocity < 0 )
    {
        //Set the animation to left
        walkstatus = FOO_LEFT;
 
        //Move to the next frame in the animation
        frame++;
    }
 
    //If Foo is moving right
    else if( velocity > 0 )
    {
        //Set the animation to right
        walkstatus = FOO_RIGHT;
 
        //Move to the next frame in the animation
        frame++;
    }
 
    //If foo is standing
    else
    {
        //Restart the animation
        walkstatus = FOO_STILL;
    }
 
    if( cooldown >= CHAIN_COOLDOWN - 4 )
    {
        walkstatus = FOO_STILL;
    }
 
    if( dead == true )
    {
        walkstatus = FOO_DEAD;
    }
 
    //Loop the animation
    if( frame >= 20 )
    {
        frame = 0;
    }
}
 
//balloon2 is only needed to give Foo class access to Balloon class functions
//Balloon balloon2;
 
void Foo::show()
{
 
    //Show the chain
    if( weaponstatus == WEAPON_ON )
    {
        apply_surface( chainoffsetX, chainoffsetY, fooWeapon, screen );
        apply_surface( chainoffsetX - FOO_WIDTH / 15, chainoffsetY, fooverigatop, screen );
    }
 
    //Show foo
    if( walkstatus == FOO_STILL )
    {
        apply_surface( foobox.x, foobox.y, stayStill, screen );
    }
    else if( walkstatus == FOO_RIGHT )
    {
        apply_surface( foobox.x, foobox.y, moveRight[frame], screen );
    }
    else if( walkstatus == FOO_LEFT )
    {
        apply_surface( foobox.x, foobox.y, moveLeft[frame], screen );
    }
 
    if( walkstatus == FOO_DEAD )
    {
        apply_surface( foobox.x, foobox.y, fooDead, screen );
       // apply_surface( SCREEN_WIDTH /2 - gameOver->clip_rect.w /2, SCREEN_HEIGHT /3, gameOver, screen );
    }
}
 
Balloon::Balloon()
{
    velocityX = 1.2f;
    velocityY = 6;
    accelerationY = 0.1f;
    balloonWeight = 5.3f;
 
    //Set the collision foobox
    enemybox.w = BALLOON_WIDTH;
    enemybox.h = BALLOON_WIDTH;
}
 
Balloon::Balloon( int a, int b )
{
    enemybox.x = a;
    enemybox.y = b;
}
 
void Balloon::movement()
{
    enemybox.x += velocityX;
    enemybox.y += velocityY;
    velocityY += accelerationY;
 
        //When the chain hits the bubble
    if( check_collision( enemybox, veriga ) && weaponstatus == WEAPON_ON && hitsNumber <= 3 )
    {
        collisionCheck = TTF_RenderText_Solid( font, "Collision ON", textColor );
 
        //Stop the chain
        weaponstatus = WEAPON_OFF;
 
        //Make the balloon Rect and weight smaller
       // balloon2.make_smaller();
        //Make the bubble rectangle smaller
        enemybox.x = enemybox.x + enemybox.h / 4;
        enemybox.w = enemybox.w / 2;
        enemybox.h = enemybox.h / 2;
 
        //Decrease the weight, so it bounces
        balloonWeight -= 0.5;
 
        //Pushes the balloon away when hit with chain
        velocityY = -balloonWeight / 1.4f;
 
        //Increment the number of hits
        hitsNumber++;
    }
 
    //Keep the foo in bounds
    if( enemybox.x < 0 )
    {
        /*enemybox.x -= velocity;
        enemybox.y -= velocity;*/
        velocityX = 1.2f;
    }
 
    if( enemybox.x + enemybox.w > SCREEN_WIDTH )
    {
        velocityX = -1.0f;
    }
 
    if( enemybox.y < 0 )
    {
        velocityY = balloonWeight;
    }
 
    if( enemybox.y + enemybox.h > SCREEN_HEIGHT )
    {
        velocityY = -balloonWeight;
    }
}
 
void Balloon::show()
{
    if( hitsNumber <=3 )
    {
        apply_surface( enemybox.x, enemybox.y, enemyBalloon[hitsNumber], screen );
    }
 
    if( hitsNumber == 4)
    {
        apply_surface( 190, 200, finished, screen );
    }
}
 
 
void Balloon::push_away()
{
    velocityY = -balloonWeight / 2;
}
 
Timer::Timer()
{
    //Initialize the variables
    startTicks = 0;
    paused = false;
    pausedTicks = 0;
    started = false;
}
 
void Timer::start()
{
    //Start the timer
    started = true;
 
    //Unpause the timer
    paused = false;
 
    //Get the current clock time
    startTicks = SDL_GetTicks();
}
 
void Timer::stop()
{
    //Stop the timer
    started = false;
 
    //Unpause the timer
    paused = false;
}
 
void Timer::pause()
{
    //If the timer is running and isn't already paused
    if( ( started == true ) && ( paused == false ) )
    {
        //Pause the timer
        paused = true;
 
        //Calculate the paused ticks
        pausedTicks = SDL_GetTicks() - startTicks;
    }
}
 
void Timer::unpause()
{
    //If the timer is paused
    if( paused == true )
    {
        //Unpause the timer
        paused = false;
 
        //Reset the starting ticks
        startTicks = SDL_GetTicks() - pausedTicks;
 
        //Reset the paused ticks
        pausedTicks = 0;
    }
}
 
int Timer::get_ticks()
{
    //If the timer is running
    if( started == true )
    {
        //If the timer is paused
        if( paused == true )
        {
            //Return the number of ticks when the timer was paused
            return pausedTicks;
        }
        else
        {
            //Return the current time minus the start time
            return SDL_GetTicks() - startTicks;
        }
    }
 
    //If the timer isn't running
    return 0;
}
 
bool Timer::is_started()
{
    return started;
}
 
bool Timer::is_paused()
{
    return paused;
}
 
int main( int argc, char* args[] )
{
    //Initialize
    if( init() == false )
    {
        return 1;
    }
 
    //Load the files
    if( load_files() == false )
    {
        return 1;
    }
 
    //The frame rate regulator
    Timer fps;
 
    //The menu
    Menu menu1;
 
    //The Foo
    Foo foo1;
 
    //The balloon
    Balloon balloon1;
 
    //Get the number of the menu
    int menuVal = menu1.show_menu();
 
    if( menuVal == NUMMENU - 1 )
    {
        quit = true;
    }
 
    float get_ticks;
 
    //While the user hasn't quit
    while( quit == false )
    {
        //Start the frame timer
        fps.start();
 
        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            if( dead == false )
            {
                //Handle events for foo
                foo1.handle_events();
            }
 
            //If the user has Xed out the window
            if( event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE )
            {
                //Quit the program
                quit = true;
            }
        }
 
 
 
    /*  //Fill the screen white
        SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );
    */
 
        //Pausing the game for a while when bubble hits foo
        if( pauseTime > 1 && pauseTime <= DEATH_PAUSE )
        {
            pauseGame = true;
            pauseTime --;
        }
        else pauseGame = false;
 
        //If the game is not paused
        if( pauseGame == false )
        {
            //Moves foo
            foo1.movement();
 
            //Handles shooting
            foo1.shoot();
 
            foo1.walk_anim();
 
            //Moves the balloon
            balloon1.movement();
          //  balloon2.movement();
            //Apply the background
            apply_surface( 0, 0, level1bg, screen );
 
            //Show the balloon on the screen
            balloon1.show();
          //  balloon2.show();
 
            //Show the foo on the screen
            foo1.show();
        }
 
        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }
 
        //Cap the frame rate
        if( fps.get_ticks() < ( 1000 / FRAMES_PER_SECOND ) )
        {
            SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() - 5 );
        }
    }
 
    //Clean up
    close_all();
 
    return 0;
}

Sorry for spam, but I actually don't have problems in this code, because this is my last stable version, now I need to know how to add more balloons without messing up everything. If you want, I can somehow upload the folder with the .exe file so you can see what the game is ( or you can just search it in google, the name is "Bubble Struggle 2" )

You are creating two different constructors:
Balloon::Balloon()
{
    velocityX = 1.2f;
    velocityY = 6;
    accelerationY = 0.1f;
    balloonWeight = 5.3f;
 
    //Set the collision foobox
    enemybox.w = BALLOON_WIDTH;
    enemybox.h = BALLOON_WIDTH;
}
 
Balloon::Balloon( int a, int b )
{
    enemybox.x = a;
    enemybox.y = b;
}

If you call Balloon(int a, int b), the other constructor Balloon() doesn't get called.

Balloon balloon1; //*only* calls Balloon() constructor.
Balloon balloon2(50,50); //*only* calls Balloon(int,int) constructor.

Instead, you should make your class look like this:
class Balloon
{
    private:
    //Its rate of movement
    float velocityX = 1.2f; //Or whatever a good default value is.
    float velocityY = 1.2f; //Or whatever a good default value is.
 
    float accelerationY = 0.1f;  //Or whatever a good default value is.
    float balloonWeight = 5.3f;  //Or whatever a good default value is.
 
    SDL_Rect enemybox = {0,0,BALLOON_WIDTH,BALLOON_WIDTH};
 
    public: 
    //etc...
};

Then create a single constructor that takes whatever parameters you want to give the balloon. Perhaps the position, weight, and velocity.

Also, make sure you give your function parameters, classes, functions, and variables, good names.

This is an example of bad function parameter names:
Balloon::Balloon( int a, int b ) // 'a' and 'b' don't make any sense. These should be named 'x' and 'y'.
Here's an example of bad class name:
//The foo
class Foo  //A 'foo' is a generic term that means "thing". Don't call your classes "thing", call them descriptive names like "Player".

Anyway, I'd make your class have a single constructor like:
Balloon::Balloon(int posX, int posY, float balloonWeight, float velocityX, float velocityY)
    : balloonWeight(balloonWeight), velocityX(velocityX), velocityY(velocityY)
{
    enemybox.x = posX;
    enemybox.y = posY;
}

Then you could do:
Menu mainMenu;
Player player;

Balloon balloon1(50,50, 0.5f, 1.2f, 2.0f);
Balloon balloon2(100,0, 0.7f, -0.8f, 1.4f);

After you get that working, then you can migrate to using std::vector for dynamically holding as many balloons as you want.
Menu mainMenu;
Player player;

std::vector<Balloon> allBalloons;
allBalloons.push_back(Balloon(50,50, 0.5f, 1.2f, 2.0f));
allBalloons.push_back(Balloon(100,0, 0.7f, -0.8f, 1.4f));

BALLOONS EVERYWHERE, MY GAME IS WORKING.cool.png cool.png cool.png . Thanks, Jamin, for looking through all my code and for helping me so much. YOU MADE MY WHOLE WEEK. I LOVE YOU, MAN ( I meant that I love you platonically, don't get horny ) THANKS A LOT AGAIN. I will surely post all my future questions here so I can exploit your generosity further for egocentric purposes. Thanks again.and BYEee

This topic is closed to new replies.

Advertisement